@@ -174,24 +174,25 @@ class ExplodeTupleValue
174
174
175
175
enum class ImplodeKind { Unmanaged, Forward, Copy };
176
176
177
- template <ImplodeKind KIND>
177
+ template <ImplodeKind KIND>
178
178
class ImplodeLoadableTupleValue
179
- : public CanTypeVisitor<ImplodeLoadableTupleValue<KIND>,
180
- /* RetTy=*/ SILValue,
181
- /* Args...=*/ SILLocation>
182
- {
179
+ : public CanTypeVisitor<ImplodeLoadableTupleValue<KIND>,
180
+ /* RetTy=*/ ManagedValue,
181
+ /* Args...=*/ SILLocation> {
183
182
public:
184
183
ArrayRef<ManagedValue> values;
185
184
SILGenFunction &SGF;
186
185
187
- static SILValue getValue (SILGenFunction &SGF, ManagedValue v, SILLocation l) {
186
+ static ManagedValue getValue (SILGenFunction &SGF, ManagedValue v,
187
+ SILLocation l) {
188
188
switch (KIND) {
189
189
case ImplodeKind::Unmanaged:
190
- return v.getUnmanagedValue ();
190
+ assert (!v.hasCleanup ());
191
+ return v.unmanagedBorrow ();
191
192
case ImplodeKind::Forward:
192
- return v.ensurePlusOne (SGF, l). forward (SGF) ;
193
+ return v.ensurePlusOne (SGF, l);
193
194
case ImplodeKind::Copy:
194
- return v.copyUnmanaged (SGF, l). forward (SGF );
195
+ return v.copy (SGF, l);
195
196
}
196
197
197
198
llvm_unreachable (" Unhandled ImplodeKind in switch." );
@@ -202,14 +203,14 @@ class ImplodeLoadableTupleValue
202
203
: values(values), SGF(SGF)
203
204
{}
204
205
205
- SILValue visitType (CanType t, SILLocation l) {
206
- SILValue result = getValue (SGF, values[0 ], l);
206
+ ManagedValue visitType (CanType t, SILLocation l) {
207
+ ManagedValue result = getValue (SGF, values[0 ], l);
207
208
values = values.slice (1 );
208
209
return result;
209
210
}
210
211
211
- SILValue visitTupleType (CanTupleType t, SILLocation l) {
212
- SmallVector<SILValue , 4 > elts;
212
+ ManagedValue visitTupleType (CanTupleType t, SILLocation l) {
213
+ SmallVector<ManagedValue , 4 > elts;
213
214
for (auto fieldTy : t.getElementTypes ())
214
215
elts.push_back (this ->visit (fieldTy, l));
215
216
SILType ty = SGF.getLoweredLoadableType (t);
@@ -220,12 +221,11 @@ class ImplodeLoadableTupleValue
220
221
}
221
222
};
222
223
223
- template <ImplodeKind KIND>
224
+ template <ImplodeKind KIND>
224
225
class ImplodeAddressOnlyTuple
225
- : public CanTypeVisitor<ImplodeAddressOnlyTuple<KIND>,
226
- /* RetTy=*/ void ,
227
- /* Args...=*/ SILValue, SILLocation>
228
- {
226
+ : public CanTypeVisitor<ImplodeAddressOnlyTuple<KIND>,
227
+ /* RetTy=*/ void ,
228
+ /* Args...=*/ Initialization *, SILLocation> {
229
229
public:
230
230
ArrayRef<ManagedValue> values;
231
231
SILGenFunction &SGF;
@@ -235,7 +235,7 @@ class ImplodeAddressOnlyTuple
235
235
: values(values), SGF(SGF)
236
236
{}
237
237
238
- void visitType (CanType t, SILValue address, SILLocation l) {
238
+ void visitType (CanType t, Initialization * address, SILLocation l) {
239
239
ManagedValue v = values[0 ];
240
240
switch (KIND) {
241
241
case ImplodeKind::Unmanaged:
@@ -245,25 +245,30 @@ class ImplodeAddressOnlyTuple
245
245
// If a value is forwarded into, we require the value to be at +1. If the
246
246
// the value is already at +1, we just forward. Otherwise, we perform the
247
247
// copy.
248
- v.ensurePlusOne (SGF, l).forwardInto (SGF, l, address);
248
+ address->copyOrInitValueInto (SGF, l, v.ensurePlusOne (SGF, l),
249
+ true /* isInit*/ );
249
250
break ;
250
251
251
252
case ImplodeKind::Copy:
252
- v. copyInto (SGF, address, l );
253
+ address-> copyOrInitValueInto (SGF, l, v, false /* isInit */ );
253
254
break ;
254
255
}
256
+
257
+ address->finishInitialization (SGF);
255
258
values = values.slice (1 );
256
259
}
257
260
258
- void visitTupleType (CanTupleType t, SILValue address, SILLocation l) {
259
- for ( unsigned n = 0 , size = t-> getNumElements (); n < size; ++n) {
260
- CanType fieldCanTy = t. getElementType (n) ;
261
- SILType fieldTy = SGF. getLoweredType (fieldCanTy );
262
- SILValue fieldAddr = SGF. B . createTupleElementAddr (l,
263
- address, n,
264
- fieldTy. getAddressType () );
265
- this ->visit (fieldCanTy, fieldAddr , l);
261
+ void visitTupleType (CanTupleType t, Initialization * address, SILLocation l) {
262
+ assert (address-> canSplitIntoTupleElements ());
263
+ llvm::SmallVector<InitializationPtr, 4 > buf ;
264
+ auto bufResult = address-> splitIntoTupleElements (SGF, l, t, buf );
265
+
266
+ for ( unsigned i : range (t-> getNumElements ())) {
267
+ CanType fieldCanTy = t. getElementType (i );
268
+ this ->visit (fieldCanTy, bufResult[i]. get () , l);
266
269
}
270
+
271
+ address->finishInitialization (SGF);
267
272
}
268
273
269
274
~ImplodeAddressOnlyTuple () {
@@ -273,27 +278,27 @@ class ImplodeAddressOnlyTuple
273
278
274
279
} // end anonymous namespace
275
280
276
- template <ImplodeKind KIND>
277
- static SILValue implodeTupleValues (ArrayRef<ManagedValue> values,
278
- SILGenFunction &SGF,
279
- CanType tupleType, SILLocation l) {
281
+ template <ImplodeKind KIND>
282
+ static ManagedValue implodeTupleValues (ArrayRef<ManagedValue> values,
283
+ SILGenFunction &SGF, CanType tupleType ,
284
+ SILLocation l) {
280
285
// Non-tuples don't need to be imploded.
281
286
if (!isa<TupleType>(tupleType)) {
282
287
assert (values.size () == 1 && " exploded non-tuple value?!" );
283
288
return ImplodeLoadableTupleValue<KIND>::getValue (SGF, values[0 ], l);
284
289
}
285
290
286
- SILType loweredType = SGF.getLoweredType (tupleType);
291
+ const auto &TL = SGF.getTypeLowering (tupleType);
287
292
288
293
// To implode an address-only tuple, we need to create a buffer to hold the
289
294
// result tuple.
290
- if (loweredType.isAddressOnly (SGF.getModule ()) &&
291
- SGF.silConv .useLoweredAddresses ()) {
295
+ if (TL.isAddressOnly () && SGF.silConv .useLoweredAddresses ()) {
292
296
assert (KIND != ImplodeKind::Unmanaged &&
293
297
" address-only values are always managed!" );
294
- SILValue buffer = SGF.emitTemporaryAllocation (l, loweredType);
295
- ImplodeAddressOnlyTuple<KIND>(values, SGF).visit (tupleType, buffer, l);
296
- return buffer;
298
+ auto buffer = SGF.emitTemporary (l, TL);
299
+ ImplodeAddressOnlyTuple<KIND>(values, SGF)
300
+ .visit (tupleType, buffer.get (), l);
301
+ return buffer->getManagedAddress ();
297
302
}
298
303
299
304
// To implode loadable tuples, we just need to combine the elements with
@@ -363,13 +368,12 @@ static void copyOrInitValuesInto(Initialization *init,
363
368
// Otherwise, process this by turning the values corresponding to the tuple
364
369
// into a single value (through an implosion) and then binding that value to
365
370
// our initialization.
366
- SILValue scalar = implodeTupleValues<KIND>(values, SGF, type, loc);
367
-
371
+ ManagedValue scalar = implodeTupleValues<KIND>(values, SGF, type, loc);
372
+
368
373
// This will have just used up the first values in the list, pop them off.
369
374
values = values.slice (getRValueSize (type));
370
-
371
- init->copyOrInitValueInto (SGF, loc, ManagedValue::forUnmanaged (scalar),
372
- isInit);
375
+
376
+ init->copyOrInitValueInto (SGF, loc, scalar, isInit);
373
377
init->finishInitialization (SGF);
374
378
}
375
379
@@ -513,11 +517,10 @@ void RValue::addElement(SILGenFunction &SGF, ManagedValue element,
513
517
514
518
SILValue RValue::forwardAsSingleValue (SILGenFunction &SGF, SILLocation l) && {
515
519
assert (isComplete () && " rvalue is not complete" );
516
- // *NOTE* Inside implodeTupleValues, we copy our values if they are not at +1.
517
- SILValue result
518
- = implodeTupleValues<ImplodeKind::Forward>(values, SGF, type, l);
520
+ assert (!isUsed () && " rvalue was used?!" );
521
+ ManagedValue mv = std::move (*this ).getAsSingleValue (SGF, l);
519
522
makeUsed ();
520
- return result ;
523
+ return mv. forward (SGF) ;
521
524
}
522
525
523
526
SILValue RValue::forwardAsSingleStorageValue (SILGenFunction &SGF,
@@ -593,16 +596,16 @@ ManagedValue RValue::getAsSingleValue(SILGenFunction &SGF, SILLocation loc) && {
593
596
return result;
594
597
}
595
598
596
- // Forward into a single value, then install a cleanup on the resulting
597
- // imploded value if we have a +1 rvalue.
598
- CleanupCloner cloner (SGF, *this );
599
- return cloner.clone (std::move (*this ).forwardAsSingleValue (SGF, loc));
599
+ // *NOTE* Inside implodeTupleValues, we copy our values if they are not at +1.
600
+ return implodeTupleValues<ImplodeKind::Forward>(values, SGF, type, loc);
600
601
}
601
602
602
603
SILValue RValue::getUnmanagedSingleValue (SILGenFunction &SGF,
603
604
SILLocation l) const & {
604
605
assert (isComplete () && " rvalue is not complete" );
605
- return implodeTupleValues<ImplodeKind::Unmanaged>(values, SGF, type, l);
606
+ ManagedValue mv =
607
+ implodeTupleValues<ImplodeKind::Unmanaged>(values, SGF, type, l);
608
+ return mv.getValue ();
606
609
}
607
610
608
611
void RValue::forwardAll (SILGenFunction &SGF,
0 commit comments