@@ -1174,6 +1174,26 @@ static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
1174
1174
return true ;
1175
1175
}
1176
1176
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
+
1177
1197
void IRGenerator::emitGlobalTopLevel (
1178
1198
const std::vector<std::string> &linkerDirectives) {
1179
1199
if (PrimaryIGM->getSILModule ().getOptions ().StopOptimizationAfterSerialization ) {
@@ -1207,6 +1227,9 @@ void IRGenerator::emitGlobalTopLevel(
1207
1227
createLinkerDirectiveVariable (*PrimaryIGM, directive);
1208
1228
}
1209
1229
for (SILGlobalVariable &v : PrimaryIGM->getSILModule ().getSILGlobals ()) {
1230
+ if (isLazilyEmittedGlobalVariable (v, PrimaryIGM->getSILModule ()))
1231
+ continue ;
1232
+
1210
1233
Decl *decl = v.getDecl ();
1211
1234
CurrentIGMPtr IGM = getGenModule (decl ? decl->getDeclContext () : nullptr );
1212
1235
IGM->emitSILGlobalVariable (&v);
@@ -1368,6 +1391,7 @@ void IRGenerator::emitLazyDefinitions() {
1368
1391
!LazyExtensionDescriptors.empty () ||
1369
1392
!LazyFieldDescriptors.empty () ||
1370
1393
!LazyFunctionDefinitions.empty () || !LazyWitnessTables.empty () ||
1394
+ !LazyGlobalVariables.empty () ||
1371
1395
!LazyCanonicalSpecializedMetadataAccessors.empty () ||
1372
1396
!LazyMetadataAccessors.empty () ||
1373
1397
!LazyClassMetadata.empty () ||
@@ -1456,6 +1480,13 @@ void IRGenerator::emitLazyDefinitions() {
1456
1480
IGM->emitSILFunction (f);
1457
1481
}
1458
1482
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
+
1459
1490
while (!LazyCanonicalSpecializedMetadataAccessors.empty ()) {
1460
1491
CanType theType =
1461
1492
LazyCanonicalSpecializedMetadataAccessors.pop_back_val ();
@@ -1529,6 +1560,26 @@ void IRGenerator::addLazyFunction(SILFunction *f) {
1529
1560
DefaultIGMForFunction.insert (std::make_pair (f, CurrentIGM));
1530
1561
}
1531
1562
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
+
1532
1583
bool IRGenerator::hasLazyMetadata (TypeDecl *type) {
1533
1584
assert (isa<NominalTypeDecl>(type) ||
1534
1585
isa<OpaqueTypeDecl>(type));
@@ -2714,6 +2765,9 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
2714
2765
auto alignment =
2715
2766
Alignment (getClangASTContext ().getDeclAlign (clangDecl).getQuantity ());
2716
2767
return Address (addr, ti.getStorageType (), alignment);
2768
+ } else if (!forDefinition &&
2769
+ isLazilyEmittedGlobalVariable (*var, getSILModule ())) {
2770
+ IRGen.addLazyGlobalVariable (var);
2717
2771
}
2718
2772
2719
2773
ResilienceExpansion expansion = getResilienceExpansionForLayout (var);
0 commit comments