Skip to content

Add a package serialization bit to Module for SIL verifier in Package CMO mode. #72937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
HasAnyUnavailableDuringLoweringValues : 1
);

SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
/// If the module is compiled as static library.
StaticLibrary : 1,

Expand Down Expand Up @@ -756,7 +756,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
HasCxxInteroperability : 1,

/// Whether this module has been built with -experimental-allow-non-resilient-access.
AllowNonResilientAccess : 1
AllowNonResilientAccess : 1,

/// Whether this module has been built with -experimental-package-cmo.
SerializePackageEnabled : 1
);

SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,
Expand Down
10 changes: 10 additions & 0 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,16 @@ class ModuleDecl
Bits.ModuleDecl.AllowNonResilientAccess = flag;
}

/// Returns true if -experimental-package-cmo was passed, which
/// enables serialization of package, public, and inlinable decls in a
/// package. This requires -experimental-allow-non-resilient-access.
bool serializePackageEnabled() const {
return Bits.ModuleDecl.SerializePackageEnabled;
}
void setSerializePackageEnabled(bool flag = true) {
Bits.ModuleDecl.SerializePackageEnabled = flag;
}

/// Returns true if this module is a non-Swift module that was imported into
/// Swift.
///
Expand Down
5 changes: 5 additions & 0 deletions include/swift/Serialization/Validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class ExtendedValidationInfo {
unsigned IsConcurrencyChecked : 1;
unsigned HasCxxInteroperability : 1;
unsigned AllowNonResilientAccess: 1;
unsigned SerializePackageEnabled: 1;
} Bits;
public:
ExtendedValidationInfo() : Bits() {}
Expand Down Expand Up @@ -209,6 +210,10 @@ class ExtendedValidationInfo {
void setAllowNonResilientAccess(bool val) {
Bits.AllowNonResilientAccess = val;
}
bool serializePackageEnabled() const { return Bits.SerializePackageEnabled; }
void setSerializePackageEnabled(bool val) {
Bits.SerializePackageEnabled = val;
}
bool isAllowModuleWithCompilerErrorsEnabled() {
return Bits.IsAllowModuleWithCompilerErrorsEnabled;
}
Expand Down
1 change: 1 addition & 0 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
Bits.ModuleDecl.ObjCNameLookupCachePopulated = 0;
Bits.ModuleDecl.HasCxxInteroperability = 0;
Bits.ModuleDecl.AllowNonResilientAccess = 0;
Bits.ModuleDecl.SerializePackageEnabled = 0;
}

