1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
// RUN: %target-swift-frontend -enable-copy-propagation=requested-passes-only -enable-lexical-lifetimes=false -emit-sil %s -O | %FileCheck %s
@_optimize(none)
@inline(never)
func blackhole<T>(_ x:T) {
}
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply9testapplySiyF :
// CHECK-NOT: alloc_box
// CHECK: [[STK:%.*]] = alloc_stack [var_decl] $Int, var, name "x"
// CHECK-LABEL: } // end sil function '$s26allocboxtostack_localapply9testapplySiyF'
@inline(never)
public func testapply() -> Int {
var x = 0
@inline(never)
func bar() -> Int {
blackhole(x)
return x + 1
}
@inline(never)
func bas() -> Int {
return bar()
}
return bas()
}
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply12testtryapplySiyKF :
// CHECK-NOT: alloc_box
// CHECK: [[STK:%.*]] = alloc_stack [var_decl] $Int, var, name "x"
// CHECK-LABEL: } // end sil function '$s26allocboxtostack_localapply12testtryapplySiyKF'
@inline(never)
public func testtryapply() throws -> Int {
var x = 0
@inline(never)
func bar() throws -> Int {
blackhole(x)
return x + 1
}
@inline(never)
func bas() throws -> Int {
return try bar()
}
let res = try bas()
return res
}
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply16testpartialapplySiyF :
// CHECK-NOT: alloc_box
// CHECK: [[STK:%.*]] = alloc_stack [var_decl] $Int, var, name "x"
// CHECK-LABEL: } // end sil function '$s26allocboxtostack_localapply16testpartialapplySiyF'
@inline(never)
public func testpartialapply() -> Int {
var x = 0
@inline(never)
func bar() -> Int {
blackhole(x)
return x + 1
}
@inline(never)
func bas() -> Int {
return bar()
}
return {bas()}()
}
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply12testtwoboxesSiyF :
// CHECK-NOT: alloc_box
// CHECK: [[STK1:%.*]] = alloc_stack [var_decl] $Int, var, name "x"
// CHECK: [[STK2:%.*]] = alloc_stack [var_decl] $Int, var, name "y"
// CHECK-LABEL: } // end sil function '$s26allocboxtostack_localapply12testtwoboxesSiyF'
@inline(never)
public func testtwoboxes() -> Int {
var x = 0
var y = 0
@inline(never)
func bar() -> Int {
blackhole(x)
return x + y
}
@inline(never)
func bas() -> Int {
return bar()
}
return bas()
}
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply14testboxescapesyycyF :
// CHECK: alloc_box ${ var Int }, var, name "x"
// CHECK-LABEL: } // end sil function '$s26allocboxtostack_localapply14testboxescapesyycyF'
@inline(never)
public func testboxescapes() -> (() -> ()) {
var x = 0
@inline(never)
func bar() -> (() -> ()) {
return {x + 1}
}
@inline(never)
func bas() -> (() -> ()) {
return bar()
}
return bas()
}
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply9testrecurSiyF :
// CHECK: alloc_box ${ var Int }, var, name "x"
// CHECK-LABEL: } // end sil function '$s26allocboxtostack_localapply9testrecurSiyF'
@inline(never)
public func testrecur() -> Int {
var x = 0
@inline(never)
func bar() -> Int {
return x + bas()
}
@inline(never)
func bas() -> Int {
return bar()
}
return bas() + bar()
}
// Test to make sure AppliesToSpecialize in AllocBoxToStack is populated correctly when there are common function calls for multiple allox_boxes.
// Order of function calls constructed in PromotedOperands: bar common bas common.
// AppliesToSpecialize should have the order: bar bas common.
// Only then, the functions get specialized correctly, and we won't see an assert in checkNoPromotedBoxInApply.
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply8testdfs1SiyF :
// CHECK-NOT: alloc_box ${ var Int }, var, name "x"
// CHECK-NOT: alloc_box ${ var Int }, var, name "y"
// CHECK-LABEL:} // end sil function '$s26allocboxtostack_localapply8testdfs1SiyF'
@inline(never)
public func testdfs1() -> Int {
var x = 0
var y = 0
@inline(never)
func bar() -> Int {
return x
}
@inline(never)
func bas() -> Int {
return y
}
@inline(never)
func common() -> Int {
return bar() + bas()
}
return common()
}
// Test to make sure we don't optimize the case when we have an inner common function call for multiple boxes.
// We don't optimize this case now, because we don't have additional logic to correctly construct AppliesToSpecialize
// Order of function calls constructed in PromotedOperands: bar innercommon local1 bas innercommon local2
// AppliesToSpecialize should have the order: bar bas innercommon local1 local2
// Since we don't maintain any tree like data structure with more info on the call tree, this is not possible to construct today
// CHECK-LABEL: sil [noinline] @$s26allocboxtostack_localapply8testdfs2SiyF :
// CHECK: alloc_box ${ var Int }, var, name "x"
// CHECK: alloc_box ${ var Int }, var, name "y"
// CHECK-LABEL:} // end sil function '$s26allocboxtostack_localapply8testdfs2SiyF'
@inline(never)
public func testdfs2() -> Int {
var x = 0
var y = 0
@inline(never)
func bar() -> Int {
return x
}
@inline(never)
func bas() -> Int {
return y
}
@inline(never)
func innercommon() -> Int {
return bar() + bas()
}
@inline(never)
func local1() -> Int {
return innercommon()
}
@inline(never)
func local2() -> Int {
return innercommon()
}
return local1() + local2()
}
|