diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index e35e101de39..896664c1c10 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -348,10 +348,12 @@ public: /// Get all nodes dominated by R, including R itself. void getDescendants(NodeT *R, SmallVectorImpl &Result) const { + Result.clear(); const DomTreeNodeBase *RN = getNode(R); + if (RN == NULL) + return; // If R is unreachable, it will not be present in the DOM tree. SmallVector *, 8> WL; WL.push_back(RN); - Result.clear(); while (!WL.empty()) { const DomTreeNodeBase *N = WL.pop_back_val(); diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp index 4e5af9395cc..387d7326601 100644 --- a/unittests/IR/DominatorTreeTest.cpp +++ b/unittests/IR/DominatorTreeTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/Assembly/Parser.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" @@ -26,6 +27,7 @@ namespace llvm { static char ID; virtual bool runOnFunction(Function &F) { DominatorTree *DT = &getAnalysis(); + PostDominatorTree *PDT = &getAnalysis(); Function::iterator FI = F.begin(); BasicBlock *BB0 = FI++; @@ -148,10 +150,34 @@ namespace llvm { EXPECT_TRUE(DT->dominates(Y6, BB3)); + // Post dominance. + EXPECT_TRUE(PDT->dominates(BB0, BB0)); + EXPECT_FALSE(PDT->dominates(BB1, BB0)); + EXPECT_FALSE(PDT->dominates(BB2, BB0)); + EXPECT_FALSE(PDT->dominates(BB3, BB0)); + EXPECT_TRUE(PDT->dominates(BB4, BB1)); + + // Dominance descendants. + SmallVector DominatedBBs, PostDominatedBBs; + + DT->getDescendants(BB0, DominatedBBs); + PDT->getDescendants(BB0, PostDominatedBBs); + EXPECT_EQ(DominatedBBs.size(), 4UL); + EXPECT_EQ(PostDominatedBBs.size(), 1UL); + + // BB3 is unreachable. It should have no dominators nor postdominators. + DominatedBBs.clear(); + PostDominatedBBs.clear(); + DT->getDescendants(BB3, DominatedBBs); + DT->getDescendants(BB3, PostDominatedBBs); + EXPECT_EQ(DominatedBBs.size(), 0UL); + EXPECT_EQ(PostDominatedBBs.size(), 0UL); + return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); } DPass() : FunctionPass(ID) { initializeDPassPass(*PassRegistry::getPassRegistry()); @@ -201,4 +227,5 @@ namespace llvm { INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)