Skip to content

Commit 681fb90

Browse files
committed
Treat non-loadable types as loadable in minimal resilience expansion
if package serialization (Package CMO) is enabled and use site is in the same package in SIL verifier and builder. This allows non-loadable types to be serialized when their defining modules are built resiliently. Resolves rdar://127400743
1 parent 5019d23 commit 681fb90

File tree

4 files changed

+40
-24
lines changed

4 files changed

+40
-24
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,21 @@ class SILBuilder {
30673067
if (!SILModuleConventions(M).useLoweredAddresses())
30683068
return true;
30693069

3070-
return getTypeLowering(Ty).isLoadable();
3070+
const auto &lowering = getTypeLowering(Ty);
3071+
if (lowering.isLoadable())
3072+
return true;
3073+
3074+
// Treat non-loadable as loadable in minimal resilience
3075+
// expansion if package serialization is enabled and the
3076+
// use site is in the same package.
3077+
auto tyMod = Ty.getASTType().getAnyNominal()->getModuleContext();
3078+
if (tyMod && tyMod->serializePackageEnabled() &&
3079+
tyMod->inSamePackage(M.getSwiftModule()) &&
3080+
lowering.getResilienceExpansion() == ResilienceExpansion::Minimal &&
3081+
lowering.isResilient())
3082+
return true;
3083+
3084+
return false;
30713085
}
30723086

30733087
void appendOperandTypeName(SILType OpdTy, llvm::SmallString<16> &Name) {

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4275,7 +4275,7 @@ bool ValueDecl::bypassResilienceInPackage(ModuleDecl *accessingModule) const {
42754275
// Client and the loaded module both need to be in the same package.
42764276
// The loaded module needs to be built from source and opt in to allow
42774277
// non-resilient access.
4278-
return getASTContext().LangOpts.EnableBypassResilienceInPackage &&
4278+
return accessingModule->getASTContext().LangOpts.EnableBypassResilienceInPackage &&
42794279
getModuleContext()->inSamePackage(accessingModule) &&
42804280
getModuleContext()->allowNonResilientAccess();
42814281
}

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,7 +2553,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
25532553
void checkLoadInst(LoadInst *LI) {
25542554
require(LI->getType().isObject(), "Result of load must be an object");
25552555
require(!fnConv.useLoweredAddresses()
2556-
|| LI->getType().isLoadable(*LI->getFunction()),
2556+
|| LI->getType().isLoadable(*LI->getFunction())
2557+
|| treatAsLoadableIfSerializedPackage(LI->getType(), *LI->getFunction()),
25572558
"Load must have a loadable type");
25582559
require(LI->getOperand()->getType().isAddress(),
25592560
"Load operand must be an address");
@@ -2596,7 +2597,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
25962597
"Inst with qualified ownership in a function that is not qualified");
25972598
require(LBI->getType().isObject(), "Result of load must be an object");
25982599
require(!fnConv.useLoweredAddresses()
2599-
|| LBI->getType().isLoadable(*LBI->getFunction()),
2600+
|| LBI->getType().isLoadable(*LBI->getFunction())
2601+
|| treatAsLoadableIfSerializedPackage(LBI->getType(), *LBI->getFunction()),
26002602
"Load must have a loadable type");
26012603
require(LBI->getOperand()->getType().isAddress(),
26022604
"Load operand must be an address");
@@ -2831,11 +2833,24 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
28312833
checkAccessEnforcement(I);
28322834
}
28332835

