Skip to content

Commit ba2af97

Browse files
authored
Merge pull request #84095 from DougGregor/embedded-deferred-codegen
2 parents de8c4cd + bee2369 commit ba2af97

File tree

17 files changed

+102
-26
lines changed

17 files changed

+102
-26
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
752752
HasAnyUnavailableDuringLoweringValues : 1
753753
);
754754

755-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
755+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
756756
/// If the module is compiled as static library.
757757
StaticLibrary : 1,
758758

@@ -821,7 +821,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
821821
SerializePackageEnabled : 1,
822822

823823
/// Whether this module has enabled strict memory safety checking.
824-
StrictMemorySafety : 1
824+
StrictMemorySafety : 1,
825+
826+
/// Whether this module uses deferred code generation in Embedded Swift.
827+
DeferredCodeGen : 1
825828
);
826829

827830
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,

include/swift/AST/Module.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ class ModuleDecl
818818
Bits.ModuleDecl.IsConcurrencyChecked = value;
819819
}
820820

821-
/// Whether this module has enable strict memory safety checking.
821+
/// Whether this module has enabled strict memory safety checking.
822822
bool strictMemorySafety() const {
823823
return Bits.ModuleDecl.StrictMemorySafety;
824824
}
@@ -827,6 +827,15 @@ class ModuleDecl
827827
Bits.ModuleDecl.StrictMemorySafety = value;
828828
}
829829

830+
/// Whether this module uses deferred code generation.
831+
bool deferredCodeGen() const {
832+
return Bits.ModuleDecl.DeferredCodeGen;
833+
}
834+
835+
void setDeferredCodeGen(bool value = true) {
836+
Bits.ModuleDecl.DeferredCodeGen = value;
837+
}
838+
830839
bool isObjCNameLookupCachePopulated() const {
831840
return Bits.ModuleDecl.ObjCNameLookupCachePopulated;
832841
}

include/swift/Basic/Features.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,12 @@ EXPERIMENTAL_FEATURE(KeyPathWithMethodMembers, false)
324324
// Whether to enable @_used and @_section attributes
325325
EXPERIMENTAL_FEATURE(SymbolLinkageMarkers, true)
326326

327+
// Whether to emit an Embedded Swift module with "deferred" code generation,
328+
// meaning that the only code that will be emitted into the object file is
329+
// code that was marked as "never emit into client". For everything else,
330+
// Swift still store the SIL and emit it into the client only when used.
331+
EXPERIMENTAL_FEATURE(DeferredCodeGen, true)
332+
327333
// Whether to compile scripts lazily in immediate mode
328334
EXPERIMENTAL_FEATURE(LazyImmediate, false)
329335

include/swift/Serialization/Validation.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class ExtendedValidationInfo {
147147
unsigned AllowNonResilientAccess: 1;
148148
unsigned SerializePackageEnabled: 1;
149149
unsigned StrictMemorySafety: 1;
150+
unsigned DeferredCodeGen: 1;
150151
} Bits;
151152

152153
public:
@@ -251,7 +252,14 @@ class ExtendedValidationInfo {
251252
void setStrictMemorySafety(bool val = true) {
252253
Bits.StrictMemorySafety = val;
253254
}
254-
255+
256+
bool deferredCodeGen() const {
257+
return Bits.DeferredCodeGen;
258+
}
259+
void setDeferredCodeGen(bool val = true) {
260+
Bits.DeferredCodeGen = val;
261+
}
262+
255263
bool hasCxxInteroperability() const { return Bits.HasCxxInteroperability; }
256264
void setHasCxxInteroperability(bool val) {
257265
Bits.HasCxxInteroperability = val;

lib/AST/FeatureSet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ UNINTERESTING_FEATURE(CodeItemMacros)
8484
UNINTERESTING_FEATURE(PreambleMacros)
8585
UNINTERESTING_FEATURE(TupleConformances)
8686
UNINTERESTING_FEATURE(SymbolLinkageMarkers)
87+
UNINTERESTING_FEATURE(DeferredCodeGen)
8788
UNINTERESTING_FEATURE(LazyImmediate)
8889
UNINTERESTING_FEATURE(MoveOnlyClasses)
8990
UNINTERESTING_FEATURE(NoImplicitCopy)

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
784784
Bits.ModuleDecl.AllowNonResilientAccess = 0;
785785
Bits.ModuleDecl.SerializePackageEnabled = 0;
786786
Bits.ModuleDecl.StrictMemorySafety = 0;
787+
Bits.ModuleDecl.DeferredCodeGen = 0;
787788

788789
// Populate the module's files.
789790
SmallVector<FileUnit *, 2> files;

lib/Frontend/Frontend.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,9 @@ ModuleDecl *CompilerInstance::getMainModule() const {
15111511
MainModule->setSerializePackageEnabled();
15121512
if (Invocation.getLangOptions().hasFeature(Feature::StrictMemorySafety))
15131513
MainModule->setStrictMemorySafety(true);
1514+
if (Invocation.getLangOptions().hasFeature(Feature::Embedded) &&
1515+
Invocation.getLangOptions().hasFeature(Feature::DeferredCodeGen))
1516+
MainModule->setDeferredCodeGen(true);
15141517

15151518
configureAvailabilityDomains(getASTContext(),
15161519
Invocation.getFrontendOptions(), MainModule);

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,10 +1115,20 @@ bool SILDeclRef::declHasNonUniqueDefinition(const ValueDecl *decl) {
11151115
if (decl->isNeverEmittedIntoClient())
11161116
return false;
11171117

1118-
// If the declaration is not from the main module, treat its definition as
1119-
// non-unique.
1118+
/// @_alwaysEmitIntoClient means that we have a non-unique definition.
1119+
if (decl->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>())
1120+
return true;
1121+
11201122
auto module = decl->getModuleContext();
11211123
auto &ctx = module->getASTContext();
1124+
1125+
/// With deferred code generation, declarations are emitted as late as
1126+
/// possible, so they must have non-unique definitions.
1127+
if (module->deferredCodeGen())
1128+
return true;
1129+
1130+
// If the declaration is not from the main module, treat its definition as
1131+
// non-unique.
11221132
return module != ctx.MainModule && ctx.MainModule;
11231133
}
11241134

lib/SIL/IR/SILFunction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,10 @@ bool SILFunction::hasNonUniqueDefinition() const {
558558
if (!getASTContext().LangOpts.hasFeature(Feature::Embedded))
559559
return false;
560560

561+
// If this function is the entrypoint, it is unique.
562+
if (getName() == getASTContext().getEntryPointFunctionName())
563+
return false;
564+
561565
// If this is for a declaration, ask it.
562566
if (auto declRef = getDeclRef()) {
563567
return declRef.hasNonUniqueDefinition();

lib/Serialization/ModuleFile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,9 @@ class ModuleFile
710710
/// \c true if this module was built with strict memory safety.
711711
bool strictMemorySafety() const { return Core->strictMemorySafety(); }
712712

713+
/// \c true if this module uses deferred code generation.
714+
bool deferredCodeGen() const { return Core->deferredCodeGen(); }
715+
713716
/// Associates this module file with the AST node representing it.
714717
///
715718
/// Checks that the file is compatible with the AST module it's being loaded

0 commit comments

Comments
 (0)