@@ -2263,12 +2263,41 @@ SILGenFunction::enterLocalVariableAddressableBufferScope(VarDecl *decl,
2263
2263
Cleanups.pushCleanup <DeallocateLocalVariableAddressableBuffer>(decl, destroyCleanup);
2264
2264
}
2265
2265
2266
+ static bool isFullyAbstractedLowering (SILGenFunction &SGF,
2267
+ Type formalType, SILType loweredType) {
2268
+ return SGF.getLoweredType (AbstractionPattern::getOpaque (), formalType)
2269
+ .getASTType ()
2270
+ == loweredType.getASTType ();
2271
+ }
2272
+
2273
+ static bool isNaturallyFullyAbstractedType (SILGenFunction &SGF,
2274
+ Type formalType) {
2275
+ return isFullyAbstractedLowering (SGF, formalType, SGF.getLoweredType (formalType));
2276
+ }
2277
+
2266
2278
SILValue
2267
- SILGenFunction::getLocalVariableAddressableBuffer (VarDecl *decl,
2268
- SILLocation curLoc,
2269
- ValueOwnership ownership) {
2279
+ SILGenFunction::getVariableAddressableBuffer (VarDecl *decl,
2280
+ SILLocation curLoc,
2281
+ ValueOwnership ownership) {
2282
+ // For locals, we might be able to retroactively produce a local addressable
2283
+ // representation.
2270
2284
auto foundVarLoc = VarLocs.find (decl);
2271
2285
if (foundVarLoc == VarLocs.end ()) {
2286
+ // If it's not local, is it at least a global stored variable?
2287
+ if (decl->isGlobalStorage ()) {
2288
+ // Is the global immutable?
2289
+ if (!decl->isLet ()) {
2290
+ return SILValue ();
2291
+ }
2292
+
2293
+ // Does the storage naturally have a fully abstracted representation?
2294
+ if (!isNaturallyFullyAbstractedType (*this , decl->getTypeInContext ())) {
2295
+ return SILValue ();
2296
+ }
2297
+
2298
+ // We can get the stable address via the addressor.
2299
+ return emitGlobalVariableRef (curLoc, decl, std::nullopt ).getUnmanagedValue ();
2300
+ }
2272
2301
return SILValue ();
2273
2302
}
2274
2303
@@ -2282,7 +2311,8 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2282
2311
// Check whether the bound value is inherently suitable for addressability.
2283
2312
// It must already be in memory and fully abstracted.
2284
2313
if (value->getType ().isAddress ()
2285
- && fullyAbstractedTy.getASTType () == value->getType ().getASTType ()) {
2314
+ && isFullyAbstractedLowering (*this , decl->getTypeInContext ()->getRValueType (),
2315
+ value->getType ())) {
2286
2316
SILValue address = value;
2287
2317
// Begin an access if the address is mutable.
2288
2318
if (access != SILAccessEnforcement::Unknown) {
0 commit comments