Skip to content

Commit

Permalink
[SCCP] Simplify CFG in SCCP as well
Browse files Browse the repository at this point in the history
Currently, we only remove dead blocks and non-feasible edges in
IPSCCP, but not in SCCP. I'm not aware of any strong reason for
that difference, so this patch updates SCCP to perform the CFG
cleanup as well.

Compile-time impact seems to be pretty minimal, in the 0.05%
geomean range on CTMark.

For the test case from https://reviews.llvm.org/D126962#3611579
the result after -sccp now looks like this:

    define void @test(i1 %c) {
    entry:
      br i1 %c, label %unreachable, label %next
    next:
      unreachable
    unreachable:
      call void @bar()
      unreachable
    }

-jump-threading does nothing on this, but -simplifycfg will produce
the optimal result.

Differential Revision: https://reviews.llvm.org/D128796
  • Loading branch information
nikic committed Jun 30, 2022
1 parent 1e55ec6 commit 10c531c
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 53 deletions.
37 changes: 29 additions & 8 deletions llvm/lib/Transforms/Scalar/SCCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,14 @@ static bool simplifyInstsInBlock(SCCPSolver &Solver, BasicBlock &BB,
return MadeChanges;
}

static bool removeNonFeasibleEdges(const SCCPSolver &Solver, BasicBlock *BB,
DomTreeUpdater &DTU,
BasicBlock *&NewUnreachableBB);

// runSCCP() - Run the Sparse Conditional Constant Propagation algorithm,
// and return true if the function was modified.
static bool runSCCP(Function &F, const DataLayout &DL,
const TargetLibraryInfo *TLI) {
const TargetLibraryInfo *TLI, DomTreeUpdater &DTU) {
LLVM_DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
SCCPSolver Solver(
DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; },
Expand Down Expand Up @@ -221,13 +225,12 @@ static bool runSCCP(Function &F, const DataLayout &DL,
// as we cannot modify the CFG of the function.

SmallPtrSet<Value *, 32> InsertedValues;
SmallVector<BasicBlock *, 8> BlocksToErase;
for (BasicBlock &BB : F) {
if (!Solver.isBlockExecutable(&BB)) {
LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);

++NumDeadBlocks;
NumInstRemoved += removeAllNonTerminatorAndEHPadInstructions(&BB).first;

BlocksToErase.push_back(&BB);
MadeChanges = true;
continue;
}
Expand All @@ -236,17 +239,32 @@ static bool runSCCP(Function &F, const DataLayout &DL,
NumInstRemoved, NumInstReplaced);
}

// Remove unreachable blocks and non-feasible edges.
for (BasicBlock *DeadBB : BlocksToErase)
NumInstRemoved += changeToUnreachable(DeadBB->getFirstNonPHI(),
/*PreserveLCSSA=*/false, &DTU);

BasicBlock *NewUnreachableBB = nullptr;
for (BasicBlock &BB : F)
MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU, NewUnreachableBB);

for (BasicBlock *DeadBB : BlocksToErase)
if (!DeadBB->hasAddressTaken())
DTU.deleteBB(DeadBB);

return MadeChanges;
}

PreservedAnalyses SCCPPass::run(Function &F, FunctionAnalysisManager &AM) {
const DataLayout &DL = F.getParent()->getDataLayout();
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
if (!runSCCP(F, DL, &TLI))
auto *DT = AM.getCachedResult<DominatorTreeAnalysis>(F);
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
if (!runSCCP(F, DL, &TLI, DTU))
return PreservedAnalyses::all();

auto PA = PreservedAnalyses();
PA.preserveSet<CFGAnalyses>();
PA.preserve<DominatorTreeAnalysis>();
return PA;
}

Expand All @@ -269,7 +287,7 @@ class SCCPLegacyPass : public FunctionPass {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
AU.setPreservesCFG();
AU.addPreserved<DominatorTreeWrapperPass>();
}

// runOnFunction - Run the Sparse Conditional Constant Propagation
Expand All @@ -280,7 +298,10 @@ class SCCPLegacyPass : public FunctionPass {
const DataLayout &DL = F.getParent()->getDataLayout();
const TargetLibraryInfo *TLI =
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
return runSCCP(F, DL, TLI);
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DomTreeUpdater DTU(DTWP ? &DTWP->getDomTree() : nullptr,
DomTreeUpdater::UpdateStrategy::Lazy);
return runSCCP(F, DL, TLI, DTU);
}
};

