@@ -221,7 +221,9 @@ namespace {
221
221
DifferentiabilityWitnessesToEmit;
222
222
223
223
// / Additional functions we might need to serialize.
224
- llvm::SmallVector<const SILFunction *, 16 > Worklist;
224
+ llvm::SmallVector<const SILFunction *, 16 > functionWorklist;
225
+
226
+ llvm::SmallVector<const SILGlobalVariable *, 16 > globalWorklist;
225
227
226
228
// / String storage for temporarily created strings which are referenced from
227
229
// / the tables.
@@ -244,7 +246,9 @@ namespace {
244
246
bool emitDeclarationsForOnoneSupport);
245
247
void addReferencedSILFunction (const SILFunction *F,
246
248
bool DeclOnly = false );
247
- void processSILFunctionWorklist ();
249
+ void addReferencedGlobalVariable (const SILGlobalVariable *gl);
250
+
251
+ void processWorklists ();
248
252
249
253
// / Helper function to update ListOfValues for MethodInst. Format:
250
254
// / Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
@@ -334,7 +338,7 @@ void SILSerializer::addMandatorySILFunction(const SILFunction *F,
334
338
// Function body should be serialized unless it is a KeepAsPublic function
335
339
// (which is typically a pre-specialization).
336
340
if (!emitDeclarationsForOnoneSupport)
337
- Worklist .push_back (F);
341
+ functionWorklist .push_back (F);
338
342
}
339
343
340
344
void SILSerializer::addReferencedSILFunction (const SILFunction *F,
@@ -348,7 +352,7 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
348
352
// serialize the body or just the declaration.
349
353
if (shouldEmitFunctionBody (F)) {
350
354
FuncsToEmit[F] = false ;
351
- Worklist .push_back (F);
355
+ functionWorklist .push_back (F);
352
356
return ;
353
357
}
354
358
@@ -357,23 +361,35 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
357
361
F->hasForeignBody ());
358
362
359
363
FuncsToEmit[F] = false ;
360
- Worklist .push_back (F);
364
+ functionWorklist .push_back (F);
361
365
return ;
362
366
}
363
367
364
368
// Ok, we just need to emit a declaration.
365
369
FuncsToEmit[F] = true ;
366
370
}
367
371
368
- void SILSerializer::processSILFunctionWorklist () {
369
- while (!Worklist.empty ()) {
370
- const SILFunction *F = Worklist.back ();
371
- Worklist.pop_back ();
372
- assert (F != nullptr );
372
+ void SILSerializer::addReferencedGlobalVariable (const SILGlobalVariable *gl) {
373
+ if (GlobalsToEmit.insert (gl).second )
374
+ globalWorklist.push_back (gl);
375
+ }
373
376
374
- assert (FuncsToEmit.count (F) > 0 );
375
- writeSILFunction (*F, FuncsToEmit[F]);
376
- }
377
+
378
+ void SILSerializer::processWorklists () {
379
+ do {
380
+ while (!functionWorklist.empty ()) {
381
+ const SILFunction *F = functionWorklist.pop_back_val ();
382
+ assert (F != nullptr );
383
+
384
+ assert (FuncsToEmit.count (F) > 0 );
385
+ writeSILFunction (*F, FuncsToEmit[F]);
386
+ }
387
+ while (!globalWorklist.empty ()) {
388
+ const SILGlobalVariable *gl = globalWorklist.pop_back_val ();
389
+ assert (GlobalsToEmit.count (gl) > 0 );
390
+ writeSILGlobalVar (*gl);
391
+ }
392
+ } while (!functionWorklist.empty ());
377
393
}
378
394
379
395
// / We enumerate all values in a SILFunction beforehand to correctly
@@ -1116,7 +1132,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
1116
1132
// Format: Name and type. Use SILOneOperandLayout.
1117
1133
const AllocGlobalInst *AGI = cast<AllocGlobalInst>(&SI);
1118
1134
auto *G = AGI->getReferencedGlobal ();
1119
- GlobalsToEmit. insert (G);
1135
+ addReferencedGlobalVariable (G);
1120
1136
SILOneOperandLayout::emitRecord (Out, ScratchRecord,
1121
1137
SILAbbrCodes[SILOneOperandLayout::Code],
1122
1138
(unsigned )SI.getKind (), 0 , 0 , 0 ,
@@ -1128,7 +1144,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
1128
1144
// Format: Name and type. Use SILOneOperandLayout.
1129
1145
const GlobalAccessInst *GI = cast<GlobalAccessInst>(&SI);
1130
1146
auto *G = GI->getReferencedGlobal ();
1131
- GlobalsToEmit. insert (G);
1147
+ addReferencedGlobalVariable (G);
1132
1148
SILOneOperandLayout::emitRecord (Out, ScratchRecord,
1133
1149
SILAbbrCodes[SILOneOperandLayout::Code],
1134
1150
(unsigned )SI.getKind (), 0 ,
@@ -2816,6 +2832,12 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2816
2832
writeSILDefaultWitnessTable (wt);
2817
2833
}
2818
2834
2835
+ // Add global variables that must be emitted to the list.
2836
+ for (const SILGlobalVariable &g : SILMod->getSILGlobals ()) {
2837
+ if (g.isSerialized () || ShouldSerializeAll)
2838
+ addReferencedGlobalVariable (&g);
2839
+ }
2840
+
2819
2841
// Emit only declarations if it is a module with pre-specializations.
2820
2842
// And only do it in optimized builds.
2821
2843
bool emitDeclarationsForOnoneSupport =
@@ -2835,7 +2857,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2835
2857
}
2836
2858
2837
2859
addMandatorySILFunction (&F, emitDeclarationsForOnoneSupport);
2838
- processSILFunctionWorklist ();
2860
+ processWorklists ();
2839
2861
}
2840
2862
2841
2863
// Write out differentiability witnesses.
@@ -2854,7 +2876,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2854
2876
// Process SIL functions referenced by differentiability witnesses.
2855
2877
// Note: this is necessary despite processing `FuncsToEmit` below because
2856
2878
// `Worklist` is processed separately.
2857
- processSILFunctionWorklist ();
2879
+ processWorklists ();
2858
2880
2859
2881
// Now write function declarations for every function we've
2860
2882
// emitted a reference to without emitting a function body for.
@@ -2868,16 +2890,8 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2868
2890
}
2869
2891
}
2870
2892
2871
- // Add global variables that must be emitted to the list.
2872
- for (const SILGlobalVariable &g : SILMod->getSILGlobals ())
2873
- if (g.isSerialized () || ShouldSerializeAll)
2874
- GlobalsToEmit.insert (&g);
2875
-
2876
- // Now write out all referenced global variables.
2877
- for (auto *g : GlobalsToEmit)
2878
- writeSILGlobalVar (*g);
2879
-
2880
- assert (Worklist.empty () && " Did not emit everything in worklist" );
2893
+ assert (functionWorklist.empty () && globalWorklist.empty () &&
2894
+ " Did not emit everything in worklists" );
2881
2895
}
2882
2896
2883
2897
void SILSerializer::writeSILModule (const SILModule *SILMod) {
0 commit comments