[IR] Require well-formed IR for BasicBlock::getTerminator (#189416)
BasicBlock::getTerminator() is frequently called on valid IR, yet the function has to check that the last instruction is in fact a terminator, even in release builds. This check can only be optimized away when the instruction is dereferenced. Therefore, introduce the functions hasTerminator() and getTerminatorOrNull() as replacement and require (assert) that getTerminator() always returns a valid terminator. As a side effect, this forces explicit expression of intent at call sites when unfinished basic blocks should be supported.
This commit is contained in:
parent
c32d670757
commit
7581430722
@ -367,7 +367,6 @@ static llvm::SwitchInst *TransitionToCleanupSwitch(CodeGenFunction &CGF,
|
||||
// If it's a branch, turn it into a switch whose default
|
||||
// destination is its original target.
|
||||
llvm::Instruction *Term = Block->getTerminator();
|
||||
assert(Term && "can't transition block without terminator");
|
||||
|
||||
if (llvm::UncondBrInst *Br = dyn_cast<llvm::UncondBrInst>(Term)) {
|
||||
auto Load = createLoadInstBefore(CGF.getNormalCleanupDestSlot(),
|
||||
@ -697,7 +696,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough,
|
||||
// rest of IR gen doesn't need to worry about this; it only happens
|
||||
// during the execution of PopCleanupBlocks().
|
||||
bool HasPrebranchedFallthrough =
|
||||
(FallthroughSource && FallthroughSource->getTerminator());
|
||||
(FallthroughSource && FallthroughSource->hasTerminator());
|
||||
|
||||
// If this is a normal cleanup, then having a prebranched
|
||||
// fallthrough implies that the fallthrough source unconditionally
|
||||
|
||||
@ -1325,7 +1325,7 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
|
||||
// we follow the false destination for each of the cond branches to reach
|
||||
// the rethrow block.
|
||||
llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
|
||||
while (llvm::Instruction *TI = RethrowBlock->getTerminator())
|
||||
while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
|
||||
RethrowBlock = cast<llvm::CondBrInst>(TI)->getSuccessor(1);
|
||||
assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
|
||||
Builder.SetInsertPoint(RethrowBlock);
|
||||
|
||||
@ -663,7 +663,7 @@ void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
|
||||
// terminator, don't emit it.
|
||||
llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
|
||||
if (!CurBB || CurBB->getTerminator()) {
|
||||
if (!CurBB || CurBB->hasTerminator()) {
|
||||
// If there is no insert point or the previous block is already
|
||||
// terminated, don't touch it.
|
||||
} else {
|
||||
@ -859,7 +859,7 @@ void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
|
||||
cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB);
|
||||
|
||||
EmitBranch(IndGotoBB);
|
||||
if (CurBB && CurBB->getTerminator())
|
||||
if (CurBB && CurBB->hasTerminator())
|
||||
addInstToCurrentSourceAtom(CurBB->getTerminator(), nullptr);
|
||||
}
|
||||
|
||||
|
||||
@ -309,7 +309,7 @@ llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {
|
||||
llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
|
||||
if (CurBB) {
|
||||
assert(!CurBB->getTerminator() && "Unexpected terminated block.");
|
||||
assert(!CurBB->hasTerminator() && "Unexpected terminated block.");
|
||||
|
||||
// We have a valid insert point, reuse it if it is empty or there are no
|
||||
// explicit jumps to the return block.
|
||||
|
||||
@ -2012,7 +2012,7 @@ public:
|
||||
llvm::BasicBlock &FiniBB, llvm::Function *Fn,
|
||||
ArrayRef<llvm::Value *> Args) {
|
||||
llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
|
||||
if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator())
|
||||
if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminatorOrNull())
|
||||
CodeGenIPBBTI->eraseFromParent();
|
||||
|
||||
CGF.Builder.SetInsertPoint(CodeGenIPBB);
|
||||
|
||||
@ -228,11 +228,14 @@ public:
|
||||
/// Requires the basic block to have a parent module.
|
||||
LLVM_ABI const DataLayout &getDataLayout() const;
|
||||
|
||||
/// Returns the terminator instruction if the block is well formed or
|
||||
/// null if the block is not well formed.
|
||||
/// Returns whether the block has a terminator.
|
||||
bool hasTerminator() const LLVM_READONLY {
|
||||
return !InstList.empty() && InstList.back().isTerminator();
|
||||
}
|
||||
|
||||
/// Returns the terminator instruction; assumes that the block is well-formed.
|
||||
const Instruction *getTerminator() const LLVM_READONLY {
|
||||
if (InstList.empty() || !InstList.back().isTerminator())
|
||||
return nullptr;
|
||||
assert(hasTerminator() && "cannot get terminator of non-well-formed block");
|
||||
return &InstList.back();
|
||||
}
|
||||
Instruction *getTerminator() {
|
||||
@ -240,6 +243,15 @@ public:
|
||||
static_cast<const BasicBlock *>(this)->getTerminator());
|
||||
}
|
||||
|
||||
/// Returns the terminator instruction if the block is well formed or
|
||||
/// null if the block is not well formed.
|
||||
const Instruction *getTerminatorOrNull() const LLVM_READONLY {
|
||||
return hasTerminator() ? getTerminator() : nullptr;
|
||||
}
|
||||
Instruction *getTerminatorOrNull() {
|
||||
return hasTerminator() ? getTerminator() : nullptr;
|
||||
}
|
||||
|
||||
/// Returns the call instruction calling \@llvm.experimental.deoptimize
|
||||
/// prior to the terminating return instruction of this basic block, if such
|
||||
/// a call is present. Otherwise, returns null.
|
||||
|
||||
@ -7895,7 +7895,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(
|
||||
// if what we are checking for includes undef and the value is not an integer.
|
||||
if (!includesUndef(Kind) || V->getType()->isIntegerTy())
|
||||
while (Dominator) {
|
||||
auto *TI = Dominator->getBlock()->getTerminator();
|
||||
auto *TI = Dominator->getBlock()->getTerminatorOrNull();
|
||||
|
||||
Value *Cond = nullptr;
|
||||
if (auto BI = dyn_cast_or_null<CondBrInst>(TI)) {
|
||||
|
||||
@ -301,7 +301,7 @@ computeOpenMPScheduleType(ScheduleKind ClauseKind, bool HasChunks,
|
||||
/// * \p Source is a degenerate block (no terminator because the BB is
|
||||
/// the current head of the IR construction).
|
||||
static void redirectTo(BasicBlock *Source, BasicBlock *Target, DebugLoc DL) {
|
||||
if (Instruction *Term = Source->getTerminator()) {
|
||||
if (Instruction *Term = Source->getTerminatorOrNull()) {
|
||||
auto *Br = cast<UncondBrInst>(Term);
|
||||
BasicBlock *Succ = Br->getSuccessor();
|
||||
Succ->removePredecessor(Source, /*KeepOneInputPHIs=*/true);
|
||||
@ -884,9 +884,8 @@ void OpenMPIRBuilder::finalize(Function *Fn) {
|
||||
|
||||
if (I.isTerminator()) {
|
||||
// Absorb any debug value that terminator may have
|
||||
if (OI.EntryBB->getTerminator())
|
||||
OI.EntryBB->getTerminator()->adoptDbgRecords(
|
||||
&ArtificialEntry, I.getIterator(), false);
|
||||
if (Instruction *TI = OI.EntryBB->getTerminatorOrNull())
|
||||
TI->adoptDbgRecords(&ArtificialEntry, I.getIterator(), false);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -4928,7 +4927,7 @@ Error OpenMPIRBuilder::emitScanBasedDirectiveDeclsIR(
|
||||
return AfterIP.takeError();
|
||||
Builder.restoreIP(*AfterIP);
|
||||
BasicBlock *InputBB = Builder.GetInsertBlock();
|
||||
if (InputBB->getTerminator())
|
||||
if (InputBB->hasTerminator())
|
||||
Builder.SetInsertPoint(Builder.GetInsertBlock()->getTerminator());
|
||||
AfterIP = createBarrier(Builder.saveIP(), llvm::omp::OMPD_barrier);
|
||||
if (!AfterIP)
|
||||
@ -4963,8 +4962,8 @@ Error OpenMPIRBuilder::emitScanBasedDirectiveFinalsIR(
|
||||
// called for variables which have destructors/finalizers.
|
||||
auto FiniCB = [&](InsertPointTy CodeGenIP) { return llvm::Error::success(); };
|
||||
|
||||
if (ScanRedInfo->OMPScanFinish->getTerminator())
|
||||
Builder.SetInsertPoint(ScanRedInfo->OMPScanFinish->getTerminator());
|
||||
if (Instruction *TI = ScanRedInfo->OMPScanFinish->getTerminatorOrNull())
|
||||
Builder.SetInsertPoint(TI);
|
||||
else
|
||||
Builder.SetInsertPoint(ScanRedInfo->OMPScanFinish);
|
||||
|
||||
@ -4976,7 +4975,7 @@ Error OpenMPIRBuilder::emitScanBasedDirectiveFinalsIR(
|
||||
return AfterIP.takeError();
|
||||
Builder.restoreIP(*AfterIP);
|
||||
BasicBlock *InputBB = Builder.GetInsertBlock();
|
||||
if (InputBB->getTerminator())
|
||||
if (InputBB->hasTerminator())
|
||||
Builder.SetInsertPoint(Builder.GetInsertBlock()->getTerminator());
|
||||
AfterIP = createBarrier(Builder.saveIP(), llvm::omp::OMPD_barrier);
|
||||
if (!AfterIP)
|
||||
@ -5605,7 +5604,7 @@ OpenMPIRBuilder::applyStaticChunkedWorkshareLoop(
|
||||
// FIXME: Don't run analyses on incomplete/invalid IR.
|
||||
SmallVector<Instruction *> UIs;
|
||||
for (BasicBlock &BB : *F)
|
||||
if (!BB.getTerminator())
|
||||
if (!BB.hasTerminator())
|
||||
UIs.push_back(new UnreachableInst(F->getContext(), &BB));
|
||||
FunctionAnalysisManager FAM;
|
||||
FAM.registerPass([]() { return DominatorTreeAnalysis(); });
|
||||
@ -6902,7 +6901,7 @@ void OpenMPIRBuilder::applySimd(CanonicalLoopInfo *CanonicalLoop,
|
||||
// FIXME: Don't run analyses on incomplete/invalid IR.
|
||||
SmallVector<Instruction *> UIs;
|
||||
for (BasicBlock &BB : *F)
|
||||
if (!BB.getTerminator())
|
||||
if (!BB.hasTerminator())
|
||||
UIs.push_back(new UnreachableInst(F->getContext(), &BB));
|
||||
|
||||
// TODO: We should not rely on pass manager. Currently we use pass manager
|
||||
@ -7041,7 +7040,7 @@ static int32_t computeHeuristicUnrollFactor(CanonicalLoopInfo *CLI) {
|
||||
// FIXME: Don't run analyses on incomplete/invalid IR.
|
||||
SmallVector<Instruction *> UIs;
|
||||
for (BasicBlock &BB : *F)
|
||||
if (!BB.getTerminator())
|
||||
if (!BB.hasTerminator())
|
||||
UIs.push_back(new UnreachableInst(F->getContext(), &BB));
|
||||
|
||||
FunctionAnalysisManager FAM;
|
||||
@ -7451,7 +7450,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::EmitOMPInlinedRegion(
|
||||
// Create inlined region's entry and body blocks, in preparation
|
||||
// for conditional creation
|
||||
BasicBlock *EntryBB = Builder.GetInsertBlock();
|
||||
Instruction *SplitPos = EntryBB->getTerminator();
|
||||
Instruction *SplitPos = EntryBB->getTerminatorOrNull();
|
||||
if (!isa_and_nonnull<UncondBrInst, CondBrInst>(SplitPos))
|
||||
SplitPos = new UnreachableInst(Builder.getContext(), EntryBB);
|
||||
BasicBlock *ExitBB = EntryBB->splitBasicBlock(SplitPos, "omp_region.end");
|
||||
@ -7581,7 +7580,7 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createCopyinClauseBlocks(
|
||||
|
||||
// If entry block is terminated, split to preserve the branch to following
|
||||
// basic block (i.e. OMP.Entry.Next), otherwise, leave everything as is.
|
||||
if (isa_and_nonnull<CondBrInst>(OMP_Entry->getTerminator())) {
|
||||
if (isa_and_nonnull<CondBrInst>(OMP_Entry->getTerminatorOrNull())) {
|
||||
CopyEnd = OMP_Entry->splitBasicBlock(OMP_Entry->getTerminator(),
|
||||
"copyin.not.master.end");
|
||||
OMP_Entry->getTerminator()->eraseFromParent();
|
||||
@ -10170,7 +10169,7 @@ Error OpenMPIRBuilder::emitOffloadingArrays(
|
||||
void OpenMPIRBuilder::emitBranch(BasicBlock *Target) {
|
||||
BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
|
||||
if (!CurBB || CurBB->getTerminator()) {
|
||||
if (!CurBB || CurBB->hasTerminator()) {
|
||||
// If there is no insert point or the previous block is already
|
||||
// terminated, don't touch it.
|
||||
} else {
|
||||
@ -10525,7 +10524,7 @@ Expected<std::pair<Value *, Value *>> OpenMPIRBuilder::emitAtomicUpdate(
|
||||
OldVal->getAlign(), true /* UseLibcall */, AllocaIP, X);
|
||||
auto AtomicLoadRes = atomicInfo.EmitAtomicLoadLibcall(AO);
|
||||
BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
Instruction *CurBBTI = CurBB->getTerminator();
|
||||
Instruction *CurBBTI = CurBB->getTerminatorOrNull();
|
||||
CurBBTI = CurBBTI ? CurBBTI : Builder.CreateUnreachable();
|
||||
BasicBlock *ExitBB =
|
||||
CurBB->splitBasicBlock(CurBBTI, X->getName() + ".atomic.exit");
|
||||
@ -10574,7 +10573,7 @@ Expected<std::pair<Value *, Value *>> OpenMPIRBuilder::emitAtomicUpdate(
|
||||
// | \---/
|
||||
// ExitBB
|
||||
BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
Instruction *CurBBTI = CurBB->getTerminator();
|
||||
Instruction *CurBBTI = CurBB->getTerminatorOrNull();
|
||||
CurBBTI = CurBBTI ? CurBBTI : Builder.CreateUnreachable();
|
||||
BasicBlock *ExitBB =
|
||||
CurBB->splitBasicBlock(CurBBTI, X->getName() + ".atomic.exit");
|
||||
@ -10733,7 +10732,7 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
|
||||
//
|
||||
// where ContBB only contains the store of old value to 'v'.
|
||||
BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
Instruction *CurBBTI = CurBB->getTerminator();
|
||||
Instruction *CurBBTI = CurBB->getTerminatorOrNull();
|
||||
CurBBTI = CurBBTI ? CurBBTI : Builder.CreateUnreachable();
|
||||
BasicBlock *ExitBB = CurBB->splitBasicBlock(
|
||||
CurBBTI, X.Var->getName() + ".atomic.exit");
|
||||
@ -11609,7 +11608,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createIteratorLoop(
|
||||
|
||||
InsertPointTy SplitIP = Builder.saveIP();
|
||||
if (SplitIP.getPoint() == CurBB->end())
|
||||
if (Instruction *Terminator = CurBB->getTerminator())
|
||||
if (Instruction *Terminator = CurBB->getTerminatorOrNull())
|
||||
SplitIP = InsertPointTy(CurBB, Terminator->getIterator());
|
||||
|
||||
BasicBlock *ContBB =
|
||||
@ -11625,7 +11624,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createIteratorLoop(
|
||||
redirectTo(CurBB, CLI->getPreheader(), Builder.getCurrentDebugLocation());
|
||||
|
||||
// Remove the unconditional branch inserted by createLoopSkeleton in the body
|
||||
if (Instruction *T = CLI->getBody()->getTerminator())
|
||||
if (Instruction *T = CLI->getBody()->getTerminatorOrNull())
|
||||
T->eraseFromParent();
|
||||
|
||||
InsertPointTy BodyIP = CLI->getBodyIP();
|
||||
@ -11633,7 +11632,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createIteratorLoop(
|
||||
return Err;
|
||||
|
||||
// Body must either fallthrough to the latch or branch directly to it.
|
||||
if (Instruction *BodyTerminator = CLI->getBody()->getTerminator()) {
|
||||
if (Instruction *BodyTerminator = CLI->getBody()->getTerminatorOrNull()) {
|
||||
auto *BodyBr = dyn_cast<UncondBrInst>(BodyTerminator);
|
||||
if (!BodyBr || BodyBr->getSuccessor() != CLI->getLatch()) {
|
||||
return make_error<StringError>(
|
||||
@ -11649,7 +11648,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createIteratorLoop(
|
||||
|
||||
// Link After -> ContBB
|
||||
Builder.SetInsertPoint(CLI->getAfter(), CLI->getAfter()->begin());
|
||||
if (!CLI->getAfter()->getTerminator())
|
||||
if (!CLI->getAfter()->hasTerminator())
|
||||
Builder.CreateBr(ContBB);
|
||||
|
||||
return InsertPointTy{ContBB, ContBB->begin()};
|
||||
|
||||
@ -25,7 +25,7 @@ static DominatorTree getDomTree(Function &F) {
|
||||
// Dominator tree construction requires that all blocks have terminators.
|
||||
SmallVector<Instruction *> AddedInsts;
|
||||
for (BasicBlock &BB : F)
|
||||
if (!BB.getTerminator())
|
||||
if (!BB.hasTerminator())
|
||||
AddedInsts.push_back(new UnreachableInst(F.getContext(), &BB));
|
||||
DominatorTree DT(F);
|
||||
for (Instruction *I : AddedInsts)
|
||||
@ -219,7 +219,7 @@ Value *RandomIRBuilder::findOrCreateSource(BasicBlock &BB,
|
||||
Module *M = BB.getParent()->getParent();
|
||||
auto [GV, DidCreate] = findOrCreateGlobalVariable(M, Srcs, Pred);
|
||||
Type *Ty = GV->getValueType();
|
||||
InsertPosition IP = BB.getTerminator()
|
||||
InsertPosition IP = BB.hasTerminator()
|
||||
? InsertPosition(BB.getFirstInsertionPt())
|
||||
: InsertPosition(&BB);
|
||||
// Build a legal load and track new instructions in case a rollback is
|
||||
@ -292,7 +292,7 @@ Value *RandomIRBuilder::newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts,
|
||||
Type *Ty = newSrc->getType();
|
||||
Function *F = BB.getParent();
|
||||
AllocaInst *Alloca = createStackMemory(F, Ty, newSrc);
|
||||
if (BB.getTerminator()) {
|
||||
if (BB.hasTerminator()) {
|
||||
newSrc = new LoadInst(Ty, Alloca, /*ArrLen,*/ "L",
|
||||
BB.getTerminator()->getIterator());
|
||||
} else {
|
||||
|
||||
@ -614,7 +614,7 @@ void BasicBlock::replacePhiUsesWith(BasicBlock *Old, BasicBlock *New) {
|
||||
|
||||
void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *Old,
|
||||
BasicBlock *New) {
|
||||
Instruction *TI = getTerminator();
|
||||
Instruction *TI = getTerminatorOrNull();
|
||||
if (!TI)
|
||||
// Cope with being called on a BasicBlock that doesn't have a terminator
|
||||
// yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this.
|
||||
@ -676,7 +676,7 @@ void BasicBlock::flushTerminatorDbgRecords() {
|
||||
// DbgRecords in front of the terminator.
|
||||
|
||||
// If there's no terminator, there's nothing to do.
|
||||
Instruction *Term = getTerminator();
|
||||
Instruction *Term = getTerminatorOrNull();
|
||||
if (!Term)
|
||||
return;
|
||||
|
||||
|
||||
@ -1126,7 +1126,7 @@ DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
// If this block already has a terminator then insert this intrinsic before
|
||||
// the terminator. Otherwise, put it at the end of the block.
|
||||
Instruction *InsertBefore = InsertAtEnd->getTerminator();
|
||||
Instruction *InsertBefore = InsertAtEnd->getTerminatorOrNull();
|
||||
return insertDeclare(Storage, VarInfo, Expr, DL,
|
||||
InsertBefore ? InsertBefore->getIterator()
|
||||
: InsertAtEnd->end());
|
||||
|
||||
@ -823,7 +823,7 @@ public:
|
||||
BasicBlock *HoistCommonSucc = CreateHoistedBlock(CommonSucc);
|
||||
|
||||
// Link up these blocks with branches.
|
||||
if (!HoistCommonSucc->getTerminator()) {
|
||||
if (!HoistCommonSucc->hasTerminator()) {
|
||||
// The new common successor we've generated will branch to whatever that
|
||||
// hoist target branched to.
|
||||
BasicBlock *TargetSucc = HoistTarget->getSingleSuccessor();
|
||||
@ -831,11 +831,11 @@ public:
|
||||
HoistCommonSucc->moveBefore(TargetSucc);
|
||||
UncondBrInst::Create(TargetSucc, HoistCommonSucc);
|
||||
}
|
||||
if (!HoistTrueDest->getTerminator()) {
|
||||
if (!HoistTrueDest->hasTerminator()) {
|
||||
HoistTrueDest->moveBefore(HoistCommonSucc);
|
||||
UncondBrInst::Create(HoistCommonSucc, HoistTrueDest);
|
||||
}
|
||||
if (!HoistFalseDest->getTerminator()) {
|
||||
if (!HoistFalseDest->hasTerminator()) {
|
||||
HoistFalseDest->moveBefore(HoistCommonSucc);
|
||||
UncondBrInst::Create(HoistCommonSucc, HoistFalseDest);
|
||||
}
|
||||
|
||||
@ -709,7 +709,7 @@ static bool unswitchTrivialBranch(Loop &L, CondBrInst &BI, DominatorTree &DT,
|
||||
" condition!");
|
||||
buildPartialUnswitchConditionalBranch(
|
||||
*OldPH, Invariants, ExitDirection, *UnswitchedBB, *NewPH,
|
||||
FreezeLoopUnswitchCond, OldPH->getTerminator(), nullptr, DT, BI);
|
||||
FreezeLoopUnswitchCond, OldPH->getTerminatorOrNull(), nullptr, DT, BI);
|
||||
}
|
||||
|
||||
// Update the dominator tree with the added edge.
|
||||
|
||||
@ -1024,7 +1024,7 @@ void StructurizeCFG::simplifyAffectedPhis() {
|
||||
|
||||
/// Remove phi values from all successors and then remove the terminator.
|
||||
DebugLoc StructurizeCFG::killTerminator(BasicBlock *BB) {
|
||||
Instruction *Term = BB->getTerminator();
|
||||
Instruction *Term = BB->getTerminatorOrNull();
|
||||
if (!Term)
|
||||
return DebugLoc();
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ static Value *getStrlenWithNull(IRBuilder<> &Builder, Value *Str) {
|
||||
// Strictly speaking, the zero does not matter since
|
||||
// __ockl_printf_append_string_n ignores the length if the pointer is null.
|
||||
BasicBlock *Join = nullptr;
|
||||
if (Prev->getTerminator()) {
|
||||
if (Prev->hasTerminator()) {
|
||||
Join = Prev->splitBasicBlock(Builder.GetInsertPoint(),
|
||||
"strlen.join");
|
||||
Prev->getTerminator()->eraseFromParent();
|
||||
|
||||
@ -1277,10 +1277,10 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
|
||||
// | v
|
||||
// | for.body <---- (md2)
|
||||
// |_______| |______|
|
||||
if (Instruction *TI = BB->getTerminator())
|
||||
if (Instruction *TI = BB->getTerminatorOrNull())
|
||||
if (TI->hasNonDebugLocLoopMetadata())
|
||||
for (BasicBlock *Pred : predecessors(BB))
|
||||
if (Instruction *PredTI = Pred->getTerminator())
|
||||
if (Instruction *PredTI = Pred->getTerminatorOrNull())
|
||||
if (PredTI->hasNonDebugLocLoopMetadata())
|
||||
return false;
|
||||
|
||||
@ -1348,7 +1348,7 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
|
||||
// If the unconditional branch we replaced contains non-debug llvm.loop
|
||||
// metadata, we add the metadata to the branch instructions in the
|
||||
// predecessors.
|
||||
if (Instruction *TI = BB->getTerminator())
|
||||
if (Instruction *TI = BB->getTerminatorOrNull())
|
||||
if (TI->hasNonDebugLocLoopMetadata()) {
|
||||
MDNode *LoopMD = TI->getMetadata(LLVMContext::MD_loop);
|
||||
for (BasicBlock *Pred : predecessors(BB))
|
||||
@ -1363,7 +1363,7 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
|
||||
Succ->takeName(BB);
|
||||
|
||||
// Clear the successor list of BB to match updates applying to DTU later.
|
||||
if (BB->getTerminator())
|
||||
if (BB->hasTerminator())
|
||||
BB->back().eraseFromParent();
|
||||
|
||||
new UnreachableInst(BB->getContext(), BB);
|
||||
|
||||
@ -43,7 +43,7 @@ static void ConnectBlocks(BasicBlock *From, BasicBlock *To) {
|
||||
|
||||
if (isa<UnreachableInst>(From->getTerminator()))
|
||||
From->getTerminator()->eraseFromParent();
|
||||
if (!From->getTerminator()) {
|
||||
if (!From->hasTerminator()) {
|
||||
IRBuilder<> IRB(From);
|
||||
IRB.CreateSwitch(ConstantInt::get(IntTy, 0), To);
|
||||
return;
|
||||
|
||||
@ -1220,7 +1220,7 @@ setInsertPointForPossiblyEmptyBlock(llvm::IRBuilderBase &builder,
|
||||
if (block == nullptr)
|
||||
block = builder.GetInsertBlock();
|
||||
|
||||
if (block->empty() || block->getTerminator() == nullptr)
|
||||
if (!block->hasTerminator())
|
||||
builder.SetInsertPoint(block);
|
||||
else
|
||||
builder.SetInsertPoint(block->getTerminator());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user