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:
Matt Arsenault 2018-01-31 22:54:37 +00:00
parent af88f0eb44
commit 06dfbb50d7
4 changed files with 68 additions and 6 deletions

View File

@ -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;
}

View File

@ -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());
}

View File

@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
add_llvm_unittest(UtilsTests
ASanStackFrameLayoutTest.cpp
BasicBlockUtils.cpp
Cloning.cpp
CodeExtractor.cpp
FunctionComparator.cpp

View File

@ -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)