Skip to content

Commit d9ce289

Browse files
authored
Merge pull request #34791 from apple/release/5.3-20201012
[5.3] Pull in changes from PR 34323, 34327, 34445 and 34495
2 parents 0b3544e + 3c8a284 commit d9ce289

10 files changed

+371
-46
lines changed

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -713,11 +713,6 @@ void SILGlobalOpt::reset() {
713713

714714
void SILGlobalOpt::collect() {
715715
for (auto &F : *Module) {
716-
// TODO: Add support for ownership.
717-
if (F.hasOwnership()) {
718-
continue;
719-
}
720-
721716
// Make sure to create an entry. This is important in case a global variable
722717
// (e.g. a public one) is not used inside the same module.
723718
if (F.isGlobalInit())

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ bool TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
481481
// our base, we fail since those would be re-initializations.
482482
if (auto *li = dyn_cast<LoadInst>(user)) {
483483
if (li->getOwnershipQualifier() == LoadOwnershipQualifier::Take) {
484-
continue;
484+
return false;
485485
}
486486
}
487487

@@ -621,7 +621,7 @@ TempRValueOptPass::tryOptimizeStoreIntoTemp(StoreInst *si) {
621621
// our base, we fail since those would be re-initializations.
622622
if (auto *li = dyn_cast<LoadInst>(user)) {
623623
if (li->getOwnershipQualifier() == LoadOwnershipQualifier::Take) {
624-
continue;
624+
return {std::next(si->getIterator()), false};
625625
}
626626
}
627627

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1565,7 +1565,10 @@ static bool isInsideCompatibleUnavailableDeclaration(
15651565
auto IsUnavailable = [platform](const Decl *D) {
15661566
auto EnclosingUnavailable =
15671567
D->getAttrs().getUnavailable(D->getASTContext());
1568-
return EnclosingUnavailable && EnclosingUnavailable->Platform == platform;
1568+
return EnclosingUnavailable &&
1569+
(EnclosingUnavailable->Platform == platform ||
1570+
inheritsAvailabilityFromPlatform(platform,
1571+
EnclosingUnavailable->Platform));
15691572
};
15701573

15711574
return someEnclosingDeclMatches(ReferenceRange, ReferenceDC, IsUnavailable);

stdlib/public/core/Array.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ extension Array: RangeReplaceableCollection {
12271227
// elements. It reduces code size, because the following code
12281228
// can be removed by the optimizer by constant folding this check in a
12291229
// generic specialization.
1230-
if newElements is [Element] {
1230+
if S.self == [Element].self {
12311231
_internalInvariant(remainder.next() == nil)
12321232
return
12331233
}

test/SILOptimizer/globalopt_ossa.sil

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -global-opt | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
8+
private var testGlobal: Int64
9+
10+
sil_global private @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_token0 : $Builtin.Word
11+
12+
sil_global private @$s4test10testGlobalSivp : $Int64
13+
14+
sil private [ossa] @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_func0 : $@convention(c) () -> () {
15+
bb0:
16+
alloc_global @$s4test10testGlobalSivp
17+
%1 = global_addr @$s4test10testGlobalSivp : $*Int64
18+
%2 = integer_literal $Builtin.Int64, 27
19+
%3 = struct $Int64 (%2 : $Builtin.Int64)
20+
store %3 to [trivial] %1 : $*Int64
21+
%5 = tuple ()
22+
return %5 : $()
23+
}
24+
25+
sil hidden [global_init] [ossa] @$s4test10testGlobalSivau : $@convention(thin) () -> Builtin.RawPointer {
26+
bb0:
27+
%0 = global_addr @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_token0 : $*Builtin.Word
28+
%1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer
29+
%2 = function_ref @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_func0 : $@convention(c) () -> ()
30+
%3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $()
31+
%4 = global_addr @$s4test10testGlobalSivp : $*Int64
32+
%5 = address_to_pointer %4 : $*Int64 to $Builtin.RawPointer
33+
return %5 : $Builtin.RawPointer
34+
}
35+
36+
// CHECK-LABEL: sil [ossa] @dont_propagate_global_with_multiple_writes
37+
// CHECK: [[V:%[0-9]+]] = load
38+
// CHECK: return [[V]]
39+
// CHECK: } // end sil function 'dont_propagate_global_with_multiple_writes'
40+
sil [ossa] @dont_propagate_global_with_multiple_writes : $@convention(thin) (Int64) -> Int64 {
41+
bb0(%0 : $Int64):
42+
%2 = function_ref @$s4test10testGlobalSivau : $@convention(thin) () -> Builtin.RawPointer
43+
%3 = apply %2() : $@convention(thin) () -> Builtin.RawPointer
44+
%4 = pointer_to_address %3 : $Builtin.RawPointer to [strict] $*Int64
45+
%5 = integer_literal $Builtin.Int64, 42
46+
%6 = struct $Int64 (%5 : $Builtin.Int64)
47+
%7 = begin_access [modify] [dynamic] [no_nested_conflict] %4 : $*Int64
48+
store %6 to [trivial] %7 : $*Int64
49+
end_access %7 : $*Int64
50+
%33 = begin_access [read] [dynamic] [no_nested_conflict] %4 : $*Int64
51+
%35 = load [trivial] %33 : $*Int64
52+
end_access %33 : $*Int64
53+
return %35 : $Int64
54+
}
55+
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -global-opt | %FileCheck %s
2+
3+
// This tests GlobalOpt of a trivial global variable
4+
// Loads of trivial global variable initialized with a constant is replaced with the constant in GlobalOpt
5+
// This also tests GlobalOpt to be a no-op for a non-trivial global variable used in the same way
6+
// The difference in GlobalOpt for trivial v/s non-trivial values is shown in $bartrivial and $barnontrivial
7+
8+
sil_stage canonical
9+
10+
import Builtin
11+
import Swift
12+
import SwiftShims
13+
14+
public struct TStruct {
15+
let x: Int32
16+
init(x: Int32)
17+
}
18+
19+
let trivialglobal: TStruct
20+
21+
public class TClass {
22+
final let x: Int32
23+
init(x: Int32)
24+
deinit
25+
}
26+
27+
let nontrivialglobal: TClass
28+
29+
// CHECK-LABEL: sil_global hidden [let] @$trivialglobal : $TStruct = {
30+
// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10
31+
// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32)
32+
// CHECK: %initval = struct $TStruct ([[INT]] : $Int32)
33+
sil_global private @globalinit_trivialglobal_token : $Builtin.Word
34+
35+
sil_global hidden [let] @$trivialglobal : $TStruct
36+
37+
sil_global private @globalinit_nontrivialglobal_token : $Builtin.Word
38+
39+
sil_global hidden [let] @$nontrivialglobal : $TClass
40+
41+
sil private @globalinit_trivialglobal_func : $@convention(c) () -> () {
42+
bb0:
43+
alloc_global @$trivialglobal
44+
%1 = global_addr @$trivialglobal : $*TStruct
45+
%2 = integer_literal $Builtin.Int32, 10
46+
%3 = struct $Int32 (%2 : $Builtin.Int32)
47+
%4 = struct $TStruct (%3 : $Int32)
48+
store %4 to %1 : $*TStruct
49+
%6 = tuple ()
50+
return %6 : $()
51+
}
52+
53+
// CHECK-LABEL: sil hidden [global_init] @$trivialglobal_unsafemutableaddressor :
54+
// CHECK: [[GLOBL:%.*]] = global_addr @$trivialglobal : $*TStruct
55+
// CHECK: [[GLOBL_ADDR:%.*]] = address_to_pointer [[GLOBL]] : $*TStruct to $Builtin.RawPointer
56+
// CHECK: return [[GLOBL_ADDR]] : $Builtin.RawPointer
57+
// CHECK: } // end sil function '$trivialglobal_unsafemutableaddressor'
58+
sil hidden [global_init] @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer {
59+
bb0:
60+
%0 = global_addr @globalinit_trivialglobal_token : $*Builtin.Word
61+
%1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer
62+
%2 = function_ref @globalinit_trivialglobal_func : $@convention(c) () -> ()
63+
%3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $()
64+
%4 = global_addr @$trivialglobal : $*TStruct
65+
%5 = address_to_pointer %4 : $*TStruct to $Builtin.RawPointer
66+
return %5 : $Builtin.RawPointer
67+
}
68+
69+
// $bartrivial's access to the trivial global variable via the accessor is optimized to the rhs of the init value
70+
71+
// CHECK-LABEL: sil hidden [noinline] @$bartrivial :
72+
// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10
73+
// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32)
74+
// CHECK: return [[INT]] : $Int32
75+
// CHECK-LABEL: } // end sil function '$bartrivial'
76+
sil hidden [noinline] @$bartrivial : $@convention(thin) () -> Int32 {
77+
bb0:
78+
%0 = function_ref @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer
79+
%1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
80+
%2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TStruct
81+
%3 = struct_element_addr %2 : $*TStruct, #TStruct.x
82+
%4 = load %3 : $*Int32
83+
return %4 : $Int32
84+
}
85+
86+
// CHECK-LABEL: sil private @globalinit_nontrivialglobal_func :
87+
// CHECK: alloc_global @$nontrivialglobal
88+
// CHECK: [[GLOBL_ADDR:%.*]] = global_addr @$nontrivialglobal : $*TClass
89+
// CHECK: [[REF:%.*]] = alloc_ref $TClass
90+
// CHECK: store [[REF]] to [[GLOBL_ADDR]] : $*TClass
91+
// CHECK: } // end sil function 'globalinit_nontrivialglobal_func'
92+
sil private @globalinit_nontrivialglobal_func : $@convention(c) () -> () {
93+
bb0:
94+
alloc_global @$nontrivialglobal
95+
%1 = global_addr @$nontrivialglobal : $*TClass
96+
%2 = integer_literal $Builtin.Int32, 10
97+
%3 = struct $Int32 (%2 : $Builtin.Int32)
98+
%4 = alloc_ref $TClass
99+
%7 = ref_element_addr %4 : $TClass, #TClass.x
100+
store %3 to %7 : $*Int32
101+
store %4 to %1 : $*TClass
102+
%10 = tuple ()
103+
return %10 : $()
104+
}
105+
106+
sil hidden [global_init] @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer {
107+
bb0:
108+
%0 = global_addr @globalinit_nontrivialglobal_token : $*Builtin.Word
109+
%1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer
110+
%2 = function_ref @globalinit_nontrivialglobal_func : $@convention(c) () -> ()
111+
%3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $()
112+
%4 = global_addr @$nontrivialglobal : $*TClass
113+
%5 = address_to_pointer %4 : $*TClass to $Builtin.RawPointer
114+
return %5 : $Builtin.RawPointer
115+
}
116+
117+
// $barnontrivial's access to the non-trivial global variable does not get optimized away
118+
119+
// CHECK-LABEL: sil hidden [noinline] @$barnontrivial :
120+
// CHECK: [[FUNC_REF:%.*]] = function_ref @$nontrivialglobal_unsafemutableaccessor :
121+
// CHECK: [[APPLY:%.*]] = apply [[FUNC_REF]]() :
122+
// CHECK-LABEL: } // end sil function '$barnontrivial'
123+
sil hidden [noinline] @$barnontrivial : $@convention(thin) () -> Int32 {
124+
bb0:
125+
%0 = function_ref @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer
126+
%1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
127+
%2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TClass
128+
%3 = load %2 : $*TClass
129+
%4 = ref_element_addr %3 : $TClass, #TClass.x
130+
%5 = load %4 : $*Int32
131+
return %5 : $Int32
132+
}
133+
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -global-opt | %FileCheck %s
2+
sil_stage canonical
3+
4+
import Builtin
5+
import Swift
6+
import SwiftShims
7+
8+
public struct TStruct {
9+
let x: Int32
10+
init(x: Int32)
11+
}
12+
13+
let trivialglobal: TStruct
14+
15+
public class TClass {
16+
final let x: Int32
17+
init(x: Int32)
18+
deinit
19+
}
20+
21+
let nontrivialglobal: TClass
22+
23+
// CHECK-LABEL: sil_global hidden [let] @$trivialglobal : $TStruct = {
24+
// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10
25+
// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32)
26+
// CHECK: %initval = struct $TStruct ([[INT]] : $Int32)
27+
sil_global private @globalinit_trivialglobal_token : $Builtin.Word
28+
29+
sil_global hidden [let] @$trivialglobal : $TStruct
30+
31+
sil_global private @globalinit_nontrivialglobal_token : $Builtin.Word
32+
33+
sil_global hidden [let] @$nontrivialglobal : $TClass
34+
35+
sil private [ossa] @globalinit_trivialglobal_func : $@convention(c) () -> () {
36+
bb0:
37+
alloc_global @$trivialglobal
38+
%1 = global_addr @$trivialglobal : $*TStruct
39+
%2 = integer_literal $Builtin.Int32, 10
40+
%3 = struct $Int32 (%2 : $Builtin.Int32)
41+
%4 = struct $TStruct (%3 : $Int32)
42+
store %4 to [trivial] %1 : $*TStruct
43+
%6 = tuple ()
44+
return %6 : $()
45+
}
46+
47+
// CHECK-LABEL: sil hidden [global_init] [ossa] @$trivialglobal_unsafemutableaddressor :
48+
// CHECK: [[GLOBL:%.*]] = global_addr @$trivialglobal : $*TStruct
49+
// CHECK: [[GLOBL_ADDR:%.*]] = address_to_pointer [[GLOBL]] : $*TStruct to $Builtin.RawPointer
50+
// CHECK: return [[GLOBL_ADDR]] : $Builtin.RawPointer
51+
// CHECK: } // end sil function '$trivialglobal_unsafemutableaddressor'
52+
sil hidden [global_init] [ossa] @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer {
53+
bb0:
54+
%0 = global_addr @globalinit_trivialglobal_token : $*Builtin.Word
55+
%1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer
56+
%2 = function_ref @globalinit_trivialglobal_func : $@convention(c) () -> ()
57+
%3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $()
58+
%4 = global_addr @$trivialglobal : $*TStruct
59+
%5 = address_to_pointer %4 : $*TStruct to $Builtin.RawPointer
60+
return %5 : $Builtin.RawPointer
61+
}
62+
63+
// CHECK-LABEL: sil hidden [noinline] [ossa] @$bartrivial :
64+
// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10
65+
// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32)
66+
// CHECK: return [[INT]] : $Int32
67+
// CHECK-LABEL: } // end sil function '$bartrivial'
68+
sil hidden [noinline] [ossa] @$bartrivial : $@convention(thin) () -> Int32 {
69+
bb0:
70+
%0 = function_ref @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer
71+
%1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
72+
%2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TStruct
73+
%3 = struct_element_addr %2 : $*TStruct, #TStruct.x
74+
%4 = load [trivial] %3 : $*Int32
75+
return %4 : $Int32
76+
}
77+
78+
// CHECK-LABEL: sil private [ossa] @globalinit_nontrivialglobal_func :
79+
// CHECK: alloc_global @$nontrivialglobal
80+
// CHECK: [[GLOBL_ADDR:%.*]] = global_addr @$nontrivialglobal : $*TClass
81+
// CHECK: [[REF:%.*]] = alloc_ref $TClass
82+
// CHECK: store [[REF]] to [init] [[GLOBL_ADDR]] : $*TClass
83+
// CHECK: } // end sil function 'globalinit_nontrivialglobal_func'
84+
sil private [ossa] @globalinit_nontrivialglobal_func : $@convention(c) () -> () {
85+
bb0:
86+
alloc_global @$nontrivialglobal
87+
%1 = global_addr @$nontrivialglobal : $*TClass
88+
%2 = integer_literal $Builtin.Int32, 10
89+
%3 = struct $Int32 (%2 : $Builtin.Int32)
90+
%4 = alloc_ref $TClass
91+
%5 = begin_borrow %4 : $TClass
92+
%6 = ref_element_addr %5 : $TClass, #TClass.x
93+
store %3 to [trivial] %6 : $*Int32
94+
end_borrow %5 : $TClass
95+
store %4 to [init] %1 : $*TClass
96+
%10 = tuple ()
97+
return %10 : $()
98+
}
99+
100+
sil hidden [global_init] [ossa] @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer {
101+
bb0:
102+
%0 = global_addr @globalinit_nontrivialglobal_token : $*Builtin.Word
103+
%1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer
104+
%2 = function_ref @globalinit_nontrivialglobal_func : $@convention(c) () -> ()
105+
%3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $()
106+
%4 = global_addr @$nontrivialglobal : $*TClass
107+
%5 = address_to_pointer %4 : $*TClass to $Builtin.RawPointer
108+
return %5 : $Builtin.RawPointer
109+
}
110+
111+
// CHECK-LABEL: sil hidden [noinline] [ossa] @$barnontrivial :
112+
// CHECK: [[FUNC_REF:%.*]] = function_ref @$nontrivialglobal_unsafemutableaccessor :
113+
// CHECK: [[APPLY:%.*]] = apply [[FUNC_REF]]() :
114+
// CHECK-LABEL: } // end sil function '$barnontrivial'
115+
sil hidden [noinline] [ossa] @$barnontrivial : $@convention(thin) () -> Int32 {
116+
bb0:
117+
%0 = function_ref @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer
118+
%1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
119+
%2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TClass
120+
%3 = load [copy] %2 : $*TClass
121+
%3b = begin_borrow %3 : $TClass
122+
%4 = ref_element_addr %3b : $TClass, #TClass.x
123+
%5 = load [trivial] %4 : $*Int32
124+
end_borrow %3b : $TClass
125+
destroy_value %3 : $TClass
126+
return %5 : $Int32
127+
}
128+

0 commit comments

Comments
 (0)