diff options
-rw-r--r-- | llvm/lib/Transforms/Scalar/NewGVN.cpp | 31 | ||||
-rw-r--r-- | llvm/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll | 38 | ||||
-rw-r--r-- | llvm/test/Transforms/NewGVN/pr31594.ll | 2 |
3 files changed, 38 insertions, 33 deletions
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp index c17b9f7fcf2..259a4eade0d 100644 --- a/llvm/lib/Transforms/Scalar/NewGVN.cpp +++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -2106,21 +2106,26 @@ void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) { DEBUG(dbgs() << " BasicBlock Dead:" << *BB); ++NumGVNBlocksDeleted; - // Change to unreachable does not handle destroying phi nodes. We just replace - // the users with undef. - if (BB->empty()) + // Check to see if there are non-terminating instructions to delete. + if (isa<TerminatorInst>(BB->begin())) return; - auto BBI = BB->begin(); - while (auto *Phi = dyn_cast<PHINode>(BBI)) { - Phi->replaceAllUsesWith(UndefValue::get(Phi->getType())); - ++BBI; - } - Instruction *ToKill = &*BBI; - // Nothing but phi nodes, so nothing left to remove. - if (!ToKill) - return; - NumGVNInstrDeleted += changeToUnreachable(ToKill, false); + // Delete the instructions backwards, as it has a reduced likelihood of having + // to update as many def-use and use-def chains. Start after the terminator. + auto StartPoint = BB->rbegin(); + ++StartPoint; + // Note that we explicitly recalculate BB->rend() on each iteration, + // as it may change when we remove the first instruction. + for (BasicBlock::reverse_iterator I(StartPoint); I != BB->rend();) { + Instruction &Inst = *I++; + if (!Inst.use_empty()) + Inst.replaceAllUsesWith(UndefValue::get(Inst.getType())); + if (isa<LandingPadInst>(Inst)) + continue; + + Inst.eraseFromParent(); + ++NumGVNInstrDeleted; + } } void NewGVN::markInstructionForDeletion(Instruction *I) { diff --git a/llvm/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll b/llvm/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll index 05fe2a22a3f..c1b5cc81fb5 100644 --- a/llvm/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll +++ b/llvm/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll @@ -1,4 +1,3 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -newgvn -S | FileCheck %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" @@ -10,29 +9,30 @@ target triple = "i386-apple-darwin9.5" %struct.demangle_component = type { i32, { %struct.anon } } define void @d_print_mod_list(%struct.d_print_info* %dpi, %struct.d_print_mod* %mods, i32 %suffix) nounwind { -; CHECK-LABEL: @d_print_mod_list( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_D_PRINT_INFO:%.*]], %struct.d_print_info* [[DPI:%.*]], i32 0, i32 1 -; CHECK-NEXT: br i1 false, label [[RETURN:%.*]], label [[BB:%.*]] -; CHECK: bb: -; CHECK-NEXT: br label [[BB21:%.*]] -; CHECK: bb21: -; CHECK-NEXT: br label [[BB21]] -; CHECK: return: -; CHECK-NEXT: unreachable -; entry: - %0 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 ; <i8**> [#uses=1] - br i1 false, label %return, label %bb + %0 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 ; <i8**> [#uses=1] + br i1 false, label %return, label %bb bb: ; preds = %entry - %1 = load i8*, i8** %0, align 4 ; <i8*> [#uses=0] - %2 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 ; <i8**> [#uses=0] - br label %bb21 + %1 = load i8*, i8** %0, align 4 ; <i8*> [#uses=0] + %2 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 ; <i8**> [#uses=0] + br label %bb21 bb21: ; preds = %bb21, %bb - br label %bb21 + br label %bb21 return: ; preds = %entry - ret void + ret void } + +; CHECK: define void @d_print_mod_list(%struct.d_print_info* %dpi, %struct.d_print_mod* %mods, i32 %suffix) #0 { +; CHECK: entry: +; CHECK: %0 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 +; CHECK: br i1 false, label %return, label %bb +; CHECK: bb: +; CHECK: br label %bb21 +; CHECK: bb21: +; CHECK: br label %bb21 +; CHECK: return: +; CHECK: ret void +; CHECK: } diff --git a/llvm/test/Transforms/NewGVN/pr31594.ll b/llvm/test/Transforms/NewGVN/pr31594.ll index 11b44ede6d7..c24b03278b7 100644 --- a/llvm/test/Transforms/NewGVN/pr31594.ll +++ b/llvm/test/Transforms/NewGVN/pr31594.ll @@ -77,7 +77,7 @@ define void @foo(i8* %arg) { ; CHECK-NEXT: i8 6, label [[BB8:%.*]] ; CHECK-NEXT: ] ; CHECK: bb8: -; CHECK-NEXT: unreachable +; CHECK-NEXT: br label [[BB4]] ; CHECK: bb9: ; CHECK-NEXT: store i8 0, i8* [[ARG]], !g !0 ; CHECK-NEXT: unreachable |