@@ -21,6 +21,10 @@ import SILBridging
2121public protocol ForwardingInstruction : Instruction {
2222 var singleForwardedOperand : Operand ? { get }
2323
24+ /// Return true if the result has the same object identify, and therefore the same reference counting semantics as the
25+ /// source. This is true for most forwarding operations unless they extract or aggregate components.
26+ var preservesIdentity : Bool { get }
27+
2428 /// Return true if the forwarded value has the same representation. If true, then the result can be mapped to the same storage without a move or copy.
2529 var preservesRepresentation : Bool { get }
2630
@@ -154,6 +158,7 @@ public struct ForwardedResults : Collection {
154158extension StructInst : ForwardingInstruction {
155159 public var singleForwardedOperand : Operand ? { nil }
156160
161+ public var preservesIdentity : Bool { false }
157162 public var preservesRepresentation : Bool { true }
158163 public var canForwardGuaranteedValues : Bool { true }
159164 public var canForwardOwnedValues : Bool { true }
@@ -162,6 +167,7 @@ extension StructInst : ForwardingInstruction {
162167extension TupleInst : ForwardingInstruction {
163168 public var singleForwardedOperand : Operand ? { nil }
164169
170+ public var preservesIdentity : Bool { false }
165171 public var preservesRepresentation : Bool { true }
166172 public var canForwardGuaranteedValues : Bool { true }
167173 public var canForwardOwnedValues : Bool { true }
@@ -170,6 +176,7 @@ extension TupleInst : ForwardingInstruction {
170176extension LinearFunctionInst : ForwardingInstruction {
171177 public var singleForwardedOperand : Operand ? { nil }
172178
179+ public var preservesIdentity : Bool { false }
173180 public var preservesRepresentation : Bool { true }
174181 public var canForwardGuaranteedValues : Bool { true }
175182 public var canForwardOwnedValues : Bool { true }
@@ -178,6 +185,7 @@ extension LinearFunctionInst : ForwardingInstruction {
178185extension DifferentiableFunctionInst : ForwardingInstruction {
179186 public var singleForwardedOperand : Operand ? { nil }
180187
188+ public var preservesIdentity : Bool { false }
181189 public var preservesRepresentation : Bool { true }
182190 public var canForwardGuaranteedValues : Bool { true }
183191 public var canForwardOwnedValues : Bool { true }
@@ -191,6 +199,7 @@ extension MarkDependenceInst : ForwardingInstruction {
191199 return valueOperand
192200 }
193201
202+ public var preservesIdentity : Bool { true }
194203 public var preservesRepresentation : Bool { true }
195204 public var canForwardGuaranteedValues : Bool { true }
196205 public var canForwardOwnedValues : Bool { true }
@@ -201,6 +210,7 @@ extension RefToBridgeObjectInst : ForwardingInstruction {
201210 return convertedOperand
202211 }
203212
213+ public var preservesIdentity : Bool { true }
204214 public var preservesRepresentation : Bool { true }
205215 public var canForwardGuaranteedValues : Bool { true }
206216 public var canForwardOwnedValues : Bool { true }
@@ -209,6 +219,7 @@ extension RefToBridgeObjectInst : ForwardingInstruction {
209219extension TuplePackExtractInst : ForwardingInstruction {
210220 public var singleForwardedOperand : Operand ? { return tupleOperand }
211221
222+ public var preservesIdentity : Bool { false }
212223 public var preservesRepresentation : Bool { true }
213224 public var canForwardGuaranteedValues : Bool { true }
214225 public var canForwardOwnedValues : Bool { false }
@@ -229,6 +240,13 @@ extension TuplePackExtractInst : ForwardingInstruction {
229240/// support type-dependent operands.
230241public protocol ConversionInstruction : SingleValueInstruction , UnaryInstruction , ForwardingInstruction { }
231242
243+ extension ConversionInstruction {
244+ /// Conversion instructions naturally preserve identity as long as they preserve reference counts because they do not
245+ /// aggregate or disaggregate values. They can only lose identity by destroying the source object and instantiating a
246+ /// new object, like certain bridging casts do.
247+ public var preservesIdentity : Bool { preservesReferenceCounts }
248+ }
249+
232250extension MarkUnresolvedNonCopyableValueInst : ConversionInstruction {
233251 public var preservesRepresentation : Bool { true }
234252 public var canForwardGuaranteedValues : Bool { true }
@@ -309,90 +327,105 @@ extension EnumInst : ForwardingInstruction {
309327 return operand // nil for an enum with no payload
310328 }
311329
330+ public var preservesIdentity : Bool { false }
312331 public var preservesRepresentation : Bool { true }
313332 public var canForwardGuaranteedValues : Bool { true }
314333 public var canForwardOwnedValues : Bool { true }
315334}
316335
317336extension DestructureTupleInst : ForwardingInstruction {
337+ public var preservesIdentity : Bool { false }
318338 public var preservesRepresentation : Bool { true }
319339 public var canForwardGuaranteedValues : Bool { true }
320340 public var canForwardOwnedValues : Bool { true }
321341}
322342
323343extension DestructureStructInst : ForwardingInstruction {
344+ public var preservesIdentity : Bool { false }
324345 public var preservesRepresentation : Bool { true }
325346 public var canForwardGuaranteedValues : Bool { true }
326347 public var canForwardOwnedValues : Bool { true }
327348}
328349
329350extension InitExistentialRefInst : ForwardingInstruction {
351+ public var preservesIdentity : Bool { false }
330352 public var preservesRepresentation : Bool { true }
331353 public var canForwardGuaranteedValues : Bool { true }
332354 public var canForwardOwnedValues : Bool { true }
333355}
334356
335357extension OpenExistentialRefInst : ForwardingInstruction {
358+ public var preservesIdentity : Bool { false }
336359 public var preservesRepresentation : Bool { true }
337360 public var canForwardGuaranteedValues : Bool { true }
338361 public var canForwardOwnedValues : Bool { true }
339362}
340363
341364extension OpenExistentialValueInst : ForwardingInstruction {
365+ public var preservesIdentity : Bool { false }
342366 public var preservesRepresentation : Bool { true }
343367 public var canForwardGuaranteedValues : Bool { true }
344368 public var canForwardOwnedValues : Bool { true }
345369}
346370
347371extension OpenExistentialBoxValueInst : ForwardingInstruction {
372+ public var preservesIdentity : Bool { false }
348373 public var preservesRepresentation : Bool { true }
349374 public var canForwardGuaranteedValues : Bool { true }
350375 public var canForwardOwnedValues : Bool { true }
351376}
352377
353378extension StructExtractInst : ForwardingInstruction {
379+ public var preservesIdentity : Bool { false }
354380 public var preservesRepresentation : Bool { true }
355381 public var canForwardGuaranteedValues : Bool { true }
356382 public var canForwardOwnedValues : Bool { false }
357383}
358384
359385extension TupleExtractInst : ForwardingInstruction {
386+ public var preservesIdentity : Bool { false }
360387 public var preservesRepresentation : Bool { true }
361388 public var canForwardGuaranteedValues : Bool { true }
362389 public var canForwardOwnedValues : Bool { false }
363390}
364391
365392extension DifferentiableFunctionExtractInst : ForwardingInstruction {
393+ public var preservesIdentity : Bool { false }
366394 public var preservesRepresentation : Bool { true }
367395 public var canForwardGuaranteedValues : Bool { true }
368396 public var canForwardOwnedValues : Bool { false }
369397}
370398
371399extension CheckedCastBranchInst : ForwardingInstruction {
400+ public var preservesIdentity : Bool { false }
372401 public var preservesRepresentation : Bool { true }
373402 public var canForwardGuaranteedValues : Bool { true }
374403 public var canForwardOwnedValues : Bool { true }
375404}
376405
377406extension UncheckedEnumDataInst : ForwardingInstruction {
407+ public var preservesIdentity : Bool { false }
378408 public var preservesRepresentation : Bool { true }
379409 public var canForwardGuaranteedValues : Bool { true }
380410 public var canForwardOwnedValues : Bool { true }
381411}
382412
383413extension SwitchEnumInst : ForwardingInstruction {
414+ public var preservesIdentity : Bool { false }
384415 public var preservesRepresentation : Bool { true }
385416 public var canForwardGuaranteedValues : Bool { true }
386417 public var canForwardOwnedValues : Bool { true }
387418}
388419
389420extension MarkUnresolvedReferenceBindingInst : ForwardingInstruction {
421+ public var preservesIdentity : Bool { true }
390422 public var preservesRepresentation : Bool { true }
391423 public var canForwardGuaranteedValues : Bool { true }
392424 public var canForwardOwnedValues : Bool { true }
393425}
394426
395427extension LinearFunctionExtractInst : ForwardingInstruction {
428+ public var preservesIdentity : Bool { false }
396429 public var preservesRepresentation : Bool { true }
397430 public var canForwardGuaranteedValues : Bool { true }
398431 public var canForwardOwnedValues : Bool { true }
@@ -404,6 +437,8 @@ extension LinearFunctionExtractInst: ForwardingInstruction {
404437/// An instruction that transfers lifetime dependence from a single operand to a single result. The operand and result
405438/// have the same identity, but they are not part of the same forwarded lifetime:
406439/// copy_value, move_value, begin_borrow.
440+ ///
441+ /// OwnershipTransitionInstructions always preserve the identity of the source. See swift::isIdentityPreservingRefCast.
407442public protocol OwnershipTransitionInstruction : UnaryInstruction {
408443 var ownershipResult : Value { get }
409444}
0 commit comments