Index: include/llvm/Support/GenericDomTree.h =================================================================== --- include/llvm/Support/GenericDomTree.h +++ include/llvm/Support/GenericDomTree.h @@ -230,7 +230,6 @@ void wipe() { DomTreeNodes.clear(); IDoms.clear(); - Info.clear(); RootNode = nullptr; } @@ -242,21 +241,9 @@ mutable bool DFSInfoValid = false; mutable unsigned int SlowQueries = 0; - // Information record used during immediate dominators computation. - struct InfoRec { - unsigned DFSNum = 0; - unsigned Parent = 0; - unsigned Semi = 0; - NodeT *Label = nullptr; - - InfoRec() = default; - }; DenseMap IDoms; - // Info - Collection of information used during the computation of idoms. - DenseMap Info; - void reset() { DomTreeNodes.clear(); IDoms.clear(); @@ -335,8 +322,7 @@ RootNode(std::move(Arg.RootNode)), DFSInfoValid(std::move(Arg.DFSInfoValid)), SlowQueries(std::move(Arg.SlowQueries)), - IDoms(std::move(Arg.IDoms)), - Info(std::move(Arg.Info)) { + IDoms(std::move(Arg.IDoms)) { Arg.wipe(); } @@ -348,7 +334,6 @@ DFSInfoValid = std::move(RHS.DFSInfoValid); SlowQueries = std::move(RHS.SlowQueries); IDoms = std::move(RHS.IDoms); - Info = std::move(RHS.Info); RHS.wipe(); return *this; } @@ -670,22 +655,37 @@ } protected: + // Information record used by Semi-NCA during tree construction. + struct SemiNCAInfo { + using NodePtr = NodeT *; + struct InfoRec { + unsigned DFSNum = 0; + unsigned Parent = 0; + unsigned Semi = 0; + NodePtr Label = nullptr; + }; + + std::vector NumToNode; + DenseMap NodeToInfo; + }; + template friend typename GraphT::NodeRef Eval( DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, - const std::vector &NumToNode, + typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info, unsigned LastLinked); template friend unsigned ReverseDFSPass( DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, - std::vector &NumToNode, unsigned N); + typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info, + unsigned N); template - friend unsigned DFSPass(DominatorTreeBaseByGraphTraits &DT, - typename GraphT::NodeRef V, - std::vector &NumToNode, - unsigned N); + friend unsigned DFSPass( + DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, + typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info, + unsigned N); template friend void Calculate(DominatorTreeBaseByGraphTraits> &DT, Index: include/llvm/Support/GenericDomTreeConstruction.h =================================================================== --- include/llvm/Support/GenericDomTreeConstruction.h +++ include/llvm/Support/GenericDomTreeConstruction.h @@ -49,26 +49,27 @@ }; template -unsigned ReverseDFSPass(DominatorTreeBaseByGraphTraits &DT, - typename GraphT::NodeRef V, - std::vector &NumToNode, - unsigned N) { - df_iterator_dom_storage< - typename GraphT::NodeRef, - typename DominatorTreeBaseByGraphTraits::InfoRec> - DFStorage(DT.Info); +unsigned ReverseDFSPass( + DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, + typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA, + unsigned N) { + using SNCAInfoTy = typename std::remove_reference::type; + df_iterator_dom_storage + DFStorage(SNCA.NodeToInfo); + bool IsChildOfArtificialExit = (N != 0); for (auto I = idf_ext_begin(V, DFStorage), E = idf_ext_end(V, DFStorage); I != E; ++I) { typename GraphT::NodeRef BB = *I; - auto &BBInfo = DT.Info[BB]; + auto &BBInfo = SNCA.NodeToInfo[BB]; BBInfo.DFSNum = BBInfo.Semi = ++N; BBInfo.Label = BB; // Set the parent to the top of the visited stack. The stack includes us, // and is 1 based, so we subtract to account for both of these. if (I.getPathLength() > 1) - BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum; - NumToNode.push_back(BB); // NumToNode[n] = V; + BBInfo.Parent = SNCA.NodeToInfo[I.getPath(I.getPathLength() - 2)].DFSNum; + SNCA.NumToNode.push_back(BB); // NumToNode[n] = V; if (IsChildOfArtificialExit) BBInfo.Parent = 1; @@ -78,24 +79,25 @@ return N; } template -unsigned DFSPass(DominatorTreeBaseByGraphTraits &DT, - typename GraphT::NodeRef V, - std::vector &NumToNode, unsigned N) { - df_iterator_dom_storage< - typename GraphT::NodeRef, - typename DominatorTreeBaseByGraphTraits::InfoRec> - DFStorage(DT.Info); +unsigned DFSPass( + DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V, + typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA, + unsigned N) { + using SNCAInfoTy = typename std::remove_reference::type; + df_iterator_dom_storage + DFStorage(SNCA.NodeToInfo); for (auto I = df_ext_begin(V, DFStorage), E = df_ext_end(V, DFStorage); I != E; ++I) { typename GraphT::NodeRef BB = *I; - auto &BBInfo = DT.Info[BB]; + auto &BBInfo = SNCA.NodeToInfo[BB]; BBInfo.DFSNum = BBInfo.Semi = ++N; BBInfo.Label = BB; // Set the parent to the top of the visited stack. The stack includes us, // and is 1 based, so we subtract to account for both of these. if (I.getPathLength() > 1) - BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum; - NumToNode.push_back(BB); // NumToNode[n] = V; + BBInfo.Parent = SNCA.NodeToInfo[I.getPath(I.getPathLength() - 2)].DFSNum; + SNCA.NumToNode.push_back(BB); // NumToNode[n] = V; } return N; } @@ -103,11 +105,11 @@ template typename GraphT::NodeRef Eval( DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef VIn, - const std::vector &NumToNode, + typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA, unsigned LastLinked) { using NodePtr = typename GraphT::NodeRef; - auto &VInInfo = DT.Info[VIn]; + auto &VInInfo = SNCA.NodeToInfo[VIn]; if (VInInfo.DFSNum < LastLinked) return VIn; @@ -119,8 +121,8 @@ while (!Work.empty()) { NodePtr V = Work.back(); - auto &VInfo = DT.Info[V]; - NodePtr VAncestor = NumToNode[VInfo.Parent]; + auto &VInfo = SNCA.NodeToInfo[V]; + NodePtr VAncestor = SNCA.NumToNode[VInfo.Parent]; // Process Ancestor first if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) { @@ -133,10 +135,10 @@ if (VInfo.Parent < LastLinked) continue; - auto &VAInfo = DT.Info[VAncestor]; + auto &VAInfo = SNCA.NodeToInfo[VAncestor]; NodePtr VAncestorLabel = VAInfo.Label; NodePtr VLabel = VInfo.Label; - if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) + if (SNCA.NodeToInfo[VAncestorLabel].Semi < SNCA.NodeToInfo[VLabel].Semi) VInfo.Label = VAncestorLabel; VInfo.Parent = VAInfo.Parent; } @@ -157,15 +159,16 @@ using NodeType = typename std::remove_pointer::type; unsigned N = 0; - std::vector NumToNode = {nullptr}; + typename DominatorTreeBaseByGraphTraits::SemiNCAInfo SNCA; + SNCA.NumToNode.push_back(nullptr); bool MultipleRoots = (DT.Roots.size() > 1); if (MultipleRoots) { - auto &BBInfo = DT.Info[nullptr]; + auto &BBInfo = SNCA.NodeToInfo[nullptr]; BBInfo.DFSNum = BBInfo.Semi = ++N; BBInfo.Label = nullptr; - NumToNode.push_back(nullptr); // NumToNode[n] = V; + SNCA.NumToNode.push_back(nullptr); // NumToNode[n] = V; } // Step #1: Number blocks in depth-first order and initialize variables used @@ -173,9 +176,9 @@ if (DT.isPostDominator()){ for (unsigned i = 0, e = static_cast(DT.Roots.size()); i != e; ++i) - N = ReverseDFSPass(DT, DT.Roots[i], NumToNode, N); + N = ReverseDFSPass(DT, DT.Roots[i], SNCA, N); } else { - N = DFSPass(DT, DT.Roots[0], NumToNode, N); + N = DFSPass(DT, DT.Roots[0], SNCA, N); } // It might be that some blocks did not get a DFS number (e.g., blocks of @@ -184,20 +187,20 @@ // Initialize IDoms to spanning tree parents. for (unsigned i = 1; i <= N; ++i) { - const NodePtr V = NumToNode[i]; - DT.IDoms[V] = NumToNode[DT.Info[V].Parent]; + const NodePtr V = SNCA.NumToNode[i]; + DT.IDoms[V] = SNCA.NumToNode[SNCA.NodeToInfo[V].Parent]; } // Step #2: Calculate the semidominators of all vertices. for (unsigned i = N; i >= 2; --i) { - NodePtr W = NumToNode[i]; - auto &WInfo = DT.Info[W]; + NodePtr W = SNCA.NumToNode[i]; + auto &WInfo = SNCA.NodeToInfo[W]; // Initialize the semi dominator to point to the parent node. WInfo.Semi = WInfo.Parent; for (const auto &N : inverse_children(W)) - if (DT.Info.count(N)) { // Only if this predecessor is reachable! - unsigned SemiU = DT.Info[Eval(DT, N, NumToNode, i + 1)].Semi; + if (SNCA.NodeToInfo.count(N)) { // Only if this predecessor is reachable! + unsigned SemiU = SNCA.NodeToInfo[Eval(DT, N, SNCA, i + 1)].Semi; if (SemiU < WInfo.Semi) WInfo.Semi = SemiU; } @@ -208,11 +211,11 @@ // Note that the parents were stored in IDoms and later got invalidated during // path compression in Eval. for (unsigned i = 2; i <= N; ++i) { - const NodePtr W = NumToNode[i]; - const auto &WInfo = DT.Info[W]; - const unsigned SDomNum = DT.Info[NumToNode[WInfo.Semi]].DFSNum; + const NodePtr W = SNCA.NumToNode[i]; + const auto &WInfo = SNCA.NodeToInfo[W]; + const unsigned SDomNum = SNCA.NodeToInfo[SNCA.NumToNode[WInfo.Semi]].DFSNum; NodePtr WIDomCandidte = DT.IDoms[W]; - while (DT.Info[WIDomCandidte].DFSNum > SDomNum) + while (SNCA.NodeToInfo[WIDomCandidte].DFSNum > SDomNum) WIDomCandidte = DT.IDoms[WIDomCandidte]; DT.IDoms[W] = WIDomCandidte; @@ -233,7 +236,7 @@ // Loop over all of the reachable blocks in the function... for (unsigned i = 2; i <= N; ++i) { - NodePtr W = NumToNode[i]; + NodePtr W = SNCA.NumToNode[i]; // Don't replace this with 'count', the insertion side effect is important if (DT.DomTreeNodes[W]) @@ -254,7 +257,6 @@ // Free temporary memory used to construct idom's DT.IDoms.clear(); - DT.Info.clear(); } }