@@ -221,7 +221,9 @@ namespace {
221221 DifferentiabilityWitnessesToEmit;
222222
223223 // / 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;
225227
226228 // / String storage for temporarily created strings which are referenced from
227229 // / the tables.
@@ -244,7 +246,9 @@ namespace {
244246 bool emitDeclarationsForOnoneSupport);
245247 void addReferencedSILFunction (const SILFunction *F,
246248 bool DeclOnly = false );
247- void processSILFunctionWorklist ();
249+ void addReferencedGlobalVariable (const SILGlobalVariable *gl);
250+
251+ void processWorklists ();
248252
249253 // / Helper function to update ListOfValues for MethodInst. Format:
250254 // / Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
@@ -334,7 +338,7 @@ void SILSerializer::addMandatorySILFunction(const SILFunction *F,
334338 // Function body should be serialized unless it is a KeepAsPublic function
335339 // (which is typically a pre-specialization).
336340 if (!emitDeclarationsForOnoneSupport)
337- Worklist .push_back (F);
341+ functionWorklist .push_back (F);
338342}
339343
340344void SILSerializer::addReferencedSILFunction (const SILFunction *F,
@@ -348,7 +352,7 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
348352 // serialize the body or just the declaration.
349353 if (shouldEmitFunctionBody (F)) {
350354 FuncsToEmit[F] = false ;
351- Worklist .push_back (F);
355+ functionWorklist .push_back (F);
352356 return ;
353357 }
354358
@@ -357,23 +361,35 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F,
357361 F->hasForeignBody ());
358362
359363 FuncsToEmit[F] = false ;
360- Worklist .push_back (F);
364+ functionWorklist .push_back (F);
361365 return ;
362366 }
363367
364368 // Ok, we just need to emit a declaration.
365369 FuncsToEmit[F] = true ;
366370}
367371
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+ }
373376
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 ());
377393}
378394
379395// / We enumerate all values in a SILFunction beforehand to correctly
@@ -1116,7 +1132,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
11161132 // Format: Name and type. Use SILOneOperandLayout.
11171133 const AllocGlobalInst *AGI = cast<AllocGlobalInst>(&SI);
11181134 auto *G = AGI->getReferencedGlobal ();
1119- GlobalsToEmit. insert (G);
1135+ addReferencedGlobalVariable (G);
11201136 SILOneOperandLayout::emitRecord (Out, ScratchRecord,
11211137 SILAbbrCodes[SILOneOperandLayout::Code],
11221138 (unsigned )SI.getKind (), 0 , 0 , 0 ,
@@ -1128,7 +1144,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
11281144 // Format: Name and type. Use SILOneOperandLayout.
11291145 const GlobalAccessInst *GI = cast<GlobalAccessInst>(&SI);
11301146 auto *G = GI->getReferencedGlobal ();
1131- GlobalsToEmit. insert (G);
1147+ addReferencedGlobalVariable (G);
11321148 SILOneOperandLayout::emitRecord (Out, ScratchRecord,
11331149 SILAbbrCodes[SILOneOperandLayout::Code],
11341150 (unsigned )SI.getKind (), 0 ,
@@ -2816,6 +2832,12 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28162832 writeSILDefaultWitnessTable (wt);
28172833 }
28182834
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+
28192841 // Emit only declarations if it is a module with pre-specializations.
28202842 // And only do it in optimized builds.
28212843 bool emitDeclarationsForOnoneSupport =
@@ -2835,7 +2857,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28352857 }
28362858
28372859 addMandatorySILFunction (&F, emitDeclarationsForOnoneSupport);
2838- processSILFunctionWorklist ();
2860+ processWorklists ();
28392861 }
28402862
28412863 // Write out differentiability witnesses.
@@ -2854,7 +2876,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28542876 // Process SIL functions referenced by differentiability witnesses.
28552877 // Note: this is necessary despite processing `FuncsToEmit` below because
28562878 // `Worklist` is processed separately.
2857- processSILFunctionWorklist ();
2879+ processWorklists ();
28582880
28592881 // Now write function declarations for every function we've
28602882 // emitted a reference to without emitting a function body for.
@@ -2868,16 +2890,8 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
28682890 }
28692891 }
28702892
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" );
28812895}
28822896
28832897void SILSerializer::writeSILModule (const SILModule *SILMod) {
0 commit comments