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 OptimizerBridging
@@ -97,6 +98,15 @@ struct FunctionPassContext : MutatingContext {
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 {
return String(taking: bridgedPassContext.mangleOutlinedVariable(function.bridged))
}

View File

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

View File

@@ -89,8 +89,9 @@ private struct VTableSpecializer {
guard !methodSubs.conformances.contains(where: {!$0.isValid}),
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
}
notifyNewFunction(specializedMethod)
@@ -146,8 +147,9 @@ func specializeWitnessTable(for conformance: Conformance, _ context: ModulePassC
guard !methodSubs.conformances.contains(where: {!$0.isValid}),
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 .method(requirement: requirement, witness: specializedMethod)
@@ -212,8 +214,9 @@ private func specializeDefaultMethods(for conformance: Conformance,
guard !methodSubs.conformances.contains(where: {!$0.isValid}),
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
}
specialized = true

View File

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

View File

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

View File

@@ -4,7 +4,7 @@
// REQUIRES: swift_feature_Embedded
// 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> {
}