Index: include/llvm/IR/Dominators.h =================================================================== --- include/llvm/IR/Dominators.h +++ include/llvm/IR/Dominators.h @@ -33,6 +33,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase); EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase); +EXTERN_TEMPLATE_INSTANTIATION(class NearestCommonDominatorBase); typedef DomTreeNodeBase DomTreeNode; @@ -108,6 +109,17 @@ void verifyDomTree() const; }; +/// \brief Concrete subclass of NearestCommonDominatorBase that is used to +/// compute a the nearest common dominator for N nodes in a normal dominator +/// tree. +class NearestCommonDominator : public NearestCommonDominatorBase { +public: + typedef NearestCommonDominatorBase Base; + + NearestCommonDominator(DominatorTreeBase *DT_) : + NearestCommonDominatorBase(DT_) {} +}; + //===------------------------------------- // DominatorTree GraphTraits specializations so the DominatorTree can be // iterable by generic graph iterators. Index: include/llvm/Support/GenericDomTree.h =================================================================== --- include/llvm/Support/GenericDomTree.h +++ include/llvm/Support/GenericDomTree.h @@ -713,6 +713,70 @@ getNode(const_cast(B))); } +/// @brief Find the nearest common dominator for multiple BasicBlocks +/// +template +class NearestCommonDominatorBase { + typedef DenseMap *, unsigned> DTN2UnsignedMap; + + DominatorTreeBase *DT; + + DTN2UnsignedMap IndexMap; + + NodeT *Result; + unsigned ResultIndex; + bool ExplicitMentioned; + +public: + /// \brief Start a new query + NearestCommonDominatorBase(DominatorTreeBase *DomTree) { + DT = DomTree; + Result = 0; + } + + /// \brief Add BB to the resulting dominator + void addNode(NodeT *BB, bool Remember = true) { + DomTreeNodeBase *Node = DT->getNode(BB); + + if (!Result) { + unsigned Numbering = 0; + for (;Node;Node = Node->getIDom()) + IndexMap[Node] = ++Numbering; + Result = BB; + ResultIndex = 1; + ExplicitMentioned = Remember; + return; + } + + for (;Node;Node = Node->getIDom()) + if (IndexMap.count(Node)) + break; + else + IndexMap[Node] = 0; + + assert(Node && "Dominator tree invalid!"); + + unsigned Numbering = IndexMap[Node]; + if (Numbering > ResultIndex) { + Result = Node->getBlock(); + ResultIndex = Numbering; + ExplicitMentioned = Remember && (Result == BB); + } else if (Numbering == ResultIndex) { + ExplicitMentioned |= Remember; + } + } + + /// \brief Is "Result" one of the BBs added with "Remember" = True? + bool wasResultExplicitMentioned() { + return ExplicitMentioned; + } + + /// \brief Get the query result + NodeT *getResult() { + return Result; + } +}; + } #endif Index: lib/IR/Dominators.cpp =================================================================== --- lib/IR/Dominators.cpp +++ lib/IR/Dominators.cpp @@ -63,6 +63,7 @@ TEMPLATE_INSTANTIATION(class llvm::DomTreeNodeBase); TEMPLATE_INSTANTIATION(class llvm::DominatorTreeBase); +TEMPLATE_INSTANTIATION(class llvm::NearestCommonDominatorBase); // dominates - Return true if Def dominates a use in User. This performs // the special checks necessary if Def and User are in the same basic block. Index: lib/Transforms/Scalar/StructurizeCFG.cpp =================================================================== --- lib/Transforms/Scalar/StructurizeCFG.cpp +++ lib/Transforms/Scalar/StructurizeCFG.cpp @@ -37,7 +37,6 @@ typedef MapVector PhiMap; typedef MapVector BB2BBVecMap; -typedef DenseMap DTN2UnsignedMap; typedef DenseMap BBPhiMap; typedef DenseMap BBPredicates; typedef DenseMap PredMap; @@ -47,69 +46,6 @@ static const char *const FlowBlockName = "Flow"; -/// @brief Find the nearest common dominator for multiple BasicBlocks -/// -/// Helper class for StructurizeCFG -/// TODO: Maybe move into common code -class NearestCommonDominator { - DominatorTree *DT; - - DTN2UnsignedMap IndexMap; - - BasicBlock *Result; - unsigned ResultIndex; - bool ExplicitMentioned; - -public: - /// \brief Start a new query - NearestCommonDominator(DominatorTree *DomTree) { - DT = DomTree; - Result = 0; - } - - /// \brief Add BB to the resulting dominator - void addBlock(BasicBlock *BB, bool Remember = true) { - DomTreeNode *Node = DT->getNode(BB); - - if (Result == 0) { - unsigned Numbering = 0; - for (;Node;Node = Node->getIDom()) - IndexMap[Node] = ++Numbering; - Result = BB; - ResultIndex = 1; - ExplicitMentioned = Remember; - return; - } - - for (;Node;Node = Node->getIDom()) - if (IndexMap.count(Node)) - break; - else - IndexMap[Node] = 0; - - assert(Node && "Dominator tree invalid!"); - - unsigned Numbering = IndexMap[Node]; - if (Numbering > ResultIndex) { - Result = Node->getBlock(); - ResultIndex = Numbering; - ExplicitMentioned = Remember && (Result == BB); - } else if (Numbering == ResultIndex) { - ExplicitMentioned |= Remember; - } - } - - /// \brief Is "Result" one of the BBs added with "Remember" = True? - bool wasResultExplicitMentioned() { - return ExplicitMentioned; - } - - /// \brief Get the query result - BasicBlock *getResult() { - return Result; - } -}; - /// @brief Transforms the control flow graph on one single entry/exit region /// at a time. /// @@ -477,7 +413,7 @@ BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue]; NearestCommonDominator Dominator(DT); - Dominator.addBlock(Parent, false); + Dominator.addNode(Parent, false); Value *ParentValue = 0; for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end(); @@ -488,7 +424,7 @@ break; } PhiInserter.AddAvailableValue(PI->first, PI->second); - Dominator.addBlock(PI->first); + Dominator.addNode(PI->first); } if (ParentValue) { @@ -552,12 +488,12 @@ Updater.AddAvailableValue(To, Undef); NearestCommonDominator Dominator(DT); - Dominator.addBlock(To, false); + Dominator.addNode(To, false); for (BBValueVector::iterator VI = PI->second.begin(), VE = PI->second.end(); VI != VE; ++VI) { Updater.AddAvailableValue(VI->first, VI->second); - Dominator.addBlock(VI->first); + Dominator.addNode(VI->first); } if (!Dominator.wasResultExplicitMentioned())