Skip to content

Commit 17aa1c0

Browse files
committed
SILOptimizer: add a mechanism to pre-specialize internal stdlib symbols for OnoneSupport.
When compiling the OnoneSupport library, the compiler checks for @_semantics("prespecialize.X") attributes to pre-specialize function X. rdar://problem/48924409
1 parent 39e681c commit 17aa1c0

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ ERROR(circular_transparent,none,
251251
"inlining 'transparent' functions forms circular loop", ())
252252
NOTE(note_while_inlining,none,
253253
"while inlining here", ())
254+
ERROR(cannot_prespecialize,none,
255+
"Cannot pre-specialize %0", (StringRef))
254256

255257
// Arithmetic diagnostics.
256258
ERROR(integer_conversion_overflow,none,

include/swift/SIL/SILModule.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,16 +266,16 @@ class SILModule {
266266
SILModule(const SILModule&) = delete;
267267
void operator=(const SILModule&) = delete;
268268

269-
/// Method which returns the SerializedSILLoader, creating the loader if it
270-
/// has not been created yet.
271-
SerializedSILLoader *getSILLoader();
272-
273269
/// Folding set for key path patterns.
274270
llvm::FoldingSet<KeyPathPattern> KeyPathPatterns;
275271

276272
public:
277273
~SILModule();
278274

275+
/// Method which returns the SerializedSILLoader, creating the loader if it
276+
/// has not been created yet.
277+
SerializedSILLoader *getSILLoader();
278+
279279
/// Add a callback for each newly deserialized SIL function body.
280280
void registerDeserializationNotificationHandler(
281281
std::unique_ptr<DeserializationNotificationHandler> &&handler);

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
#include "swift/AST/GenericEnvironment.h"
1717
#include "swift/AST/GenericSignatureBuilder.h"
1818
#include "swift/AST/TypeMatcher.h"
19+
#include "swift/AST/DiagnosticEngine.h"
20+
#include "swift/AST/DiagnosticsSIL.h"
1921
#include "swift/Basic/Statistic.h"
22+
#include "swift/Serialization/SerializedSILLoader.h"
2023
#include "swift/SIL/DebugUtils.h"
2124
#include "swift/SIL/InstructionUtils.h"
2225
#include "swift/SIL/OptimizationRemark.h"
@@ -2288,6 +2291,69 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments(
22882291
return ReturnValueAddr;
22892292
}
22902293

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+
22912357
void swift::trySpecializeApplyOfGeneric(
22922358
SILOptFunctionBuilder &FuncBuilder,
22932359
ApplySite Apply, DeadInstructionSet &DeadApplies,
@@ -2332,8 +2398,12 @@ void swift::trySpecializeApplyOfGeneric(
23322398
// as we do not SIL serialize their bodies.
23332399
// It is important to set this flag here, because it affects the
23342400
// 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+
}
23362405
Serialized = IsNotSerialized;
2406+
}
23372407

23382408
ReabstractionInfo ReInfo(Apply, RefF, Apply.getSubstitutionMap(),
23392409
Serialized, /*ConvertIndirectToDirect=*/true,

0 commit comments

Comments
 (0)