X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FAnalysis%2FLoopIterator.h;h=e3dd96354c65a414969af84d0d735fd47ef9741d;hb=4f7e2c38e864d7eaeb407ac501478e9579624d1b;hp=2797e67b0967f3fa9de2310faec80fdae25f6d40;hpb=5207936a24ab9e0bfaa10e798625df65143e3716;p=oota-llvm.git diff --git a/include/llvm/Analysis/LoopIterator.h b/include/llvm/Analysis/LoopIterator.h index 2797e67b096..e3dd96354c6 100644 --- a/include/llvm/Analysis/LoopIterator.h +++ b/include/llvm/Analysis/LoopIterator.h @@ -21,10 +21,9 @@ // reachable from the loop header. //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H -#define LLVM_ANALYSIS_LOOP_ITERATOR_H +#ifndef LLVM_ANALYSIS_LOOPITERATOR_H +#define LLVM_ANALYSIS_LOOPITERATOR_H -#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/Analysis/LoopInfo.h" @@ -61,6 +60,9 @@ public: Loop *getLoop() const { return L; } + /// Traverse the loop blocks and store the DFS result. + void perform(LoopInfo *LI); + /// Return true if postorder numbers are assigned to all loop blocks. bool isComplete() const { return PostBlocks.size() == L->getNumBlocks(); } @@ -106,27 +108,21 @@ public: } }; -/// Define a graph of blocks within a loop. Allows LoopBlocksTraversal to -/// use the generic po_iterator with specialized GraphTraits. -struct LoopBlocksGraph { - Loop *L; - - LoopBlocksGraph(Loop *Container) : L(Container) {} -}; - -template<> struct GraphTraits : - public GraphTraits { - - static BasicBlock *getEntryNode(LoopBlocksGraph G) { - return G.L->getHeader(); - } +/// Specialize po_iterator_storage to record postorder numbers. +template<> class po_iterator_storage { + LoopBlocksTraversal &LBT; +public: + po_iterator_storage(LoopBlocksTraversal &lbs) : LBT(lbs) {} + // These functions are defined below. + bool insertEdge(BasicBlock *From, BasicBlock *To); + void finishPostorder(BasicBlock *BB); }; /// Traverse the blocks in a loop using a depth-first search. class LoopBlocksTraversal { public: /// Graph traversal iterator. - typedef po_iterator POTIterator; + typedef po_iterator POTIterator; private: LoopBlocksDFS &DFS; @@ -141,10 +137,12 @@ public: /// finishPostorder to record the DFS result. POTIterator begin() { assert(DFS.PostBlocks.empty() && "Need clear DFS result before traversing"); - return po_ext_begin(LoopBlocksGraph(DFS.L), *this); + assert(DFS.L->getNumBlocks() && "po_iterator cannot handle an empty graph"); + return po_ext_begin(DFS.L->getHeader(), *this); } POTIterator end() { - return po_ext_end(LoopBlocksGraph(DFS.L), *this); + // po_ext_end interface requires a basic block, but ignores its value. + return po_ext_end(DFS.L->getHeader(), *this); } /// Called by po_iterator upon reaching a block via a CFG edge. If this block @@ -166,31 +164,17 @@ public: DFS.PostBlocks.push_back(BB); DFS.PostNumbers[BB] = DFS.PostBlocks.size(); } - - //===---------------------------------------------------------------------- - // Implement part of the std::set interface for the purpose of driving the - // generic po_iterator. - - /// Return true if the block is outside the loop or has already been visited. - /// Sorry if this is counterintuitive. - bool count(BasicBlock *BB) const { - return !DFS.L->contains(LI->getLoopFor(BB)) || DFS.PostNumbers.count(BB); - } - - /// If this block is contained in the loop and has not been visited, return - /// true and assign a preorder number. This is a proxy for visitPreorder - /// called by POIterator. - bool insert(BasicBlock *BB) { - return visitPreorder(BB); - } }; -/// Specialize DFSetTraits to record postorder numbers. -template<> struct DFSetTraits { - static void finishPostorder(BasicBlock *BB, LoopBlocksTraversal& LBT) { - LBT.finishPostorder(BB); - } -}; +inline bool po_iterator_storage:: +insertEdge(BasicBlock *From, BasicBlock *To) { + return LBT.visitPreorder(To); +} + +inline void po_iterator_storage:: +finishPostorder(BasicBlock *BB) { + LBT.finishPostorder(BB); +} } // End namespace llvm