Skip to content

Commit 28e7e95

Browse files
committed
[mandatory-combine] Put canonicalization and trivial DCE behind a flag so I can use it for writing OSSA RAUW tests.
I am going to loop back around and enable this all the time, but this is seeming to disturb codegen more than expected, so I am going to enable it everywhere later (since it is not my primary goal).
1 parent c6525fd commit 28e7e95

File tree

5 files changed

+135
-33
lines changed

5 files changed

+135
-33
lines changed

lib/SILOptimizer/Mandatory/MandatoryCombine.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,13 @@ class MandatoryCombiner final
186186
// MandatoryCombiner Non-Visitor Utility Methods
187187
//===----------------------------------------------------------------------===//
188188

189+
static llvm::cl::opt<bool> EnableCanonicalizationAndTrivialDCE(
190+
"sil-mandatory-combine-enable-canon-and-simple-dce", llvm::cl::Hidden,
191+
llvm::cl::init(false),
192+
llvm::cl::desc("An option for compiler developers that cause the Mandatory "
193+
"Combiner to be more aggressive at eliminating trivially "
194+
"dead code and canonicalizing SIL"));
195+
189196
void MandatoryCombiner::addReachableCodeToWorklist(SILFunction &function) {
190197
SmallVector<SILBasicBlock *, 32> blockWorklist;
191198
SmallPtrSet<SILBasicBlock *, 32> blockAlreadyAddedToWorklist;
@@ -207,9 +214,11 @@ void MandatoryCombiner::addReachableCodeToWorklist(SILFunction &function) {
207214
++iterator;
208215

209216
if (isInstructionTriviallyDead(instruction)) {
210-
if (compilingWithOptimization) {
211-
instruction->replaceAllUsesOfAllResultsWithUndef();
212-
instruction->eraseFromParent();
217+
if (EnableCanonicalizationAndTrivialDCE) {
218+
if (compilingWithOptimization) {
219+
instruction->replaceAllUsesOfAllResultsWithUndef();
220+
instruction->eraseFromParent();
221+
}
213222
}
214223
continue;
215224
}
@@ -243,19 +252,21 @@ bool MandatoryCombiner::doOneIteration(SILFunction &function,
243252
continue;
244253
}
245254

246-
if (compilingWithOptimization) {
247-
if (isInstructionTriviallyDead(instruction)) {
248-
worklist.eraseInstFromFunction(*instruction);
255+
if (EnableCanonicalizationAndTrivialDCE) {
256+
if (compilingWithOptimization) {
257+
if (isInstructionTriviallyDead(instruction)) {
258+
worklist.eraseInstFromFunction(*instruction);
259+
madeChange = true;
260+
continue;
261+
}
262+
}
263+
264+
if (mcCanonicialize.tryCanonicalize(instruction)) {
249265
madeChange = true;
250266
continue;
251267
}
252268
}
253269

254-
if (mcCanonicialize.tryCanonicalize(instruction)) {
255-
madeChange = true;
256-
continue;
257-
}
258-
259270
#ifndef NDEBUG
260271
std::string instructionDescription;
261272
#endif

test/SILGen/addressors.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
// RUN: %target-swift-emit-sil -parse-stdlib %s | %FileCheck %s
23
// RUN: %target-swift-emit-silgen -parse-stdlib %s | %FileCheck %s -check-prefix=SILGEN
34
// RUN: %target-swift-emit-ir -parse-stdlib %s
@@ -59,8 +60,7 @@ func test0() {
5960
// CHECK: [[T2:%.*]] = struct_extract [[T1]] : $UnsafePointer<Int32>, #UnsafePointer._rawValue
6061
// CHECK: [[T3:%.*]] = pointer_to_address [[T2]] : $Builtin.RawPointer to [strict] $*Int32
6162
// CHECK: [[ACCESS:%.*]] = begin_access [read] [unsafe] [[T3]] : $*Int32
62-
// CHECK: [[ACCESS_GEP:%.*]] = struct_element_addr [[ACCESS]]
63-
// CHECK: [[Z:%.*]] = load [[ACCESS_GEP]]
63+
// CHECK: [[Z:%.*]] = load [[ACCESS]] : $*Int32
6464
let z = a[10]
6565

6666
// CHECK: [[WRITE:%.*]] = begin_access [modify] [static] [[A]] : $*A
@@ -106,8 +106,8 @@ var global: Int32 {
106106
}
107107
// CHECK-LABEL: sil hidden @$s10addressors6globals5Int32Vvlu : $@convention(thin) () -> UnsafePointer<Int32> {
108108
// CHECK: [[T0:%.*]] = global_addr @$s10addressors10uninitAddrSpys5Int32VGvp : $*UnsafeMutablePointer<Int32>
109-
// CHECK: [[T1:%.*]] = struct_element_addr [[T0]]
110-
// CHECK: [[T2:%.*]] = load [[T1]]
109+
// CHECK: [[T1:%.*]] = load [[T0]] : $*UnsafeMutablePointer<Int32>
110+
// CHECK: [[T2:%.*]] = struct_extract [[T1]] : $UnsafeMutablePointer<Int32>, #UnsafeMutablePointer._rawValue
111111
// CHECK: [[T3:%.*]] = struct $UnsafePointer<Int32> ([[T2]] : $Builtin.RawPointer)
112112
// CHECK: return [[T3]] : $UnsafePointer<Int32>
113113
}

test/SILGen/unmanaged.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ func set(holder holder: inout Holder) {
2424
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [static] [[ADDR]] : $*Holder
2525
// CHECK-NEXT: [[T0:%.*]] = struct_element_addr [[WRITE]] : $*Holder, #Holder.value
2626
// CHECK-NEXT: [[T1:%.*]] = ref_to_unmanaged [[C]]
27-
// CHECK-NEXT: [[T2:%.*]] = struct $Holder ([[T1]] : $@sil_unmanaged C)
28-
// CHECK-NEXT: store [[T2]] to [[WRITE]]
27+
// CHECK-NEXT: store [[T1]] to [[T0]]
2928
// CHECK-NEXT: strong_release [[C]]
3029
// CHECK-NEXT: end_access [[WRITE]] : $*Holder
3130
// CHECK-NEXT: tuple ()

test/SILOptimizer/mandatory_combiner.sil

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -924,19 +924,3 @@ bb0(%0 : @guaranteed $Klass, %1 : @guaranteed $Klass, %2 : @guaranteed $Klass):
924924
%9999 = tuple ()
925925
return %9999 : $()
926926
}
927-
928-
// CHECK-LABEL: sil [ossa] @eliminate_simple_arc_traffic : $@convention(thin) (@guaranteed Klass) -> () {
929-
// CHECK-NOT: copy_value
930-
// CHECK-NOT: destroy_value
931-
// CHECK-NOT: enum
932-
// CHECK-NOT: end_borrow
933-
// CHECK: } // end sil function 'eliminate_simple_arc_traffic'
934-
sil [ossa] @eliminate_simple_arc_traffic : $@convention(thin) (@guaranteed Klass) -> () {
935-
bb0(%0 : @guaranteed $Klass):
936-
%1 = copy_value %0 : $Klass
937-
destroy_value %1 : $Klass
938-
%2 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
939-
end_borrow %2 : $FakeOptional<Klass>
940-
%9999 = tuple()
941-
return %9999 : $()
942-
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// RUN: %target-sil-opt -mandatory-combine -sil-mandatory-combine-enable-canon-and-simple-dce %s | %FileCheck %s
2+
3+
// Tests for when the mandatory combiner is running with optimizations
4+
// enabled. Only put tests here for functionality that only occurs when the
5+
// Mandatory Combiner runs in between the diagnostics/perf pipeline at -O,
6+
// -Osize.
7+
8+
sil_stage canonical
9+
10+
import Builtin
11+
12+
// Trivial declarations
13+
14+
struct MyInt {
15+
var value: Builtin.Int64
16+
}
17+
18+
// Generic declarations
19+
20+
protocol Addable {
21+
static var an: Self { get }
22+
}
23+
24+
// Class declarations
25+
26+
class Klass {
27+
init()
28+
deinit
29+
}
30+
31+
// Existential declarations
32+
33+
protocol Proto {
34+
static var an: Proto { get }
35+
}
36+
37+
// Trivial support
38+
39+
sil @first_of_three_ints : $@convention(thin) (MyInt, MyInt, MyInt) -> MyInt
40+
41+
sil @constant_zero : $@convention(thin) () -> MyInt
42+
43+
sil @identity_int : $@convention(thin) (MyInt) -> MyInt
44+
45+
// Generic support
46+
47+
sil @first_of_three_addables : $@convention(thin) <A where A : Addable> (@in_guaranteed A, @guaranteed <τ_0_0 where τ_0_0 : Addable> { var τ_0_0 } <A>, @guaranteed <τ_0_0 where τ_0_0 : Addable> { var τ_0_0 } <A>) -> @
48+
out A
49+
50+
// Class support
51+
52+
sil [exact_self_class] @klass_alloc_init : $@convention(method) (@thick Klass.Type) -> @owned Klass
53+
54+
// Klass.init()
55+
sil @klass_init : $@convention(method) (@owned Klass) -> @owned Klass
56+
// Klass.deinit
57+
sil @klass_deinit : $@convention(method) (@guaranteed Klass) -> @owned Builtin.NativeObject
58+
59+
// Klass.__deallocating_deinit
60+
sil @klass_dealloc_deinit : $@convention(method) (@owned Klass) -> ()
61+
62+
sil_vtable Klass {
63+
#Klass.init!allocator: (Klass.Type) -> () -> Klass : @klass_alloc_init
64+
#Klass.deinit!deallocator: @klass_dealloc_deinit
65+
}
66+
67+
sil @first_of_three_klasses : $@convention(thin) (@guaranteed Klass, @guaranteed Klass, @guaranteed Klass) -> @owned Klass
68+
69+
// Existential support
70+
71+
sil @first_of_three_protos : $@convention(thin) (@in_guaranteed Proto, @guaranteed { var Proto }, @guaranteed { var Proto }) -> @out Proto
72+
73+
sil @get_proto : $@convention(thin) () -> @out Proto
74+
75+
// Mixed support
76+
77+
sil @proto_from_proto_and_myint : $@convention(thin) (@in_guaranteed Proto, MyInt) -> @out Proto
78+
79+
sil @myint_from_myint_and_proto : $@convention(thin) (MyInt, @guaranteed { var Proto }) -> MyInt
80+
81+
sil @myint_from_proto_and_myint : $@convention(thin) (@guaranteed { var Proto }, MyInt) -> MyInt
82+
83+
// Optional support
84+
enum FakeOptional<T> {
85+
case none
86+
case some(T)
87+
}
88+
89+
///////////
90+
// Tests //
91+
///////////
92+
93+
94+
// CHECK-LABEL: sil [ossa] @eliminate_simple_arc_traffic : $@convention(thin) (@guaranteed Klass) -> () {
95+
// CHECK-NOT: copy_value
96+
// CHECK-NOT: destroy_value
97+
// CHECK-NOT: enum
98+
// CHECK-NOT: end_borrow
99+
// CHECK: } // end sil function 'eliminate_simple_arc_traffic'
100+
sil [ossa] @eliminate_simple_arc_traffic : $@convention(thin) (@guaranteed Klass) -> () {
101+
bb0(%0 : @guaranteed $Klass):
102+
%1 = copy_value %0 : $Klass
103+
destroy_value %1 : $Klass
104+
%2 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
105+
end_borrow %2 : $FakeOptional<Klass>
106+
%9999 = tuple()
107+
return %9999 : $()
108+
}

0 commit comments

Comments
 (0)