@@ -1174,6 +1174,26 @@ static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
11741174 return true ;
11751175}
11761176
1177+ // Eagerly emit global variables that are externally visible.
1178+ static bool isLazilyEmittedGlobalVariable (SILGlobalVariable &v, SILModule &m) {
1179+ // FIXME: Eagerly emit statically-initialized objects due to an issue I
1180+ // have yet to debug.
1181+ if (v.isInitializedObject ())
1182+ return false ;
1183+
1184+ if (v.isPossiblyUsedExternally ()) {
1185+ // Under the embedded linkage model, if it has a non-unique definition,
1186+ // treat it lazily.
1187+ if (v.hasNonUniqueDefinition () && !v.markedAsUsed ()) {
1188+ return true ;
1189+ }
1190+
1191+ return false ;
1192+ }
1193+
1194+ return true ;
1195+ }
1196+
11771197void IRGenerator::emitGlobalTopLevel (
11781198 const std::vector<std::string> &linkerDirectives) {
11791199 if (PrimaryIGM->getSILModule ().getOptions ().StopOptimizationAfterSerialization ) {
@@ -1207,6 +1227,9 @@ void IRGenerator::emitGlobalTopLevel(
12071227 createLinkerDirectiveVariable (*PrimaryIGM, directive);
12081228 }
12091229 for (SILGlobalVariable &v : PrimaryIGM->getSILModule ().getSILGlobals ()) {
1230+ if (isLazilyEmittedGlobalVariable (v, PrimaryIGM->getSILModule ()))
1231+ continue ;
1232+
12101233 Decl *decl = v.getDecl ();
12111234 CurrentIGMPtr IGM = getGenModule (decl ? decl->getDeclContext () : nullptr );
12121235 IGM->emitSILGlobalVariable (&v);
@@ -1368,6 +1391,7 @@ void IRGenerator::emitLazyDefinitions() {
13681391 !LazyExtensionDescriptors.empty () ||
13691392 !LazyFieldDescriptors.empty () ||
13701393 !LazyFunctionDefinitions.empty () || !LazyWitnessTables.empty () ||
1394+ !LazyGlobalVariables.empty () ||
13711395 !LazyCanonicalSpecializedMetadataAccessors.empty () ||
13721396 !LazyMetadataAccessors.empty () ||
13731397 !LazyClassMetadata.empty () ||
@@ -1456,6 +1480,13 @@ void IRGenerator::emitLazyDefinitions() {
14561480 IGM->emitSILFunction (f);
14571481 }
14581482
1483+ // Emit any lazy global variables we require.
1484+ while (!LazyGlobalVariables.empty ()) {
1485+ SILGlobalVariable *v = LazyGlobalVariables.pop_back_val ();
1486+ CurrentIGMPtr IGM = getGenModule (v);
1487+ IGM->emitSILGlobalVariable (v);
1488+ }
1489+
14591490 while (!LazyCanonicalSpecializedMetadataAccessors.empty ()) {
14601491 CanType theType =
14611492 LazyCanonicalSpecializedMetadataAccessors.pop_back_val ();
@@ -1529,6 +1560,26 @@ void IRGenerator::addLazyFunction(SILFunction *f) {
15291560 DefaultIGMForFunction.insert (std::make_pair (f, CurrentIGM));
15301561}
15311562
1563+ void IRGenerator::addLazyGlobalVariable (SILGlobalVariable *v) {
1564+ // Add it to the queue if it hasn't already been put there.
1565+ if (!LazilyEmittedGlobalVariables.insert (v).second )
1566+ return ;
1567+
1568+ assert (!FinishedEmittingLazyDefinitions);
1569+ LazyGlobalVariables.push_back (v);
1570+
1571+ if (auto decl = v->getDecl ()) {
1572+ if (decl->getDeclContext ()->getParentSourceFile ())
1573+ return ;
1574+ }
1575+
1576+ if (CurrentIGM == nullptr )
1577+ return ;
1578+
1579+ // Don't update the map if we already have an entry.
1580+ DefaultIGMForGlobalVariable.insert (std::make_pair (v, CurrentIGM));
1581+ }
1582+
15321583bool IRGenerator::hasLazyMetadata (TypeDecl *type) {
15331584 assert (isa<NominalTypeDecl>(type) ||
15341585 isa<OpaqueTypeDecl>(type));
@@ -2714,6 +2765,9 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
27142765 auto alignment =
27152766 Alignment (getClangASTContext ().getDeclAlign (clangDecl).getQuantity ());
27162767 return Address (addr, ti.getStorageType (), alignment);
2768+ } else if (!forDefinition &&
2769+ isLazilyEmittedGlobalVariable (*var, getSILModule ())) {
2770+ IRGen.addLazyGlobalVariable (var);
27172771 }
27182772
27192773 ResilienceExpansion expansion = getResilienceExpansionForLayout (var);
0 commit comments