Skip to content

Commit 1e0d5b8

Browse files
authored
Merge pull request swiftlang#40401 from gottesmm/pr-ae46eb0543b75f6523f9651bda7834965d471b09
[silgen] Add the lexical flag on more alloc_stack that are used to represent variables.
2 parents 7ad553f + 5d5b0da commit 1e0d5b8

19 files changed

+72
-56
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,10 +1976,14 @@ class AllocStackInst final
19761976
/// Whether the alloc_stack instruction corresponds to a source-level VarDecl.
19771977
bool isLexical() const { return lexical; }
19781978

1979-
/// If this is a lexical borrow, eliminate the lexical bit. If this borrow
1980-
/// doesn't have a lexical bit, do not do anything.
1979+
/// If this is a lexical alloc_stack, eliminate the lexical bit. If this
1980+
/// alloc_stack doesn't have a lexical bit, do not do anything.
19811981
void removeIsLexical() { lexical = false; }
19821982

1983+
/// If this is not a lexical alloc_stack, set the lexical bit. If this
1984+
/// alloc_stack is already lexical, this does nothing.
1985+
void setIsLexical() { lexical = true; }
1986+
19831987
/// Return the debug variable information attached to this instruction.
19841988
Optional<SILDebugVariable> getVarInfo() const {
19851989
Optional<SILType> AuxVarType;

lib/SILGen/SILGenDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,11 @@ class LetValueInitialization : public Initialization {
472472
}
473473

474474
if (needsTemporaryBuffer) {
475-
address = SGF.emitTemporaryAllocation(vd, lowering.getLoweredType());
475+
bool isLexical =
476+
SGF.getASTContext().SILOpts.supportsLexicalLifetimes(SGF.getModule());
477+
address =
478+
SGF.emitTemporaryAllocation(vd, lowering.getLoweredType(),
479+
false /*hasDynamicLifetime*/, isLexical);
476480
if (isUninitialized)
477481
address = SGF.B.createMarkUninitializedVar(vd, address);
478482
DestroyCleanup = SGF.enterDormantTemporaryCleanup(address, lowering);

lib/SILGen/SILGenExpr.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,8 @@ RValue RValueEmitter::visitLoadExpr(LoadExpr *E, SGFContext C) {
10271027
}
10281028

10291029
SILValue SILGenFunction::emitTemporaryAllocation(SILLocation loc, SILType ty,
1030-
bool hasDynamicLifetime) {
1030+
bool hasDynamicLifetime,
1031+
bool isLexical) {
10311032
ty = ty.getObjectType();
10321033
Optional<SILDebugVariable> DbgVar;
10331034
if (auto *VD = loc.getAsASTNode<VarDecl>())
@@ -1042,7 +1043,8 @@ SILValue SILGenFunction::emitTemporaryAllocation(SILLocation loc, SILType ty,
10421043
DbgVar = SILDebugVariable(VD->isLet(), 0);
10431044
loc = SILLocation(VD);
10441045
}
1045-
auto alloc = B.createAllocStack(loc, ty, DbgVar, hasDynamicLifetime);
1046+
auto *alloc =
1047+
B.createAllocStack(loc, ty, DbgVar, hasDynamicLifetime, isLexical);
10461048
enterDeallocStackCleanup(alloc);
10471049
return alloc;
10481050
}

lib/SILGen/SILGenFunction.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -981,12 +981,16 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
981981
/// emitSelfDecl - Emit a SILArgument for 'self', register it in varlocs, set
982982
/// up debug info, etc. This returns the 'self' value.
983983
SILValue emitSelfDecl(VarDecl *selfDecl);
984-
984+
985985
/// Emits a temporary allocation that will be deallocated automatically at the
986986
/// end of the current scope. Returns the address of the allocation.
987+
///
988+
/// \p isLexical if set to true, this is a temporary that we are using for a
989+
/// local let that we need to mark with the lexical flag.
987990
SILValue emitTemporaryAllocation(SILLocation loc, SILType ty,
988-
bool hasDynamicLifetime = false);
989-
991+
bool hasDynamicLifetime = false,
992+
bool isLexical = false);
993+
990994
/// Prepares a buffer to receive the result of an expression, either using the
991995
/// 'emit into' initialization buffer if available, or allocating a temporary
992996
/// allocation if not.

lib/SILGen/SILGenProlog.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,12 @@ struct ArgumentInitHelper {
290290
}
291291
SGF.B.createDebugValue(loc, value, varinfo);
292292
} else {
293-
if (auto AllocStack = dyn_cast<AllocStackInst>(value))
294-
AllocStack->setArgNo(ArgNo);
295-
else
293+
if (auto *allocStack = dyn_cast<AllocStackInst>(value)) {
294+
allocStack->setArgNo(ArgNo);
295+
allocStack->setIsLexical();
296+
} else {
296297
SGF.B.createDebugValueAddr(loc, value, varinfo);
298+
}
297299
}
298300
SGF.VarLocs[pd] = SILGenFunction::VarLoc::get(value);
299301
}

