@@ -124,12 +124,15 @@ class LoweredValue {
124
124
public:
125
125
enum class Kind {
126
126
// / This LoweredValue corresponds to a SIL address value.
127
+ // / The LoweredValue of an alloc_stack keeps an owning container in
128
+ // / addition to the address of the allocated buffer.
129
+ // / Depending on the allocated type, the container may be equal to the
130
+ // / buffer itself (for types with known sizes) or it may be the address
131
+ // / of a fixed-size container which points to the heap-allocated buffer.
132
+ // / In this case the address-part may be null, which means that the buffer
133
+ // / is not allocated yet.
127
134
Address,
128
135
129
- // / This LoweredValue corresponds to a SIL address value owned by an
130
- // / uninitialized fixed-size buffer.
131
- UnallocatedAddressInBuffer,
132
-
133
136
// / The following kinds correspond to SIL non-address values.
134
137
Value_First,
135
138
// / A normal value, represented as an exploded array of llvm Values.
@@ -151,7 +154,7 @@ class LoweredValue {
151
154
using ExplosionVector = SmallVector<llvm::Value *, 4 >;
152
155
153
156
union {
154
- Address address;
157
+ ContainedAddress address;
155
158
struct {
156
159
ExplosionVector values;
157
160
} explosion;
@@ -160,14 +163,24 @@ class LoweredValue {
160
163
};
161
164
162
165
public:
166
+
167
+ // / Create an address value without a container (the usual case).
163
168
LoweredValue (const Address &address)
164
- : kind(Kind::Address), address(address)
169
+ : kind(Kind::Address), address(Address(), address)
165
170
{}
166
171
167
- enum UnallocatedAddressInBuffer_t { UnallocatedAddressInBuffer };
172
+ enum ContainerForUnallocatedAddress_t { ContainerForUnallocatedAddress };
173
+
174
+ // / Create an address value for an alloc_stack, consisting of a container and
175
+ // / a not yet allocated buffer.
176
+ LoweredValue (const Address &container, ContainerForUnallocatedAddress_t)
177
+ : kind(Kind::Address), address(container, Address())
178
+ {}
168
179
169
- LoweredValue (const Address &address, UnallocatedAddressInBuffer_t)
170
- : kind(Kind::UnallocatedAddressInBuffer), address(address)
180
+ // / Create an address value for an alloc_stack, consisting of a container and
181
+ // / the address of the allocated buffer.
182
+ LoweredValue (const ContainedAddress &address)
183
+ : kind(Kind::Address), address(address)
171
184
{}
172
185
173
186
LoweredValue (StaticFunction &&staticFunction)
@@ -189,8 +202,7 @@ class LoweredValue {
189
202
{
190
203
switch (kind) {
191
204
case Kind::Address:
192
- case Kind::UnallocatedAddressInBuffer:
193
- ::new (&address) Address (std::move (lv.address ));
205
+ ::new (&address) ContainedAddress (std::move (lv.address ));
194
206
break ;
195
207
case Kind::Explosion:
196
208
::new (&explosion.values ) ExplosionVector (std::move (lv.explosion .values ));
@@ -212,23 +224,24 @@ class LoweredValue {
212
224
}
213
225
214
226
bool isAddress () const {
215
- return kind == Kind::Address;
227
+ return kind == Kind::Address && address. getAddress (). isValid () ;
216
228
}
217
229
bool isUnallocatedAddressInBuffer () const {
218
- return kind == Kind::UnallocatedAddressInBuffer ;
230
+ return kind == Kind::Address && !address. getAddress (). isValid () ;
219
231
}
220
232
bool isValue () const {
221
233
return kind >= Kind::Value_First && kind <= Kind::Value_Last;
222
234
}
223
235
224
236
Address getAddress () const {
225
- assert (kind == Kind::Address && " not an allocated address" );
226
- return address;
237
+ assert (isAddress () && " not an allocated address" );
238
+ return address. getAddress () ;
227
239
}
228
240
229
- Address getAddressOfUnallocatedBuffer () const {
230
- assert (kind == Kind::UnallocatedAddressInBuffer);
231
- return address;
241
+ Address getContainerOfAddress () const {
242
+ assert (kind == Kind::Address);
243
+ assert (address.getContainer ().isValid () && " address has no container" );
244
+ return address.getContainer ();
232
245
}
233
246
234
247
void getExplosion (IRGenFunction &IGF, Explosion &ex) const ;
@@ -254,8 +267,7 @@ class LoweredValue {
254
267
~LoweredValue () {
255
268
switch (kind) {
256
269
case Kind::Address:
257
- case Kind::UnallocatedAddressInBuffer:
258
- address.~Address ();
270
+ address.~ContainedAddress ();
259
271
break ;
260
272
case Kind::Explosion:
261
273
explosion.values .~ExplosionVector ();
@@ -345,18 +357,28 @@ class IRGenSILFunction :
345
357
setLoweredValue (v, address);
346
358
}
347
359
348
- void setLoweredUnallocatedAddressInBuffer (SILValue v,
349
- const Address &buffer) {
360
+ void setLoweredContainedAddress (SILValue v, const ContainedAddress &address) {
361
+ assert ((v.getType ().isAddress () || v.getType ().isLocalStorage ()) &&
362
+ " address for non-address value?!" );
363
+ setLoweredValue (v, address);
364
+ }
365
+
366
+ void setContainerOfUnallocatedAddress (SILValue v,
367
+ const Address &buffer) {
350
368
assert ((v.getType ().isAddress () || v.getType ().isLocalStorage ()) &&
351
369
" address for non-address value?!" );
352
370
setLoweredValue (v,
353
- LoweredValue (buffer, LoweredValue::UnallocatedAddressInBuffer ));
371
+ LoweredValue (buffer, LoweredValue::ContainerForUnallocatedAddress ));
354
372
}
355
373
356
- void overwriteLoweredAddress (SILValue v, const Address &address) {
374
+ void overwriteAllocatedAddress (SILValue v, const Address &address) {
357
375
assert ((v.getType ().isAddress () || v.getType ().isLocalStorage ()) &&
358
376
" address for non-address value?!" );
359
- overwriteLoweredValue (v, address);
377
+ auto it = LoweredValues.find (v);
378
+ assert (it != LoweredValues.end () && " no existing entry for overwrite?" );
379
+ assert (it->second .isUnallocatedAddressInBuffer () &&
380
+ " not an unallocated address" );
381
+ it->second = ContainedAddress (it->second .getContainerOfAddress (), address);
360
382
}
361
383
362
384
void setAllocatedAddressForBuffer (SILValue v, const Address &allocedAddress);
@@ -466,6 +488,9 @@ class IRGenSILFunction :
466
488
Address getLoweredAddress (SILValue v) {
467
489
return getLoweredValue (v).getAddress ();
468
490
}
491
+ Address getLoweredContainerOfAddress (SILValue v) {
492
+ return getLoweredValue (v).getContainerOfAddress ();
493
+ }
469
494
// / Add the unmanaged LLVM values lowered from a SIL value to an explosion.
470
495
void getLoweredExplosion (SILValue v, Explosion &e) {
471
496
getLoweredValue (v).getExplosion (*this , e);
@@ -781,7 +806,6 @@ llvm::Value *StaticFunction::getExplosionValue(IRGenFunction &IGF) const {
781
806
void LoweredValue::getExplosion (IRGenFunction &IGF, Explosion &ex) const {
782
807
switch (kind) {
783
808
case Kind::Address:
784
- case Kind::UnallocatedAddressInBuffer:
785
809
llvm_unreachable (" not a value" );
786
810
787
811
case Kind::Explosion:
@@ -802,7 +826,6 @@ void LoweredValue::getExplosion(IRGenFunction &IGF, Explosion &ex) const {
802
826
llvm::Value *LoweredValue::getSingletonExplosion (IRGenFunction &IGF) const {
803
827
switch (kind) {
804
828
case Kind::Address:
805
- case Kind::UnallocatedAddressInBuffer:
806
829
llvm_unreachable (" not a value" );
807
830
808
831
case Kind::Explosion:
@@ -1849,7 +1872,6 @@ static CallEmission getCallEmissionForLoweredValue(IRGenSILFunction &IGF,
1849
1872
}
1850
1873
1851
1874
case LoweredValue::Kind::Address:
1852
- case LoweredValue::Kind::UnallocatedAddressInBuffer:
1853
1875
llvm_unreachable (" sil address isn't a valid callee" );
1854
1876
}
1855
1877
@@ -2015,7 +2037,6 @@ getPartialApplicationFunction(IRGenSILFunction &IGF,
2015
2037
2016
2038
switch (lv.kind ) {
2017
2039
case LoweredValue::Kind::Address:
2018
- case LoweredValue::Kind::UnallocatedAddressInBuffer:
2019
2040
llvm_unreachable (" can't partially apply an address" );
2020
2041
case LoweredValue::Kind::ObjCMethod:
2021
2042
llvm_unreachable (" objc method partial application shouldn't get here" );
@@ -3255,7 +3276,6 @@ visitIsUniqueOrPinnedInst(swift::IsUniqueOrPinnedInst *i) {
3255
3276
static bool tryDeferFixedSizeBufferInitialization (IRGenSILFunction &IGF,
3256
3277
const SILInstruction *allocInst,
3257
3278
const TypeInfo &ti,
3258
- SILValue containerValue,
3259
3279
SILValue addressValue,
3260
3280
Address fixedSizeBuffer,
3261
3281
const llvm::Twine &name) {
@@ -3298,9 +3318,7 @@ static bool tryDeferFixedSizeBufferInitialization(IRGenSILFunction &IGF,
3298
3318
IGF.Builder .CreateLifetimeStart (fixedSizeBuffer,
3299
3319
getFixedBufferSize (IGF.IGM ));
3300
3320
}
3301
- if (containerValue)
3302
- IGF.setLoweredAddress (containerValue, fixedSizeBuffer);
3303
- IGF.setLoweredUnallocatedAddressInBuffer (addressValue, fixedSizeBuffer);
3321
+ IGF.setContainerOfUnallocatedAddress (addressValue, fixedSizeBuffer);
3304
3322
return true ;
3305
3323
}
3306
3324
@@ -3345,8 +3363,7 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
3345
3363
// operation, we can combine the allocation and initialization using an
3346
3364
// optimized value witness.
3347
3365
if (tryDeferFixedSizeBufferInitialization (*this , i, type,
3348
- i->getContainerResult (),
3349
- i->getAddressResult (),
3366
+ SILValue (i, 0 ),
3350
3367
Address (),
3351
3368
dbgname))
3352
3369
return ;
@@ -3356,8 +3373,8 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
3356
3373
dbgname);
3357
3374
3358
3375
emitDebugInfoForAllocStack (i, type, addr.getAddress ().getAddress ());
3359
- setLoweredAddress (i-> getContainerResult (), addr. getContainer ());
3360
- setLoweredAddress (i-> getAddressResult () , addr. getAddress () );
3376
+
3377
+ setLoweredContainedAddress (i , addr);
3361
3378
}
3362
3379
3363
3380
void IRGenSILFunction::visitAllocRefInst (swift::AllocRefInst *i) {
@@ -3392,8 +3409,8 @@ void IRGenSILFunction::visitAllocRefDynamicInst(swift::AllocRefDynamicInst *i) {
3392
3409
3393
3410
void IRGenSILFunction::visitDeallocStackInst (swift::DeallocStackInst *i) {
3394
3411
const TypeInfo &type = getTypeInfo (i->getOperand ().getType ());
3395
- Address addr = getLoweredAddress (i->getOperand ());
3396
- type.deallocateStack (*this , addr ,
3412
+ Address container = getLoweredContainerOfAddress (i->getOperand ());
3413
+ type.deallocateStack (*this , container ,
3397
3414
i->getOperand ().getType ());
3398
3415
}
3399
3416
@@ -4204,8 +4221,7 @@ void IRGenSILFunction::visitInitExistentialAddrInst(swift::InitExistentialAddrIn
4204
4221
auto &srcTI = getTypeInfo (i->getLoweredConcreteType ());
4205
4222
4206
4223
// See if we can defer initialization of the buffer to a copy_addr into it.
4207
- if (tryDeferFixedSizeBufferInitialization (*this , i, srcTI, SILValue (), i,
4208
- buffer, " " ))
4224
+ if (tryDeferFixedSizeBufferInitialization (*this , i, srcTI, i, buffer, " " ))
4209
4225
return ;
4210
4226
4211
4227
// Compute basic layout information about the type. If we have a
@@ -4414,11 +4430,8 @@ void IRGenSILFunction::visitWitnessMethodInst(swift::WitnessMethodInst *i) {
4414
4430
4415
4431
void IRGenSILFunction::setAllocatedAddressForBuffer (SILValue v,
4416
4432
const Address &allocedAddress) {
4417
- assert (getLoweredValue (v).kind ==
4418
- LoweredValue::Kind::UnallocatedAddressInBuffer &&
4419
- " not an unallocated address" );
4433
+ overwriteAllocatedAddress (v, allocedAddress);
4420
4434
4421
- overwriteLoweredAddress (v, allocedAddress);
4422
4435
// Emit the debug info for the variable if any.
4423
4436
if (auto allocStack = dyn_cast<AllocStackInst>(v)) {
4424
4437
emitDebugInfoForAllocStack (allocStack, getTypeInfo (v.getType ()),
@@ -4435,7 +4448,7 @@ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) {
4435
4448
auto &loweredDest = getLoweredValue (i->getDest ());
4436
4449
if (loweredDest.isUnallocatedAddressInBuffer ()) {
4437
4450
isFixedBufferInitialization = true ;
4438
- dest = loweredDest.getAddressOfUnallocatedBuffer ();
4451
+ dest = loweredDest.getContainerOfAddress ();
4439
4452
} else {
4440
4453
isFixedBufferInitialization = false ;
4441
4454
dest = loweredDest.getAddress ();
0 commit comments