From 3eedb093ba260310dc032120096b29dfb983e134 Mon Sep 17 00:00:00 2001 From: Daniel Berlin Date: Thu, 26 Jan 2017 18:30:29 +0000 Subject: [PATCH] NewGVN: Make unreachable blocks be marked with unreachable llvm-svn: 293196 --- lib/Transforms/Scalar/NewGVN.cpp | 31 +++++++-------- .../NewGVN/2008-12-09-SelfRemove.ll | 38 +++++++++---------- test/Transforms/NewGVN/pr31594.ll | 2 +- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/lib/Transforms/Scalar/NewGVN.cpp b/lib/Transforms/Scalar/NewGVN.cpp index 747c913278f..bf73375908f 100644 --- a/lib/Transforms/Scalar/NewGVN.cpp +++ b/lib/Transforms/Scalar/NewGVN.cpp @@ -1989,26 +1989,21 @@ void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) { DEBUG(dbgs() << " BasicBlock Dead:" << *BB); ++NumGVNBlocksDeleted; - // Check to see if there are non-terminating instructions to delete. - if (isa(BB->begin())) + // Change to unreachable does not handle destroying phi nodes. We just replace + // the users with undef. + if (BB->empty()) return; - - // 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(Inst)) - continue; - - Inst.eraseFromParent(); - ++NumGVNInstrDeleted; + auto BBI = BB->begin(); + while (auto *Phi = dyn_cast(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); } void NewGVN::markInstructionForDeletion(Instruction *I) { diff --git a/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll b/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll index c1b5cc81fb5..05fe2a22a3f 100644 --- a/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll +++ b/test/Transforms/NewGVN/2008-12-09-SelfRemove.ll @@ -1,3 +1,4 @@ +; 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" @@ -9,30 +10,29 @@ 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 ; [#uses=1] - br i1 false, label %return, label %bb + %0 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 ; [#uses=1] + br i1 false, label %return, label %bb bb: ; preds = %entry - %1 = load i8*, i8** %0, align 4 ; [#uses=0] - %2 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 ; [#uses=0] - br label %bb21 + %1 = load i8*, i8** %0, align 4 ; [#uses=0] + %2 = getelementptr %struct.d_print_info, %struct.d_print_info* %dpi, i32 0, i32 1 ; [#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/test/Transforms/NewGVN/pr31594.ll b/test/Transforms/NewGVN/pr31594.ll index bca4127d3ae..071fe9b0134 100644 --- a/test/Transforms/NewGVN/pr31594.ll +++ b/test/Transforms/NewGVN/pr31594.ll @@ -76,7 +76,7 @@ define void @foo(i8* %arg) { ; CHECK-NEXT: i8 6, label [[BB8:%.*]] ; CHECK-NEXT: ] ; CHECK: bb8: -; CHECK-NEXT: br label [[BB4]] +; CHECK-NEXT: unreachable ; CHECK: bb9: ; CHECK-NEXT: store i8 0, i8* [[ARG]], !g !0 ; CHECK-NEXT: unreachable