test/AutoDiff/SILOptimizer/activity_analysis.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,12 +844,12 @@ func testActiveEnumAddr<T>(_ e: IndirectEnum<T>) -> T {
844844
// CHECK: [ACTIVE] %3 = alloc_stack $IndirectEnum<T>
845845
// CHECK: bb1:
846846
// CHECK: [ACTIVE] %6 = unchecked_take_enum_data_addr %3 : $*IndirectEnum<T>, #IndirectEnum.case1!enumelt
847-
// CHECK: [ACTIVE] %7 = alloc_stack $T, let, name "y1"
847+
// CHECK: [ACTIVE] %7 = alloc_stack [lexical] $T, let, name "y1"
848848
// CHECK: bb2:
849849
// CHECK: [ACTIVE] {{.*}} = unchecked_take_enum_data_addr {{.*}} : $*IndirectEnum<T>, #IndirectEnum.case2!enumelt
850850
// CHECK: [ACTIVE] {{.*}} = tuple_element_addr {{.*}} : $*(Float, T), 0
851851
// CHECK: [VARIED] {{.*}} = load [trivial] {{.*}} : $*Float
852852
// CHECK: [ACTIVE] {{.*}} = tuple_element_addr {{.*}} : $*(Float, T), 1
853-
// CHECK: [ACTIVE] {{.*}} = alloc_stack $T, let, name "y2"
853+
// CHECK: [ACTIVE] {{.*}} = alloc_stack [lexical] $T, let, name "y2"
854854
// CHECK: bb3:
855855
// CHECK: [NONE] {{.*}} = tuple ()

test/Interop/Cxx/class/type-classification-non-trivial-silgen.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import TypeClassification
55
// Make sure that "StructWithDestructor" is marked as non-trivial by checking for a
66
// "destroy_addr".
77
// CHECK-LABEL: sil [ossa] @$s4main24testStructWithDestructoryyF
8-
// CHECK: [[AS:%.*]] = alloc_stack $StructWithDestructor
8+
// CHECK: [[AS:%.*]] = alloc_stack [lexical] $StructWithDestructor
99
// CHECK: [[FN:%.*]] = function_ref @{{_ZN20StructWithDestructorC1Ev|\?\?0StructWithDestructor@@QEAA@XZ}} : $@convention(c) () -> @out StructWithDestructor
1010
// CHECK: apply [[FN]]([[AS]]) : $@convention(c) () -> @out StructWithDestructor
1111
// CHECK: destroy_addr [[AS]]
@@ -20,7 +20,7 @@ public func testStructWithDestructor() {
2020
// Make sure that "HasMemberWithDestructor" is marked as non-trivial by checking
2121
// for a "destroy_addr".
2222
// CHECK-LABEL: sil [ossa] @$s4main33testStructWithSubobjectDestructoryyF : $@convention(thin) () -> ()
23-
// CHECK: [[AS:%.*]] = alloc_stack $StructWithSubobjectDestructor
23+
// CHECK: [[AS:%.*]] = alloc_stack [lexical] $StructWithSubobjectDestructor
2424
// CHECK: [[FN:%.*]] = function_ref @{{_ZN29StructWithSubobjectDestructorC1Ev|\?\?0StructWithSubobjectDestructor@@QEAA@XZ}} : $@convention(c) () -> @out StructWithSubobjectDestructor
2525
// CHECK: apply [[FN]]([[AS]]) : $@convention(c) () -> @out StructWithSubobjectDestructor
2626
// CHECK: destroy_addr [[AS]]
@@ -32,7 +32,7 @@ public func testStructWithSubobjectDestructor() {
3232
}
3333

3434
// CHECK-LABLE: sil [ossa] @$s4main37testStructWithCopyConstructorAndValueSbyF
35-
// CHECK: [[AS:%.*]] = alloc_stack $StructWithCopyConstructorAndValue
35+
// CHECK: [[AS:%.*]] = alloc_stack [lexical] $StructWithCopyConstructorAndValue
3636
// CHECK: [[FN:%.*]] = function_ref @{{_ZN33StructWithCopyConstructorAndValueC1Ei|\?\?0StructWithCopyConstructorAndValue@@QEAA@H@Z}} : $@convention(c) (Int32) -> @out StructWithCopyConstructorAndValue
3737
// CHECK: apply [[FN]]([[AS]], %{{.*}}) : $@convention(c) (Int32) -> @out StructWithCopyConstructorAndValue
3838
// CHECK: [[OBJ_VAL_ADDR:%.*]] = struct_element_addr [[AS]] : $*StructWithCopyConstructorAndValue, #StructWithCopyConstructorAndValue.value
@@ -53,10 +53,10 @@ public func testStructWithCopyConstructorAndValue() -> Bool {
5353
}
5454

5555
// CHECK-LABEL: sil [ossa] @$s4main46testStructWithSubobjectCopyConstructorAndValueSbyF : $@convention(thin) () -> Bool
56-
// CHECK: [[MEMBER_0:%.*]] = alloc_stack $StructWithCopyConstructorAndValue
56+
// CHECK: [[MEMBER_0:%.*]] = alloc_stack [lexical] $StructWithCopyConstructorAndValue
5757
// CHECK: [[MAKE_MEMBER_FN:%.*]] = function_ref @{{_ZN33StructWithCopyConstructorAndValueC1Ei|\?\?0StructWithCopyConstructorAndValue@@QEAA@H@Z}} : $@convention(c) (Int32) -> @out StructWithCopyConstructorAndValue
5858
// CHECK: apply [[MAKE_MEMBER_FN]]([[MEMBER_0]], %{{.*}}) : $@convention(c) (Int32) -> @out StructWithCopyConstructorAndValue
59-
// CHECK: [[AS:%.*]] = alloc_stack $StructWithSubobjectCopyConstructorAndValue
59+
// CHECK: [[AS:%.*]] = alloc_stack [lexical] $StructWithSubobjectCopyConstructorAndValue
6060
// CHECK: [[META:%.*]] = metatype $@thin StructWithSubobjectCopyConstructorAndValue.Type
6161
// CHECK: [[MEMBER_1:%.*]] = alloc_stack $StructWithCopyConstructorAndValue
6262
// CHECK: copy_addr %0 to [initialization] [[MEMBER_1]] : $*StructWithCopyConstructorAndValue
@@ -87,10 +87,10 @@ public func testStructWithSubobjectCopyConstructorAndValue() -> Bool {
8787

8888
// testStructWithCopyConstructorAndSubobjectCopyConstructorAndValue()
8989
// CHECK-LABEL: sil [ossa] @$s4main041testStructWithCopyConstructorAndSubobjectefG5ValueSbyF : $@convention(thin) () -> Bool
90-
// CHECK: [[MEMBER_0:%.*]] = alloc_stack $StructWithCopyConstructorAndValue
90+
// CHECK: [[MEMBER_0:%.*]] = alloc_stack [lexical] $StructWithCopyConstructorAndValue
9191
// CHECK: [[CREATE_MEMBER_FN:%.*]] = function_ref @{{_ZN33StructWithCopyConstructorAndValueC1Ei|\?\?0StructWithCopyConstructorAndValue@@QEAA@H@Z}} : $@convention(c) (Int32) -> @out StructWithCopyConstructorAndValue
9292
// CHECK: apply [[CREATE_MEMBER_FN]]([[MEMBER_0]], %{{.*}}) : $@convention(c) (Int32) -> @out StructWithCopyConstructorAndValue
93-
// CHECK: [[AS:%.*]] = alloc_stack $StructWithCopyConstructorAndSubobjectCopyConstructorAndValue
93+
// CHECK: [[AS:%.*]] = alloc_stack [lexical] $StructWithCopyConstructorAndSubobjectCopyConstructorAndValue
9494
// CHECK: [[MEMBER_1:%.*]] = alloc_stack $StructWithCopyConstructorAndValue
9595
// CHECK: copy_addr [[MEMBER_0]] to [initialization] [[MEMBER_1]] : $*StructWithCopyConstructorAndValue
9696
// CHECK: [[FN:%.*]] = function_ref @{{_ZN60StructWithCopyConstructorAndSubobjectCopyConstructorAndValueC1E33StructWithCopyConstructorAndValue|\?\?0StructWithCopyConstructorAndSubobjectCopyConstructorAndValue@@QEAA@UStructWithCopyConstructorAndValue@@@Z}} : $@convention(c) (@in StructWithCopyConstructorAndValue) -> @out StructWithCopyConstructorAndSubobjectCopyConstructorAndValue

test/SILGen/existential_metatypes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct S: P {
2424
func existentialMetatype(_ x: P) {
2525
// CHECK: [[TYPE1:%.*]] = existential_metatype $@thick P.Type, [[X]]
2626
let type1 = type(of: x)
27-
// CHECK: [[INSTANCE1:%.*]] = alloc_stack $P
27+
// CHECK: [[INSTANCE1:%.*]] = alloc_stack [lexical] $P
2828
// CHECK: [[OPEN_TYPE1:%.*]] = open_existential_metatype [[TYPE1]]
2929
// CHECK: [[INIT:%.*]] = witness_method {{.*}} #P.init!allocator
3030
// CHECK: [[INSTANCE1_VALUE:%.*]] = init_existential_addr [[INSTANCE1]] : $*P
@@ -34,7 +34,7 @@ func existentialMetatype(_ x: P) {
3434
// CHECK: [[S:%.*]] = metatype $@thick S.Type
3535
// CHECK: [[TYPE2:%.*]] = init_existential_metatype [[S]] : $@thick S.Type, $@thick P.Type
3636
let type2: P.Type = S.self
37-
// CHECK: [[INSTANCE2:%.*]] = alloc_stack $P
37+
// CHECK: [[INSTANCE2:%.*]] = alloc_stack [lexical] $P
3838
// CHECK: [[OPEN_TYPE2:%.*]] = open_existential_metatype [[TYPE2]]
3939
// CHECK: [[STATIC_METHOD:%.*]] = witness_method {{.*}} #P.staticMethod
4040
// CHECK: [[INSTANCE2_VALUE:%.*]] = init_existential_addr [[INSTANCE2]] : $*P

test/SILGen/foreach.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ func existentialBreak(_ xx: [P]) {
220220
// CHECK: switch_enum_addr [[ELT_STACK]] : $*Optional<P>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
221221
//
222222
// CHECK: [[SOME_BB]]:
223-
// CHECK: [[T0:%.*]] = alloc_stack $P, let, name "x"
223+
// CHECK: [[T0:%.*]] = alloc_stack [lexical] $P, let, name "x"
224224
// CHECK: [[ELT_STACK_TAKE:%.*]] = unchecked_take_enum_data_addr [[ELT_STACK]] : $*Optional<P>, #Optional.some!enumelt
225225
// CHECK: copy_addr [take] [[ELT_STACK_TAKE]] to [initialization] [[T0]]
226226
// CHECK: cond_br {{%.*}}, [[LOOP_BREAK_END_BLOCK:bb[0-9]+]], [[CONTINUE_CHECK_BLOCK:bb[0-9]+]]
@@ -380,7 +380,7 @@ func genericStructBreak<T>(_ xx: [GenericStruct<T>]) {
380380
// CHECK: switch_enum_addr [[ELT_STACK]] : $*Optional<GenericStruct<T>>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
381381
//
382382
// CHECK: [[SOME_BB]]:
383-
// CHECK: [[T0:%.*]] = alloc_stack $GenericStruct<T>, let, name "x"
383+
// CHECK: [[T0:%.*]] = alloc_stack [lexical] $GenericStruct<T>, let, name "x"
384384
// CHECK: [[ELT_STACK_TAKE:%.*]] = unchecked_take_enum_data_addr [[ELT_STACK]] : $*Optional<GenericStruct<T>>, #Optional.some!enumelt
385385
// CHECK: copy_addr [take] [[ELT_STACK_TAKE]] to [initialization] [[T0]]
386386
// CHECK: cond_br {{%.*}}, [[LOOP_BREAK_END_BLOCK:bb[0-9]+]], [[CONTINUE_CHECK_BLOCK:bb[0-9]+]]
@@ -486,7 +486,7 @@ func genericCollectionBreak<T : Collection>(_ xx: T) {
486486
// CHECK: switch_enum_addr [[ELT_STACK]] : $*Optional<T.Element>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
487487
//
488488
// CHECK: [[SOME_BB]]:
489-
// CHECK: [[T0:%.*]] = alloc_stack $T.Element, let, name "x"
489+
// CHECK: [[T0:%.*]] = alloc_stack [lexical] $T.Element, let, name "x"
490490
// CHECK: [[ELT_STACK_TAKE:%.*]] = unchecked_take_enum_data_addr [[ELT_STACK]] : $*Optional<T.Element>, #Optional.some!enumelt
491491
// CHECK: copy_addr [take] [[ELT_STACK_TAKE]] to [initialization] [[T0]]
492492
// CHECK: cond_br {{%.*}}, [[LOOP_BREAK_END_BLOCK:bb[0-9]+]], [[CONTINUE_CHECK_BLOCK:bb[0-9]+]]
@@ -624,7 +624,7 @@ func injectForEachElementIntoOptional(_ xs: [Int]) {
624624
// CHECK: copy_addr [take] [[NEXT_RESULT:%.*]] to [initialization] [[NEXT_RESULT_COPY:%.*]] : $*Optional<T>
625625
// CHECK: switch_enum_addr [[NEXT_RESULT_COPY]] : $*Optional<T>, case #Optional.some!enumelt: [[BB_SOME:bb.*]], case
626626
// CHECK: [[BB_SOME]]:
627-
// CHECK: [[X_BINDING:%.*]] = alloc_stack $Optional<T>, let, name "x"
627+
// CHECK: [[X_BINDING:%.*]] = alloc_stack [lexical] $Optional<T>, let, name "x"
628628
// CHECK: [[ADDR:%.*]] = unchecked_take_enum_data_addr [[NEXT_RESULT_COPY]] : $*Optional<T>, #Optional.some!enumelt
629629
// CHECK: [[X_ADDR:%.*]] = init_enum_data_addr [[X_BINDING]] : $*Optional<T>, #Optional.some!enumelt
630630
// CHECK: copy_addr [take] [[ADDR]] to [initialization] [[X_ADDR]] : $*T

test/SILGen/guaranteed_closure_context.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func guaranteed_captures() {
2222
// CHECK: [[IMMUTABLE_RETAINABLE:%.*]] = apply {{.*}} -> @owned C
2323
// CHECK: [[B_IMMUTABLE_RETAINABLE:%.*]] = begin_borrow [lexical] [[IMMUTABLE_RETAINABLE]] : $C
2424
let immutableRetainable = C()
25-
// CHECK: [[IMMUTABLE_ADDRESS_ONLY:%.*]] = alloc_stack $P
25+
// CHECK: [[IMMUTABLE_ADDRESS_ONLY:%.*]] = alloc_stack [lexical] $P
2626
let immutableAddressOnly: P = C()
2727

2828
func captureEverything() {

0 commit comments

Comments
 (0)