@@ -227,7 +227,9 @@ namespace {
227227 DifferentiabilityWitnessesToEmit;
228228
229229 // / 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;
231233
232234 // / String storage for temporarily created strings which are referenced from
233235 // / the tables.
@@ -250,7 +252,9 @@ namespace {
250252 bool emitDeclarationsForOnoneSupport);
251253 void addReferencedSILFunction (const SILFunction *F,
252254 bool DeclOnly = false );
253- void processSILFunctionWorklist ();
255+ void addReferencedGlobalVariable (const SILGlobalVariable *gl);
256+
257+ void processWorklists ();
254258
255259 // / Helper function to update ListOfValues for MethodInst. Format:
256260 // / Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
@@ -340,7 +344,7 @@ void SILSerializer::addMandatorySILFunction(const SILFunction *F,
340344 // Function body should be serialized unless it is a KeepAsPublic function
341345 // (which is typically a pre-specialization).
342346 if (!emitDeclarationsForOnoneSupport)
343- Worklist .push_back (F);
347+ functionWorklist .push_back (F);
344348}
345349
346350void SILSerializer::addReferencedSILFunction (const SILFunction *F,
@@ -354,7 +358,7 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
354358 // serialize the body or just the declaration.
355359 if (shouldEmitFunctionBody (F)) {
356360 FuncsToEmit[F] = false ;
357- Worklist .push_back (F);
361+ functionWorklist .push_back (F);
358362 return ;
359363 }
360364
@@ -363,23 +367,35 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
363367 F->hasForeignBody ());
364368
365369 FuncsToEmit[F] = false ;
366- Worklist .push_back (F);
370+ functionWorklist .push_back (F);
367371 return ;
368372 }
369373
370374 // Ok, we just need to emit a declaration.
371375 FuncsToEmit[F] = true ;
372376}
373377
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+ }
379382
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 ());
383399}
384400
385401// / We enumerate all values in a SILFunction beforehand to correctly
@@ -1121,7 +1137,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
11211137 // Format: Name and type. Use SILOneOperandLayout.
11221138 const AllocGlobalInst *AGI = cast<AllocGlobalInst>(&SI);
11231139 auto *G = AGI->getReferencedGlobal ();
1124- GlobalsToEmit. insert (G);
1140+ addReferencedGlobalVariable (G);
11251141 SILOneOperandLayout::emitRecord (Out, ScratchRecord,
11261142 SILAbbrCodes[SILOneOperandLayout::Code],
11271143 (unsigned )SI.getKind (), 0 , 0 , 0 ,
@@ -1133,7 +1149,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
11331149 // Format: Name and type. Use SILOneOperandLayout.
11341150 const GlobalAccessInst *GI = cast<GlobalAccessInst>(&SI);
11351151 auto *G = GI->getReferencedGlobal ();
1136- GlobalsToEmit. insert (G);
1152+ addReferencedGlobalVariable (G);
11371153 SILOneOperandLayout::emitRecord (Out, ScratchRecord,
11381154 SILAbbrCodes[SILOneOperandLayout::Code],
11391155 (unsigned )SI.getKind (), 0 ,
@@ -2841,6 +2857,12 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28412857 writeSILDefaultWitnessTable (wt);
28422858 }
28432859
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+
28442866 // Emit only declarations if it is a module with pre-specializations.
28452867 // And only do it in optimized builds.
28462868 bool emitDeclarationsForOnoneSupport =
@@ -2860,7 +2882,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28602882 }
28612883
28622884 addMandatorySILFunction (&F, emitDeclarationsForOnoneSupport);
2863- processSILFunctionWorklist ();
2885+ processWorklists ();
28642886 }
28652887
28662888 // Write out differentiability witnesses.
@@ -2879,7 +2901,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28792901 // Process SIL functions referenced by differentiability witnesses.
28802902 // Note: this is necessary despite processing `FuncsToEmit` below because
28812903 // `Worklist` is processed separately.
2882- processSILFunctionWorklist ();
2904+ processWorklists ();
28832905
28842906 // Now write function declarations for every function we've
28852907 // emitted a reference to without emitting a function body for.
@@ -2893,16 +2915,8 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28932915 }
28942916 }
28952917
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" );
29062920}
29072921
29082922void SILSerializer::writeSILModule (const SILModule *SILMod) {
0 commit comments