mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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
This commit is contained in:
@@ -251,6 +251,8 @@ ERROR(circular_transparent,none,
|
||||
"inlining 'transparent' functions forms circular loop", ())
|
||||
NOTE(note_while_inlining,none,
|
||||
"while inlining here", ())
|
||||
ERROR(cannot_prespecialize,none,
|
||||
"Cannot pre-specialize %0", (StringRef))
|
||||
|
||||
// Arithmetic diagnostics.
|
||||
ERROR(integer_conversion_overflow,none,
|
||||
|
||||
@@ -266,16 +266,16 @@ private:
|
||||
SILModule(const SILModule&) = delete;
|
||||
void operator=(const SILModule&) = delete;
|
||||
|
||||
/// Method which returns the SerializedSILLoader, creating the loader if it
|
||||
/// has not been created yet.
|
||||
SerializedSILLoader *getSILLoader();
|
||||
|
||||
/// Folding set for key path patterns.
|
||||
llvm::FoldingSet<KeyPathPattern> KeyPathPatterns;
|
||||
|
||||
public:
|
||||
~SILModule();
|
||||
|
||||
/// Method which returns the SerializedSILLoader, creating the loader if it
|
||||
/// has not been created yet.
|
||||
SerializedSILLoader *getSILLoader();
|
||||
|
||||
/// Add a callback for each newly deserialized SIL function body.
|
||||
void registerDeserializationNotificationHandler(
|
||||
std::unique_ptr<DeserializationNotificationHandler> &&handler);
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
#include "swift/AST/GenericEnvironment.h"
|
||||
#include "swift/AST/GenericSignatureBuilder.h"
|
||||
#include "swift/AST/TypeMatcher.h"
|
||||
#include "swift/AST/DiagnosticEngine.h"
|
||||
#include "swift/AST/DiagnosticsSIL.h"
|
||||
#include "swift/Basic/Statistic.h"
|
||||
#include "swift/Serialization/SerializedSILLoader.h"
|
||||
#include "swift/SIL/DebugUtils.h"
|
||||
#include "swift/SIL/InstructionUtils.h"
|
||||
#include "swift/SIL/OptimizationRemark.h"
|
||||
@@ -2288,6 +2291,69 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments(
|
||||
return ReturnValueAddr;
|
||||
}
|
||||
|
||||
/// Create a pre-specialization of the library function with
|
||||
/// \p UnspecializedName, using the substitutions from \p Apply.
|
||||
static bool createPrespecialized(StringRef UnspecializedName,
|
||||
ApplySite Apply,
|
||||
SILOptFunctionBuilder &FuncBuilder) {
|
||||
SILModule &M = FuncBuilder.getModule();
|
||||
SILFunction *UnspecFunc = M.lookUpFunction(UnspecializedName);
|
||||
if (UnspecFunc) {
|
||||
if (!UnspecFunc->isDefinition())
|
||||
M.loadFunction(UnspecFunc);
|
||||
} else {
|
||||
UnspecFunc = M.getSILLoader()->lookupSILFunction(UnspecializedName,
|
||||
/*declarationOnly*/ false);
|
||||
}
|
||||
|
||||
if (!UnspecFunc || !UnspecFunc->isDefinition())
|
||||
return false;
|
||||
|
||||
ReabstractionInfo ReInfo(ApplySite(), UnspecFunc, Apply.getSubstitutionMap(),
|
||||
IsNotSerialized, /*ConvertIndirectToDirect=*/true,
|
||||
nullptr);
|
||||
|
||||
if (!ReInfo.canBeSpecialized())
|
||||
return false;
|
||||
|
||||
GenericFuncSpecializer FuncSpecializer(FuncBuilder,
|
||||
UnspecFunc, Apply.getSubstitutionMap(),
|
||||
ReInfo);
|
||||
SILFunction *SpecializedF = FuncSpecializer.lookupSpecialization();
|
||||
if (!SpecializedF)
|
||||
SpecializedF = FuncSpecializer.tryCreateSpecialization();
|
||||
if (!SpecializedF)
|
||||
return false;
|
||||
|
||||
SpecializedF->setLinkage(SILLinkage::Public);
|
||||
SpecializedF->setSerialized(IsNotSerialized);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Create pre-specializations of the library function X if \p ProxyFunc has
|
||||
/// @_semantics("prespecialize.X") attributes.
|
||||
static bool createPrespecializations(ApplySite Apply, SILFunction *ProxyFunc,
|
||||
SILOptFunctionBuilder &FuncBuilder) {
|
||||
if (Apply.getSubstitutionMap().hasArchetypes())
|
||||
return false;
|
||||
|
||||
SILModule &M = FuncBuilder.getModule();
|
||||
|
||||
bool prespecializeFound = false;
|
||||
for (const std::string &semAttrStr : ProxyFunc->getSemanticsAttrs()) {
|
||||
StringRef semAttr(semAttrStr);
|
||||
if (semAttr.consume_front("prespecialize.")) {
|
||||
prespecializeFound = true;
|
||||
if (!createPrespecialized(semAttr, Apply, FuncBuilder)) {
|
||||
M.getASTContext().Diags.diagnose(Apply.getLoc().getSourceLoc(),
|
||||
diag::cannot_prespecialize,
|
||||
semAttr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return prespecializeFound;
|
||||
}
|
||||
|
||||
void swift::trySpecializeApplyOfGeneric(
|
||||
SILOptFunctionBuilder &FuncBuilder,
|
||||
ApplySite Apply, DeadInstructionSet &DeadApplies,
|
||||
@@ -2332,8 +2398,12 @@ void swift::trySpecializeApplyOfGeneric(
|
||||
// as we do not SIL serialize their bodies.
|
||||
// It is important to set this flag here, because it affects the
|
||||
// mangling of the specialization's name.
|
||||
if (Apply.getModule().isOptimizedOnoneSupportModule())
|
||||
if (Apply.getModule().isOptimizedOnoneSupportModule()) {
|
||||
if (createPrespecializations(Apply, RefF, FuncBuilder)) {
|
||||
return;
|
||||
}
|
||||
Serialized = IsNotSerialized;
|
||||
}
|
||||
|
||||
ReabstractionInfo ReInfo(Apply, RefF, Apply.getSubstitutionMap(),
|
||||
Serialized, /*ConvertIndirectToDirect=*/true,
|
||||
|
||||
Reference in New Issue
Block a user