[llvm-branch-commits] [llvm] 2d07414 - [SimplifyCFG] Teach simplifyUnreachable() to preserve DomTree
Roman Lebedev via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Dec 17 13:43:47 PST 2020
Author: Roman Lebedev
Date: 2020-12-18T00:37:22+03:00
New Revision: 2d07414ee5f74a09fb89723b4a9bb0818bdc2e18
URL: https://github.com/llvm/llvm-project/commit/2d07414ee5f74a09fb89723b4a9bb0818bdc2e18
DIFF: https://github.com/llvm/llvm-project/commit/2d07414ee5f74a09fb89723b4a9bb0818bdc2e18.diff
LOG: [SimplifyCFG] Teach simplifyUnreachable() to preserve DomTree
Pretty boring, removeUnwindEdge() already known how to update DomTree,
so if we are to call it, we must first flush our own pending updates;
otherwise, we just stop predecessors from branching to us,
and for certain predecessors, stop their predecessors from
branching to them also.
Added:
Modified:
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/Transforms/CallSiteSplitting/split-loop.ll
llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll
llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll
llvm/test/Transforms/SimplifyCFG/branch-fold.ll
llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
llvm/test/Transforms/SimplifyCFG/switch-profmd.ll
llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll
llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 9e4650fefff7..6a0859d84c89 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -4479,9 +4479,12 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
if (&BB->front() != UI)
return Changed;
+ std::vector<DominatorTree::UpdateType> Updates;
+
SmallVector<BasicBlock *, 8> Preds(pred_begin(BB), pred_end(BB));
for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
- Instruction *TI = Preds[i]->getTerminator();
+ auto *Predecessor = Preds[i];
+ Instruction *TI = Predecessor->getTerminator();
IRBuilder<> Builder(TI);
if (auto *BI = dyn_cast<BranchInst>(TI)) {
if (BI->isUnconditional()) {
@@ -4491,6 +4494,9 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
Changed = true;
} else {
Value* Cond = BI->getCondition();
+ assert(BI->getSuccessor(0) != BI->getSuccessor(1) &&
+ "Same-destination conditional branch instruction was "
+ "already canonicalized into an unconditional branch.");
if (BI->getSuccessor(0) == BB) {
Builder.CreateAssumption(Builder.CreateNot(Cond));
Builder.CreateBr(BI->getSuccessor(1));
@@ -4502,6 +4508,7 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
EraseTerminatorAndDCECond(BI);
Changed = true;
}
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
} else if (auto *SI = dyn_cast<SwitchInst>(TI)) {
SwitchInstProfUpdateWrapper SU(*SI);
for (auto i = SU->case_begin(), e = SU->case_end(); i != e;) {
@@ -4514,14 +4521,21 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
e = SU->case_end();
Changed = true;
}
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
} else if (auto *II = dyn_cast<InvokeInst>(TI)) {
if (II->getUnwindDest() == BB) {
- removeUnwindEdge(TI->getParent());
+ if (DTU)
+ DTU->applyUpdatesPermissive(Updates);
+ Updates.clear();
+ removeUnwindEdge(TI->getParent(), DTU);
Changed = true;
}
} else if (auto *CSI = dyn_cast<CatchSwitchInst>(TI)) {
if (CSI->getUnwindDest() == BB) {
- removeUnwindEdge(TI->getParent());
+ if (DTU)
+ DTU->applyUpdatesPermissive(Updates);
+ Updates.clear();
+ removeUnwindEdge(TI->getParent(), DTU);
Changed = true;
continue;
}
@@ -4536,35 +4550,54 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
Changed = true;
}
}
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
if (CSI->getNumHandlers() == 0) {
- BasicBlock *CatchSwitchBB = CSI->getParent();
if (CSI->hasUnwindDest()) {
- // Redirect preds to the unwind dest
- CatchSwitchBB->replaceAllUsesWith(CSI->getUnwindDest());
+ // Redirect all predecessors of the block containing CatchSwitchInst
+ // to instead branch to the CatchSwitchInst's unwind destination.
+ for (auto *PredecessorOfPredecessor : predecessors(Predecessor)) {
+ Updates.push_back(
+ {DominatorTree::Delete, PredecessorOfPredecessor, Predecessor});
+ Updates.push_back({DominatorTree::Insert, PredecessorOfPredecessor,
+ CSI->getUnwindDest()});
+ }
+ Predecessor->replaceAllUsesWith(CSI->getUnwindDest());
} else {
// Rewrite all preds to unwind to caller (or from invoke to call).
- SmallVector<BasicBlock *, 8> EHPreds(predecessors(CatchSwitchBB));
+ if (DTU)
+ DTU->applyUpdatesPermissive(Updates);
+ Updates.clear();
+ SmallVector<BasicBlock *, 8> EHPreds(predecessors(Predecessor));
for (BasicBlock *EHPred : EHPreds)
- removeUnwindEdge(EHPred);
+ removeUnwindEdge(EHPred, DTU);
}
// The catchswitch is no longer reachable.
new UnreachableInst(CSI->getContext(), CSI);
CSI->eraseFromParent();
Changed = true;
}
- } else if (isa<CleanupReturnInst>(TI)) {
+ } else if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) {
+ assert(CRI->hasUnwindDest() && CRI->getUnwindDest() == BB &&
+ "Expected to always have an unwind to BB.");
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
new UnreachableInst(TI->getContext(), TI);
TI->eraseFromParent();
Changed = true;
}
}
+ if (DTU)
+ DTU->applyUpdatesPermissive(Updates);
+
// If this block is now dead, remove it.
if (pred_empty(BB) && BB != &BB->getParent()->getEntryBlock()) {
// We know there are no successors, so just nuke the block.
if (LoopHeaders)
LoopHeaders->erase(BB);
- BB->eraseFromParent();
+ if (DTU)
+ DTU->deleteBB(BB);
+ else
+ BB->eraseFromParent();
return true;
}
diff --git a/llvm/test/Transforms/CallSiteSplitting/split-loop.ll b/llvm/test/Transforms/CallSiteSplitting/split-loop.ll
index 1e71643b7b9e..0c65e724c8a7 100644
--- a/llvm/test/Transforms/CallSiteSplitting/split-loop.ll
+++ b/llvm/test/Transforms/CallSiteSplitting/split-loop.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -callsite-splitting -simplifycfg < %s | FileCheck %s
+; RUN: opt -S -callsite-splitting -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
define i16 @test1() {
; CHECK-LABEL: @test1(
diff --git a/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll b/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll
index f5f7970566cb..79170e6615b7 100644
--- a/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll
+++ b/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -inline -instcombine -jump-threading -licm -simple-loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -verify -disable-output
+; RUN: opt < %s -inline -instcombine -jump-threading -licm -simple-loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -verify -disable-output
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"
target triple = "i386-apple-darwin9"
@@ -18,7 +18,7 @@ target triple = "i386-apple-darwin9"
@scaleFactorsPH = external global [2 x [2 x %struct.BF_PartHolder*]] ; <[2 x [2 x %struct.BF_PartHolder*]]*> [#uses=1]
@slen1_tab = external constant [16 x i32] ; <[16 x i32]*> [#uses=1]
-declare %struct.BF_PartHolder* @BF_addElement(%struct.BF_PartHolder*, %struct.BF_BitstreamElement*) nounwind
+declare %struct.BF_PartHolder* @BF_addElement(%struct.BF_PartHolder*, %struct.BF_BitstreamElement*) nounwind
define %struct.BF_PartHolder* @BF_addEntry(%struct.BF_PartHolder* %thePH, i32 %value, i32 %length) nounwind {
entry:
@@ -38,7 +38,7 @@ bb13: ; preds = %entry
define void @III_format_bitstream(%struct.lame_global_flags* %gfp, i32 %bitsPerFrame, [2 x [576 x i32]]* %l3_enc, %struct.III_side_info_t* %l3_side, [2 x %struct.III_scalefac_t]* %scalefac, %struct.Bit_stream_struc* %in_bs) nounwind {
entry:
- call fastcc void @encodeMainData( %struct.lame_global_flags* %gfp, [2 x [576 x i32]]* %l3_enc, %struct.III_side_info_t* %l3_side, [2 x %struct.III_scalefac_t]* %scalefac ) nounwind
+ call fastcc void @encodeMainData( %struct.lame_global_flags* %gfp, [2 x [576 x i32]]* %l3_enc, %struct.III_side_info_t* %l3_side, [2 x %struct.III_scalefac_t]* %scalefac ) nounwind
unreachable
}
diff --git a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
index c8f59d4bd9ae..4ec8fe7e68f8 100644
--- a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
+++ b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -simplifycfg -S | FileCheck %s
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
define void @test1(i1 %C, i1* %BP) {
; CHECK-LABEL: @test1(
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll b/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll
index bc422ddcd5f6..8704bcf005ea 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -simplifycfg < %s | FileCheck %s
+; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/Transforms/SimplifyCFG/branch-fold.ll b/llvm/test/Transforms/SimplifyCFG/branch-fold.ll
index 7097dea424e1..a4ac23bada70 100644
--- a/llvm/test/Transforms/SimplifyCFG/branch-fold.ll
+++ b/llvm/test/Transforms/SimplifyCFG/branch-fold.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -simplifycfg -S | FileCheck %s
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
define void @test(i32* %P, i32* %Q, i1 %A, i1 %B) {
; CHECK: test
diff --git a/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
index 2926cd3f7dc7..6e9141568df6 100644
--- a/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
+++ b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -simplifycfg -S | FileCheck %s
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
declare void @f()
declare void @llvm.foo(i32) nounwind
diff --git a/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll b/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
index a498976c10f8..c758826dc435 100644
--- a/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
+++ b/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -simplifycfg -S | FileCheck %s
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
declare void @llvm.lifetime.start.p0i8(i64, i8*)
declare void @llvm.lifetime.end.p0i8(i64, i8*)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll b/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll
index c17214e18f20..3f8f5716604a 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -simplifycfg < %s | FileCheck %s
+; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
declare i32 @f(i32 %val)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
index d99e84b6b940..7125575b2f33 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt %s -simplifycfg -S | FileCheck %s
+; RUN: opt %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
declare i32 @f(i32)
diff --git a/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll b/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll
index e0d1e27a9952..2eb7f4da1d8a 100644
--- a/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll
+++ b/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt %s -simplifycfg -instcombine -S | FileCheck %s
+; RUN: opt %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -instcombine -S | FileCheck %s
define i32 @assume1(i32 %p) {
; CHECK-LABEL: @assume1(
diff --git a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
index 7655fa7875f2..c951294233ff 100644
--- a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
+++ b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -simplifycfg < %s | FileCheck %s
+; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
declare void @Personality()
declare void @f()
More information about the llvm-branch-commits
mailing list