/// Identify connected sections of the control flow graph which have
/// dead terminators and rewrite the control flow graph to remove them.
- void updateDeadRegions();
+ bool updateDeadRegions();
/// Set the BlockInfo::PostOrder field based on a post-order
/// numbering of the reverse control flow graph.
//===----------------------------------------------------------------------===//
bool AggressiveDeadCodeElimination::removeDeadInstructions() {
// Updates control and dataflow around dead blocks
- updateDeadRegions();
+ bool RegionsUpdated = updateDeadRegions();
LLVM_DEBUG({
for (Instruction &I : instructions(F)) {
I->eraseFromParent();
}
- return !Worklist.empty();
+ return !Worklist.empty() || RegionsUpdated;
}
// A dead region is the set of dead blocks with a common live post-dominator.
-void AggressiveDeadCodeElimination::updateDeadRegions() {
+bool AggressiveDeadCodeElimination::updateDeadRegions() {
LLVM_DEBUG({
dbgs() << "final dead terminator blocks: " << '\n';
for (auto *BB : BlocksWithDeadTerminators)
// Don't compute the post ordering unless we needed it.
bool HavePostOrder = false;
+ bool Changed = false;
for (auto *BB : BlocksWithDeadTerminators) {
auto &Info = BlockInfo[BB];
.applyUpdates(DeletedEdges);
NumBranchesRemoved += 1;
+ Changed = true;
}
+
+ return Changed;
}
// reverse top-sort order
return PreservedAnalyses::all();
PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
+ // TODO: We could track if we have actually done CFG changes.
+ if (!RemoveControlFlowFlag)
+ PA.preserveSet<CFGAnalyses>();
+ else {
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<PostDominatorTreeAnalysis>();
+ }
PA.preserve<GlobalsAA>();
- PA.preserve<DominatorTreeAnalysis>();
- PA.preserve<PostDominatorTreeAnalysis>();
return PA;
}
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -licm -adce -licm -S < %s | FileCheck %s
; RUN: opt -passes='loop(licm),adce,loop(licm)' -S < %s | FileCheck %s
;
-; XFAIL: *
-; REQUIRES: asserts
-;
-; This test demonstrates a bug in ADCE's work with loop info. It does some
-; changes that make loop's block unreachable, but never bothers to update
-; loop info accordingly.
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
target triple = "x86_64-unknown-linux-gnu"
define void @test() {
-; CHECK-LABEL: test
+; CHECK-LABEL: @test(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br label [[BB2:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: ret void
+; CHECK: bb2:
+; CHECK-NEXT: br label [[BB4:%.*]]
+; CHECK: bb3:
+; CHECK-NEXT: unreachable
+; CHECK: bb4:
+; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2]]
+;
bb:
br label %bb2