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