diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h index 6d95a4b38e9..063602e92f2 100644 --- a/include/llvm/Analysis/DominatorInternals.h +++ b/include/llvm/Analysis/DominatorInternals.h @@ -233,14 +233,7 @@ void Calculate(DominatorTreeBase::NodeType>& DT, typedef GraphTraits GraphT; unsigned N = 0; - - // Add a node for the root. This node might be the actual root, if there is - // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) - // which postdominates all real exits if there are multiple exit blocks. - typename GraphT::NodeType* Root = DT.Roots.size() == 1 ? DT.Roots[0] - : 0; bool MultipleRoots = (DT.Roots.size() > 1); - if (MultipleRoots) { typename DominatorTreeBase::InfoRec &BBInfo = DT.Info[NULL]; @@ -258,6 +251,10 @@ void Calculate(DominatorTreeBase::NodeType>& DT, for (unsigned i = 0, e = DT.Roots.size(); i != e; ++i) N = DFSPass(DT, DT.Roots[i], N); + // it might be that some blocks did not get a DFS number (e.g., blocks of + // infinite loops). In these cases an artificial exit node is required. + MultipleRoots |= (DT.isPostDominator() && N != F.size()); + for (unsigned i = N; i >= 2; --i) { typename GraphT::NodeType* W = DT.Vertex[i]; typename DominatorTreeBase::InfoRec &WInfo = @@ -311,15 +308,18 @@ void Calculate(DominatorTreeBase::NodeType>& DT, if (WIDom != DT.Vertex[DT.Info[W].Semi]) WIDom = DT.IDoms[WIDom]; } - + if (DT.Roots.empty()) return; - + // Add a node for the root. This node might be the actual root, if there is // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) - // which postdominates all real exits if there are multiple exit blocks. + // which postdominates all real exits if there are multiple exit blocks, or + // an infinite loop. + typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0; + DT.DomTreeNodes[Root] = DT.RootNode = new DomTreeNodeBase(Root, 0); - + // Loop over all of the reachable blocks in the function... for (unsigned i = 2; i <= N; ++i) { typename GraphT::NodeType* W = DT.Vertex[i]; @@ -329,20 +329,12 @@ void Calculate(DominatorTreeBase::NodeType>& DT, typename GraphT::NodeType* ImmDom = DT.getIDom(W); - // skip all non root nodes that have no dominator - this occures with - // infinite loops. - if (!ImmDom && std::count(DT.Roots.begin(), DT.Roots.end(), W) == 0) - continue; + assert(ImmDom || DT.DomTreeNodes[NULL]); // Get or calculate the node for the immediate dominator DomTreeNodeBase *IDomNode = DT.getNodeForBlock(ImmDom); - // skip all children that are dominated by a non root node that, by itself, - // has no dominator. - if (!IDomNode) - continue; - // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode DomTreeNodeBase *C = diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index 11c0bc234ca..ad1766c85ab 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -605,17 +605,9 @@ protected: // immediate dominator. NodeT *IDom = getIDom(BB); - // skip all non root nodes that have no dominator - if (!IDom && std::count(this->Roots.begin(), this->Roots.end(), BB) == 0) - return NULL; - + assert(IDom || this->DomTreeNodes[NULL]); DomTreeNodeBase *IDomNode = getNodeForBlock(IDom); - // skip all nodes that are dominated by a non root node that, by itself, - // has no dominator. - if (!IDomNode) - return NULL; - // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode DomTreeNodeBase *C = new DomTreeNodeBase(BB, IDomNode); diff --git a/test/Analysis/PostDominators/dg.exp b/test/Analysis/PostDominators/dg.exp new file mode 100644 index 00000000000..879685ca879 --- /dev/null +++ b/test/Analysis/PostDominators/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] diff --git a/test/Analysis/PostDominators/pr1098.ll b/test/Analysis/PostDominators/pr1098.ll new file mode 100644 index 00000000000..b54a9fe1c75 --- /dev/null +++ b/test/Analysis/PostDominators/pr1098.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | opt -postdomtree -analyze | grep entry +; PR932 + +define void @foo(i1 %x) { +entry: + br i1 %x, label %bb1, label %bb0 +bb0: ; preds = %entry, bb0 + br label %bb0 +bb1: ; preds = %entry + br label %bb2 +bb2: ; preds = %bb1 + ret void +} +