From 40b2b61e65286a64c6881d3070111d5393f7619d Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Sun, 13 Oct 2019 05:27:09 +0000 Subject: [PATCH] [Attributor][FIX] Avoid splitting blocks if possible Before, we eagerly split blocks even if it was not necessary, e.g., they had a single unreachable instruction and only a single predecessor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374703 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/Attributor.cpp | 22 ++++++++++++------- test/Transforms/FunctionAttrs/liveness.ll | 4 ++-- .../FunctionAttrs/noreturn_async.ll | 8 +++---- .../Transforms/FunctionAttrs/noreturn_sync.ll | 4 ++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/Transforms/IPO/Attributor.cpp b/lib/Transforms/IPO/Attributor.cpp index 08675de6cb1..2778daf9fab 100644 --- a/lib/Transforms/IPO/Attributor.cpp +++ b/lib/Transforms/IPO/Attributor.cpp @@ -2139,8 +2139,6 @@ struct AAIsDeadImpl : public AAIsDead { BasicBlock *BB = I->getParent(); Instruction *SplitPos = I->getNextNode(); // TODO: mark stuff before unreachable instructions as dead. - if (isa_and_nonnull(SplitPos)) - continue; if (auto *II = dyn_cast(I)) { // If we keep the invoke the split position is at the beginning of the @@ -2183,15 +2181,23 @@ struct AAIsDeadImpl : public AAIsDead { // also manifest. assert(!NormalDestBB->isLandingPad() && "Expected the normal destination not to be a landingpad!"); - BasicBlock *SplitBB = - SplitBlockPredecessors(NormalDestBB, {BB}, ".dead"); - // The split block is live even if it contains only an unreachable - // instruction at the end. - assumeLive(A, *SplitBB); - SplitPos = SplitBB->getTerminator(); + if (NormalDestBB->getUniquePredecessor() == BB) { + assumeLive(A, *NormalDestBB); + } else { + BasicBlock *SplitBB = + SplitBlockPredecessors(NormalDestBB, {BB}, ".dead"); + // The split block is live even if it contains only an unreachable + // instruction at the end. + assumeLive(A, *SplitBB); + SplitPos = SplitBB->getTerminator(); + HasChanged = ChangeStatus::CHANGED; + } } } + if (isa_and_nonnull(SplitPos)) + continue; + BB = SplitPos->getParent(); SplitBlock(BB, SplitPos); changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false); diff --git a/test/Transforms/FunctionAttrs/liveness.ll b/test/Transforms/FunctionAttrs/liveness.ll index b75887efb8f..b6a4900d2af 100644 --- a/test/Transforms/FunctionAttrs/liveness.ll +++ b/test/Transforms/FunctionAttrs/liveness.ll @@ -177,7 +177,7 @@ cond.true: ; preds = %entry %call = invoke i32 @foo_noreturn() to label %continue unwind label %cleanup ; CHECK: %call = invoke i32 @foo_noreturn() - ; CHECK-NEXT: to label %continue.dead unwind label %cleanup + ; CHECK-NEXT: to label %continue unwind label %cleanup cond.false: ; preds = %entry call void @normal_call() @@ -189,7 +189,7 @@ cond.end: ; preds = %cond.false, %contin ret i32 %cond continue: - ; CHECK: continue.dead: + ; CHECK: continue: ; CHECK-NEXT: unreachable br label %cond.end diff --git a/test/Transforms/FunctionAttrs/noreturn_async.ll b/test/Transforms/FunctionAttrs/noreturn_async.ll index e9e423688df..e06a13f40c5 100644 --- a/test/Transforms/FunctionAttrs/noreturn_async.ll +++ b/test/Transforms/FunctionAttrs/noreturn_async.ll @@ -42,12 +42,12 @@ entry: %retval = alloca i32, align 4 %__exception_code = alloca i32, align 4 ; CHECK: invoke void @"?overflow@@YAXXZ"() -; CHECK: to label %invoke.cont.dead unwind label %catch.dispatch +; CHECK: to label %invoke.cont unwind label %catch.dispatch invoke void @"?overflow@@YAXXZ"() to label %invoke.cont unwind label %catch.dispatch invoke.cont: ; preds = %entry -; CHECK: invoke.cont.dead: +; CHECK: invoke.cont: ; CHECK-NEXT: unreachable br label %invoke.cont1 @@ -101,12 +101,12 @@ entry: %retval = alloca i32, align 4 %__exception_code = alloca i32, align 4 ; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"() -; CHECK: to label %invoke.cont.dead unwind label %catch.dispatch +; CHECK: to label %invoke.cont unwind label %catch.dispatch invoke void @"?overflow@@YAXXZ_may_throw"() to label %invoke.cont unwind label %catch.dispatch invoke.cont: ; preds = %entry -; CHECK: invoke.cont.dead: +; CHECK: invoke.cont: ; CHECK-NEXT: unreachable br label %invoke.cont1 diff --git a/test/Transforms/FunctionAttrs/noreturn_sync.ll b/test/Transforms/FunctionAttrs/noreturn_sync.ll index 5d644965fb2..423a369f704 100644 --- a/test/Transforms/FunctionAttrs/noreturn_sync.ll +++ b/test/Transforms/FunctionAttrs/noreturn_sync.ll @@ -97,12 +97,12 @@ entry: %retval = alloca i32, align 4 %__exception_code = alloca i32, align 4 ; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"() -; CHECK: to label %invoke.cont.dead unwind label %catch.dispatch +; CHECK: to label %invoke.cont unwind label %catch.dispatch invoke void @"?overflow@@YAXXZ_may_throw"() to label %invoke.cont unwind label %catch.dispatch invoke.cont: ; preds = %entry -; CHECK: invoke.cont.dead: +; CHECK: invoke.cont: ; CHECK-NEXT: unreachable br label %invoke.cont1 -- 2.49.0