@@ -59,6 +59,7 @@ OutliningMetadataCollector::OutliningMetadataCollector(
5959 : T(T), IGF(IGF), needsLayout(needsLayout), needsDeinit(needsDeinitTypes) {}
6060
6161void OutliningMetadataCollector::collectTypeMetadata (SILType ty) {
62+ assert (state != OutliningMetadataCollector::State::Kind::Collected);
6263 // If the type has no archetypes, we can emit it from scratch in the callee.
6364 if (!ty.hasArchetype ()) {
6465 return ;
@@ -89,10 +90,10 @@ void OutliningMetadataCollector::collectTypeMetadataForLayout(SILType ty) {
8990 // FIXME: does this force us to emit a more expensive metadata than we need
9091 // to?
9192 if (astType->isLegalFormalType ()) {
92- return collectFormalTypeMetadata (astType);
93+ return state. getCollecting (). addFormalTypeMetadata (astType);
9394 }
9495
95- collectRepresentationTypeMetadata (ty);
96+ state. getCollecting (). addRepresentationTypeMetadata (ty);
9697}
9798
9899void OutliningMetadataCollector::collectTypeMetadataForDeinit (SILType ty) {
@@ -106,92 +107,155 @@ void OutliningMetadataCollector::collectTypeMetadataForDeinit(SILType ty) {
106107 return ;
107108 assert (ty.isMoveOnly ());
108109
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);
123111}
124112
125- void OutliningMetadataCollector::collectFormalTypeMetadata (CanType ty) {
113+ void OutliningMetadataCollector::materializeFormalTypeMetadata (
114+ CanType ty, State::Collected::Elements &into) {
126115 // If the type has no archetypes, we can emit it from scratch in the callee.
127116 assert (ty->hasArchetype ());
128117
129118 auto key = LocalTypeDataKey (ty, LocalTypeDataKind::forFormalTypeMetadata ());
130- if (Values.count (key)) return ;
119+ if (into.Values .count (key))
120+ return ;
131121
132122 auto metadata = IGF.emitTypeMetadataRef (ty);
133- Values.insert ({key, metadata});
123+ into.Values .insert ({key, metadata});
124+
125+ assert (into.Values .count (key));
134126}
135127
136- void OutliningMetadataCollector::collectRepresentationTypeMetadata (SILType ty) {
128+ void OutliningMetadataCollector::materializeRepresentationTypeMetadata (
129+ SILType ty, State::Collected::Elements &into) {
137130 auto key = LocalTypeDataKey (
138131 ty.getASTType (), LocalTypeDataKind::forRepresentationTypeMetadata ());
139- if (Values.count (key))
132+ if (into. Values .count (key))
140133 return ;
141134
142135 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+ }
144180}
145181
146182void OutliningMetadataCollector::addPolymorphicArguments (
147183 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 ) {
150199 auto *value = pair.second ;
151200 args.push_back (value);
152201 }
153202 return ;
154203 }
155- for (auto &pair : Values) {
156- auto metadata = pair.second ;
157- assert (metadata->getType () == IGF.IGM .TypeMetadataPtrTy );
158- args.push_back (metadata);
159204 }
160205}
161206
162207void OutliningMetadataCollector::addPolymorphicParameterTypes (
163208 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 ) {
166223 auto *value = pair.second ;
167224 paramTys.push_back (value->getType ());
168225 }
169226 return ;
170227 }
171- for (auto &pair : Values) {
172- auto *metadata = pair.second ;
173- paramTys.push_back (metadata->getType ());
174228 }
175229}
176230
177231void OutliningMetadataCollector::bindPolymorphicParameters (
178232 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 ) {
181254 bindGenericRequirement (IGF, pair.first , params.claimNext (),
182- MetadataState::Complete, * Subs);
255+ MetadataState::Complete, environment. Subs );
183256 }
184257 return ;
185258 }
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));
195259 }
196260}
197261
@@ -231,6 +295,7 @@ bool TypeInfo::withWitnessableMetadataCollector(
231295 // Only collect if anything would be collected.
232296 collectMetadataForOutlining (collector, T);
233297 }
298+ collector.materialize ();
234299 invocation (collector);
235300 return true ;
236301 }
@@ -264,6 +329,7 @@ void TypeInfo::callOutlinedCopy(IRGenFunction &IGF, Address dest, Address src,
264329void OutliningMetadataCollector::emitCallToOutlinedCopy (
265330 Address dest, Address src, SILType T, const TypeInfo &ti,
266331 IsInitialization_t isInit, IsTake_t isTake) const {
332+ assert (hasFinished ());
267333 assert (!needsDeinit);
268334 llvm::SmallVector<llvm::Value *, 4 > args;
269335 args.push_back (IGF.Builder .CreateElementBitCast (src, ti.getStorageType ())
@@ -411,6 +477,7 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
411477 const OutliningMetadataCollector &collector,
412478 StringRef funcName,
413479 CopyAddrHelperGenerator generator) {
480+ assert (collector.hasFinished ());
414481 auto ptrTy = ti.getStorageType ()->getPointerTo ();
415482
416483 llvm::SmallVector<llvm::Type *, 4 > paramTys;
@@ -450,6 +517,7 @@ void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
450517
451518void OutliningMetadataCollector::emitCallToOutlinedDestroy (
452519 Address addr, SILType T, const TypeInfo &ti) const {
520+ assert (hasFinished ());
453521 assert (needsDeinit);
454522 llvm::SmallVector<llvm::Value *, 4 > args;
455523 args.push_back (IGF.Builder .CreateElementBitCast (addr, ti.getStorageType ())
@@ -528,11 +596,13 @@ void TypeInfo::callOutlinedRelease(IRGenFunction &IGF, Address addr, SILType T,
528596 OutliningMetadataCollector collector (T, IGF, LayoutIsNotNeeded,
529597 DeinitIsNeeded);
530598 collectMetadataForOutlining (collector, T);
599+ collector.materialize ();
531600 collector.emitCallToOutlinedRelease (addr, T, *this , atomicity);
532601}
533602
534603void OutliningMetadataCollector::emitCallToOutlinedRelease (
535604 Address addr, SILType T, const TypeInfo &ti, Atomicity atomicity) const {
605+ assert (hasFinished ());
536606 assert (!needsLayout);
537607 assert (needsDeinit);
538608 llvm::SmallVector<llvm::Value *, 4 > args;
0 commit comments