3636#include " swift/SIL/SILType.h"
3737#include " swift/SIL/TypeLowering.h"
3838#include " llvm/ADT/SmallString.h"
39+ #include " llvm/Support/ErrorHandling.h"
3940#include < iterator>
4041
4142using namespace swift ;
@@ -698,20 +699,23 @@ class DeallocateLocalVariableAddressableBuffer : public Cleanup {
698699
699700 void emit (SILGenFunction &SGF, CleanupLocation l,
700701 ForUnwind_t forUnwind) override {
702+ auto addressableBuffer = SGF.getAddressableBufferInfo (vd);
703+ if (!addressableBuffer) {
704+ return ;
705+ }
701706 auto found = SGF.VarLocs .find (vd);
702707 if (found == SGF.VarLocs .end ()) {
703708 return ;
704709 }
705- auto &loc = found->second ;
706710
707- if (auto & state = loc. addressableBuffer . state ) {
711+ if (auto * state = addressableBuffer-> getState () ) {
708712 // The addressable buffer was forced, so clean it up now.
709713 deallocateAddressable (SGF, l, *state);
710714 } else {
711715 // Remember this insert location in case we need to force the addressable
712716 // buffer later.
713717 SILInstruction *marker = SGF.B .createTuple (l, {});
714- loc. addressableBuffer . cleanupPoints .emplace_back (marker);
718+ addressableBuffer-> cleanupPoints .emplace_back (marker);
715719 }
716720 }
717721
@@ -2253,7 +2257,7 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
22532257
22542258 auto value = foundVarLoc->second .value ;
22552259 auto access = foundVarLoc->second .access ;
2256- auto *state = foundVarLoc-> second . addressableBuffer . state . get ();
2260+ auto *state = getAddressableBufferInfo (decl)-> getState ();
22572261
22582262 SILType fullyAbstractedTy = getLoweredType (AbstractionPattern::getOpaque (),
22592263 decl->getTypeInContext ()->getRValueType ());
@@ -2291,9 +2295,26 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
22912295 SILValue reabstraction, allocStack, storeBorrow;
22922296 {
22932297 SavedInsertionPointRAII save (B);
2294- ASSERT (AddressableBuffers.find (decl) != AddressableBuffers.end ()
2295- && " local variable did not have an addressability scope set" );
2296- auto insertPoint = AddressableBuffers[decl].insertPoint ;
2298+ SILInstruction *insertPoint = nullptr ;
2299+ // Look through bindings that might alias the original addressable buffer
2300+ // (such as case block variables, which use an alias variable to represent the
2301+ // incoming value from all of the case label patterns).
2302+ VarDecl *origDecl = decl;
2303+ do {
2304+ auto bufferIter = AddressableBuffers.find (origDecl);
2305+ ASSERT (bufferIter != AddressableBuffers.end ()
2306+ && " local variable didn't have an addressability scope set" );
2307+
2308+ insertPoint = bufferIter->second .getInsertPoint ();
2309+ if (insertPoint) {
2310+ break ;
2311+ }
2312+
2313+ origDecl = bufferIter->second .getOriginalForAlias ();
2314+ ASSERT (origDecl && " no insert point or alias for addressable declaration!" );
2315+ } while (true );
2316+
2317+ assert (insertPoint && " didn't find an insertion point for the addressable buffer" );
22972318 B.setInsertionPoint (insertPoint);
22982319 auto allocStackTy = fullyAbstractedTy;
22992320 if (value->getType ().isMoveOnlyWrapped ()) {
@@ -2312,8 +2333,12 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
23122333 SavedInsertionPointRAII save (B);
23132334 if (isa<ParamDecl>(decl)) {
23142335 B.setInsertionPoint (allocStack->getNextInstruction ());
2336+ } else if (auto inst = value->getDefiningInstruction ()) {
2337+ B.setInsertionPoint (inst->getParent (), std::next (inst->getIterator ()));
2338+ } else if (auto arg = dyn_cast<SILArgument>(value)) {
2339+ B.setInsertionPoint (arg->getParent ()->begin ());
23152340 } else {
2316- B. setInsertionPoint ( value-> getNextInstruction () );
2341+ llvm_unreachable ( " unexpected value source! " );
23172342 }
23182343 auto declarationLoc = value->getDefiningInsertionPoint ()->getLoc ();
23192344
@@ -2333,17 +2358,15 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
23332358 }
23342359
23352360 // Record the addressable representation.
2336- auto &addressableBuffer = VarLocs[decl].addressableBuffer ;
2337- addressableBuffer.state
2338- = std::make_unique<VarLoc::AddressableBuffer::State>(reabstraction,
2339- allocStack,
2340- storeBorrow);
2341- auto *newState = addressableBuffer.state .get ();
2361+ auto *addressableBuffer = getAddressableBufferInfo (decl);
2362+ auto *newState
2363+ = new VarLoc::AddressableBuffer::State (reabstraction, allocStack, storeBorrow);
2364+ addressableBuffer->stateOrAlias = newState;
23422365
23432366 // Emit cleanups on any paths where we previously would have cleaned up
23442367 // the addressable representation if it had been forced earlier.
2345- decltype (addressableBuffer. cleanupPoints ) cleanupPoints;
2346- cleanupPoints.swap (addressableBuffer. cleanupPoints );
2368+ decltype (addressableBuffer-> cleanupPoints ) cleanupPoints;
2369+ cleanupPoints.swap (addressableBuffer-> cleanupPoints );
23472370
23482371 for (SILInstruction *cleanupPoint : cleanupPoints) {
23492372 SavedInsertionPointRAII insertCleanup (B, cleanupPoint);
@@ -2390,4 +2413,7 @@ SILGenFunction::VarLoc::AddressableBuffer::~AddressableBuffer() {
23902413 for (auto cleanupPoint : cleanupPoints) {
23912414 cleanupPoint->eraseFromParent ();
23922415 }
2416+ if (auto state = stateOrAlias.dyn_cast <State*>()) {
2417+ delete state;
2418+ }
23932419}
0 commit comments