Skip to content

Commit a986cf2

Browse files
committed
[Test] Unit test lexical destroy folding.
Adapt a preexisting test to be a unit test that runs the utility.
1 parent 8baf57f commit a986cf2

File tree

3 files changed

+69
-49
lines changed

3 files changed

+69
-49
lines changed

lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,23 @@ struct OwnershipUtilsHasPointerEscape : UnitTest {
288288
// MARK: OSSA Lifetime Unit Tests
289289
//===----------------------------------------------------------------------===//
290290

291+
// Arguments:
292+
// - the lexical borrow to fold
293+
// Dumpts:
294+
// - the function
295+
struct LexicalDestroyFoldingTest : UnitTest {
296+
LexicalDestroyFoldingTest(UnitTestRunner *pass) : UnitTest(pass) {}
297+
void invoke(Arguments &arguments) override {
298+
auto *dominanceAnalysis = getAnalysis<DominanceAnalysis>();
299+
DominanceInfo *domTree = dominanceAnalysis->get(getFunction());
300+
auto value = arguments.takeValue();
301+
auto *bbi = cast<BeginBorrowInst>(value);
302+
InstructionDeleter deleter;
303+
foldDestroysOfCopiedLexicalBorrow(bbi, *domTree, deleter);
304+
getFunction()->dump();
305+
}
306+
};
307+
291308
// Arguments:
292309
// - variadic list of - instruction: a last user
293310
// Dumps:

test/SILOptimizer/lexical_destroy_folding.sil

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -544,55 +544,6 @@ exit:
544544
return %retval : $()
545545
}
546546

547-
// Fold apply when guaranteed lexical value used in one but not two branches
548-
// and the lexical scope ends before the use on the non-lexical branch.
549-
//
550-
// CHECK-LABEL: sil [ossa] @nofold_two_parallel_owned_uses_one_lexical___scope_ends_before_use : {{.*}} {
551-
// CHECK: [[GET_OWNED:%[^,]+]] = function_ref @get_owned
552-
// CHECK: [[INSTANCE:%[^,]+]] = apply [[GET_OWNED]]
553-
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
554-
// CHECK: [[CALLEE_OWNED:%[^,]+]] = function_ref @callee_owned
555-
// CHECK: cond_br undef, [[LEFT:bb[0-9]+]], [[RIGHT:bb[0-9]+]]
556-
// CHECK: [[LEFT]]:
557-
// CHECK: [[COPY:%[^,]+]] = copy_value [[LIFETIME]]
558-
// CHECK: apply [[CALLEE_OWNED]]([[COPY]])
559-
// CHECK: end_borrow [[LIFETIME]]
560-
// CHECK: destroy_value [[INSTANCE]]
561-
// CHECK: br [[EXIT:bb[0-9]+]]
562-
// CHECK: [[RIGHT]]:
563-
// CHECK: end_borrow [[LIFETIME]]
564-
// CHECK: apply [[CALLEE_OWNED]]([[INSTANCE]])
565-
// CHECK: br [[EXIT]]
566-
// CHECK: [[EXIT]]:
567-
// CHECK-LABEL: } // end sil function 'nofold_two_parallel_owned_uses_one_lexical___scope_ends_before_use'
568-
sil [ossa] @nofold_two_parallel_owned_uses_one_lexical___scope_ends_before_use : $@convention(thin) () -> () {
569-
entry:
570-
%get_owned = function_ref @get_owned : $@convention(thin) () -> (@owned C)
571-
%instance = apply %get_owned() : $@convention(thin) () -> (@owned C)
572-
%copy_2 = copy_value %instance : $C
573-
%lifetime = begin_borrow [lexical] %instance : $C
574-
%callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
575-
cond_br undef, left, right
576-
577-
left:
578-
%copy_1 = copy_value %lifetime : $C
579-
apply %callee_owned(%copy_1) : $@convention(thin) (@owned C) -> ()
580-
end_borrow %lifetime : $C
581-
destroy_value %instance : $C
582-
destroy_value %copy_2 : $C
583-
br exit
584-
585-
right:
586-
end_borrow %lifetime : $C
587-
destroy_value %instance : $C
588-
apply %callee_owned(%copy_2) : $@convention(thin) (@owned C) -> ()
589-
br exit
590-
591-
exit:
592-
%retval = tuple ()
593-
return %retval : $()
594-
}
595-
596547
// Fold even if there is a noncanonicalized copy which is otherwise used.
597548
// CHECK-LABEL: sil [ossa] @fold_noncanonical_copy_with_other_use : {{.*}} {
598549
// CHECK: {{bb[0-9]+}}:
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %target-sil-opt -unit-test-runner %s -o /dev/null 2>&1 | %FileCheck %s
2+
3+
class C {}
4+
sil [ossa] @callee_owned : $@convention(thin) (@owned C) -> ()
5+
6+
// Fold apply when guaranteed lexical value used in one but not two branches
7+
// and the lexical scope ends before the use on the non-lexical branch.
8+
//
9+
// CHECK-LABEL: sil [ossa] @nofold_two_parallel_owned_uses_one_lexical___scope_ends_before_use : {{.*}} {
10+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] :
11+
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
12+
// CHECK: [[MOVE:%[^,]+]] = move_value [lexical] [[INSTANCE]]
13+
// CHECK: [[CALLEE_OWNED:%[^,]+]] = function_ref @callee_owned
14+
// CHECK: cond_br undef, [[LEFT:bb[0-9]+]], [[RIGHT:bb[0-9]+]]
15+
// CHECK: [[LEFT]]:
16+
// CHECK: apply [[CALLEE_OWNED]]([[MOVE]])
17+
// CHECK: destroy_value [[COPY]]
18+
// CHECK: br [[EXIT:bb[0-9]+]]
19+
// CHECK: [[RIGHT]]:
20+
// CHECK: destroy_value [[MOVE]]
21+
// CHECK: apply [[CALLEE_OWNED]]([[COPY]])
22+
// CHECK: br [[EXIT]]
23+
// CHECK: [[EXIT]]:
24+
// CHECK-LABEL: } // end sil function 'nofold_two_parallel_owned_uses_one_lexical___scope_ends_before_use'
25+
sil [ossa] @nofold_two_parallel_owned_uses_one_lexical___scope_ends_before_use : $@convention(thin) (@owned C) -> () {
26+
entry(%instance : @owned $C):
27+
test_specification "lexical-destroy-folding @trace[0]"
28+
%copy_2 = copy_value %instance : $C
29+
%lifetime = begin_borrow [lexical] %instance : $C
30+
debug_value [trace] %lifetime : $C
31+
%callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
32+
cond_br undef, left, right
33+
34+
left:
35+
%copy_1 = copy_value %lifetime : $C
36+
apply %callee_owned(%copy_1) : $@convention(thin) (@owned C) -> ()
37+
end_borrow %lifetime : $C
38+
destroy_value %instance : $C
39+
destroy_value %copy_2 : $C
40+
br exit
41+
42+
right:
43+
end_borrow %lifetime : $C
44+
destroy_value %instance : $C
45+
apply %callee_owned(%copy_2) : $@convention(thin) (@owned C) -> ()
46+
br exit
47+
48+
exit:
49+
%retval = tuple ()
50+
return %retval : $()
51+
}
52+

0 commit comments

Comments
 (0)