2
2
3
3
import Swift
4
4
import Builtin
5
+ import SwiftShims
5
6
6
7
//////////
7
8
// Data //
@@ -22,6 +23,11 @@ class NontrivialDestructor {
22
23
init()
23
24
}
24
25
26
+ class ArrayStorage {
27
+ @_hasStorage var bodyField : Kl
28
+ init()
29
+ }
30
+
25
31
sil @$s4main17TrivialDestructorCfD : $@convention(method) (@owned TrivialDestructor) -> () {
26
32
bb0(%0 : $TrivialDestructor):
27
33
// Alloc/Dealloc stack should not disrupt elimination of the
@@ -445,3 +451,196 @@ bb0(%0 : $X):
445
451
return %10 : $()
446
452
}
447
453
454
+ // CHECK-LABEL: sil @remove_dead_array_with_destroy_simple
455
+ // CHECK-NOT: alloc_ref
456
+ // CHECK-NOT: dealloc_ref
457
+ // CHECK: strong_release %0 : $Kl
458
+ // CHECK-NEXT: strong_release %0 : $Kl
459
+ // CHECK-NEXT: tuple
460
+ // CHECK-NEXT: return
461
+ // CHECK: } // end sil function 'remove_dead_array_with_destroy_simple'
462
+ sil @remove_dead_array_with_destroy_simple : $@convention(thin) (@owned Kl) -> () {
463
+ bb0(%0 : $Kl):
464
+ %3 = integer_literal $Builtin.Word, 2
465
+ %4 = alloc_ref [tail_elems $Kl * %3 : $Builtin.Word] $ArrayStorage
466
+ %11 = ref_tail_addr %4 : $ArrayStorage, $Kl
467
+ store %0 to %11 : $*Kl
468
+ %27 = integer_literal $Builtin.Word, 1
469
+ %28 = index_addr %11 : $*Kl, %27 : $Builtin.Word
470
+ retain_value %0 : $Kl
471
+ store %0 to %28 : $*Kl
472
+ set_deallocating %4 : $ArrayStorage
473
+ %65 = address_to_pointer %11 : $*Kl to $Builtin.RawPointer
474
+ %66 = metatype $@thick Kl.Type
475
+ %67 = builtin "destroyArray"<Kl>(%66 : $@thick Kl.Type, %65 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
476
+ dealloc_ref %4 : $ArrayStorage
477
+ %10 = tuple ()
478
+ return %10 : $()
479
+ }
480
+
481
+ // CHECK-LABEL: sil @remove_dead_array_with_destroy_complex
482
+ // CHECK-NOT: alloc_ref
483
+ // CHECK-NOT: dealloc_ref
484
+ // CHECK: release_value %0 : $String
485
+ // CHECK-NEXT: release_value %0 : $String
486
+ // CHECK-NEXT: tuple
487
+ // CHECK-NEXT: return
488
+ // CHECK: } // end sil function 'remove_dead_array_with_destroy_complex'
489
+ sil @remove_dead_array_with_destroy_complex : $@convention(thin) (@guaranteed String, Int, UInt) -> () {
490
+ bb0(%0 : $String, %1 : $Int, %2 : $UInt):
491
+ %3 = integer_literal $Builtin.Word, 2
492
+ %4 = alloc_ref [stack] [tail_elems $(Int, String) * %3 : $Builtin.Word] $_ContiguousArrayStorage<(Int, String)>
493
+ %5 = upcast %4 : $_ContiguousArrayStorage<(Int, String)> to $__ContiguousArrayStorageBase
494
+ %6 = struct $_SwiftArrayBodyStorage (%1 : $Int, %2 : $UInt)
495
+ %7 = struct $_ArrayBody (%6 : $_SwiftArrayBodyStorage)
496
+ %9 = ref_element_addr %5 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity
497
+ store %7 to %9 : $*_ArrayBody
498
+ %11 = ref_tail_addr %5 : $__ContiguousArrayStorageBase, $(Int, String)
499
+ %12 = tuple_element_addr %11 : $*(Int, String), 0
500
+ %13 = tuple_element_addr %11 : $*(Int, String), 1
501
+ retain_value %0 : $String
502
+ store %1 to %12 : $*Int
503
+ store %0 to %13 : $*String
504
+ %27 = integer_literal $Builtin.Word, 1
505
+ %28 = index_addr %11 : $*(Int, String), %27 : $Builtin.Word
506
+ %29 = tuple_element_addr %28 : $*(Int, String), 0
507
+ %30 = tuple_element_addr %28 : $*(Int, String), 1
508
+ retain_value %0 : $String
509
+ store %1 to %29 : $*Int
510
+ store %0 to %30 : $*String
511
+ set_deallocating %4 : $_ContiguousArrayStorage<(Int, String)>
512
+ %64 = ref_tail_addr %4 : $_ContiguousArrayStorage<(Int, String)>, $(Int, String)
513
+ %65 = address_to_pointer %64 : $*(Int, String) to $Builtin.RawPointer
514
+ %66 = metatype $@thick (Int, String).Type
515
+ %67 = builtin "destroyArray"<(Int, String)>(%66 : $@thick (Int, String).Type, %65 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
516
+ fix_lifetime %4 : $_ContiguousArrayStorage<(Int, String)>
517
+ dealloc_ref %4 : $_ContiguousArrayStorage<(Int, String)>
518
+ dealloc_ref [stack] %4 : $_ContiguousArrayStorage<(Int, String)>
519
+ %10 = tuple ()
520
+ return %10 : $()
521
+ }
522
+
523
+ // CHECK-LABEL: sil @dont_remove_dead_array_overlapping_stores
524
+ // CHECK: alloc_ref
525
+ // CHECK: dealloc_ref
526
+ // CHECK: } // end sil function 'dont_remove_dead_array_overlapping_stores'
527
+ sil @dont_remove_dead_array_overlapping_stores : $@convention(thin) (@owned Kl) -> () {
528
+ bb0(%0 : $Kl):
529
+ %3 = integer_literal $Builtin.Word, 2
530
+ %4 = alloc_ref [tail_elems $Kl * %3 : $Builtin.Word] $ArrayStorage
531
+ %11 = ref_tail_addr %4 : $ArrayStorage, $Kl
532
+ %27 = integer_literal $Builtin.Word, 1
533
+ %28 = index_addr %11 : $*Kl, %27 : $Builtin.Word
534
+ retain_value %0 : $Kl
535
+ store %0 to %28 : $*Kl
536
+ store %0 to %11 : $*Kl
537
+ %30 = index_addr %11 : $*Kl, %27 : $Builtin.Word
538
+ retain_value %0 : $Kl
539
+ store %0 to %30 : $*Kl // Overwrites the first store
540
+ set_deallocating %4 : $ArrayStorage
541
+ %65 = address_to_pointer %11 : $*Kl to $Builtin.RawPointer
542
+ %66 = metatype $@thick Kl.Type
543
+ %67 = builtin "destroyArray"<Kl>(%66 : $@thick Kl.Type, %65 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
544
+ dealloc_ref %4 : $ArrayStorage
545
+ %10 = tuple ()
546
+ return %10 : $()
547
+ }
548
+
549
+ // CHECK-LABEL: sil @dont_remove_dead_array_store_to_body
550
+ // CHECK: alloc_ref
551
+ // CHECK: dealloc_ref
552
+ // CHECK: } // end sil function 'dont_remove_dead_array_store_to_body'
553
+ sil @dont_remove_dead_array_store_to_body : $@convention(thin) (@owned Kl) -> () {
554
+ bb0(%0 : $Kl):
555
+ %3 = integer_literal $Builtin.Word, 2
556
+ %4 = alloc_ref [tail_elems $Kl * %3 : $Builtin.Word] $ArrayStorage
557
+ %5 = ref_element_addr %4 : $ArrayStorage, #ArrayStorage.bodyField
558
+ %11 = ref_tail_addr %4 : $ArrayStorage, $Kl
559
+ store %0 to %5 : $*Kl // Store non-trivial type to body of ArrayStorage
560
+ %27 = integer_literal $Builtin.Word, 1
561
+ %28 = index_addr %11 : $*Kl, %27 : $Builtin.Word
562
+ retain_value %0 : $Kl
563
+ store %0 to %28 : $*Kl
564
+ set_deallocating %4 : $ArrayStorage
565
+ %65 = address_to_pointer %11 : $*Kl to $Builtin.RawPointer
566
+ %66 = metatype $@thick Kl.Type
567
+ %67 = builtin "destroyArray"<Kl>(%66 : $@thick Kl.Type, %65 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
568
+ dealloc_ref %4 : $ArrayStorage
569
+ %10 = tuple ()
570
+ return %10 : $()
571
+ }
572
+
573
+ // CHECK-LABEL: sil @dont_remove_dead_array_out_of_bounds_store
574
+ // CHECK: alloc_ref
575
+ // CHECK: dealloc_ref
576
+ // CHECK: } // end sil function 'dont_remove_dead_array_out_of_bounds_store'
577
+ sil @dont_remove_dead_array_out_of_bounds_store: $@convention(thin) (@owned Kl) -> () {
578
+ bb0(%0 : $Kl):
579
+ %2 = integer_literal $Builtin.Word, 1
580
+ %3 = integer_literal $Builtin.Word, 2
581
+ %4 = alloc_ref [tail_elems $Kl * %3 : $Builtin.Word] $ArrayStorage
582
+ %11 = ref_tail_addr %4 : $ArrayStorage, $Kl
583
+ store %0 to %11 : $*Kl
584
+ %28 = index_addr %11 : $*Kl, %2 : $Builtin.Word // out-of-bounds store
585
+ retain_value %0 : $Kl
586
+ store %0 to %28 : $*Kl
587
+ set_deallocating %4 : $ArrayStorage
588
+ %65 = address_to_pointer %11 : $*Kl to $Builtin.RawPointer
589
+ %66 = metatype $@thick Kl.Type
590
+ %67 = builtin "destroyArray"<Kl>(%66 : $@thick Kl.Type, %65 : $Builtin.RawPointer, %2 : $Builtin.Word) : $()
591
+ dealloc_ref %4 : $ArrayStorage
592
+ %10 = tuple ()
593
+ return %10 : $()
594
+ }
595
+
596
+ // CHECK-LABEL: sil @dont_remove_dead_array_unknown_bounds
597
+ // CHECK: alloc_ref
598
+ // CHECK: dealloc_ref
599
+ // CHECK: } // end sil function 'dont_remove_dead_array_unknown_bounds'
600
+ sil @dont_remove_dead_array_unknown_bounds : $@convention(thin) (@owned Kl, Builtin.Word) -> () {
601
+ bb0(%0 : $Kl, %1 : $Builtin.Word):
602
+ %3 = integer_literal $Builtin.Word, 2
603
+ %4 = alloc_ref [tail_elems $Kl * %3 : $Builtin.Word] $ArrayStorage
604
+ %11 = ref_tail_addr %4 : $ArrayStorage, $Kl
605
+ store %0 to %11 : $*Kl
606
+ %27 = integer_literal $Builtin.Word, 1
607
+ %28 = index_addr %11 : $*Kl, %27 : $Builtin.Word
608
+ retain_value %0 : $Kl
609
+ store %0 to %28 : $*Kl
610
+ set_deallocating %4 : $ArrayStorage
611
+ %65 = address_to_pointer %11 : $*Kl to $Builtin.RawPointer
612
+ %66 = metatype $@thick Kl.Type
613
+ %67 = builtin "destroyArray"<Kl>(%66 : $@thick Kl.Type, %65 : $Builtin.RawPointer, %1 : $Builtin.Word) : $()
614
+ dealloc_ref %4 : $ArrayStorage
615
+ %10 = tuple ()
616
+ return %10 : $()
617
+ }
618
+
619
+ // CHECK-LABEL: sil @dont_remove_dead_array_wrong_blocks
620
+ // CHECK: alloc_ref
621
+ // CHECK: dealloc_ref
622
+ // CHECK: } // end sil function 'dont_remove_dead_array_wrong_blocks'
623
+ sil @dont_remove_dead_array_wrong_blocks : $@convention(thin) (@owned Kl) -> () {
624
+ bb0(%0 : $Kl):
625
+ %3 = integer_literal $Builtin.Word, 2
626
+ %4 = alloc_ref [tail_elems $Kl * %3 : $Builtin.Word] $ArrayStorage
627
+ %11 = ref_tail_addr %4 : $ArrayStorage, $Kl
628
+ cond_br undef, bb1, bb2
629
+ bb1:
630
+ store %0 to %11 : $*Kl
631
+ br bb3
632
+ bb2:
633
+ %27 = integer_literal $Builtin.Word, 1
634
+ %28 = index_addr %11 : $*Kl, %27 : $Builtin.Word
635
+ store %0 to %28 : $*Kl
636
+ br bb3
637
+ bb3:
638
+ set_deallocating %4 : $ArrayStorage
639
+ %65 = address_to_pointer %11 : $*Kl to $Builtin.RawPointer
640
+ %66 = metatype $@thick Kl.Type
641
+ %67 = builtin "destroyArray"<Kl>(%66 : $@thick Kl.Type, %65 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
642
+ dealloc_ref %4 : $ArrayStorage
643
+ %10 = tuple ()
644
+ return %10 : $()
645
+ }
646
+
0 commit comments