Skip to content

Commit 73a6cd1

Browse files
committed
[SimplifyCFG] Allow some switch optimizations early in the pipeline
While we do not want to form actual lookup tables early, we do want to perform some optimizations, as they may enable inlining of the much simpler form. Builds on llvm#156477, which originally included this change as well.
1 parent fd4ef8e commit 73a6cd1

File tree

2 files changed

+29
-69
lines changed

2 files changed

+29
-69
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6508,6 +6508,9 @@ class SwitchReplacement {
65086508
/// Return true if the replacement is a lookup table.
65096509
bool isLookupTable();
65106510

6511+
/// Return true if the replacement is a bit map.
6512+
bool isBitMap();
6513+
65116514
private:
65126515
// Depending on the switch, there are different alternatives.
65136516
enum {
@@ -6798,6 +6801,8 @@ Constant *SwitchReplacement::getDefaultValue() { return DefaultValue; }
67986801

67996802
bool SwitchReplacement::isLookupTable() { return Kind == LookupTableKind; }
68006803

6804+
bool SwitchReplacement::isBitMap() { return Kind == BitMapKind; }
6805+
68016806
static bool isSwitchDense(uint64_t NumCases, uint64_t CaseRange) {
68026807
// 40% is the default density for building a jump table in optsize/minsize
68036808
// mode. See also TargetLoweringBase::isSuitableForJumpTable(), which this
@@ -6963,7 +6968,8 @@ static void reuseTableCompare(
69636968
/// lookup tables.
69646969
static bool simplifySwitchLookup(SwitchInst *SI, IRBuilder<> &Builder,
69656970
DomTreeUpdater *DTU, const DataLayout &DL,
6966-
const TargetTransformInfo &TTI) {
6971+
const TargetTransformInfo &TTI,
6972+
bool ConvertSwitchToLookupTable) {
69676973
assert(SI->getNumCases() > 1 && "Degenerate switch?");
69686974

69696975
BasicBlock *BB = SI->getParent();
@@ -7128,6 +7134,8 @@ static bool simplifySwitchLookup(SwitchInst *SI, IRBuilder<> &Builder,
71287134

71297135
bool AnyLookupTables = any_of(
71307136
PhiToReplacementMap, [](auto &KV) { return KV.second.isLookupTable(); });
7137+
bool AnyBitMaps = any_of(PhiToReplacementMap,
7138+
[](auto &KV) { return KV.second.isBitMap(); });
71317139

71327140
// A few conditions prevent the generation of lookup tables:
71337141
// 1. The target does not support lookup tables.
@@ -7140,6 +7148,11 @@ static bool simplifySwitchLookup(SwitchInst *SI, IRBuilder<> &Builder,
71407148
Fn->getFnAttribute("no-jump-tables").getValueAsBool()))
71417149
return false;
71427150

7151+
// In the early optimization pipeline, disable formation of lookup tables
7152+
// and bit maps, as they may inhibit further optimization.
7153+
if (!ConvertSwitchToLookupTable && (AnyLookupTables || AnyBitMaps))
7154+
return false;
7155+
71437156
Builder.SetInsertPoint(SI);
71447157
// TableIndex is the switch condition - TableIndexOffset if we don't
71457158
// use the condition directly
@@ -7780,13 +7793,8 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
77807793
if (Options.ForwardSwitchCondToPhi && forwardSwitchConditionToPHI(SI))
77817794
return requestResimplify();
77827795

7783-
// The conversion from switch to lookup tables results in difficult-to-analyze
7784-
// code and makes pruning branches much harder. This is a problem if the
7785-
// switch expression itself can still be restricted as a result of inlining or
7786-
// CVP. Therefore, only apply this transformation during late stages of the
7787-
// optimisation pipeline.
7788-
if (Options.ConvertSwitchToLookupTable &&
7789-
simplifySwitchLookup(SI, Builder, DTU, DL, TTI))
7796+
if (simplifySwitchLookup(SI, Builder, DTU, DL, TTI,
7797+
Options.ConvertSwitchToLookupTable))
77907798
return requestResimplify();
77917799

77927800
if (simplifySwitchOfPowersOfTwo(SI, Builder, DL, TTI))

llvm/test/Transforms/SimplifyCFG/switch-transformations-no-lut.ll

Lines changed: 13 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
77
define i32 @linear_transform_with_default(i32 %x) {
88
; OPTNOLUT-LABEL: define i32 @linear_transform_with_default(
99
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
10-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
11-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[END:.*]] [
12-
; OPTNOLUT-NEXT: i32 0, label %[[CASE0:.*]]
13-
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
14-
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
15-
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
16-
; OPTNOLUT-NEXT: ]
17-
; OPTNOLUT: [[CASE0]]:
18-
; OPTNOLUT-NEXT: br label %[[END]]
19-
; OPTNOLUT: [[CASE1]]:
20-
; OPTNOLUT-NEXT: br label %[[END]]
21-
; OPTNOLUT: [[CASE2]]:
22-
; OPTNOLUT-NEXT: br label %[[END]]
23-
; OPTNOLUT: [[CASE3]]:
24-
; OPTNOLUT-NEXT: br label %[[END]]
25-
; OPTNOLUT: [[END]]:
26-
; OPTNOLUT-NEXT: [[IDX:%.*]] = phi i32 [ 1, %[[CASE0]] ], [ 4, %[[CASE1]] ], [ 7, %[[CASE2]] ], [ 10, %[[CASE3]] ], [ 13, %[[ENTRY]] ]
10+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
11+
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 4
12+
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[X]], 3
13+
; OPTNOLUT-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i32 [[SWITCH_IDX_MULT]], 1
14+
; OPTNOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 13
2715
; OPTNOLUT-NEXT: ret i32 [[IDX]]
2816
;
2917
; TTINOLUT-LABEL: define i32 @linear_transform_with_default(
@@ -138,26 +126,8 @@ end:
138126
define i32 @linear_transform_no_default(i32 %x) {
139127
; OPTNOLUT-LABEL: define i32 @linear_transform_no_default(
140128
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
141-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
142-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
143-
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
144-
; OPTNOLUT-NEXT: i32 1, label %[[CASE1:.*]]
145-
; OPTNOLUT-NEXT: i32 2, label %[[CASE2:.*]]
146-
; OPTNOLUT-NEXT: i32 3, label %[[CASE3:.*]]
147-
; OPTNOLUT-NEXT: i32 4, label %[[CASE4:.*]]
148-
; OPTNOLUT-NEXT: ]
149-
; OPTNOLUT: [[CASE1]]:
150-
; OPTNOLUT-NEXT: br label %[[END]]
151-
; OPTNOLUT: [[CASE2]]:
152-
; OPTNOLUT-NEXT: br label %[[END]]
153-
; OPTNOLUT: [[CASE3]]:
154-
; OPTNOLUT-NEXT: br label %[[END]]
155-
; OPTNOLUT: [[CASE4]]:
156-
; OPTNOLUT-NEXT: br label %[[END]]
157-
; OPTNOLUT: [[DEFAULT]]:
158-
; OPTNOLUT-NEXT: unreachable
159-
; OPTNOLUT: [[END]]:
160-
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = phi i32 [ 3, %[[CASE1]] ], [ 6, %[[CASE2]] ], [ 9, %[[CASE3]] ], [ 12, %[[CASE4]] ], [ 0, %[[ENTRY]] ]
129+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
130+
; OPTNOLUT-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nsw i32 [[X]], 3
161131
; OPTNOLUT-NEXT: ret i32 [[SWITCH_IDX_MULT]]
162132
;
163133
; TTINOLUT-LABEL: define i32 @linear_transform_no_default(
@@ -350,18 +320,9 @@ end:
350320
define i32 @single_value_withdefault(i32 %x) {
351321
; OPTNOLUT-LABEL: define i32 @single_value_withdefault(
352322
; OPTNOLUT-SAME: i32 [[X:%.*]]) {
353-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
354-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
355-
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
356-
; OPTNOLUT-NEXT: i32 1, label %[[END]]
357-
; OPTNOLUT-NEXT: i32 2, label %[[END]]
358-
; OPTNOLUT-NEXT: i32 3, label %[[END]]
359-
; OPTNOLUT-NEXT: i32 4, label %[[END]]
360-
; OPTNOLUT-NEXT: ]
361-
; OPTNOLUT: [[DEFAULT]]:
362-
; OPTNOLUT-NEXT: br label %[[END]]
363-
; OPTNOLUT: [[END]]:
364-
; OPTNOLUT-NEXT: [[DOT:%.*]] = phi i32 [ 3, %[[DEFAULT]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ]
323+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
324+
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 5
325+
; OPTNOLUT-NEXT: [[DOT:%.*]] = select i1 [[TMP0]], i32 2, i32 3
365326
; OPTNOLUT-NEXT: ret i32 [[DOT]]
366327
;
367328
; TTINOLUT-LABEL: define i32 @single_value_withdefault(
@@ -401,18 +362,9 @@ end:
401362
define i32 @single_value_no_jump_tables(i32 %x) "no-jump-tables"="true" {
402363
; OPTNOLUT-LABEL: define i32 @single_value_no_jump_tables(
403364
; OPTNOLUT-SAME: i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
404-
; OPTNOLUT-NEXT: [[ENTRY:.*]]:
405-
; OPTNOLUT-NEXT: switch i32 [[X]], label %[[DEFAULT:.*]] [
406-
; OPTNOLUT-NEXT: i32 0, label %[[END:.*]]
407-
; OPTNOLUT-NEXT: i32 1, label %[[END]]
408-
; OPTNOLUT-NEXT: i32 2, label %[[END]]
409-
; OPTNOLUT-NEXT: i32 3, label %[[END]]
410-
; OPTNOLUT-NEXT: i32 4, label %[[END]]
411-
; OPTNOLUT-NEXT: ]
412-
; OPTNOLUT: [[DEFAULT]]:
413-
; OPTNOLUT-NEXT: br label %[[END]]
414-
; OPTNOLUT: [[END]]:
415-
; OPTNOLUT-NEXT: [[IDX:%.*]] = phi i32 [ 3, %[[DEFAULT]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ], [ 2, %[[ENTRY]] ]
365+
; OPTNOLUT-NEXT: [[ENTRY:.*:]]
366+
; OPTNOLUT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 5
367+
; OPTNOLUT-NEXT: [[IDX:%.*]] = select i1 [[TMP0]], i32 2, i32 3
416368
; OPTNOLUT-NEXT: ret i32 [[IDX]]
417369
;
418370
; TTINOLUT-LABEL: define i32 @single_value_no_jump_tables(

0 commit comments

Comments
 (0)