@@ -15,6 +15,21 @@ import SIL
1515extension DestructureTupleInst : OnoneSimplifyable , SILCombineSimplifyable {
1616 func simplify( _ context: SimplifyContext ) {
1717
18+ // If the tuple is trivial, replace
19+ // ```
20+ // (%1, %2) = destructure_tuple %t
21+ // ```
22+ // ->
23+ // ```
24+ // %1 = tuple_extract %t, 0
25+ // %2 = tuple_extract %t, 1
26+ // ```
27+ // This canonicalization helps other optimizations to e.g. CSE tuple_extracts.
28+ //
29+ if replaceWithTupleExtract ( context) {
30+ return
31+ }
32+
1833 // Eliminate the redundant instruction pair
1934 // ```
2035 // %t = tuple (%0, %1, %2)
@@ -26,11 +41,39 @@ extension DestructureTupleInst : OnoneSimplifyable, SILCombineSimplifyable {
2641 tryReplaceConstructDestructPair ( construct: tuple, destruct: self , context)
2742 }
2843 }
44+
45+ private func replaceWithTupleExtract( _ context: SimplifyContext ) -> Bool {
46+ guard self . tuple. type. isTrivial ( in: parentFunction) else {
47+ return false
48+ }
49+ let builder = Builder ( before: self , context)
50+ for (elementIdx, result) in results. enumerated ( ) {
51+ let elementValue = builder. createTupleExtract ( tuple: self . tuple, elementIndex: elementIdx)
52+ result. uses. replaceAll ( with: elementValue, context)
53+ }
54+ context. erase ( instruction: self )
55+ return true
56+ }
2957}
3058
3159extension DestructureStructInst : OnoneSimplifyable , SILCombineSimplifyable {
3260 func simplify( _ context: SimplifyContext ) {
3361
62+ // If the struct is trivial, replace
63+ // ```
64+ // (%1, %2) = destructure_struct %s
65+ // ```
66+ // ->
67+ // ```
68+ // %1 = struct_extract %s, #S.field0
69+ // %2 = struct_extract %s, #S.field1
70+ // ```
71+ // This canonicalization helps other optimizations to e.g. CSE tuple_extracts.
72+ //
73+ if replaceWithStructExtract ( context) {
74+ return
75+ }
76+
3477 switch self . struct {
3578 case let str as StructInst :
3679 // Eliminate the redundant instruction pair
@@ -82,6 +125,19 @@ extension DestructureStructInst : OnoneSimplifyable, SILCombineSimplifyable {
82125 break
83126 }
84127 }
128+
129+ private func replaceWithStructExtract( _ context: SimplifyContext ) -> Bool {
130+ guard self . struct. type. isTrivial ( in: parentFunction) else {
131+ return false
132+ }
133+ let builder = Builder ( before: self , context)
134+ for (fieldIdx, result) in results. enumerated ( ) {
135+ let fieldValue = builder. createStructExtract ( struct: self . struct, fieldIndex: fieldIdx)
136+ result. uses. replaceAll ( with: fieldValue, context)
137+ }
138+ context. erase ( instruction: self )
139+ return true
140+ }
85141}
86142
87143private func tryReplaceConstructDestructPair( construct: SingleValueInstruction ,
0 commit comments