@@ -102,47 +102,43 @@ private func tryDevirtualizeReleaseOfObject(
102102}
103103
104104private func stripRCIdentityPreservingInsts( _ value: Value ) -> Value ? {
105- switch value {
105+ guard let inst = value as? Instruction else { return nil }
106+
107+ switch inst {
106108 // 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 :
115117 return inst. operands [ 0 ] . value
116118
117119 // Then if we have a struct_extract that is extracting a non-trivial member
118120 // from a struct with no other non-trivial members, a ref count operation on
119121 // the struct is equivalent to a ref count operation on the extracted
120122 // member. Strip off the extract.
121123 case let sei as StructExtractInst where sei. isFieldOnlyNonTrivialField:
122- return sei. operands [ 0 ] . value
124+ return sei. operand
123125
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
129131
130132 // If we have an enum instruction with a payload, strip off the enum to
131133 // expose the enum's payload.
132134 case let ei as EnumInst where !ei. operands. isEmpty:
133- return ei. operands [ 0 ] . value
135+ return ei. operand
134136
135137 // If we have a tuple_extract that is extracting the only non trivial member
136138 // of a tuple, a retain_value on the tuple is equivalent to a retain_value on
137139 // the extracted value.
138140 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
146142
147143 default :
148144 return nil
@@ -156,11 +152,8 @@ private extension Instruction {
156152 var candidateElt : Value ?
157153 let function = self . function
158154
159- // For each operand...
160155 for op in operands {
161- // If the operand is not trivial...
162156 if !op. value. type. isTrivial ( in: function) {
163- // And we have not found a `candidateElt` yet, set index to `op` and continue.
164157 if candidateElt == nil {
165158 candidateElt = op. value
166159 continue
@@ -178,38 +171,16 @@ private extension Instruction {
178171private extension TupleExtractInst {
179172 var isEltOnlyNonTrivialElt : Bool {
180173 let function = self . function
181- // If the elt we are extracting is trivial, we cannot be a non-trivial
182- // field... return false.
174+
183175 if type. isTrivial ( in: function) {
184176 return false
185177 }
186178
187- // Ok, we know that the elt we are extracting is non-trivial. Make sure that
188- // we have no other non-trivial elts.
189179 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- }
204180
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
213184 }
214185}
215186
@@ -223,14 +194,8 @@ private extension StructExtractInst {
223194
224195 let structType = operand. type
225196
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
235200 }
236201}
0 commit comments