From ab2345a2edbc6e285432dbc36edc39276f8eaee9 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Tue, 25 Nov 2025 14:16:45 +0100 Subject: [PATCH] FunctionPassContext: support setting arbitrary function type representations when creating specialized functions --- .../Optimizer/FunctionPasses/ClosureSpecialization.swift | 2 +- .../Optimizer/FunctionPasses/PackSpecialization.swift | 2 +- .../Optimizer/PassManager/FunctionPassContext.swift | 7 ++++--- include/swift/SILOptimizer/OptimizerBridging.h | 2 +- lib/SILOptimizer/Utils/OptimizerBridging.cpp | 6 ++---- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ClosureSpecialization.swift b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ClosureSpecialization.swift index b57244b9873..d25baaea349 100644 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ClosureSpecialization.swift +++ b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ClosureSpecialization.swift @@ -410,7 +410,7 @@ private struct SpecializationInfo { // The specialized function is always a thin function. This is important because we add additional // parameters after the Self parameter of witness methods. In this case the new function is not a // method anymore. - makeThin: true, makeBare: true) + withRepresentation: .thin, makeBare: true) context.buildSpecializedFunction( specializedFunction: specializedFunction, diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/PackSpecialization.swift b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/PackSpecialization.swift index a77335dae99..f302586d265 100644 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/PackSpecialization.swift +++ b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/PackSpecialization.swift @@ -553,7 +553,7 @@ private struct PackExplodedFunction { withParams: newParameters, withResults: newResults, // If a method has a dynamic self parameter, it cannot be converted into a thin function (non-method). - makeThin: !original.mayBindDynamicSelf) + withRepresentation: original.mayBindDynamicSelf ? nil : .thin) self.buildSpecializedFunction(context) } diff --git a/SwiftCompilerSources/Sources/Optimizer/PassManager/FunctionPassContext.swift b/SwiftCompilerSources/Sources/Optimizer/PassManager/FunctionPassContext.swift index be9c8ed882c..651c61b4985 100644 --- a/SwiftCompilerSources/Sources/Optimizer/PassManager/FunctionPassContext.swift +++ b/SwiftCompilerSources/Sources/Optimizer/PassManager/FunctionPassContext.swift @@ -168,12 +168,13 @@ struct FunctionPassContext : MutatingContext { from original: Function, withName specializedFunctionName: String, withParams specializedParameters: [ParameterInfo], withResults specializedResults: [ResultInfo]? = nil, - makeThin: Bool = false, + withRepresentation: FunctionTypeRepresentation? = nil, makeBare: Bool = false, preserveGenericSignature: Bool = true ) -> Function { return specializedFunctionName._withBridgedStringRef { nameRef in let bridgedParamInfos = specializedParameters.map { $0._bridged } + let repr = withRepresentation ?? original.loweredFunctionType.functionTypeRepresentation return bridgedParamInfos.withUnsafeBufferPointer { paramBuf in @@ -183,7 +184,7 @@ struct FunctionPassContext : MutatingContext { return bridgedPassContext.createSpecializedFunctionDeclaration( nameRef, paramBuf.baseAddress, paramBuf.count, resultBuf.baseAddress, resultBuf.count, - original.bridged, makeThin, makeBare, + original.bridged, repr.bridged, makeBare, preserveGenericSignature ).function } @@ -191,7 +192,7 @@ struct FunctionPassContext : MutatingContext { return bridgedPassContext.createSpecializedFunctionDeclaration( nameRef, paramBuf.baseAddress, paramBuf.count, nil, 0, - original.bridged, makeThin, makeBare, + original.bridged, repr.bridged, makeBare, preserveGenericSignature ).function } diff --git a/include/swift/SILOptimizer/OptimizerBridging.h b/include/swift/SILOptimizer/OptimizerBridging.h index 43107cfd135..5973699ccc1 100644 --- a/include/swift/SILOptimizer/OptimizerBridging.h +++ b/include/swift/SILOptimizer/OptimizerBridging.h @@ -274,7 +274,7 @@ struct BridgedPassContext { const BridgedResultInfo *_Nullable specializedBridgedResults, SwiftInt resultCount, BridgedFunction bridgedOriginal, - bool makeThin, + BridgedASTType::FunctionTypeRepresentation representation, bool makeBare, bool preserveGenericSignature) const; diff --git a/lib/SILOptimizer/Utils/OptimizerBridging.cpp b/lib/SILOptimizer/Utils/OptimizerBridging.cpp index a1e7954d2ae..da80b877f69 100644 --- a/lib/SILOptimizer/Utils/OptimizerBridging.cpp +++ b/lib/SILOptimizer/Utils/OptimizerBridging.cpp @@ -393,7 +393,7 @@ createSpecializedFunctionDeclaration(BridgedStringRef specializedName, const BridgedResultInfo * _Nullable specializedBridgedResults, SwiftInt resultCount, BridgedFunction bridgedOriginal, - bool makeThin, + BridgedASTType::FunctionTypeRepresentation representation, bool makeBare, bool preserveGenericSignature) const { auto *original = bridgedOriginal.getFunction(); @@ -415,9 +415,7 @@ createSpecializedFunctionDeclaration(BridgedStringRef specializedName, // The specialized function is always a thin function. This is important // because we may add additional parameters after the Self parameter of // witness methods. In this case the new function is not a method anymore. - auto extInfo = originalType->getExtInfo(); - if (makeThin) - extInfo = extInfo.withRepresentation(SILFunctionTypeRepresentation::Thin); + auto extInfo = originalType->getExtInfo().withRepresentation((SILFunctionTypeRepresentation)representation); auto ClonedTy = SILFunctionType::get( preserveGenericSignature ? originalType->getInvocationGenericSignature() : GenericSignature(),