@@ -227,7 +227,9 @@ namespace {
227
227
DifferentiabilityWitnessesToEmit;
228
228
229
229
// / Additional functions we might need to serialize.
230
- llvm::SmallVector<const SILFunction *, 16 > Worklist;
230
+ llvm::SmallVector<const SILFunction *, 16 > functionWorklist;
231
+
232
+ llvm::SmallVector<const SILGlobalVariable *, 16 > globalWorklist;
231
233
232
234
// / String storage for temporarily created strings which are referenced from
233
235
// / the tables.
@@ -250,7 +252,9 @@ namespace {
250
252
bool emitDeclarationsForOnoneSupport);
251
253
void addReferencedSILFunction (const SILFunction *F,
252
254
bool DeclOnly = false );
253
- void processSILFunctionWorklist ();
255
+ void addReferencedGlobalVariable (const SILGlobalVariable *gl);
256
+
257
+ void processWorklists ();
254
258
255
259
// / Helper function to update ListOfValues for MethodInst. Format:
256
260
// / Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
@@ -340,7 +344,7 @@ void SILSerializer::addMandatorySILFunction(const SILFunction *F,
340
344
// Function body should be serialized unless it is a KeepAsPublic function
341
345
// (which is typically a pre-specialization).
342
346
if (!emitDeclarationsForOnoneSupport)
343
- Worklist .push_back (F);
347
+ functionWorklist .push_back (F);
344
348
}
345
349
346
350
void SILSerializer::addReferencedSILFunction (const SILFunction *F,
@@ -354,7 +358,7 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
354
358
// serialize the body or just the declaration.
355
359
if (shouldEmitFunctionBody (F)) {
356
360
FuncsToEmit[F] = false ;
357
- Worklist .push_back (F);
361
+ functionWorklist .push_back (F);
358
362
return ;
359
363
}
360
364
@@ -363,23 +367,35 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
363
367
F->hasForeignBody ());
364
368
365
369
FuncsToEmit[F] = false ;
366
- Worklist .push_back (F);
370
+ functionWorklist .push_back (F);
367
371
return ;
368
372
}
369
373
370
374
// Ok, we just need to emit a declaration.
371
375
FuncsToEmit[F] = true ;
372
376
}
373
377
374
- void SILSerializer::processSILFunctionWorklist () {
375
- while (!Worklist.empty ()) {
376
- const SILFunction *F = Worklist.back ();
377
- Worklist.pop_back ();
378
- assert (F != nullptr );
378
+ void SILSerializer::addReferencedGlobalVariable (const SILGlobalVariable *gl) {
379
+ if (GlobalsToEmit.insert (gl).second )
380
+ globalWorklist.push_back (gl);
381
+ }
379
382
380
- assert (FuncsToEmit.count (F) > 0 );
381
- writeSILFunction (*F, FuncsToEmit[F]);
382
- }
383
+
384
+ void SILSerializer::processWorklists () {
385
+ do {
386
+ while (!functionWorklist.empty ()) {
387
+ const SILFunction *F = functionWorklist.pop_back_val ();
388
+ assert (F != nullptr );
389
+
390
+ assert (FuncsToEmit.count (F) > 0 );
391
+ writeSILFunction (*F, FuncsToEmit[F]);
392
+ }
393
+ while (!globalWorklist.empty ()) {
394
+ const SILGlobalVariable *gl = globalWorklist.pop_back_val ();
395
+ assert (GlobalsToEmit.count (gl) > 0 );
396
+ writeSILGlobalVar (*gl);
397
+ }
398
+ } while (!functionWorklist.empty ());
383
399
}
384
400
385
401
// / We enumerate all values in a SILFunction beforehand to correctly
@@ -1121,7 +1137,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
1121
1137
// Format: Name and type. Use SILOneOperandLayout.
1122
1138
const AllocGlobalInst *AGI = cast<AllocGlobalInst>(&SI);
1123
1139
auto *G = AGI->getReferencedGlobal ();
1124
- GlobalsToEmit. insert (G);
1140
+ addReferencedGlobalVariable (G);
1125
1141
SILOneOperandLayout::emitRecord (Out, ScratchRecord,
1126
1142
SILAbbrCodes[SILOneOperandLayout::Code],
1127
1143
(unsigned )SI.getKind (), 0 , 0 , 0 ,
@@ -1133,7 +1149,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
1133
1149
// Format: Name and type. Use SILOneOperandLayout.
1134
1150
const GlobalAccessInst *GI = cast<GlobalAccessInst>(&SI);
1135
1151
auto *G = GI->getReferencedGlobal ();
1136
- GlobalsToEmit. insert (G);
1152
+ addReferencedGlobalVariable (G);
1137
1153
SILOneOperandLayout::emitRecord (Out, ScratchRecord,
1138
1154
SILAbbrCodes[SILOneOperandLayout::Code],
1139
1155
(unsigned )SI.getKind (), 0 ,
@@ -2841,6 +2857,12 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2841
2857
writeSILDefaultWitnessTable (wt);
2842
2858
}
2843
2859
2860
+ // Add global variables that must be emitted to the list.
2861
+ for (const SILGlobalVariable &g : SILMod->getSILGlobals ()) {
2862
+ if (g.isSerialized () || ShouldSerializeAll)
2863
+ addReferencedGlobalVariable (&g);
2864
+ }
2865
+
2844
2866
// Emit only declarations if it is a module with pre-specializations.
2845
2867
// And only do it in optimized builds.
2846
2868
bool emitDeclarationsForOnoneSupport =
@@ -2860,7 +2882,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2860
2882
}
2861
2883
2862
2884
addMandatorySILFunction (&F, emitDeclarationsForOnoneSupport);
2863
- processSILFunctionWorklist ();
2885
+ processWorklists ();
2864
2886
}
2865
2887
2866
2888
// Write out differentiability witnesses.
@@ -2879,7 +2901,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2879
2901
// Process SIL functions referenced by differentiability witnesses.
2880
2902
// Note: this is necessary despite processing `FuncsToEmit` below because
2881
2903
// `Worklist` is processed separately.
2882
- processSILFunctionWorklist ();
2904
+ processWorklists ();
2883
2905
2884
2906
// Now write function declarations for every function we've
2885
2907
// emitted a reference to without emitting a function body for.
@@ -2893,16 +2915,8 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2893
2915
}
2894
2916
}
2895
2917
2896
- // Add global variables that must be emitted to the list.
2897
- for (const SILGlobalVariable &g : SILMod->getSILGlobals ())
2898
- if (g.isSerialized () || ShouldSerializeAll)
2899
- GlobalsToEmit.insert (&g);
2900
-
2901
- // Now write out all referenced global variables.
2902
- for (auto *g : GlobalsToEmit)
2903
- writeSILGlobalVar (*g);
2904
-
2905
- assert (Worklist.empty () && " Did not emit everything in worklist" );
2918
+ assert (functionWorklist.empty () && globalWorklist.empty () &&
2919
+ " Did not emit everything in worklists" );
2906
2920
}
2907
2921
2908
2922
void SILSerializer::writeSILModule (const SILModule *SILMod) {
0 commit comments