Skip to content

Commit e465a10

Browse files
committed
Mandatory Inlining: Turn skipFuncConvert() lambda into a top-level stripFunctionConversions() function
1 parent 36c821c commit e465a10

File tree

1 file changed

+74
-73
lines changed

1 file changed

+74
-73
lines changed

lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

Lines changed: 74 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,78 @@ static SILValue getLoadedCalleeValue(LoadInst *li) {
610610
return si->getSrc();
611611
}
612612

613+
// PartialApply/ThinToThick -> ConvertFunction patterns are generated
614+
// by @noescape closures.
615+
//
616+
// FIXME: We don't currently handle mismatched return types, however, this
617+
// would be a good optimization to handle and would be as simple as inserting
618+
// a cast.
619+
static SILValue stripFunctionConversions(SILValue CalleeValue) {
620+
// Skip any copies that we see.
621+
CalleeValue = stripCopiesAndBorrows(CalleeValue);
622+
623+
// We can also allow a thin @escape to noescape conversion as such:
624+
// %1 = function_ref @thin_closure_impl : $@convention(thin) () -> ()
625+
// %2 = convert_function %1 :
626+
// $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
627+
// %3 = thin_to_thick_function %2 :
628+
// $@convention(thin) @noescape () -> () to
629+
// $@noescape @callee_guaranteed () -> ()
630+
// %4 = apply %3() : $@noescape @callee_guaranteed () -> ()
631+
if (auto *ConvertFn = dyn_cast<ConvertFunctionInst>(CalleeValue)) {
632+
// If the conversion only changes the substitution level of the function,
633+
// we can also look through it.
634+
if (ConvertFn->onlyConvertsSubstitutions())
635+
return stripCopiesAndBorrows(ConvertFn->getOperand());
636+
637+
auto FromCalleeTy =
638+
ConvertFn->getOperand()->getType().castTo<SILFunctionType>();
639+
if (FromCalleeTy->getExtInfo().hasContext())
640+
return CalleeValue;
641+
642+
auto ToCalleeTy = ConvertFn->getType().castTo<SILFunctionType>();
643+
auto EscapingCalleeTy = ToCalleeTy->getWithExtInfo(
644+
ToCalleeTy->getExtInfo().withNoEscape(false));
645+
if (FromCalleeTy != EscapingCalleeTy)
646+
return CalleeValue;
647+
648+
return stripCopiesAndBorrows(ConvertFn->getOperand());
649+
}
650+
651+
// Ignore mark_dependence users. A partial_apply [stack] uses them to mark
652+
// the dependence of the trivial closure context value on the captured
653+
// arguments.
654+
if (auto *MD = dyn_cast<MarkDependenceInst>(CalleeValue)) {
655+
while (MD) {
656+
CalleeValue = MD->getValue();
657+
MD = dyn_cast<MarkDependenceInst>(CalleeValue);
658+
}
659+
return CalleeValue;
660+
}
661+
662+
auto *CFI = dyn_cast<ConvertEscapeToNoEscapeInst>(CalleeValue);
663+
if (!CFI)
664+
return stripCopiesAndBorrows(CalleeValue);
665+
666+
// TODO: Handle argument conversion. All the code in this file needs to be
667+
// cleaned up and generalized. The argument conversion handling in
668+
// optimizeApplyOfConvertFunctionInst should apply to any combine
669+
// involving an apply, not just a specific pattern.
670+
//
671+
// For now, just handle conversion that doesn't affect argument types,
672+
// return types, or throws. We could trivially handle any other
673+
// representation change, but the only one that doesn't affect the ABI and
674+
// matters here is @noescape, so just check for that.
675+
auto FromCalleeTy = CFI->getOperand()->getType().castTo<SILFunctionType>();
676+
auto ToCalleeTy = CFI->getType().castTo<SILFunctionType>();
677+
auto EscapingCalleeTy =
678+
ToCalleeTy->getWithExtInfo(ToCalleeTy->getExtInfo().withNoEscape(false));
679+
if (FromCalleeTy != EscapingCalleeTy)
680+
return stripCopiesAndBorrows(CalleeValue);
681+
682+
return stripCopiesAndBorrows(CFI->getOperand());
683+
}
684+
613685
/// Returns the callee SILFunction called at a call site, in the case
614686
/// that the call is transparent (as in, both that the call is marked
615687
/// with the transparent flag and that callee function is actually transparently
@@ -646,79 +718,8 @@ getCalleeFunction(SILFunction *F, FullApplySite AI, bool &IsThick,
646718
CalleeValue = stripCopiesAndBorrows(CalleeValue);
647719
}
648720

