Skip to content

Commit 2ed480c

Browse files
authored
Merge pull request #35191 from meg-gupta/arraycountpropossa
Enable ArrayCountPropagation on OSSA
2 parents be8f4cc + d24d264 commit 2ed480c

File tree

2 files changed

+185
-6
lines changed

2 files changed

+185
-6
lines changed

lib/SILOptimizer/Transforms/ArrayCountPropagation.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ bool ArrayAllocation::recursivelyCollectUses(ValueBase *Def) {
123123
for (auto *Opd : Def->getUses()) {
124124
auto *User = Opd->getUser();
125125
// Ignore reference counting and debug instructions.
126-
if (isa<RefCountingInst>(User) ||
126+
if (isa<RefCountingInst>(User) || isa<DestroyValueInst>(User) ||
127127
isa<DebugValueInst>(User))
128128
continue;
129129

@@ -195,11 +195,6 @@ class ArrayCountPropagation : public SILFunctionTransform {
195195

196196
void run() override {
197197
auto &Fn = *getFunction();
198-
199-
// FIXME: Add ownership support.
200-
if (Fn.hasOwnership())
201-
return;
202-
203198
bool Changed = false;
204199
SmallVector<ApplyInst *, 16> DeadArrayCountCalls;
205200
// Propagate the count of array allocations to array.count users.
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all -array-count-propagation %s | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
8+
struct MyInt {
9+
@_hasStorage var _value: Builtin.Int64
10+
}
11+
12+
struct MyBool {}
13+
14+
struct _MyBridgeStorage {
15+
@_hasStorage var rawValue : Builtin.BridgeObject
16+
}
17+
18+
struct _MyArrayBuffer<T> {
19+
@_hasStorage var _storage : _MyBridgeStorage
20+
}
21+
22+
struct MyArray<T> {
23+
@_hasStorage var _buffer : _MyArrayBuffer<T>
24+
}
25+
26+
class Klass {
27+
}
28+
29+
sil [ossa] @swift_bufferAllocate : $@convention(thin)() -> @owned AnyObject
30+
sil [ossa] [_semantics "array.uninitialized"] @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
31+
sil [ossa] [_semantics "array.get_count"] @getCount : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
32+
sil [ossa] [_semantics "array.get_element"] @getElement : $@convention(method) (MyInt, MyBool, @guaranteed MyArray<MyInt>) -> @out MyInt
33+
sil [ossa] [_semantics "array.uninitialized"] @allocateUninitialized : $@convention(thin) (MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
34+
sil [ossa] [_semantics "array.finalize_intrinsic"] @finalize : $@convention(thin) (@owned MyArray<MyInt>) -> @owned MyArray<MyInt>
35+
sil [ossa] [_semantics "array.init"] @initRepeatedValueCount : $@convention(thin) (@in MyInt, MyInt, @thin MyArray<MyInt>.Type) -> @owned MyArray<MyInt>
36+
sil [ossa] [_semantics "array.init"] @initEmpty : $@convention(thin) (@thin MyArray<MyInt>.Type) -> @owned MyArray<MyInt>
37+
38+
// CHECK-LABEL: sil [ossa] @test_adoptStorage1 :
39+
// CHECK: [[COUNTVAL:%.*]] = integer_literal $Builtin.Int64, 3
40+
// CHECK: [[COUNT:%.*]] = struct $MyInt ([[COUNTVAL]]
41+
// CHECK: [[GETCOUNTFUN:%.*]] = function_ref @getCount
42+
// CHECK-NOT: apply [[GETCOUNTFUN]]
43+
// CHECK-LABEL: } // end sil function 'test_adoptStorage1'
44+
sil [ossa] @test_adoptStorage1 : $@convention(thin) () -> MyInt {
45+
bb0:
46+
%0 = integer_literal $Builtin.Int64, 3
47+
%1 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned AnyObject
48+
%2 = apply %1() : $@convention(thin) () -> @owned AnyObject
49+
%3 = struct $MyInt(%0 : $Builtin.Int64)
50+
%4 = metatype $@thin MyArray<MyInt>.Type
51+
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
52+
%6 = apply %5(%2, %3, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
53+
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
54+
debug_value %7 : $MyArray<MyInt>
55+
%f = function_ref @finalize : $@convention(thin) (@owned MyArray<MyInt>) -> @owned MyArray<MyInt>
56+
%a = apply %f(%7) : $@convention(thin) (@owned MyArray<MyInt>) -> @owned MyArray<MyInt>
57+
%9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
58+
%10 = apply %9(%a) : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
59+
destroy_value %a : $MyArray<MyInt>
60+
return %10 : $MyInt
61+
}
62+
63+
// CHECK-LABEL: sil [ossa] @test_allocateUninitialized :
64+
// CHECK: [[COUNTVAL:%.*]] = integer_literal $Builtin.Int64, 3
65+
// CHECK: [[COUNT:%.*]] = struct $MyInt ([[COUNTVAL]]
66+
// CHECK: [[GETCOUNTFUN:%.*]] = function_ref @getCount
67+
// CHECK-NOT: apply [[GETCOUNTFUN]]
68+
// CHECK-LABEL: } // end sil function 'test_allocateUninitialized'
69+
sil [ossa] @test_allocateUninitialized : $@convention(thin) () -> MyInt {
70+
bb0:
71+
%0 = integer_literal $Builtin.Int64, 3
72+
%3 = struct $MyInt(%0 : $Builtin.Int64)
73+
%4 = metatype $@thin MyArray<MyInt>.Type
74+
%5 = function_ref @allocateUninitialized : $@convention(thin) (MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
75+
%6 = apply %5(%3, %4) : $@convention(thin) (MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
76+
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
77+
debug_value %7 : $MyArray<MyInt>
78+
%9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
79+
%10 = apply %9(%7) : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
80+
%15 = function_ref @getElement : $@convention(method) (MyInt, MyBool, @guaranteed MyArray<MyInt>) -> @out MyInt
81+
%16 = alloc_stack $MyInt
82+
%17 = struct $MyBool()
83+
%18 = apply %15(%16, %3, %17, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray<MyInt>) -> @out MyInt
84+
destroy_value %7 : $MyArray<MyInt>
85+
dealloc_stack %16 : $*MyInt
86+
return %10 : $MyInt
87+
}
88+
89+
// CHECK-LABEL: sil [ossa] @test_initRepeatedValueCount :
90+
// CHECK: [[COUNTVAL:%.*]] = integer_literal $Builtin.Int64, 3
91+
// CHECK: [[COUNT:%.*]] = struct $MyInt ([[COUNTVAL]]
92+
// CHECK: [[GETCOUNTFUN:%.*]] = function_ref @getCount
93+
// CHECK-NOT: apply [[GETCOUNTFUN]]
94+
// CHECK-LABEL: } // end sil function 'test_initRepeatedValueCount'
95+
sil [ossa] @test_initRepeatedValueCount : $@convention(thin) () -> MyInt {
96+
bb0:
97+
%0 = integer_literal $Builtin.Int64, 3
98+
%1 = alloc_stack $MyInt
99+
%3 = struct $MyInt(%0 : $Builtin.Int64)
100+
store %3 to [trivial] %1: $*MyInt
101+
%4 = metatype $@thin MyArray<MyInt>.Type
102+
%5 = function_ref @initRepeatedValueCount : $@convention(thin) (@in MyInt, MyInt, @thin MyArray<MyInt>.Type) -> @owned MyArray<MyInt>
103+
%6 = apply %5(%1, %3, %4) : $@convention(thin) (@in MyInt, MyInt, @thin MyArray<MyInt>.Type) -> @owned MyArray<MyInt>
104+
debug_value %6 : $MyArray<MyInt>
105+
%9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
106+
%10 = apply %9(%6) : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
107+
%15 = function_ref @getElement : $@convention(method) (MyInt, MyBool, @guaranteed MyArray<MyInt>) -> @out MyInt
108+
%16 = alloc_stack $MyInt
109+
%17 = struct $MyBool()
110+
%18 = apply %15(%16, %3, %17, %6) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray<MyInt>) -> @out MyInt
111+
destroy_value %6 : $MyArray<MyInt>
112+
dealloc_stack %16 : $*MyInt
113+
dealloc_stack %1 : $*MyInt
114+
return %10 : $MyInt
115+
}
116+
117+
// CHECK-LABEL: sil [ossa] @test_escape :
118+
// CHECK: [[GETCOUNTFUN:%.*]] = function_ref @getCount
119+
// CHECK: [[RESULT:%.*]] = apply [[GETCOUNTFUN]]
120+
// CHECK-LABEL: } // end sil function 'test_escape'
121+
sil [ossa] @test_escape : $@convention(thin) () -> MyInt {
122+
bb0:
123+
%0 = integer_literal $Builtin.Int64, 3
124+
%15 = alloc_stack $MyArray<MyInt>
125+
%1 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned AnyObject
126+
%2 = apply %1() : $@convention(thin) () -> @owned AnyObject
127+
%3 = struct $MyInt(%0 : $Builtin.Int64)
128+
%4 = metatype $@thin MyArray<MyInt>.Type
129+
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
130+
%6 = apply %5(%2, %3, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
131+
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
132+
%copy7 = copy_value %7 : $MyArray<MyInt>
133+
debug_value %7 : $MyArray<MyInt>
134+
store %7 to [init] %15 : $*MyArray<MyInt>
135+
%9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
136+
%10 = apply %9(%copy7) : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
137+
destroy_value %copy7 : $MyArray<MyInt>
138+
destroy_addr %15 : $*MyArray<MyInt>
139+
dealloc_stack %15 : $*MyArray<MyInt>
140+
return %10 : $MyInt
141+
}
142+
143+
sil [ossa] @mayWrite : $@convention(thin) (@guaranteed MyArray<MyInt>) -> ()
144+
145+
// CHECK-LABEL: sil [ossa] @test_mayWrite :
146+
// CHECK: [[GETCOUNTFUN:%.*]] = function_ref @getCount
147+
// CHECK: [[RESULT:%.*]] = apply [[GETCOUNTFUN]]
148+
// CHECK-LABEL: } // end sil function 'test_mayWrite'
149+
sil [ossa] @test_mayWrite : $@convention(thin) () -> MyInt {
150+
bb0:
151+
%0 = integer_literal $Builtin.Int64, 3
152+
%1 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned AnyObject
153+
%2 = apply %1() : $@convention(thin) () -> @owned AnyObject
154+
%3 = struct $MyInt(%0 : $Builtin.Int64)
155+
%4 = metatype $@thin MyArray<MyInt>.Type
156+
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
157+
%6 = apply %5(%2, %3, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
158+
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
159+
debug_value %7 : $MyArray<MyInt>
160+
%15 = function_ref @mayWrite : $@convention(thin) (@guaranteed MyArray<MyInt>) -> ()
161+
%16 = apply %15(%7) : $@convention(thin) (@guaranteed MyArray<MyInt>) -> ()
162+
%9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
163+
%10 = apply %9(%7) : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
164+
destroy_value %7 : $MyArray<MyInt>
165+
return %10 : $MyInt
166+
}
167+
168+
// We don't handle empty array allocations yet.
169+
// CHECK-LABEL: sil [ossa] @test_initEmpty :
170+
// CHECK: [[GETCOUNTFUN:%.*]] = function_ref @getCount
171+
// CHECK: [[RESULT:%.*]] = apply [[GETCOUNTFUN]]
172+
// CHECK-LABEL: } // end sil function 'test_initEmpty'
173+
sil [ossa] @test_initEmpty : $@convention(thin) () -> MyInt {
174+
bb0:
175+
%4 = metatype $@thin MyArray<MyInt>.Type
176+
%5 = function_ref @initEmpty : $@convention(thin) (@thin MyArray<MyInt>.Type) -> @owned MyArray<MyInt>
177+
%6 = apply %5(%4) : $@convention(thin) (@thin MyArray<MyInt>.Type) -> @owned MyArray<MyInt>
178+
debug_value %6 : $MyArray<MyInt>
179+
%9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
180+
%10 = apply %9(%6) : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyInt
181+
destroy_value %6 : $MyArray<MyInt>
182+
return %10 : $MyInt
183+
}
184+

0 commit comments

Comments
 (0)