<div dir="ltr">Rafael,<br><br>Thanks for telling me about the failing test.<br><br>There was a missing null checks that caused <span style="font-size:12.8px">CodeGen/ARM/2011-02-07-</span><wbr style="font-size:12.8px"><span style="font-size:12.8px">AntidepClobber.ll to fail.<br><br>I fixed the issue and reapplied the patch in r</span>306919.<br><br>Best,<br>~Kuba</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 30, 2017 at 3:57 PM, Jakub (Kuba) Kuderski <span dir="ltr"><<a href="mailto:kubakuderski@gmail.com" target="_blank">kubakuderski@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Reverted in r306907.</div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On Fri, Jun 30, 2017 at 3:52 PM, Jakub (Kuba) Kuderski <span dir="ltr"><<a href="mailto:kubakuderski@gmail.com" target="_blank">kubakuderski@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Reverting now.<br></div><div class="gmail_extra"><div><div class="m_-5447481841382877418h5"><br><div class="gmail_quote">On Fri, Jun 30, 2017 at 3:40 PM, Rafael Avila de Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is crashing on<br>
<br>
CodeGen/ARM/2011-02-07-Antidep<wbr>Clobber.ll<br>
<br>
Cheers,<br>
Rafael<br>
<div class="m_-5447481841382877418m_4726431574129168926HOEnZb"><div class="m_-5447481841382877418m_4726431574129168926h5"><br>
Jakub Kuderski via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> writes:<br>
<br>
> Author: kuhar<br>
> Date: Fri Jun 30 14:51:40 2017<br>
> New Revision: 306892<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=306892&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=306892&view=rev</a><br>
> Log:<br>
> [Dominators] Keep tree level in DomTreeNode and use it to find NCD and answer dominance queries<br>
><br>
> Summary:<br>
> This patch makes DomTreeNodes keep their level (depth) in the DomTree. By having this information always available, it is possible to speedup and simplify findNearestCommonDominator and certain dominance queries.<br>
><br>
> In the future, level information will be also needed to perform incremental updates.<br>
><br>
> My testing doesn't show any noticeable performance differences after applying this patch. There may be some improvements when other passes are thought to use the level information.<br>
><br>
> Reviewers: dberlin, sanjoy, chandlerc, grosser<br>
><br>
> Reviewed By: dberlin<br>
><br>
> Subscribers: llvm-commits<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D34548" rel="noreferrer" target="_blank">https://reviews.llvm.org/D3454<wbr>8</a><br>
><br>
> Modified:<br>
> llvm/trunk/include/llvm/Suppo<wbr>rt/GenericDomTree.h<br>
> llvm/trunk/include/llvm/Suppo<wbr>rt/GenericDomTreeConstruction.<wbr>h<br>
> llvm/trunk/unittests/IR/Domin<wbr>atorTreeTest.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTree.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/GenericDomTree.h?rev=306892&r1=306891&r2=306892&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>Support/GenericDomTree.h?rev=3<wbr>06892&r1=306891&r2=306892&view<wbr>=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTree.h (original)<br>
> +++ llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTree.h Fri Jun 30 14:51:40 2017<br>
> @@ -65,12 +65,14 @@ template <class NodeT> class DomTreeNode<br>
><br>
> NodeT *TheBB;<br>
> DomTreeNodeBase *IDom;<br>
> + unsigned Level;<br>
> std::vector<DomTreeNodeBase *> Children;<br>
> mutable unsigned DFSNumIn = ~0;<br>
> mutable unsigned DFSNumOut = ~0;<br>
><br>
> public:<br>
> - DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom) : TheBB(BB), IDom(iDom) {}<br>
> + DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom)<br>
> + : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}<br>
><br>
> using iterator = typename std::vector<DomTreeNodeBase *>::iterator;<br>
> using const_iterator =<br>
> @@ -83,6 +85,7 @@ template <class NodeT> class DomTreeNode<br>
><br>
> NodeT *getBlock() const { return TheBB; }<br>
> DomTreeNodeBase *getIDom() const { return IDom; }<br>
> + unsigned getLevel() const { return Level; }<br>
><br>
> const std::vector<DomTreeNodeBase *> &getChildren() const { return Children; }<br>
><br>
> @@ -100,6 +103,8 @@ template <class NodeT> class DomTreeNode<br>
> if (getNumChildren() != Other->getNumChildren())<br>
> return true;<br>
><br>
> + if (Level != Other->Level) return true;<br>
> +<br>
> SmallPtrSet<const NodeT *, 4> OtherChildren;<br>
> for (const DomTreeNodeBase *I : *Other) {<br>
> const NodeT *Nd = I->getBlock();<br>
> @@ -116,18 +121,19 @@ template <class NodeT> class DomTreeNode<br>
><br>
> void setIDom(DomTreeNodeBase *NewIDom) {<br>
> assert(IDom && "No immediate dominator?");<br>
> - if (IDom != NewIDom) {<br>
> - typename std::vector<DomTreeNodeBase *>::iterator I =<br>
> - find(IDom->Children, this);<br>
> - assert(I != IDom->Children.end() &&<br>
> - "Not in immediate dominator children set!");<br>
> - // I am no longer your child...<br>
> - IDom->Children.erase(I);<br>
> -<br>
> - // Switch to new dominator<br>
> - IDom = NewIDom;<br>
> - IDom->Children.push_back(this)<wbr>;<br>
> - }<br>
> + if (IDom == NewIDom) return;<br>
> +<br>
> + auto I = find(IDom->Children, this);<br>
> + assert(I != IDom->Children.end() &&<br>
> + "Not in immediate dominator children set!");<br>
> + // I am no longer your child...<br>
> + IDom->Children.erase(I);<br>
> +<br>
> + // Switch to new dominator<br>
> + IDom = NewIDom;<br>
> + IDom->Children.push_back(this)<wbr>;<br>
> +<br>
> + UpdateLevel();<br>
> }<br>
><br>
> /// getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes<br>
> @@ -143,6 +149,23 @@ private:<br>
> return this->DFSNumIn >= other->DFSNumIn &&<br>
> this->DFSNumOut <= other->DFSNumOut;<br>
> }<br>
> +<br>
> + void UpdateLevel() {<br>
> + assert(IDom);<br>
> + if (Level == IDom->Level + 1) return;<br>
> +<br>
> + SmallVector<DomTreeNodeBase *, 64> WorkStack = {this};<br>
> +<br>
> + while (!WorkStack.empty()) {<br>
> + DomTreeNodeBase *Current = WorkStack.pop_back_val();<br>
> + Current->Level = Current->IDom->Level + 1;<br>
> +<br>
> + for (DomTreeNodeBase *C : *Current) {<br>
> + assert(C->IDom);<br>
> + if (C->Level != C->IDom->Level + 1) WorkStack.push_back(C);<br>
> + }<br>
> + }<br>
> + }<br>
> };<br>
><br>
> template <class NodeT><br>
> @@ -152,9 +175,10 @@ raw_ostream &operator<<(raw_ostream &O,<br>
> else<br>
> O << " <<exit node>>";<br>
><br>
> - O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";<br>
> + O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "} ["<br>
> + << Node->getLevel() << "]\n";<br>
><br>
> - return O << "\n";<br>
> + return O;<br>
> }<br>
><br>
> template <class NodeT><br>
> @@ -345,6 +369,13 @@ template <class NodeT> class DominatorTr<br>
> if (!isReachableFromEntry(A))<br>
> return false;<br>
><br>
> + if (B->getIDom() == A) return true;<br>
> +<br>
> + if (A->getIDom() == B) return false;<br>
> +<br>
> + // A can only dominate B if it is higher in the tree.<br>
> + if (A->getLevel() >= B->getLevel()) return false;<br>
> +<br>
> // Compare the result of the tree walk and the dfs numbers, if expensive<br>
> // checks are enabled.<br>
> #ifdef EXPENSIVE_CHECKS<br>
> @@ -388,51 +419,18 @@ template <class NodeT> class DominatorTr<br>
> return &Entry;<br>
> }<br>
><br>
> - // If B dominates A then B is nearest common dominator.<br>
> - if (dominates(B, A))<br>
> - return B;<br>
> -<br>
> - // If A dominates B then A is nearest common dominator.<br>
> - if (dominates(A, B))<br>
> - return A;<br>
> -<br>
> DomTreeNodeBase<NodeT> *NodeA = getNode(A);<br>
> DomTreeNodeBase<NodeT> *NodeB = getNode(B);<br>
><br>
> - // If we have DFS info, then we can avoid all allocations by just querying<br>
> - // it from each IDom. Note that because we call 'dominates' twice above, we<br>
> - // expect to call through this code at most 16 times in a row without<br>
> - // building valid DFS information. This is important as below is a *very*<br>
> - // slow tree walk.<br>
> - if (DFSInfoValid) {<br>
> - DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();<br>
> - while (IDomA) {<br>
> - if (NodeB->DominatedBy(IDomA))<br>
> - return IDomA->getBlock();<br>
> - IDomA = IDomA->getIDom();<br>
> - }<br>
> - return nullptr;<br>
> - }<br>
> + // Use level information to go up the tree until the levels match. Then<br>
> + // continue going up til we arrive at the same node.<br>
> + while (NodeA && NodeA != NodeB) {<br>
> + if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB);<br>
><br>
> - // Collect NodeA dominators set.<br>
> - SmallPtrSet<DomTreeNodeBase<No<wbr>deT> *, 16> NodeADoms;<br>
> - NodeADoms.insert(NodeA);<br>
> - DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();<br>
> - while (IDomA) {<br>
> - NodeADoms.insert(IDomA);<br>
> - IDomA = IDomA->getIDom();<br>
> + NodeA = NodeA->IDom;<br>
> }<br>
><br>
> - // Walk NodeB immediate dominators chain and find common dominator node.<br>
> - DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom();<br>
> - while (IDomB) {<br>
> - if (NodeADoms.count(IDomB) != 0)<br>
> - return IDomB->getBlock();<br>
> -<br>
> - IDomB = IDomB->getIDom();<br>
> - }<br>
> -<br>
> - return nullptr;<br>
> + return NodeA ? NodeA->getBlock() : nullptr;<br>
> }<br>
><br>
> const NodeT *findNearestCommonDominator(co<wbr>nst NodeT *A, const NodeT *B) {<br>
> @@ -481,8 +479,10 @@ template <class NodeT> class DominatorTr<br>
> } else {<br>
> assert(Roots.size() == 1);<br>
> NodeT *OldRoot = Roots.front();<br>
> - DomTreeNodes[OldRoot] =<br>
> - NewNode->addChild(std::move(Do<wbr>mTreeNodes[OldRoot]));<br>
> + auto &OldNode = DomTreeNodes[OldRoot];<br>
> + OldNode = NewNode->addChild(std::move(Do<wbr>mTreeNodes[OldRoot]));<br>
> + OldNode->IDom = NewNode;<br>
> + OldNode->UpdateLevel();<br>
> Roots[0] = BB;<br>
> }<br>
> return RootNode = NewNode;<br>
><br>
> Modified: llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTreeConstruction.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h?rev=306892&r1=306891&r2=306892&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>Support/GenericDomTreeConstruc<wbr>tion.h?rev=306892&r1=306891&r2<wbr>=306892&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTreeConstruction.h (original)<br>
> +++ llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTreeConstruction.h Fri Jun 30 14:51:40 2017<br>
> @@ -318,6 +318,39 @@ struct SemiNCAInfo {<br>
> return true;<br>
> }<br>
><br>
> + // Check if for every parent with a level L in the tree all of its children<br>
> + // have level L + 1.<br>
> + static bool VerifyLevels(const DomTreeT &DT) {<br>
> + for (auto &NodeToTN : DT.DomTreeNodes) {<br>
> + const TreeNodePtr TN = NodeToTN.second.get();<br>
> + const NodePtr BB = TN->getBlock();<br>
> + if (!BB) continue;<br>
> +<br>
> + const TreeNodePtr IDom = TN->getIDom();<br>
> + if (!IDom && TN->getLevel() != 0) {<br>
> + errs() << "Node without an IDom ";<br>
> + PrintBlockOrNullptr(errs(), BB);<br>
> + errs() << " has a nonzero level " << TN->getLevel() << "!\n";<br>
> + errs().flush();<br>
> +<br>
> + return false;<br>
> + }<br>
> +<br>
> + if (IDom && TN->getLevel() != IDom->getLevel() + 1) {<br>
> + errs() << "Node ";<br>
> + PrintBlockOrNullptr(errs(), BB);<br>
> + errs() << " has level " << TN->getLevel() << " while it's IDom ";<br>
> + PrintBlockOrNullptr(errs(), IDom->getBlock());<br>
> + errs() << " has level " << IDom->getLevel() << "!\n";<br>
> + errs().flush();<br>
> +<br>
> + return false;<br>
> + }<br>
> + }<br>
> +<br>
> + return true;<br>
> + }<br>
> +<br>
> // Checks if the tree has the parent property: if for all edges from V to W in<br>
> // the input graph, such that V is reachable, the parent of W in the tree is<br>
> // an ancestor of V in the tree.<br>
> @@ -405,9 +438,8 @@ bool Verify(const DominatorTreeBaseByGra<br>
> "NodePtr should be a pointer type");<br>
> SemiNCAInfo<typename std::remove_pointer<NodePtr>::<wbr>type> SNCA;<br>
><br>
> - return SNCA.verifyReachability(DT) && SNCA.verifyParentProperty(DT) &&<br>
> - SNCA.verifySiblingProperty(DT<wbr>);<br>
> -<br>
> + return SNCA.verifyReachability(DT) && SNCA.VerifyLevels(DT) &&<br>
> + SNCA.verifyParentProperty(DT) && SNCA.verifySiblingProperty(DT)<wbr>;<br>
> }<br>
><br>
> } // namespace DomTreeBuilder<br>
><br>
> Modified: llvm/trunk/unittests/IR/Domina<wbr>torTreeTest.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/DominatorTreeTest.cpp?rev=306892&r1=306891&r2=306892&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/unittests/IR/<wbr>DominatorTreeTest.cpp?rev=3068<wbr>92&r1=306891&r2=306892&view=di<wbr>ff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/unittests/IR/Domina<wbr>torTreeTest.cpp (original)<br>
> +++ llvm/trunk/unittests/IR/Domina<wbr>torTreeTest.cpp Fri Jun 30 14:51:40 2017<br>
> @@ -230,6 +230,12 @@ TEST(DominatorTree, Unreachable) {<br>
> EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumIn(), 3UL);<br>
> EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumOut(), 4UL);<br>
><br>
> + // Check levels before<br>
> + EXPECT_EQ(DT->getNode(BB0)->ge<wbr>tLevel(), 0U);<br>
> + EXPECT_EQ(DT->getNode(BB1)->ge<wbr>tLevel(), 1U);<br>
> + EXPECT_EQ(DT->getNode(BB2)->ge<wbr>tLevel(), 1U);<br>
> + EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tLevel(), 1U);<br>
> +<br>
> // Reattach block 3 to block 1 and recalculate<br>
> BB1->getTerminator()->eraseFro<wbr>mParent();<br>
> BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getCont<wbr>ext()), BB1);<br>
> @@ -248,6 +254,13 @@ TEST(DominatorTree, Unreachable) {<br>
> EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumIn(), 5UL);<br>
> EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumOut(), 6UL);<br>
><br>
> + // Check levels after<br>
> + EXPECT_EQ(DT->getNode(BB0)->ge<wbr>tLevel(), 0U);<br>
> + EXPECT_EQ(DT->getNode(BB1)->ge<wbr>tLevel(), 1U);<br>
> + EXPECT_EQ(DT->getNode(BB2)->ge<wbr>tLevel(), 1U);<br>
> + EXPECT_EQ(DT->getNode(BB3)->ge<wbr>tLevel(), 2U);<br>
> + EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tLevel(), 1U);<br>
> +<br>
> // Change root node<br>
> DT->verifyDomTree();<br>
> BasicBlock *NewEntry =<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div></div></div><span class="m_-5447481841382877418HOEnZb"><font color="#888888">-- <br><div class="m_-5447481841382877418m_4726431574129168926gmail_signature" data-smartmail="gmail_signature"><div>Jakub Kuderski</div></div>
</font></span></div>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div class="m_-5447481841382877418gmail_signature" data-smartmail="gmail_signature"><div>Jakub Kuderski</div></div>
</font></span></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div>Jakub Kuderski</div></div>
</div>