Optimizer: make ModulePassContext.specialize() also available in FunctionPassContext and add two argument flags

add `convertIndirectToDirect` and `isMandatory`
This commit is contained in:
Erik Eckstein
2025-09-03 09:36:07 +02:00
parent b8a49692eb
commit 45b1a21e74
6 changed files with 37 additions and 15 deletions

View File

@@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
import AST
import SIL import SIL
import OptimizerBridging import OptimizerBridging
@@ -97,6 +98,15 @@ struct FunctionPassContext : MutatingContext {
return false return false
} }
func specialize(function: Function,
for substitutions: SubstitutionMap,
convertIndirectToDirect: Bool,
isMandatory: Bool
) -> Function? {
return bridgedPassContext.specializeFunction(function.bridged, substitutions.bridged,
convertIndirectToDirect, isMandatory).function
}
func mangleOutlinedVariable(from function: Function) -> String { func mangleOutlinedVariable(from function: Function) -> String {
return String(taking: bridgedPassContext.mangleOutlinedVariable(function.bridged)) return String(taking: bridgedPassContext.mangleOutlinedVariable(function.bridged))
} }

View File

@@ -131,8 +131,13 @@ struct ModulePassContext : Context, CustomStringConvertible {
return function.isDefinition return function.isDefinition
} }
func specialize(function: Function, for substitutions: SubstitutionMap) -> Function? { func specialize(function: Function,
return bridgedPassContext.specializeFunction(function.bridged, substitutions.bridged).function for substitutions: SubstitutionMap,
convertIndirectToDirect: Bool,
isMandatory: Bool
) -> Function? {
return bridgedPassContext.specializeFunction(function.bridged, substitutions.bridged,
convertIndirectToDirect, isMandatory).function
} }
enum DeserializationMode { enum DeserializationMode {

View File

@@ -89,8 +89,9 @@ private struct VTableSpecializer {
guard !methodSubs.conformances.contains(where: {!$0.isValid}), guard !methodSubs.conformances.contains(where: {!$0.isValid}),
context.loadFunction(function: entry.implementation, loadCalleesRecursively: true), context.loadFunction(function: entry.implementation, loadCalleesRecursively: true),
let specializedMethod = context.specialize(function: entry.implementation, for: methodSubs) else let specializedMethod = context.specialize(function: entry.implementation, for: methodSubs,
{ convertIndirectToDirect: true, isMandatory: true)
else {
return entry return entry
} }
notifyNewFunction(specializedMethod) notifyNewFunction(specializedMethod)
@@ -146,8 +147,9 @@ func specializeWitnessTable(for conformance: Conformance, _ context: ModulePassC
guard !methodSubs.conformances.contains(where: {!$0.isValid}), guard !methodSubs.conformances.contains(where: {!$0.isValid}),
context.loadFunction(function: origMethod, loadCalleesRecursively: true), context.loadFunction(function: origMethod, loadCalleesRecursively: true),
let specializedMethod = context.specialize(function: origMethod, for: methodSubs) else let specializedMethod = context.specialize(function: origMethod, for: methodSubs,
{ convertIndirectToDirect: true, isMandatory: true)
else {
return origEntry return origEntry
} }
return .method(requirement: requirement, witness: specializedMethod) return .method(requirement: requirement, witness: specializedMethod)
@@ -212,8 +214,9 @@ private func specializeDefaultMethods(for conformance: Conformance,
guard !methodSubs.conformances.contains(where: {!$0.isValid}), guard !methodSubs.conformances.contains(where: {!$0.isValid}),
context.loadFunction(function: origMethod, loadCalleesRecursively: true), context.loadFunction(function: origMethod, loadCalleesRecursively: true),
let specializedMethod = context.specialize(function: origMethod, for: methodSubs) else let specializedMethod = context.specialize(function: origMethod, for: methodSubs,
{ convertIndirectToDirect: true, isMandatory: true)
else {
return origEntry return origEntry
} }
specialized = true specialized = true

View File

@@ -178,7 +178,9 @@ struct BridgedPassContext {
bool tryOptimizeKeypath(BridgedInstruction apply) const; bool tryOptimizeKeypath(BridgedInstruction apply) const;
SWIFT_IMPORT_UNSAFE OptionalBridgedValue constantFoldBuiltin(BridgedInstruction builtin) const; SWIFT_IMPORT_UNSAFE OptionalBridgedValue constantFoldBuiltin(BridgedInstruction builtin) const;
SWIFT_IMPORT_UNSAFE OptionalBridgedFunction specializeFunction(BridgedFunction function, SWIFT_IMPORT_UNSAFE OptionalBridgedFunction specializeFunction(BridgedFunction function,
BridgedSubstitutionMap substitutions) const; BridgedSubstitutionMap substitutions,
bool convertIndirectToDirect,
bool isMandatory) const;
void deserializeAllCallees(BridgedFunction function, bool deserializeAll) const; void deserializeAllCallees(BridgedFunction function, bool deserializeAll) const;
bool specializeClassMethodInst(BridgedInstruction cm) const; bool specializeClassMethodInst(BridgedInstruction cm) const;
bool specializeWitnessMethodInst(BridgedInstruction wm) const; bool specializeWitnessMethodInst(BridgedInstruction wm) const;

View File

@@ -173,13 +173,15 @@ bool BridgedPassContext::canMakeStaticObjectReadOnly(BridgedType type) const {
} }
OptionalBridgedFunction BridgedPassContext::specializeFunction(BridgedFunction function, OptionalBridgedFunction BridgedPassContext::specializeFunction(BridgedFunction function,
BridgedSubstitutionMap substitutions) const { BridgedSubstitutionMap substitutions,
bool convertIndirectToDirect,
bool isMandatory) const {
swift::SILModule *mod = invocation->getPassManager()->getModule(); swift::SILModule *mod = invocation->getPassManager()->getModule();
SILFunction *origFunc = function.getFunction(); SILFunction *origFunc = function.getFunction();
SubstitutionMap subs = substitutions.unbridged(); SubstitutionMap subs = substitutions.unbridged();
ReabstractionInfo ReInfo(mod->getSwiftModule(), mod->isWholeModule(), ReabstractionInfo ReInfo(mod->getSwiftModule(), mod->isWholeModule(),
ApplySite(), origFunc, subs, IsNotSerialized, ApplySite(), origFunc, subs, origFunc->getSerializedKind(),
/*ConvertIndirectToDirect=*/true, convertIndirectToDirect,
/*dropUnusedArguments=*/false); /*dropUnusedArguments=*/false);
if (!ReInfo.canBeSpecialized()) { if (!ReInfo.canBeSpecialized()) {
@@ -188,8 +190,8 @@ OptionalBridgedFunction BridgedPassContext::specializeFunction(BridgedFunction f
SILOptFunctionBuilder FunctionBuilder(*invocation->getTransform()); SILOptFunctionBuilder FunctionBuilder(*invocation->getTransform());
GenericFuncSpecializer FuncSpecializer(FunctionBuilder, origFunc, subs, GenericFuncSpecializer FuncSpecializer(FunctionBuilder, origFunc, ReInfo.getClonerParamSubstitutionMap(),
ReInfo, /*isMandatory=*/true); ReInfo, isMandatory);
SILFunction *SpecializedF = FuncSpecializer.lookupSpecialization(); SILFunction *SpecializedF = FuncSpecializer.lookupSpecialization();
if (!SpecializedF) SpecializedF = FuncSpecializer.tryCreateSpecialization(); if (!SpecializedF) SpecializedF = FuncSpecializer.tryCreateSpecialization();
if (!SpecializedF || SpecializedF->getLoweredFunctionType()->hasError()) { if (!SpecializedF || SpecializedF->getLoweredFunctionType()->hasError()) {

View File

@@ -4,7 +4,7 @@
// REQUIRES: swift_feature_Embedded // REQUIRES: swift_feature_Embedded
// CHECK: @"$e4main8MyBufferCN" = {{.*global.*}} <{ ptr @"$es13ManagedBufferCySis5UInt8VGN", ptr @"$e4main8MyBufferCfD{{[^"]*}}", ptr null, ptr @"$e4main8MyBufferC12_doNotCallMeACyt_tcfC{{[^"]*}}" }> // CHECK: @"$e4main8MyBufferCN" = {{.*global.*}} <{ ptr @"$es13ManagedBufferCySis5UInt8VGN", ptr @"$e4main8MyBufferCfD{{[^"]*}}", ptr null, ptr @"$e4main8MyBufferC12_doNotCallMeACyt_tcfC{{[^"]*}}" }>
// CHECK: @"$es13ManagedBufferCySis5UInt8VGN" = {{.*global.*}} <{ ptr null, ptr @"$es13ManagedBufferCfDSi_s5UInt8VTg5{{[^"]*}}", ptr null, ptr @"$es13ManagedBufferC12_doNotCallMeAByxq_Gyt_tcfCSi_s5UInt8VTg5{{[^"]*}}" }> // CHECK: @"$es13ManagedBufferCySis5UInt8VGN" = {{.*global.*}} <{ ptr null, ptr @"$es13ManagedBufferCfDSi_s5UInt8VTgq5{{[^"]*}}", ptr null, ptr @"$es13ManagedBufferC12_doNotCallMeAByxq_Gyt_tcfCSi_s5UInt8VTgq5{{[^"]*}}" }>
final public class MyBuffer: ManagedBuffer<Int, UInt8> { final public class MyBuffer: ManagedBuffer<Int, UInt8> {
} }