Skip to content

Commit 198d4ab

Browse files
committed
Optimizer: run TempRValueElimination also at Onone
Introduce a new pass MandatoryTempRValueElimination, which works as the original TempRValueElimination, except that it does not remove any alloc_stack instruction which are associated with source variables. Running this pass at Onone helps to reduce copies of large structs, e.g. InlineArrays or structs containing InlineArrays. Copying large structs can be a performance problem, even at Onone. rdar://151629149
1 parent 8464b97 commit 198d4ab

File tree

16 files changed

+130
-67
lines changed

16 files changed

+130
-67
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/TempRValueElimination.swift

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,15 @@ import SIL
3636
///
3737
let tempRValueElimination = FunctionPass(name: "temp-rvalue-elimination") {
3838
(function: Function, context: FunctionPassContext) in
39+
removeTempRValues(in: function, keepDebugInfo: false, context)
40+
}
3941

42+
let mandatoryTempRValueElimination = FunctionPass(name: "mandatory-temp-rvalue-elimination") {
43+
(function: Function, context: FunctionPassContext) in
44+
removeTempRValues(in: function, keepDebugInfo: true, context)
45+
}
46+
47+
private func removeTempRValues(in function: Function, keepDebugInfo: Bool, _ context: FunctionPassContext) {
4048
for inst in function.instructions {
4149
switch inst {
4250
case let copy as CopyAddrInst:
@@ -45,12 +53,12 @@ let tempRValueElimination = FunctionPass(name: "temp-rvalue-elimination") {
4553
// copied the `alloc_stack` back to the source location.
4654
context.erase(instruction: copy)
4755
} else {
48-
tryEliminate(copy: copy, context)
56+
tryEliminate(copy: copy, keepDebugInfo: keepDebugInfo, context)
4957
}
5058
case let store as StoreInst:
5159
// Also handle `load`-`store` pairs which are basically the same thing as a `copy_addr`.
5260
if let load = store.source as? LoadInst, load.uses.isSingleUse, load.parentBlock == store.parentBlock {
53-
tryEliminate(copy: store, context)
61+
tryEliminate(copy: store, keepDebugInfo: keepDebugInfo, context)
5462
}
5563
default:
5664
break
@@ -82,9 +90,10 @@ extension StoreInst: CopyLikeInstruction {
8290
private var load: LoadInst { source as! LoadInst }
8391
}
8492

85-
private func tryEliminate(copy: CopyLikeInstruction, _ context: FunctionPassContext) {
93+
private func tryEliminate(copy: CopyLikeInstruction, keepDebugInfo: Bool, _ context: FunctionPassContext) {
8694

87-
guard let (allocStack, lastUseOfAllocStack) = getRemovableAllocStackDestination(of: copy, context) else {
95+
guard let (allocStack, lastUseOfAllocStack) =
96+
getRemovableAllocStackDestination(of: copy, keepDebugInfo: keepDebugInfo, context) else {
8897
return
8998
}
9099

@@ -127,6 +136,9 @@ private func tryEliminate(copy: CopyLikeInstruction, _ context: FunctionPassCont
127136
}
128137
}
129138
context.erase(instruction: allocStack)
139+
if keepDebugInfo {
140+
Builder(before: copy, context).createDebugStep()
141+
}
130142
context.erase(instructionIncludingAllUsers: copy.loadingInstruction)
131143
}
132144

@@ -138,18 +150,24 @@ private func tryEliminate(copy: CopyLikeInstruction, _ context: FunctionPassCont
138150
/// %lastUseOfAllocStack = load %allocStack
139151
/// ```
140152
private func getRemovableAllocStackDestination(
141-
of copy: CopyLikeInstruction, _ context: FunctionPassContext
153+
of copy: CopyLikeInstruction, keepDebugInfo: Bool, _ context: FunctionPassContext
142154
) -> (allocStack: AllocStackInst, lastUseOfAllocStack: Instruction)? {
143155
guard copy.isInitializationOfDestination,
144156
let allocStack = copy.destinationAddress as? AllocStackInst
145157
else {
146158
return nil
147159
}
148160

149-
// If the `allocStack` is lexical we can eliminate it if the source of the copy is lexical and
150-
// it is live for longer than the `allocStack`.
151-
if allocStack.isLexical && !copy.sourceAddress.accessBase.storageIsLexical {
152-
return nil
161+
if keepDebugInfo {
162+
if allocStack.isFromVarDecl || allocStack.isLexical {
163+
return nil
164+
}
165+
} else {
166+
// If the `allocStack` is lexical we can eliminate it if the source of the copy is lexical and
167+
// it is live for longer than the `allocStack`.
168+
if allocStack.isLexical && !copy.sourceAddress.accessBase.storageIsLexical {
169+
return nil
170+
}
153171
}
154172

155173
var allocStackUses = UseCollector(copy: copy, context)

SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ private func registerSwiftPasses() {
101101
registerPass(lifetimeDependenceScopeFixupPass, { lifetimeDependenceScopeFixupPass.run($0) })
102102
registerPass(copyToBorrowOptimization, { copyToBorrowOptimization.run($0) })
103103
registerPass(tempRValueElimination, { tempRValueElimination.run($0) })
104+
registerPass(mandatoryTempRValueElimination, { mandatoryTempRValueElimination.run($0) })
104105
registerPass(generalClosureSpecialization, { generalClosureSpecialization.run($0) })
105106
registerPass(autodiffClosureSpecialization, { autodiffClosureSpecialization.run($0) })
106107

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ PASS(StackPromotion, "stack-promotion",
140140
"Stack Promotion of Class Objects")
141141
PASS(UpdateBorrowedFrom, "update-borrowed-from",
142142
"Test pass for update borrowed-from instructions")
143+
PASS(MandatoryTempRValueElimination, "mandatory-temp-rvalue-elimination",
144+
"Mandatory remove short-lived immutable temporary copies")
143145
PASS(TempRValueElimination, "temp-rvalue-elimination",
144146
"Remove short-lived immutable temporary copies")
145147

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,9 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
10821082
// Now that we have serialized, propagate debug info.
10831083
P.addMovedAsyncVarDebugInfoPropagator();
10841084

1085+
// Even at Onone it's important to remove copies of structs, especially if they are large.
1086+
P.addMandatoryTempRValueElimination();
1087+
10851088
// If we are asked to stop optimizing before lowering ownership, do so now.
10861089
if (P.Options.StopOptimizationBeforeLoweringOwnership)
10871090
return P;

test/AutoDiff/SILOptimizer/optional_pullback.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,9 @@ import _Differentiation
1313
// CHECK: apply %[[ZERO1]]<τ_0_0.TangentVector>(%[[RET_TAN_BUF]], %{{.*}})
1414
// CHECK: %[[ADJ_IN_BB:.+]] = alloc_stack $τ_0_0.TangentVector
1515
//
16-
// CHECK: %[[TAN_VAL_COPY:.+]] = alloc_stack $Optional<τ_0_0.TangentVector>
17-
// CHECK: %[[TAN_BUF:.+]] = alloc_stack $Optional<τ_0_0>.TangentVector
18-
19-
// CHECK: copy_addr %[[OPT_TAN]] to [init] %[[TAN_BUF]] : $*Optional<τ_0_0>.TangentVector
20-
// CHECK: %[[TAN_VAL:.+]] = struct_element_addr %[[TAN_BUF]] : $*Optional<τ_0_0>.TangentVector, #Optional.TangentVector.value
21-
// CHECK: copy_addr %[[TAN_VAL]] to [init] %[[TAN_VAL_COPY]] : $*Optional<τ_0_0.TangentVector>
16+
// CHECK: %[[TAN_VAL:.+]] = struct_element_addr %[[OPT_TAN]] : $*Optional<τ_0_0>.TangentVector, #Optional.TangentVector.value
2217
//
23-
// CHECK: %[[TAN_DATA:.+]] = unchecked_take_enum_data_addr %[[TAN_VAL_COPY]] : $*Optional<τ_0_0.TangentVector>, #Optional.some!enumelt
18+
// CHECK: %[[TAN_DATA:.+]] = unchecked_take_enum_data_addr %[[TAN_VAL]] : $*Optional<τ_0_0.TangentVector>, #Optional.some!enumelt
2419
// CHECK: %[[PLUS_EQUAL:.+]] = witness_method $τ_0_0.TangentVector, #AdditiveArithmetic."+="
2520
// CHECK: apply %[[PLUS_EQUAL]]<τ_0_0.TangentVector>(%[[ADJ_IN_BB]], %[[TAN_DATA]], %{{.*}})
2621

@@ -29,9 +24,6 @@ import _Differentiation
2924
// CHECK: destroy_addr %[[ADJ_IN_BB]] : $*τ_0_0.TangentVector
3025

3126
// CHECK: copy_addr [take] %[[RET_TAN_BUF:.+]] to [init] %[[RET_TAN:.+]]
32-
// CHECK: destroy_addr %[[TAN_BUF]] : $*Optional<τ_0_0>.TangentVector
33-
// CHECK: dealloc_stack %[[TAN_BUF]] : $*Optional<τ_0_0>.TangentVector
34-
// CHECK: dealloc_stack %[[TAN_VAL_COPY]] : $*Optional<τ_0_0.TangentVector>
3527
// CHECK: dealloc_stack %[[RET_TAN_BUF]] : $*τ_0_0.TangentVector
3628

3729
@differentiable(reverse)

test/DebugInfo/move_function_dbginfo_async.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend -parse-as-library -target %target-swift-5.1-abi-triple -g -emit-sil -o - %s | %FileCheck -check-prefix=SIL %s
3-
// RUN: %target-swift-frontend -parse-as-library -target %target-swift-5.1-abi-triple -g -emit-ir -o - %s | %FileCheck %s
4-
// RUN: %target-swift-frontend -parse-as-library -target %target-swift-5.1-abi-triple -g -c %s -o %t/out.o
2+
// RUN: %target-swift-frontend -parse-as-library -target %target-swift-5.1-abi-triple -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -g -emit-sil -o - %s | %FileCheck -check-prefix=SIL %s
3+
// RUN: %target-swift-frontend -parse-as-library -target %target-swift-5.1-abi-triple -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -g -emit-ir -o - %s | %FileCheck %s
4+
// RUN: %target-swift-frontend -parse-as-library -target %target-swift-5.1-abi-triple -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -g -c %s -o %t/out.o
55

66
// This test checks that:
77
//

test/IRGen/archetype_resilience.sil

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
// REQUIRES: CPU=x86_64
21
// REQUIRES: OS=macosx
32

43
// RUN: %empty-directory(%t)
54
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
65
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
7-
// RUN: %target-swift-frontend -disable-type-layout -I %t -emit-ir -enable-library-evolution %s | %FileCheck %s
6+
// RUN: %target-swift-frontend -disable-type-layout -I %t -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -emit-ir -enable-library-evolution %s | %FileCheck %s
87

98
sil_stage canonical
109

test/IRGen/lifetime.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -disable-debugger-shadow-copies -gnone -emit-ir %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s -DINT=i%target-ptrsize
1+
// RUN: %target-swift-frontend -disable-debugger-shadow-copies -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -gnone -emit-ir %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s -DINT=i%target-ptrsize
22

33
sil_stage canonical
44

test/IRGen/typelayout_based_value_operation.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-frontend -enable-type-layout %s -emit-ir -sil-verify-all | %FileCheck %s
2-
// RUNx: %target-swift-frontend -disable-type-layout %s -emit-ir -sil-verify-all | %FileCheck %s --check-prefix=NOTYPELAYOUT
1+
// RUN: %target-swift-frontend -enable-type-layout %s -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -emit-ir -sil-verify-all | %FileCheck %s
2+
// RUNx: %target-swift-frontend -disable-type-layout %s -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -emit-ir -sil-verify-all | %FileCheck %s --check-prefix=NOTYPELAYOUT
33

44
sil_stage canonical
55
import Builtin

test/IRGen/variadic_generic_fulfillment.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-ir %s -target %target-swift-5.9-abi-triple | %FileCheck %s -DINT=i%target-ptrsize
1+
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=mandatory-temp-rvalue-elimination -emit-ir %s -target %target-swift-5.9-abi-triple | %FileCheck %s -DINT=i%target-ptrsize
22

33
public struct G<T> {}
44

test/Interop/Cxx/class/closure-thunk-irgen.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,7 @@ public func testClosureToBlock() {
2121
}
2222

2323
// CHECK: define internal void @"$s4main20testClosureToFuncPtryyFySo10NonTrivialVcfU_To"(ptr %[[V0:.*]])
24-
// CHECK: %[[V1:.*]] = alloca %{{.*}}, align 8
25-
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr %[[V1]])
26-
// CHECK-NEXT: call {{void|ptr}} @_ZN10NonTrivialC{{1|2}}ERKS_(ptr %[[V1]], ptr %[[V0]])
27-
// CHECK-NEXT: call swiftcc void @"$s4main20testClosureToFuncPtryyFySo10NonTrivialVcfU_"(ptr noalias dereferenceable(8) %[[V1]])
28-
// CHECK-NEXT: call {{void|ptr}} @_ZN10NonTrivialD{{1|2}}Ev(ptr %[[V1]])
29-
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr %[[V1]])
24+
// CHECK: call swiftcc void @"$s4main20testClosureToFuncPtryyFySo10NonTrivialVcfU_"(ptr noalias dereferenceable(8) %[[V0]])
3025
// CHECK-NEXT: ret void
3126

3227
public func testClosureToFuncPtr() {

test/Interop/Cxx/class/closure-thunk.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,8 @@ public func testClosureToBlock() {
4444

4545
// CHECK: sil private [thunk] @$s4main20testClosureToFuncPtryyFySo10NonTrivialVcfU_To : $@convention(c) (@in_cxx NonTrivial) -> () {
4646
// CHECK: bb0(%[[V0:.*]] : $*NonTrivial):
47-
// CHECK: %[[V1:.*]] = alloc_stack $NonTrivial
48-
// CHECK: copy_addr %[[V0]] to [init] %[[V1]] : $*NonTrivial
4947
// CHECK: %[[V3:.*]] = function_ref @$s4main20testClosureToFuncPtryyFySo10NonTrivialVcfU_ : $@convention(thin) (@in_guaranteed NonTrivial) -> ()
50-
// CHECK: %[[V4:.*]] = apply %[[V3]](%[[V1]]) : $@convention(thin) (@in_guaranteed NonTrivial) -> ()
51-
// CHECK: destroy_addr %[[V1]] : $*NonTrivial
52-
// CHECK: dealloc_stack %[[V1]] : $*NonTrivial
48+
// CHECK: %[[V4:.*]] = apply %[[V3]](%[[V0]]) : $@convention(thin) (@in_guaranteed NonTrivial) -> ()
5349
// CHECK: return %[[V4]] : $()
5450

5551
public func testClosureToFuncPtr() {

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ public func testStructWithCopyConstructorAndValue() -> Bool {
2727
// CHECK: [[MEMBER:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
2828
// CHECK: [[OBJ:%.*]] = alloca %TSo42StructWithSubobjectCopyConstructorAndValueV
2929
// CHECK: alloca %TSo33StructWithCopyConstructorAndValueV
30-
// CHECK: [[TMP:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
3130
// CHECK: call {{.*}}@{{_ZN33StructWithCopyConstructorAndValueC(1|2)Ei|"\?\?0StructWithCopyConstructorAndValue@@QEAA@H@Z"}}(ptr {{(noalias )?}}[[MEMBER]], i32 42)
32-
// CHECK: [[TEMP_MEMBER:%.*]] = getelementptr inbounds{{.*}} %TSo33StructWithCopyConstructorAndValueV, ptr [[TMP]], i32 0, i32 0
31+
// CHECK: getelementptr inbounds{{.*}} %TSo42StructWithSubobjectCopyConstructorAndValueV, ptr [[OBJ]]
32+
// CHECK: [[M1:%.*]] = getelementptr inbounds{{.*}} %TSo42StructWithSubobjectCopyConstructorAndValueV, ptr [[OBJ]], i32 0, i32 0
33+
// CHECK: [[TEMP_MEMBER:%.*]] = getelementptr inbounds{{.*}} %TSo33StructWithCopyConstructorAndValueV, ptr [[M1]], i32 0, i32 0
3334
// CHECK: [[TEMP_MEMBER_VALUE:%.*]] = getelementptr inbounds{{.*}} %Ts5Int32V, ptr [[TEMP_MEMBER]], i32 0, i32 0
3435
// CHECK: [[LHS:%.*]] = load i32, ptr [[TEMP_MEMBER_VALUE]]
3536
// CHECK: [[OUT:%.*]] = icmp eq i32 [[LHS]], 42
@@ -44,11 +45,11 @@ public func testStructWithSubobjectCopyConstructorAndValue() -> Bool {
4445
// CHECK: [[MEMBER:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
4546
// CHECK: [[OBJ:%.*]] = alloca %TSo037StructWithCopyConstructorAndSubobjectcdE5ValueV
4647
// CHECK: [[TEMP:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
47-
// CHECK: [[TEMP2:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
4848
// CHECK: call {{.*}}@{{_ZN33StructWithCopyConstructorAndValueC(1|2)Ei|"\?\?0StructWithCopyConstructorAndValue@@QEAA@H@Z"}}(ptr {{(noalias )?}}[[MEMBER]], i32 42)
4949
// CHECK: call {{.*}}@{{_ZN33StructWithCopyConstructorAndValueC(1|2)ERKS_|"\?\?0StructWithCopyConstructorAndValue@@QEAA@AEBU0@@Z"}}(ptr [[TEMP]], ptr [[MEMBER]])
5050
// CHECK: call {{.*}}@{{_ZN60StructWithCopyConstructorAndSubobjectCopyConstructorAndValueC(1|2)E33StructWithCopyConstructorAndValue|"\?\?0StructWithCopyConstructorAndSubobjectCopyConstructorAndValue@@QEAA@UStructWithCopyConstructorAndValue@@@Z"}}(ptr {{(noalias )?}}[[OBJ]], ptr [[TEMP]])
51-
// CHECK: [[TEMP_MEMBER:%.*]] = getelementptr inbounds{{.*}} %TSo33StructWithCopyConstructorAndValueV, ptr [[TEMP2]], i32 0, i32 0
51+
// CHECK: [[M1:%.*]] = getelementptr inbounds{{.*}} %TSo037StructWithCopyConstructorAndSubobjectcdE5ValueV, ptr [[OBJ]], i32 0, i32 0
52+
// CHECK: [[TEMP_MEMBER:%.*]] = getelementptr inbounds{{.*}} %TSo33StructWithCopyConstructorAndValueV, ptr [[M1]], i32 0, i32 0
5253
// CHECK: [[TEMP_MEMBER_VAL:%.*]] = getelementptr inbounds{{.*}} %Ts5Int32V, ptr [[TEMP_MEMBER]], i32 0, i32 0
5354
// CHECK: [[LHS:%.*]] = load i32, ptr [[TEMP_MEMBER_VAL]]
5455
// CHECK: [[OUT:%.*]] = icmp eq i32 [[LHS]], 42
@@ -73,9 +74,8 @@ public func test(obj: StructWithCopyConstructorAndValue) -> Bool {
7374
}
7475

7576
// CHECK-LABEL: define {{.*}}i1 @"$s4main4test3objSbSo42StructWithSubobjectCopyConstructorAndValueV_tF"(ptr noalias dereferenceable(4) %0)
76-
// CHECK: [[TMP:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
7777
// CHECK: [[MEMBER:%.*]] = getelementptr inbounds{{.*}} %TSo42StructWithSubobjectCopyConstructorAndValueV, ptr %0, i32 0, i32 0
78-
// CHECK: [[VAL:%.*]] = getelementptr inbounds{{.*}} %TSo33StructWithCopyConstructorAndValueV, ptr [[TMP]], i32 0, i32 0
78+
// CHECK: [[VAL:%.*]] = getelementptr inbounds{{.*}} %TSo33StructWithCopyConstructorAndValueV, ptr [[MEMBER]], i32 0, i32 0
7979
// CHECK: [[VAL_VAL:%.*]] = getelementptr inbounds{{.*}} %Ts5Int32V, ptr [[VAL]], i32 0, i32 0
8080
// CHECK: [[LHS:%.*]] = load i32, ptr [[VAL_VAL]]
8181
// CHECK: [[OUT:%.*]] = icmp eq i32 [[LHS]], 42
@@ -85,7 +85,7 @@ public func test(obj: StructWithSubobjectCopyConstructorAndValue) -> Bool {
8585
}
8686

8787
// CHECK-LABEL: define {{.*}}i1 @"$s4main4test3objSbSo037StructWithCopyConstructorAndSubobjectfgH5ValueV_tF"(ptr noalias dereferenceable(4) %0)
88-
// CHECK:[[TEMP:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
88+
// CHECK:[[TEMP:%.*]] = getelementptr inbounds{{.*}} %TSo037StructWithCopyConstructorAndSubobjectcdE5ValueV, ptr %0, i32 0, i32 0
8989
// CHECK:[[VAL:%.*]] = getelementptr inbounds{{.*}} %TSo33StructWithCopyConstructorAndValueV, ptr [[TEMP]], i32 0, i32 0
9090
// CHECK:[[VAL_VAL:%.*]] = getelementptr inbounds{{.*}} %Ts5Int32V, ptr [[VAL]], i32 0, i32 0
9191
// CHECK:[[LHS:%.*]] = load i32, ptr [[VAL_VAL]]

test/Interop/Cxx/objc-correctness/call-to-generated-init-with-nsstring.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@ testSdump()
5656
// IR-TRIVIAL: }
5757

5858
// IR-NONTRIVIAL-LABEL: define {{.*}} swiftcc void @"$s4main9testSdumpyyF"()
59-
// IR-NONTRIVIAL: call {{.*}} @_ZN1SC1ERKS_
6059
// IR-NONTRIVIAL: call {{.*}} @_ZNK1S4dumpEv
60+
// IR-NONTRIVIAL: call {{.*}} @_ZN1SC1ERKS_
6161
// IR-NONTRIVIAL: call {{.*}} @_ZN1SD1Ev

test/SILOptimizer/inline_arrays.swift

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
// RUN: %target-swift-frontend -primary-file %s -O -disable-availability-checking -module-name=test -emit-sil | %FileCheck %s
1+
// RUN: %target-swift-frontend -primary-file %s -O -disable-availability-checking -module-name=test -emit-sil | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT
2+
// RUN: %target-swift-frontend -primary-file %s -Onone -disable-availability-checking -module-name=test -emit-sil | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ONONE
23

34
// REQUIRES: swift_stdlib_no_asserts, optimized_stdlib
45

56
// CHECK-LABEL: sil @$s4test0A9Subscriptys5UInt8Vs11InlineArrayVy$255_ADGz_SitF :
6-
// CHECK: [[S:%.*]] = struct_element_addr %0, #InlineArray._storage
7+
// CHECK-OPT: [[S:%.*]] = struct_element_addr %0, #InlineArray._storage
8+
// CHECK-ONONE: [[ACC:%.*]] = begin_access [read] [static] %0
9+
// CHECK-ONONE: [[S:%.*]] = struct_element_addr [[ACC]], #InlineArray._storage
710
// CHECK: [[BA:%.*]] = vector_base_addr [[S]]
811
// CHECK: [[EA:%.*]] = index_addr [stack_protection] [[BA]],
9-
// CHECK: [[E:%.*]] = load [[EA]]
12+
// CHECK-OPT: [[E:%.*]] = load [[EA]]
13+
// CHECK-ONONE: [[ACC2:%.*]] = begin_access [read] [unsafe] [[EA]]
14+
// CHECK-ONONE: [[E:%.*]] = load [[ACC2]]
1015
// CHECK: return [[E]]
1116
// CHECK: } // end sil function '$s4test0A9Subscriptys5UInt8Vs11InlineArrayVy$255_ADGz_SitF'
1217
public func testSubscript(_ a: inout InlineArray<256, UInt8>, _ i: Int) -> UInt8 {
@@ -25,11 +30,31 @@ public final class C {
2530
// CHECK: [[S:%.*]] = struct_element_addr [[CA]], #InlineArray._storage
2631
// CHECK: [[BA:%.*]] = vector_base_addr [[S]]
2732
// CHECK: [[EA:%.*]] = index_addr [stack_protection] [[BA]],
28-
// CHECK: [[E:%.*]] = load [[EA]]
33+
// CHECK-OPT: [[E:%.*]] = load [[EA]]
34+
// CHECK-ONONE: [[ACC2:%.*]] = begin_access [read] [unsafe] [[EA]]
35+
// CHECK-ONONE: [[E:%.*]] = load [[ACC2]]
2936
// CHECK: return [[E]]
3037
// CHECK: } // end sil function '$s4test1CC0A9Subscriptys5UInt8VSiF'
3138
public func testSubscript(_ i: Int) -> UInt8 {
3239
return a[i]
3340
}
3441
}
3542

43+
public struct S {
44+
let a: InlineArray<7000, UInt8>
45+
46+
// CHECK-LABEL: sil @$s4test1SV0A9Subscriptys5UInt8VSiF :
47+
// CHECK: [[A:%.*]] = struct_element_addr %1, #S.a
48+
// CHECK: [[S:%.*]] = struct_element_addr [[A]], #InlineArray._storage
49+
// CHECK: [[BA:%.*]] = vector_base_addr [[S]]
50+
// CHECK: [[EA:%.*]] = index_addr [stack_protection] [[BA]],
51+
// CHECK-OPT: [[E:%.*]] = load [[EA]]
52+
// CHECK-ONONE: [[ACC2:%.*]] = begin_access [read] [unsafe] [[EA]]
53+
// CHECK-ONONE: [[E:%.*]] = load [[ACC2]]
54+
// CHECK: return [[E]]
55+
// CHECK: } // end sil function '$s4test1SV0A9Subscriptys5UInt8VSiF'
56+
public func testSubscript(_ i: Int) -> UInt8 {
57+
return a[i]
58+
}
59+
}
60+

0 commit comments

Comments
 (0)