Skip to content

Commit adf3891

Browse files
committedOct 29, 2017
[(new) Pass Manager] instantiate SimplifyCFG with the same options as the old PM
The old PM sets the options of what used to be known as "latesimplifycfg" on the instantiation after the vectorizers have run, so that's what we'redoing here. FWIW, there's a later SimplifyCFGPass instantiation in both PMs where we do not set the "late" options. I'm not sure if that's intentional or not. Differential Revision: https://reviews.llvm.org/D39407 llvm-svn: 316869
1 parent 61921f7 commit adf3891

File tree

3 files changed

+40
-64
lines changed

3 files changed

+40
-64
lines changed
 

‎llvm/include/llvm/Transforms/Scalar/SimplifyCFG.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ class SimplifyCFGPass : public PassInfoMixin<SimplifyCFGPass> {
3131
SimplifyCFGOptions Options;
3232

3333
public:
34-
/// The default constructor sets the pass options to create optimal IR,
35-
/// rather than canonical IR. That is, by default we do transformations that
36-
/// are likely to improve performance but make analysis more difficult.
37-
/// FIXME: This is inverted from what most instantiations of the pass should
38-
/// be.
34+
/// The default constructor sets the pass options to create canonical IR,
35+
/// rather than optimal IR. That is, by default we bypass transformations that
36+
/// are likely to improve performance but make analysis for other passes more
37+
/// difficult.
3938
SimplifyCFGPass()
4039
: SimplifyCFGPass(SimplifyCFGOptions()
41-
.forwardSwitchCondToPhi(true)
42-
.convertSwitchToLookupTable(true)
43-
.needCanonicalLoops(false)) {}
40+
.forwardSwitchCondToPhi(false)
41+
.convertSwitchToLookupTable(false)
42+
.needCanonicalLoops(true)) {}
43+
4444

4545
/// Construct a pass with optional optimizations.
4646
SimplifyCFGPass(const SimplifyCFGOptions &PassOptions);

‎llvm/lib/Passes/PassBuilder.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -751,8 +751,13 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
751751
// Optimize parallel scalar instruction chains into SIMD instructions.
752752
OptimizePM.addPass(SLPVectorizerPass());
753753

754-
// Cleanup after all of the vectorizers.
755-
OptimizePM.addPass(SimplifyCFGPass());
754+
// Cleanup after all of the vectorizers. Simplification passes like CVP and
755+
// GVN, loop transforms, and others have already run, so it's now better to
756+
// convert to more optimized IR using more aggressive simplify CFG options.
757+
OptimizePM.addPass(SimplifyCFGPass(SimplifyCFGOptions().
758+
forwardSwitchCondToPhi(true).
759+
convertSwitchToLookupTable(true).
760+
needCanonicalLoops(false)));
756761
OptimizePM.addPass(InstCombinePass());
757762

758763
// Unroll small loops to hide loop backedge latency and saturate any parallel

‎llvm/test/Transforms/PhaseOrdering/simplifycfg-options.ll

+25-54
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,34 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt -O1 -S < %s | FileCheck %s --check-prefix=OLDPM
3-
; RUN: opt -passes='default<O1>' -S < %s | FileCheck %s --check-prefix=NEWPM
2+
; RUN: opt -O1 -S < %s | FileCheck %s --check-prefix=ALL --check-prefix=OLDPM
3+
; RUN: opt -passes='default<O1>' -S < %s | FileCheck %s --check-prefix=ALL --check-prefix=NEWPM
44

55
; Don't simplify unconditional branches from empty blocks in simplifyCFG
66
; until late in the pipeline because it can destroy canonical loop structure.
77

