forked from OSchip/llvm-project
Fix dominator descendants for unreachable blocks.
When a block is unreachable, asking its dom tree descendants should return the empty set. However, the computation of the descendants was causing a segmentation fault because the dom tree node we get from the basic block is initially NULL. Fixed by adding a test for a valid dom tree node before we iterate. The patch also adds some unit tests to the existing dom tree tests. llvm-svn: 196099
This commit is contained in:
parent
c0378e72d1
commit
ee592429f1
|
@ -348,10 +348,12 @@ public:
|
||||||
|
|
||||||
/// Get all nodes dominated by R, including R itself.
|
/// Get all nodes dominated by R, including R itself.
|
||||||
void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
|
void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
|
||||||
|
Result.clear();
|
||||||
const DomTreeNodeBase<NodeT> *RN = getNode(R);
|
const DomTreeNodeBase<NodeT> *RN = getNode(R);
|
||||||
|
if (RN == NULL)
|
||||||
|
return; // If R is unreachable, it will not be present in the DOM tree.
|
||||||
SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
|
SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
|
||||||
WL.push_back(RN);
|
WL.push_back(RN);
|
||||||
Result.clear();
|
|
||||||
|
|
||||||
while (!WL.empty()) {
|
while (!WL.empty()) {
|
||||||
const DomTreeNodeBase<NodeT> *N = WL.pop_back_val();
|
const DomTreeNodeBase<NodeT> *N = WL.pop_back_val();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
|
#include "llvm/Analysis/PostDominators.h"
|
||||||
#include "llvm/Assembly/Parser.h"
|
#include "llvm/Assembly/Parser.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
|
@ -26,6 +27,7 @@ namespace llvm {
|
||||||
static char ID;
|
static char ID;
|
||||||
virtual bool runOnFunction(Function &F) {
|
virtual bool runOnFunction(Function &F) {
|
||||||
DominatorTree *DT = &getAnalysis<DominatorTree>();
|
DominatorTree *DT = &getAnalysis<DominatorTree>();
|
||||||
|
PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>();
|
||||||
Function::iterator FI = F.begin();
|
Function::iterator FI = F.begin();
|
||||||
|
|
||||||
BasicBlock *BB0 = FI++;
|
BasicBlock *BB0 = FI++;
|
||||||
|
@ -148,10 +150,34 @@ namespace llvm {
|
||||||
|
|
||||||
EXPECT_TRUE(DT->dominates(Y6, BB3));
|
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<BasicBlock *, 8> 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;
|
return false;
|
||||||
}
|
}
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequired<DominatorTree>();
|
AU.addRequired<DominatorTree>();
|
||||||
|
AU.addRequired<PostDominatorTree>();
|
||||||
}
|
}
|
||||||
DPass() : FunctionPass(ID) {
|
DPass() : FunctionPass(ID) {
|
||||||
initializeDPassPass(*PassRegistry::getPassRegistry());
|
initializeDPassPass(*PassRegistry::getPassRegistry());
|
||||||
|
@ -201,4 +227,5 @@ namespace llvm {
|
||||||
|
|
||||||
INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false)
|
INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false)
|
||||||
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
|
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
|
||||||
|
INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
|
||||||
INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)
|
INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)
|
||||||
|
|
Loading…
Reference in New Issue