forked from OSchip/llvm-project
Rearrange Dom unittest to accommodate multiple tests
I've taken the approach from the LoopInfo test: * Rather than running in the pass manager just build the analyses manually * Split out the common parts (makeLLVMModule, runWithDomTree) into helpers Differential Revision: https://reviews.llvm.org/D33617 llvm-svn: 304061
This commit is contained in:
parent
7fa6dee2e3
commit
147ede9a08
|
@ -13,219 +13,37 @@
|
|||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
void initializeDPassPass(PassRegistry &);
|
||||
/// Build the dominator tree for the function and run the Test.
|
||||
static void
|
||||
runWithDomTree(Module &M, StringRef FuncName,
|
||||
function_ref<void(Function &F, DominatorTree *DT,
|
||||
DominatorTreeBase<BasicBlock> *PDT)>
|
||||
Test) {
|
||||
auto *F = M.getFunction(FuncName);
|
||||
ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
|
||||
// Compute the dominator tree for the function.
|
||||
DominatorTree DT(*F);
|
||||
DominatorTreeBase<BasicBlock> PDT(/*isPostDom*/ true);
|
||||
PDT.recalculate(*F);
|
||||
Test(*F, &DT, &PDT);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct DPass : public FunctionPass {
|
||||
static char ID;
|
||||
bool runOnFunction(Function &F) override {
|
||||
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
PostDominatorTree *PDT =
|
||||
&getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
|
||||
Function::iterator FI = F.begin();
|
||||
static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
|
||||
StringRef ModuleStr) {
|
||||
SMDiagnostic Err;
|
||||
std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
|
||||
assert(M && "Bad assembly?");
|
||||
return M;
|
||||
}
|
||||
|
||||
BasicBlock *BB0 = &*FI++;
|
||||
BasicBlock::iterator BBI = BB0->begin();
|
||||
Instruction *Y1 = &*BBI++;
|
||||
Instruction *Y2 = &*BBI++;
|
||||
Instruction *Y3 = &*BBI++;
|
||||
|
||||
BasicBlock *BB1 = &*FI++;
|
||||
BBI = BB1->begin();
|
||||
Instruction *Y4 = &*BBI++;
|
||||
|
||||
BasicBlock *BB2 = &*FI++;
|
||||
BBI = BB2->begin();
|
||||
Instruction *Y5 = &*BBI++;
|
||||
|
||||
BasicBlock *BB3 = &*FI++;
|
||||
BBI = BB3->begin();
|
||||
Instruction *Y6 = &*BBI++;
|
||||
Instruction *Y7 = &*BBI++;
|
||||
|
||||
BasicBlock *BB4 = &*FI++;
|
||||
BBI = BB4->begin();
|
||||
Instruction *Y8 = &*BBI++;
|
||||
Instruction *Y9 = &*BBI++;
|
||||
|
||||
// Reachability
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB0));
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB1));
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB2));
|
||||
EXPECT_FALSE(DT->isReachableFromEntry(BB3));
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB4));
|
||||
|
||||
// BB dominance
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB0));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB1));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB3));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(BB1, BB0));
|
||||
EXPECT_TRUE(DT->dominates(BB1, BB1));
|
||||
EXPECT_FALSE(DT->dominates(BB1, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB1, BB3));
|
||||
EXPECT_FALSE(DT->dominates(BB1, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(BB2, BB0));
|
||||
EXPECT_FALSE(DT->dominates(BB2, BB1));
|
||||
EXPECT_TRUE(DT->dominates(BB2, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB2, BB3));
|
||||
EXPECT_FALSE(DT->dominates(BB2, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB0));
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB1));
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB3, BB3));
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB4));
|
||||
|
||||
// BB proper dominance
|
||||
EXPECT_FALSE(DT->properlyDominates(BB0, BB0));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB0, BB1));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB0, BB2));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB0, BB3));
|
||||
|
||||
EXPECT_FALSE(DT->properlyDominates(BB1, BB0));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB1, BB1));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB1, BB2));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB1, BB3));
|
||||
|
||||
EXPECT_FALSE(DT->properlyDominates(BB2, BB0));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB2, BB1));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB2, BB2));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB2, BB3));
|
||||
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB0));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB1));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB2));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB3));
|
||||
|
||||
// Instruction dominance in the same reachable BB
|
||||
EXPECT_FALSE(DT->dominates(Y1, Y1));
|
||||
EXPECT_TRUE(DT->dominates(Y1, Y2));
|
||||
EXPECT_FALSE(DT->dominates(Y2, Y1));
|
||||
EXPECT_FALSE(DT->dominates(Y2, Y2));
|
||||
|
||||
// Instruction dominance in the same unreachable BB
|
||||
EXPECT_TRUE(DT->dominates(Y6, Y6));
|
||||
EXPECT_TRUE(DT->dominates(Y6, Y7));
|
||||
EXPECT_TRUE(DT->dominates(Y7, Y6));
|
||||
EXPECT_TRUE(DT->dominates(Y7, Y7));
|
||||
|
||||
// Invoke
|
||||
EXPECT_TRUE(DT->dominates(Y3, Y4));
|
||||
EXPECT_FALSE(DT->dominates(Y3, Y5));
|
||||
|
||||
// Phi
|
||||
EXPECT_TRUE(DT->dominates(Y2, Y9));
|
||||
EXPECT_FALSE(DT->dominates(Y3, Y9));
|
||||
EXPECT_FALSE(DT->dominates(Y8, Y9));
|
||||
|
||||
// Anything dominates unreachable
|
||||
EXPECT_TRUE(DT->dominates(Y1, Y6));
|
||||
EXPECT_TRUE(DT->dominates(Y3, Y6));
|
||||
|
||||
// Unreachable doesn't dominate reachable
|
||||
EXPECT_FALSE(DT->dominates(Y6, Y1));
|
||||
|
||||
// Instruction, BB dominance
|
||||
EXPECT_FALSE(DT->dominates(Y1, BB0));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB1));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB2));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB3));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(Y3, BB0));
|
||||
EXPECT_TRUE(DT->dominates(Y3, BB1));
|
||||
EXPECT_FALSE(DT->dominates(Y3, BB2));
|
||||
EXPECT_TRUE(DT->dominates(Y3, BB3));
|
||||
EXPECT_FALSE(DT->dominates(Y3, BB4));
|
||||
|
||||
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);
|
||||
|
||||
// Check DFS Numbers before
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 7UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 2UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 5UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 6UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 3UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 4UL);
|
||||
|
||||
// Reattach block 3 to block 1 and recalculate
|
||||
BB1->getTerminator()->eraseFromParent();
|
||||
BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getContext()), BB1);
|
||||
DT->recalculate(F);
|
||||
|
||||
// Check DFS Numbers after
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 9UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 4UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 7UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 8UL);
|
||||
EXPECT_EQ(DT->getNode(BB3)->getDFSNumIn(), 2UL);
|
||||
EXPECT_EQ(DT->getNode(BB3)->getDFSNumOut(), 3UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 5UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 6UL);
|
||||
|
||||
// Change root node
|
||||
DT->verifyDomTree();
|
||||
BasicBlock *NewEntry =
|
||||
BasicBlock::Create(F.getContext(), "new_entry", &F, BB0);
|
||||
BranchInst::Create(BB0, NewEntry);
|
||||
EXPECT_EQ(F.begin()->getName(), NewEntry->getName());
|
||||
EXPECT_TRUE(&F.getEntryBlock() == NewEntry);
|
||||
DT->setNewRoot(NewEntry);
|
||||
DT->verifyDomTree();
|
||||
|
||||
return false;
|
||||
}
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<PostDominatorTreeWrapperPass>();
|
||||
}
|
||||
DPass() : FunctionPass(ID) {
|
||||
initializeDPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
};
|
||||
char DPass::ID = 0;
|
||||
|
||||
std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context, DPass *P) {
|
||||
const char *ModuleString =
|
||||
TEST(DominatorTree, Unreachable) {
|
||||
StringRef ModuleString =
|
||||
"declare i32 @g()\n"
|
||||
"define void @f(i32 %x) personality i32 ()* @g {\n"
|
||||
"bb0:\n"
|
||||
|
@ -248,22 +66,194 @@ std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context, DPass *P) {
|
|||
" %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n"
|
||||
" ret void\n"
|
||||
"}\n";
|
||||
SMDiagnostic Err;
|
||||
return parseAssemblyString(ModuleString, Err, Context);
|
||||
}
|
||||
|
||||
TEST(DominatorTree, Unreachable) {
|
||||
DPass *P = new DPass();
|
||||
// Parse the module.
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M = makeLLVMModule(Context, P);
|
||||
legacy::PassManager Passes;
|
||||
Passes.add(P);
|
||||
Passes.run(*M);
|
||||
}
|
||||
} // namespace
|
||||
} // namespace llvm
|
||||
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)
|
||||
runWithDomTree(
|
||||
*M, "f",
|
||||
[&](Function &F, DominatorTree *DT, DominatorTreeBase<BasicBlock> *PDT) {
|
||||
Function::iterator FI = F.begin();
|
||||
|
||||
BasicBlock *BB0 = &*FI++;
|
||||
BasicBlock::iterator BBI = BB0->begin();
|
||||
Instruction *Y1 = &*BBI++;
|
||||
Instruction *Y2 = &*BBI++;
|
||||
Instruction *Y3 = &*BBI++;
|
||||
|
||||
BasicBlock *BB1 = &*FI++;
|
||||
BBI = BB1->begin();
|
||||
Instruction *Y4 = &*BBI++;
|
||||
|
||||
BasicBlock *BB2 = &*FI++;
|
||||
BBI = BB2->begin();
|
||||
Instruction *Y5 = &*BBI++;
|
||||
|
||||
BasicBlock *BB3 = &*FI++;
|
||||
BBI = BB3->begin();
|
||||
Instruction *Y6 = &*BBI++;
|
||||
Instruction *Y7 = &*BBI++;
|
||||
|
||||
BasicBlock *BB4 = &*FI++;
|
||||
BBI = BB4->begin();
|
||||
Instruction *Y8 = &*BBI++;
|
||||
Instruction *Y9 = &*BBI++;
|
||||
|
||||
// Reachability
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB0));
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB1));
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB2));
|
||||
EXPECT_FALSE(DT->isReachableFromEntry(BB3));
|
||||
EXPECT_TRUE(DT->isReachableFromEntry(BB4));
|
||||
|
||||
// BB dominance
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB0));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB1));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB3));
|
||||
EXPECT_TRUE(DT->dominates(BB0, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(BB1, BB0));
|
||||
EXPECT_TRUE(DT->dominates(BB1, BB1));
|
||||
EXPECT_FALSE(DT->dominates(BB1, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB1, BB3));
|
||||
EXPECT_FALSE(DT->dominates(BB1, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(BB2, BB0));
|
||||
EXPECT_FALSE(DT->dominates(BB2, BB1));
|
||||
EXPECT_TRUE(DT->dominates(BB2, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB2, BB3));
|
||||
EXPECT_FALSE(DT->dominates(BB2, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB0));
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB1));
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB2));
|
||||
EXPECT_TRUE(DT->dominates(BB3, BB3));
|
||||
EXPECT_FALSE(DT->dominates(BB3, BB4));
|
||||
|
||||
// BB proper dominance
|
||||
EXPECT_FALSE(DT->properlyDominates(BB0, BB0));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB0, BB1));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB0, BB2));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB0, BB3));
|
||||
|
||||
EXPECT_FALSE(DT->properlyDominates(BB1, BB0));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB1, BB1));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB1, BB2));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB1, BB3));
|
||||
|
||||
EXPECT_FALSE(DT->properlyDominates(BB2, BB0));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB2, BB1));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB2, BB2));
|
||||
EXPECT_TRUE(DT->properlyDominates(BB2, BB3));
|
||||
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB0));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB1));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB2));
|
||||
EXPECT_FALSE(DT->properlyDominates(BB3, BB3));
|
||||
|
||||
// Instruction dominance in the same reachable BB
|
||||
EXPECT_FALSE(DT->dominates(Y1, Y1));
|
||||
EXPECT_TRUE(DT->dominates(Y1, Y2));
|
||||
EXPECT_FALSE(DT->dominates(Y2, Y1));
|
||||
EXPECT_FALSE(DT->dominates(Y2, Y2));
|
||||
|
||||
// Instruction dominance in the same unreachable BB
|
||||
EXPECT_TRUE(DT->dominates(Y6, Y6));
|
||||
EXPECT_TRUE(DT->dominates(Y6, Y7));
|
||||
EXPECT_TRUE(DT->dominates(Y7, Y6));
|
||||
EXPECT_TRUE(DT->dominates(Y7, Y7));
|
||||
|
||||
// Invoke
|
||||
EXPECT_TRUE(DT->dominates(Y3, Y4));
|
||||
EXPECT_FALSE(DT->dominates(Y3, Y5));
|
||||
|
||||
// Phi
|
||||
EXPECT_TRUE(DT->dominates(Y2, Y9));
|
||||
EXPECT_FALSE(DT->dominates(Y3, Y9));
|
||||
EXPECT_FALSE(DT->dominates(Y8, Y9));
|
||||
|
||||
// Anything dominates unreachable
|
||||
EXPECT_TRUE(DT->dominates(Y1, Y6));
|
||||
EXPECT_TRUE(DT->dominates(Y3, Y6));
|
||||
|
||||
// Unreachable doesn't dominate reachable
|
||||
EXPECT_FALSE(DT->dominates(Y6, Y1));
|
||||
|
||||
// Instruction, BB dominance
|
||||
EXPECT_FALSE(DT->dominates(Y1, BB0));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB1));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB2));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB3));
|
||||
EXPECT_TRUE(DT->dominates(Y1, BB4));
|
||||
|
||||
EXPECT_FALSE(DT->dominates(Y3, BB0));
|
||||
EXPECT_TRUE(DT->dominates(Y3, BB1));
|
||||
EXPECT_FALSE(DT->dominates(Y3, BB2));
|
||||
EXPECT_TRUE(DT->dominates(Y3, BB3));
|
||||
EXPECT_FALSE(DT->dominates(Y3, BB4));
|
||||
|
||||
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);
|
||||
|
||||
// Check DFS Numbers before
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 7UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 2UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 5UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 6UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 3UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 4UL);
|
||||
|
||||
// Reattach block 3 to block 1 and recalculate
|
||||
BB1->getTerminator()->eraseFromParent();
|
||||
BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getContext()), BB1);
|
||||
DT->recalculate(F);
|
||||
|
||||
// Check DFS Numbers after
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
|
||||
EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 9UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
|
||||
EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 4UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 7UL);
|
||||
EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 8UL);
|
||||
EXPECT_EQ(DT->getNode(BB3)->getDFSNumIn(), 2UL);
|
||||
EXPECT_EQ(DT->getNode(BB3)->getDFSNumOut(), 3UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 5UL);
|
||||
EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 6UL);
|
||||
|
||||
// Change root node
|
||||
DT->verifyDomTree();
|
||||
BasicBlock *NewEntry =
|
||||
BasicBlock::Create(F.getContext(), "new_entry", &F, BB0);
|
||||
BranchInst::Create(BB0, NewEntry);
|
||||
EXPECT_EQ(F.begin()->getName(), NewEntry->getName());
|
||||
EXPECT_TRUE(&F.getEntryBlock() == NewEntry);
|
||||
DT->setNewRoot(NewEntry);
|
||||
DT->verifyDomTree();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue