Skip to content

Commit e86dc2c

Browse files
committed
Enable jump threading
1 parent f93a9d1 commit e86dc2c

File tree

3 files changed

+83
-10
lines changed

3 files changed

+83
-10
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -906,24 +906,20 @@ static bool hasInjectedEnumAtEndOfBlock(SILBasicBlock *block, SILValue enumAddr)
906906
/// tryJumpThreading - Check to see if it looks profitable to duplicate the
907907
/// destination of an unconditional jump into the bottom of this block.
908908
bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
909-
if (!EnableOSSASimplifyCFG && Fn.hasOwnership())
910-
return false;
911-
912909
auto *DestBB = BI->getDestBB();
913910
auto *SrcBB = BI->getParent();
914911
TermInst *destTerminator = DestBB->getTerminator();
915-
if (!EnableOSSARewriteTerminator && Fn.hasOwnership()) {
916-
if (llvm::any_of(DestBB->getArguments(), [this](SILValue op) {
917-
return !op->getType().isTrivial(Fn);
918-
})) {
919-
return false;
920-
}
921-
}
912+
922913
// If the destination block ends with a return, we don't want to duplicate it.
923914
// We want to maintain the canonical form of a single return where possible.
924915
if (destTerminator->isFunctionExiting())
925916
return false;
926917

918+
// There is no benefit duplicating such a destination.
919+
if (DestBB->getSinglePredecessorBlock() != nullptr) {
920+
return false;
921+
}
922+
927923
// Jump threading only makes sense if there is an argument on the branch
928924
// (which is reacted on in the DestBB), or if this goes through a memory
929925
// location (switch_enum_addr is the only address-instruction which we
@@ -942,6 +938,7 @@ bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
942938
for (unsigned i : indices(BI->getArgs())) {
943939
SILValue Arg = BI->getArg(i);
944940

941+
// TODO: Verify if we need to jump thread to remove releases in OSSA.
945942
// If the value being substituted on is release there is a chance we could
946943
// remove the release after jump threading.
947944
if (!Arg->getType().isTrivial(*SrcBB->getParent()) &&

lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,19 @@ struct SimplifyCFGSimplifyTermWithIdenticalDestBlocks : UnitTest {
361361
}
362362
};
363363

364+
struct SimplifyCFGTryJumpThreading : UnitTest {
365+
SimplifyCFGTryJumpThreading(UnitTestRunner *pass)
366+
: UnitTest(pass) {}
367+
void invoke(Arguments &arguments) override {
368+
auto *passToRun = cast<SILFunctionTransform>(createSimplifyCFG());
369+
passToRun->injectPassManager(getPass()->getPassManager());
370+
passToRun->injectFunction(getFunction());
371+
SimplifyCFG(*getFunction(), *passToRun, /*VerifyAll=*/false,
372+
/*EnableJumpThread=*/false)
373+
.tryJumpThreading(cast<BranchInst>(arguments.takeInstruction()));
374+
}
375+
};
376+
364377
// Arguments:
365378
// - string: list of characters, each of which specifies subsequent arguments
366379
// - A: (block) argument
@@ -500,6 +513,9 @@ void UnitTestRunner::withTest(StringRef name, Doit doit) {
500513
ADD_UNIT_TEST_SUBCLASS(
501514
"simplify-cfg-simplify-term-with-identical-dest-blocks",
502515
SimplifyCFGSimplifyTermWithIdenticalDestBlocks)
516+
ADD_UNIT_TEST_SUBCLASS(
517+
"simplify-cfg-try-jump-threading",
518+
SimplifyCFGTryJumpThreading)
503519

504520
ADD_UNIT_TEST_SUBCLASS("test-specification-parsing", TestSpecificationTest)
505521
ADD_UNIT_TEST_SUBCLASS("visit-adjacent-reborrows-of-phi", VisitAdjacentReborrowsOfPhiTest)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
class Klass {
3+
}
4+
5+
enum FakeOptional<T> {
6+
case some(T)
7+
case none
8+
}
9+
10+
sil [ossa] @test_simplify_switch_enum_jump_threading1 : $@convention(thin) (@owned Klass) -> () {
11+
bb0(%0 : @owned $Klass):
12+
test_specification "simplify-cfg-try-jump-threading @instruction[1]"
13+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
14+
br bb1(%1 : $FakeOptional<Klass>)
15+
16+
bb1(%3 : @owned $FakeOptional<Klass>):
17+
switch_enum %3 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb3, case #FakeOptional.none!enumelt: bb2
18+
19+
bb2:
20+
br bb4
21+
22+
bb3(%6 : @owned $Klass):
23+
destroy_value %6 : $Klass
24+
br bb4
25+
26+
bb4:
27+
%t = tuple ()
28+
return %t : $()
29+
}
30+
31+
32+
sil [ossa] @test_simplify_switch_enum_jump_threading2 : $@convention(thin) (@owned Klass) -> () {
33+
bb0(%0 : @owned $Klass):
34+
cond_br undef, bb1, bb2
35+
36+
bb1:
37+
test_specification "simplify-cfg-try-jump-threading @instruction[2]"
38+
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
39+
br bb3(%1 : $FakeOptional<Klass>)
40+
41+
bb2:
42+
test_specification "simplify-cfg-try-jump-threading @instruction[5]"
43+
destroy_value %0 : $Klass
44+
%2 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
45+
br bb3(%2 : $FakeOptional<Klass>)
46+
47+
bb3(%3 : @owned $FakeOptional<Klass>):
48+
switch_enum %3 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb5, case #FakeOptional.none!enumelt: bb4
49+
50+
bb4:
51+
br bb6
52+
53+
bb5(%6 : @owned $Klass):
54+
destroy_value %6 : $Klass
55+
br bb6
56+
57+
bb6:
58+
%t = tuple ()
59+
return %t : $()
60+
}

0 commit comments

Comments
 (0)