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 ;
@@ -699,20 +700,23 @@ class DeallocateLocalVariableAddressableBuffer : public Cleanup {
699700
700701 void emit (SILGenFunction &SGF, CleanupLocation l,
701702 ForUnwind_t forUnwind) override {
703+ auto addressableBuffer = SGF.getAddressableBufferInfo (vd);
704+ if (!addressableBuffer) {
705+ return ;
706+ }
702707 auto found = SGF.VarLocs .find (vd);
703708 if (found == SGF.VarLocs .end ()) {
704709 return ;
705710 }
706- auto &loc = found->second ;
707711
708- if (auto & state = loc. addressableBuffer . state ) {
712+ if (auto * state = addressableBuffer-> getState () ) {
709713 // The addressable buffer was forced, so clean it up now.
710714 deallocateAddressable (SGF, l, *state);
711715 } else {
712716 // Remember this insert location in case we need to force the addressable
713717 // buffer later.
714718 SILInstruction *marker = SGF.B .createTuple (l, {});
715- loc. addressableBuffer . cleanupPoints .emplace_back (marker);
719+ addressableBuffer-> cleanupPoints .emplace_back (marker);
716720 }
717721 }
718722
@@ -2254,7 +2258,7 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
22542258
22552259 auto value = foundVarLoc->second .value ;
22562260 auto access = foundVarLoc->second .access ;
2257- auto *state = foundVarLoc-> second . addressableBuffer . state . get ();
2261+ auto *state = getAddressableBufferInfo (decl)-> getState ();
22582262
22592263 SILType fullyAbstractedTy = getLoweredType (AbstractionPattern::getOpaque (),
22602264 decl->getTypeInContext ()->getRValueType ());
@@ -2292,9 +2296,26 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
22922296 SILValue reabstraction, allocStack, storeBorrow;
22932297 {
22942298 SavedInsertionPointRAII save (B);
2295- ASSERT (AddressableBuffers.find (decl) != AddressableBuffers.end ()
2296- && " local variable did not have an addressability scope set" );
2297- auto insertPoint = AddressableBuffers[decl].insertPoint ;
2299+ SILInstruction *insertPoint = nullptr ;
2300+ // Look through bindings that might alias the original addressable buffer
2301+ // (such as case block variables, which use an alias variable to represent the
2302+ // incoming value from all of the case label patterns).
2303+ VarDecl *origDecl = decl;
2304+ do {
2305+ auto bufferIter = AddressableBuffers.find (origDecl);
2306+ ASSERT (bufferIter != AddressableBuffers.end ()
2307+ && " local variable didn't have an addressability scope set" );
2308+
2309+ insertPoint = bufferIter->second .getInsertPoint ();
2310+ if (insertPoint) {
2311+ break ;
2312+ }
2313+
2314+ origDecl = bufferIter->second .getOriginalForAlias ();
2315+ ASSERT (origDecl && " no insert point or alias for addressable declaration!" );
2316+ } while (true );
2317+
2318+ assert (insertPoint && " didn't find an insertion point for the addressable buffer" );
22982319 B.setInsertionPoint (insertPoint);
22992320 auto allocStackTy = fullyAbstractedTy;
23002321 if (value->getType ().isMoveOnlyWrapped ()) {
@@ -2313,8 +2334,12 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
23132334 SavedInsertionPointRAII save (B);
23142335 if (isa<ParamDecl>(decl)) {
23152336 B.setInsertionPoint (allocStack->getNextInstruction ());
2337+ } else if (auto inst = value->getDefiningInstruction ()) {
2338+ B.setInsertionPoint (inst->getParent (), std::next (inst->getIterator ()));
2339+ } else if (auto arg = dyn_cast<SILArgument>(value)) {
2340+ B.setInsertionPoint (arg->getParent ()->begin ());
23162341 } else {
2317- B. setInsertionPoint ( value-> getNextInstruction () );
2342+ llvm_unreachable ( " unexpected value source! " );
23182343 }
23192344 auto declarationLoc = value->getDefiningInsertionPoint ()->getLoc ();
23202345
@@ -2334,17 +2359,15 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
23342359 }
23352360
23362361 // Record the addressable representation.
2337- auto &addressableBuffer = VarLocs[decl].addressableBuffer ;
2338- addressableBuffer.state
2339- = std::make_unique<VarLoc::AddressableBuffer::State>(reabstraction,
2340- allocStack,
2341- storeBorrow);
2342- auto *newState = addressableBuffer.state .get ();
2362+ auto *addressableBuffer = getAddressableBufferInfo (decl);
2363+ auto *newState
2364+ = new VarLoc::AddressableBuffer::State (reabstraction, allocStack, storeBorrow);
2365+ addressableBuffer->stateOrAlias = newState;
23432366
23442367 // Emit cleanups on any paths where we previously would have cleaned up
23452368 // the addressable representation if it had been forced earlier.
2346- decltype (addressableBuffer. cleanupPoints ) cleanupPoints;
2347- cleanupPoints.swap (addressableBuffer. cleanupPoints );
2369+ decltype (addressableBuffer-> cleanupPoints ) cleanupPoints;
2370+ cleanupPoints.swap (addressableBuffer-> cleanupPoints );
23482371
23492372 for (SILInstruction *cleanupPoint : cleanupPoints) {
23502373 SavedInsertionPointRAII insertCleanup (B, cleanupPoint);
@@ -2391,4 +2414,7 @@ SILGenFunction::VarLoc::AddressableBuffer::~AddressableBuffer() {
23912414 for (auto cleanupPoint : cleanupPoints) {
23922415 cleanupPoint->eraseFromParent ();
23932416 }
2417+ if (auto state = stateOrAlias.dyn_cast <State*>()) {
2418+ delete state;
2419+ }
23942420}
0 commit comments