8-
; FIXME: The new pass manager is not limiting simplifycfg at any point in the pipeline,
9-
; so it performs a transformation before loop optimizations that is avoided in the old PM.
10-
118
define i1 @PR33605(i32 %a, i32 %b, i32* %c) {
12-
; OLDPM-LABEL: @PR33605(
13-
; OLDPM-NEXT: for.body:
14-
; OLDPM-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
15-
; OLDPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[C:%.*]], i64 1
16-
; OLDPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
17-
; OLDPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], [[TMP0]]
18-
; OLDPM-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
19-
; OLDPM: if.then:
20-
; OLDPM-NEXT: store i32 [[OR]], i32* [[ARRAYIDX]], align 4
21-
; OLDPM-NEXT: tail call void @foo()
22-
; OLDPM-NEXT: br label [[IF_END]]
23-
; OLDPM: if.end:
24-
; OLDPM-NEXT: [[CHANGED_1_OFF0:%.*]] = phi i1 [ true, [[IF_THEN]] ], [ false, [[FOR_BODY:%.*]] ]
25-
; OLDPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[C]], align 4
26-
; OLDPM-NEXT: [[CMP_1:%.*]] = icmp eq i32 [[OR]], [[TMP1]]
27-
; OLDPM-NEXT: br i1 [[CMP_1]], label [[IF_END_1:%.*]], label [[IF_THEN_1:%.*]]
28-
; OLDPM: if.then.1:
29-
; OLDPM-NEXT: store i32 [[OR]], i32* [[C]], align 4
30-
; OLDPM-NEXT: tail call void @foo()
31-
; OLDPM-NEXT: br label [[IF_END_1]]
32-
; OLDPM: if.end.1:
33-
; OLDPM-NEXT: [[CHANGED_1_OFF0_1:%.*]] = phi i1 [ true, [[IF_THEN_1]] ], [ [[CHANGED_1_OFF0]], [[IF_END]] ]
34-
; OLDPM-NEXT: ret i1 [[CHANGED_1_OFF0_1]]
35-
;
36-
; NEWPM-LABEL: @PR33605(
37-
; NEWPM-NEXT: entry:
38-
; NEWPM-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
39-
; NEWPM-NEXT: br label [[FOR_COND_OUTER:%.*]]
40-
; NEWPM: for.cond.outer:
41-
; NEWPM-NEXT: [[I_0_PH:%.*]] = phi i32 [ [[DEC:%.*]], [[IF_THEN:%.*]] ], [ 2, [[ENTRY:%.*]] ]
42-
; NEWPM-NEXT: [[CHANGED_0_OFF0_PH:%.*]] = phi i1 [ true, [[IF_THEN]] ], [ false, [[ENTRY]] ]
43-
; NEWPM-NEXT: br label [[FOR_COND:%.*]]
44-
; NEWPM: for.cond:
45-
; NEWPM-NEXT: [[I_0:%.*]] = phi i32 [ [[DEC]], [[FOR_BODY:%.*]] ], [ [[I_0_PH]], [[FOR_COND_OUTER]] ]
46-
; NEWPM-NEXT: [[DEC]] = add nsw i32 [[I_0]], -1
47-
; NEWPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[I_0]], 0
48-
; NEWPM-NEXT: br i1 [[TOBOOL]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
49-
; NEWPM: for.cond.cleanup:
50-
; NEWPM-NEXT: ret i1 [[CHANGED_0_OFF0_PH]]
51-
; NEWPM: for.body:
52-
; NEWPM-NEXT: [[IDXPROM:%.*]] = sext i32 [[DEC]] to i64
53-
; NEWPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[C:%.*]], i64 [[IDXPROM]]
54-
; NEWPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
55-
; NEWPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], [[TMP0]]
56-
; NEWPM-NEXT: br i1 [[CMP]], label [[FOR_COND]], label [[IF_THEN]]
57-
; NEWPM: if.then:
58-
; NEWPM-NEXT: store i32 [[OR]], i32* [[ARRAYIDX]], align 4
59-
; NEWPM-NEXT: tail call void @foo()
60-
; NEWPM-NEXT: br label [[FOR_COND_OUTER]]
9+
; ALL-LABEL: @PR33605(
10+
; ALL-NEXT: for.body:
11+
; ALL-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
12+
; ALL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[C:%.*]], i64 1
13+
; ALL-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
14+
; ALL-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], [[TMP0]]
15+
; ALL-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
16+
; ALL: if.then:
17+
; ALL-NEXT: store i32 [[OR]], i32* [[ARRAYIDX]], align 4
18+
; ALL-NEXT: tail call void @foo()
19+
; ALL-NEXT: br label [[IF_END]]
20+
; ALL: if.end:
21+
; ALL-NEXT: [[CHANGED_1_OFF0:%.*]] = phi i1 [ true, [[IF_THEN]] ], [ false, [[FOR_BODY:%.*]] ]
22+
; ALL-NEXT: [[TMP1:%.*]] = load i32, i32* [[C]], align 4
23+
; ALL-NEXT: [[CMP_1:%.*]] = icmp eq i32 [[OR]], [[TMP1]]
24+
; ALL-NEXT: br i1 [[CMP_1]], label [[IF_END_1:%.*]], label [[IF_THEN_1:%.*]]
25+
; ALL: if.then.1:
26+
; ALL-NEXT: store i32 [[OR]], i32* [[C]], align 4
27+
; ALL-NEXT: tail call void @foo()
28+
; ALL-NEXT: br label [[IF_END_1]]
29+
; ALL: if.end.1:
30+
; ALL-NEXT: [[CHANGED_1_OFF0_1:%.*]] = phi i1 [ true, [[IF_THEN_1]] ], [ [[CHANGED_1_OFF0]], [[IF_END]] ]
31+
; ALL-NEXT: ret i1 [[CHANGED_1_OFF0_1]]
6132
;
6233
entry:
6334
br label %for.cond

0 commit comments

Comments
 (0)
Please sign in to comment.