Files
swift-mirror/test/SILOptimizer/inline_devirtualize_specialize.sil
T
Mark Lacey 82fd057eaf Remove devirtualization and specialization from the inliner.
Now that we process functions in bottom-up order in the pass manager and
have a mechanism to restart the pass pipeline on the current
function (or on a newly created callee function), we can split these
passes back out from the inliner and end up with the same benefits we
had from initially integrating them. We get the further benefit of fully
optimizing newly created callee functions before continuing with the
function that resulted in the creation of those callee
functions (e.g. as a result of a specialization pass running).
2016-02-04 08:52:01 -08:00

103 lines
3.1 KiB
Plaintext

// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -devirtualizer -generic-specializer -dce | FileCheck %s
sil_stage canonical
import Builtin
protocol P {
func foo() -> Builtin.Int1
}
struct S : P {
func foo() -> Builtin.Int1
}
private class C : P {
func foo() -> Builtin.Int1
}
// CHECK-LABEL: struct_target
sil [always_inline] @struct_target : $@convention(method) (S) -> Builtin.Int1 {
// CHECK: bb0
bb0(%0 : $S):
%2 = integer_literal $Builtin.Int1, 0
return %2 : $Builtin.Int1
}
// CHECK-LABEL: struct_witness
sil [always_inline] [thunk] @struct_witness : $@convention(witness_method) (@in_guaranteed S) -> Builtin.Int1 {
// CHECK: bb0
bb0(%0 : $*S):
// CHECK-NOT: load
%1 = load %0 : $*S
// CHECK-NOT: function_ref
%2 = function_ref @struct_target : $@convention(method) (S) -> Builtin.Int1
// CHECK-NOT: apply
%3 = apply %2(%1) : $@convention(method) (S) -> Builtin.Int1
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK: return [[ZERO]]
return %3 : $Builtin.Int1
}
// CHECK-LABEL: struct_caller
sil shared @struct_caller : $@convention(thin) (@in S) -> Builtin.Int1 {
// CHECK: bb0
bb0(%0 : $*S):
// CHECK-NOT: witness_method
%2 = witness_method $S, #P.foo!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1
// CHECK-NOT: apply
%3 = apply %2<S>(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK: return [[ZERO]]
destroy_addr %0 : $*S
return %3 : $Builtin.Int1
}
// CHECK-LABEL: class_target
sil [always_inline] @class_target : $@convention(method) (@guaranteed C) -> Builtin.Int1 {
bb0(%0 : $C):
%1 = integer_literal $Builtin.Int1, -1
return %1 : $Builtin.Int1
}
// CHECK-LABEL: class_witness
sil [always_inline] [thunk] @class_witness : $@convention(witness_method) (@in_guaranteed C) -> Builtin.Int1 {
// CHECK: bb0
bb0(%0 : $*C):
// CHECK-NOT: load
%1 = load %0 : $*C
// CHECK-NOT: class_method
%3 = class_method %1 : $C, #C.foo!1 : C -> () -> Builtin.Int1 , $@convention(method) (@guaranteed C) -> Builtin.Int1
// CHECK-NOT: apply
%4 = apply %3(%1) : $@convention(method) (@guaranteed C) -> Builtin.Int1
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK: return [[ONE]]
return %4 : $Builtin.Int1
}
// CHECK-LABEL: class_caller
sil shared @class_caller : $@convention(thin) (@in C) -> Builtin.Int1 {
// CHECK: bb0
bb0(%0 : $*C):
// CHECK-NOT: witness_method
%1 = witness_method $C, #P.foo!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1
// CHECK-NOT: apply
%2 = apply %1<C>(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1
destroy_addr %0 : $*C
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK: return [[ONE]]
return %2 : $Builtin.Int1
}
sil_vtable C {
#C.foo!1: class_target
}
sil_witness_table C: P module main {
method #P.foo!1: @class_witness
}
sil_witness_table S: P module main {
method #P.foo!1: @struct_witness
}