2836+
bool treatAsLoadableIfSerializedPackage(SILType instType,
2837+
const SILFunction &instFunc) {
2838+
// This func should only be called if the passed type is not loadable.
2839+
assert(!instType.isLoadable(instFunc));
2840+
// Treat non-loadable as loadable in minimal resilience
2841+
// expansion if package serialization is enabled and the
2842+
// use site is in the same package.
2843+
return instFunc.getModule().getSwiftModule()->serializePackageEnabled() &&
2844+
M->inSamePackage(instFunc.getModule().getSwiftModule()) &&
2845+
instFunc.getResilienceExpansion() == ResilienceExpansion::Minimal;
2846+
}
2847+
28342848
void checkStoreInst(StoreInst *SI) {
28352849
require(SI->getSrc()->getType().isObject(),
28362850
"Can't store from an address source");
28372851
require(!fnConv.useLoweredAddresses()
2838-
|| SI->getSrc()->getType().isLoadable(*SI->getFunction()),
2852+
|| SI->getSrc()->getType().isLoadable(*SI->getFunction())
2853+
|| treatAsLoadableIfSerializedPackage(SI->getSrc()->getType(), *SI->getFunction()),
28392854
"Can't store a non loadable type");
28402855
require(SI->getDest()->getType().isAddress(),
28412856
"Must store to an address dest");
@@ -2881,7 +2896,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
28812896
require(SI->getSrc()->getType().isObject(),
28822897
"Can't store from an address source");
28832898
require(!fnConv.useLoweredAddresses()
2884-
|| SI->getSrc()->getType().isLoadable(*SI->getFunction()),
2899+
|| SI->getSrc()->getType().isLoadable(*SI->getFunction())
2900+
|| treatAsLoadableIfSerializedPackage(SI->getSrc()->getType(), *SI->getFunction()),
28852901
"Can't store a non loadable type");
28862902
require(SI->getDest()->getType().isAddress(),
28872903
"Must store to an address dest");

lib/SILOptimizer/IPO/CrossModuleOptimization.cpp

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class CrossModuleOptimization {
8484

8585
bool canSerializeGlobal(SILGlobalVariable *global);
8686

87-
bool canSerializeType(SILType type, TypeExpansionContext typeExpCtx);
87+
bool canSerializeType(SILType type);
8888

8989
bool canUseFromInline(DeclContext *declCtxt);
9090

@@ -331,14 +331,12 @@ bool CrossModuleOptimization::canSerializeFunction(
331331
bool CrossModuleOptimization::canSerializeInstruction(
332332
SILInstruction *inst, FunctionFlags &canSerializeFlags, int maxDepth) {
333333
// First check if any result or operand types prevent serialization.
334-
auto typeExpCtx = inst->getFunction()->getTypeExpansionContext();
335-
336334
for (SILValue result : inst->getResults()) {
337-
if (!canSerializeType(result->getType(), typeExpCtx))
335+
if (!canSerializeType(result->getType()))
338336
return false;
339337
}
340338
for (Operand &op : inst->getAllOperands()) {
341-
if (!canSerializeType(op.get()->getType(), typeExpCtx))
339+
if (!canSerializeType(op.get()->getType()))
342340
return false;
343341
}
344342

@@ -437,23 +435,11 @@ bool CrossModuleOptimization::canSerializeGlobal(SILGlobalVariable *global) {
437435
return true;
438436
}
439437

440-
bool CrossModuleOptimization::canSerializeType(SILType type,
441-
TypeExpansionContext typeExpCtx) {
438+
bool CrossModuleOptimization::canSerializeType(SILType type) {
442439
auto iter = typesChecked.find(type);
443440
if (iter != typesChecked.end())
444441
return iter->getSecond();
445442

446-
if (M.getSwiftModule()->isResilient()) {
447-
auto minResilientCtx = TypeExpansionContext(ResilienceExpansion::Minimal,
448-
typeExpCtx.getContext(),
449-
typeExpCtx.isWholeModuleContext());
450-
auto loadableInMinResilientCtx = M.Types.getTypeLowering(type, minResilientCtx).isLoadable();
451-
if (!loadableInMinResilientCtx) {
452-
typesChecked[type] = false;
453-
return false;
454-
}
455-
}
456-
457443
bool success = !type.getASTType().findIf(
458444
[this](Type rawSubType) {
459445
CanType subType = rawSubType->getCanonicalType();

0 commit comments

Comments
 (0)