diff options
Diffstat (limited to 'include/llvm/Analysis/LoopInfo.h')
-rw-r--r-- | include/llvm/Analysis/LoopInfo.h | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 2babc25..9455fd8 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -256,6 +256,27 @@ public: /// BlockT *getLoopPreheader() const { // Keep track of nodes outside the loop branching to the header... + BlockT *Out = getLoopPredecessor(); + if (!Out) return 0; + + // Make sure there is only one exit out of the preheader. + typedef GraphTraits<BlockT*> BlockTraits; + typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out); + ++SI; + if (SI != BlockTraits::child_end(Out)) + return 0; // Multiple exits from the block, must not be a preheader. + + // The predecessor has exactly one successor, so it is a preheader. + return Out; + } + + /// getLoopPredecessor - If the given loop's header has exactly one unique + /// predecessor outside the loop, return it. Otherwise return null. + /// This is less strict that the loop "preheader" concept, which requires + /// the predecessor to have exactly one successor. + /// + BlockT *getLoopPredecessor() const { + // Keep track of nodes outside the loop branching to the header... BlockT *Out = 0; // Loop over the predecessors of the header node... @@ -264,22 +285,17 @@ public: typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; for (typename InvBlockTraits::ChildIteratorType PI = InvBlockTraits::child_begin(Header), - PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) - if (!contains(*PI)) { // If the block is not in the loop... - if (Out && Out != *PI) + PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) { + typename InvBlockTraits::NodeType *N = *PI; + if (!contains(N)) { // If the block is not in the loop... + if (Out && Out != N) return 0; // Multiple predecessors outside the loop - Out = *PI; + Out = N; } + } // Make sure there is only one exit out of the preheader. assert(Out && "Header of loop has no predecessors from outside loop?"); - typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out); - ++SI; - if (SI != BlockTraits::child_end(Out)) - return 0; // Multiple exits from the block, must not be a preheader. - - // If there is exactly one preheader, return it. If there was zero, then - // Out is still null. return Out; } @@ -293,11 +309,13 @@ public: typename InvBlockTraits::ChildIteratorType PE = InvBlockTraits::child_end(Header); BlockT *Latch = 0; - for (; PI != PE; ++PI) - if (contains(*PI)) { + for (; PI != PE; ++PI) { + typename InvBlockTraits::NodeType *N = *PI; + if (contains(N)) { if (Latch) return 0; - Latch = *PI; + Latch = N; } + } return Latch; } @@ -409,10 +427,11 @@ public: for (typename InvBlockTraits::ChildIteratorType PI = InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB); PI != PE; ++PI) { - if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *PI)) + typename InvBlockTraits::NodeType *N = *PI; + if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), N)) HasInsideLoopPreds = true; else - OutsideLoopPreds.push_back(*PI); + OutsideLoopPreds.push_back(N); } if (BB == getHeader()) { @@ -743,9 +762,11 @@ public: typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; for (typename InvBlockTraits::ChildIteratorType I = InvBlockTraits::child_begin(BB), E = InvBlockTraits::child_end(BB); - I != E; ++I) - if (DT.dominates(BB, *I)) // If BB dominates its predecessor... - TodoStack.push_back(*I); + I != E; ++I) { + typename InvBlockTraits::NodeType *N = *I; + if (DT.dominates(BB, N)) // If BB dominates its predecessor... + TodoStack.push_back(N); + } if (TodoStack.empty()) return 0; // No backedges to this block... |