void ModuleDecl::setIsSystemModule(bool flag) {
Expand Down
2 changes: 2 additions & 0 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,8 @@ ModuleDecl *CompilerInstance::getMainModule() const {
MainModule->setHasCxxInteroperability();
if (Invocation.getLangOptions().AllowNonResilientAccess)
MainModule->setAllowNonResilientAccess();
if (Invocation.getSILOptions().EnableSerializePackage)
MainModule->setSerializePackageEnabled();

// Register the main module with the AST context.
Context->addLoadedModule(MainModule);
Expand Down
23 changes: 19 additions & 4 deletions lib/SIL/Verifier/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,28 @@ static bool isArchetypeValidInFunction(ArchetypeType *A, const SILFunction *F) {

namespace {

/// When resilience is bypassed, direct access is legal, but the decls are still
/// resilient.
/// When resilience is bypassed for debugging or package serialization is enabled,
/// direct access is legal, but the decls are still resilient.
template <typename DeclType>
bool checkResilience(DeclType *D, ModuleDecl *M,
ResilienceExpansion expansion) {
return !D->getModuleContext()->getBypassResilience() &&
D->isResilient(M, expansion);
auto refDeclModule = D->getModuleContext();
// Explicitly bypassed for debugging with `bypass-resilience-checks`
if (refDeclModule->getBypassResilience())
return false;

// If package serialization is enabled with `experimental-package-cmo`,
// decls can be serialized in a resiliently built module. In such case,
// a direct access should be allowed.
auto packageSerialized = expansion == ResilienceExpansion::Minimal &&
refDeclModule->isResilient() &&
refDeclModule->allowNonResilientAccess() &&
refDeclModule->serializePackageEnabled() &&
refDeclModule->inSamePackage(M);
if (packageSerialized)
return false;

return D->isResilient(M, expansion);
}

bool checkTypeABIAccessible(SILFunction const &F, SILType ty) {
Expand Down
5 changes: 5 additions & 0 deletions lib/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,11 @@ class ModuleFile
return Core->Bits.AllowNonResilientAccess;
}

/// Whether this module was built with -experimental-package-cmo.
bool serializePackageEnabled() const {
return Core->Bits.SerializePackageEnabled;
}

/// Whether this module is compiled with implicit dynamic.
bool isImplicitDynamicEnabled() const {
return Core->Bits.IsImplicitDynamicEnabled;
Expand Down
4 changes: 4 additions & 0 deletions lib/Serialization/ModuleFileSharedCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
case options_block::ALLOW_NON_RESILIENT_ACCESS:
extendedInfo.setAllowNonResilientAccess(true);
break;
case options_block::SERIALIZE_PACKAGE_ENABLED:
extendedInfo.setSerializePackageEnabled(true);
break;
default:
// Unknown options record, possibly for use by a future version of the
// module format.
Expand Down Expand Up @@ -1448,6 +1451,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
Bits.IsConcurrencyChecked = extInfo.isConcurrencyChecked();
Bits.HasCxxInteroperability = extInfo.hasCxxInteroperability();
Bits.AllowNonResilientAccess = extInfo.allowNonResilientAccess();
Bits.SerializePackageEnabled = extInfo.serializePackageEnabled();
MiscVersion = info.miscVersion;
ModuleABIName = extInfo.getModuleABIName();
ModulePackageName = extInfo.getModulePackageName();
Expand Down
3 changes: 3 additions & 0 deletions lib/Serialization/ModuleFileSharedCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@ class ModuleFileSharedCore {
/// Whether this module is built with -experimental-allow-non-resilient-access.
unsigned AllowNonResilientAccess : 1;

/// Whether this module is built with -experimental-package-cmo.
unsigned SerializePackageEnabled : 1;

// Explicitly pad out to the next word boundary.
unsigned : 3;
} Bits = {};
Expand Down
7 changes: 6 additions & 1 deletion lib/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t SWIFTMODULE_VERSION_MINOR = 871; // ~ for suppression
const uint16_t SWIFTMODULE_VERSION_MINOR = 872; // SerializePackageEnabled

/// A standard hash seed used for all string hashes in a serialized module.
///
Expand Down Expand Up @@ -941,6 +941,7 @@ namespace options_block {
PLUGIN_SEARCH_OPTION,
HAS_CXX_INTEROPERABILITY_ENABLED,
ALLOW_NON_RESILIENT_ACCESS,
SERIALIZE_PACKAGE_ENABLED,
};

using SDKPathLayout = BCRecordLayout<
Expand Down Expand Up @@ -1027,6 +1028,10 @@ namespace options_block {
using AllowNonResilientAccess = BCRecordLayout<
ALLOW_NON_RESILIENT_ACCESS
>;

using SerializePackageEnabled = BCRecordLayout<
SERIALIZE_PACKAGE_ENABLED
>;
}

/// The record types within the input block.
Expand Down
6 changes: 6 additions & 0 deletions lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,7 @@ void Serializer::writeBlockInfoBlock() {
BLOCK_RECORD(options_block, MODULE_EXPORT_AS_NAME);
BLOCK_RECORD(options_block, PLUGIN_SEARCH_OPTION);
BLOCK_RECORD(options_block, ALLOW_NON_RESILIENT_ACCESS);
BLOCK_RECORD(options_block, SERIALIZE_PACKAGE_ENABLED);

BLOCK(INPUT_BLOCK);
BLOCK_RECORD(input_block, IMPORTED_MODULE);
Expand Down Expand Up @@ -1092,6 +1093,11 @@ void Serializer::writeHeader() {
AllowNonResAcess.emit(ScratchRecord);
}

if (M->serializePackageEnabled()) {
options_block::SerializePackageEnabled SerializePkgEnabled(Out);
SerializePkgEnabled.emit(ScratchRecord);
}

if (allowCompilerErrors()) {
options_block::IsAllowModuleWithCompilerErrorsEnabledLayout
AllowErrors(Out);
Expand Down
2 changes: 2 additions & 0 deletions lib/Serialization/SerializedModuleLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,8 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
M.setIsBuiltFromInterface();
if (loadedModuleFile->allowNonResilientAccess())
M.setAllowNonResilientAccess();
if (loadedModuleFile->serializePackageEnabled())
M.setSerializePackageEnabled();
if (!loadedModuleFile->getModuleABIName().empty())
M.setABIName(Ctx.getIdentifier(loadedModuleFile->getModuleABIName()));
if (loadedModuleFile->isConcurrencyChecked())
Expand Down
Loading