@@ -102,47 +102,43 @@ private func tryDevirtualizeReleaseOfObject(
102
102
}
103
103
104
104
private func stripRCIdentityPreservingInsts( _ value: Value ) -> Value ? {
105
- switch value {
105
+ guard let inst = value as? Instruction else { return nil }
106
+
107
+ switch inst {
106
108
// First strip off RC identity preserving casts.
107
- case let inst as Instruction where inst is UpcastInst ||
108
- inst is UncheckedRefCastInst ||
109
- inst is InitExistentialRefInst ||
110
- inst is OpenExistentialRefInst ||
111
- inst is RefToBridgeObjectInst ||
112
- inst is BridgeObjectToRefInst ||
113
- inst is ConvertFunctionInst ||
114
- inst is UncheckedEnumDataInst :
109
+ case is UpcastInst ,
110
+ is UncheckedRefCastInst ,
111
+ is InitExistentialRefInst ,
112
+ is OpenExistentialRefInst ,
113
+ is RefToBridgeObjectInst ,
114
+ is BridgeObjectToRefInst ,
115
+ is ConvertFunctionInst ,
116
+ is UncheckedEnumDataInst :
115
117
return inst. operands [ 0 ] . value
116
118
117
119
// Then if we have a struct_extract that is extracting a non-trivial member
118
120
// from a struct with no other non-trivial members, a ref count operation on
119
121
// the struct is equivalent to a ref count operation on the extracted
120
122
// member. Strip off the extract.
121
123
case let sei as StructExtractInst where sei. isFieldOnlyNonTrivialField:
122
- return sei. operands [ 0 ] . value
124
+ return sei. operand
123
125
124
- // If we have a struct instruction with only one non-trivial stored field , the
125
- // only reference count that can be modified is the non-trivial field . Return
126
- // the non-trivial field .
127
- case let si as StructInst :
128
- return si . uniqueNonTrivialOperand
126
+ // If we have a struct or tuple instruction with only one non-trivial operand , the
127
+ // only reference count that can be modified is the non-trivial operand . Return
128
+ // the non-trivial operand .
129
+ case is StructInst , is TupleInst :
130
+ return inst . uniqueNonTrivialOperand
129
131
130
132
// If we have an enum instruction with a payload, strip off the enum to
131
133
// expose the enum's payload.
132
134
case let ei as EnumInst where !ei. operands. isEmpty:
133
- return ei. operands [ 0 ] . value
135
+ return ei. operand
134
136
135
137
// If we have a tuple_extract that is extracting the only non trivial member
136
138
// of a tuple, a retain_value on the tuple is equivalent to a retain_value on
137
139
// the extracted value.
138
140
case let tei as TupleExtractInst where tei. isEltOnlyNonTrivialElt:
139
- return tei. operands [ 0 ] . value
140
-
141
- // If we are forming a tuple and the tuple only has one element with reference
142
- // semantics, a retain_value on the tuple is equivalent to a retain value on
143
- // the tuple operand.
144
- case let ti as TupleInst :
145
- return ti. uniqueNonTrivialOperand
141
+ return tei. operand
146
142
147
143
default :
148
144
return nil
@@ -156,11 +152,8 @@ private extension Instruction {
156
152
var candidateElt : Value ?
157
153
let function = self . function
158
154
159
- // For each operand...
160
155
for op in operands {
161
- // If the operand is not trivial...
162
156
if !op. value. type. isTrivial ( in: function) {
163
- // And we have not found a `candidateElt` yet, set index to `op` and continue.
164
157
if candidateElt == nil {
165
158
candidateElt = op. value
166
159
continue
@@ -178,38 +171,16 @@ private extension Instruction {
178
171
private extension TupleExtractInst {
179
172
var isEltOnlyNonTrivialElt : Bool {
180
173
let function = self . function
181
- // If the elt we are extracting is trivial, we cannot be a non-trivial
182
- // field... return false.
174
+
183
175
if type. isTrivial ( in: function) {
184
176
return false
185
177
}
186
178
187
- // Ok, we know that the elt we are extracting is non-trivial. Make sure that
188
- // we have no other non-trivial elts.
189
179
let opType = operand. type
190
- let fieldNo = self . fieldIndex
191
-
192
- // For each element index of the tuple...
193
- for (i, eltType) in opType. tupleElements. enumerated ( ) {
194
- // If the element index is the one we are extracting, skip it...
195
- if i == fieldNo {
196
- continue
197
- }
198
-
199
- // Otherwise check if we have a non-trivial type. If we don't have one,
200
- // continue.
201
- if eltType. isTrivial ( in: function) {
202
- continue
203
- }
204
180
205
- // If we do have a non-trivial type, return false. We have multiple
206
- // non-trivial types violating our condition.
207
- return false
208
- }
209
-
210
- // We checked every other elt of the tuple and did not find any
211
- // non-trivial elt except for ourselves. Return `true``.
212
- return true
181
+ return opType. tupleElements. filter {
182
+ !$0. isTrivial ( in: function)
183
+ } . count == 1
213
184
}
214
185
}
215
186
@@ -223,14 +194,8 @@ private extension StructExtractInst {
223
194
224
195
let structType = operand. type
225
196
226
- for (i, fieldType) in structType. getStructFields ( in: function) . enumerated ( ) {
227
- if i == fieldIndex || fieldType. isTrivial ( in: function) {
228
- continue
229
- }
230
-
231
- return false
232
- }
233
-
234
- return true
197
+ return structType. getStructFields ( in: function) . filter {
198
+ !$0. isTrivial ( in: function)
199
+ } . count == 1
235
200
}
236
201
}
0 commit comments