| //===-- UnrollLoop.cpp - Loop unrolling utilities -------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file implements some loop unrolling utilities. It does not define any | |
| // actual pass or policy, but provides a single function to perform loop | |
| // unrolling. | |
| // | |
| // The process of unrolling can produce extraneous basic blocks linked with | |
| // unconditional branches. This will be corrected in the future. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/ADT/ArrayRef.h" | |
| #include "llvm/ADT/DenseMap.h" | |
| #include "llvm/ADT/MapVector.h" | |
| #include "llvm/ADT/STLExtras.h" | |
| #include "llvm/ADT/ScopedHashTable.h" | |
| #include "llvm/ADT/SetVector.h" | |
| #include "llvm/ADT/SmallVector.h" | |
| #include "llvm/ADT/Statistic.h" | |
| #include "llvm/ADT/StringRef.h" | |
| #include "llvm/ADT/Twine.h" | |
| #include "llvm/Analysis/AliasAnalysis.h" | |
| #include "llvm/Analysis/AssumptionCache.h" | |
| #include "llvm/Analysis/DomTreeUpdater.h" | |
| #include "llvm/Analysis/InstructionSimplify.h" | |
| #include "llvm/Analysis/LoopInfo.h" | |
| #include "llvm/Analysis/LoopIterator.h" | |
| #include "llvm/Analysis/MemorySSA.h" | |
| #include "llvm/Analysis/OptimizationRemarkEmitter.h" | |
| #include "llvm/Analysis/ScalarEvolution.h" | |
| #include "llvm/IR/BasicBlock.h" | |
| #include "llvm/IR/CFG.h" | |
| #include "llvm/IR/Constants.h" | |
| #include "llvm/IR/DebugInfoMetadata.h" | |
| #include "llvm/IR/DebugLoc.h" | |
| #include "llvm/IR/DiagnosticInfo.h" | |
| #include "llvm/IR/Dominators.h" | |
| #include "llvm/IR/Function.h" | |
| #include "llvm/IR/IRBuilder.h" | |
| #include "llvm/IR/Instruction.h" | |
| #include "llvm/IR/Instructions.h" | |
| #include "llvm/IR/IntrinsicInst.h" | |
| #include "llvm/IR/Metadata.h" | |
| #include "llvm/IR/PatternMatch.h" | |
| #include "llvm/IR/Use.h" | |
| #include "llvm/IR/User.h" | |
| #include "llvm/IR/ValueHandle.h" | |
| #include "llvm/IR/ValueMap.h" | |
| #include "llvm/Support/Casting.h" | |
| #include "llvm/Support/CommandLine.h" | |
| #include "llvm/Support/Debug.h" | |
| #include "llvm/Support/GenericDomTree.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| #include "llvm/Transforms/Utils/BasicBlockUtils.h" | |
| #include "llvm/Transforms/Utils/Cloning.h" | |
| #include "llvm/Transforms/Utils/Local.h" | |
| #include "llvm/Transforms/Utils/LoopSimplify.h" | |
| #include "llvm/Transforms/Utils/LoopUtils.h" | |
| #include "llvm/Transforms/Utils/SimplifyIndVar.h" | |
| #include "llvm/Transforms/Utils/UnrollLoop.h" | |
| #include "llvm/Transforms/Utils/ValueMapper.h" | |
| #include <assert.h> | |
| #include <cmath> | |
| #include <numeric> | |
| #include <vector> | |
| namespace llvm { | |
| class DataLayout; | |
| class Value; | |
| } // namespace llvm | |
| using namespace llvm; | |
| #define DEBUG_TYPE "loop-unroll" | |
| // TODO: Should these be here or in LoopUnroll? | |
| STATISTIC(NumCompletelyUnrolled, "Number of loops completely unrolled"); | |
| STATISTIC(NumUnrolled, "Number of loops unrolled (completely or otherwise)"); | |
| STATISTIC(NumUnrolledNotLatch, "Number of loops unrolled without a conditional " | |
| "latch (completely or otherwise)"); | |
| static cl::opt<bool> | |
| UnrollRuntimeEpilog("unroll-runtime-epilog", cl::init(false), cl::Hidden, | |
| cl::desc("Allow runtime unrolled loops to be unrolled " | |
| "with epilog instead of prolog.")); | |
| static cl::opt<bool> UnrollUniformWeights( | |
| "unroll-uniform-weights", cl::init(false), cl::Hidden, | |
| cl::desc("If new branch weights must be found, work harder to keep them " | |
| "uniform.")); | |
| static cl::opt<bool> | |
| UnrollVerifyDomtree("unroll-verify-domtree", cl::Hidden, | |
| cl::desc("Verify domtree after unrolling"), | |
| #ifdef EXPENSIVE_CHECKS | |
| cl::init(true) | |
| #else | |
| cl::init(false) | |
| #endif | |
| ); | |
| static cl::opt<bool> | |
| UnrollVerifyLoopInfo("unroll-verify-loopinfo", cl::Hidden, | |
| cl::desc("Verify loopinfo after unrolling"), | |
| #ifdef EXPENSIVE_CHECKS | |
| cl::init(true) | |
| #else | |
| cl::init(false) | |
| #endif | |
| ); | |
| static cl::opt<bool> UnrollAddParallelReductions( | |
| "unroll-add-parallel-reductions", cl::init(false), cl::Hidden, | |
| cl::desc("Allow unrolling to add parallel reduction phis.")); | |
| /// Check if unrolling created a situation where we need to insert phi nodes to | |
| /// preserve LCSSA form. | |
| /// \param Blocks is a vector of basic blocks representing unrolled loop. | |
| /// \param L is the outer loop. | |
| /// It's possible that some of the blocks are in L, and some are not. In this | |
| /// case, if there is a use is outside L, and definition is inside L, we need to | |
| /// insert a phi-node, otherwise LCSSA will be broken. | |
| /// The function is just a helper function for llvm::UnrollLoop that returns | |
| /// true if this situation occurs, indicating that LCSSA needs to be fixed. | |
| static bool needToInsertPhisForLCSSA(Loop *L, | |
| const std::vector<BasicBlock *> &Blocks, | |
| LoopInfo *LI) { | |
| for (BasicBlock *BB : Blocks) { | |
| if (LI->getLoopFor(BB) == L) | |
| continue; | |
| for (Instruction &I : *BB) { | |
| for (Use &U : I.operands()) { | |
| if (const auto *Def = dyn_cast<Instruction>(U)) { | |
| Loop *DefLoop = LI->getLoopFor(Def->getParent()); | |
| if (!DefLoop) | |
| continue; | |
| if (DefLoop->contains(L)) | |
| return true; | |
| } | |
| } | |
| } | |
| } | |
| return false; | |
| } | |
| /// Adds ClonedBB to LoopInfo, creates a new loop for ClonedBB if necessary | |
| /// and adds a mapping from the original loop to the new loop to NewLoops. | |
| /// Returns nullptr if no new loop was created and a pointer to the | |
| /// original loop OriginalBB was part of otherwise. | |
| const Loop* llvm::addClonedBlockToLoopInfo(BasicBlock *OriginalBB, | |
| BasicBlock *ClonedBB, LoopInfo *LI, | |
| NewLoopsMap &NewLoops) { | |
| // Figure out which loop New is in. | |
| const Loop *OldLoop = LI->getLoopFor(OriginalBB); | |
| assert(OldLoop && "Should (at least) be in the loop being unrolled!"); | |
| Loop *&NewLoop = NewLoops[OldLoop]; | |
| if (!NewLoop) { | |
| // Found a new sub-loop. | |
| assert(OriginalBB == OldLoop->getHeader() && | |
| "Header should be first in RPO"); | |
| NewLoop = LI->AllocateLoop(); | |
| Loop *NewLoopParent = NewLoops.lookup(OldLoop->getParentLoop()); | |
| if (NewLoopParent) | |
| NewLoopParent->addChildLoop(NewLoop); | |
| else | |
| LI->addTopLevelLoop(NewLoop); | |
| NewLoop->addBasicBlockToLoop(ClonedBB, *LI); | |
| return OldLoop; | |
| } else { | |
| NewLoop->addBasicBlockToLoop(ClonedBB, *LI); | |
| return nullptr; | |
| } | |
| } | |
| /// The function chooses which type of unroll (epilog or prolog) is more | |
| /// profitabale. | |
| /// Epilog unroll is more profitable when there is PHI that starts from | |
| /// constant. In this case epilog will leave PHI start from constant, | |
| /// but prolog will convert it to non-constant. | |
| /// | |
| /// loop: | |
| /// PN = PHI [I, Latch], [CI, PreHeader] | |
| /// I = foo(PN) | |
| /// ... | |
| /// | |
| /// Epilog unroll case. | |
| /// loop: | |
| /// PN = PHI [I2, Latch], [CI, PreHeader] | |
| /// I1 = foo(PN) | |
| /// I2 = foo(I1) | |
| /// ... | |
| /// Prolog unroll case. | |
| /// NewPN = PHI [PrologI, Prolog], [CI, PreHeader] | |
| /// loop: | |
| /// PN = PHI [I2, Latch], [NewPN, PreHeader] | |
| /// I1 = foo(PN) | |
| /// I2 = foo(I1) | |
| /// ... | |
| /// | |
| static bool isEpilogProfitable(Loop *L) { | |
| BasicBlock *PreHeader = L->getLoopPreheader(); | |
| BasicBlock *Header = L->getHeader(); | |
| assert(PreHeader && Header); | |
| for (const PHINode &PN : Header->phis()) { | |
| if (isa<ConstantInt>(PN.getIncomingValueForBlock(PreHeader))) | |
| return true; | |
| } | |
| return false; | |
| } | |
| struct LoadValue { | |
| Instruction *DefI = nullptr; | |
| unsigned Generation = 0; | |
| LoadValue() = default; | |
| LoadValue(Instruction *Inst, unsigned Generation) | |
| : DefI(Inst), Generation(Generation) {} | |
| }; | |
| class StackNode { | |
| ScopedHashTable<const SCEV *, LoadValue>::ScopeTy LoadScope; | |
| unsigned CurrentGeneration; | |
| unsigned ChildGeneration; | |
| DomTreeNode *Node; | |
| DomTreeNode::const_iterator ChildIter; | |
| DomTreeNode::const_iterator EndIter; | |
| bool Processed = false; | |
| public: | |
| StackNode(ScopedHashTable<const SCEV *, LoadValue> &AvailableLoads, | |
| unsigned cg, DomTreeNode *N, DomTreeNode::const_iterator Child, | |
| DomTreeNode::const_iterator End) | |
| : LoadScope(AvailableLoads), CurrentGeneration(cg), ChildGeneration(cg), | |
| Node(N), ChildIter(Child), EndIter(End) {} | |
| // Accessors. | |
| unsigned currentGeneration() const { return CurrentGeneration; } | |
| unsigned childGeneration() const { return ChildGeneration; } | |
| void childGeneration(unsigned generation) { ChildGeneration = generation; } | |
| DomTreeNode *node() { return Node; } | |
| DomTreeNode::const_iterator childIter() const { return ChildIter; } | |
| DomTreeNode *nextChild() { | |
| DomTreeNode *Child = *ChildIter; | |
| ++ChildIter; | |
| return Child; | |
| } | |
| DomTreeNode::const_iterator end() const { return EndIter; } | |
| bool isProcessed() const { return Processed; } | |
| void process() { Processed = true; } | |
| }; | |
| Value *getMatchingValue(LoadValue LV, LoadInst *LI, unsigned CurrentGeneration, | |
| BatchAAResults &BAA, | |
| function_ref<MemorySSA *()> GetMSSA) { | |
| if (!LV.DefI) | |
| return nullptr; | |
| if (LV.DefI->getType() != LI->getType()) | |
| return nullptr; | |
| if (LV.Generation != CurrentGeneration) { | |
| MemorySSA *MSSA = GetMSSA(); | |
| if (!MSSA) | |
| return nullptr; | |
| auto *EarlierMA = MSSA->getMemoryAccess(LV.DefI); | |
| MemoryAccess *LaterDef = | |
| MSSA->getWalker()->getClobberingMemoryAccess(LI, BAA); | |
| if (!MSSA->dominates(LaterDef, EarlierMA)) | |
| return nullptr; | |
| } | |
| return LV.DefI; | |
| } | |
| void loadCSE(Loop *L, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI, | |
| BatchAAResults &BAA, function_ref<MemorySSA *()> GetMSSA) { | |
| ScopedHashTable<const SCEV *, LoadValue> AvailableLoads; | |
| SmallVector<std::unique_ptr<StackNode>> NodesToProcess; | |
| DomTreeNode *HeaderD = DT.getNode(L->getHeader()); | |
| NodesToProcess.emplace_back(new StackNode(AvailableLoads, 0, HeaderD, | |
| HeaderD->begin(), HeaderD->end())); | |
| unsigned CurrentGeneration = 0; | |
| while (!NodesToProcess.empty()) { | |
| StackNode *NodeToProcess = &*NodesToProcess.back(); | |
| CurrentGeneration = NodeToProcess->currentGeneration(); | |
| if (!NodeToProcess->isProcessed()) { | |
| // Process the node. | |
| // If this block has a single predecessor, then the predecessor is the | |
| // parent | |
| // of the domtree node and all of the live out memory values are still | |
| // current in this block. If this block has multiple predecessors, then | |
| // they could have invalidated the live-out memory values of our parent | |
| // value. For now, just be conservative and invalidate memory if this | |
| // block has multiple predecessors. | |
| if (!NodeToProcess->node()->getBlock()->getSinglePredecessor()) | |
| ++CurrentGeneration; | |
| for (auto &I : make_early_inc_range(*NodeToProcess->node()->getBlock())) { | |
| auto *Load = dyn_cast<LoadInst>(&I); | |
| if (!Load || !Load->isSimple()) { | |
| if (I.mayWriteToMemory()) | |
| CurrentGeneration++; | |
| continue; | |
| } | |
| const SCEV *PtrSCEV = SE.getSCEV(Load->getPointerOperand()); | |
| LoadValue LV = AvailableLoads.lookup(PtrSCEV); | |
| if (Value *M = | |
| getMatchingValue(LV, Load, CurrentGeneration, BAA, GetMSSA)) { | |
| if (LI.replacementPreservesLCSSAForm(Load, M)) { | |
| Load->replaceAllUsesWith(M); | |
| Load->eraseFromParent(); | |
| } | |
| } else { | |
| AvailableLoads.insert(PtrSCEV, LoadValue(Load, CurrentGeneration)); | |
| } | |
| } | |
| NodeToProcess->childGeneration(CurrentGeneration); | |
| NodeToProcess->process(); | |
| } else if (NodeToProcess->childIter() != NodeToProcess->end()) { | |
| // Push the next child onto the stack. | |
| DomTreeNode *Child = NodeToProcess->nextChild(); | |
| if (!L->contains(Child->getBlock())) | |
| continue; | |
| NodesToProcess.emplace_back( | |
| new StackNode(AvailableLoads, NodeToProcess->childGeneration(), Child, | |
| Child->begin(), Child->end())); | |
| } else { | |
| // It has been processed, and there are no more children to process, | |
| // so delete it and pop it off the stack. | |
| NodesToProcess.pop_back(); | |
| } | |
| } | |
| } | |
| /// Perform some cleanup and simplifications on loops after unrolling. It is | |
| /// useful to simplify the IV's in the new loop, as well as do a quick | |
| /// simplify/dce pass of the instructions. | |
| void llvm::simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI, | |
| ScalarEvolution *SE, DominatorTree *DT, | |
| AssumptionCache *AC, | |
| const TargetTransformInfo *TTI, | |
| ArrayRef<BasicBlock *> Blocks, | |
| AAResults *AA) { | |
| using namespace llvm::PatternMatch; | |
| // Simplify any new induction variables in the partially unrolled loop. | |
| if (SE && SimplifyIVs) { | |
| SmallVector<WeakTrackingVH, 16> DeadInsts; | |
| simplifyLoopIVs(L, SE, DT, LI, TTI, DeadInsts); | |
| // Aggressively clean up dead instructions that simplifyLoopIVs already | |
| // identified. Any remaining should be cleaned up below. | |
| while (!DeadInsts.empty()) { | |
| Value *V = DeadInsts.pop_back_val(); | |
| if (Instruction *Inst = dyn_cast_or_null<Instruction>(V)) | |
| RecursivelyDeleteTriviallyDeadInstructions(Inst); | |
| } | |
| if (AA) { | |
| std::unique_ptr<MemorySSA> MSSA = nullptr; | |
| BatchAAResults BAA(*AA); | |
| loadCSE(L, *DT, *SE, *LI, BAA, [L, AA, DT, &MSSA]() -> MemorySSA * { | |
| if (!MSSA) | |
| MSSA.reset(new MemorySSA(*L, AA, DT)); | |
| return &*MSSA; | |
| }); | |
| } | |
| } | |
| // At this point, the code is well formed. Perform constprop, instsimplify, | |
| // and dce. | |
| SmallVector<WeakTrackingVH, 16> DeadInsts; | |
| for (BasicBlock *BB : Blocks) { | |
| // Remove repeated debug instructions after loop unrolling. | |
| if (BB->getParent()->getSubprogram()) | |
| RemoveRedundantDbgInstrs(BB); | |
| for (Instruction &Inst : llvm::make_early_inc_range(*BB)) { | |
| if (Value *V = simplifyInstruction( | |
| &Inst, {BB->getDataLayout(), nullptr, DT, AC})) | |
| if (LI->replacementPreservesLCSSAForm(&Inst, V)) | |
| Inst.replaceAllUsesWith(V); | |
| if (isInstructionTriviallyDead(&Inst)) | |
| DeadInsts.emplace_back(&Inst); | |
| // Fold ((add X, C1), C2) to (add X, C1+C2). This is very common in | |
| // unrolled loops, and handling this early allows following code to | |
| // identify the IV as a "simple recurrence" without first folding away | |
| // a long chain of adds. | |
| { | |
| Value *X; | |
| const APInt *C1, *C2; | |
| if (match(&Inst, m_Add(m_Add(m_Value(X), m_APInt(C1)), m_APInt(C2)))) { | |
| auto *InnerI = dyn_cast<Instruction>(Inst.getOperand(0)); | |
| auto *InnerOBO = cast<OverflowingBinaryOperator>(Inst.getOperand(0)); | |
| bool SignedOverflow; | |
| APInt NewC = C1->sadd_ov(*C2, SignedOverflow); | |
| Inst.setOperand(0, X); | |
| Inst.setOperand(1, ConstantInt::get(Inst.getType(), NewC)); | |
| Inst.setHasNoUnsignedWrap(Inst.hasNoUnsignedWrap() && | |
| InnerOBO->hasNoUnsignedWrap()); | |
| Inst.setHasNoSignedWrap(Inst.hasNoSignedWrap() && | |
| InnerOBO->hasNoSignedWrap() && | |
| !SignedOverflow); | |
| if (InnerI && isInstructionTriviallyDead(InnerI)) | |
| DeadInsts.emplace_back(InnerI); | |
| } | |
| } | |
| } | |
| // We can't do recursive deletion until we're done iterating, as we might | |
| // have a phi which (potentially indirectly) uses instructions later in | |
| // the block we're iterating through. | |
| RecursivelyDeleteTriviallyDeadInstructions(DeadInsts); | |
| } | |
| } | |
| // If LoopUnroll has proven OriginalLoopProb is incorrect for some iterations | |
| // of the original loop, adjust latch probabilities in the unrolled loop to | |
| // maintain the original total frequency of the original loop body. | |
| // | |
| // OriginalLoopProb is practical but imprecise | |
| // ------------------------------------------- | |
| // | |
| // The latch branch weights that LLVM originally adds to a loop encode one latch | |
| // probability, OriginalLoopProb, applied uniformly across the loop's infinite | |
| // set of theoretically possible iterations. While this uniform latch | |
| // probability serves as a practical statistic summarizing the trip counts | |
| // observed during profiling, it is imprecise. Specifically, unless it is zero, | |
| // it is impossible for it to be the actual probability observed at every | |
| // individual iteration. To see why, consider that the only way to actually | |
| // observe at run time that the latch probability remains non-zero is to profile | |
| // at least one loop execution that has an infinite number of iterations. I do | |
| // not know how to profile an infinite number of loop iterations, and most loops | |
| // I work with are always finite. | |
| // | |
| // LoopUnroll proves OriginalLoopProb is incorrect | |
| // ------------------------------------------------ | |
| // | |
| // LoopUnroll reorganizes the original loop so that loop iterations are no | |
| // longer all implemented by the same code, and then it analyzes some of those | |
| // loop iteration implementations independently of others. In particular, it | |
| // converts some of their conditional latches to unconditional. That is, by | |
| // examining code structure without any profile data, LoopUnroll proves that the | |
| // actual latch probability at the end of such an iteration is either 1 or 0. | |
| // When an individual iteration's actual latch probability is 1 or 0, that means | |
| // it always behaves the same, so it is impossible to observe it as having any | |
| // other probability. The original uniform latch probability is rarely 1 or 0 | |
| // because, when applied to all possible iterations, that would yield an | |
| // estimated trip count of infinity or 1, respectively. | |
| // | |
| // Thus, the new probabilities of 1 or 0 are proven corrections to | |
| // OriginalLoopProb for individual iterations in the original loop. However, | |
| // LoopUnroll often is able to perform these corrections for only some | |
| // iterations, leaving other iterations with OriginalLoopProb, and thus | |
| // corrupting the aggregate effect on the total frequency of the original loop | |
| // body. | |
| // | |
| // Adjusting latch probabilities | |
| // ----------------------------- | |
| // | |
| // This function ensures that the total frequency of the original loop body, | |
| // summed across all its occurrences in the unrolled loop after the | |
| // aforementioned latch conversions, is the same as in the original loop. To do | |
| // so, it adjusts probabilities on the remaining conditional latches. However, | |
| // it cannot derive the new probabilities directly from the original uniform | |
| // latch probability because the latter has been proven incorrect for some | |
| // original loop iterations. | |
| // | |
| // There are often many sets of latch probabilities that can produce the | |
| // original total loop body frequency. If there are many remaining conditional | |
| // latches and !UnrollUniformWeights, this function just quickly hacks a few of | |
| // their probabilities to restore the original total loop body frequency. | |
| // Otherwise, it tries harder to determine less arbitrary probabilities. | |
| static void fixProbContradiction(Loop *L, UnrollLoopOptions ULO, | |
| OptimizationRemarkEmitter *ORE, | |
| BranchProbability OriginalLoopProb, | |
| bool CompletelyUnroll, | |
| std::vector<unsigned> &IterCounts, | |
| const std::vector<BasicBlock *> &CondLatches, | |
| std::vector<BasicBlock *> &CondLatchNexts) { | |
| // Runtime unrolling is handled later in LoopUnroll not here. | |
| // | |
| // There are two scenarios in which LoopUnroll sets ProbUpdateRequired to true | |
| // because it needs to update probabilities that were originally | |
| // OriginalLoopProb, but only in one scenario has LoopUnroll proven | |
| // OriginalLoopProb incorrect for iterations within the original loop: | |
| // - If ULO.Runtime, LoopUnroll adds new guards that enforce new reaching | |
| // conditions for new loop iteration implementations (e.g., one unrolled | |
| // loop iteration executes only if at least ULO.Count original loop | |
| // iterations remain). Those reaching conditions dictate how conditional | |
| // latches can be converted to unconditional (e.g., within an unrolled loop | |
| // iteration, there is no need to recheck the number of remaining original | |
| // loop iterations). None of this reorganization alters the set of possible | |
| // original loop iteration counts or proves OriginalLoopProb incorrect for | |
| // any of the original loop iterations. Thus, LoopUnroll derives | |
| // probabilities for the new guards and latches directly from | |
| // OriginalLoopProb based on the probabilities that their reaching | |
| // conditions would occur in the original loop. Doing so maintains the | |
| // total frequency of the original loop body. | |
| // - If !ULO.Runtime, LoopUnroll initially adds new loop iteration | |
| // implementations, which have the same latch probabilities as in the | |
| // original loop because there are no new guards that change their reaching | |
| // conditions. Sometimes, LoopUnroll is then done, and so does not set | |
| // ProbUpdateRequired to true. Other times, LoopUnroll then proves that | |
| // some latches are unconditional, directly contradicting OriginalLoopProb | |
| // for the corresponding original loop iterations. That reduces the set of | |
| // possible original loop iteration counts, possibly producing a finite set | |
| // if it manages to eliminate the backedge. LoopUnroll has to choose a new | |
| // set of latch probabilities that produce the same total loop body | |
| // frequency. | |
| // | |
| // This function addresses the second scenario only. | |
| if (ULO.Runtime) | |
| return; | |
| // If CondLatches.empty(), there are no latch branches with probabilities we | |
| // can adjust. That should mean that the actual trip count is always exactly | |
| // the number of remaining unrolled iterations, and so OriginalLoopProb should | |
| // have yielded that trip count as the original loop body frequency. Of | |
| // course, OriginalLoopProb could be based on inaccurate profile data, but | |
| // there is nothing we can do about that here. | |
| if (CondLatches.empty()) | |
| return; | |
| // If the original latch probability is 1, the original frequency is infinity. | |
| // Leaving all remaining probabilities set to 1 might or might not get us | |
| // there (e.g., a completely unrolled loop cannot be infinite), but it is the | |
| // closest we can come. | |
| assert(!OriginalLoopProb.isUnknown() && | |
| "Expected to have loop probability to fix"); | |
| if (OriginalLoopProb.isOne()) | |
| return; | |
| // FreqDesired is the frequency implied by the original loop probability. | |
| double FreqDesired = 1 / (1 - OriginalLoopProb.toDouble()); | |
| // Get the probability at CondLatches[I]. | |
| auto GetProb = [&](unsigned I) { | |
| CondBrInst *B = cast<CondBrInst>(CondLatches[I]->getTerminator()); | |
| bool FirstTargetIsNext = B->getSuccessor(0) == CondLatchNexts[I]; | |
| return getBranchProbability(B, FirstTargetIsNext).toDouble(); | |
| }; | |
| // Set the probability at CondLatches[I] to Prob. | |
| auto SetProb = [&](unsigned I, double Prob) { | |
| CondBrInst *B = cast<CondBrInst>(CondLatches[I]->getTerminator()); | |
| bool FirstTargetIsNext = B->getSuccessor(0) == CondLatchNexts[I]; | |
| setBranchProbability(B, BranchProbability::getBranchProbability(Prob), | |
| FirstTargetIsNext); | |
| }; | |
| // Set all probabilities in CondLatches to Prob. | |
| auto SetAllProbs = [&](double Prob) { | |
| for (unsigned I = 0, E = CondLatches.size(); I < E; ++I) | |
| SetProb(I, Prob); | |
| }; | |
| // If UnrollUniformWeights or n <= 2, we choose the simplest probability model | |
| // we can think of: every remaining conditional branch instruction has the | |
| // same probability, Prob, of continuing to the next iteration. This model | |
| // has several helpful properties: | |
| // - There is only one search parameter, Prob. | |
| // - We have no reason to think one latch branch's probability should be | |
| // higher or lower than another, and so this model makes them all the same. | |
| // In the worst cases, we thus avoid setting just some probabilities to 0 or | |
| // 1, which can unrealistically make some code appear unreachable. There | |
| // are cases where they *all* must become 0 or 1 to achieve the total | |
| // frequency of original loop body, and our model does permit that. | |
| // - The frequency, FreqOne, of the original loop body in a single iteration | |
| // of the unrolled loop is computed by a simple polynomial, where p=Prob, | |
| // n=CondLatches.size(), and c_i=IterCounts[i]: | |
| // | |
| // FreqOne = Sum(i=0..n)(c_i * p^i) | |
| // | |
| // - If the backedge has been eliminated: | |
| // - FreqOne is the total frequency of the original loop body in the | |
| // unrolled loop. | |
| // - If Prob == 1, the total frequency of the original loop body is exactly | |
| // the number of remaining loop iterations, as expected because every | |
| // remaining loop iteration always then executes. | |
| // - If the backedge remains: | |
| // - Sum(i=0..inf)(FreqOne * p^(n*i)) = FreqOne / (1 - p^n) is the total | |
| // frequency of the original loop body in the unrolled loop, regardless of | |
| // whether the backedge is conditional or unconditional. | |
| // - As Prob approaches 1, the total frequency of the original loop body | |
| // approaches infinity, as expected because the loop approaches never | |
| // exiting. | |
| // - For n <= 2, we can use simple formulas to solve the above polynomial | |
| // equations exactly for p without performing a search. | |
| // - For n > 2, evaluating each point in the search space, using ComputeFreq | |
| // below, requires about as few instructions as we could hope for. That is, | |
| // the probability is constant across the conditional branches, so the only | |
| // computation is across conditional branches and any backedge, as required | |
| // for any model for Prob. | |
| // - Prob == 1 produces the maximum possible total frequency for the original | |
| // loop body, as described above. Prob == 0 produces the minimum, 0. | |
| // Increasing or decreasing Prob monotonically increases or decreases the | |
| // frequency, respectively. Thus, for every possible frequency, there | |
| // exists some Prob that can produce it, and we can easily use bisection to | |
| // search the problem space. | |
| // When iterating for a solution, we stop early if we find probabilities | |
| // that produce a Freq whose relative difference from FreqDesired is small | |
| // (FreqPrec). Otherwise, we expect to compute a solution at least that | |
| // accurate (but surely far more accurate). | |
| const double FreqPrec = 1e-6; | |
| // Compute the new frequency produced by using Prob throughout CondLatches. | |
| auto ComputeFreq = [&](double Prob) { | |
| double ProbReaching = 1; // p^0 | |
| double FreqOne = IterCounts[0]; // c_0*p^0 | |
| for (unsigned I = 0, E = CondLatches.size(); I < E; ++I) { | |
| ProbReaching *= Prob; // p^(I+1) | |
| FreqOne += IterCounts[I + 1] * ProbReaching; // c_(I+1)*p^(I+1) | |
| } | |
| double ProbReachingBackedge = CompletelyUnroll ? 0 : ProbReaching; | |
| assert(FreqOne > 0 && "Expected at least one iteration before first latch"); | |
| if (ProbReachingBackedge == 1) | |
| return std::numeric_limits<double>::infinity(); | |
| return FreqOne / (1 - ProbReachingBackedge); | |
| }; | |
| // Compute the probability that, used at CondLaches[0] where | |
| // CondLatches.size() == 1, gets as close as possible to FreqDesired. | |
| auto ComputeProbForLinear = [&]() { | |
| // The polynomial is linear (0 = A*p + B), so just solve it. | |
| double A = IterCounts[1] + (CompletelyUnroll ? 0 : FreqDesired); | |
| double B = IterCounts[0] - FreqDesired; | |
| assert(A > 0 && "Expected iterations after last conditional latch"); | |
| double Prob = -B / A; | |
| // If it computes an invalid Prob, FreqDesired is impossibly low or high. | |
| // Otherwise, Prob should produce nearly FreqDesired. | |
| assert((Prob < 0 || Prob > 1 || | |
| fabs(ComputeFreq(Prob) - FreqDesired) / FreqDesired < FreqPrec) && | |
| "Expected accurate frequency when linear case is possible"); | |
| Prob = std::max(Prob, 0.); | |
| Prob = std::min(Prob, 1.); | |
| return Prob; | |
| }; | |
| // Compute the probability that, used throughout CondLatches where | |
| // CondLatches.size() == 2, gets as close as possible to FreqDesired. | |
| auto ComputeProbForQuadratic = [&]() { | |
| // The polynomial is quadratic (0 = A*p^2 + B*p + C), so just solve it. | |
| double A = IterCounts[2] + (CompletelyUnroll ? 0 : FreqDesired); | |
| double B = IterCounts[1]; | |
| double C = IterCounts[0] - FreqDesired; | |
| assert(A > 0 && "Expected iterations after last conditional latch"); | |
| double Prob = (-B + sqrt(B * B - 4 * A * C)) / (2 * A); | |
| // If it computes an invalid Prob, FreqDesired is impossibly low or high. | |
| // Otherwise, Prob should produce nearly FreqDesired. | |
| assert((Prob < 0 || Prob > 1 || | |
| fabs(ComputeFreq(Prob) - FreqDesired) / FreqDesired < FreqPrec) && | |
| "Expected accurate frequency when quadratic case is possible"); | |
| Prob = std::max(Prob, 0.); | |
| Prob = std::min(Prob, 1.); | |
| return Prob; | |
| }; | |
| // Adjust the probability at CondLatches[ComputeIdx] to get as close as | |
| // possible to FreqDesired without replacing probabilities elsewhere in | |
| // CondLatches. Return the new total frequency. | |
| // | |
| // Given a CondLatches index I, then for a single unrolled loop iteration: | |
| // - ProbBefore or ProbAfter is the probability that control flow can pass | |
| // through every CondLatches[J] for J < I or J > I, respectively. | |
| // - FreqBefore or FreqAfter is the total frequency accumulated before or | |
| // after CondLatches[I], respectively, while the probability at | |
| // CondLatches[I] is treated as 1. | |
| // | |
| // If ComputeIdx == 0, then ComputeProb will set those values for I == 0 and | |
| // ignore the current values. If ComputeIdx > 0, then it expects those values | |
| // to already be set for I == ComputeIdx - 1, and it will set them for I == | |
| // ComputeIdx. | |
| auto AdjustProb = [&](unsigned ComputeIdx, double &ProbBefore, | |
| double &ProbAfter, double &FreqBefore, | |
| double &FreqAfter) { | |
| assert(ComputeIdx < CondLatches.size() && | |
| "Expected valid CondLatches index"); | |
| // Compute or update ProbBefore, ProbAfter, FreqBefore, and FreqAfter. | |
| auto ComputeAfter = [&]() { | |
| ProbAfter = 1; | |
| FreqAfter = IterCounts[ComputeIdx + 1]; | |
| for (unsigned I = ComputeIdx + 1, E = CondLatches.size(); I < E; ++I) { | |
| double Prob = GetProb(I); | |
| ProbAfter *= Prob; | |
| // After Prob == 0, ProbAfter and FreqAfter won't change, so save time. | |
| if (Prob == 0) | |
| break; | |
| FreqAfter += IterCounts[I + 1] * ProbAfter; | |
| } | |
| }; | |
| if (ComputeIdx == 0) { | |
| ProbBefore = 1; | |
| FreqBefore = IterCounts[0]; | |
| ComputeAfter(); | |
| } else { | |
| // Rather than iterating all of CondLatches again, we fix up the | |
| // previously computed values. | |
| double ProbOld = GetProb(ComputeIdx); | |
| if (ProbOld > 0) { | |
| FreqAfter -= IterCounts[ComputeIdx] * ProbBefore; | |
| ProbAfter /= ProbOld; | |
| FreqAfter /= ProbOld; | |
| } else { | |
| // We cannot divide out the old zero probability. We short-circuited | |
| // the iteration at that zero in the previous ComputeAfter call, so now | |
| // we pick up where we left off. | |
| ComputeAfter(); | |
| } | |
| ProbBefore *= GetProb(ComputeIdx - 1); | |
| FreqBefore += IterCounts[ComputeIdx] * ProbBefore; | |
| } | |
| // Compute the required probability, and limit it to a valid probability (0 | |
| // <= p <= 1). See the FreqCompute formula below for how to derive the | |
| // ProbCompute formula. | |
| double ProbReachingBackedge = CompletelyUnroll ? 0 : ProbBefore * ProbAfter; | |
| double ProbComputeNumerator = FreqDesired - FreqBefore; | |
| double ProbComputeDenominator = | |
| FreqAfter + FreqDesired * ProbReachingBackedge; | |
| double ProbCompute = -1; // Init expected to be unused. | |
| if (ProbComputeNumerator <= 0) { | |
| // FreqBefore has already reached or surpassed FreqDesired, so add no more | |
| // frequency. It is possible that ProbComputeDenominator == 0 here | |
| // because some latch probability (maybe the original) was set to zero, so | |
| // this check avoids setting ProbCompute=1 (in the else if below) and | |
| // division by zero where the numerator <= 0 (in the else below). | |
| ProbCompute = 0; | |
| } else if (ProbComputeDenominator == 0) { | |
| // Analytically, this case seems impossible. It would occur if either: | |
| // - Both FreqAfter and FreqDesired are zero. But the latter would cause | |
| // ProbComputeNumerator < 0, which we catch above, and FreqDesired | |
| // should always be >= 1 anyway. | |
| // - There are no iterations after CondLatches[ComputeIdx], not even via | |
| // a backedge, so that both FreqAfter and ProbReachingBackedge are zero. | |
| // But iterations should exist after even the last conditional latch. | |
| // - Some latch probability (maybe the original) was set to zero so that | |
| // both FreqAfter and ProbReachingBackedge are zero. But that should | |
| // not have happened because, according to the above | |
| // ProbComputeNumerator check, we have not yet reached FreqDesired | |
| // (which, if the original latch probability is zero, is just 1 and thus | |
| // always reached or surpassed). | |
| // | |
| // Numerically, perhaps this case is possible. We interpret it to mean we | |
| // need more frequency (ProbComputeNumerator > 0) but have no way to get | |
| // any (ProbComputeDenominator is analytically too small to distinguish it | |
| // from 0 in floating point), suggesting infinite probability is needed, | |
| // but 1 is the maximum valid probability and thus the best we can do. | |
| // | |
| // TODO: Cover this case in the test suite if you can. | |
| ProbCompute = 1; | |
| } else { | |
| ProbCompute = ProbComputeNumerator / ProbComputeDenominator; | |
| ProbCompute = std::max(ProbCompute, 0.); | |
| ProbCompute = std::min(ProbCompute, 1.); | |
| } | |
| SetProb(ComputeIdx, ProbCompute); | |
| // Compute the resulting total frequency. | |
| double FreqCompute = -1; // Init expected to be unused. | |
| if (ProbReachingBackedge * ProbCompute == 1) { | |
| // Analytically, this case seems impossible. It requires that there is a | |
| // backedge and that FreqDesired == infinity so that every conditional | |
| // latch's probability had to be set to 1. But FreqDesired == infinity | |
| // means OriginalLoopProb.isOne(), which we guarded against earlier. | |
| // | |
| // Numerically, perhaps this case is possible. We interpret it to mean | |
| // that analytically the probability has to be so near 1 that, in floating | |
| // point, the frequency is computed as infinite. | |
| // | |
| // TODO: Cover this case in the test suite if you can. | |
| FreqCompute = std::numeric_limits<double>::infinity(); | |
| if (ORE) { | |
| ORE->emit([&]() { | |
| return OptimizationRemark(DEBUG_TYPE, "InfiniteFrequency", | |
| L->getStartLoc(), L->getHeader()); | |
| }); | |
| } | |
| } else { | |
| assert(FreqBefore > 0 && | |
| "Expected at least one iteration before first latch"); | |
| // In this equation, if we replace the left-hand side with FreqDesired and | |
| // then solve for ProbCompute, we get the ProbCompute formula above. | |
| FreqCompute = (FreqBefore + FreqAfter * ProbCompute) / | |
| (1 - ProbReachingBackedge * ProbCompute); | |
| } | |
| assert(FreqCompute > 0 && "Expected valid frequency"); | |
| return FreqCompute; | |
| }; | |
| // Determine and set branch weights. | |
| // | |
| // Prob < 0 and Prob > 1 cannot be represented as branch weights. We might | |
| // compute such a Prob if FreqDesired is impossible (e.g., due to inaccurate | |
| // profile data) for the maximum trip count we have determined when completely | |
| // unrolling. In that case, so just go with whichever is closest. | |
| if (CondLatches.size() == 1) { | |
| SetAllProbs(ComputeProbForLinear()); | |
| } else if (CondLatches.size() == 2) { | |
| SetAllProbs(ComputeProbForQuadratic()); | |
| } else if (!UnrollUniformWeights) { | |
| // The polynomial is too complex for a simple formula, and the quick and | |
| // dirty fix has been selected. Adjust probabilities starting from the | |
| // first latch, which has the most influence on the total frequency, so | |
| // starting there should minimize the number of latches that have to be | |
| // visited. We do have to iterate because the first latch alone might not | |
| // be enough. For example, we might need to set all probabilities to 1 if | |
| // the frequency is the unroll factor. | |
| double ProbBefore = -1, ProbAfter = -1; // Inits expected to be unused. | |
| double FreqBefore = -1, FreqAfter = -1; // Inits expected to be unused. | |
| for (unsigned I = 0; I != CondLatches.size(); ++I) { | |
| double Freq = AdjustProb(I, ProbBefore, ProbAfter, FreqBefore, FreqAfter); | |
| if (fabs(Freq - FreqDesired) / FreqDesired < FreqPrec) | |
| break; | |
| } | |
| } else { | |
| // The polynomial is too complex for a simple formula, and uniform branch | |
| // weights have been selected, so bisect. | |
| double ProbMin = -1, ProbMax = -1; // Inits expected to be unused. | |
| double ProbPrev = -1; // Inits expected to be unused. | |
| auto TryProb = [&](double Prob) { | |
| ProbPrev = Prob; | |
| double FreqDelta = ComputeFreq(Prob) - FreqDesired; | |
| if (fabs(FreqDelta) / FreqDesired < FreqPrec) | |
| return 0; | |
| if (FreqDelta < 0) { | |
| ProbMin = Prob; | |
| return -1; | |
| } | |
| ProbMax = Prob; | |
| return 1; | |
| }; | |
| // If Prob == 0 is too small and Prob == 1 is too large, bisect between | |
| // them. Accuracy (relative difference) is controlled by FreqPrec above. | |
| // However, to place a hard upper limit on the search time, we stop | |
| // bisecting when Prob stops changing (ProbDelta) by much (ProbPrec). In | |
| // this case, we compute an absolute difference not a relative difference, | |
| // which could produce more search time for smaller probabilities. | |
| if (TryProb(0.) < 0 && TryProb(1.) > 0) { | |
| assert(ProbMin == 0 && ProbMax == 1 && | |
| "expected probability bounds to be initialized"); | |
| const double ProbPrec = 1e-12; | |
| double Prob, ProbDelta; | |
| do { | |
| Prob = (ProbMin + ProbMax) / 2; | |
| ProbDelta = Prob - ProbPrev; | |
| } while (TryProb(Prob) != 0 && fabs(ProbDelta) > ProbPrec); | |
| } | |
| SetAllProbs(ProbPrev); | |
| } | |
| // FIXME: We have not considered non-latch loop exits: | |
| // - Their original probabilities are not considered in our calculation of | |
| // FreqDesired. | |
| // - Their probabilities are not considered in our probability model used to | |
| // determine new probabilities for remaining conditional branches. | |
| // - If they are conditional and LoopUnroll converts them to unconditional, | |
| // LoopUnroll has proven their original probabilities are incorrect for some | |
| // original loop iterations, but that does not cause ProbUpdateRequired to | |
| // be set to true. | |
| // | |
| // To adjust FreqDesired and our probability model correctly for a non-latch | |
| // loop exit, we would need to compute the original probability that the exit | |
| // is reached from the loop header (in contrast, we currently assume that | |
| // probability is 1 in the case of a latch exit) and the probability that the | |
| // exit is taken if it is conditional (use the branch's old or new weights for | |
| // FreqDesired or the probability model, respectively). Does computing the | |
| // reaching probability require a CFG traversal, or is there some existing | |
| // library that can do it? Prior discussions suggest some such libraries are | |
| // difficult to use within LoopUnroll: | |
| // <https://github.com/llvm/llvm-project/pull/164799#issuecomment-3438681519>. | |
| // For now, we just let our corrected probabilities be less accurate in that | |
| // scenario. Alternatively, we could refuse to correct probabilities at all | |
| // in that scenario, but that seems worse. | |
| } | |
| /// Unroll the given loop by Count. The loop must be in LCSSA form. Unrolling | |
| /// can only fail when the loop's latch block is not terminated by a conditional | |
| /// branch instruction. However, if the trip count (and multiple) are not known, | |
| /// loop unrolling will mostly produce more code that is no faster. | |
| /// | |
| /// If Runtime is true then UnrollLoop will try to insert a prologue or | |
| /// epilogue that ensures the latch has a trip multiple of Count. UnrollLoop | |
| /// will not runtime-unroll the loop if computing the run-time trip count will | |
| /// be expensive and AllowExpensiveTripCount is false. | |
| /// | |
| /// The LoopInfo Analysis that is passed will be kept consistent. | |
| /// | |
| /// This utility preserves LoopInfo. It will also preserve ScalarEvolution and | |
| /// DominatorTree if they are non-null. | |
| /// | |
| /// If RemainderLoop is non-null, it will receive the remainder loop (if | |
| /// required and not fully unrolled). | |
| LoopUnrollResult | |
| llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI, | |
| ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, | |
| const TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE, | |
| bool PreserveLCSSA, Loop **RemainderLoop, AAResults *AA) { | |
| assert(DT && "DomTree is required"); | |
| if (!L->getLoopPreheader()) { | |
| LLVM_DEBUG(dbgs() << " Can't unroll; loop preheader-insertion failed.\n"); | |
| return LoopUnrollResult::Unmodified; | |
| } | |
| if (!L->getLoopLatch()) { | |
| LLVM_DEBUG(dbgs() << " Can't unroll; loop exit-block-insertion failed.\n"); | |
| return LoopUnrollResult::Unmodified; | |
| } | |
| // Loops with indirectbr cannot be cloned. | |
| if (!L->isSafeToClone()) { | |
| LLVM_DEBUG(dbgs() << " Can't unroll; Loop body cannot be cloned.\n"); | |
| return LoopUnrollResult::Unmodified; | |
| } | |
| if (L->getHeader()->hasAddressTaken()) { | |
| // The loop-rotate pass can be helpful to avoid this in many cases. | |
| LLVM_DEBUG( | |
| dbgs() << " Won't unroll loop: address of header block is taken.\n"); | |
| return LoopUnrollResult::Unmodified; | |
| } | |
| assert(ULO.Count > 0); | |
| // All these values should be taken only after peeling because they might have | |
| // changed. | |
| BasicBlock *Preheader = L->getLoopPreheader(); | |
| BasicBlock *Header = L->getHeader(); | |
| BasicBlock *LatchBlock = L->getLoopLatch(); | |
| SmallVector<BasicBlock *, 4> ExitBlocks; | |
| L->getExitBlocks(ExitBlocks); | |
| std::vector<BasicBlock *> OriginalLoopBlocks = L->getBlocks(); | |
| const unsigned MaxTripCount = SE->getSmallConstantMaxTripCount(L); | |
| const bool MaxOrZero = SE->isBackedgeTakenCountMaxOrZero(L); | |
| std::optional<unsigned> OriginalTripCount = | |
| llvm::getLoopEstimatedTripCount(L); | |
| BranchProbability OriginalLoopProb = llvm::getLoopProbability(L); | |
| // Effectively "DCE" unrolled iterations that are beyond the max tripcount | |
| // and will never be executed. | |
| if (MaxTripCount && ULO.Count > MaxTripCount) | |
| ULO.Count = MaxTripCount; | |
| struct ExitInfo { | |
| unsigned TripCount; | |
| unsigned TripMultiple; | |
| unsigned BreakoutTrip; | |
| bool ExitOnTrue; | |
| BasicBlock *FirstExitingBlock = nullptr; | |
| SmallVector<BasicBlock *> ExitingBlocks; | |
| }; | |
| MapVector<BasicBlock *, ExitInfo> ExitInfos; | |
| SmallVector<BasicBlock *, 4> ExitingBlocks; | |
| L->getExitingBlocks(ExitingBlocks); | |
| for (auto *ExitingBlock : ExitingBlocks) { | |
| // The folding code is not prepared to deal with non-branch instructions | |
| // right now. | |
| auto *BI = dyn_cast<CondBrInst>(ExitingBlock->getTerminator()); | |
| if (!BI) | |
| continue; | |
| ExitInfo &Info = ExitInfos[ExitingBlock]; | |
| Info.TripCount = SE->getSmallConstantTripCount(L, ExitingBlock); | |
| Info.TripMultiple = SE->getSmallConstantTripMultiple(L, ExitingBlock); | |
| if (Info.TripCount != 0) { | |
| Info.BreakoutTrip = Info.TripCount % ULO.Count; | |
| Info.TripMultiple = 0; | |
| } else { | |
| Info.BreakoutTrip = Info.TripMultiple = | |
| (unsigned)std::gcd(ULO.Count, Info.TripMultiple); | |
| } | |
| Info.ExitOnTrue = !L->contains(BI->getSuccessor(0)); | |
| Info.ExitingBlocks.push_back(ExitingBlock); | |
| LLVM_DEBUG(dbgs() << " Exiting block %" << ExitingBlock->getName() | |
| << ": TripCount=" << Info.TripCount | |
| << ", TripMultiple=" << Info.TripMultiple | |
| << ", BreakoutTrip=" << Info.BreakoutTrip << "\n"); | |
| } | |
| // Are we eliminating the loop control altogether? Note that we can know | |
| // we're eliminating the backedge without knowing exactly which iteration | |
| // of the unrolled body exits. | |
| const bool CompletelyUnroll = ULO.Count == MaxTripCount; | |
| const bool PreserveOnlyFirst = CompletelyUnroll && MaxOrZero; | |
| // There's no point in performing runtime unrolling if this unroll count | |
| // results in a full unroll. | |
| if (CompletelyUnroll) | |
| ULO.Runtime = false; | |
| // Go through all exits of L and see if there are any phi-nodes there. We just | |
| // conservatively assume that they're inserted to preserve LCSSA form, which | |
| // means that complete unrolling might break this form. We need to either fix | |
| // it in-place after the transformation, or entirely rebuild LCSSA. TODO: For | |
| // now we just recompute LCSSA for the outer loop, but it should be possible | |
| // to fix it in-place. | |
| bool NeedToFixLCSSA = | |
| PreserveLCSSA && CompletelyUnroll && | |
| any_of(ExitBlocks, | |
| [](const BasicBlock *BB) { return isa<PHINode>(BB->begin()); }); | |
| // The current loop unroll pass can unroll loops that have | |
| // (1) single latch; and | |
| // (2a) latch is unconditional; or | |
| // (2b) latch is conditional and is an exiting block | |
| // FIXME: The implementation can be extended to work with more complicated | |
| // cases, e.g. loops with multiple latches. | |
| Instruction *LatchTerm = LatchBlock->getTerminator(); | |
| // A conditional branch which exits the loop, which can be optimized to an | |
| // unconditional branch in the unrolled loop in some cases. | |
| bool LatchIsExiting = L->isLoopExiting(LatchBlock); | |
| if (!isa<UncondBrInst>(LatchTerm) && | |
| !(isa<CondBrInst>(LatchTerm) && LatchIsExiting)) { | |
| LLVM_DEBUG( | |
| dbgs() << "Can't unroll; a conditional latch must exit the loop"); | |
| return LoopUnrollResult::Unmodified; | |
| } | |
| bool EpilogProfitability = | |
| UnrollRuntimeEpilog.getNumOccurrences() ? UnrollRuntimeEpilog | |
| : isEpilogProfitable(L); | |
| if (ULO.Runtime && | |
| !UnrollRuntimeLoopRemainder( | |
| L, ULO.Count, ULO.AllowExpensiveTripCount, EpilogProfitability, | |
| ULO.UnrollRemainder, ULO.ForgetAllSCEV, LI, SE, DT, AC, TTI, | |
| PreserveLCSSA, ULO.SCEVExpansionBudget, ULO.RuntimeUnrollMultiExit, | |
| RemainderLoop, OriginalTripCount, OriginalLoopProb)) { | |
| if (ULO.Force) | |
| ULO.Runtime = false; | |
| else { | |
| LLVM_DEBUG(dbgs() << "Won't unroll; remainder loop could not be " | |
| "generated when assuming runtime trip count\n"); | |
| return LoopUnrollResult::Unmodified; | |
| } | |
| } | |
| using namespace ore; | |
| // Determine whether this loop originated from the vectorizer so we can | |
| // produce more informative remarks. | |
| StringRef LoopKind = getLoopVectorizeKindPrefix(L); | |
| // Report the unrolling decision. | |
| if (CompletelyUnroll) { | |
| LLVM_DEBUG(dbgs() << "COMPLETELY UNROLLING loop %" << Header->getName() | |
| << " with trip count " << ULO.Count << "!\n"); | |
| if (ORE) | |
| ORE->emit([&]() { | |
| return OptimizationRemark(DEBUG_TYPE, "FullyUnrolled", L->getStartLoc(), | |
| L->getHeader()) | |
| << "completely unrolled " + LoopKind.str() + "loop with " | |
| << NV("UnrollCount", ULO.Count) << " iterations"; | |
| }); | |
| } else { | |
| LLVM_DEBUG({ | |
| dbgs() << "UNROLLING loop %" << Header->getName() << " by " << ULO.Count; | |
| if (ULO.Runtime) { | |
| dbgs() << " with run-time trip count"; | |
| if (ULO.UnrollRemainder) | |
| dbgs() << " (remainder unrolled)"; | |
| } | |
| dbgs() << "!\n"; | |
| }); | |
| if (ORE) | |
| ORE->emit([&]() { | |
| OptimizationRemark Diag(DEBUG_TYPE, "PartialUnrolled", L->getStartLoc(), | |
| L->getHeader()); | |
| Diag << "unrolled " + LoopKind.str() + "loop by a factor of " | |
| << NV("UnrollCount", ULO.Count); | |
| if (ULO.Runtime) | |
| Diag << " with run-time trip count" | |
| << (ULO.UnrollRemainder ? " (remainder unrolled)" : ""); | |
| return Diag; | |
| }); | |
| } | |
| // We are going to make changes to this loop. SCEV may be keeping cached info | |
| // about it, in particular about backedge taken count. The changes we make | |
| // are guaranteed to invalidate this information for our loop. It is tempting | |
| // to only invalidate the loop being unrolled, but it is incorrect as long as | |
| // all exiting branches from all inner loops have impact on the outer loops, | |
| // and if something changes inside them then any of outer loops may also | |
| // change. When we forget outermost loop, we also forget all contained loops | |
| // and this is what we need here. | |
| if (SE) { | |
| if (ULO.ForgetAllSCEV) | |
| SE->forgetAllLoops(); | |
| else { | |
| SE->forgetTopmostLoop(L); | |
| SE->forgetBlockAndLoopDispositions(); | |
| } | |
| } | |
| if (!LatchIsExiting) | |
| ++NumUnrolledNotLatch; | |
| // For the first iteration of the loop, we should use the precloned values for | |
| // PHI nodes. Insert associations now. | |
| ValueToValueMapTy LastValueMap; | |
| std::vector<PHINode*> OrigPHINode; | |
| for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) { | |
| OrigPHINode.push_back(cast<PHINode>(I)); | |
| } | |
| // Collect phi nodes for reductions for which we can introduce multiple | |
| // parallel reduction phis and compute the final reduction result after the | |
| // loop. This requires a single exit block after unrolling. This is ensured by | |
| // restricting to single-block loops where the unrolled iterations are known | |
| // to not exit. | |
| DenseMap<PHINode *, RecurrenceDescriptor> Reductions; | |
| bool CanAddAdditionalAccumulators = | |
| (UnrollAddParallelReductions.getNumOccurrences() > 0 | |
| ? UnrollAddParallelReductions | |
| : ULO.AddAdditionalAccumulators) && | |
| !CompletelyUnroll && L->getNumBlocks() == 1 && | |
| (ULO.Runtime || | |
| (ExitInfos.contains(Header) && ((ExitInfos[Header].TripCount != 0 && | |
| ExitInfos[Header].BreakoutTrip == 0)))); | |
| // Limit parallelizing reductions to unroll counts of 4 or less for now. | |
| // TODO: The number of parallel reductions should depend on the number of | |
| // execution units. We also don't have to add a parallel reduction phi per | |
| // unrolled iteration, but could for example add a parallel phi for every 2 | |
| // unrolled iterations. | |
| if (CanAddAdditionalAccumulators && ULO.Count <= 4) { | |
| for (PHINode &Phi : Header->phis()) { | |
| auto RdxDesc = canParallelizeReductionWhenUnrolling(Phi, L, SE); | |
| if (!RdxDesc) | |
| continue; | |
| // Only handle duplicate phis for a single reduction for now. | |
| // TODO: Handle any number of reductions | |
| if (!Reductions.empty()) | |
| continue; | |
| Reductions[&Phi] = *RdxDesc; | |
| } | |
| } | |
| std::vector<BasicBlock *> Headers; | |
| std::vector<BasicBlock *> Latches; | |
| Headers.push_back(Header); | |
| Latches.push_back(LatchBlock); | |
| // The current on-the-fly SSA update requires blocks to be processed in | |
| // reverse postorder so that LastValueMap contains the correct value at each | |
| // exit. | |
| LoopBlocksDFS DFS(L); | |
| DFS.perform(LI); | |
| // Stash the DFS iterators before adding blocks to the loop. | |
| LoopBlocksDFS::RPOIterator BlockBegin = DFS.beginRPO(); | |
| LoopBlocksDFS::RPOIterator BlockEnd = DFS.endRPO(); | |
| std::vector<BasicBlock*> UnrolledLoopBlocks = L->getBlocks(); | |
| // Loop Unrolling might create new loops. While we do preserve LoopInfo, we | |
| // might break loop-simplified form for these loops (as they, e.g., would | |
| // share the same exit blocks). We'll keep track of loops for which we can | |
| // break this so that later we can re-simplify them. | |
| SmallSetVector<Loop *, 4> LoopsToSimplify; | |
| LoopsToSimplify.insert_range(*L); | |
| // When a FSDiscriminator is enabled, we don't need to add the multiply | |
| // factors to the discriminators. | |
| if (Header->getParent()->shouldEmitDebugInfoForProfiling() && | |
| !EnableFSDiscriminator) | |
| for (BasicBlock *BB : L->getBlocks()) | |
| for (Instruction &I : *BB) | |
| if (!I.isDebugOrPseudoInst()) | |
| if (const DILocation *DIL = I.getDebugLoc()) { | |
| auto NewDIL = DIL->cloneByMultiplyingDuplicationFactor(ULO.Count); | |
| if (NewDIL) | |
| I.setDebugLoc(*NewDIL); | |
| else | |
| LLVM_DEBUG(dbgs() | |
| << "Failed to create new discriminator: " | |
| << DIL->getFilename() << " Line: " << DIL->getLine()); | |
| } | |
| // Identify what noalias metadata is inside the loop: if it is inside the | |
| // loop, the associated metadata must be cloned for each iteration. | |
| SmallVector<MDNode *, 6> LoopLocalNoAliasDeclScopes; | |
| identifyNoAliasScopesToClone(L->getBlocks(), LoopLocalNoAliasDeclScopes); | |
| // We place the unrolled iterations immediately after the original loop | |
| // latch. This is a reasonable default placement if we don't have block | |
| // frequencies, and if we do, well the layout will be adjusted later. | |
| auto BlockInsertPt = std::next(LatchBlock->getIterator()); | |
| SmallVector<Instruction *> PartialReductions; | |
| for (unsigned It = 1; It != ULO.Count; ++It) { | |
| SmallVector<BasicBlock *, 8> NewBlocks; | |
| SmallDenseMap<const Loop *, Loop *, 4> NewLoops; | |
| NewLoops[L] = L; | |
| for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) { | |
| ValueToValueMapTy VMap; | |
| BasicBlock *New = CloneBasicBlock(*BB, VMap, "." + Twine(It)); | |
| Header->getParent()->insert(BlockInsertPt, New); | |
| assert((*BB != Header || LI->getLoopFor(*BB) == L) && | |
| "Header should not be in a sub-loop"); | |
| // Tell LI about New. | |
| const Loop *OldLoop = addClonedBlockToLoopInfo(*BB, New, LI, NewLoops); | |
| if (OldLoop) | |
| LoopsToSimplify.insert(NewLoops[OldLoop]); | |
| if (*BB == Header) { | |
| // Loop over all of the PHI nodes in the block, changing them to use | |
| // the incoming values from the previous block. | |
| for (PHINode *OrigPHI : OrigPHINode) { | |
| PHINode *NewPHI = cast<PHINode>(VMap[OrigPHI]); | |
| Value *InVal = NewPHI->getIncomingValueForBlock(LatchBlock); | |
| // Use cloned phis as parallel phis for partial reductions, which will | |
| // get combined to the final reduction result after the loop. | |
| if (Reductions.contains(OrigPHI)) { | |
| // Collect partial reduction results. | |
| if (PartialReductions.empty()) | |
| PartialReductions.push_back(cast<Instruction>(InVal)); | |
| PartialReductions.push_back(cast<Instruction>(VMap[InVal])); | |
| // Update the start value for the cloned phis to use the identity | |
| // value for the reduction. | |
| const RecurrenceDescriptor &RdxDesc = Reductions[OrigPHI]; | |
| NewPHI->setIncomingValueForBlock( | |
| L->getLoopPreheader(), | |
| getRecurrenceIdentity(RdxDesc.getRecurrenceKind(), | |
| OrigPHI->getType(), | |
| RdxDesc.getFastMathFlags())); | |
| // Update NewPHI to use the cloned value for the iteration and move | |
| // to header. | |
| NewPHI->replaceUsesOfWith(InVal, VMap[InVal]); | |
| NewPHI->moveBefore(OrigPHI->getIterator()); | |
| continue; | |
| } | |
| if (Instruction *InValI = dyn_cast<Instruction>(InVal)) | |
| if (It > 1 && L->contains(InValI)) | |
| InVal = LastValueMap[InValI]; | |
| VMap[OrigPHI] = InVal; | |
| NewPHI->eraseFromParent(); | |
| } | |
| // Eliminate copies of the loop heart intrinsic, if any. | |
| if (ULO.Heart) { | |
| auto it = VMap.find(ULO.Heart); | |
| assert(it != VMap.end()); | |
| Instruction *heartCopy = cast<Instruction>(it->second); | |
| heartCopy->eraseFromParent(); | |
| VMap.erase(it); | |
| } | |
| } | |
| // Remap source location atom instance. Do this now, rather than | |
| // when we remap instructions, because remap is called once we've | |
| // cloned all blocks (all the clones would get the same atom | |
| // number). | |
| if (!VMap.AtomMap.empty()) | |
| for (Instruction &I : *New) | |
| RemapSourceAtom(&I, VMap); | |
| // Update our running map of newest clones | |
| LastValueMap[*BB] = New; | |
| for (ValueToValueMapTy::iterator VI = VMap.begin(), VE = VMap.end(); | |
| VI != VE; ++VI) | |
| LastValueMap[VI->first] = VI->second; | |
| // Add phi entries for newly created values to all exit blocks. | |
| for (BasicBlock *Succ : successors(*BB)) { | |
| if (L->contains(Succ)) | |
| continue; | |
| for (PHINode &PHI : Succ->phis()) { | |
| Value *Incoming = PHI.getIncomingValueForBlock(*BB); | |
| ValueToValueMapTy::iterator It = LastValueMap.find(Incoming); | |
| if (It != LastValueMap.end()) | |
| Incoming = It->second; | |
| PHI.addIncoming(Incoming, New); | |
| SE->forgetLcssaPhiWithNewPredecessor(L, &PHI); | |
| } | |
| } | |
| // Keep track of new headers and latches as we create them, so that | |
| // we can insert the proper branches later. | |
| if (*BB == Header) | |
| Headers.push_back(New); | |
| if (*BB == LatchBlock) | |
| Latches.push_back(New); | |
| // Keep track of the exiting block and its successor block contained in | |
| // the loop for the current iteration. | |
| auto ExitInfoIt = ExitInfos.find(*BB); | |
| if (ExitInfoIt != ExitInfos.end()) | |
| ExitInfoIt->second.ExitingBlocks.push_back(New); | |
| NewBlocks.push_back(New); | |
| UnrolledLoopBlocks.push_back(New); | |
| // Update DomTree: since we just copy the loop body, and each copy has a | |
| // dedicated entry block (copy of the header block), this header's copy | |
| // dominates all copied blocks. That means, dominance relations in the | |
| // copied body are the same as in the original body. | |
| if (*BB == Header) | |
| DT->addNewBlock(New, Latches[It - 1]); | |
| else { | |
| auto BBDomNode = DT->getNode(*BB); | |
| auto BBIDom = BBDomNode->getIDom(); | |
| BasicBlock *OriginalBBIDom = BBIDom->getBlock(); | |
| DT->addNewBlock( | |
| New, cast<BasicBlock>(LastValueMap[cast<Value>(OriginalBBIDom)])); | |
| } | |
| } | |
| // Remap all instructions in the most recent iteration. | |
| // Key Instructions: Nothing to do - we've already remapped the atoms. | |
| remapInstructionsInBlocks(NewBlocks, LastValueMap); | |
| for (BasicBlock *NewBlock : NewBlocks) | |
| for (Instruction &I : *NewBlock) | |
| if (auto *II = dyn_cast<AssumeInst>(&I)) | |
| AC->registerAssumption(II); | |
| { | |
| // Identify what other metadata depends on the cloned version. After | |
| // cloning, replace the metadata with the corrected version for both | |
| // memory instructions and noalias intrinsics. | |
| std::string ext = (Twine("It") + Twine(It)).str(); | |
| cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, NewBlocks, | |
| Header->getContext(), ext); | |
| } | |
| } | |
| // Loop over the PHI nodes in the original block, setting incoming values. | |
| for (PHINode *PN : OrigPHINode) { | |
| if (CompletelyUnroll) { | |
| // The RAUW below disconnects the original PHI from its users. | |
| // Invalidate cached SCEVs while the def-use chain is still intact. | |
| if (SE) | |
| SE->forgetValue(PN); | |
| PN->replaceAllUsesWith(PN->getIncomingValueForBlock(Preheader)); | |
| PN->eraseFromParent(); | |
| } else if (ULO.Count > 1) { | |
| if (Reductions.contains(PN)) | |
| continue; | |
| Value *InVal = PN->removeIncomingValue(LatchBlock, false); | |
| // If this value was defined in the loop, take the value defined by the | |
| // last iteration of the loop. | |
| if (Instruction *InValI = dyn_cast<Instruction>(InVal)) { | |
| if (L->contains(InValI)) | |
| InVal = LastValueMap[InVal]; | |
| } | |
| assert(Latches.back() == LastValueMap[LatchBlock] && "bad last latch"); | |
| PN->addIncoming(InVal, Latches.back()); | |
| } | |
| } | |
| // Connect latches of the unrolled iterations to the headers of the next | |
| // iteration. Currently they point to the header of the same iteration. | |
| for (unsigned i = 0, e = Latches.size(); i != e; ++i) { | |
| unsigned j = (i + 1) % e; | |
| Latches[i]->getTerminator()->replaceSuccessorWith(Headers[i], Headers[j]); | |
| } | |
| // Remove loop metadata copied from the original loop latch to branches that | |
| // are no longer latches. | |
| for (unsigned I = 0, E = Latches.size() - (CompletelyUnroll ? 0 : 1); I < E; | |
| ++I) | |
| Latches[I]->getTerminator()->setMetadata(LLVMContext::MD_loop, nullptr); | |
| // Update dominators of blocks we might reach through exits. | |
| // Immediate dominator of such block might change, because we add more | |
| // routes which can lead to the exit: we can now reach it from the copied | |
| // iterations too. | |
| if (ULO.Count > 1) { | |
| for (auto *BB : OriginalLoopBlocks) { | |
| auto *BBDomNode = DT->getNode(BB); | |
| SmallVector<BasicBlock *, 16> ChildrenToUpdate; | |
| for (auto *ChildDomNode : BBDomNode->children()) { | |
| auto *ChildBB = ChildDomNode->getBlock(); | |
| if (!L->contains(ChildBB)) | |
| ChildrenToUpdate.push_back(ChildBB); | |
| } | |
| // The new idom of the block will be the nearest common dominator | |
| // of all copies of the previous idom. This is equivalent to the | |
| // nearest common dominator of the previous idom and the first latch, | |
| // which dominates all copies of the previous idom. | |
| BasicBlock *NewIDom = DT->findNearestCommonDominator(BB, LatchBlock); | |
| for (auto *ChildBB : ChildrenToUpdate) | |
| DT->changeImmediateDominator(ChildBB, NewIDom); | |
| } | |
| } | |
| assert(!UnrollVerifyDomtree || | |
| DT->verify(DominatorTree::VerificationLevel::Fast)); | |
| SmallVector<DominatorTree::UpdateType> DTUpdates; | |
| auto SetDest = [&](BasicBlock *Src, bool WillExit, bool ExitOnTrue) { | |
| auto *Term = cast<CondBrInst>(Src->getTerminator()); | |
| const unsigned Idx = ExitOnTrue ^ WillExit; | |
| BasicBlock *Dest = Term->getSuccessor(Idx); | |
| BasicBlock *DeadSucc = Term->getSuccessor(1-Idx); | |
| // Remove predecessors from all non-Dest successors. | |
| DeadSucc->removePredecessor(Src, /* KeepOneInputPHIs */ true); | |
| // Replace the conditional branch with an unconditional one. | |
| auto *BI = UncondBrInst::Create(Dest, Term->getIterator()); | |
| BI->setDebugLoc(Term->getDebugLoc()); | |
| Term->eraseFromParent(); | |
| DTUpdates.emplace_back(DominatorTree::Delete, Src, DeadSucc); | |
| }; | |
| auto WillExit = [&](const ExitInfo &Info, unsigned i, unsigned j, | |
| bool IsLatch) -> std::optional<bool> { | |
| if (CompletelyUnroll) { | |
| if (PreserveOnlyFirst) { | |
| if (i == 0) | |
| return std::nullopt; | |
| return j == 0; | |
| } | |
| // Complete (but possibly inexact) unrolling | |
| if (j == 0) | |
| return true; | |
| if (Info.TripCount && j != Info.TripCount) | |
| return false; | |
| return std::nullopt; | |
| } | |
| if (ULO.Runtime) { | |
| // If runtime unrolling inserts a prologue, information about non-latch | |
| // exits may be stale. | |
| if (IsLatch && j != 0) | |
| return false; | |
| return std::nullopt; | |
| } | |
| if (j != Info.BreakoutTrip && | |
| (Info.TripMultiple == 0 || j % Info.TripMultiple != 0)) { | |
| // If we know the trip count or a multiple of it, we can safely use an | |
| // unconditional branch for some iterations. | |
| return false; | |
| } | |
| return std::nullopt; | |
| }; | |
| // Fold branches for iterations where we know that they will exit or not | |
| // exit. In the case of an iteration's latch, if we thus find | |
| // *OriginalLoopProb is incorrect, set ProbUpdateRequired to true. | |
| bool ProbUpdateRequired = false; | |
| for (auto &Pair : ExitInfos) { | |
| ExitInfo &Info = Pair.second; | |
| for (unsigned i = 0, e = Info.ExitingBlocks.size(); i != e; ++i) { | |
| // The branch destination. | |
| unsigned j = (i + 1) % e; | |
| bool IsLatch = Pair.first == LatchBlock; | |
| std::optional<bool> KnownWillExit = WillExit(Info, i, j, IsLatch); | |
| if (!KnownWillExit) { | |
| if (!Info.FirstExitingBlock) | |
| Info.FirstExitingBlock = Info.ExitingBlocks[i]; | |
| continue; | |
| } | |
| // We don't fold known-exiting branches for non-latch exits here, | |
| // because this ensures that both all loop blocks and all exit blocks | |
| // remain reachable in the CFG. | |
| // TODO: We could fold these branches, but it would require much more | |
| // sophisticated updates to LoopInfo. | |
| if (*KnownWillExit && !IsLatch) { | |
| if (!Info.FirstExitingBlock) | |
| Info.FirstExitingBlock = Info.ExitingBlocks[i]; | |
| continue; | |
| } | |
| // For a latch, record any OriginalLoopProb contradiction. | |
| if (!OriginalLoopProb.isUnknown() && IsLatch) { | |
| BranchProbability ActualProb = *KnownWillExit | |
| ? BranchProbability::getZero() | |
| : BranchProbability::getOne(); | |
| ProbUpdateRequired |= OriginalLoopProb != ActualProb; | |
| } | |
| SetDest(Info.ExitingBlocks[i], *KnownWillExit, Info.ExitOnTrue); | |
| } | |
| } | |
| DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); | |
| DomTreeUpdater *DTUToUse = &DTU; | |
| if (ExitingBlocks.size() == 1 && ExitInfos.size() == 1) { | |
| // Manually update the DT if there's a single exiting node. In that case | |
| // there's a single exit node and it is sufficient to update the nodes | |
| // immediately dominated by the original exiting block. They will become | |
| // dominated by the first exiting block that leaves the loop after | |
| // unrolling. Note that the CFG inside the loop does not change, so there's | |
| // no need to update the DT inside the unrolled loop. | |
| DTUToUse = nullptr; | |
| auto &[OriginalExit, Info] = *ExitInfos.begin(); | |
| if (!Info.FirstExitingBlock) | |
| Info.FirstExitingBlock = Info.ExitingBlocks.back(); | |
| for (auto *C : to_vector(DT->getNode(OriginalExit)->children())) { | |
| if (L->contains(C->getBlock())) | |
| continue; | |
| C->setIDom(DT->getNode(Info.FirstExitingBlock)); | |
| } | |
| } else { | |
| DTU.applyUpdates(DTUpdates); | |
| } | |
| // When completely unrolling, the last latch becomes unreachable. | |
| if (!LatchIsExiting && CompletelyUnroll) { | |
| // There is no need to update the DT here, because there must be a unique | |
| // latch. Hence if the latch is not exiting it must directly branch back to | |
| // the original loop header and does not dominate any nodes. | |
| assert(LatchBlock->getSingleSuccessor() && "Loop with multiple latches?"); | |
| changeToUnreachable(Latches.back()->getTerminator(), PreserveLCSSA); | |
| } | |
| // After merging adjacent blocks in Latches below: | |
| // - CondLatches will list the blocks from Latches that are still terminated | |
| // with conditional branches. | |
| // - For 1 <= I < CondLatches.size(), IterCounts[I] will store the number of | |
| // the original loop iterations through which control flows from | |
| // CondLatches[I-1] to CondLatches[I]. | |
| // - For I == 0 or I == CondLatches.size(), IterCounts[I] will store the | |
| // number of the original loop iterations through which control can flow | |
| // before CondLatches.front() or after CondLatches.back(), respectively, | |
| // without taking the unrolled loop's backedge, if any. | |
| // - CondLatchNexts[I] will store the CondLatches[I] branch target for the | |
| // next of the original loop's iterations (as opposed to the exit target). | |
| assert(ULO.Count == Latches.size() && | |
| "Expected one latch block per unrolled iteration"); | |
| std::vector<unsigned> IterCounts(1, 0); | |
| std::vector<BasicBlock *> CondLatches; | |
| std::vector<BasicBlock *> CondLatchNexts; | |
| IterCounts.reserve(Latches.size() + 1); | |
| CondLatches.reserve(Latches.size()); | |
| CondLatchNexts.reserve(Latches.size()); | |
| // Merge adjacent basic blocks, if possible. | |
| for (auto [I, Latch] : enumerate(Latches)) { | |
| ++IterCounts.back(); | |
| assert((isa<UncondBrInst, CondBrInst>(Latch->getTerminator()) || | |
| (CompletelyUnroll && !LatchIsExiting && Latch == Latches.back())) && | |
| "Need a branch as terminator, except when fully unrolling with " | |
| "unconditional latch"); | |
| if (auto *Term = dyn_cast<UncondBrInst>(Latch->getTerminator())) { | |
| BasicBlock *Dest = Term->getSuccessor(); | |
| BasicBlock *Fold = Dest->getUniquePredecessor(); | |
| if (MergeBlockIntoPredecessor(Dest, /*DTU=*/DTUToUse, LI, | |
| /*MSSAU=*/nullptr, /*MemDep=*/nullptr, | |
| /*PredecessorWithTwoSuccessors=*/false, | |
| DTUToUse ? nullptr : DT)) { | |
| // Dest has been folded into Fold. Update our worklists accordingly. | |
| llvm::replace(Latches, Dest, Fold); | |
| llvm::erase(UnrolledLoopBlocks, Dest); | |
| } | |
| } else if (isa<CondBrInst>(Latch->getTerminator())) { | |
| IterCounts.push_back(0); | |
| CondLatches.push_back(Latch); | |
| CondLatchNexts.push_back(Headers[(I + 1) % Latches.size()]); | |
| } | |
| } | |
| // Fix probabilities we contradicted above. | |
| if (ProbUpdateRequired) { | |
| fixProbContradiction(L, ULO, ORE, OriginalLoopProb, CompletelyUnroll, | |
| IterCounts, CondLatches, CondLatchNexts); | |
| } | |
| // If there are partial reductions, create code in the exit block to compute | |
| // the final result and update users of the final result. | |
| if (!PartialReductions.empty()) { | |
| BasicBlock *ExitBlock = L->getExitBlock(); | |
| assert(ExitBlock && | |
| "Can only introduce parallel reduction phis with single exit block"); | |
| assert(Reductions.size() == 1 && | |
| "currently only a single reduction is supported"); | |
| Value *FinalRdxValue = PartialReductions.back(); | |
| Value *RdxResult = nullptr; | |
| for (PHINode &Phi : ExitBlock->phis()) { | |
| if (Phi.getIncomingValueForBlock(L->getLoopLatch()) != FinalRdxValue) | |
| continue; | |
| if (!RdxResult) { | |
| RdxResult = PartialReductions.front(); | |
| IRBuilder Builder(ExitBlock, ExitBlock->getFirstNonPHIIt()); | |
| Builder.setFastMathFlags(Reductions.begin()->second.getFastMathFlags()); | |
| RecurKind RK = Reductions.begin()->second.getRecurrenceKind(); | |
| for (Instruction *RdxPart : drop_begin(PartialReductions)) { | |
| if (RecurrenceDescriptor::isMinMaxRecurrenceKind(RK)) | |
| RdxResult = createMinMaxOp(Builder, RK, RdxResult, RdxPart); | |
| else | |
| RdxResult = Builder.CreateBinOp( | |
| (Instruction::BinaryOps)RecurrenceDescriptor::getOpcode(RK), | |
| RdxPart, RdxResult, "bin.rdx"); | |
| } | |
| NeedToFixLCSSA = true; | |
| for (Instruction *RdxPart : PartialReductions) | |
| RdxPart->dropPoisonGeneratingFlags(); | |
| } | |
| Phi.replaceAllUsesWith(RdxResult); | |
| } | |
| } | |
| if (DTUToUse) { | |
| // Apply updates to the DomTree. | |
| DT = &DTU.getDomTree(); | |
| } | |
| assert(!UnrollVerifyDomtree || | |
| DT->verify(DominatorTree::VerificationLevel::Fast)); | |
| Loop *OuterL = L->getParentLoop(); | |
| std::vector<BasicBlock *> Blocks; | |
| // Update LoopInfo if the loop is completely removed. | |
| if (CompletelyUnroll) { | |
| Blocks = L->getBlocks(); | |
| LI->erase(L); | |
| // We shouldn't try to use `L` anymore. | |
| L = nullptr; | |
| } | |
| // At this point, the code is well formed. We now simplify the unrolled loop, | |
| // doing constant propagation and dead code elimination as we go. | |
| simplifyLoopAfterUnroll( | |
| L, !CompletelyUnroll && ULO.Count > 1, LI, SE, DT, AC, TTI, | |
| CompletelyUnroll ? ArrayRef<BasicBlock *>(Blocks) : L->getBlocks(), AA); | |
| NumCompletelyUnrolled += CompletelyUnroll; | |
| ++NumUnrolled; | |
| if (!CompletelyUnroll) { | |
| // Update metadata for the loop's branch weights and estimated trip count: | |
| // - If ULO.Runtime, UnrollRuntimeLoopRemainder sets the guard branch | |
| // weights, latch branch weights, and estimated trip count of the | |
| // remainder loop it creates. It also sets the branch weights for the | |
| // unrolled loop guard it creates. The branch weights for the unrolled | |
| // loop latch are adjusted below. FIXME: Handle prologue loops. | |
| // - Otherwise, if unrolled loop iteration latches become unconditional, | |
| // branch weights are adjusted by the fixProbContradiction call above. | |
| // - Otherwise, the original loop's branch weights are correct for the | |
| // unrolled loop, so do not adjust them. | |
| // - In all cases, the unrolled loop's estimated trip count is set below. | |
| // | |
| // As an example of the last case, consider what happens if the unroll count | |
| // is 4 for a loop with an estimated trip count of 10 when we do not create | |
| // a remainder loop and all iterations' latches remain conditional. Each | |
| // unrolled iteration's latch still has the same probability of exiting the | |
| // loop as it did when in the original loop, and thus it should still have | |
| // the same branch weights. Each unrolled iteration's non-zero probability | |
| // of exiting already appropriately reduces the probability of reaching the | |
| // remaining iterations just as it did in the original loop. Trying to also | |
| // adjust the branch weights of the final unrolled iteration's latch (i.e., | |
| // the backedge for the unrolled loop as a whole) to reflect its new trip | |
| // count of 3 will erroneously further reduce its block frequencies. | |
| // However, in case an analysis later needs to estimate the trip count of | |
| // the unrolled loop as a whole without considering the branch weights for | |
| // each unrolled iteration's latch within it, we store the new trip count as | |
| // separate metadata. | |
| if (!OriginalLoopProb.isUnknown() && ULO.Runtime && EpilogProfitability) { | |
| assert((CondLatches.size() == 1 && | |
| (ProbUpdateRequired || OriginalLoopProb.isOne())) && | |
| "Expected ULO.Runtime to give unrolled loop 1 conditional latch, " | |
| "the backedge, requiring a probability update unless infinite"); | |
| // Where p is always the probability of executing at least 1 more | |
| // iteration, the probability for at least n more iterations is p^n. | |
| setLoopProbability(L, OriginalLoopProb.pow(ULO.Count)); | |
| } | |
| if (OriginalTripCount) { | |
| unsigned NewTripCount = *OriginalTripCount / ULO.Count; | |
| if (!ULO.Runtime && *OriginalTripCount % ULO.Count) | |
| ++NewTripCount; | |
| setLoopEstimatedTripCount(L, NewTripCount); | |
| } | |
| } | |
| // LoopInfo should not be valid, confirm that. | |
| if (UnrollVerifyLoopInfo) | |
| LI->verify(); | |
| // After complete unrolling most of the blocks should be contained in OuterL. | |
| // However, some of them might happen to be out of OuterL (e.g. if they | |
| // precede a loop exit). In this case we might need to insert PHI nodes in | |
| // order to preserve LCSSA form. | |
| // We don't need to check this if we already know that we need to fix LCSSA | |
| // form. | |
| // TODO: For now we just recompute LCSSA for the outer loop in this case, but | |
| // it should be possible to fix it in-place. | |
| if (PreserveLCSSA && OuterL && CompletelyUnroll && !NeedToFixLCSSA) | |
| NeedToFixLCSSA |= ::needToInsertPhisForLCSSA(OuterL, UnrolledLoopBlocks, LI); | |
| // Make sure that loop-simplify form is preserved. We want to simplify | |
| // at least one layer outside of the loop that was unrolled so that any | |
| // changes to the parent loop exposed by the unrolling are considered. | |
| if (OuterL) { | |
| // OuterL includes all loops for which we can break loop-simplify, so | |
| // it's sufficient to simplify only it (it'll recursively simplify inner | |
| // loops too). | |
| if (NeedToFixLCSSA) { | |
| // LCSSA must be performed on the outermost affected loop. The unrolled | |
| // loop's last loop latch is guaranteed to be in the outermost loop | |
| // after LoopInfo's been updated by LoopInfo::erase. | |
| Loop *LatchLoop = LI->getLoopFor(Latches.back()); | |
| Loop *FixLCSSALoop = OuterL; | |
| if (!FixLCSSALoop->contains(LatchLoop)) | |
| while (FixLCSSALoop->getParentLoop() != LatchLoop) | |
| FixLCSSALoop = FixLCSSALoop->getParentLoop(); | |
| formLCSSARecursively(*FixLCSSALoop, *DT, LI, SE); | |
| } else if (PreserveLCSSA) { | |
| assert(OuterL->isLCSSAForm(*DT) && | |
| "Loops should be in LCSSA form after loop-unroll."); | |
| } | |
| // TODO: That potentially might be compile-time expensive. We should try | |
| // to fix the loop-simplified form incrementally. | |
| simplifyLoop(OuterL, DT, LI, SE, AC, nullptr, PreserveLCSSA); | |
| } else { | |
| // Simplify loops for which we might've broken loop-simplify form. | |
| for (Loop *SubLoop : LoopsToSimplify) | |
| simplifyLoop(SubLoop, DT, LI, SE, AC, nullptr, PreserveLCSSA); | |
| } | |
| return CompletelyUnroll ? LoopUnrollResult::FullyUnrolled | |
| : LoopUnrollResult::PartiallyUnrolled; | |
| } | |
| /// Given an llvm.loop loop id metadata node, returns the loop hint metadata | |
| /// node with the given name (for example, "llvm.loop.unroll.count"). If no | |
| /// such metadata node exists, then nullptr is returned. | |
| MDNode *llvm::GetUnrollMetadata(MDNode *LoopID, StringRef Name) { | |
| // First operand should refer to the loop id itself. | |
| assert(LoopID->getNumOperands() > 0 && "requires at least one operand"); | |
| assert(LoopID->getOperand(0) == LoopID && "invalid loop id"); | |
| for (MDNode *MD : | |
| make_isa_range<MDNode>(llvm::drop_begin(LoopID->operands()))) { | |
| MDString *S = dyn_cast<MDString>(MD->getOperand(0)); | |
| if (!S) | |
| continue; | |
| if (Name == S->getString()) | |
| return MD; | |
| } | |
| return nullptr; | |
| } | |
| // Returns the loop hint metadata node with the given name (for example, | |
| // "llvm.loop.unroll.count"). If no such metadata node exists, then nullptr is | |
| // returned. | |
| MDNode *llvm::getUnrollMetadataForLoop(const Loop *L, StringRef Name) { | |
| if (MDNode *LoopID = L->getLoopID()) | |
| return GetUnrollMetadata(LoopID, Name); | |
| return nullptr; | |
| } | |
| std::optional<RecurrenceDescriptor> | |
| llvm::canParallelizeReductionWhenUnrolling(PHINode &Phi, Loop *L, | |
| ScalarEvolution *SE) { | |
| RecurrenceDescriptor RdxDesc; | |
| if (!RecurrenceDescriptor::isReductionPHI(&Phi, L, RdxDesc, | |
| /*DemandedBits=*/nullptr, | |
| /*AC=*/nullptr, /*DT=*/nullptr, SE)) | |
| return std::nullopt; | |
| if (RdxDesc.hasUsesOutsideReductionChain()) | |
| return std::nullopt; | |
| RecurKind RK = RdxDesc.getRecurrenceKind(); | |
| static const auto ValidRKs = { | |
| RecurKind::Add, RecurKind::Mul, RecurKind::Or, | |
| RecurKind::And, RecurKind::Xor, RecurKind::SMin, | |
| RecurKind::SMax, RecurKind::UMin, RecurKind::UMax, | |
| RecurKind::FAdd, RecurKind::FMul, RecurKind::FMin, | |
| RecurKind::FMax, RecurKind::FMinNum, RecurKind::FMaxNum, | |
| RecurKind::FMinimum, RecurKind::FMaximum, RecurKind::FMinimumNum, | |
| RecurKind::FMaximumNum, RecurKind::FMulAdd}; | |
| // Skip unsupported reductions, including sub, any-of and find-last. | |
| // TODO: Handle sub, any-of and find-last reductions. | |
| if (!any_of(ValidRKs, equal_to(RK))) | |
| return std::nullopt; | |
| if (RdxDesc.hasExactFPMath()) | |
| return std::nullopt; | |
| if (RdxDesc.IntermediateStore) | |
| return std::nullopt; | |
| BasicBlock *Latch = L->getLoopLatch(); | |
| if (!Latch) | |
| return std::nullopt; | |
| Instruction *LatchInst = | |
| cast<Instruction>(Phi.getIncomingValueForBlock(Latch)); | |
| // Don't unroll reductions with constant ops; those can be folded to a | |
| // single induction update. For calls (e.g. fmuladd or min/max | |
| // intrinsics), the called function is itself a Constant operand and is | |
| // not a reduction operand, so restrict the check to the argument list. | |
| auto Ops = isa<CallBase>(LatchInst) ? cast<CallBase>(LatchInst)->args() | |
| : LatchInst->operands(); | |
| if (any_of(Ops, IsaPred<Constant>)) | |
| return std::nullopt; | |
| if (!is_contained(LatchInst->operands(), &Phi)) | |
| return std::nullopt; | |
| return RdxDesc; | |
| } |