Skip to content

Commit cb02d6b

Browse files
authored
Merge pull request swiftlang#84084 from jckarter/global-let-addressable
SILGen: Global constants are addressable.
2 parents f3da6b2 + ee2ee0b commit cb02d6b

File tree

4 files changed

+69
-9
lines changed

4 files changed

+69
-9
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3568,8 +3568,8 @@ SILGenFunction::tryEmitAddressableParameterAsAddress(ArgumentSource &&arg,
35683568
}
35693569
if (auto dre = dyn_cast<DeclRefExpr>(expr)) {
35703570
if (auto param = dyn_cast<VarDecl>(dre->getDecl())) {
3571-
if (auto addr = getLocalVariableAddressableBuffer(param, expr,
3572-
ownership)) {
3571+
if (auto addr = getVariableAddressableBuffer(param, expr,
3572+
ownership)) {
35733573
return ManagedValue::forBorrowedAddressRValue(addr);
35743574
}
35753575
}

lib/SILGen/SILGenDecl.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,12 +2266,41 @@ SILGenFunction::enterLocalVariableAddressableBufferScope(VarDecl *decl,
22662266
Cleanups.pushCleanup<DeallocateLocalVariableAddressableBuffer>(decl, destroyCleanup);
22672267
}
22682268

2269+
static bool isFullyAbstractedLowering(SILGenFunction &SGF,
2270+
Type formalType, SILType loweredType) {
2271+
return SGF.getLoweredType(AbstractionPattern::getOpaque(), formalType)
2272+
.getASTType()
2273+
== loweredType.getASTType();
2274+
}
2275+
2276+
static bool isNaturallyFullyAbstractedType(SILGenFunction &SGF,
2277+
Type formalType) {
2278+
return isFullyAbstractedLowering(SGF, formalType, SGF.getLoweredType(formalType));
2279+
}
2280+
22692281
SILValue
2270-
SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2271-
SILLocation curLoc,
2272-
ValueOwnership ownership) {
2282+
SILGenFunction::getVariableAddressableBuffer(VarDecl *decl,
2283+
SILLocation curLoc,
2284+
ValueOwnership ownership) {
2285+
// For locals, we might be able to retroactively produce a local addressable
2286+
// representation.
22732287
auto foundVarLoc = VarLocs.find(decl);
22742288
if (foundVarLoc == VarLocs.end()) {
2289+
// If it's not local, is it at least a global stored variable?
2290+
if (decl->isGlobalStorage()) {
2291+
// Is the global immutable?
2292+
if (!decl->isLet()) {
2293+
return SILValue();
2294+
}
2295+
2296+
// Does the storage naturally have a fully abstracted representation?
2297+
if (!isNaturallyFullyAbstractedType(*this, decl->getTypeInContext())) {
2298+
return SILValue();
2299+
}
2300+
2301+
// We can get the stable address via the addressor.
2302+
return emitGlobalVariableRef(curLoc, decl, std::nullopt).getUnmanagedValue();
2303+
}
22752304
return SILValue();
22762305
}
22772306

@@ -2285,7 +2314,8 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
22852314
// Check whether the bound value is inherently suitable for addressability.
22862315
// It must already be in memory and fully abstracted.
22872316
if (value->getType().isAddress()
2288-
&& fullyAbstractedTy.getASTType() == value->getType().getASTType()) {
2317+
&& isFullyAbstractedLowering(*this, decl->getTypeInContext()->getRValueType(),
2318+
value->getType())) {
22892319
SILValue address = value;
22902320
// Begin an access if the address is mutable.
22912321
if (access != SILAccessEnforcement::Unknown) {

lib/SILGen/SILGenFunction.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
576576

577577
/// Get a stable address which is suitable for forming dependent pointers
578578
/// if possible.
579-
SILValue getLocalVariableAddressableBuffer(VarDecl *decl,
580-
SILLocation loc,
581-
ValueOwnership ownership);
579+
SILValue getVariableAddressableBuffer(VarDecl *decl,
580+
SILLocation loc,
581+
ValueOwnership ownership);
582582

583583
/// The local auxiliary declarations for the parameters of this function that
584584
/// need to be emitted inside the next brace statement.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %target-swift-emit-silgen -parse-as-library -disable-availability-checking %s | %FileCheck %s
2+
3+
enum Color {
4+
case R, G, B
5+
}
6+
7+
let colors: InlineArray<_, Color> = [
8+
.G, .G, .R, .G, .G, .B,
9+
.G, .G, .B, .G, .G, .R,
10+
.B, .R, .G, .R, .B, .G,
11+
.G, .G, .B, .G, .G, .R,
12+
.G, .G, .R, .G, .G, .B,
13+
.R, .B, .G, .B, .R, .G,
14+
]
15+
16+
// CHECK-LABEL: sil{{.*}} @$s{{.*}}4main
17+
func main() {
18+
// CHECK: [[POINTER:%.*]] = apply {{.*}}() : $@convention(thin) () -> Builtin.RawPointer
19+
// CHECK: [[ADDRESS:%.*]] = pointer_to_address [[POINTER]]
20+
// CHECK: [[GET_SPAN:%.*]] = function_ref @$s{{.*}}11InlineArray{{.*}}4span
21+
// CHECK: apply [[GET_SPAN]]<{{.*}}>([[ADDRESS]])
22+
let span = colors.span
23+
for elem in [3, 9, 8] {
24+
switch span[elem] {
25+
case .R: print(0)
26+
case .G: print(1)
27+
case .B: print(2)
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)