Skip to content

Commit 345f9c1

Browse files
committed
AliasAnalysis: handle destroy_value [dead_end] in computeMemoryEffect
We don't have to take deinit effects into acount for a `destroy_value [dead_end]`. Such destroys are lowered to no-ops and will not call any deinit.
1 parent b24b088 commit 345f9c1

File tree

5 files changed

+45
-0
lines changed

5 files changed

+45
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ struct AliasAnalysis {
309309
if destroy.destroyedValue.type.isNoEscapeFunction {
310310
return .noEffects
311311
}
312+
if destroy.isDeadEnd {
313+
// We don't have to take deinit effects into acount for a `destroy_value [dead_end]`.
314+
// Such destroys are lowered to no-ops and will not call any deinit.
315+
return .noEffects
316+
}
312317
return defaultEffects(of: destroy, on: memLoc)
313318

314319
default:

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,11 @@ final public class UnmanagedAutoreleaseValueInst : RefCountingInst {}
506506

507507
final public class DestroyValueInst : Instruction, UnaryInstruction {
508508
public var destroyedValue: Value { operand.value }
509+
510+
/// True if this `destroy_value` is inside a dead-end block is only needed to formally
511+
/// end the lifetime of its operand.
512+
/// Such `destroy_value` instructions are lowered to no-ops.
513+
public var isDeadEnd: Bool { bridged.DestroyValueInst_isDeadEnd() }
509514
}
510515

511516
final public class DestroyAddrInst : Instruction, UnaryInstruction {

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,7 @@ struct BridgedInstruction {
951951

952952
BRIDGED_INLINE SwiftInt ProjectBoxInst_fieldIndex() const;
953953
BRIDGED_INLINE bool EndCOWMutationInst_doKeepUnique() const;
954+
BRIDGED_INLINE bool DestroyValueInst_isDeadEnd() const;
954955
BRIDGED_INLINE SwiftInt EnumInst_caseIndex() const;
955956
BRIDGED_INLINE SwiftInt UncheckedEnumDataInst_caseIndex() const;
956957
BRIDGED_INLINE SwiftInt InitEnumDataAddrInst_caseIndex() const;

include/swift/SIL/SILBridgingImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,10 @@ bool BridgedInstruction::EndCOWMutationInst_doKeepUnique() const {
11111111
return getAs<swift::EndCOWMutationInst>()->doKeepUnique();
11121112
}
11131113

1114+
bool BridgedInstruction::DestroyValueInst_isDeadEnd() const {
1115+
return getAs<swift::DestroyValueInst>()->isDeadEnd();
1116+
}
1117+
11141118
SwiftInt BridgedInstruction::EnumInst_caseIndex() const {
11151119
return getAs<swift::EnumInst>()->getCaseIndex();
11161120
}

test/SILOptimizer/mem-behavior.sil

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,36 @@ bb0 (%0 : $*C):
10091009
return %2 : $()
10101010
}
10111011

1012+
// CHECK-LABEL: @test_destroy_value_with_effects
1013+
// CHECK: PAIR #1.
1014+
// CHECK-NEXT: destroy_value %0 : $X
1015+
// CHECK-NEXT: %2 = ref_element_addr %1 : $X, #X.x
1016+
// CHECK-NEXT: r=1,w=1
1017+
sil [ossa] @test_destroy_value_with_effects : $@convention(thin) (@owned X) -> () {
1018+
bb0 (%0 : @owned $X):
1019+
%1 = begin_borrow %0 : $X
1020+
%2 = ref_element_addr %1 : $X, #X.x
1021+
fix_lifetime %2 : $*X
1022+
end_borrow %1 : $X
1023+
destroy_value %0 : $X
1024+
unreachable
1025+
}
1026+
1027+
// CHECK-LABEL: @test_deadend_destroy_value
1028+
// CHECK: PAIR #1.
1029+
// CHECK-NEXT: destroy_value [dead_end] %0 : $X
1030+
// CHECK-NEXT: %2 = ref_element_addr %1 : $X, #X.x
1031+
// CHECK-NEXT: r=0,w=0
1032+
sil [ossa] @test_deadend_destroy_value : $@convention(thin) (@owned X) -> () {
1033+
bb0 (%0 : @owned $X):
1034+
%1 = begin_borrow %0 : $X
1035+
%2 = ref_element_addr %1 : $X, #X.x
1036+
fix_lifetime %2 : $*X
1037+
end_borrow %1 : $X
1038+
destroy_value [dead_end] %0 : $X
1039+
unreachable
1040+
}
1041+
10121042
// CHECK-LABEL: @test_copy_value
10131043
// CHECK: PAIR #1.
10141044
// CHECK-NEXT: %2 = copy_value %1 : $C

0 commit comments

Comments
 (0)