mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[SIL][PackageCMO] Allow optimizing [serialized_for_pkg] functions during SIL
inlining, generic/closure specialization, and devirtualization optimization passes. SILFunction::canBeInlinedIntoCaller now exlicitly requires a caller's SerializedKind_t arg. isAnySerialized() is added as a convenience function that checks if [serialized] or [serialized_for_pkg]. Resolves rdar://128704752
This commit is contained in:
@@ -278,7 +278,7 @@ namespace {
|
||||
void writeSILGlobalVar(const SILGlobalVariable &g);
|
||||
void writeSILWitnessTable(const SILWitnessTable &wt);
|
||||
void writeSILWitnessTableEntry(const SILWitnessTable::Entry &entry,
|
||||
std::optional<SerializedKind_t> serializedKind = std::nullopt);
|
||||
SerializedKind_t serializedKind);
|
||||
void writeSILDefaultWitnessTable(const SILDefaultWitnessTable &wt);
|
||||
void
|
||||
writeSILDifferentiabilityWitness(const SILDifferentiabilityWitness &dw);
|
||||
@@ -376,8 +376,7 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
|
||||
}
|
||||
|
||||
if (F->getLinkage() == SILLinkage::Shared) {
|
||||
assert(!F->isNotSerialized() ||
|
||||
F->hasForeignBody());
|
||||
assert(F->isAnySerialized() || F->hasForeignBody());
|
||||
|
||||
FuncsToEmit[F] = false;
|
||||
functionWorklist.push_back(F);
|
||||
@@ -495,7 +494,6 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
|
||||
}
|
||||
|
||||
unsigned numAttrs = NoBody ? 0 : F.getSpecializeAttrs().size();
|
||||
// pcmo TODO: check if package-cmo is enabled
|
||||
auto resilience = F.getModule().getSwiftModule()->getResilienceStrategy();
|
||||
bool serializeDerivedEffects = (resilience != ResilienceStrategy::Resilient) &&
|
||||
!F.hasSemanticsAttr("optimize.no.crossmodule");
|
||||
@@ -2879,7 +2877,7 @@ void SILSerializer::writeSILGlobalVar(const SILGlobalVariable &g) {
|
||||
TyID, dID);
|
||||
|
||||
// Don't emit the initializer instructions if not marked as "serialized".
|
||||
if (g.isNotSerialized())
|
||||
if (!g.isAnySerialized())
|
||||
return;
|
||||
|
||||
ValueIDs.clear();
|
||||
@@ -2926,8 +2924,8 @@ void SILSerializer::writeSILVTable(const SILVTable &vt) {
|
||||
SILFunction *impl = entry.getImplementation();
|
||||
|
||||
if (ShouldSerializeAll ||
|
||||
impl->hasValidLinkageForFragileRef(vt.getSerializedKind(),
|
||||
/*assumeFragileCaller*/ false)) {
|
||||
(vt.isAnySerialized() &&
|
||||
impl->hasValidLinkageForFragileRef(vt.getSerializedKind()))) {
|
||||
handleSILDeclRef(S, entry.getMethod(), ListOfValues);
|
||||
addReferencedSILFunction(impl, true);
|
||||
// Each entry is a pair of SILDeclRef and SILFunction.
|
||||
@@ -2950,7 +2948,7 @@ void SILSerializer::writeSILMoveOnlyDeinit(const SILMoveOnlyDeinit &deinit) {
|
||||
return;
|
||||
|
||||
SILFunction *impl = deinit.getImplementation();
|
||||
if (!ShouldSerializeAll && !impl->hasValidLinkageForFragileRef())
|
||||
if (!ShouldSerializeAll && !impl->hasValidLinkageForFragileRef(IsSerialized))
|
||||
return;
|
||||
|
||||
// Use the mangled name of the class as a key to distinguish between classes
|
||||
@@ -3026,7 +3024,7 @@ void SILSerializer::writeSILWitnessTable(const SILWitnessTable &wt) {
|
||||
|
||||
void SILSerializer::writeSILWitnessTableEntry(
|
||||
const SILWitnessTable::Entry &entry,
|
||||
std::optional<SerializedKind_t> serializedKind) {
|
||||
SerializedKind_t serializedKind) {
|
||||
if (entry.getKind() == SILWitnessTable::BaseProtocol) {
|
||||
auto &baseWitness = entry.getBaseProtocolWitness();
|
||||
|
||||
@@ -3068,8 +3066,8 @@ void SILSerializer::writeSILWitnessTableEntry(
|
||||
IdentifierID witnessID = 0;
|
||||
SILFunction *witness = methodWitness.Witness;
|
||||
if (witness &&
|
||||
witness->hasValidLinkageForFragileRef(serializedKind,
|
||||
/*assumeFragileCaller*/ false)) {
|
||||
serializedKind != IsNotSerialized &&
|
||||
witness->hasValidLinkageForFragileRef(serializedKind)) {
|
||||
addReferencedSILFunction(witness, true);
|
||||
witnessID = S.addUniquedStringRef(witness->getName());
|
||||
}
|
||||
@@ -3102,7 +3100,7 @@ writeSILDefaultWitnessTable(const SILDefaultWitnessTable &wt) {
|
||||
SILAbbrCodes[DefaultWitnessTableNoEntryLayout::Code]);
|
||||
continue;
|
||||
}
|
||||
writeSILWitnessTableEntry(entry);
|
||||
writeSILWitnessTableEntry(entry, IsNotSerialized);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3174,8 +3172,7 @@ bool SILSerializer::shouldEmitFunctionBody(const SILFunction *F,
|
||||
// If F is serialized, we should always emit its body.
|
||||
// Shared functions are only serialized if they are referenced from another
|
||||
// serialized function. This is handled in `addReferencedSILFunction`.
|
||||
if (!F->isNotSerialized() &&
|
||||
!hasSharedVisibility(F->getLinkage()))
|
||||
if (F->isAnySerialized() && !hasSharedVisibility(F->getLinkage()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -3237,13 +3234,13 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
|
||||
// serialize everything.
|
||||
// FIXME: Resilience: could write out vtable for fragile classes.
|
||||
for (const auto &vt : SILMod->getVTables()) {
|
||||
if ((ShouldSerializeAll || !vt->isNotSerialized()) &&
|
||||
if ((ShouldSerializeAll || vt->isAnySerialized()) &&
|
||||
SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(vt->getClass()))
|
||||
writeSILVTable(*vt);
|
||||
}
|
||||
|
||||
for (const auto &deinit : SILMod->getMoveOnlyDeinits()) {
|
||||
if ((ShouldSerializeAll || !deinit->isNotSerialized()) &&
|
||||
if ((ShouldSerializeAll || deinit->isAnySerialized()) &&
|
||||
SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(
|
||||
deinit->getNominalDecl()))
|
||||
writeSILMoveOnlyDeinit(*deinit);
|
||||
@@ -3251,7 +3248,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
|
||||
|
||||
// Write out property descriptors.
|
||||
for (const SILProperty &prop : SILMod->getPropertyList()) {
|
||||
if ((ShouldSerializeAll || !prop.isNotSerialized()) &&
|
||||
if ((ShouldSerializeAll || prop.isAnySerialized()) &&
|
||||
SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(
|
||||
prop.getDecl()->getInnermostDeclContext()))
|
||||
writeSILProperty(prop);
|
||||
@@ -3259,7 +3256,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
|
||||
|
||||
// Write out fragile WitnessTables.
|
||||
for (const SILWitnessTable &wt : SILMod->getWitnessTables()) {
|
||||
if ((ShouldSerializeAll || !wt.isNotSerialized()) &&
|
||||
if ((ShouldSerializeAll || wt.isAnySerialized()) &&
|
||||
SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(
|
||||
wt.getConformance()->getDeclContext()))
|
||||
writeSILWitnessTable(wt);
|
||||
@@ -3276,7 +3273,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
|
||||
|
||||
// Add global variables that must be emitted to the list.
|
||||
for (const SILGlobalVariable &g : SILMod->getSILGlobals()) {
|
||||
if (!g.isNotSerialized() || ShouldSerializeAll)
|
||||
if (g.isAnySerialized() || ShouldSerializeAll)
|
||||
addReferencedGlobalVariable(&g);
|
||||
}
|
||||
|
||||
@@ -3322,7 +3319,6 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
|
||||
|
||||
// Now write function declarations for every function we've
|
||||
// emitted a reference to without emitting a function body for.
|
||||
// pcmo TODO: check if package-cmo is enabled
|
||||
auto resilience = SILMod->getSwiftModule()->getResilienceStrategy();
|
||||
for (const SILFunction &F : *SILMod) {
|
||||
auto iter = FuncsToEmit.find(&F);
|
||||
|
||||
Reference in New Issue
Block a user