Skip to content

Commit 16f4fbe

Browse files
committed
MandatoryGenericSpecializer: always inline co-routines
Co-routines (called by `begin_apply`) may allocate and therefore it’s important to always inline them. Also, refactor the code a bit to fix the if-changed-then-return-true logic. rdar://94833845
1 parent 374691b commit 16f4fbe

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

lib/SILOptimizer/Transforms/GenericSpecializer.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -295,27 +295,38 @@ bool MandatoryGenericSpecializer::
295295
optimizeInst(SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
296296
InstructionDeleter &deleter, ClassHierarchyAnalysis *cha) {
297297
if (auto as = ApplySite::isa(inst)) {
298+
299+
bool changed = false;
300+
298301
// Specialization opens opportunities to devirtualize method calls.
299-
ApplySite newAS = tryDevirtualizeApply(as, cha).first;
300-
if (!newAS)
301-
return false;
302-
deleter.forceDelete(as.getInstruction());
303-
auto newFAS = FullApplySite::isa(newAS.getInstruction());
304-
if (!newFAS)
305-
return true;
302+
if (ApplySite newAS = tryDevirtualizeApply(as, cha).first) {
303+
deleter.forceDelete(as.getInstruction());
304+
changed = true;
305+
as = newAS;
306+
}
307+
308+
auto fas = FullApplySite::isa(as.getInstruction());
309+
if (!fas)
310+
return changed;
311+
312+
SILFunction *callee = fas.getReferencedFunctionOrNull();
313+
if (!callee)
314+
return changed;
306315

307-
SILFunction *callee = newFAS.getReferencedFunctionOrNull();
308-
if (!callee || callee->isTransparent() == IsNotTransparent)
309-
return true;
316+
if (callee->isTransparent() == IsNotTransparent &&
317+
// Force inlining of co-routines, because co-routines may allocate
318+
// memory.
319+
!isa<BeginApplyInst>(fas.getInstruction()))
320+
return changed;
310321

311322
if (callee->isExternalDeclaration())
312323
getModule()->loadFunction(callee, SILModule::LinkingMode::LinkAll);
313324

314325
if (callee->isExternalDeclaration())
315-
return true;
326+
return changed;
316327

317328
// If the de-virtualized callee is a transparent function, inline it.
318-
SILInliner::inlineFullApply(newFAS, SILInliner::InlineKind::MandatoryInline,
329+
SILInliner::inlineFullApply(fas, SILInliner::InlineKind::MandatoryInline,
319330
funcBuilder, deleter);
320331
return true;
321332
}

0 commit comments

Comments
 (0)