Skip to content

Commit 3eefd16

Browse files
committed
Enable SimplifyCFG::simplifySwitchEnumBlock for OSSA
1 parent b841523 commit 3eefd16

File tree

3 files changed

+168
-18
lines changed

3 files changed

+168
-18
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,12 +2076,6 @@ bool SimplifyCFG::simplifySwitchEnumBlock(SwitchEnumInst *SEI) {
20762076
auto *LiveBlock = SEI->getCaseDestination(EnumCase.get());
20772077
auto *ThisBB = SEI->getParent();
20782078

2079-
if (!EnableOSSARewriteTerminator && Fn.hasOwnership()) {
2080-
// TODO: OSSA; cleanup terminator results.
2081-
if (!SEI->getOperand()->getType().isTrivial(Fn))
2082-
return false;
2083-
}
2084-
20852079
bool DroppedLiveBlock = false;
20862080
// Copy the successors into a vector, dropping one entry for the liveblock.
20872081
SmallVector<SILBasicBlock*, 4> Dests;
@@ -2096,29 +2090,27 @@ bool SimplifyCFG::simplifySwitchEnumBlock(SwitchEnumInst *SEI) {
20962090
LLVM_DEBUG(llvm::dbgs() << "fold switch " << *SEI);
20972091

20982092
auto *EI = dyn_cast<EnumInst>(SEI->getOperand());
2093+
auto loc = SEI->getLoc();
20992094
SILBuilderWithScope Builder(SEI);
21002095
if (!LiveBlock->args_empty()) {
21012096
SILValue PayLoad;
21022097
if (SEI->hasDefault() && LiveBlock == SEI->getDefaultBB()) {
21032098
assert(Fn.hasOwnership() && "Only OSSA default case has an argument");
21042099
PayLoad = SEI->getOperand();
21052100
} else {
2106-
if (EI) {
2107-
PayLoad = EI->getOperand();
2108-
} else {
2109-
PayLoad = Builder.createUncheckedEnumData(SEI->getLoc(),
2110-
SEI->getOperand(),
2111-
EnumCase.get());
2112-
}
2101+
PayLoad = Builder.createUncheckedEnumData(loc, SEI->getOperand(),
2102+
EnumCase.get());
21132103
}
2114-
Builder.createBranch(SEI->getLoc(), LiveBlock, PayLoad);
2104+
Builder.createBranch(loc, LiveBlock, PayLoad);
21152105
} else {
2116-
Builder.createBranch(SEI->getLoc(), LiveBlock);
2106+
Builder.createBranch(loc, LiveBlock);
21172107
}
2108+
21182109
SEI->eraseFromParent();
2119-
// TODO: also remove this EnumInst in OSSA default case when the only
2120-
// remaining uses are destroys, and incidental uses.
2121-
if (EI && EI->use_empty()) EI->eraseFromParent();
2110+
if (EI && isInstructionTriviallyDead(EI)) {
2111+
EI->replaceAllUsesOfAllResultsWithUndef();
2112+
EI->eraseFromParent();
2113+
}
21222114

21232115
addToWorklist(ThisBB);
21242116

lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,18 @@ struct SimplifyCFGCanonicalizeSwitchEnum : UnitTest {
282282
}
283283
};
284284

285+
struct SimplifyCFGSimplifySwitchEnumBlock : UnitTest {
286+
SimplifyCFGSimplifySwitchEnumBlock(UnitTestRunner *pass) : UnitTest(pass) {}
287+
void invoke(Arguments &arguments) override {
288+
auto *passToRun = cast<SILFunctionTransform>(createSimplifyCFG());
289+
passToRun->injectPassManager(getPass()->getPassManager());
290+
passToRun->injectFunction(getFunction());
291+
SimplifyCFG(*getFunction(), *passToRun, /*VerifyAll=*/false,
292+
/*EnableJumpThread=*/false)
293+
.simplifySwitchEnumBlock(
294+
cast<SwitchEnumInst>(arguments.takeInstruction()));
295+
}
296+
};
285297

286298
// Arguments:
287299
// - string: list of characters, each of which specifies subsequent arguments
@@ -404,6 +416,8 @@ void UnitTestRunner::withTest(StringRef name, Doit doit) {
404416
ADD_UNIT_TEST_SUBCLASS("pruned-liveness-boundary-with-list-of-last-users-insertion-points", PrunedLivenessBoundaryWithListOfLastUsersInsertionPointsTest)
405417
ADD_UNIT_TEST_SUBCLASS("shrink-borrow-scope", ShrinkBorrowScopeTest)
406418
ADD_UNIT_TEST_SUBCLASS("simplify-cfg-canonicalize-switch-enum", SimplifyCFGCanonicalizeSwitchEnum)
419+
ADD_UNIT_TEST_SUBCLASS("simplify-cfg-simplify-switch-enum-block",
420+
SimplifyCFGSimplifySwitchEnumBlock)
407421
ADD_UNIT_TEST_SUBCLASS("test-specification-parsing", TestSpecificationTest)
408422
ADD_UNIT_TEST_SUBCLASS("visit-adjacent-reborrows-of-phi", VisitAdjacentReborrowsOfPhiTest)
409423
/// [new_tests] Add the new mapping from string to subclass above this line.

test/SILOptimizer/simplify_cfg_ossa_switch_enum.sil

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,147 @@ bb3:
8282
return %t : $()
8383
}
8484

85+
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum1 :
86+
// CHECK-NOT: switch_enum
87+
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum1'
88+
sil [ossa] @test_simplify_switch_enum1 : $@convention(thin) (@owned Klass) -> () {
89+
bb0(%0 : @owned $Klass):
90+
test_specification "simplify-cfg-simplify-switch-enum-block @instruction[1]"
91+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
92+
switch_enum %1 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
93+
94+
bb2:
95+
br bb3
96+
97+
bb1(%3 : @owned $Klass):
98+
destroy_value %3 : $Klass
99+
br bb3
100+
101+
bb3:
102+
%t = tuple ()
103+
return %t : $()
104+
}
105+
106+
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum2 :
107+
// CHECK-NOT: switch_enum
108+
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum2'
109+
sil [ossa] @test_simplify_switch_enum2 : $@convention(thin) (@guaranteed Klass) -> () {
110+
bb0(%0 : @guaranteed $Klass):
111+
test_specification "simplify-cfg-simplify-switch-enum-block @instruction[1]"
112+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
113+
switch_enum %1 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
114+
115+
bb2:
116+
br bb3
117+
118+
bb1(%3 : @guaranteed $Klass):
119+
br bb3
120+
121+
bb3:
122+
%t = tuple ()
123+
return %t : $()
124+
}
125+
126+
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum3 :
127+
// CHECK-NOT: switch_enum
128+
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum3'
129+
sil [ossa] @test_simplify_switch_enum3 : $@convention(thin) (@owned Klass) -> () {
130+
bb0(%0 : @owned $Klass):
131+
test_specification "simplify-cfg-simplify-switch-enum-block @instruction[2]"
132+
%b = begin_borrow %0 : $Klass
133+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %b : $Klass
134+
switch_enum %1 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
135+
136+
bb2:
137+
br bb3
138+
139+
bb1(%3 : @guaranteed $Klass):
140+
br bb3
141+
142+
bb3:
143+
end_borrow %b : $Klass
144+
destroy_value %0 : $Klass
145+
%t = tuple ()
146+
return %t : $()
147+
}
148+
149+
sil @use_optional : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> ()
150+
151+
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum4 :
152+
// CHECK-NOT: switch_enum
153+
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum4'
154+
sil [ossa] @test_simplify_switch_enum4 : $@convention(thin) (@guaranteed Klass) -> () {
155+
bb0(%0 : @guaranteed $Klass):
156+
test_specification "simplify-cfg-simplify-switch-enum-block @instruction[3]"
157+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
158+
%f = function_ref @use_optional : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> ()
159+
%c = apply %f(%1) : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> ()
160+
switch_enum %1 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
161+
162+
bb2:
163+
br bb3
164+
165+
bb1(%3 : @guaranteed $Klass):
166+
br bb3
167+
168+
bb3:
169+
%t = tuple ()
170+
return %t : $()
171+
}
172+
173+
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum5 :
174+
// CHECK-NOT: switch_enum
175+
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum5'
176+
sil [ossa] @test_simplify_switch_enum5 : $@convention(thin) (@owned Klass) -> () {
177+
bb0(%0 : @owned $Klass):
178+
test_specification "simplify-cfg-simplify-switch-enum-block @instruction[4]"
179+
%b = begin_borrow %0 : $Klass
180+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %b : $Klass
181+
%f = function_ref @use_optional : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> ()
182+
%c = apply %f(%1) : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> ()
183+
switch_enum %1 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
184+
185+
bb2:
186+
br bb3
187+
188+
bb1(%3 : @guaranteed $Klass):
189+
br bb3
190+
191+
bb3:
192+
end_borrow %b : $Klass
193+
destroy_value %0 : $Klass
194+
%t = tuple ()
195+
return %t : $()
196+
}
197+
198+
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum6 :
199+
// CHECK-NOT: switch_enum
200+
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum6'
201+
sil [ossa] @test_simplify_switch_enum6 : $@convention(thin) (@owned Klass) -> () {
202+
bb0(%0 : @owned $Klass):
203+
cond_br undef, bb1, bb2
204+
205+
bb1:
206+
%2 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
207+
br bb3(%2 : $FakeOptional<Klass>)
208+
209+
bb2:
210+
%4 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
211+
br bb3(%4 : $FakeOptional<Klass>)
212+
213+
bb3(%6 :@owned $FakeOptional<Klass>):
214+
test_specification "simplify-cfg-simplify-switch-enum-block @instruction[7]"
215+
switch_enum %6 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb4, case #FakeOptional.none!enumelt: bb5
216+
217+
bb4(%8 : @owned $Klass):
218+
destroy_value %8 : $Klass
219+
br bb6
220+
221+
bb5:
222+
br bb6
223+
224+
bb6:
225+
%t = tuple ()
226+
return %t : $()
227+
}
228+

0 commit comments

Comments
 (0)