@@ -124,12 +124,15 @@ class LoweredValue {
124124public:
125125 enum class Kind {
126126 // / 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.
127134 Address,
128135
129- // / This LoweredValue corresponds to a SIL address value owned by an
130- // / uninitialized fixed-size buffer.
131- UnallocatedAddressInBuffer,
132-
133136 // / The following kinds correspond to SIL non-address values.
134137 Value_First,
135138 // / A normal value, represented as an exploded array of llvm Values.
@@ -151,7 +154,7 @@ class LoweredValue {
151154 using ExplosionVector = SmallVector<llvm::Value *, 4 >;
152155
153156 union {
154- Address address;
157+ ContainedAddress address;
155158 struct {
156159 ExplosionVector values;
157160 } explosion;
@@ -160,14 +163,24 @@ class LoweredValue {
160163 };
161164
162165public:
166+
167+ // / Create an address value without a container (the usual case).
163168 LoweredValue (const Address &address)
164- : kind(Kind::Address), address(address)
169+ : kind(Kind::Address), address(Address(), address)
165170 {}
166171
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+ {}
168179
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)
171184 {}
172185
173186 LoweredValue (StaticFunction &&staticFunction)
@@ -189,8 +202,7 @@ class LoweredValue {
189202 {
190203 switch (kind) {
191204 case Kind::Address:
192- case Kind::UnallocatedAddressInBuffer:
193- ::new (&address) Address (std::move (lv.address ));
205+ ::new (&address) ContainedAddress (std::move (lv.address ));
194206 break ;
195207 case Kind::Explosion:
196208 ::new (&explosion.values ) ExplosionVector (std::move (lv.explosion .values ));
@@ -212,23 +224,24 @@ class LoweredValue {
212224 }
213225
214226 bool isAddress () const {
215- return kind == Kind::Address;
227+ return kind == Kind::Address && address. getAddress (). isValid () ;
216228 }
217229 bool isUnallocatedAddressInBuffer () const {
218- return kind == Kind::UnallocatedAddressInBuffer ;
230+ return kind == Kind::Address && !address. getAddress (). isValid () ;
219231 }
220232 bool isValue () const {
221233 return kind >= Kind::Value_First && kind <= Kind::Value_Last;
222234 }
223235
224236 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 () ;
227239 }
228240
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 ();
232245 }
233246
234247 void getExplosion (IRGenFunction &IGF, Explosion &ex) const ;
@@ -254,8 +267,7 @@ class LoweredValue {
254267 ~LoweredValue () {
255268 switch (kind) {
256269 case Kind::Address:
257- case Kind::UnallocatedAddressInBuffer:
258- address.~Address ();
270+ address.~ContainedAddress ();
259271 break ;
260272 case Kind::Explosion:
261273 explosion.values .~ExplosionVector ();
@@ -345,18 +357,28 @@ class IRGenSILFunction :
345357 setLoweredValue (v, address);
346358 }
347359
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) {
350368 assert ((v.getType ().isAddress () || v.getType ().isLocalStorage ()) &&
351369 " address for non-address value?!" );
352370 setLoweredValue (v,
353- LoweredValue (buffer, LoweredValue::UnallocatedAddressInBuffer ));
371+ LoweredValue (buffer, LoweredValue::ContainerForUnallocatedAddress ));
354372 }
355373
356- void overwriteLoweredAddress (SILValue v, const Address &address) {
374+ void overwriteAllocatedAddress (SILValue v, const Address &address) {
357375 assert ((v.getType ().isAddress () || v.getType ().isLocalStorage ()) &&
358376 " 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);
360382 }
361383
362384 void setAllocatedAddressForBuffer (SILValue v, const Address &allocedAddress);
@@ -466,6 +488,9 @@ class IRGenSILFunction :
466488 Address getLoweredAddress (SILValue v) {
467489 return getLoweredValue (v).getAddress ();
468490 }
491+ Address getLoweredContainerOfAddress (SILValue v) {
492+ return getLoweredValue (v).getContainerOfAddress ();
493+ }
469494 // / Add the unmanaged LLVM values lowered from a SIL value to an explosion.
470495 void getLoweredExplosion (SILValue v, Explosion &e) {
471496 getLoweredValue (v).getExplosion (*this , e);
@@ -781,7 +806,6 @@ llvm::Value *StaticFunction::getExplosionValue(IRGenFunction &IGF) const {
781806void LoweredValue::getExplosion (IRGenFunction &IGF, Explosion &ex) const {
782807 switch (kind) {
783808 case Kind::Address:
784- case Kind::UnallocatedAddressInBuffer:
785809 llvm_unreachable (" not a value" );
786810
787811 case Kind::Explosion:
@@ -802,7 +826,6 @@ void LoweredValue::getExplosion(IRGenFunction &IGF, Explosion &ex) const {
802826llvm::Value *LoweredValue::getSingletonExplosion (IRGenFunction &IGF) const {
803827 switch (kind) {
804828 case Kind::Address:
805- case Kind::UnallocatedAddressInBuffer:
806829 llvm_unreachable (" not a value" );
807830
808831 case Kind::Explosion:
@@ -1849,7 +1872,6 @@ static CallEmission getCallEmissionForLoweredValue(IRGenSILFunction &IGF,
18491872 }
18501873
18511874 case LoweredValue::Kind::Address:
1852- case LoweredValue::Kind::UnallocatedAddressInBuffer:
18531875 llvm_unreachable (" sil address isn't a valid callee" );
18541876 }
18551877
@@ -2015,7 +2037,6 @@ getPartialApplicationFunction(IRGenSILFunction &IGF,
20152037
20162038 switch (lv.kind ) {
20172039 case LoweredValue::Kind::Address:
2018- case LoweredValue::Kind::UnallocatedAddressInBuffer:
20192040 llvm_unreachable (" can't partially apply an address" );
20202041 case LoweredValue::Kind::ObjCMethod:
20212042 llvm_unreachable (" objc method partial application shouldn't get here" );
@@ -3255,7 +3276,6 @@ visitIsUniqueOrPinnedInst(swift::IsUniqueOrPinnedInst *i) {
32553276static bool tryDeferFixedSizeBufferInitialization (IRGenSILFunction &IGF,
32563277 const SILInstruction *allocInst,
32573278 const TypeInfo &ti,
3258- SILValue containerValue,
32593279 SILValue addressValue,
32603280 Address fixedSizeBuffer,
32613281 const llvm::Twine &name) {
@@ -3298,9 +3318,7 @@ static bool tryDeferFixedSizeBufferInitialization(IRGenSILFunction &IGF,
32983318 IGF.Builder .CreateLifetimeStart (fixedSizeBuffer,
32993319 getFixedBufferSize (IGF.IGM ));
33003320 }
3301- if (containerValue)
3302- IGF.setLoweredAddress (containerValue, fixedSizeBuffer);
3303- IGF.setLoweredUnallocatedAddressInBuffer (addressValue, fixedSizeBuffer);
3321+ IGF.setContainerOfUnallocatedAddress (addressValue, fixedSizeBuffer);
33043322 return true ;
33053323 }
33063324
@@ -3345,8 +3363,7 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
33453363 // operation, we can combine the allocation and initialization using an
33463364 // optimized value witness.
33473365 if (tryDeferFixedSizeBufferInitialization (*this , i, type,
3348- i->getContainerResult (),
3349- i->getAddressResult (),
3366+ SILValue (i, 0 ),
33503367 Address (),
33513368 dbgname))
33523369 return ;
@@ -3356,8 +3373,8 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
33563373 dbgname);
33573374
33583375 emitDebugInfoForAllocStack (i, type, addr.getAddress ().getAddress ());
3359- setLoweredAddress (i-> getContainerResult (), addr. getContainer ());
3360- setLoweredAddress (i-> getAddressResult () , addr. getAddress () );
3376+
3377+ setLoweredContainedAddress (i , addr);
33613378}
33623379
33633380void IRGenSILFunction::visitAllocRefInst (swift::AllocRefInst *i) {
@@ -3392,8 +3409,8 @@ void IRGenSILFunction::visitAllocRefDynamicInst(swift::AllocRefDynamicInst *i) {
33923409
33933410void IRGenSILFunction::visitDeallocStackInst (swift::DeallocStackInst *i) {
33943411 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 ,
33973414 i->getOperand ().getType ());
33983415}
33993416
@@ -4204,8 +4221,7 @@ void IRGenSILFunction::visitInitExistentialAddrInst(swift::InitExistentialAddrIn
42044221 auto &srcTI = getTypeInfo (i->getLoweredConcreteType ());
42054222
42064223 // 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, " " ))
42094225 return ;
42104226
42114227 // Compute basic layout information about the type. If we have a
@@ -4414,11 +4430,8 @@ void IRGenSILFunction::visitWitnessMethodInst(swift::WitnessMethodInst *i) {
44144430
44154431void IRGenSILFunction::setAllocatedAddressForBuffer (SILValue v,
44164432 const Address &allocedAddress) {
4417- assert (getLoweredValue (v).kind ==
4418- LoweredValue::Kind::UnallocatedAddressInBuffer &&
4419- " not an unallocated address" );
4433+ overwriteAllocatedAddress (v, allocedAddress);
44204434
4421- overwriteLoweredAddress (v, allocedAddress);
44224435 // Emit the debug info for the variable if any.
44234436 if (auto allocStack = dyn_cast<AllocStackInst>(v)) {
44244437 emitDebugInfoForAllocStack (allocStack, getTypeInfo (v.getType ()),
@@ -4435,7 +4448,7 @@ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) {
44354448 auto &loweredDest = getLoweredValue (i->getDest ());
44364449 if (loweredDest.isUnallocatedAddressInBuffer ()) {
44374450 isFixedBufferInitialization = true ;
4438- dest = loweredDest.getAddressOfUnallocatedBuffer ();
4451+ dest = loweredDest.getContainerOfAddress ();
44394452 } else {
44404453 isFixedBufferInitialization = false ;
44414454 dest = loweredDest.getAddress ();
0 commit comments