Index: llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp +++ llvm/trunk/lib/Transforms/Scalar/StructurizeCFG.cpp @@ -43,77 +43,58 @@ typedef MapVector PhiMap; typedef MapVector BB2BBVecMap; -typedef DenseMap DTN2UnsignedMap; typedef DenseMap BBPhiMap; typedef DenseMap BBPredicates; typedef DenseMap PredMap; typedef DenseMap BB2BBMap; // The name for newly created blocks. - static const char *const FlowBlockName = "Flow"; -/// @brief Find the nearest common dominator for multiple BasicBlocks +/// Finds the nearest common dominator of a set of BasicBlocks. /// -/// Helper class for StructurizeCFG -/// TODO: Maybe move into common code +/// For every BB you add to the set, you can specify whether we "remember" the +/// block. When you get the common dominator, you can also ask whether it's one +/// of the blocks we remembered. class NearestCommonDominator { DominatorTree *DT; + BasicBlock *Result = nullptr; + bool ResultIsRemembered = false; - DTN2UnsignedMap IndexMap; - - BasicBlock *Result; - unsigned ResultIndex; - bool ExplicitMentioned; - -public: - /// \brief Start a new query - NearestCommonDominator(DominatorTree *DomTree) { - DT = DomTree; - Result = nullptr; - } - - /// \brief Add BB to the resulting dominator - void addBlock(BasicBlock *BB, bool Remember = true) { - DomTreeNode *Node = DT->getNode(BB); - + /// Add BB to the resulting dominator. + void addBlock(BasicBlock *BB, bool Remember) { if (!Result) { - unsigned Numbering = 0; - for (;Node;Node = Node->getIDom()) - IndexMap[Node] = ++Numbering; Result = BB; - ResultIndex = 1; - ExplicitMentioned = Remember; + ResultIsRemembered = Remember; return; } - for (;Node;Node = Node->getIDom()) - if (IndexMap.count(Node)) - break; - else - IndexMap[Node] = 0; + BasicBlock *NewResult = DT->findNearestCommonDominator(Result, BB); + if (NewResult != Result) + ResultIsRemembered = false; + if (NewResult == BB) + ResultIsRemembered |= Remember; + Result = NewResult; + } - assert(Node && "Dominator tree invalid!"); +public: + explicit NearestCommonDominator(DominatorTree *DomTree) : DT(DomTree) {} - unsigned Numbering = IndexMap[Node]; - if (Numbering > ResultIndex) { - Result = Node->getBlock(); - ResultIndex = Numbering; - ExplicitMentioned = Remember && (Result == BB); - } else if (Numbering == ResultIndex) { - ExplicitMentioned |= Remember; - } + void addBlock(BasicBlock *BB) { + addBlock(BB, /* Remember = */ false); } - /// \brief Is "Result" one of the BBs added with "Remember" = True? - bool wasResultExplicitMentioned() { - return ExplicitMentioned; + void addAndRememberBlock(BasicBlock *BB) { + addBlock(BB, /* Remember = */ true); } - /// \brief Get the query result - BasicBlock *getResult() { - return Result; - } + /// Get the nearest common dominator of all the BBs added via addBlock() and + /// addAndRememberBlock(). + BasicBlock *result() { return Result; } + + /// Is the BB returned by getResult() one of the blocks we added to the set + /// with addAndRememberBlock()? + bool resultIsRememberedBlock() { return ResultIsRemembered; } }; /// @brief Transforms the control flow graph on one single entry/exit region @@ -517,7 +498,7 @@ BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue]; NearestCommonDominator Dominator(DT); - Dominator.addBlock(Parent, false); + Dominator.addBlock(Parent); Value *ParentValue = nullptr; for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end(); @@ -528,14 +509,14 @@ break; } PhiInserter.AddAvailableValue(PI->first, PI->second); - Dominator.addBlock(PI->first); + Dominator.addAndRememberBlock(PI->first); } if (ParentValue) { Term->setCondition(ParentValue); } else { - if (!Dominator.wasResultExplicitMentioned()) - PhiInserter.AddAvailableValue(Dominator.getResult(), Default); + if (!Dominator.resultIsRememberedBlock()) + PhiInserter.AddAvailableValue(Dominator.result(), Default); Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent)); } @@ -590,15 +571,15 @@ Updater.AddAvailableValue(To, Undef); NearestCommonDominator Dominator(DT); - Dominator.addBlock(To, false); + Dominator.addBlock(To); for (const auto &VI : PI.second) { Updater.AddAvailableValue(VI.first, VI.second); - Dominator.addBlock(VI.first); + Dominator.addAndRememberBlock(VI.first); } - if (!Dominator.wasResultExplicitMentioned()) - Updater.AddAvailableValue(Dominator.getResult(), Undef); + if (!Dominator.resultIsRememberedBlock()) + Updater.AddAvailableValue(Dominator.result(), Undef); for (BasicBlock *FI : From) {