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:
Erik Eckstein
2019-03-21 16:44:53 -07:00
parent 39e681c965
commit 17aa1c0c20
3 changed files with 77 additions and 5 deletions

View File

@@ -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,

View File

@@ -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);

View File

@@ -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,