Skip to content

Commit b85aea1

Browse files
committed
Unit tests for findEnclosingDefs and findBorrowIntroducers.
1 parent 0a94845 commit b85aea1

File tree

3 files changed

+471
-0
lines changed

3 files changed

+471
-0
lines changed

lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,40 @@ struct VisitAdjacentReborrowsOfPhiTest : UnitTest {
381381
}
382382
};
383383

384+
// Arguments:
385+
// - SILValue: value
386+
// Dumps:
387+
// - function
388+
// - the enclosing defs
389+
struct FindEnclosingDefsTest : UnitTest {
390+
FindEnclosingDefsTest(UnitTestRunner *pass) : UnitTest(pass) {}
391+
void invoke(Arguments &arguments) override {
392+
getFunction()->dump();
393+
llvm::dbgs() << "Enclosing Defs:\n";
394+
visitEnclosingDefs(arguments.takeValue(), [](SILValue def) {
395+
def->dump();
396+
return true;
397+
});
398+
}
399+
};
400+
401+
// Arguments:
402+
// - SILValue: value
403+
// Dumps:
404+
// - function
405+
// - the borrow introducers
406+
struct FindBorrowIntroducers : UnitTest {
407+
FindBorrowIntroducers(UnitTestRunner *pass) : UnitTest(pass) {}
408+
void invoke(Arguments &arguments) override {
409+
getFunction()->dump();
410+
llvm::dbgs() << "Introducers:\n";
411+
visitBorrowIntroducers(arguments.takeValue(), [](SILValue def) {
412+
def->dump();
413+
return true;
414+
});
415+
}
416+
};
417+
384418
/// [new_tests] Add the new UnitTest subclass above this line.
385419
/// Please sort alphabetically by to help reduce merge conflicts.
386420

