mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Support Package CMO
* Add a new flag -experimental-package-cmo that requires -experimental-allow-non-resilient-access. * Support serializing package decls for CMO in package if enabled. * Only applies to default mode CMO. * Unlike the existing CMO, package CMO can be built with -enable-library-evolution as package modules are required to be built together in the same project. * Create hasPublicOrPackageVisibility to opt in for package decls; needed for CMO, SILVerifier, and other call sites that verify or determine codegen. Resolves rdar://121976014
This commit is contained in:
@@ -161,6 +161,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static bool isVisible(SILLinkage linkage, SILOptions options) {
|
||||
if (options.EnableSerializePackage)
|
||||
return linkage == SILLinkage::Public || linkage == SILLinkage::Package;
|
||||
return linkage == SILLinkage::Public;
|
||||
}
|
||||
static bool isVisible(AccessLevel accessLevel, SILOptions options) {
|
||||
if (options.EnableSerializePackage)
|
||||
return accessLevel == AccessLevel::Package || accessLevel == AccessLevel::Public;
|
||||
return accessLevel == AccessLevel::Public;
|
||||
}
|
||||
|
||||
/// Select functions in the module which should be serialized.
|
||||
void CrossModuleOptimization::serializeFunctionsInModule() {
|
||||
|
||||
@@ -168,7 +179,8 @@ void CrossModuleOptimization::serializeFunctionsInModule() {
|
||||
|
||||
// Start with public functions.
|
||||
for (SILFunction &F : M) {
|
||||
if (F.getLinkage() == SILLinkage::Public || everything) {
|
||||
if (isVisible(F.getLinkage(), M.getOptions()) ||
|
||||
everything) {
|
||||
if (canSerializeFunction(&F, canSerializeFlags, /*maxDepth*/ 64)) {
|
||||
serializeFunction(&F, canSerializeFlags);
|
||||
}
|
||||
@@ -185,7 +197,6 @@ bool CrossModuleOptimization::canSerializeFunction(
|
||||
FunctionFlags &canSerializeFlags,
|
||||
int maxDepth) {
|
||||
auto iter = canSerializeFlags.find(function);
|
||||
|
||||
// Avoid infinite recursion in case it's a cycle in the call graph.
|
||||
if (iter != canSerializeFlags.end())
|
||||
return iter->second;
|
||||
@@ -270,7 +281,7 @@ bool CrossModuleOptimization::canSerializeInstruction(SILInstruction *inst,
|
||||
// function is completely inlined afterwards.
|
||||
// Also, when emitting TBD files, we cannot introduce a new public symbol.
|
||||
if ((conservative || M.getOptions().emitTBD) &&
|
||||
!hasPublicVisibility(callee->getLinkage())) {
|
||||
!hasPublicOrPackageVisibility(callee->getLinkage(), M.getOptions().EnableSerializePackage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -290,13 +301,12 @@ bool CrossModuleOptimization::canSerializeInstruction(SILInstruction *inst,
|
||||
// inline.
|
||||
if (!canUseFromInline(callee))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
if (auto *GAI = dyn_cast<GlobalAddrInst>(inst)) {
|
||||
SILGlobalVariable *global = GAI->getReferencedGlobal();
|
||||
if ((conservative || M.getOptions().emitTBD) &&
|
||||
!hasPublicVisibility(global->getLinkage())) {
|
||||
!hasPublicOrPackageVisibility(global->getLinkage(), M.getOptions().EnableSerializePackage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -344,7 +354,7 @@ bool CrossModuleOptimization::canSerializeGlobal(SILGlobalVariable *global) {
|
||||
// function is completely inlined afterwards.
|
||||
// Also, when emitting TBD files, we cannot introduce a new public symbol.
|
||||
if ((conservative || M.getOptions().emitTBD) &&
|
||||
!hasPublicVisibility(referencedFunc->getLinkage())) {
|
||||
!hasPublicOrPackageVisibility(referencedFunc->getLinkage(), M.getOptions().EnableSerializePackage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -368,7 +378,7 @@ bool CrossModuleOptimization::canSerializeType(SILType type) {
|
||||
if (conservative && subNT->getEffectiveAccess() < AccessLevel::Package) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Exclude types which are defined in an @_implementationOnly imported
|
||||
// module. Such modules are not transitively available.
|
||||
if (!canUseFromInline(subNT)) {
|
||||
@@ -542,7 +552,7 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst,
|
||||
}
|
||||
}
|
||||
serializeFunction(callee, canSerializeFlags);
|
||||
assert(callee->isSerialized() || callee->getLinkage() == SILLinkage::Public);
|
||||
assert(callee->isSerialized() || isVisible(callee->getLinkage(), M.getOptions()));
|
||||
return;
|
||||
}
|
||||
if (auto *GAI = dyn_cast<GlobalAddrInst>(inst)) {
|
||||
@@ -550,7 +560,7 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst,
|
||||
if (canSerializeGlobal(global)) {
|
||||
serializeGlobal(global);
|
||||
}
|
||||
if (!hasPublicVisibility(global->getLinkage())) {
|
||||
if (!hasPublicOrPackageVisibility(global->getLinkage(), M.getOptions().EnableSerializePackage)) {
|
||||
global->setLinkage(SILLinkage::Public);
|
||||
}
|
||||
return;
|
||||
@@ -606,7 +616,7 @@ void CrossModuleOptimization::makeDeclUsableFromInline(ValueDecl *decl) {
|
||||
if (M.getSwiftModule() != decl->getDeclContext()->getParentModule())
|
||||
return;
|
||||
|
||||
if (decl->getFormalAccess() < AccessLevel::Public &&
|
||||
if (!isVisible(decl->getFormalAccess(), M.getOptions()) &&
|
||||
!decl->isUsableFromInline()) {
|
||||
// Mark the nominal type as "usableFromInline".
|
||||
// TODO: find a way to do this without modifying the AST. The AST should be
|
||||
|
||||
Reference in New Issue
Block a user