diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -22,6 +22,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/Value.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" @@ -376,7 +377,13 @@ /// If \p KeepOneInputPHIs is true then don't remove PHIs that are left with /// zero or one incoming values, and don't simplify PHIs with all incoming /// values the same. - void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false); + /// + /// If \p MaybeDeadInstrs is not nullptr then whenever we drop a reference to + /// an instruction, append it to the vector. The caller should check whether + /// these instructions are now trivially dead, and if so delete them. + void + removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false, + SmallVectorImpl *MaybeDeadInstrs = nullptr); bool canSplitPredecessors() const; diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -323,8 +323,13 @@ /// If \p KeepOneInputPHIs is true then don't remove PHIs that are left with /// zero or one incoming values, and don't simplify PHIs with all incoming /// values the same. -void BasicBlock::removePredecessor(BasicBlock *Pred, - bool KeepOneInputPHIs) { +/// +/// If \p MaybeDeadInstrs is not nullptr then whenever we drop a reference to +/// an instruction, append it to the vector. The caller should check whether +/// these instructions are now trivially dead, and if so delete them. +void BasicBlock::removePredecessor( + BasicBlock *Pred, bool KeepOneInputPHIs, + SmallVectorImpl *MaybeDeadInstrs) { // Use hasNUsesOrMore to bound the cost of this assertion for complex CFGs. assert((hasNUsesOrMore(16) || find(pred_begin(this), pred_end(this), Pred) != pred_end(this)) && @@ -338,7 +343,11 @@ // Update all PHI nodes. for (iterator II = begin(); isa(II);) { PHINode *PN = cast(II++); - PN->removeIncomingValue(Pred, !KeepOneInputPHIs); + Value *V = PN->removeIncomingValue(Pred); + if (MaybeDeadInstrs) { + if (auto *I = dyn_cast(V)) + MaybeDeadInstrs->push_back(I); + } if (!KeepOneInputPHIs) { // If we have a single predecessor, removeIncomingValue erased the PHI // node itself. diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -126,8 +126,11 @@ BasicBlock *OldDest = Cond->getZExtValue() ? Dest2 : Dest1; // Let the basic block know that we are letting go of it. Based on this, - // it will adjust it's PHI nodes. - OldDest->removePredecessor(BB); + // it will adjust its PHI nodes. + SmallVector MaybeDeadInstrs; + OldDest->removePredecessor(BB, false, &MaybeDeadInstrs); + RecursivelyDeleteTriviallyDeadInstructionsPermissive(MaybeDeadInstrs, + TLI); // Replace the conditional branch with an unconditional one. Builder.CreateBr(Destination); @@ -470,8 +473,8 @@ MemorySSAUpdater *MSSAU) { unsigned S = 0, E = DeadInsts.size(), Alive = 0; for (; S != E; ++S) { - auto *I = cast(DeadInsts[S]); - if (!isInstructionTriviallyDead(I)) { + auto *I = dyn_cast(DeadInsts[S]); + if (!I || !isInstructionTriviallyDead(I)) { DeadInsts[S] = nullptr; ++Alive; } diff --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll --- a/llvm/test/Transforms/PGOProfile/chr.ll +++ b/llvm/test/Transforms/PGOProfile/chr.ll @@ -448,34 +448,33 @@ ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[I:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 15 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 15 -; CHECK-NEXT: br i1 [[TMP2]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 85 -; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[SUM0]], 173 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 173 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 255 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[SUM0]], 42 -; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM0]], i32 [[TMP9]], !prof !16 -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[SUM1_NONCHR]], 43 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP11]], i32 [[SUM1_NONCHR]], i32 [[TMP12]], !prof !16 -; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP0]], 4 -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 -; CHECK-NEXT: [[TMP15:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP16]], i32 44, i32 88 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM0]], 42 +; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM0]], i32 [[TMP8]], !prof !16 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[SUM1_NONCHR]], 43 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP10]], i32 [[SUM1_NONCHR]], i32 [[TMP11]], !prof !16 +; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP0]], 4 +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 +; CHECK-NEXT: [[TMP14:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i32 [[TMP14]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP15]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP14]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP3]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: @@ -548,34 +547,33 @@ ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 11 ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 11 ; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP2]] -; CHECK-NEXT: br i1 [[TMP5]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[SUM0]], 85 -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[SUM0]], 173 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[SUM0]], 173 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: -; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 -; CHECK-NEXT: br i1 [[TMP9]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 255 +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 +; CHECK-NEXT: br i1 [[TMP8]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[SUM0]], 42 -; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP11]], i32 [[SUM0]], i32 [[TMP12]], !prof !16 -; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 -; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[SUM1_NONCHR]], 43 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP14]], i32 [[SUM1_NONCHR]], i32 [[TMP15]], !prof !16 -; CHECK-NEXT: [[TMP16:%.*]] = and i32 [[SUM0]], 4 -; CHECK-NEXT: [[TMP17:%.*]] = icmp eq i32 [[TMP16]], 0 -; CHECK-NEXT: [[TMP18:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP19]], i32 44, i32 88 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[SUM0]], 42 +; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP10]], i32 [[SUM0]], i32 [[TMP11]], !prof !16 +; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 +; CHECK-NEXT: [[TMP14:%.*]] = add i32 [[SUM1_NONCHR]], 43 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM1_NONCHR]], i32 [[TMP14]], !prof !16 +; CHECK-NEXT: [[TMP15:%.*]] = and i32 [[SUM0]], 4 +; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 +; CHECK-NEXT: [[TMP17:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[TMP17]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP18]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP17]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP16]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP7]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP6]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: @@ -649,10 +647,9 @@ ; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[I0]], 10 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 10 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[V10]] -; CHECK-NEXT: br i1 [[TMP2]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[V8:%.*]] = add i32 [[SUM0:%.*]], 43 -; CHECK-NEXT: [[V13:%.*]] = add i32 [[SUM0]], 131 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[V13:%.*]] = add i32 [[SUM0:%.*]], 131 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[V1:%.*]] = and i32 [[I0]], 255 @@ -672,7 +669,7 @@ ; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[V10_NONCHR]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[V13]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[V13]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: @@ -1737,28 +1734,27 @@ ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[I:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 9 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 9 -; CHECK-NEXT: br i1 [[TMP2]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 85 -; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[SUM0]], 173 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 173 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 255 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[SUM0]], 85 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM0]], i32 [[TMP9]], !prof !16 -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP11]], i32 44, i32 88 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM0]], 85 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM0]], i32 [[TMP8]], !prof !16 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP10]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP3]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: