Skip to content

Commit

Permalink
Enable large loadable types by default
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe Shajrawi committed Aug 3, 2017
1 parent 25ac930 commit 84994dc
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 111 deletions.
2 changes: 1 addition & 1 deletion include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class SILOptions {
bool EnableMandatorySemanticARCOpts = false;

/// \brief Enable large loadable types IRGen pass.
bool EnableLargeLoadableTypes = false;
bool EnableLargeLoadableTypes = true;

/// Enables the "fully fragile" resilience strategy.
///
Expand Down
17 changes: 16 additions & 1 deletion lib/IRGen/LoadableByAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,22 @@ static void rewriteFunction(StructLoweringState &pass,
auto retOp = instr->getOperand();
auto storageType = retOp->getType();
if (storageType.isAddress()) {
createOutlinedCopyCall(retBuilder, retOp, retArg, pass, &regLoc);
// There *might* be a dealloc_stack that already released this value
// we should create the copy *before* the epilogue's deallocations
auto IIR = instr->getReverseIterator();
for (++IIR; IIR != instr->getParent()->rend(); ++IIR) {
auto *currIIInstr = &(*IIR);
if (currIIInstr->getKind() != ValueKind::DeallocStackInst) {
// got the right location - stop.
--IIR;
break;
}
}
auto II = (IIR != instr->getParent()->rend())
? IIR->getIterator()
: instr->getParent()->begin();
SILBuilder retCopyBuilder(II);
createOutlinedCopyCall(retCopyBuilder, retOp, retArg, pass, &regLoc);
} else {
if (pass.F->hasQualifiedOwnership()) {
retBuilder.createStore(regLoc, retOp, retArg,
Expand Down
2 changes: 2 additions & 0 deletions test/DebugInfo/enum.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | %FileCheck %s
// RUN: %target-swift-frontend -primary-file %s -emit-ir -gdwarf-types -o - | %FileCheck %s --check-prefix=DWARF

// UNSUPPORTED: OS=watchos

protocol P {}

enum Either {
Expand Down
3 changes: 3 additions & 0 deletions test/DebugInfo/guard-let.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s --check-prefix=CHECK2

// UNSUPPORTED: OS=watchos

func use<T>(_ t: T) {}

public func f(_ i : Int?)
Expand Down
8 changes: 4 additions & 4 deletions test/IRGen/copy_value_destroy_value.sil
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ bb0(%0 : $Builtin.Int32):
}

// CHECK: define{{( protected)?}} swiftcc void @non_trivial(
// CHECK: [[GEP1:%.*]] = getelementptr inbounds %T019copy_value_destroy_B03FooV, %T019copy_value_destroy_B03FooV* %0, i32 0, i32 2
// CHECK: [[VAL1:%.*]] = load %swift.refcounted*, %swift.refcounted** [[GEP1]], align 8
// CHECK: [[GEP2:%.*]] = getelementptr inbounds %T019copy_value_destroy_B03FooV, %T019copy_value_destroy_B03FooV* %0, i32 0, i32 5
// CHECK: [[VAL2:%.*]] = load %swift.refcounted*, %swift.refcounted** [[GEP2]], align 8
// CHECK: [[GEP1:%.*]] = getelementptr inbounds %T019copy_value_destroy_B03FooV, %T019copy_value_destroy_B03FooV* %1, i32 0, i32 2
// CHECK-NEXT: [[VAL1:%.*]] = load %swift.refcounted*, %swift.refcounted** [[GEP1]], align 8
// CHECK: [[GEP2:%.*]] = getelementptr inbounds %T019copy_value_destroy_B03FooV, %T019copy_value_destroy_B03FooV* %1, i32 0, i32 5
// CHECK-NEXT: [[VAL2:%.*]] = load %swift.refcounted*, %swift.refcounted** [[GEP2]], align 8
// CHECK: call void @swift_rt_swift_retain(%swift.refcounted* [[VAL1]])
// CHECK: call void @swift_rt_swift_retain(%swift.refcounted* [[VAL2]])
// CHECK: call void @swift_rt_swift_release(%swift.refcounted* [[VAL1]])
Expand Down
22 changes: 0 additions & 22 deletions test/IRGen/enum.sil
Original file line number Diff line number Diff line change
Expand Up @@ -221,27 +221,17 @@ sil @singleton_switch_arg : $(Singleton) -> () {
// CHECK-32: entry:
entry(%u : $Singleton):
// CHECK-32: [[CAST:%.*]] = bitcast %T4enum9SingletonO* %0 to <{ i64, i64 }>*
// CHECK-32: [[GEP1:%.*]] = getelementptr inbounds <{ i64, i64 }>, <{ i64, i64 }>* [[CAST]], i32 0, i32 0
// CHECK-32: [[ELT1:%.*]] = load i64, i64* [[GEP1]]
// CHECK-32: [[GEP2:%.*]] = getelementptr inbounds <{ i64, i64 }>, <{ i64, i64 }>* [[CAST]], i32 0, i32 1
// CHECK-32: [[ELT2:%.*]] = load i64, i64* [[GEP2]]
// CHECK-64: br label %[[PREDEST:[0-9]+]]
// CHECK-32: br label %[[PREDEST:[0-9]+]]
switch_enum %u : $Singleton, case #Singleton.value!enumelt.1: dest

// CHECK-64: ; <label>:[[PREDEST]]
// CHECK-64: br label %[[DEST:[0-9]+]]
// CHECK-64: ; <label>:[[DEST]]
// CHECK-32: ; <label>:[[PREDEST]]
// CHECK-32: br label %[[DEST:[0-9]+]]
// CHECK-32: ; <label>:[[DEST]]
dest(%u2 : $(Builtin.Int64, Builtin.Int64)):
// CHECK-64: {{%.*}} = phi i64 [ %0, %[[PREDEST]] ]
// CHECK-64: {{%.*}} = phi i64 [ %1, %[[PREDEST]] ]
// CHECK-64: ret void
// CHECK-32: {{%.*}} = phi i64 [ [[ELT1]], %[[PREDEST]] ]
// CHECK-32: {{%.*}} = phi i64 [ [[ELT2]], %[[PREDEST]] ]
// CHECK-32: ret void
%x = tuple ()
return %x : $()
}
Expand Down Expand Up @@ -746,20 +736,8 @@ enum AggregateSinglePayload2 {
// CHECK-32: define{{( protected)?}} swiftcc void @aggregate_single_payload_unpack_2(%T4enum23AggregateSinglePayload2O* noalias nocapture dereferenceable(16)) {{.*}} {
sil @aggregate_single_payload_unpack_2 : $@convention(thin) (AggregateSinglePayload2) -> () {
entry(%u : $AggregateSinglePayload2):
// CHECK-32: [[CAST:%.*]] = bitcast %T4enum23AggregateSinglePayload2O* %0 to { i32, i32, i32, i32 }*
// CHECK-32: [[GEP:%.*]] = getelementptr inbounds {{.*}} [[CAST]], i32 0, i32 0
// CHECK-32: [[LOAD1:%.*]] = load i32, i32* [[GEP]]
// CHECK-32: [[LOAD2:%.*]] = load i32, i32* {{.*}}
// CHECK-32: [[LOAD3:%.*]] = load i32, i32* {{.*}}
// CHECK-32: [[LOAD4:%.*]] = load i32, i32* {{.*}}
switch_enum %u : $AggregateSinglePayload2, case #AggregateSinglePayload2.x!enumelt.1: x_dest, default end

// CHECK-32: [[TRUNC:%.*]] = trunc [[WORD]] [[LOAD1]] to i21
// CHECK-32: phi i21 [ [[TRUNC]]
// CHECK-32: phi [[WORD]] [ [[LOAD2]]
// CHECK-32: phi [[WORD]] [ [[LOAD3]]
// CHECK-32: phi [[WORD]] [ [[LOAD4]]

// CHECK-64: [[TRUNC:%.*]] = trunc [[WORD]] %0 to i21
// CHECK-64: phi i21 [ [[TRUNC]]
// CHECK-64: phi [[WORD]] [ %1
Expand Down
28 changes: 13 additions & 15 deletions test/IRGen/indirect_argument.sil
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ struct HugeAlignment {
}

// TODO: could be the context param
// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_method(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}))
// CHECK: [[TMP:%.*]] = alloca
// CHECK: call swiftcc void @huge_method(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) [[TMP]])
// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_method(%T17indirect_argument4HugeV* noalias nocapture swiftself dereferenceable({{.*}}))
// CHECK-NOT: alloca
// CHECK: call swiftcc void @huge_method(%T17indirect_argument4HugeV* noalias nocapture swiftself dereferenceable({{.*}}) %0)
sil @huge_method : $@convention(method) Huge -> () {
entry(%x : $Huge):
%f = function_ref @huge_method : $@convention(method) Huge -> ()
Expand All @@ -23,8 +23,8 @@ entry(%x : $Huge):
}

// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_param(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}))
// CHECK: [[TMP:%.*]] = alloca
// CHECK: call swiftcc void @huge_param(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) [[TMP]])
// CHECK-NOT: alloca
// CHECK: call swiftcc void @huge_param(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %0)
sil @huge_param : $@convention(thin) Huge -> () {
entry(%x : $Huge):
%f = function_ref @huge_param : $@convention(thin) Huge -> ()
Expand All @@ -33,8 +33,8 @@ entry(%x : $Huge):
}

// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_alignment_param(%T17indirect_argument13HugeAlignmentV* noalias nocapture dereferenceable({{.*}}))
// CHECK: [[TMP:%.*]] = alloca
// CHECK: call swiftcc void @huge_alignment_param(%T17indirect_argument13HugeAlignmentV* noalias nocapture dereferenceable({{.*}}) [[TMP]])
// CHECK-NOT: alloca
// CHECK: call swiftcc void @huge_alignment_param(%T17indirect_argument13HugeAlignmentV* noalias nocapture dereferenceable({{.*}}) %0)
sil @huge_alignment_param : $@convention(thin) HugeAlignment -> () {
entry(%x : $HugeAlignment):
%f = function_ref @huge_alignment_param : $@convention(thin) HugeAlignment -> ()
Expand All @@ -43,9 +43,8 @@ entry(%x : $HugeAlignment):
}

// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_param_and_return(%T17indirect_argument4HugeV* noalias nocapture sret, %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}))
// CHECK: [[TMP_ARG:%.*]] = alloca
// CHECK: [[TMP_RET:%.*]] = alloca
// CHECK: call swiftcc void @huge_param_and_return(%T17indirect_argument4HugeV* noalias nocapture sret [[TMP_RET]], %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) [[TMP_ARG]])
// CHECK: call swiftcc void @huge_param_and_return(%T17indirect_argument4HugeV* noalias nocapture sret [[TMP_RET]], %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %1)
sil @huge_param_and_return : $@convention(thin) Huge -> Huge {
entry(%x : $Huge):
%f = function_ref @huge_param_and_return : $@convention(thin) Huge -> Huge
Expand All @@ -54,8 +53,8 @@ entry(%x : $Huge):
}

// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_param_and_indirect_return(%T17indirect_argument4HugeV* noalias nocapture sret, %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}))
// CHECK: [[TMP_ARG:%.*]] = alloca
// CHECK: call swiftcc void @huge_param_and_indirect_return(%T17indirect_argument4HugeV* noalias nocapture sret %0, %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) [[TMP_ARG]])
// CHECK-NOT: alloca
// CHECK: call swiftcc void @huge_param_and_indirect_return(%T17indirect_argument4HugeV* noalias nocapture sret %0, %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %1)
sil @huge_param_and_indirect_return : $@convention(thin) (Huge) -> @out Huge {
entry(%o : $*Huge, %x : $Huge):
%f = function_ref @huge_param_and_indirect_return : $@convention(thin) (Huge) -> @out Huge
Expand All @@ -64,10 +63,10 @@ entry(%o : $*Huge, %x : $Huge):
}

// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_partial_application(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}), %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}))
// CHECK: [[TMP_ARG:%.*]] = alloca
// CHECK-NOT: alloca
// CHECK: [[CLOSURE:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject
// CHECK: bitcast %swift.refcounted* [[CLOSURE]] to <{ %swift.refcounted, %T17indirect_argument4HugeV }>*
// CHECK: call swiftcc void @_T024huge_partial_applicationTA(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) [[TMP_ARG]], %swift.refcounted* swiftself [[CLOSURE]])
// CHECK: call swiftcc void @_T024huge_partial_applicationTA(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %0, %swift.refcounted* swiftself [[CLOSURE]])
// CHECK: define internal swiftcc void @_T024huge_partial_applicationTA(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}), %swift.refcounted* swiftself)
// CHECK: [[TMP_ARG:%.*]] = alloca
// CHECK-NOT: tail
Expand All @@ -81,11 +80,10 @@ entry(%x : $Huge, %y : $Huge):
}

// CHECK-LABEL: define{{( protected)?}} swiftcc void @huge_partial_application_stret(%T17indirect_argument4HugeV* noalias nocapture sret, %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}), %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}))
// CHECK: [[TMP_ARG:%.*]] = alloca
// CHECK: [[TMP_RET:%.*]] = alloca
// CHECK: [[CLOSURE:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject
// CHECK: bitcast %swift.refcounted* [[CLOSURE]] to <{ %swift.refcounted, %T17indirect_argument4HugeV }>*
// CHECK: call swiftcc void @_T030huge_partial_application_stretTA(%T17indirect_argument4HugeV* noalias nocapture sret [[TMP_RET]], %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) [[TMP_ARG]], %swift.refcounted* swiftself [[CLOSURE]])
// CHECK: call swiftcc void @_T030huge_partial_application_stretTA(%T17indirect_argument4HugeV* noalias nocapture sret [[TMP_RET]], %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %1, %swift.refcounted* swiftself [[CLOSURE]])
// CHECK: define internal swiftcc void @_T030huge_partial_application_stretTA(%T17indirect_argument4HugeV* noalias nocapture sret, %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}), %swift.refcounted* swiftself)
// CHECK: [[TMP_ARG:%.*]] = alloca
// CHECK-NOT: tail
Expand Down
22 changes: 3 additions & 19 deletions test/IRGen/partial_apply.sil
Original file line number Diff line number Diff line change
Expand Up @@ -472,26 +472,10 @@ sil public_external @generic_indirect_return2 : $@convention(thin) <T> (Int) ->
// CHECK-LABEL: define{{.*}} @partial_apply_generic_indirect_return2
// CHECK: insertvalue {{.*}}_T024generic_indirect_return2TA

// CHECK-LABEL: define internal swiftcc { i64, i64, i64, i8 } @_T024generic_indirect_return2TA(%swift.refcounted* swiftself) #0 {
// CHECK: [[TMP:%.*]] = alloca %T13partial_apply12GenericEnum2OySiG
// CHECK: [[CASTED_ADDR:%.*]] = bitcast %T13partial_apply12GenericEnum2OySiG* [[TMP]] to %T13partial_apply12GenericEnum2O*
// CHECK-LABEL: define internal swiftcc void @_T024generic_indirect_return2TA(%T13partial_apply12GenericEnum2OySiG* noalias nocapture sret, %swift.refcounted* swiftself) #0 {
// CHECK: [[CASTED_ADDR:%.*]] = bitcast %T13partial_apply12GenericEnum2OySiG* %0 to %T13partial_apply12GenericEnum2O*
// CHECK: call swiftcc void @generic_indirect_return2(%T13partial_apply12GenericEnum2O* noalias nocapture sret [[CASTED_ADDR]]
// CHECK: [[SUBST_ADDR:%.*]] = bitcast %T13partial_apply12GenericEnum2OySiG* [[TMP]] to { i64, i64, i64 }*
// CHECK: [[ELT_ADDR:%.*]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[SUBST_ADDR]], i32 0, i32 0
// CHECK: [[ELT:%.*]] = load i64, i64* [[ELT_ADDR]]
// CHECK: [[ELT_ADDR:%.*]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[SUBST_ADDR]], i32 0, i32 1
// CHECK: [[ELT2:%.*]] = load i64, i64* [[ELT_ADDR]]
// CHECK: [[ELT_ADDR:%.*]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[SUBST_ADDR]], i32 0, i32 2
// CHECK: [[ELT3:%.*]] = load i64, i64* [[ELT_ADDR]]
// CHECK: [[ENUMTAGADDR:%.*]] = getelementptr inbounds %T13partial_apply12GenericEnum2OySiG, %T13partial_apply12GenericEnum2OySiG* [[TMP]], i32 0, i32 1
// CHECK: [[ENUMTAGBITADDR:%.*]] = bitcast [1 x i8]* [[ENUMTAGADDR]] to i1*
// CHECK: [[TAGBIT:%.*]] = load i1, i1* [[ENUMTAGBITADDR]]
// CHECK: [[ELT4:%.*]] = zext i1 [[TAGBIT]] to i8
// CHECK: [[TMP:%.*]] = insertvalue { i64, i64, i64, i8 } undef, i64 [[ELT]], 0
// CHECK: [[TMP2:%.*]] = insertvalue { i64, i64, i64, i8 } [[TMP]], i64 [[ELT2]], 1
// CHECK: [[TMP3:%.*]] = insertvalue { i64, i64, i64, i8 } [[TMP2]], i64 [[ELT3]], 2
// CHECK: [[TMP4:%.*]] = insertvalue { i64, i64, i64, i8 } [[TMP3]], i8 [[ELT4]], 3
// CHECK: ret { i64, i64, i64, i8 } [[TMP4]]
// CHECK: ret void
sil @partial_apply_generic_indirect_return2 : $@convention(thin) (Int) -> @callee_owned () -> @owned GenericEnum2<Int> {
bb0(%0 : $Int):
%fn = function_ref @generic_indirect_return2 :$@convention(thin) <T> (Int) -> @owned GenericEnum2<T>
Expand Down

0 comments on commit 84994dc

Please sign in to comment.