diff options
Diffstat (limited to 'contrib/llvm/lib/Analysis/LoopInfo.cpp')
-rw-r--r-- | contrib/llvm/lib/Analysis/LoopInfo.cpp | 142 |
1 files changed, 102 insertions, 40 deletions
diff --git a/contrib/llvm/lib/Analysis/LoopInfo.cpp b/contrib/llvm/lib/Analysis/LoopInfo.cpp index 697b58622bb4..9e54d60779a0 100644 --- a/contrib/llvm/lib/Analysis/LoopInfo.cpp +++ b/contrib/llvm/lib/Analysis/LoopInfo.cpp @@ -16,6 +16,7 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/LoopInfoImpl.h" #include "llvm/Analysis/LoopIterator.h" @@ -44,9 +45,9 @@ bool llvm::VerifyLoopInfo = true; #else bool llvm::VerifyLoopInfo = false; #endif -static cl::opt<bool,true> -VerifyLoopInfoX("verify-loop-info", cl::location(VerifyLoopInfo), - cl::desc("Verify loop info (time consuming)")); +static cl::opt<bool, true> + VerifyLoopInfoX("verify-loop-info", cl::location(VerifyLoopInfo), + cl::Hidden, cl::desc("Verify loop info (time consuming)")); //===----------------------------------------------------------------------===// // Loop implementation @@ -55,7 +56,7 @@ VerifyLoopInfoX("verify-loop-info", cl::location(VerifyLoopInfo), bool Loop::isLoopInvariant(const Value *V) const { if (const Instruction *I = dyn_cast<Instruction>(V)) return !contains(I); - return true; // All non-instructions are loop invariant + return true; // All non-instructions are loop invariant } bool Loop::hasLoopInvariantOperands(const Instruction *I) const { @@ -66,7 +67,7 @@ bool Loop::makeLoopInvariant(Value *V, bool &Changed, Instruction *InsertPt) const { if (Instruction *I = dyn_cast<Instruction>(V)) return makeLoopInvariant(I, Changed, InsertPt); - return true; // All non-instructions are loop-invariant. + return true; // All non-instructions are loop-invariant. } bool Loop::makeLoopInvariant(Instruction *I, bool &Changed, @@ -112,12 +113,13 @@ PHINode *Loop::getCanonicalInductionVariable() const { BasicBlock *Incoming = nullptr, *Backedge = nullptr; pred_iterator PI = pred_begin(H); - assert(PI != pred_end(H) && - "Loop must have at least one backedge!"); + assert(PI != pred_end(H) && "Loop must have at least one backedge!"); Backedge = *PI++; - if (PI == pred_end(H)) return nullptr; // dead loop + if (PI == pred_end(H)) + return nullptr; // dead loop Incoming = *PI++; - if (PI != pred_end(H)) return nullptr; // multiple backedges? + if (PI != pred_end(H)) + return nullptr; // multiple backedges? if (contains(Incoming)) { if (contains(Backedge)) @@ -130,12 +132,11 @@ PHINode *Loop::getCanonicalInductionVariable() const { for (BasicBlock::iterator I = H->begin(); isa<PHINode>(I); ++I) { PHINode *PN = cast<PHINode>(I); if (ConstantInt *CI = - dyn_cast<ConstantInt>(PN->getIncomingValueForBlock(Incoming))) + dyn_cast<ConstantInt>(PN->getIncomingValueForBlock(Incoming))) if (CI->isZero()) if (Instruction *Inc = - dyn_cast<Instruction>(PN->getIncomingValueForBlock(Backedge))) - if (Inc->getOpcode() == Instruction::Add && - Inc->getOperand(0) == PN) + dyn_cast<Instruction>(PN->getIncomingValueForBlock(Backedge))) + if (Inc->getOpcode() == Instruction::Add && Inc->getOperand(0) == PN) if (ConstantInt *CI = dyn_cast<ConstantInt>(Inc->getOperand(1))) if (CI->isOne()) return PN; @@ -255,7 +256,8 @@ void Loop::setLoopID(MDNode *LoopID) const { return; } - assert(!getLoopLatch() && "The loop should have no single latch at this point"); + assert(!getLoopLatch() && + "The loop should have no single latch at this point"); BasicBlock *H = getHeader(); for (BasicBlock *BB : this->blocks()) { TerminatorInst *TI = BB->getTerminator(); @@ -266,11 +268,44 @@ void Loop::setLoopID(MDNode *LoopID) const { } } +void Loop::setLoopAlreadyUnrolled() { + MDNode *LoopID = getLoopID(); + // First remove any existing loop unrolling metadata. + SmallVector<Metadata *, 4> MDs; + // Reserve first location for self reference to the LoopID metadata node. + MDs.push_back(nullptr); + + if (LoopID) { + for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) { + bool IsUnrollMetadata = false; + MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i)); + if (MD) { + const MDString *S = dyn_cast<MDString>(MD->getOperand(0)); + IsUnrollMetadata = S && S->getString().startswith("llvm.loop.unroll."); + } + if (!IsUnrollMetadata) + MDs.push_back(LoopID->getOperand(i)); + } + } + + // Add unroll(disable) metadata to disable future unrolling. + LLVMContext &Context = getHeader()->getContext(); + SmallVector<Metadata *, 1> DisableOperands; + DisableOperands.push_back(MDString::get(Context, "llvm.loop.unroll.disable")); + MDNode *DisableNode = MDNode::get(Context, DisableOperands); + MDs.push_back(DisableNode); + + MDNode *NewLoopID = MDNode::get(Context, MDs); + // Set operand 0 to refer to the loop id itself. + NewLoopID->replaceOperandWith(0, NewLoopID); + setLoopID(NewLoopID); +} + bool Loop::isAnnotatedParallel() const { MDNode *DesiredLoopIdMetadata = getLoopID(); if (!DesiredLoopIdMetadata) - return false; + return false; // The loop branch contains the parallel loop metadata. In order to ensure // that any parallel-loop-unaware optimization pass hasn't added loop-carried @@ -307,9 +342,7 @@ bool Loop::isAnnotatedParallel() const { return true; } -DebugLoc Loop::getStartLoc() const { - return getLocRange().getStart(); -} +DebugLoc Loop::getStartLoc() const { return getLocRange().getStart(); } Loop::LocRange Loop::getLocRange() const { // If we have a debug location in the loop ID, then use it. @@ -357,8 +390,8 @@ bool Loop::hasDedicatedExits() const { return true; } -void -Loop::getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const { +void Loop::getUniqueExitBlocks( + SmallVectorImpl<BasicBlock *> &ExitBlocks) const { assert(hasDedicatedExits() && "getUniqueExitBlocks assumes the loop has canonical form exits!"); @@ -408,12 +441,10 @@ BasicBlock *Loop::getUniqueExitBlock() const { } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void Loop::dump() const { - print(dbgs()); -} +LLVM_DUMP_METHOD void Loop::dump() const { print(dbgs()); } LLVM_DUMP_METHOD void Loop::dumpVerbose() const { - print(dbgs(), /*Depth=*/ 0, /*Verbose=*/ true); + print(dbgs(), /*Depth=*/0, /*Verbose=*/true); } #endif @@ -434,15 +465,15 @@ class UnloopUpdater { // loops within these subloops will not change parents. However, an immediate // subloop's new parent will be the nearest loop reachable from either its own // exits *or* any of its nested loop's exits. - DenseMap<Loop*, Loop*> SubloopParents; + DenseMap<Loop *, Loop *> SubloopParents; // Flag the presence of an irreducible backedge whose destination is a block // directly contained by the original unloop. bool FoundIB; public: - UnloopUpdater(Loop *UL, LoopInfo *LInfo) : - Unloop(*UL), LI(LInfo), DFS(UL), FoundIB(false) {} + UnloopUpdater(Loop *UL, LoopInfo *LInfo) + : Unloop(*UL), LI(LInfo), DFS(UL), FoundIB(false) {} void updateBlockParents(); @@ -472,8 +503,7 @@ void UnloopUpdater::updateBlockParents() { assert((NL != &Unloop && (!NL || NL->contains(&Unloop))) && "uninitialized successor"); LI->changeLoopFor(POI, NL); - } - else { + } else { // Or the current block is part of a subloop, in which case its parent // is unchanged. assert((FoundIB || Unloop.contains(L)) && "uninitialized successor"); @@ -490,7 +520,8 @@ void UnloopUpdater::updateBlockParents() { // from successors to predecessors as before. Changed = false; for (LoopBlocksDFS::POIterator POI = DFS.beginPostorder(), - POE = DFS.endPostorder(); POI != POE; ++POI) { + POE = DFS.endPostorder(); + POI != POE; ++POI) { Loop *L = LI->getLoopFor(*POI); Loop *NL = getNearestLoop(*POI, L); @@ -508,8 +539,8 @@ void UnloopUpdater::updateBlockParents() { void UnloopUpdater::removeBlocksFromAncestors() { // Remove all unloop's blocks (including those in nested subloops) from // ancestors below the new parent loop. - for (Loop::block_iterator BI = Unloop.block_begin(), - BE = Unloop.block_end(); BI != BE; ++BI) { + for (Loop::block_iterator BI = Unloop.block_begin(), BE = Unloop.block_end(); + BI != BE; ++BI) { Loop *OuterParent = LI->getLoopFor(*BI); if (Unloop.contains(OuterParent)) { while (OuterParent->getParentLoop() != &Unloop) @@ -609,9 +640,7 @@ Loop *UnloopUpdater::getNearestLoop(BasicBlock *BB, Loop *BBLoop) { return NearLoop; } -LoopInfo::LoopInfo(const DomTreeBase<BasicBlock> &DomTree) { - analyze(DomTree); -} +LoopInfo::LoopInfo(const DomTreeBase<BasicBlock> &DomTree) { analyze(DomTree); } bool LoopInfo::invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &) { @@ -622,10 +651,10 @@ bool LoopInfo::invalidate(Function &F, const PreservedAnalyses &PA, PAC.preservedSet<CFGAnalyses>()); } -void LoopInfo::markAsRemoved(Loop *Unloop) { - assert(!Unloop->isInvalid() && "Loop has already been removed"); - Unloop->invalidate(); - RemovedLoops.push_back(Unloop); +void LoopInfo::erase(Loop *Unloop) { + assert(!Unloop->isInvalid() && "Loop has already been erased!"); + + auto InvalidateOnExit = make_scope_exit([&]() { destroy(Unloop); }); // First handle the special case of no parent loop to simplify the algorithm. if (!Unloop->getParentLoop()) { @@ -702,12 +731,43 @@ PreservedAnalyses LoopPrinterPass::run(Function &F, } void llvm::printLoop(Loop &L, raw_ostream &OS, const std::string &Banner) { + + if (forcePrintModuleIR()) { + // handling -print-module-scope + OS << Banner << " (loop: "; + L.getHeader()->printAsOperand(OS, false); + OS << ")\n"; + + // printing whole module + OS << *L.getHeader()->getModule(); + return; + } + OS << Banner; + + auto *PreHeader = L.getLoopPreheader(); + if (PreHeader) { + OS << "\n; Preheader:"; + PreHeader->print(OS); + OS << "\n; Loop:"; + } + for (auto *Block : L.blocks()) if (Block) Block->print(OS); else OS << "Printing <null> block"; + + SmallVector<BasicBlock *, 8> ExitBlocks; + L.getExitBlocks(ExitBlocks); + if (!ExitBlocks.empty()) { + OS << "\n; Exit blocks"; + for (auto *Block : ExitBlocks) + if (Block) + Block->print(OS); + else + OS << "Printing <null> block"; + } } //===----------------------------------------------------------------------===// @@ -766,5 +826,7 @@ PreservedAnalyses LoopVerifierPass::run(Function &F, void LoopBlocksDFS::perform(LoopInfo *LI) { LoopBlocksTraversal Traversal(*this, LI); for (LoopBlocksTraversal::POTIterator POI = Traversal.begin(), - POE = Traversal.end(); POI != POE; ++POI) ; + POE = Traversal.end(); + POI != POE; ++POI) + ; } |