Skip to content

Commit fa365c6

Browse files
authored
Merge pull request #18947 from rjmccall/coroutine-optimizer-fixes
More SIL optimizer fixes for coroutines.
2 parents 6adac7a + 348fda2 commit fa365c6

File tree

8 files changed

+77
-25
lines changed

8 files changed

+77
-25
lines changed

lib/SIL/SILVerifier.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4309,16 +4309,22 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
43094309
void verifyEpilogBlocks(SILFunction *F) {
43104310
bool FoundReturnBlock = false;
43114311
bool FoundThrowBlock = false;
4312+
bool FoundUnwindBlock = false;
43124313
for (auto &BB : *F) {
43134314
if (isa<ReturnInst>(BB.getTerminator())) {
43144315
require(!FoundReturnBlock,
43154316
"more than one return block in function");
43164317
FoundReturnBlock = true;
4317-
}
4318-
if (isa<ThrowInst>(BB.getTerminator())) {
4318+
} else if (isa<ThrowInst>(BB.getTerminator())) {
43194319
require(!FoundThrowBlock,
43204320
"more than one throw block in function");
43214321
FoundThrowBlock = true;
4322+
} else if (isa<UnwindInst>(BB.getTerminator())) {
4323+
require(!FoundUnwindBlock,
4324+
"more than one unwind block in function");
4325+
FoundUnwindBlock = true;
4326+
} else {
4327+
assert(!BB.getTerminator()->isFunctionExiting());
43224328
}
43234329
}
43244330
}

