@@ -732,15 +732,16 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
732732
733733 emittedFunctions[constant] = F;
734734
735- if (!delayedFunctions.count (constant)) {
735+ auto foundDelayed = delayedFunctions.find (constant);
736+ if (foundDelayed == delayedFunctions.end ()) {
736737 if (isEmittedOnDemand (M, constant)) {
737- forcedFunctions.push_back (constant);
738+ if (forcedFunctions.insert (constant).second )
739+ pendingForcedFunctions.push_back (constant);
738740 return F;
739741 }
740742 }
741743
742744 // If we delayed emitting this function previously, we need it now.
743- auto foundDelayed = delayedFunctions.find (constant);
744745 if (foundDelayed != delayedFunctions.end ()) {
745746 // Move the function to its proper place within the module.
746747 M.functions .remove (F);
@@ -752,7 +753,8 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
752753 M.functions .insertAfter (insertAfter->getIterator (), F);
753754 }
754755
755- forcedFunctions.push_back (constant);
756+ if (forcedFunctions.insert (constant).second )
757+ pendingForcedFunctions.push_back (constant);
756758 delayedFunctions.erase (foundDelayed);
757759 } else {
758760 // We would have registered a delayed function as "last emitted" when we
@@ -770,7 +772,6 @@ bool SILGenModule::hasFunction(SILDeclRef constant) {
770772void SILGenModule::visitFuncDecl (FuncDecl *fd) { emitFunction (fd); }
771773
772774void SILGenModule::emitFunctionDefinition (SILDeclRef constant, SILFunction *f) {
773-
774775 if (!f->empty ()) {
775776 diagnose (constant.getAsRegularLocation (), diag::sil_function_redefinition,
776777 f->getName ());
@@ -1150,24 +1151,28 @@ static void emitOrDelayFunction(SILGenModule &SGM, SILDeclRef constant) {
11501151 !constant.isDynamicallyReplaceable () &&
11511152 !isPossiblyUsedExternally (linkage, SGM.M .isWholeModule ());
11521153
1153- // Avoid emitting a delayable definition if it hasn't already been referenced.
1154- SILFunction *f = nullptr ;
1155- if (mayDelay)
1156- f = SGM.getEmittedFunction (constant, ForDefinition);
1157- else
1158- f = SGM.getFunction (constant, ForDefinition);
1159-
1160- // If we don't want to emit now, remember how for later.
1161- if (!f) {
1162- SGM.delayedFunctions .insert ({constant, emitAfter});
1163- // Even though we didn't emit the function now, update the
1164- // lastEmittedFunction so that we preserve the original ordering that
1165- // the symbols would have been emitted in.
1166- SGM.lastEmittedFunction = constant;
1154+ if (!mayDelay) {
1155+ SGM.emitFunctionDefinition (constant, SGM.getFunction (constant, ForDefinition));
1156+ return ;
1157+ }
1158+
1159+ // If the function is already forced then it was previously delayed and then
1160+ // referenced. We don't need to emit or delay it again.
1161+ if (SGM.forcedFunctions .contains (constant))
1162+ return ;
1163+
1164+ if (auto *f = SGM.getEmittedFunction (constant, ForDefinition)) {
1165+ SGM.emitFunctionDefinition (constant, f);
11671166 return ;
11681167 }
11691168
1170- SGM.emitFunctionDefinition (constant, f);
1169+ // This is a delayable function so remember how to emit it in case it gets
1170+ // referenced later.
1171+ SGM.delayedFunctions .insert ({constant, emitAfter});
1172+ // Even though we didn't emit the function now, update the
1173+ // lastEmittedFunction so that we preserve the original ordering that
1174+ // the symbols would have been emitted in.
1175+ SGM.lastEmittedFunction = constant;
11711176}
11721177
11731178void SILGenModule::preEmitFunction (SILDeclRef constant, SILFunction *F,
@@ -2222,13 +2227,13 @@ class SILGenModuleRAII {
22222227 // Emit any delayed definitions that were forced.
22232228 // Emitting these may in turn force more definitions, so we have to take
22242229 // care to keep pumping the queues.
2225- while (!SGM.forcedFunctions .empty ()
2230+ while (!SGM.pendingForcedFunctions .empty ()
22262231 || !SGM.pendingConformances .empty ()) {
2227- while (!SGM.forcedFunctions .empty ()) {
2228- auto &front = SGM.forcedFunctions .front ();
2232+ while (!SGM.pendingForcedFunctions .empty ()) {
2233+ auto &front = SGM.pendingForcedFunctions .front ();
22292234 SGM.emitFunctionDefinition (
22302235 front, SGM.getEmittedFunction (front, ForDefinition));
2231- SGM.forcedFunctions .pop_front ();
2236+ SGM.pendingForcedFunctions .pop_front ();
22322237 }
22332238 while (!SGM.pendingConformances .empty ()) {
22342239 SGM.getWitnessTable (SGM.pendingConformances .front ());
0 commit comments