@@ -732,15 +732,16 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
732
732
733
733
emittedFunctions[constant] = F;
734
734
735
- if (!delayedFunctions.count (constant)) {
735
+ auto foundDelayed = delayedFunctions.find (constant);
736
+ if (foundDelayed == delayedFunctions.end ()) {
736
737
if (isEmittedOnDemand (M, constant)) {
737
- forcedFunctions.push_back (constant);
738
+ if (forcedFunctions.insert (constant).second )
739
+ pendingForcedFunctions.push_back (constant);
738
740
return F;
739
741
}
740
742
}
741
743
742
744
// If we delayed emitting this function previously, we need it now.
743
- auto foundDelayed = delayedFunctions.find (constant);
744
745
if (foundDelayed != delayedFunctions.end ()) {
745
746
// Move the function to its proper place within the module.
746
747
M.functions .remove (F);
@@ -752,7 +753,8 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
752
753
M.functions .insertAfter (insertAfter->getIterator (), F);
753
754
}
754
755
755
- forcedFunctions.push_back (constant);
756
+ if (forcedFunctions.insert (constant).second )
757
+ pendingForcedFunctions.push_back (constant);
756
758
delayedFunctions.erase (foundDelayed);
757
759
} else {
758
760
// We would have registered a delayed function as "last emitted" when we
@@ -770,7 +772,6 @@ bool SILGenModule::hasFunction(SILDeclRef constant) {
770
772
void SILGenModule::visitFuncDecl (FuncDecl *fd) { emitFunction (fd); }
771
773
772
774
void SILGenModule::emitFunctionDefinition (SILDeclRef constant, SILFunction *f) {
773
-
774
775
if (!f->empty ()) {
775
776
diagnose (constant.getAsRegularLocation (), diag::sil_function_redefinition,
776
777
f->getName ());
@@ -1150,24 +1151,28 @@ static void emitOrDelayFunction(SILGenModule &SGM, SILDeclRef constant) {
1150
1151
!constant.isDynamicallyReplaceable () &&
1151
1152
!isPossiblyUsedExternally (linkage, SGM.M .isWholeModule ());
1152
1153
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);
1167
1166
return ;
1168
1167
}
1169
1168
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;
1171
1176
}
1172
1177
1173
1178
void SILGenModule::preEmitFunction (SILDeclRef constant, SILFunction *F,
@@ -2222,13 +2227,13 @@ class SILGenModuleRAII {
2222
2227
// Emit any delayed definitions that were forced.
2223
2228
// Emitting these may in turn force more definitions, so we have to take
2224
2229
// care to keep pumping the queues.
2225
- while (!SGM.forcedFunctions .empty ()
2230
+ while (!SGM.pendingForcedFunctions .empty ()
2226
2231
|| !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 ();
2229
2234
SGM.emitFunctionDefinition (
2230
2235
front, SGM.getEmittedFunction (front, ForDefinition));
2231
- SGM.forcedFunctions .pop_front ();
2236
+ SGM.pendingForcedFunctions .pop_front ();
2232
2237
}
2233
2238
while (!SGM.pendingConformances .empty ()) {
2234
2239
SGM.getWitnessTable (SGM.pendingConformances .front ());
0 commit comments