| //===-- 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> |
| 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); |
| } |
| } |
| |
| // Loops containing convergent instructions that are uncontrolled or controlled |
| // from outside the loop must have a count that divides their TripMultiple. |
| LLVM_ATTRIBUTE_USED |
| static bool canHaveUnrollRemainder(const Loop *L) { |
| if (getLoopConvergenceHeart(L)) |
| return false; |
| |
| // Check for uncontrolled convergent operations. |
| for (auto &BB : L->blocks()) { |
| for (auto &I : *BB) { |
| if (isa<ConvergenceControlInst>(I)) |
| return true; |
| if (auto *CB = dyn_cast<CallBase>(&I)) |
| if (CB->isConvergent()) |
| return CB->getConvergenceControlToken(); |
| } |
| } |
| return true; |
| } |
| |
| // 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, this function just quickly hacks a few of their probabilities to |
| // restore the original total loop body frequency. Otherwise, it determines |
| // 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 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: |
| // - 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 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. |
| // - For n <= 2, we can use simple formulas to solve the above polynomial |
| // equations exactly for p without performing a search. |
| |
| // When iterating for a solution, we stop early if we find probabilities |
| // that produce a Freq whose 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 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; |
| 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); |
| 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. |
| if (CondLatches.size() == 1) { |
| SetAllProbs(ComputeProbForLinear()); |
| } else if (CondLatches.size() == 2) { |
| SetAllProbs(ComputeProbForQuadratic()); |
| } else { |
| // The polynomial is too complex for a simple formula, so 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) < FreqPrec) |
| break; |
| } |
| } |
| |
| // 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) { |
| 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(*DT); |
| |
| // 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 (const MDOperand &MDO : llvm::drop_begin(LoopID->operands())) { |
| MDNode *MD = dyn_cast<MDNode>(MDO); |
| if (!MD) |
| continue; |
| |
| 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(); |
| // Skip unsupported reductions. |
| // TODO: Handle any-of and find-last reductions. |
| if (RecurrenceDescriptor::isAnyOfRecurrenceKind(RK) || |
| RecurrenceDescriptor::isFindRecurrenceKind(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; |
| } |