forked from OSchip/llvm-project
Utils: Fix DomTree update for entry block
If SplitBlockPredecessors was used on a function entry block, it wouldn't update the dominator tree. llvm-svn: 323928
This commit is contained in:
parent
af88f0eb44
commit
06dfbb50d7
|
@ -319,8 +319,15 @@ static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
|
|||
DominatorTree *DT, LoopInfo *LI,
|
||||
bool PreserveLCSSA, bool &HasLoopExit) {
|
||||
// Update dominator tree if available.
|
||||
if (DT)
|
||||
DT->splitBlock(NewBB);
|
||||
if (DT) {
|
||||
if (OldBB == DT->getRootNode()->getBlock()) {
|
||||
assert(NewBB == &NewBB->getParent()->getEntryBlock());
|
||||
DT->setNewRoot(NewBB);
|
||||
} else {
|
||||
// Split block expects NewBB to have a non-empty set of predecessors.
|
||||
DT->splitBlock(NewBB);
|
||||
}
|
||||
}
|
||||
|
||||
// The rest of the logic is only relevant for updating the loop structures.
|
||||
if (!LI)
|
||||
|
@ -504,7 +511,6 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
|
|||
// Insert dummy values as the incoming value.
|
||||
for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ++I)
|
||||
cast<PHINode>(I)->addIncoming(UndefValue::get(I->getType()), NewBB);
|
||||
return NewBB;
|
||||
}
|
||||
|
||||
// Update DominatorTree, LoopInfo, and LCCSA analysis information.
|
||||
|
@ -512,8 +518,11 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
|
|||
UpdateAnalysisInformation(BB, NewBB, Preds, DT, LI, PreserveLCSSA,
|
||||
HasLoopExit);
|
||||
|
||||
// Update the PHI nodes in BB with the values coming from NewBB.
|
||||
UpdatePHINodes(BB, NewBB, Preds, BI, HasLoopExit);
|
||||
if (!Preds.empty()) {
|
||||
// Update the PHI nodes in BB with the values coming from NewBB.
|
||||
UpdatePHINodes(BB, NewBB, Preds, BI, HasLoopExit);
|
||||
}
|
||||
|
||||
return NewBB;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
//===- BasicBlockUtils.cpp - Unit tests for BasicBlockUtils ---------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/AsmParser/Parser.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
|
||||
SMDiagnostic Err;
|
||||
std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
|
||||
if (!Mod)
|
||||
Err.print("BasicBlockUtilsTests", errs());
|
||||
return Mod;
|
||||
}
|
||||
|
||||
TEST(BasicBlockUtils, SplitBlockPredecessors) {
|
||||
LLVMContext C;
|
||||
|
||||
std::unique_ptr<Module> M = parseIR(
|
||||
C,
|
||||
"define i32 @basic_func(i1 %cond) {\n"
|
||||
"entry:\n"
|
||||
" br i1 %cond, label %bb0, label %bb1\n"
|
||||
"bb0:\n"
|
||||
" br label %bb1\n"
|
||||
"bb1:\n"
|
||||
" %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]"
|
||||
" ret i32 %phi\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
);
|
||||
|
||||
auto *F = M->getFunction("basic_func");
|
||||
DominatorTree DT(*F);
|
||||
|
||||
// Make sure the dominator tree is properly updated if calling this on the
|
||||
// entry block.
|
||||
SplitBlockPredecessors(&F->getEntryBlock(), {}, "split.entry", &DT);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
}
|
|
@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
|
||||
add_llvm_unittest(UtilsTests
|
||||
ASanStackFrameLayoutTest.cpp
|
||||
BasicBlockUtils.cpp
|
||||
Cloning.cpp
|
||||
CodeExtractor.cpp
|
||||
FunctionComparator.cpp
|
||||
|
|
|
@ -100,7 +100,7 @@ TEST(Local, RemoveDuplicatePHINodes) {
|
|||
EXPECT_EQ(3U, BB->size());
|
||||
}
|
||||
|
||||
std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
|
||||
static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
|
||||
SMDiagnostic Err;
|
||||
std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
|
||||
if (!Mod)
|
||||
|
|
Loading…
Reference in New Issue