This makes a change to the state used to maintain visited information for depth first iterator. We know assume a method "completed(...)" which is called after all children of a node have been visited. In all existing cases, this method does nothing so this patch has no functional changes. It will however allow a client to distinguish back from cross edges in a DFS tree.
Details
Details
Diff Detail
Diff Detail
- Repository
- rL LLVM
Event Timeline
Comment Actions
This looks fine to me as well.
(I don't know how you'll figure back-edge with it, but I'll see in the next patch)
Comment Actions
For illustration, this is what the client code looks like (abstracted a bit) for at least one back edge in a loop.
(Note this code is still order dependent in that the specific edges selected as back edges is order dependent for irreducible loops but is well defined otherwise).
// This stores state for the depth-first iterator. In addition // to recording which nodes have been visited we also record whether // a node is currently on the "stack" of active ancestors of the current // node. class DFState { DenseMap<BasicBlock *, bool> Status; public: typedef typename DenseMap<BasicBlock *, bool>::iterator iterator; DFState(unsigned N) { Status.reserve(N); } std::pair<iterator, bool> insert(BasicBlock *BB) { return Status.insert(std::make_pair(BB, true)); } unsigned count(BasicBlock *BB) { return Status.count(BB); } // Invoked after we have visited all children of a node. void completed(BasicBlock *BB) { Status[BB] = false; } // Return true if \p BB is currently on the active stack // of ancestors. bool onStack(BasicBlock *BB) { auto Iter = Status.find(BB); return Iter != Status.end() && Iter->second; } } State(F.size()); // Iterate over blocks in depth-first pre-order and // treat all edges to a block already seen as loop back edges // and mark the branch live it if there is a back edge. typedef df_iterator<BasicBlock *, DFState, true> Iterator; auto Iter = Iterator::begin(&F.getEntryBlock(), State); auto End = Iterator::end(&F.getEntryBlock(), State); for (; Iter != End; ++Iter) { auto *BB = *Iter; for (auto Succ : successors(BB)) if (State.onStack(Succ)) { // back edge.... } } }