lib/SILOptimizer/Analysis/CFG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ findAllNonFailureExitBBs(SILFunction *F,
7272
continue;
7373

7474
// A return inst is always a non-failure exit bb.
75-
if (isa<ReturnInst>(TI) || isa<ThrowInst>(TI)) {
75+
if (TI->isFunctionExiting()) {
7676
BBs.push_back(&BB);
7777
continue;
7878
}

lib/SILOptimizer/IPO/ClosureSpecializer.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -787,18 +787,9 @@ void ClosureSpecCloner::populateCloned() {
787787
TermInst *TI = OpBB->getTerminator();
788788
auto Loc = CleanupLocation::get(NewClosure->getLoc());
789789

790-
// If we have a return/throw, we place the release right before it so we know
790+
// If we have an exit, we place the release right before it so we know
791791
// that it will be executed at the end of the epilogue.
792-
if (isa<ReturnInst>(TI)) {
793-
Builder.setInsertionPoint(TI);
794-
if (ClosureHasRefSemantics)
795-
Builder.createReleaseValue(Loc, SILValue(NewClosure),
796-
Builder.getDefaultAtomicity());
797-
for (auto PAI : NeedsRelease)
798-
Builder.createReleaseValue(Loc, SILValue(PAI),
799-
Builder.getDefaultAtomicity());
800-
continue;
801-
} else if (isa<ThrowInst>(TI)) {
792+
if (TI->isFunctionExiting()) {
802793
Builder.setInsertionPoint(TI);
803794
if (ClosureHasRefSemantics)
804795
Builder.createReleaseValue(Loc, SILValue(NewClosure),

lib/SILOptimizer/Transforms/ARCCodeMotion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ class RetainCodeMotionContext : public CodeMotionContext {
306306
// end, this function is called many times.
307307
//
308308
// These terminator instructions block.
309-
if (isa<ReturnInst>(II) || isa<ThrowInst>(II) || isa<UnreachableInst>(II))
309+
if (isa<ReturnInst>(II) || isa<ThrowInst>(II) || isa<UnwindInst>(II) ||
310+
isa<UnreachableInst>(II))
310311
return true;
311312
// Identical RC root blocks code motion, we will be able to move this retain
312313
// further once we move the blocking retain.

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,11 @@ static SILValue getTerminatorCondition(TermInst *Term) {
262262
/// Is this basic block jump threadable.
263263
static bool isThreadableBlock(SILBasicBlock *BB,
264264
SmallPtrSetImpl<SILBasicBlock *> &LoopHeaders) {
265-
if (isa<ReturnInst>(BB->getTerminator()))
266-
return false;
265+
auto TI = BB->getTerminator();
267266

268-
// We know how to handle cond_br and switch_enum .
269-
if (!isa<CondBranchInst>(BB->getTerminator()) &&
270-
!isa<SwitchEnumInst>(BB->getTerminator()))
267+
// We know how to handle cond_br and switch_enum.
268+
if (!isa<CondBranchInst>(TI) &&
269+
!isa<SwitchEnumInst>(TI))
271270
return false;
272271

273272
if (LoopHeaders.count(BB))
@@ -279,7 +278,7 @@ static bool isThreadableBlock(SILBasicBlock *BB,
279278
return false;
280279

281280
// Don't jumpthread function calls.
282-
if (isa<ApplyInst>(Inst))
281+
if (FullApplySite::isa(&Inst))
283282
return false;
284283

285284
// Only thread 'small blocks'.
@@ -975,7 +974,7 @@ bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
975974
auto *SrcBB = BI->getParent();
976975
// If the destination block ends with a return, we don't want to duplicate it.
977976
// We want to maintain the canonical form of a single return where possible.
978-
if (isa<ReturnInst>(DestBB->getTerminator()))
977+
if (DestBB->getTerminator()->isFunctionExiting())
979978
return false;
980979

981980
// We need to update SSA if a value duplicated is used outside of the
@@ -2398,7 +2397,7 @@ static bool shouldTailDuplicate(SILBasicBlock &Block) {
23982397
unsigned Cost = 0;
23992398
bool SawRelease = false;
24002399

2401-
if (isa<ReturnInst>(Block.getTerminator()))
2400+
if (Block.getTerminator()->isFunctionExiting())
24022401
return false;
24032402

24042403
if (Block.getSinglePredecessorBlock())

lib/SILOptimizer/Utils/GenericCloner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ void GenericCloner::populateCloned() {
159159
getBuilder().createReturn(RI->getLoc(), ReturnValue);
160160
continue;
161161
}
162-
} else if (isa<ThrowInst>(OrigTermInst)) {
162+
} else if (OrigTermInst->isFunctionExiting()) {
163163
for (AllocStackInst *ASI : reverse(AllocStacks)) {
164164
getBuilder().createDeallocStack(ASI->getLoc(), ASI);
165165
}

test/SIL/Parser/coroutines.sil

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ bb2:
4343
return %r : $()
4444

4545
bb3:
46-
unwind
46+
br bb5
4747

4848
bb4:
49+
br bb5
50+
51+
bb5:
4952
unwind
5053
}
5154

test/SILOptimizer/specialize_reabstraction.sil

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,55 @@ bb0(%0 : $Val<Bool>, %1 : $Val<Int>):
7979
%8 = apply %7(%1) : $@callee_owned (Val<Int>) -> Val<(Bool, Int)>
8080
return %8 : $Val<(Bool, Int)>
8181
}
82+
83+
// CHECK-LABEL: sil shared @$S9coroutineSb_Tg5 : $@yield_once @convention(thin) (Bool) -> @yields @inout Bool {
84+
// CHECK: bb0(%0 : $Bool):
85+
// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Bool
86+
// CHECK-NEXT: store %0 to [[TEMP]] : $*Bool
87+
// CHECK-NEXT: yield [[TEMP]] : $*Bool, resume bb1, unwind bb2
88+
// CHECK: bb1:
89+
// CHECK-NEXT: destroy_addr [[TEMP]] : $*Bool
90+
// CHECK-NEXT: [[RV:%.*]] = tuple ()
91+
// CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool
92+
// CHECK-NEXT: return [[RV]] : $()
93+
// CHECK: bb2:
94+
// CHECK-NEXT: destroy_addr [[TEMP]] : $*Bool
95+
// CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool
96+
// CHECK-NEXT: unwind
97+
// CHECK-NEXT: }
98+
sil @coroutine : $@yield_once @convention(thin) <T> (@in T) -> @yields @inout T {
99+
bb0(%0 : $*T):
100+
yield %0 : $*T, resume bb1, unwind bb2
101+
bb1:
102+
destroy_addr %0 : $*T
103+
%rv = tuple ()
104+
return %rv : $()
105+
bb2:
106+
destroy_addr %0 : $*T
107+
unwind
108+
}
109+
110+
// CHECK-LABEL: @test_coroutine : $@convention(thin) (Bool) -> () {
111+
// CHECK: bb0(%0 : $Bool):
112+
// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Bool
113+
// CHECK-NEXT: store %0 to [[TEMP]] : $*Bool
114+
// CHECK-NEXT: // function_ref
115+
// CHECK-NEXT: [[CORO:%.*]] = function_ref @$S9coroutineSb_Tg5 : $@yield_once @convention(thin) (Bool) -> @yields @inout Bool
116+
// CHECK-NEXT: [[LOAD:%.*]] = load [[TEMP]] : $*Bool
117+
// CHECK-NEXT: ([[ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[CORO]]([[LOAD]])
118+
// CHECK-NEXT: end_apply [[TOKEN]]
119+
// CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool
120+
// CHECK-NEXT: [[RV:%.*]] = tuple ()
121+
// CHECK-NEXT: return [[RV]] : $()
122+
// CHECK-NEXT: }
123+
sil @test_coroutine : $@convention(thin) (Bool) -> () {
124+
bb0(%0 : $Bool):
125+
%coro = function_ref @coroutine : $@yield_once @convention(thin) <T> (@in T) -> @yields @inout T
126+
%temp = alloc_stack $Bool
127+
store %0 to %temp : $*Bool
128+
(%addr, %token) = begin_apply %coro<Bool>(%temp) : $@yield_once @convention(thin) <T> (@in T) -> @yields @inout T
129+
end_apply %token
130+
dealloc_stack %temp : $*Bool
131+
%rv = tuple ()
132+
return %rv : $()
133+
}

0 commit comments

Comments
 (0)