aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/ModuloSchedule.cpp
AgeCommit message (Collapse)AuthorFilesLines
2022-06-25[llvm] Don't use Optional::hasValue (NFC)Kazu Hirata1-4/+4
This patch replaces Optional::hasValue with the implicit cast to bool in conditionals only.
2022-06-25Revert "Don't use Optional::hasValue (NFC)"Kazu Hirata1-8/+8
This reverts commit aa8feeefd3ac6c78ee8f67bf033976fc7d68bc6d.
2022-06-25Don't use Optional::hasValue (NFC)Kazu Hirata1-8/+8
2022-06-20[llvm] Don't use Optional::getValue (NFC)Kazu Hirata1-1/+1
2022-06-20[llvm] Don't use Optional::hasValue (NFC)Kazu Hirata1-4/+4
2022-06-19[MachinePipeliner] Handle failing constrainRegClassDavid Green1-7/+27
The included test hits a verifier problems as one of the instructions: ``` %113:tgpreven, %114:tgprodd = MVE_VMLSLDAVas16 %12:tgpreven(tied-def 0), %11:tgprodd(tied-def 1), %7:mqpr, %8:mqpr, 0, $noreg, $noreg ``` Has two inputs that come from different PHIs with the same base reg, but conflicting regclasses: ``` %11:tgprodd = PHI %103:gpr, %bb.1, %16:gpr, %bb.2 %12:tgpreven = PHI %103:gpr, %bb.1, %17:gpr, %bb.2 ``` The MachinePipeliner would attempt to use %103 for both the %11 and %12 operands in the prolog, constraining the register class to the common subset of both. Unfortunately there are no registers that are both odd and even, so the second constrainRegClass fails. Fix this situation by inserting a COPY for the second if the call to constrainRegClass fails. The register allocation can then fold that extra copy away. The register allocation of Q regs changed with this test, but the R regs were the same and no new instructions are needed in the final assembly. Differential Revision: https://reviews.llvm.org/D127971
2022-06-07[NFC] Fix spelling/newlines in comments/debug messagesDavid Penry1-1/+1
Just a few spelling mistakes and missing newlines Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D127162
2022-06-06[ModuloSchedule] Fix terminator update when peeling.Hendrik Greving1-3/+3
Fixes a bug of us not correctly updating the terminator of the loop's preheader, if multiple terminating branch instructions are present. This is tested through existing tests. The bug itself is hard or not possible to get exposed with the upstream Hexagon backend, because the machine pipeliner checks for an existing preheader, which is defined as a block with only 1 edge into the header. The condition of this bug is a block into the loop with more than 1 edge, and not every downstream target checks for an existing preheader. Differential Revision: https://reviews.llvm.org/D126386
2022-04-29Reapply [CodeGen][ARM] Enable Swing Module Scheduling for ARMDavid Penry1-7/+10
Fixed "private field is not used" warning when compiled with clang. original commit: 28d09bbbc3d09c912b54a4d5edb32cab7de32a6f reverted in: fa49021c68ef7a7adcdf7b8a44b9006506523191 ------ This patch permits Swing Modulo Scheduling for ARM targets turns it on by default for the Cortex-M7. The t2Bcc instruction is recognized as a loop-ending branch. MachinePipeliner is extended by adding support for "unpipelineable" instructions. These instructions are those which contribute to the loop exit test; in the SMS papers they are removed before creating the dependence graph and then inserted into the final schedule of the kernel and prologues. Support for these instructions was not previously necessary because current targets supporting SMS have only supported it for hardware loop branches, which have no loop-exit-contributing instructions in the loop body. The current structure of the MachinePipeliner makes it difficult to remove/exclude these instructions from the dependence graph. Therefore, this patch leaves them in the graph, but adds a "normalization" method which moves them in the schedule to stage 0, which causes them to appear properly in kernel and prologues. It was also necessary to be more careful about boundary nodes when iterating across successors in the dependence graph because the loop exit branch is now a non-artificial successor to instructions in the graph. In additional, schedules with physical use/def pairs in the same cycle should be treated as creating an invalid schedule because the scheduling logic doesn't respect physical register dependence once scheduled to the same cycle. Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D122672
2022-04-28Revert "[CodeGen][ARM] Enable Swing Module Scheduling for ARM"David Penry1-10/+7
This reverts commit 28d09bbbc3d09c912b54a4d5edb32cab7de32a6f while I investigate a buildbot failure.
2022-04-28[CodeGen][ARM] Enable Swing Module Scheduling for ARMDavid Penry1-7/+10
This patch permits Swing Modulo Scheduling for ARM targets turns it on by default for the Cortex-M7. The t2Bcc instruction is recognized as a loop-ending branch. MachinePipeliner is extended by adding support for "unpipelineable" instructions. These instructions are those which contribute to the loop exit test; in the SMS papers they are removed before creating the dependence graph and then inserted into the final schedule of the kernel and prologues. Support for these instructions was not previously necessary because current targets supporting SMS have only supported it for hardware loop branches, which have no loop-exit-contributing instructions in the loop body. The current structure of the MachinePipeliner makes it difficult to remove/exclude these instructions from the dependence graph. Therefore, this patch leaves them in the graph, but adds a "normalization" method which moves them in the schedule to stage 0, which causes them to appear properly in kernel and prologues. It was also necessary to be more careful about boundary nodes when iterating across successors in the dependence graph because the loop exit branch is now a non-artificial successor to instructions in the graph. In additional, schedules with physical use/def pairs in the same cycle should be treated as creating an invalid schedule because the scheduling logic doesn't respect physical register dependence once scheduled to the same cycle. Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D122672
2022-03-16[NFC][CodeGen] Rename some functions in MachineInstr.h and remove duplicated ↵Shengchen Kan1-6/+6
comments
2022-03-16Cleanup codegen includesserge-sans-paille1-0/+1
This is a (fixed) recommit of https://reviews.llvm.org/D121169 after: 1061034926 before: 1063332844 Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D121681
2022-03-10Revert "Cleanup codegen includes"Nico Weber1-1/+0
This reverts commit 7f230feeeac8a67b335f52bd2e900a05c6098f20. Breaks CodeGenCUDA/link-device-bitcode.cu in check-clang, and many LLVM tests, see comments on https://reviews.llvm.org/D121169
2022-03-10Cleanup codegen includesserge-sans-paille1-0/+1
after: 1061034926 before: 1063332844 Differential Revision: https://reviews.llvm.org/D121169
2022-01-07[llvm] Use true/false instead of 1/0 (NFC)Kazu Hirata1-2/+2
Identified with modernize-use-bool-literals.
2021-11-28[llvm] Use range-based for loops (NFC)Kazu Hirata1-2/+1
2021-11-26[Target] Use range-based for loops (NFC)Kazu Hirata1-2/+1
2021-11-11[CodeGen, Target] Use MachineRegisterInfo::use_operands (NFC)Kazu Hirata1-12/+5
2021-11-11[CodeGen] Use MachineInstr::operands (NFC)Kazu Hirata1-6/+4
2021-11-10[llvm] Use make_early_inc_range (NFC)Kazu Hirata1-11/+4
2021-11-06[llvm] Use llvm::reverse (NFC)Kazu Hirata1-5/+3
2021-11-01[CodeGen] Use make_early_inc_range (NFC)Kazu Hirata1-12/+12
2021-10-31[CodeGen, Target] Use MachineBasicBlock::terminators (NFC)Kazu Hirata1-5/+3
2021-10-26[CodeGen, Hexagon] Use MachineBasicBlock::phis (NFC)Kazu Hirata1-12/+7
2021-06-25[ModuloSchedule] Pass loop block explicitly to kernel rewriter.Hendrik Greving1-5/+5
This change is NFC upstream. We pass in the loop's block to the kernel rewriter explicitly, instead of assuming it's the loop's top block. This change is made for downstream targets where this assumption doesn't hold. Differential Revision: https://reviews.llvm.org/D104811
2020-09-17ModuloSchedule.cpp - remove unnecessary includes. NFCI.Simon Pilgrim1-2/+0
Already included in ModuloSchedule.h
2020-06-30[ModuloSchedule] Make PeelingModuloScheduleExpander inheritable.Hendrik Greving1-6/+6
Basically a NFC, but allows subclasses access to the entire PeelingModuloScheduleExpander class. We are doing this to allow backends, particularly one that are not necessarily upstreamed, to inherit from PeelingModuloScheduleExpander and access its basic structures. Renames Info into LoopInfo for consistency in PeelingModuloScheduleExpander. Differential Revision: https://reviews.llvm.org/D82673
2020-06-25LiveIntervals.h.h - reduce AliasAnalysis.h include to forward declaration. NFC.Simon Pilgrim1-0/+1
Fix implicit include dependencies in source files and replace legacy AliasAnalysis typedef with AAResults where necessary.
2020-06-08[ModuloSchedule] Support instructions with > 1 destination when walking ↵Hendrik Greving1-3/+4
canonical use. Fixes a minor bug that led to finding the wrong register if the definition had more than one register destination.
2020-05-29[ModuloSchedule] Allow illegal phis to be moved across stages.Hendrik Greving1-12/+15
Fixes a trivial but impactful bug where we did not move illegal phis across stages. This led to incorrect mappings in certain cases.
2020-05-21[ModuloSchedule] Add missing comma.Hendrik Greving1-1/+1
This is a test commit as per Chris to verify commit access. Thanks!
2020-05-21[ModuloSchedule] Trivial fix for instruction with more than one destination ↵Thomas Raoux1-2/+2
in modulo peeler. When moving an instruction into a block where it was referenced by a phi when peeling, refer to the phi's register number and assert that the instruction has it in its destinations. This way, it also covers instructions with more than one destination. Patch by Hendrik Greving! Differential Revision: https://reviews.llvm.org/D80027
2020-05-07[ModuloSchedule] Fix epilogue peeling with illegal phi.Thomas Raoux1-5/+9
When peeling out the epilogue we need to ignore illegal phis coming from stages greater than the producer stage. Otherwise we end up with circular phi dependencies. Differential Revision: https://reviews.llvm.org/D79581
2020-02-18Add OffsetIsScalable to getMemOperandWithOffsetSander de Smalen1-1/+6
Summary: Making `Scale` a `TypeSize` in AArch64InstrInfo::getMemOpInfo, has the effect that all places where this information is used (notably, TargetInstrInfo::getMemOperandWithOffset) will need to consider Scale - and derived, Offset - possibly being scalable. This patch adds a new operand `bool &OffsetIsScalable` to TargetInstrInfo::getMemOperandWithOffset and fixes up all the places where this function is used, to consider the offset possibly being scalable. In most cases, this means bailing out because the algorithm does not (or cannot) support scalable offsets in places where it does some form of alias checking for example. Reviewers: rovka, efriedma, kristof.beyls Reviewed By: efriedma Subscribers: wuzish, kerbowa, MatzeB, arsenm, nemanjai, jvesely, nhaehnle, hiraditya, kbarton, javed.absar, asb, rbar, johnrusso, simoncook, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, PkmX, jocewei, jsji, Jim, lenary, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D72758
2019-12-09[ModuloSchedule] Fix data types in ModuloScheduleExpander::isLoopCarriedThomas Raoux1-2/+2
The cycle values in modulo scheduling results can be negative. The result of ModuloSchedule::getCycle() must be received as an int type. Patch by Masaki Arai! Differential Revision: https://reviews.llvm.org/D71122
2019-11-23[ModuloSchedule] Fix a bug in experimental expanderThomas Raoux1-14/+62
Fix two problems that popped up after my last patch. One is that the stiching of prologue/epilogue can be wrong when reading a value from a previsou stage. Also changed how we duplicate phi instructions to avoid generating extra phi that we delete later. Differential Revision: https://reviews.llvm.org/D70213
2019-11-13Sink all InitializePasses.h includesReid Kleckner1-0/+1
This file lists every pass in LLVM, and is included by Pass.h, which is very popular. Every time we add, remove, or rename a pass in LLVM, it caused lots of recompilation. I found this fact by looking at this table, which is sorted by the number of times a file was changed over the last 100,000 git commits multiplied by the number of object files that depend on it in the current checkout: recompiles touches affected_files header 342380 95 3604 llvm/include/llvm/ADT/STLExtras.h 314730 234 1345 llvm/include/llvm/InitializePasses.h 307036 118 2602 llvm/include/llvm/ADT/APInt.h 213049 59 3611 llvm/include/llvm/Support/MathExtras.h 170422 47 3626 llvm/include/llvm/Support/Compiler.h 162225 45 3605 llvm/include/llvm/ADT/Optional.h 158319 63 2513 llvm/include/llvm/ADT/Triple.h 140322 39 3598 llvm/include/llvm/ADT/StringRef.h 137647 59 2333 llvm/include/llvm/Support/Error.h 131619 73 1803 llvm/include/llvm/Support/FileSystem.h Before this change, touching InitializePasses.h would cause 1345 files to recompile. After this change, touching it only causes 550 compiles in an incremental rebuild. Reviewers: bkramer, asbirlea, bollu, jdoerfert Differential Revision: https://reviews.llvm.org/D70211
2019-11-11[ModuloSchedule] Fix modulo expansion for data loop carried dependencies.Thomas Raoux1-18/+132
The new experimental expansion has a problem when a value has a data dependency with an instruction from a previous stage. This is due to the way we peel out the kernel. To fix that I'm changing the way we peel out the kernel. We now peel the kernel NumberStage - 1 times. The code would be correct at this point if we didn't have to handle cases where the loop iteration is smaller than the number of stages. To handle this case we move instructions between different epilogues based on their stage and remap the PHI instructions correctly. Differential Revision: https://reviews.llvm.org/D69538
2019-11-11 [ModuloSchedule] Do target loop analysis before peeling.Thomas Raoux1-4/+2
Simple change to call target hook analyzeLoopForPipelining before changing the loop. After peeling analyzing the loop may be more complicated for target that don't have a loop instruction. This doesn't affect Hexagone and PPC as they have hardware loop instructions. Differential Revision: https://reviews.llvm.org/D69912
2019-10-04[ModuloSchedule] Do not remap terminatorsJames Molloy1-1/+1
This is a trivial point fix. Terminator instructions aren't scheduled, so we shouldn't expect to be able to remap them. This doesn't affect Hexagon and PPC because their terminators are always hardware loop backbranches that have no register operands. llvm-svn: 373762
2019-10-03[ModuloSchedule] removeBranch() *before* creating the trip count conditionJames Molloy1-2/+1
The Hexagon code assumes there's no existing terminator when inserting its trip count condition check. This causes swp-stages5.ll to break. The generated code looks good to me, it is likely a permutation. I have disabled the new codegen path to keep everything green and will investigate along with the other 3-4 tests that have different codegen. Fixes expensive-checks build. llvm-svn: 373629
2019-10-02[ModuloSchedule] Peel out prologs and epilogs, generate actual codeJames Molloy1-0/+262
Summary: This extends the PeelingModuloScheduleExpander to generate prolog and epilog code, and correctly stitch uses through the prolog, kernel, epilog DAG. The key concept in this patch is to ensure that all transforms are *local*; only a function of a block and its immediate predecessor and successor. By defining the problem in this way we can inductively rewrite the entire DAG using only local knowledge that is easy to reason about. For example, we assume that all prologs and epilogs are near-perfect clones of the steady-state kernel. This means that if a block has an instruction that is predicated out, we can redirect all users of that instruction to that equivalent instruction in our immediate predecessor. As all blocks are clones, every instruction must have an equivalent in every other block. Similarly we can make the assumption by construction that if a value defined in a block is used outside that block, the only possible user is its immediate successors. We maintain this even for values that are used outside the loop by creating a limited form of LCSSA. This code isn't small, but it isn't complex. Enabled a bunch of testing from Hexagon. There are a couple of tests not enabled yet; I'm about 80% sure there isn't buggy codegen but the tests are checking for patterns that we don't produce. Those still need a bit more investigation. In the meantime we (Google) are happy with the code produced by this on our downstream SMS implementation, and believe it generates correct code. Subscribers: mgorny, hiraditya, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68205 llvm-svn: 373462
2019-09-24[ModuloSchedule] KernelRewriter::rewrite - silence static analyzer ↵Simon Pilgrim1-0/+1
dyn_cast<> null dereference warning. NFCI. Assert that we've found the start of the MI schedule list. llvm-svn: 372723
2019-09-21[MachinePipeliner] Improve the TargetInstrInfo API analyzeLoop/reduceLoopCountJames Molloy1-23/+17
Recommit: fix asan errors. The way MachinePipeliner uses these target hooks is stateful - we reduce trip count by one per call to reduceLoopCount. It's a little overfit for hardware loops, where we don't have to worry about stitching a loop induction variable across prologs and epilogs (the induction variable is implicit). This patch introduces a new API: /// Analyze loop L, which must be a single-basic-block loop, and if the /// conditions can be understood enough produce a PipelinerLoopInfo object. virtual std::unique_ptr<PipelinerLoopInfo> analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const; The return value is expected to be an implementation of the abstract class: /// Object returned by analyzeLoopForPipelining. Allows software pipelining /// implementations to query attributes of the loop being pipelined. class PipelinerLoopInfo { public: virtual ~PipelinerLoopInfo(); /// Return true if the given instruction should not be pipelined and should /// be ignored. An example could be a loop comparison, or induction variable /// update with no users being pipelined. virtual bool shouldIgnoreForPipelining(const MachineInstr *MI) const = 0; /// Create a condition to determine if the trip count of the loop is greater /// than TC. /// /// If the trip count is statically known to be greater than TC, return /// true. If the trip count is statically known to be not greater than TC, /// return false. Otherwise return nullopt and fill out Cond with the test /// condition. virtual Optional<bool> createTripCountGreaterCondition(int TC, MachineBasicBlock &MBB, SmallVectorImpl<MachineOperand> &Cond) = 0; /// Modify the loop such that the trip count is /// OriginalTC + TripCountAdjust. virtual void adjustTripCount(int TripCountAdjust) = 0; /// Called when the loop's preheader has been modified to NewPreheader. virtual void setPreheader(MachineBasicBlock *NewPreheader) = 0; /// Called when the loop is being removed. virtual void disposed() = 0; }; The Pipeliner (ModuloSchedule.cpp) can use this object to modify the loop while allowing the target to hold its own state across all calls. This API, in particular the disjunction of creating a trip count check condition and adjusting the loop, improves the code quality in ModuloSchedule.cpp. llvm-svn: 372463
2019-09-20Revert "[MachinePipeliner] Improve the TargetInstrInfo API ↵Mitch Phillips1-17/+23
analyzeLoop/reduceLoopCount" This commit broke the ASan buildbot. See comments in rL372376 for more information. This reverts commit 15e27b0b6d9d51362fad85dbe95ac5b3fadf0a06. llvm-svn: 372425
2019-09-20[MachinePipeliner] Improve the TargetInstrInfo API analyzeLoop/reduceLoopCountJames Molloy1-23/+17
The way MachinePipeliner uses these target hooks is stateful - we reduce trip count by one per call to reduceLoopCount. It's a little overfit for hardware loops, where we don't have to worry about stitching a loop induction variable across prologs and epilogs (the induction variable is implicit). This patch introduces a new API: /// Analyze loop L, which must be a single-basic-block loop, and if the /// conditions can be understood enough produce a PipelinerLoopInfo object. virtual std::unique_ptr<PipelinerLoopInfo> analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const; The return value is expected to be an implementation of the abstract class: /// Object returned by analyzeLoopForPipelining. Allows software pipelining /// implementations to query attributes of the loop being pipelined. class PipelinerLoopInfo { public: virtual ~PipelinerLoopInfo(); /// Return true if the given instruction should not be pipelined and should /// be ignored. An example could be a loop comparison, or induction variable /// update with no users being pipelined. virtual bool shouldIgnoreForPipelining(const MachineInstr *MI) const = 0; /// Create a condition to determine if the trip count of the loop is greater /// than TC. /// /// If the trip count is statically known to be greater than TC, return /// true. If the trip count is statically known to be not greater than TC, /// return false. Otherwise return nullopt and fill out Cond with the test /// condition. virtual Optional<bool> createTripCountGreaterCondition(int TC, MachineBasicBlock &MBB, SmallVectorImpl<MachineOperand> &Cond) = 0; /// Modify the loop such that the trip count is /// OriginalTC + TripCountAdjust. virtual void adjustTripCount(int TripCountAdjust) = 0; /// Called when the loop's preheader has been modified to NewPreheader. virtual void setPreheader(MachineBasicBlock *NewPreheader) = 0; /// Called when the loop is being removed. virtual void disposed() = 0; }; The Pipeliner (ModuloSchedule.cpp) can use this object to modify the loop while allowing the target to hold its own state across all calls. This API, in particular the disjunction of creating a trip count check condition and adjusting the loop, improves the code quality in ModuloSchedule.cpp. llvm-svn: 372376
2019-09-17Hide implementation details in namespaces.Benjamin Kramer1-0/+2
llvm-svn: 372113
2019-09-04[ModuloSchedule] Fix no-asserts buildJames Molloy1-5/+8
Apologies, due to a git SNAFU this fix (dump doesn't exist and silence unused variables) stayed in my index rather than applying to rL370893. llvm-svn: 370894
2019-09-04[ModuloSchedule] Introduce PeelingModuloScheduleExpanderJames Molloy1-4/+461
This is the beginnings of a reimplementation of ModuloScheduleExpander. It works by generating a single-block correct pipelined kernel and then peeling out the prolog and epilogs. This patch implements kernel generation as well as a validator that will confirm the number of phis added is the same as the ModuloScheduleExpander. Prolog and epilog peeling will come in a different patch. Differential Revision: https://reviews.llvm.org/D67081 llvm-svn: 370893