|
16 | 16 | #include "swift/AST/GenericEnvironment.h"
|
17 | 17 | #include "swift/AST/GenericSignatureBuilder.h"
|
18 | 18 | #include "swift/AST/TypeMatcher.h"
|
| 19 | +#include "swift/AST/DiagnosticEngine.h" |
| 20 | +#include "swift/AST/DiagnosticsSIL.h" |
19 | 21 | #include "swift/Basic/Statistic.h"
|
| 22 | +#include "swift/Serialization/SerializedSILLoader.h" |
20 | 23 | #include "swift/SIL/DebugUtils.h"
|
21 | 24 | #include "swift/SIL/InstructionUtils.h"
|
22 | 25 | #include "swift/SIL/OptimizationRemark.h"
|
@@ -2288,6 +2291,69 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments(
|
2288 | 2291 | return ReturnValueAddr;
|
2289 | 2292 | }
|
2290 | 2293 |
|
| 2294 | +/// Create a pre-specialization of the library function with |
| 2295 | +/// \p UnspecializedName, using the substitutions from \p Apply. |
| 2296 | +static bool createPrespecialized(StringRef UnspecializedName, |
| 2297 | + ApplySite Apply, |
| 2298 | + SILOptFunctionBuilder &FuncBuilder) { |
| 2299 | + SILModule &M = FuncBuilder.getModule(); |
| 2300 | + SILFunction *UnspecFunc = M.lookUpFunction(UnspecializedName); |
| 2301 | + if (UnspecFunc) { |
| 2302 | + if (!UnspecFunc->isDefinition()) |
| 2303 | + M.loadFunction(UnspecFunc); |
| 2304 | + } else { |
| 2305 | + UnspecFunc = M.getSILLoader()->lookupSILFunction(UnspecializedName, |
| 2306 | + /*declarationOnly*/ false); |
| 2307 | + } |
| 2308 | + |
| 2309 | + if (!UnspecFunc || !UnspecFunc->isDefinition()) |
| 2310 | + return false; |
| 2311 | + |
| 2312 | + ReabstractionInfo ReInfo(ApplySite(), UnspecFunc, Apply.getSubstitutionMap(), |
| 2313 | + IsNotSerialized, /*ConvertIndirectToDirect=*/true, |
| 2314 | + nullptr); |
| 2315 | + |
| 2316 | + if (!ReInfo.canBeSpecialized()) |
| 2317 | + return false; |
| 2318 | + |
| 2319 | + GenericFuncSpecializer FuncSpecializer(FuncBuilder, |
| 2320 | + UnspecFunc, Apply.getSubstitutionMap(), |
| 2321 | + ReInfo); |
| 2322 | + SILFunction *SpecializedF = FuncSpecializer.lookupSpecialization(); |
| 2323 | + if (!SpecializedF) |
| 2324 | + SpecializedF = FuncSpecializer.tryCreateSpecialization(); |
| 2325 | + if (!SpecializedF) |
| 2326 | + return false; |
| 2327 | + |
| 2328 | + SpecializedF->setLinkage(SILLinkage::Public); |
| 2329 | + SpecializedF->setSerialized(IsNotSerialized); |
| 2330 | + return true; |
| 2331 | +} |
| 2332 | + |
| 2333 | +/// Create pre-specializations of the library function X if \p ProxyFunc has |
| 2334 | +/// @_semantics("prespecialize.X") attributes. |
| 2335 | +static bool createPrespecializations(ApplySite Apply, SILFunction *ProxyFunc, |
| 2336 | + SILOptFunctionBuilder &FuncBuilder) { |
| 2337 | + if (Apply.getSubstitutionMap().hasArchetypes()) |
| 2338 | + return false; |
| 2339 | + |
| 2340 | + SILModule &M = FuncBuilder.getModule(); |
| 2341 | + |
| 2342 | + bool prespecializeFound = false; |
| 2343 | + for (const std::string &semAttrStr : ProxyFunc->getSemanticsAttrs()) { |
| 2344 | + StringRef semAttr(semAttrStr); |
| 2345 | + if (semAttr.consume_front("prespecialize.")) { |
| 2346 | + prespecializeFound = true; |
| 2347 | + if (!createPrespecialized(semAttr, Apply, FuncBuilder)) { |
| 2348 | + M.getASTContext().Diags.diagnose(Apply.getLoc().getSourceLoc(), |
| 2349 | + diag::cannot_prespecialize, |
| 2350 | + semAttr); |
| 2351 | + } |
| 2352 | + } |
| 2353 | + } |
| 2354 | + return prespecializeFound; |
| 2355 | +} |
| 2356 | + |
2291 | 2357 | void swift::trySpecializeApplyOfGeneric(
|
2292 | 2358 | SILOptFunctionBuilder &FuncBuilder,
|
2293 | 2359 | ApplySite Apply, DeadInstructionSet &DeadApplies,
|
@@ -2332,8 +2398,12 @@ void swift::trySpecializeApplyOfGeneric(
|
2332 | 2398 | // as we do not SIL serialize their bodies.
|
2333 | 2399 | // It is important to set this flag here, because it affects the
|
2334 | 2400 | // mangling of the specialization's name.
|
2335 |
| - if (Apply.getModule().isOptimizedOnoneSupportModule()) |
| 2401 | + if (Apply.getModule().isOptimizedOnoneSupportModule()) { |
| 2402 | + if (createPrespecializations(Apply, RefF, FuncBuilder)) { |
| 2403 | + return; |
| 2404 | + } |
2336 | 2405 | Serialized = IsNotSerialized;
|
| 2406 | + } |
2337 | 2407 |
|
2338 | 2408 | ReabstractionInfo ReInfo(Apply, RefF, Apply.getSubstitutionMap(),
|
2339 | 2409 | Serialized, /*ConvertIndirectToDirect=*/true,
|
|
0 commit comments