@@ -406,6 +440,8 @@ void UnitTestRunner::withTest(StringRef name, Doit doit) {
406440
ADD_UNIT_TEST_SUBCLASS("simplify-cfg-canonicalize-switch-enum", SimplifyCFGCanonicalizeSwitchEnum)
407441
ADD_UNIT_TEST_SUBCLASS("test-specification-parsing", TestSpecificationTest)
408442
ADD_UNIT_TEST_SUBCLASS("visit-adjacent-reborrows-of-phi", VisitAdjacentReborrowsOfPhiTest)
443+
ADD_UNIT_TEST_SUBCLASS("find-enclosing-defs", FindEnclosingDefsTest)
444+
ADD_UNIT_TEST_SUBCLASS("find-borrow-introducers", FindBorrowIntroducers)
409445
/// [new_tests] Add the new mapping from string to subclass above this line.
410446
/// Please sort alphabetically by name to help reduce merge
411447
/// conflicts.
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// RUN: %target-sil-opt -unit-test-runner %s -o /dev/null 2>&1 | %FileCheck %s
2+
3+
sil_stage raw
4+
5+
import Builtin
6+
7+
struct Trivial {
8+
var value: Builtin.Int32
9+
}
10+
11+
enum FakeOptional<T> {
12+
case none
13+
case some(T)
14+
}
15+
16+
struct PairC {
17+
var first: C
18+
var second: C
19+
}
20+
21+
class C {}
22+
23+
class D : C {}
24+
25+
// The introducer of an introducer is always itself.
26+
27+
// CHECK-LABEL: introducer_identity: find-borrow-introducers with: @trace[0]
28+
// CHECK: } // end sil function 'introducer_identity'
29+
// CHECK: Introducers:
30+
// CHECK-NEXT: %0 = argument of bb0 : $C
31+
// CHECK-NEXT: introducer_identity: find-borrow-introducers with: @trace[0]
32+
33+
// CHECK-LABEL: introducer_identity: find-borrow-introducers with: @trace[1]
34+
// CHECK: } // end sil function 'introducer_identity'
35+
// CHECK: Introducers:
36+
// CHECK-NEXT: begin_borrow %0 : $C
37+
// CHECK-NEXT: introducer_identity: find-borrow-introducers with: @trace[1]
38+
39+
// CHECK-LABEL: introducer_identity: find-borrow-introducers with: @trace[2]
40+
// CHECK: } // end sil function 'introducer_identity'
41+
// CHECK: Introducers:
42+
// CHECK-NEXT: load_borrow %1 : $*C
43+
// CHECK-NEXT: introducer_identity: find-borrow-introducers with: @trace[2]
44+
45+
// CHECK-LABEL: introducer_identity: find-borrow-introducers with: @trace[3]
46+
// CHECK: } // end sil function 'introducer_identity'
47+
// CHECK: Introducers:
48+
// CHECK-NEXT: argument of bb1 : $C
49+
// CHECK-NEXT: introducer_identity: find-borrow-introducers with: @trace[3]
50+
51+
sil [ossa] @introducer_identity : $@convention(thin) (@guaranteed C, @in C) -> () {
52+
entry(%0 : @guaranteed $C, %1 : $*C):
53+
test_specification "find-borrow-introducers @trace[0]"
54+
debug_value [trace] %0 : $C
55+
%borrow1 = begin_borrow %0 : $C
56+
test_specification "find-borrow-introducers @trace[1]"
57+
debug_value [trace] %borrow1 : $C
58+
59+
%borrow2 = load_borrow %1 : $*C
60+
test_specification "find-borrow-introducers @trace[2]"
61+
debug_value [trace] %borrow2 : $C
62+
end_borrow %borrow2 : $C
63+
64+
br exit(%borrow1 : $C)
65+
66+
exit(%reborrow : @guaranteed $C):
67+
test_specification "find-borrow-introducers @trace[3]"
68+
debug_value [trace] %reborrow : $C
69+
end_borrow %reborrow : $C
70+
destroy_addr %1 : $*C
71+
%retval = tuple ()
72+
return %retval : $()
73+
}
74+
75+
// There is no introducer if the guaranteed value is produced from a
76+
// trivial value.
77+
78+
// CHECK-LABEL: introducer_trivial: find-borrow-introducers with: @trace[0]
79+
// CHECK: } // end sil function 'introducer_trivial'
80+
// CHECK: Introducers:
81+
// CHECK-NEXT: introducer_trivial: find-borrow-introducers with: @trace[0]
82+
83+
sil [ossa] @introducer_trivial : $@convention(thin) () -> () {
84+
entry:
85+
%trivial = enum $FakeOptional<C>, #FakeOptional.none!enumelt
86+
br none(%trivial : $FakeOptional<C>)
87+
88+
none(%phi : @guaranteed $FakeOptional<C>):
89+
test_specification "find-borrow-introducers @trace[0]"
90+
debug_value [trace] %phi : $FakeOptional<C>
91+
%retval = tuple ()
92+
return %retval : $()
93+
}
94+
95+
// An unreachable phi currently looks like a reborrow.
96+
//
97+
// TODO: When we have a reborrow flag, an unreachable phi can be
98+
// either a reborrow or forwarded, as long as it has no end_borrow.
99+
100+
// CHECK-LABEL: introducer_unreachable: find-borrow-introducers with: @trace[0]
101+
// CHECK: } // end sil function 'introducer_unreachable'
102+
// CHECK: Introducers:
103+
// CHECK-NEXT: argument of bb1 : $C
104+
// CHECK-NEXT: introducer_unreachable: find-borrow-introducers with: @trace[0]
105+
106+
sil [ossa] @introducer_unreachable : $@convention(thin) () -> () {
107+
entry:
108+
br exit
109+
110+
unreachable_loop(%phiCycle : @guaranteed $C):
111+
test_specification "find-borrow-introducers @trace[0]"
112+
debug_value [trace] %phiCycle : $C
113+
br unreachable_loop(%phiCycle : $C)
114+
115+
exit:
116+
%retval = tuple ()
117+
return %retval : $()
118+
}
119+
120+
// All data flow paths through phis and aggregates originate from the
121+
// same function argument.
122+
123+
// CHECK-LABEL: introducer_single: find-borrow-introducers with: @trace[0]
124+
// CHECK: } // end sil function 'introducer_single'
125+
// CHECK: Introducers:
126+
// CHECK-NEXT: %0 = argument of bb0 : $C
127+
// CHECK-NEXT: introducer_single: find-borrow-introducers with: @trace[0]
128+
129+
sil [ossa] @introducer_single : $@convention(thin) (@guaranteed C) -> () {
130+
entry(%0 : @guaranteed $C):
131+
%cast = unconditional_checked_cast %0 : $C to D
132+
%some = enum $FakeOptional<D>, #FakeOptional.some!enumelt, %cast : $D
133+
br switch(%some : $FakeOptional<D>)
134+
135+
switch(%somePhi : @guaranteed $FakeOptional<D>):
136+
switch_enum %somePhi : $FakeOptional<D>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
137+
138+
bb1(%payload : @guaranteed $D):
139+
%upcast = upcast %payload : $D to $C
140+
%aggregate = struct $PairC(%upcast : $C, %0 : $C)
141+
%first = struct_extract %aggregate : $PairC, #PairC.first
142+
%second = struct_extract %aggregate : $PairC, #PairC.second
143+
%aggregate2 = struct $PairC(%first : $C, %second : $C)
144+
test_specification "find-borrow-introducers @trace[0]"
145+
debug_value [trace] %aggregate2 : $PairC
146+
br exit
147+
148+
bb2:
149+
br exit
150+
151+
exit:
152+
%retval = tuple ()
153+
return %retval : $()
154+
}
155+
156+
// %reborrow introduces multiple borrow scopes. But it should only appear
157+
// in the list once.
158+
159+
// The forwarding %phi originates from %borrow1 and %0. But
160+
// %borrow1 cannot be an introducer in bb2 because it's scope ends at
161+
// %reborrow. Therefore, %reborrow is an introducer from separate phi
162+
// paths, but should only appear in the introducer list once.
163+
//
164+
// CHECK-LABEL: introducer_revisit_reborrow: find-borrow-introducers with: @trace[0]
165+
// CHECK: bb1([[REBORROW:%.*]] : @guaranteed $C
166+
// CHECK: } // end sil function 'introducer_revisit_reborrow'
167+
// CHECK: Introducers:
168+
// CHECK-NEXT: [[REBORROW]] = argument of bb1 : $C
169+
// CHECK-NEXT: %0 = argument of bb0 : $C
170+
// CHECK-NEXT: introducer_revisit_reborrow: find-borrow-introducers with: @trace[0]
171+
172+
sil [ossa] @introducer_revisit_reborrow : $@convention(thin) (@guaranteed C) -> () {
173+
entry(%0 : @guaranteed $C):
174+
%borrow1 = begin_borrow %0 : $C
175+
%aggregate = struct $PairC(%0 : $C, %borrow1 : $C)
176+
br bb2(%borrow1 : $C, %aggregate : $PairC)
177+
178+
bb2(%reborrow : @guaranteed $C, %phi : @guaranteed $PairC):
179+
%first = struct_extract %phi : $PairC, #PairC.first
180+
%aggregate2 = struct $PairC(%reborrow : $C, %first : $C)
181+
test_specification "find-borrow-introducers @trace[0]"
182+
debug_value [trace] %aggregate2 : $PairC
183+
br exit
184+
185+
exit:
186+
end_borrow %reborrow : $C
187+
%retval = tuple ()
188+
return %retval : $()
189+
}
190+
191+
// %phi originates from %0, %borrow1, & %borrow2. %borrow1 is, however,
192+
// reborrowed in bb2.
193+
194+
// CHECK-LABEL: introducer_multiple_borrow: find-borrow-introducers with: @trace[0]
195+
// CHECK: begin_borrow %0 : $C
196+
// CHECK: [[BORROW2:%.*]] = begin_borrow %0 : $C
197+
// CHECK: bb1([[REBORROW:%.*]] : @guaranteed $C
198+
// CHECK: } // end sil function 'introducer_multiple_borrow'
199+
// CHECK: Introducers:
200+
// CHECK-NEXT: [[REBORROW]] = argument of bb1 : $C
201+
// CHECK-NEXT: %0 = argument of bb0 : $C
202+
// CHECK-NEXT: [[BORROW2]] = begin_borrow %0 : $C
203+
// CHECK-NEXT: introducer_multiple_borrow: find-borrow-introducers with: @trace[0]
204+
205+
sil [ossa] @introducer_multiple_borrow : $@convention(thin) (@guaranteed C) -> () {
206+
entry(%0 : @guaranteed $C):
207+
%borrow1 = begin_borrow %0 : $C
208+
%borrow2 = begin_borrow %0 : $C
209+
%aggregate = struct $PairC(%0 : $C, %borrow2 : $C)
210+
br bb2(%borrow1 : $C, %aggregate : $PairC)
211+
212+
bb2(%reborrow : @guaranteed $C, %phi : @guaranteed $PairC):
213+
%first = struct_extract %phi : $PairC, #PairC.first
214+
%aggregate2 = struct $PairC(%reborrow : $C, %first : $C)
215+
test_specification "find-borrow-introducers @trace[0]"
216+
debug_value [trace] %aggregate2 : $PairC
217+
br exit
218+
219+
exit:
220+
end_borrow %reborrow : $C
221+
end_borrow %borrow2 : $C
222+
%retval = tuple ()
223+
return %retval : $()
224+
}

0 commit comments

Comments
 (0)