mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/master' into master-next
This commit is contained in:
@@ -171,11 +171,6 @@ private:
|
||||
/// would indicate.
|
||||
unsigned HasCReferences : 1;
|
||||
|
||||
/// Set if the function should be preserved and changed to public linkage
|
||||
/// during dead function elimination. This is used for some generic
|
||||
/// pre-specialization.
|
||||
unsigned KeepAsPublic : 1;
|
||||
|
||||
/// If != OptimizationMode::NotSet, the optimization mode specified with an
|
||||
/// function attribute.
|
||||
OptimizationMode OptMode;
|
||||
@@ -288,10 +283,6 @@ public:
|
||||
LoweredType = newType;
|
||||
}
|
||||
|
||||
bool canBeDeleted() const {
|
||||
return !getRefCount() && !isZombie() && !isKeepAsPublic();
|
||||
}
|
||||
|
||||
/// Return the number of entities referring to this function (other
|
||||
/// than the SILModule).
|
||||
unsigned getRefCount() const { return RefCount; }
|
||||
@@ -596,9 +587,6 @@ public:
|
||||
bool isGlobalInit() const { return GlobalInitFlag; }
|
||||
void setGlobalInit(bool isGI) { GlobalInitFlag = isGI; }
|
||||
|
||||
bool isKeepAsPublic() const { return KeepAsPublic; }
|
||||
void setKeepAsPublic(bool keep) { KeepAsPublic = keep; }
|
||||
|
||||
/// Return whether this function has a foreign implementation which can
|
||||
/// be emitted on demand.
|
||||
bool hasForeignBody() const;
|
||||
|
||||
@@ -97,7 +97,7 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, StringRef Name,
|
||||
Serialized(isSerialized), Thunk(isThunk),
|
||||
ClassSubclassScope(unsigned(classSubclassScope)), GlobalInitFlag(false),
|
||||
InlineStrategy(inlineStrategy), Linkage(unsigned(Linkage)),
|
||||
HasCReferences(false), KeepAsPublic(false),
|
||||
HasCReferences(false),
|
||||
OptMode(OptimizationMode::NotSet), EffectsKindAttr(E),
|
||||
EntryCount(entryCount) {
|
||||
if (InsertBefore)
|
||||
|
||||
@@ -1083,21 +1083,13 @@ public:
|
||||
|
||||
// A direct reference to a non-public or shared but not fragile function
|
||||
// from a fragile function is an error.
|
||||
//
|
||||
// Exception: When compiling OnoneSupport anything can reference anything,
|
||||
// because the bodies of functions are never SIL serialized, but
|
||||
// specializations are exposed as public symbols in the produced object
|
||||
// files. For the same reason, KeepAsPublic functions (i.e. specializations)
|
||||
// can refer to anything or can be referenced from any other function.
|
||||
if (!F.getModule().isOptimizedOnoneSupportModule() &&
|
||||
!(F.isKeepAsPublic() || RefF->isKeepAsPublic())) {
|
||||
if (F.isSerialized()) {
|
||||
require((SingleFunction && RefF->isExternalDeclaration()) ||
|
||||
RefF->hasValidLinkageForFragileRef(),
|
||||
"function_ref inside fragile function cannot "
|
||||
"reference a private or hidden symbol");
|
||||
}
|
||||
if (F.isSerialized()) {
|
||||
require((SingleFunction && RefF->isExternalDeclaration()) ||
|
||||
RefF->hasValidLinkageForFragileRef(),
|
||||
"function_ref inside fragile function cannot "
|
||||
"reference a private or hidden symbol");
|
||||
}
|
||||
|
||||
verifySILFunctionType(fnType);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,24 +30,6 @@ STATISTIC(NumDeadFunc, "Number of dead functions eliminated");
|
||||
|
||||
namespace {
|
||||
|
||||
/// Returns true if a function should be SIL serialized or emitted by IRGen.
|
||||
static bool shouldBeSerializedOrEmitted(SILFunction *F) {
|
||||
// global initializers are always emitted into the defining module and
|
||||
// their bodies are never SIL serialized.
|
||||
if (F->isGlobalInit())
|
||||
return true;
|
||||
|
||||
// public_external functions are never SIL serialized or emitted by IRGen.
|
||||
if (F->isAvailableExternally() && hasPublicVisibility(F->getLinkage()))
|
||||
return false;
|
||||
|
||||
// [serialized] functions should always be SIL serialized.
|
||||
if (F->isSerialized())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// This is a base class for passes that are based on function liveness
|
||||
/// computations like e.g. dead function elimination.
|
||||
/// It provides a common logic for computing live (i.e. reachable) functions.
|
||||
@@ -124,24 +106,9 @@ protected:
|
||||
if (F->getRepresentation() == SILFunctionTypeRepresentation::ObjCMethod)
|
||||
return true;
|
||||
|
||||
// Functions that may be used externally cannot be removed.
|
||||
if (isPossiblyUsedExternally(F->getLinkage(), Module->isWholeModule()))
|
||||
return true;
|
||||
|
||||
// If function is marked as "keep-as-public", don't remove it.
|
||||
// Change its linkage to public, so that other applications can refer to it.
|
||||
// It is important that this transformation is done at the end of
|
||||
// a pipeline, as it may break some optimizations.
|
||||
if (F->isKeepAsPublic()) {
|
||||
F->setLinkage(SILLinkage::Public);
|
||||
DEBUG(llvm::dbgs() << "DFE: Preserve the specialization "
|
||||
<< F->getName() << '\n');
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do not consider public_external functions that do not need to be emitted
|
||||
// into the client as anchors.
|
||||
if (shouldBeSerializedOrEmitted(F))
|
||||
// Global initializers are always emitted into the defining module and
|
||||
// their bodies are never SIL serialized.
|
||||
if (F->isGlobalInit())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
@@ -755,7 +755,7 @@ void EagerSpecializerTransform::run() {
|
||||
SpecializedFuncs.push_back(NewFunc);
|
||||
|
||||
if (SA->isExported()) {
|
||||
NewFunc->setKeepAsPublic(true);
|
||||
NewFunc->setLinkage(SILLinkage::Public);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2372,13 +2372,6 @@ void swift::trySpecializeApplyOfGeneric(
|
||||
== SpecializedF->getLoweredFunctionType() &&
|
||||
"Previously specialized function does not match expected type.");
|
||||
|
||||
// FIXME: Replace pre-specialization's "keep as public" hack with something
|
||||
// more principled
|
||||
assert((Serialized == SpecializedF->isSerialized() ||
|
||||
SpecializedF->isKeepAsPublic()) &&
|
||||
"Previously specialized function does not match expected "
|
||||
"resilience level.");
|
||||
|
||||
DeadApplies.insert(Apply.getInstruction());
|
||||
|
||||
if (replacePartialApplyWithoutReabstraction) {
|
||||
@@ -2435,27 +2428,6 @@ void swift::trySpecializeApplyOfGeneric(
|
||||
// This uses the SIL linker to checks for the does not load the body of the pres
|
||||
// =============================================================================
|
||||
|
||||
static void keepSpecializationAsPublic(SILFunction *F) {
|
||||
DEBUG(auto DemangledNameString =
|
||||
swift::Demangle::demangleSymbolAsString(F->getName());
|
||||
StringRef DemangledName = DemangledNameString;
|
||||
llvm::dbgs() << "Keep specialization public: " << DemangledName << " : "
|
||||
<< F->getName() << "\n");
|
||||
// Make it public, so that others can refer to it.
|
||||
//
|
||||
// NOTE: This function may refer to non-public symbols, which may lead to
|
||||
// problems, if you ever try to inline this function. Therefore, these
|
||||
// specializations should only be used to refer to them, but should never
|
||||
// be inlined! The general rule could be: Never inline specializations
|
||||
// from stdlib!
|
||||
//
|
||||
// NOTE: Making these specializations public at this point breaks
|
||||
// some optimizations. Therefore, just mark the function.
|
||||
// DeadFunctionElimination pass will check if the function is marked
|
||||
// and preserve it if required.
|
||||
F->setKeepAsPublic(true);
|
||||
}
|
||||
|
||||
/// Link a specialization for generating prespecialized code.
|
||||
///
|
||||
/// For now, it is performed only for specializations in the
|
||||
@@ -2467,14 +2439,15 @@ static void keepSpecializationAsPublic(SILFunction *F) {
|
||||
/// the library, but only used only by client code compiled at -Onone. They
|
||||
/// should be never inlined.
|
||||
static bool linkSpecialization(SILModule &M, SILFunction *F) {
|
||||
if (F->isKeepAsPublic())
|
||||
if (F->getLinkage() == SILLinkage::Public)
|
||||
return true;
|
||||
// Do not remove functions that are known prespecializations.
|
||||
// Keep them around. Change their linkage to public, so that other
|
||||
// applications can refer to them.
|
||||
if (M.isOptimizedOnoneSupportModule()) {
|
||||
if (isKnownPrespecialization(F->getName())) {
|
||||
keepSpecializationAsPublic(F);
|
||||
F->setLinkage(SILLinkage::Public);
|
||||
F->setSerialized(IsNotSerialized);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ void SILSerializer::addMandatorySILFunction(const SILFunction *F,
|
||||
|
||||
// Function body should be serialized unless it is a KeepAsPublic function
|
||||
// (which is typically a pre-specialization).
|
||||
if (!emitDeclarationsForOnoneSupport && !F->isKeepAsPublic())
|
||||
if (!emitDeclarationsForOnoneSupport)
|
||||
Worklist.push_back(F);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user