@@ -41,7 +41,6 @@ import SIL
4141///
4242let objectOutliner = FunctionPass ( name: " object-outliner " ) {
4343 ( function: Function , context: FunctionPassContext ) in
44-
4544 for inst in function. instructions {
4645 if let ari = inst as? AllocRefInstBase {
4746 if let globalValue = optimizeObjectAllocation ( allocRef: ari, context) {
@@ -85,6 +84,10 @@ private func findEndCOWMutation(of object: Value) -> EndCOWMutationInst? {
8584 if let ecm = findEndCOWMutation ( of: uci) {
8685 return ecm
8786 }
87+ case let urci as UncheckedRefCastInst :
88+ if let ecm = findEndCOWMutation ( of: urci) {
89+ return ecm
90+ }
8891 case let mv as MoveValueInst :
8992 if let ecm = findEndCOWMutation ( of: mv) {
9093 return ecm
@@ -147,7 +150,7 @@ private func findInitStores(of object: Value,
147150 return false
148151 }
149152 default :
150- if !isValidUseOfObject( use. instruction ) {
153+ if !isValidUseOfObject( use) {
151154 return false
152155 }
153156 }
@@ -174,6 +177,18 @@ private func findStores(toTailAddress tailAddr: Value, tailElementIndex: Int, st
174177 if !findStores( inUsesOf: tea, index: tailElementIndex * numTupleElements + tupleIdx, stores: & stores) {
175178 return false
176179 }
180+ case let atp as AddressToPointerInst :
181+ if !findStores( toTailAddress: atp, tailElementIndex: tailElementIndex, stores: & stores) {
182+ return false
183+ }
184+ case let mdi as MarkDependenceInst :
185+ if !findStores( toTailAddress: mdi, tailElementIndex: tailElementIndex, stores: & stores) {
186+ return false
187+ }
188+ case let pta as PointerToAddressInst :
189+ if !findStores( toTailAddress: pta, tailElementIndex: tailElementIndex, stores: & stores) {
190+ return false
191+ }
177192 case let store as StoreInst :
178193 if store. source. type. isTuple {
179194 // This kind of SIL is never generated because tuples are stored with separated stores to tuple_element_addr.
@@ -184,7 +199,7 @@ private func findStores(toTailAddress tailAddr: Value, tailElementIndex: Int, st
184199 return false
185200 }
186201 default :
187- if !isValidUseOfObject( use. instruction ) {
202+ if !isValidUseOfObject( use) {
188203 return false
189204 }
190205 }
@@ -198,7 +213,7 @@ private func findStores(inUsesOf address: Value, index: Int, stores: inout [Stor
198213 if !handleStore( store, index: index, stores: & stores) {
199214 return false
200215 }
201- } else if !isValidUseOfObject( use. instruction ) {
216+ } else if !isValidUseOfObject( use) {
202217 return false
203218 }
204219 }
@@ -215,7 +230,8 @@ private func handleStore(_ store: StoreInst, index: Int, stores: inout [StoreIns
215230 return false
216231}
217232
218- private func isValidUseOfObject( _ inst: Instruction ) -> Bool {
233+ private func isValidUseOfObject( _ use: Operand ) -> Bool {
234+ let inst = use. instruction
219235 switch inst {
220236 case is DebugValueInst ,
221237 is LoadInst ,
@@ -227,6 +243,17 @@ private func isValidUseOfObject(_ inst: Instruction) -> Bool {
227243 is EndCOWMutationInst :
228244 return true
229245
246+ case let mdi as MarkDependenceInst :
247+ if ( use == mdi. baseOperand) {
248+ return true ;
249+ }
250+ for mdiUse in mdi. uses {
251+ if !isValidUseOfObject( mdiUse) {
252+ return false
253+ }
254+ }
255+ return true
256+
230257 case is StructElementAddrInst ,
231258 is AddressToPointerInst ,
232259 is StructInst ,
@@ -238,9 +265,12 @@ private func isValidUseOfObject(_ inst: Instruction) -> Bool {
238265 is UpcastInst ,
239266 is BeginDeallocRefInst ,
240267 is RefTailAddrInst ,
241- is RefElementAddrInst :
242- for use in ( inst as! SingleValueInstruction ) . uses {
243- if !isValidUseOfObject( use. instruction) {
268+ is RefElementAddrInst ,
269+ is StructInst ,
270+ is PointerToAddressInst ,
271+ is IndexAddrInst :
272+ for instUse in ( inst as! SingleValueInstruction ) . uses {
273+ if !isValidUseOfObject( instUse) {
244274 return false
245275 }
246276 }
@@ -342,6 +372,8 @@ private func rewriteUses(of startValue: Value, _ context: FunctionPassContext) {
342372 context. erase ( instruction: endMutation)
343373 case let upCast as UpcastInst :
344374 worklist. pushIfNotVisited ( usersOf: upCast)
375+ case let urci as UncheckedRefCastInst :
376+ worklist. pushIfNotVisited ( usersOf: urci)
345377 case let moveValue as MoveValueInst :
346378 worklist. pushIfNotVisited ( usersOf: moveValue)
347379 case is DeallocRefInst , is DeallocStackRefInst :
0 commit comments