@@ -222,7 +222,9 @@ namespace {
222
222
DifferentiabilityWitnessesToEmit;
223
223
224
224
// / Additional functions we might need to serialize.
225
- llvm::SmallVector<const SILFunction *, 16 > Worklist;
225
+ llvm::SmallVector<const SILFunction *, 16 > functionWorklist;
226
+
227
+ llvm::SmallVector<const SILGlobalVariable *, 16 > globalWorklist;
226
228
227
229
// / String storage for temporarily created strings which are referenced from
228
230
// / the tables.
@@ -245,7 +247,9 @@ namespace {
245
247
bool emitDeclarationsForOnoneSupport);
246
248
void addReferencedSILFunction (const SILFunction *F,
247
249
bool DeclOnly = false );
248
- void processSILFunctionWorklist ();
250
+ void addReferencedGlobalVariable (const SILGlobalVariable *gl);
251
+
252
+ void processWorklists ();
249
253
250
254
// / Helper function to update ListOfValues for MethodInst. Format:
251
255
// / Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
@@ -335,7 +339,7 @@ void SILSerializer::addMandatorySILFunction(const SILFunction *F,
335
339
// Function body should be serialized unless it is a KeepAsPublic function
336
340
// (which is typically a pre-specialization).
337
341
if (!emitDeclarationsForOnoneSupport)
338
- Worklist .push_back (F);
342
+ functionWorklist .push_back (F);
339
343
}
340
344
341
345
void SILSerializer::addReferencedSILFunction (const SILFunction *F,
@@ -349,7 +353,7 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
349
353
// serialize the body or just the declaration.
350
354
if (shouldEmitFunctionBody (F)) {
351
355
FuncsToEmit[F] = false ;
352
- Worklist .push_back (F);
356
+ functionWorklist .push_back (F);
353
357
return ;
354
358
}
355
359
@@ -358,23 +362,35 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
358
362
F->hasForeignBody ());
359
363
360
364
FuncsToEmit[F] = false ;
361
- Worklist .push_back (F);
365
+ functionWorklist .push_back (F);
362
366
return ;
363
367
}
364
368
365
369
// Ok, we just need to emit a declaration.
366
370
FuncsToEmit[F] = true ;
367
371
}
368
372
369
- void SILSerializer::processSILFunctionWorklist () {
370
- while (!Worklist.empty ()) {
371
- const SILFunction *F = Worklist.back ();
372
- Worklist.pop_back ();
373
- assert (F != nullptr );
373
+ void SILSerializer::addReferencedGlobalVariable (const SILGlobalVariable *gl) {
374
+ if (GlobalsToEmit.insert (gl).second )
375
+ globalWorklist.push_back (gl);
376
+ }
374
377
375
- assert (FuncsToEmit.count (F) > 0 );
376
- writeSILFunction (*F, FuncsToEmit[F]);
377
- }
378
+
379
+ void SILSerializer::processWorklists () {
380
+ do {
381
+ while (!functionWorklist.empty ()) {
382
+ const SILFunction *F = functionWorklist.pop_back_val ();
383
+ assert (F != nullptr );
384
+
385
+ assert (FuncsToEmit.count (F) > 0 );
386
+ writeSILFunction (*F, FuncsToEmit[F]);
387
+ }
388
+ while (!globalWorklist.empty ()) {
389
+ const SILGlobalVariable *gl = globalWorklist.pop_back_val ();
390
+ assert (GlobalsToEmit.count (gl) > 0 );
391
+ writeSILGlobalVar (*gl);
392
+ }
393
+ } while (!functionWorklist.empty ());
378
394
}
379
395
380
396
// / 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 ,
@@ -2821,6 +2837,12 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2821
2837
writeSILDefaultWitnessTable (wt);
2822
2838
}
2823
2839
2840
+ // Add global variables that must be emitted to the list.
2841
+ for (const SILGlobalVariable &g : SILMod->getSILGlobals ()) {
2842
+ if (g.isSerialized () || ShouldSerializeAll)
2843
+ addReferencedGlobalVariable (&g);
2844
+ }
2845
+
2824
2846
// Emit only declarations if it is a module with pre-specializations.
2825
2847
// And only do it in optimized builds.
2826
2848
bool emitDeclarationsForOnoneSupport =
@@ -2840,7 +2862,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2840
2862
}
2841
2863
2842
2864
addMandatorySILFunction (&F, emitDeclarationsForOnoneSupport);
2843
- processSILFunctionWorklist ();
2865
+ processWorklists ();
2844
2866
}
2845
2867
2846
2868
// Write out differentiability witnesses.
@@ -2859,7 +2881,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2859
2881
// Process SIL functions referenced by differentiability witnesses.
2860
2882
// Note: this is necessary despite processing `FuncsToEmit` below because
2861
2883
// `Worklist` is processed separately.
2862
- processSILFunctionWorklist ();
2884
+ processWorklists ();
2863
2885
2864
2886
// Now write function declarations for every function we've
2865
2887
// emitted a reference to without emitting a function body for.
@@ -2873,16 +2895,8 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
2873
2895
}
2874
2896
}
2875
2897
2876
- // Add global variables that must be emitted to the list.
2877
- for (const SILGlobalVariable &g : SILMod->getSILGlobals ())
2878
- if (g.isSerialized () || ShouldSerializeAll)
2879
- GlobalsToEmit.insert (&g);
2880
-
2881
- // Now write out all referenced global variables.
2882
- for (auto *g : GlobalsToEmit)
2883
- writeSILGlobalVar (*g);
2884
-
2885
- assert (Worklist.empty () && " Did not emit everything in worklist" );
2898
+ assert (functionWorklist.empty () && globalWorklist.empty () &&
2899
+ " Did not emit everything in worklists" );
2886
2900
}
2887
2901
2888
2902
void SILSerializer::writeSILModule (const SILModule *SILMod) {
0 commit comments