@@ -59,6 +59,7 @@ OutliningMetadataCollector::OutliningMetadataCollector(
59
59
: T(T), IGF(IGF), needsLayout(needsLayout), needsDeinit(needsDeinitTypes) {}
60
60
61
61
void OutliningMetadataCollector::collectTypeMetadata (SILType ty) {
62
+ assert (state != OutliningMetadataCollector::State::Kind::Collected);
62
63
// If the type has no archetypes, we can emit it from scratch in the callee.
63
64
if (!ty.hasArchetype ()) {
64
65
return ;
@@ -89,10 +90,10 @@ void OutliningMetadataCollector::collectTypeMetadataForLayout(SILType ty) {
89
90
// FIXME: does this force us to emit a more expensive metadata than we need
90
91
// to?
91
92
if (astType->isLegalFormalType ()) {
92
- return collectFormalTypeMetadata (astType);
93
+ return state. getCollecting (). addFormalTypeMetadata (astType);
93
94
}
94
95
95
- collectRepresentationTypeMetadata (ty);
96
+ state. getCollecting (). addRepresentationTypeMetadata (ty);
96
97
}
97
98
98
99
void OutliningMetadataCollector::collectTypeMetadataForDeinit (SILType ty) {
@@ -106,92 +107,155 @@ void OutliningMetadataCollector::collectTypeMetadataForDeinit(SILType ty) {
106
107
return ;
107
108
assert (ty.isMoveOnly ());
108
109
109
- if (Requirements.size ())
110
- return ;
111
-
112
- auto pair = getTypeAndGenericSignatureForManglingOutlineFunction (T);
113
- auto sig = pair.second ;
114
- auto subs =
115
- digOutGenericEnvironment (T.getASTType ())->getForwardingSubstitutionMap ();
116
- Subs = subs;
117
- GenericTypeRequirements requirements (IGF.IGM , sig);
118
- for (auto requirement : requirements.getRequirements ()) {
119
- auto *value = emitGenericRequirementFromSubstitutions (
120
- IGF, requirement, MetadataState::Complete, subs);
121
- Requirements.insert ({requirement, value});
122
- }
110
+ state.getCollecting ().addValueTypeWithDeinit (ty);
123
111
}
124
112
125
- void OutliningMetadataCollector::collectFormalTypeMetadata (CanType ty) {
113
+ void OutliningMetadataCollector::materializeFormalTypeMetadata (
114
+ CanType ty, State::Collected::Elements &into) {
126
115
// If the type has no archetypes, we can emit it from scratch in the callee.
127
116
assert (ty->hasArchetype ());
128
117
129
118
auto key = LocalTypeDataKey (ty, LocalTypeDataKind::forFormalTypeMetadata ());
130
- if (Values.count (key)) return ;
119
+ if (into.Values .count (key))
120
+ return ;
131
121
132
122
auto metadata = IGF.emitTypeMetadataRef (ty);
133
- Values.insert ({key, metadata});
123
+ into.Values .insert ({key, metadata});
124
+
125
+ assert (into.Values .count (key));
134
126
}
135
127
136
- void OutliningMetadataCollector::collectRepresentationTypeMetadata (SILType ty) {
128
+ void OutliningMetadataCollector::materializeRepresentationTypeMetadata (
129
+ SILType ty, State::Collected::Elements &into) {
137
130
auto key = LocalTypeDataKey (
138
131
ty.getASTType (), LocalTypeDataKind::forRepresentationTypeMetadata ());
139
- if (Values.count (key))
132
+ if (into. Values .count (key))
140
133
return ;
141
134
142
135
auto metadata = IGF.emitTypeMetadataRefForLayout (ty);
143
- Values.insert ({key, metadata});
136
+ into.Values .insert ({key, metadata});
137
+ }
138
+
139
+ void OutliningMetadataCollector::materialize () {
140
+ if (state == State::Kind::Collected)
141
+ return ;
142
+
143
+ auto collection = std::move (state.getCollecting ());
144
+ switch (collection) {
145
+ case State::CollectionKind::Elements: {
146
+ auto &elements = collection.getElements ();
147
+ auto &collected = state.setCollectedElements ();
148
+ for (auto &element : elements.elements ) {
149
+ switch (element) {
150
+ case State::ElementKind::MetadataForFormal: {
151
+ auto ty = element.getFormalType ();
152
+ materializeFormalTypeMetadata (ty, /* into=*/ collected);
153
+ break ;
154
+ }
155
+ case State::ElementKind::MetadataForRepresentation: {
156
+ auto ty = element.getRepresentationType ();
157
+ materializeRepresentationTypeMetadata (ty, /* into=*/ collected);
158
+ break ;
159
+ }
160
+ }
161
+ }
162
+ return ;
163
+ }
164
+ case State::CollectionKind::Environment: {
165
+ auto pair = getTypeAndGenericSignatureForManglingOutlineFunction (T);
166
+ auto sig = pair.second ;
167
+ auto subs = digOutGenericEnvironment (T.getASTType ())
168
+ ->getForwardingSubstitutionMap ();
169
+ auto &collected = state.setCollectedEnvironment (subs);
170
+
171
+ GenericTypeRequirements requirements (IGF.IGM , sig);
172
+ for (auto requirement : requirements.getRequirements ()) {
173
+ auto *value = emitGenericRequirementFromSubstitutions (
174
+ IGF, requirement, MetadataState::Complete, subs);
175
+ collected.Requirements .insert ({requirement, value});
176
+ }
177
+ return ;
178
+ }
179
+ }
144
180
}
145
181
146
182
void OutliningMetadataCollector::addPolymorphicArguments (
147
183
SmallVectorImpl<llvm::Value *> &args) const {
148
- if (Subs) {
149
- for (auto &pair : Requirements) {
184
+ assert (hasFinished ());
185
+ if (state == State::Kind::Empty)
186
+ return ;
187
+ auto &collected = state.getCollected ();
188
+ switch (collected) {
189
+ case State::CollectionKind::Elements: {
190
+ for (auto &pair : collected.getElements ().Values ) {
191
+ auto metadata = pair.second ;
192
+ assert (metadata->getType () == IGF.IGM .TypeMetadataPtrTy );
193
+ args.push_back (metadata);
194
+ }
195
+ return ;
196
+ }
197
+ case State::CollectionKind::Environment: {
198
+ for (auto &pair : collected.getEnvironment ().Requirements ) {
150
199
auto *value = pair.second ;
151
200
args.push_back (value);
152
201
}
153
202
return ;
154
203
}
155
- for (auto &pair : Values) {
156
- auto metadata = pair.second ;
157
- assert (metadata->getType () == IGF.IGM .TypeMetadataPtrTy );
158
- args.push_back (metadata);
159
204
}
160
205
}
161
206
162
207
void OutliningMetadataCollector::addPolymorphicParameterTypes (
163
208
SmallVectorImpl<llvm::Type *> ¶mTys) const {
164
- if (Subs) {
165
- for (auto &pair : Requirements) {
209
+ assert (hasFinished ());
210
+ if (state == State::Kind::Empty)
211
+ return ;
212
+ auto &collected = state.getCollected ();
213
+ switch (collected) {
214
+ case State::CollectionKind::Elements: {
215
+ for (auto &pair : collected.getElements ().Values ) {
216
+ auto *metadata = pair.second ;
217
+ paramTys.push_back (metadata->getType ());
218
+ }
219
+ return ;
220
+ }
221
+ case State::CollectionKind::Environment: {
222
+ for (auto &pair : collected.getEnvironment ().Requirements ) {
166
223
auto *value = pair.second ;
167
224
paramTys.push_back (value->getType ());
168
225
}
169
226
return ;
170
227
}
171
- for (auto &pair : Values) {
172
- auto *metadata = pair.second ;
173
- paramTys.push_back (metadata->getType ());
174
228
}
175
229
}
176
230
177
231
void OutliningMetadataCollector::bindPolymorphicParameters (
178
232
IRGenFunction &IGF, Explosion ¶ms) const {
179
- if (Subs) {
180
- for (auto &pair : Requirements) {
233
+ assert (hasFinished ());
234
+ if (state == State::Kind::Empty)
235
+ return ;
236
+ auto &collected = state.getCollected ();
237
+ switch (collected) {
238
+ case State::CollectionKind::Elements: {
239
+ // Note that our parameter IGF intentionally shadows the IGF that this
240
+ // collector was built with.
241
+ for (auto &pair : collected.getElements ().Values ) {
242
+ llvm::Value *arg = params.claimNext ();
243
+
244
+ auto key = pair.first ;
245
+ assert (key.Kind .isAnyTypeMetadata ());
246
+ setTypeMetadataName (IGF.IGM , arg, key.Type );
247
+ IGF.setUnscopedLocalTypeData (key, MetadataResponse::forComplete (arg));
248
+ }
249
+ return ;
250
+ }
251
+ case State::CollectionKind::Environment: {
252
+ auto &environment = collected.getEnvironment ();
253
+ for (auto &pair : environment.Requirements ) {
181
254
bindGenericRequirement (IGF, pair.first , params.claimNext (),
182
- MetadataState::Complete, * Subs);
255
+ MetadataState::Complete, environment. Subs );
183
256
}
184
257
return ;
185
258
}
186
- // Note that our parameter IGF intentionally shadows the IGF that this
187
- // collector was built with.
188
- for (auto &pair : Values) {
189
- llvm::Value *arg = params.claimNext ();
190
-
191
- auto key = pair.first ;
192
- assert (key.Kind .isAnyTypeMetadata ());
193
- setTypeMetadataName (IGF.IGM , arg, key.Type );
194
- IGF.setUnscopedLocalTypeData (key, MetadataResponse::forComplete (arg));
195
259
}
196
260
}
197
261
@@ -231,6 +295,7 @@ bool TypeInfo::withWitnessableMetadataCollector(
231
295
// Only collect if anything would be collected.
232
296
collectMetadataForOutlining (collector, T);
233
297
}
298
+ collector.materialize ();
234
299
invocation (collector);
235
300
return true ;
236
301
}
@@ -264,6 +329,7 @@ void TypeInfo::callOutlinedCopy(IRGenFunction &IGF, Address dest, Address src,
264
329
void OutliningMetadataCollector::emitCallToOutlinedCopy (
265
330
Address dest, Address src, SILType T, const TypeInfo &ti,
266
331
IsInitialization_t isInit, IsTake_t isTake) const {
332
+ assert (hasFinished ());
267
333
assert (!needsDeinit);
268
334
llvm::SmallVector<llvm::Value *, 4 > args;
269
335
args.push_back (IGF.Builder .CreateElementBitCast (src, ti.getStorageType ())
@@ -411,6 +477,7 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
411
477
const OutliningMetadataCollector &collector,
412
478
StringRef funcName,
413
479
CopyAddrHelperGenerator generator) {
480
+ assert (collector.hasFinished ());
414
481
auto ptrTy = ti.getStorageType ()->getPointerTo ();
415
482
416
483
llvm::SmallVector<llvm::Type *, 4 > paramTys;
@@ -450,6 +517,7 @@ void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
450
517
451
518
void OutliningMetadataCollector::emitCallToOutlinedDestroy (
452
519
Address addr, SILType T, const TypeInfo &ti) const {
520
+ assert (hasFinished ());
453
521
assert (needsDeinit);
454
522
llvm::SmallVector<llvm::Value *, 4 > args;
455
523
args.push_back (IGF.Builder .CreateElementBitCast (addr, ti.getStorageType ())
@@ -528,11 +596,13 @@ void TypeInfo::callOutlinedRelease(IRGenFunction &IGF, Address addr, SILType T,
528
596
OutliningMetadataCollector collector (T, IGF, LayoutIsNotNeeded,
529
597
DeinitIsNeeded);
530
598
collectMetadataForOutlining (collector, T);
599
+ collector.materialize ();
531
600
collector.emitCallToOutlinedRelease (addr, T, *this , atomicity);
532
601
}
533
602
534
603
void OutliningMetadataCollector::emitCallToOutlinedRelease (
535
604
Address addr, SILType T, const TypeInfo &ti, Atomicity atomicity) const {
605
+ assert (hasFinished ());
536
606
assert (!needsLayout);
537
607
assert (needsDeinit);
538
608
llvm::SmallVector<llvm::Value *, 4 > args;
0 commit comments