36
36
#include " swift/SIL/SILType.h"
37
37
#include " swift/SIL/TypeLowering.h"
38
38
#include " llvm/ADT/SmallString.h"
39
+ #include " llvm/Support/ErrorHandling.h"
39
40
#include < iterator>
40
41
41
42
using namespace swift ;
@@ -698,20 +699,23 @@ class DeallocateLocalVariableAddressableBuffer : public Cleanup {
698
699
699
700
void emit (SILGenFunction &SGF, CleanupLocation l,
700
701
ForUnwind_t forUnwind) override {
702
+ auto addressableBuffer = SGF.getAddressableBufferInfo (vd);
703
+ if (!addressableBuffer) {
704
+ return ;
705
+ }
701
706
auto found = SGF.VarLocs .find (vd);
702
707
if (found == SGF.VarLocs .end ()) {
703
708
return ;
704
709
}
705
- auto &loc = found->second ;
706
710
707
- if (auto & state = loc. addressableBuffer . state ) {
711
+ if (auto * state = addressableBuffer-> getState () ) {
708
712
// The addressable buffer was forced, so clean it up now.
709
713
deallocateAddressable (SGF, l, *state);
710
714
} else {
711
715
// Remember this insert location in case we need to force the addressable
712
716
// buffer later.
713
717
SILInstruction *marker = SGF.B .createTuple (l, {});
714
- loc. addressableBuffer . cleanupPoints .emplace_back (marker);
718
+ addressableBuffer-> cleanupPoints .emplace_back (marker);
715
719
}
716
720
}
717
721
@@ -2253,7 +2257,7 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2253
2257
2254
2258
auto value = foundVarLoc->second .value ;
2255
2259
auto access = foundVarLoc->second .access ;
2256
- auto *state = foundVarLoc-> second . addressableBuffer . state . get ();
2260
+ auto *state = getAddressableBufferInfo (decl)-> getState ();
2257
2261
2258
2262
SILType fullyAbstractedTy = getLoweredType (AbstractionPattern::getOpaque (),
2259
2263
decl->getTypeInContext ()->getRValueType ());
@@ -2291,9 +2295,26 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2291
2295
SILValue reabstraction, allocStack, storeBorrow;
2292
2296
{
2293
2297
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" );
2297
2318
B.setInsertionPoint (insertPoint);
2298
2319
auto allocStackTy = fullyAbstractedTy;
2299
2320
if (value->getType ().isMoveOnlyWrapped ()) {
@@ -2312,8 +2333,12 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2312
2333
SavedInsertionPointRAII save (B);
2313
2334
if (isa<ParamDecl>(decl)) {
2314
2335
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 ());
2315
2340
} else {
2316
- B. setInsertionPoint ( value-> getNextInstruction () );
2341
+ llvm_unreachable ( " unexpected value source! " );
2317
2342
}
2318
2343
auto declarationLoc = value->getDefiningInsertionPoint ()->getLoc ();
2319
2344
@@ -2333,17 +2358,15 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2333
2358
}
2334
2359
2335
2360
// 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;
2342
2365
2343
2366
// Emit cleanups on any paths where we previously would have cleaned up
2344
2367
// 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 );
2347
2370
2348
2371
for (SILInstruction *cleanupPoint : cleanupPoints) {
2349
2372
SavedInsertionPointRAII insertCleanup (B, cleanupPoint);
@@ -2390,4 +2413,7 @@ SILGenFunction::VarLoc::AddressableBuffer::~AddressableBuffer() {
2390
2413
for (auto cleanupPoint : cleanupPoints) {
2391
2414
cleanupPoint->eraseFromParent ();
2392
2415
}
2416
+ if (auto state = stateOrAlias.dyn_cast <State*>()) {
2417
+ delete state;
2418
+ }
2393
2419
}
0 commit comments