Skip to content

Commit 912e08b

Browse files
authored
Merge pull request swiftlang#15129 from eeckstein/fix-oo
ObjectOutliner: restrict object outlining to tail allocated arrays.
2 parents f6ec0f0 + c408468 commit 912e08b

File tree

4 files changed

+49
-23
lines changed

4 files changed

+49
-23
lines changed

lib/SILOptimizer/Transforms/ObjectOutliner.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -286,20 +286,25 @@ bool ObjectOutliner::optimizeObjectAllocation(
286286
ArrayRef<Operand> TailCounts = ARI->getTailAllocatedCounts();
287287
SILType TailType;
288288
unsigned NumTailElems = 0;
289-
if (!TailCounts.empty()) {
290-
// We only support a single tail allocated array.
291-
if (TailCounts.size() > 1)
289+
290+
// We only support a single tail allocated arrays.
291+
// Stdlib's tail allocated arrays don't have any side-effects in the
292+
// constructor if the element type is trivial.
293+
// TODO: also exclude custom tail allocated arrays which might have
294+
// side-effects in the destructor.
295+
if (TailCounts.size() != 1)
292296
return false;
293-
// The number of tail allocated elements must be constant.
294-
if (auto *ILI = dyn_cast<IntegerLiteralInst>(TailCounts[0].get())) {
295-
if (ILI->getValue().getActiveBits() > 20)
296-
return false;
297-
NumTailElems = ILI->getValue().getZExtValue();
298-
TailType = ARI->getTailAllocatedTypes()[0];
299-
} else {
297+
298+
// The number of tail allocated elements must be constant.
299+
if (auto *ILI = dyn_cast<IntegerLiteralInst>(TailCounts[0].get())) {
300+
if (ILI->getValue().getActiveBits() > 20)
300301
return false;
301-
}
302+
NumTailElems = ILI->getValue().getZExtValue();
303+
TailType = ARI->getTailAllocatedTypes()[0];
304+
} else {
305+
return false;
302306
}
307+
303308
SILType Ty = ARI->getType();
304309
ClassDecl *Cl = Ty.getClassOrBoundGenericClass();
305310
if (!Cl)

test/SILOptimizer/globalopt-iter.sil

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ class E : B { }
88

99
// CHECK: sil @patatino : $@convention(thin) () -> () {
1010
// CHECK: bb0:
11-
// CHECK-NEXT: %0 = global_value @patatinoTv_ : $B
11+
// CHECK-NEXT: integer_literal
12+
// CHECK-NEXT: global_value @patatinoTv_ : $B
1213
// CHECK-NEXT: strong_retain
1314
// CHECK-NEXT: strong_release
1415
// CHECK-NEXT: tuple ()
1516
// CHECK-NEXT: return
1617
// CHECK-NEXT: }
1718

1819
sil @patatino : $@convention(thin) () -> () {
19-
%1 = alloc_ref [stack] $B
20+
%0 = integer_literal $Builtin.Word, 0
21+
%1 = alloc_ref [tail_elems $Int64 * %0 : $Builtin.Word] $B
2022
set_deallocating %1 : $B
21-
dealloc_ref [stack] %1 : $B
23+
dealloc_ref %1 : $B
2224
%45 = tuple ()
2325
return %45 : $()
2426
}

test/SILOptimizer/objectoutliner.sil

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ class Obj {
3535
// CHECK: return
3636
sil @outline_global_simple : $@convention(thin) () -> () {
3737
bb0:
38+
%0 = integer_literal $Builtin.Word, 0
3839
%1 = integer_literal $Builtin.Int64, 1
3940
%4 = struct $Int64 (%1 : $Builtin.Int64)
40-
%7 = alloc_ref $Obj
41+
%7 = alloc_ref [tail_elems $Int64 * %0 : $Builtin.Word] $Obj
4142
%9 = ref_element_addr %7 : $Obj, #Obj.value
4243
store %4 to %9 : $*Int64
4344
strong_release %7 : $Obj
@@ -83,9 +84,10 @@ bb0:
8384
// CHECK-NEXT: return
8485
sil @handle_deallocation : $@convention(thin) () -> () {
8586
bb0:
87+
%0 = integer_literal $Builtin.Word, 0
8688
%3 = integer_literal $Builtin.Int64, 3
8789
%4 = struct $Int64 (%3 : $Builtin.Int64)
88-
%5 = alloc_ref $Obj
90+
%5 = alloc_ref [tail_elems $Int64 * %0 : $Builtin.Word] $Obj
8991
%6 = ref_element_addr %5 : $Obj, #Obj.value
9092
store %4 to %6 : $*Int64
9193
set_deallocating %5 : $Obj
@@ -94,15 +96,32 @@ bb0:
9496
return %r : $()
9597
}
9698

99+
// CHECK-LABEL: sil @dont_outline_without_tail_elems
100+
// CHECK: alloc_ref
101+
// CHECK: store
102+
// CHECK: return
103+
sil @dont_outline_without_tail_elems : $@convention(thin) () -> () {
104+
bb0:
105+
%1 = integer_literal $Builtin.Int64, 1
106+
%4 = struct $Int64 (%1 : $Builtin.Int64)
107+
%7 = alloc_ref $Obj
108+
%9 = ref_element_addr %7 : $Obj, #Obj.value
109+
store %4 to %9 : $*Int64
110+
strong_release %7 : $Obj
111+
%r = tuple ()
112+
return %r : $()
113+
}
114+
97115
// CHECK-LABEL: sil @dont_outline_global_double_store
98116
// CHECK: alloc_ref
99117
// CHECK: store
100118
// CHECK: return
101119
sil @dont_outline_global_double_store : $@convention(thin) () -> () {
102120
bb0:
121+
%0 = integer_literal $Builtin.Word, 0
103122
%1 = integer_literal $Builtin.Int64, 1
104123
%4 = struct $Int64 (%1 : $Builtin.Int64)
105-
%7 = alloc_ref $Obj
124+
%7 = alloc_ref [tail_elems $Int64 * %0 : $Builtin.Word] $Obj
106125
%9 = ref_element_addr %7 : $Obj, #Obj.value
107126
store %4 to %9 : $*Int64
108127
store %4 to %9 : $*Int64
@@ -116,9 +135,10 @@ bb0:
116135
// CHECK: return
117136
sil @dont_outline_global_missing_store : $@convention(thin) () -> () {
118137
bb0:
138+
%0 = integer_literal $Builtin.Word, 0
119139
%1 = integer_literal $Builtin.Int64, 1
120140
%4 = struct $Int64 (%1 : $Builtin.Int64)
121-
%7 = alloc_ref $Obj
141+
%7 = alloc_ref [tail_elems $Int64 * %0 : $Builtin.Word] $Obj
122142
%9 = ref_element_addr %7 : $Obj, #Obj.value
123143
strong_release %7 : $Obj
124144
%r = tuple ()
@@ -148,9 +168,10 @@ sil @take_pointer : $@convention(thin) (Builtin.RawPointer) -> ()
148168
// CHECK: return
149169
sil @dont_outline_global_unknown_addr_use : $@convention(thin) () -> () {
150170
bb0:
171+
%0 = integer_literal $Builtin.Word, 0
151172
%1 = integer_literal $Builtin.Int64, 1
152173
%4 = struct $Int64 (%1 : $Builtin.Int64)
153-
%7 = alloc_ref $Obj
174+
%7 = alloc_ref [tail_elems $Int64 * %0 : $Builtin.Word] $Obj
154175
%9 = ref_element_addr %7 : $Obj, #Obj.value
155176
store %4 to %9 : $*Int64
156177
%10 = address_to_pointer %9 : $*Int64 to $Builtin.RawPointer
@@ -167,8 +188,9 @@ bb0:
167188
sil @dont_outline_global_escaping_obj : $@convention(thin) (@inout Obj) -> () {
168189
bb0(%0: $*Obj):
169190
%1 = integer_literal $Builtin.Int64, 1
191+
%2 = integer_literal $Builtin.Word, 0
170192
%4 = struct $Int64 (%1 : $Builtin.Int64)
171-
%7 = alloc_ref $Obj
193+
%7 = alloc_ref [tail_elems $Int64 * %2 : $Builtin.Word] $Obj
172194
%9 = ref_element_addr %7 : $Obj, #Obj.value
173195
store %4 to %9 : $*Int64
174196
store %7 to %0 : $*Obj

test/stdlib/ErrorHandling.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// RUN: %target-run-simple-swift
22
// REQUIRES: executable_test
33

4-
// FIXME: <https://bugs.swift.org/browse/SR-7146> 2 tests are failing on linux in optimized mode
5-
// UNSUPPORTED: OS=linux-gnu
6-
74
//
85
// Tests for error handling in standard library APIs.
96
//

0 commit comments

Comments
 (0)