Expand Down
4 changes: 1 addition & 3 deletions llvm/test/Transforms/GVN/gvn-loop-load-pre-order.ll
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ define void @main(i1 %cond) {
; CHECK-SCCP: while.cond.loopexit.loopexit:
; CHECK-SCCP-NEXT: ret void
; CHECK-SCCP: while.body3:
; CHECK-SCCP-NEXT: br i1 true, label [[IF_END:%.*]], label [[IF_THEN:%.*]]
; CHECK-SCCP: if.then:
; CHECK-SCCP-NEXT: br label [[IF_END]]
; CHECK-SCCP-NEXT: br label [[IF_END:%.*]]
; CHECK-SCCP: if.end:
; CHECK-SCCP-NEXT: br i1 [[COND:%.*]], label [[WHILE_COND_LOOPEXIT_LOOPEXIT:%.*]], label [[WHILE_BODY3]]
;
Expand Down
4 changes: 1 addition & 3 deletions llvm/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@

define i32 @foo() {
; CHECK-LABEL: @foo(
; CHECK-NEXT: br i1 undef, label [[T:%.*]], label [[T]]
; CHECK: T:
; CHECK-NEXT: ret i32 undef
; CHECK-NEXT: unreachable
;
br i1 undef, label %T, label %T
T:
Expand Down
12 changes: 0 additions & 12 deletions llvm/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,7 @@ define i32 @main() {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: br i1 undef, label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond_true:
; CHECK-NEXT: br i1 undef, label [[BB_BACKEDGE:%.*]], label [[BB12:%.*]]
; CHECK: bb.backedge:
; CHECK-NEXT: br label [[BB]]
; CHECK: cond_false:
; CHECK-NEXT: br i1 undef, label [[BB_BACKEDGE]], label [[BB12]]
; CHECK: bb12:
; CHECK-NEXT: br i1 undef, label [[COND_NEXT18:%.*]], label [[COND_TRUE17:%.*]]
; CHECK: cond_true17:
; CHECK-NEXT: unreachable
; CHECK: cond_next18:
; CHECK-NEXT: ret i32 0
;
entry:
br label %bb
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/SCCP/preserve-analysis.ll
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
; RUN: opt < %s -debug-pass-manager -passes='loop-vectorize,sccp,loop-vectorize' 2>&1 -S | FileCheck --check-prefix=NEW-PM %s

; Check CFG-only analysis are preserved by SCCP by running it between 2
; Check that DT is preserved by SCCP by running it between 2
; loop-vectorize runs.

; NEW-PM-DAG: Running analysis: LoopAnalysis on test
; NEW-PM-DAG: Running analysis: DominatorTreeAnalysis on test
; NEW-PM: Running pass: SCCPPass on test
; NEW-PM: Running analysis: TargetLibraryAnalysis on test
; NEW-PM-NOT: Running analysis: LoopAnalysis on test
; NEW-PM: Running analysis: LoopAnalysis on test
; NEW-PM-NOT: Running analysis: DominatorTreeAnalysis on test
; NEW-PM-NOT: Running analysis: AssumptionAnalysis on test
; NEW-PM-NOT: Running analysis: TargetLibraryAnalysis on test
Expand Down
9 changes: 3 additions & 6 deletions llvm/test/Transforms/SCCP/sccptest.ll
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,17 @@ define i32 @test2(i32 %i0, i32 %j0) {
; CHECK-NEXT: BB1:
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: BB2:
; CHECK-NEXT: [[K2:%.*]] = phi i32 [ [[K4:%.*]], [[BB7:%.*]] ], [ 0, [[BB1:%.*]] ]
; CHECK-NEXT: [[K2:%.*]] = phi i32 [ [[K3:%.*]], [[BB7:%.*]] ], [ 0, [[BB1:%.*]] ]
; CHECK-NEXT: [[KCOND:%.*]] = icmp slt i32 [[K2]], 100
; CHECK-NEXT: br i1 [[KCOND]], label [[BB3:%.*]], label [[BB4:%.*]]
; CHECK: BB3:
; CHECK-NEXT: br i1 true, label [[BB5:%.*]], label [[BB6:%.*]]
; CHECK-NEXT: br label [[BB5:%.*]]
; CHECK: BB4:
; CHECK-NEXT: ret i32 1
; CHECK: BB5:
; CHECK-NEXT: [[K3:%.*]] = add i32 [[K2]], 1
; CHECK-NEXT: br label [[BB7]]
; CHECK: BB6:
; CHECK-NEXT: [[K3]] = add i32 [[K2]], 1
; CHECK-NEXT: br label [[BB7]]
; CHECK: BB7:
; CHECK-NEXT: [[K4]] = phi i32 [ [[K3]], [[BB5]] ], [ undef, [[BB6]] ]
; CHECK-NEXT: br label [[BB2]]
;
BB1:
Expand Down
6 changes: 0 additions & 6 deletions llvm/test/Transforms/SCCP/strictfp-phis-fcmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@ define i1 @float.4_unreachable.defaultenv(float %f, i1 %cmp) #0 {
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br label [[END]]
; CHECK: dead:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: ret i1 [[C]]
Expand All @@ -251,8 +249,6 @@ define i1 @float.4_unreachable.maytrap(float %f, i1 %cmp) #0 {
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br label [[END]]
; CHECK: dead:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.maytrap") #[[ATTR0]]
; CHECK-NEXT: ret i1 [[C]]
Expand Down Expand Up @@ -280,8 +276,6 @@ define i1 @float.4_unreachable.strict(float %f, i1 %cmp) #0 {
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br label [[END]]
; CHECK: dead:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.strict") #[[ATTR0]]
; CHECK-NEXT: ret i1 [[C]]
Expand Down
6 changes: 0 additions & 6 deletions llvm/test/Transforms/SCCP/strictfp-phis-fcmps.ll
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@ define i1 @float.4_unreachable.defaultenv(float %f, i1 %cmp) #0 {
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br label [[END]]
; CHECK: dead:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: ret i1 [[C]]
Expand All @@ -251,8 +249,6 @@ define i1 @float.4_unreachable.maytrap(float %f, i1 %cmp) #0 {
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br label [[END]]
; CHECK: dead:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.maytrap") #[[ATTR0]]
; CHECK-NEXT: ret i1 [[C]]
Expand Down Expand Up @@ -280,8 +276,6 @@ define i1 @float.4_unreachable.strict(float %f, i1 %cmp) #0 {
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br label [[END]]
; CHECK: dead:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.strict") #[[ATTR0]]
; CHECK-NEXT: ret i1 [[C]]
Expand Down
14 changes: 7 additions & 7 deletions llvm/test/Transforms/SCCP/widening.ll
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,11 @@ define void @rotated_loop_2(i32 %x) {
; SCCP: bb3:
; SCCP-NEXT: br label [[EXIT]]
; SCCP: exit:
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]
; SCCP-NEXT: [[A]] = add i32 [[P]], 1
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]
; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
; SCCP-NEXT: call void @use(i1 true)
; SCCP-NEXT: call void @use(i1 false)
; SCCP-NEXT: br i1 false, label [[EXIT]], label [[EXIT_1:%.*]]
; SCCP-NEXT: br label [[EXIT_1:%.*]]
; SCCP: exit.1:
; SCCP-NEXT: ret void
;
Expand Down Expand Up @@ -451,10 +451,10 @@ define void @foo(i64* %arg) {
; SCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]]
; SCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1
; SCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
; SCCP-NEXT: [[TMP0:%.*]] = zext i32 [[TMP9]] to i64
; SCCP-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
; SCCP-NEXT: br label [[BB11:%.*]]
; SCCP: bb11:
; SCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
; SCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
; SCCP-NEXT: br label [[BB13:%.*]]
; SCCP: bb13:
; SCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
Expand Down Expand Up @@ -489,10 +489,10 @@ define void @foo(i64* %arg) {
; IPSCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]]
; IPSCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1
; IPSCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
; IPSCCP-NEXT: [[TMP0:%.*]] = zext i32 [[TMP9]] to i64
; IPSCCP-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
; IPSCCP-NEXT: br label [[BB11:%.*]]
; IPSCCP: bb11:
; IPSCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
; IPSCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
; IPSCCP-NEXT: br label [[BB13:%.*]]
; IPSCCP: bb13:
; IPSCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
Expand Down

0 comments on commit 10c531c

Please sign in to comment.