Skip to content

Commit e2563e6

Browse files
authored
Merge pull request swiftlang#35766 from meg-gupta/csechangespr
CSE OSSA: look through ownership instructions for some additional instructions
2 parents d1c7890 + b854df0 commit e2563e6

File tree

3 files changed

+140
-30
lines changed

3 files changed

+140
-30
lines changed

lib/SIL/IR/SILInstruction.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,6 @@ namespace {
544544
auto *X = cast<RefElementAddrInst>(LHS);
545545
if (X->getField() != RHS->getField())
546546
return false;
547-
if (X->getOperand() != RHS->getOperand())
548-
return false;
549547
return true;
550548
}
551549

lib/SILOptimizer/Transforms/CSE.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ class HashVisitor : public SILInstructionVisitor<HashVisitor, llvm::hash_code> {
109109
}
110110

111111
hash_code visitValueToBridgeObjectInst(ValueToBridgeObjectInst *X) {
112-
return llvm::hash_combine(X->getKind(), X->getOperand());
112+
return llvm::hash_combine(X->getKind(),
113+
lookThroughOwnershipInsts(X->getOperand()));
113114
}
114115

115116
hash_code visitRefToBridgeObjectInst(RefToBridgeObjectInst *X) {
@@ -138,7 +139,8 @@ class HashVisitor : public SILInstructionVisitor<HashVisitor, llvm::hash_code> {
138139
}
139140

140141
hash_code visitUncheckedAddrCastInst(UncheckedAddrCastInst *X) {
141-
return llvm::hash_combine(X->getKind(), X->getType(), X->getOperand());
142+
return llvm::hash_combine(X->getKind(), X->getType(),
143+
lookThroughOwnershipInsts(X->getOperand()));
142144
}
143145

144146
hash_code visitFunctionRefInst(FunctionRefInst *X) {
@@ -159,11 +161,14 @@ class HashVisitor : public SILInstructionVisitor<HashVisitor, llvm::hash_code> {
159161
}
160162

161163
hash_code visitRefElementAddrInst(RefElementAddrInst *X) {
162-
return llvm::hash_combine(X->getKind(), X->getOperand(), X->getField());
164+
return llvm::hash_combine(X->getKind(),
165+
lookThroughOwnershipInsts(X->getOperand()),
166+
X->getField());
163167
}
164168

165169
hash_code visitRefTailAddrInst(RefTailAddrInst *X) {
166-
return llvm::hash_combine(X->getKind(), X->getOperand());
170+
return llvm::hash_combine(X->getKind(),
171+
lookThroughOwnershipInsts(X->getOperand()));
167172
}
168173

169174
hash_code visitProjectBoxInst(ProjectBoxInst *X) {
@@ -177,7 +182,8 @@ class HashVisitor : public SILInstructionVisitor<HashVisitor, llvm::hash_code> {
177182
}
178183

179184
hash_code visitRawPointerToRefInst(RawPointerToRefInst *X) {
180-
return llvm::hash_combine(X->getKind(), X->getOperand());
185+
return llvm::hash_combine(X->getKind(),
186+
lookThroughOwnershipInsts(X->getOperand()));
181187
}
182188

183189
#define LOADABLE_REF_STORAGE(Name, ...) \

test/SILOptimizer/cse_ossa_nontrivial.sil

Lines changed: 129 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ sil @use_nontrivialstruct1 : $@convention(thin) (@guaranteed NonTrivialStruct) -
3636
sil @use_nontrivialstruct2 : $@convention(thin) (@owned NonTrivialStruct) -> ()
3737

3838
// CHECK-LABEL: sil [ossa] @structliteral1 :
39-
// CHECK: struct $NonTrivialStruct
40-
// CHECK-NOT: struct $NonTrivialStruct
39+
// CHECK: struct $NonTrivialStruct
40+
// CHECK-NOT: struct $NonTrivialStruct
4141
// CHECK-LABEL: } // end sil function 'structliteral1'
4242
sil [ossa] @structliteral1 : $@convention(thin) (@guaranteed Klass) -> () {
4343
bb0(%0 : @guaranteed $Klass):
@@ -51,8 +51,8 @@ bb0(%0 : @guaranteed $Klass):
5151
}
5252

5353
// CHECK-LABEL: sil [ossa] @structliteral2 :
54-
// CHECK: struct $NonTrivialStruct
55-
// CHECK-NOT: struct $NonTrivialStruct
54+
// CHECK: struct $NonTrivialStruct
55+
// CHECK-NOT: struct $NonTrivialStruct
5656
// CHECK-LABEL: } // end sil function 'structliteral2'
5757
sil [ossa] @structliteral2 : $@convention(thin) (@owned Klass) -> () {
5858
bb0(%0 : @owned $Klass):
@@ -232,7 +232,7 @@ bb0(%0 : @owned $Klass):
232232
// CHECK-LABEL: } // end sil function 'test2cse2'
233233
sil [ossa] @test2cse2 : $@convention(thin) (@owned Klass) -> () {
234234
bb0(%0 : @owned $Klass):
235-
%copy0 = copy_value %0 : $Klass
235+
%copy0 = copy_value %0 : $Klass
236236
%1 = ref_to_raw_pointer %0 : $Klass to $Builtin.RawPointer
237237
%2 = ref_to_raw_pointer %copy0 : $Klass to $Builtin.RawPointer
238238
%4 = function_ref @helper : $@convention(thin) (Builtin.RawPointer, Builtin.RawPointer) -> Builtin.Word
@@ -368,8 +368,8 @@ struct KlassPair {
368368
sil [ossa] @destructure_struct_test1 : $@convention(thin) (@owned KlassPair) -> () {
369369
bb0(%0 : @owned $KlassPair):
370370
%copy0 = copy_value %0: $KlassPair
371-
(%1, %2) = destructure_struct %0 : $KlassPair
372-
(%3, %4) = destructure_struct %copy0 : $KlassPair
371+
(%1, %2) = destructure_struct %0 : $KlassPair
372+
(%3, %4) = destructure_struct %copy0 : $KlassPair
373373
destroy_value %1 : $Klass
374374
destroy_value %2 : $Klass
375375
destroy_value %3 : $Klass
@@ -385,8 +385,8 @@ bb0(%0 : @owned $KlassPair):
385385
// CHECK-LABEL: } // end sil function 'destructure_struct_test2'
386386
sil [ossa] @destructure_struct_test2 : $@convention(thin) (@guaranteed KlassPair) -> () {
387387
bb0(%0 : @guaranteed $KlassPair):
388-
(%1, %2) = destructure_struct %0 : $KlassPair
389-
(%3, %4) = destructure_struct %0 : $KlassPair
388+
(%1, %2) = destructure_struct %0 : $KlassPair
389+
(%3, %4) = destructure_struct %0 : $KlassPair
390390
%func = function_ref @klass_user : $@convention(thin) (@guaranteed Klass) -> ()
391391
apply %func(%2) : $@convention(thin) (@guaranteed Klass) -> ()
392392
apply %func(%3) : $@convention(thin) (@guaranteed Klass) -> ()
@@ -402,8 +402,8 @@ bb0(%0 : @guaranteed $KlassPair):
402402
sil [ossa] @destructure_tuple_test1 : $@convention(thin) (@owned (Klass, Klass)) -> () {
403403
bb0(%0 : @owned $(Klass, Klass)):
404404
%copy0 = copy_value %0: $(Klass, Klass)
405-
(%1, %2) = destructure_tuple %0 : $(Klass, Klass)
406-
(%3, %4) = destructure_tuple %copy0 : $(Klass, Klass)
405+
(%1, %2) = destructure_tuple %0 : $(Klass, Klass)
406+
(%3, %4) = destructure_tuple %copy0 : $(Klass, Klass)
407407
destroy_value %1 : $Klass
408408
destroy_value %2 : $Klass
409409
destroy_value %3 : $Klass
@@ -419,8 +419,8 @@ bb0(%0 : @owned $(Klass, Klass)):
419419
// CHECK-LABEL: } // end sil function 'destructure_tuple_test2'
420420
sil [ossa] @destructure_tuple_test2 : $@convention(thin) (@guaranteed (Klass, Klass)) -> () {
421421
bb0(%0 : @guaranteed $(Klass, Klass)):
422-
(%1, %2) = destructure_tuple %0 : $(Klass, Klass)
423-
(%3, %4) = destructure_tuple %0 : $(Klass, Klass)
422+
(%1, %2) = destructure_tuple %0 : $(Klass, Klass)
423+
(%3, %4) = destructure_tuple %0 : $(Klass, Klass)
424424
%func = function_ref @klass_user : $@convention(thin) (@guaranteed Klass) -> ()
425425
apply %func(%2) : $@convention(thin) (@guaranteed Klass) -> ()
426426
apply %func(%3) : $@convention(thin) (@guaranteed Klass) -> ()
@@ -430,8 +430,8 @@ bb0(%0 : @guaranteed $(Klass, Klass)):
430430

431431

432432
// CHECK-LABEL: sil [ossa] @struct_test2 :
433-
// CHECK: struct $NonTrivialStruct
434-
// CHECK-NOT: struct $NonTrivialStruct
433+
// CHECK: struct $NonTrivialStruct
434+
// CHECK-NOT: struct $NonTrivialStruct
435435
// CHECK-LABEL: } // end sil function 'struct_test2'
436436
sil [ossa] @struct_test2 : $@convention(thin) (@guaranteed Klass) -> @owned Klass {
437437
bb0(%0 : @guaranteed $Klass):
@@ -445,8 +445,8 @@ bb0(%0 : @guaranteed $Klass):
445445
}
446446

447447
// CHECK-LABEL: sil [ossa] @struct_test3 :
448-
// CHECK: struct $NonTrivialStruct
449-
// CHECK-NOT: struct $NonTrivialStruct
448+
// CHECK: struct $NonTrivialStruct
449+
// CHECK-NOT: struct $NonTrivialStruct
450450
// CHECK-LABEL: } // end sil function 'struct_test3'
451451
sil [ossa] @struct_test3 : $@convention(thin) (@guaranteed Klass) -> () {
452452
bb0(%0 : @guaranteed $Klass):
@@ -462,8 +462,8 @@ bb0(%0 : @guaranteed $Klass):
462462
}
463463

464464
// CHECK-LABEL: sil [ossa] @struct_test4 :
465-
// CHECK: struct $NonTrivialStruct
466-
// CHECK-NOT: struct $NonTrivialStruct
465+
// CHECK: struct $NonTrivialStruct
466+
// CHECK-NOT: struct $NonTrivialStruct
467467
// CHECK-LABEL: } // end sil function 'struct_test4'
468468
sil [ossa] @struct_test4 : $@convention(thin) (@guaranteed Klass) -> () {
469469
bb0(%0 : @guaranteed $Klass):
@@ -480,8 +480,8 @@ bb0(%0 : @guaranteed $Klass):
480480
}
481481

482482
// CHECK-LABEL: sil [ossa] @struct_test5 :
483-
// CHECK: struct $NonTrivialStruct
484-
// CHECK-NOT: struct $NonTrivialStruct
483+
// CHECK: struct $NonTrivialStruct
484+
// CHECK-NOT: struct $NonTrivialStruct
485485
// CHECK-LABEL: } // end sil function 'struct_test5'
486486
sil [ossa] @struct_test5 : $@convention(thin) (@guaranteed Klass) -> @owned Klass {
487487
bb0(%0 : @guaranteed $Klass):
@@ -589,7 +589,7 @@ bb6(%arg5 : @guaranteed $Klass):
589589
bb7(%arg6 : $UInt):
590590
destroy_value %copy2 : $FakeOptional2
591591
br bb8
592-
592+
593593
bb8:
594594
destroy_value %copy1 : $FakeOptional2
595595
%res = tuple ()
@@ -627,7 +627,7 @@ bb2:
627627
bb3(%borrow : @guaranteed $Klass):
628628
end_borrow %borrow : $Klass
629629
%copy = copy_value %1 : $NonTrivialStruct
630-
return %copy : $NonTrivialStruct
630+
return %copy : $NonTrivialStruct
631631
}
632632

633633
// Test to make sure we clear the context if we fail while checking if ownership rauw is possible
@@ -661,3 +661,109 @@ bb0(%0 : $UnsafeMutablePointer<Element>, %1 : @guaranteed $_ContiguousArrayBuffe
661661
return %16 : $_SliceBuffer<Element>
662662
}
663663

664+
sil [ossa] @use_word1 : $@convention(thin) (@inout _UnsafeBitset.Word) -> ()
665+
666+
// TODO: Disable the TODO check when rauw address users correctly replaces all uses of the old ref_tail_addr with the new ref_tail_addr.
667+
// CHECK-LABEL: sil [ossa] @test_reftailaddr :
668+
// CHECK: bb0
669+
// CHECK: ref_tail_addr
670+
// TODO-CHECK-NOT: ref_tail_addr
671+
// CHECK-LABEL: } // end sil function 'test_reftailaddr'
672+
sil [ossa] @test_reftailaddr : $@convention(thin) (@owned __RawSetStorage) -> () {
673+
bb0(%0 : @owned $__RawSetStorage):
674+
%func = function_ref @use_word1 : $@convention(thin) (@inout _UnsafeBitset.Word) -> ()
675+
%1 = copy_value %0 : $__RawSetStorage
676+
%2 = begin_borrow %1 : $__RawSetStorage
677+
%3 = ref_tail_addr %2 : $__RawSetStorage, $_UnsafeBitset.Word
678+
apply %func(%3) : $@convention(thin) (@inout _UnsafeBitset.Word) -> ()
679+
end_borrow %2 : $__RawSetStorage
680+
%4 = copy_value %0 : $__RawSetStorage
681+
%5 = begin_borrow %4 : $__RawSetStorage
682+
%6 = ref_tail_addr %5 : $__RawSetStorage, $_UnsafeBitset.Word
683+
apply %func(%6) : $@convention(thin) (@inout _UnsafeBitset.Word) -> ()
684+
end_borrow %5 : $__RawSetStorage
685+
destroy_value %1 : $__RawSetStorage
686+
destroy_value %4 : $__RawSetStorage
687+
destroy_value %0 : $__RawSetStorage
688+
%res = tuple ()
689+
return %res : $()
690+
}
691+
692+
class WrapperKlass {
693+
var val:Builtin.NativeObject
694+
}
695+
696+
sil [ossa] @use_object : $@convention(thin) (@inout Builtin.NativeObject) -> ()
697+
698+
// CHECK-LABEL: sil [ossa] @test_refelementaddr :
699+
// CHECK: bb0
700+
// CHECK: ref_element_addr
701+
// CHECK-NOT: ref_element_addr
702+
// CHECK-LABEL: } // end sil function 'test_refelementaddr'
703+
sil [ossa] @test_refelementaddr : $@convention(thin) (@guaranteed WrapperKlass) -> () {
704+
bb0(%0 : @guaranteed $WrapperKlass):
705+
%func = function_ref @use_object : $@convention(thin) (@inout Builtin.NativeObject) -> ()
706+
%ele1 = ref_element_addr %0 : $WrapperKlass, #WrapperKlass.val
707+
apply %func(%ele1) : $@convention(thin) (@inout Builtin.NativeObject) -> ()
708+
%copy0 = copy_value %0 : $WrapperKlass
709+
%borrow = begin_borrow %copy0 : $WrapperKlass
710+
%ele2 = ref_element_addr %borrow : $WrapperKlass, #WrapperKlass.val
711+
apply %func(%ele2) : $@convention(thin) (@inout Builtin.NativeObject) -> ()
712+
end_borrow %borrow : $WrapperKlass
713+
destroy_value %copy0 : $WrapperKlass
714+
%res = tuple ()
715+
return %res : $()
716+
}
717+
718+
sil [ossa] @use_word2 : $@convention(thin) (@inout Builtin.Word) -> ()
719+
720+
/*
721+
// TODO: Enable this test after the verifier correctly handles the case a ref_tail_addr's result is used in an unchecked_addr_cast
722+
// TODOCHECK-LABEL: sil [ossa] @test_uncheckedaddrcast :
723+
// TODOCHECK: bb0
724+
// TODOCHECK: unchecked_addr_cast
725+
// TODO-CHECK-NOT: unchecked_addr_cast
726+
// TODOCHECK-LABEL: } // end sil function 'test_uncheckedaddrcast'
727+
sil [ossa] @test_reftailaddr : $@convention(thin) (@owned __RawSetStorage) -> () {
728+
bb0(%0 : @owned $__RawSetStorage):
729+
%func = function_ref @use_word2 : $@convention(thin) (@inout Builtin.Word) -> ()
730+
%1 = copy_value %0 : $__RawSetStorage
731+
%2 = begin_borrow %1 : $__RawSetStorage
732+
%3 = ref_tail_addr %2 : $__RawSetStorage, $_UnsafeBitset.Word
733+
%cast1 = unchecked_addr_cast %3 : $*_UnsafeBitset.Word to $*Builtin.Word
734+
apply %func(%cast1) : $@convention(thin) (@inout Builtin.Word) -> ()
735+
end_borrow %2 : $__RawSetStorage
736+
%4 = copy_value %0 : $__RawSetStorage
737+
%5 = begin_borrow %4 : $__RawSetStorage
738+
%6 = ref_tail_addr %5 : $__RawSetStorage, $_UnsafeBitset.Word
739+
%cast2 = unchecked_addr_cast %6 : $*_UnsafeBitset.Word to $*Builtin.Word
740+
apply %func(%cast2) : $@convention(thin) (@inout Builtin.Word) -> ()
741+
end_borrow %5 : $__RawSetStorage
742+
destroy_value %1 : $__RawSetStorage
743+
destroy_value %4 : $__RawSetStorage
744+
destroy_value %0 : $__RawSetStorage
745+
%res = tuple ()
746+
return %res : $()
747+
}
748+
*/
749+
750+
sil [ossa] @use_bridgeobject : $@convention(thin) (Builtin.BridgeObject) -> ()
751+
752+
// CHECK-LABEL: sil [ossa] @test_valuetobridgeobject :
753+
// CHECK: bb0
754+
// CHECK: value_to_bridge_object
755+
// CHECK-NOT: value_to_bridge_object
756+
// CHECK-LABEL: } // end sil function 'test_valuetobridgeobject'
757+
sil [ossa] @test_valuetobridgeobject : $@convention(thin) (@guaranteed WrapperKlass) -> () {
758+
bb0(%0 : @guaranteed $WrapperKlass):
759+
%func = function_ref @use_bridgeobject : $@convention(thin) (Builtin.BridgeObject) -> ()
760+
%1 = value_to_bridge_object %0 : $WrapperKlass
761+
apply %func(%1) : $@convention(thin) (Builtin.BridgeObject) -> ()
762+
%borrow = begin_borrow %0 : $WrapperKlass
763+
%2 = value_to_bridge_object %borrow : $WrapperKlass
764+
apply %func(%2) : $@convention(thin) (Builtin.BridgeObject) -> ()
765+
end_borrow %borrow : $WrapperKlass
766+
%res = tuple ()
767+
return %res : $()
768+
}
769+

0 commit comments

Comments
 (0)