649-
// PartialApply/ThinToThick -> ConvertFunction patterns are generated
650-
// by @noescape closures.
651-
//
652-
// FIXME: We don't currently handle mismatched return types, however, this
653-
// would be a good optimization to handle and would be as simple as inserting
654-
// a cast.
655-
auto skipFuncConvert = [](SILValue CalleeValue) {
656-
// Skip any copies that we see.
657-
CalleeValue = stripCopiesAndBorrows(CalleeValue);
658-
659-
// We can also allow a thin @escape to noescape conversion as such:
660-
// %1 = function_ref @thin_closure_impl : $@convention(thin) () -> ()
661-
// %2 = convert_function %1 :
662-
// $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
663-
// %3 = thin_to_thick_function %2 :
664-
// $@convention(thin) @noescape () -> () to
665-
// $@noescape @callee_guaranteed () -> ()
666-
// %4 = apply %3() : $@noescape @callee_guaranteed () -> ()
667-
if (auto *ConvertFn = dyn_cast<ConvertFunctionInst>(CalleeValue)) {
668-
// If the conversion only changes the substitution level of the function,
669-
// we can also look through it.
670-
if (ConvertFn->onlyConvertsSubstitutions()) {
671-
return stripCopiesAndBorrows(ConvertFn->getOperand());
672-
}
673-
674-
auto FromCalleeTy =
675-
ConvertFn->getOperand()->getType().castTo<SILFunctionType>();
676-
if (FromCalleeTy->getExtInfo().hasContext())
677-
return CalleeValue;
678-
auto ToCalleeTy = ConvertFn->getType().castTo<SILFunctionType>();
679-
auto EscapingCalleeTy = ToCalleeTy->getWithExtInfo(
680-
ToCalleeTy->getExtInfo().withNoEscape(false));
681-
if (FromCalleeTy != EscapingCalleeTy)
682-
return CalleeValue;
683-
return stripCopiesAndBorrows(ConvertFn->getOperand());
684-
}
685-
686-
// Ignore mark_dependence users. A partial_apply [stack] uses them to mark
687-
// the dependence of the trivial closure context value on the captured
688-
// arguments.
689-
if (auto *MD = dyn_cast<MarkDependenceInst>(CalleeValue)) {
690-
while (MD) {
691-
CalleeValue = MD->getValue();
692-
MD = dyn_cast<MarkDependenceInst>(CalleeValue);
693-
}
694-
return CalleeValue;
695-
}
696-
697-
auto *CFI = dyn_cast<ConvertEscapeToNoEscapeInst>(CalleeValue);
698-
if (!CFI)
699-
return stripCopiesAndBorrows(CalleeValue);
700-
701-
// TODO: Handle argument conversion. All the code in this file needs to be
702-
// cleaned up and generalized. The argument conversion handling in
703-
// optimizeApplyOfConvertFunctionInst should apply to any combine
704-
// involving an apply, not just a specific pattern.
705-
//
706-
// For now, just handle conversion that doesn't affect argument types,
707-
// return types, or throws. We could trivially handle any other
708-
// representation change, but the only one that doesn't affect the ABI and
709-
// matters here is @noescape, so just check for that.
710-
auto FromCalleeTy = CFI->getOperand()->getType().castTo<SILFunctionType>();
711-
auto ToCalleeTy = CFI->getType().castTo<SILFunctionType>();
712-
auto EscapingCalleeTy =
713-
ToCalleeTy->getWithExtInfo(ToCalleeTy->getExtInfo().withNoEscape(false));
714-
if (FromCalleeTy != EscapingCalleeTy)
715-
return stripCopiesAndBorrows(CalleeValue);
716-
717-
return stripCopiesAndBorrows(CFI->getOperand());
718-
};
719-
720721
// Look through a escape to @noescape conversion.
721-
CalleeValue = skipFuncConvert(CalleeValue);
722+
CalleeValue = stripFunctionConversions(CalleeValue);
722723

723724
// We are allowed to see through exactly one "partial apply" instruction or
724725
// one "thin to thick function" instructions, since those are the patterns
@@ -735,7 +736,7 @@ getCalleeFunction(SILFunction *F, FullApplySite AI, bool &IsThick,
735736
IsThick = true;
736737
}
737738

738-
CalleeValue = skipFuncConvert(CalleeValue);
739+
CalleeValue = stripFunctionConversions(CalleeValue);
739740

740741
auto *FRI = dyn_cast<FunctionRefInst>(CalleeValue);
741742
if (!FRI)

0 commit comments

Comments
 (0)