@@ -69,6 +69,8 @@ struct LoadOperation {
69
69
};
70
70
71
71
// / A wrapper type for writing generic code against conversion instructions.
72
+ // /
73
+ // / Forwards a single operand in first operand position to a single result.
72
74
struct ConversionOperation {
73
75
SingleValueInstruction *inst = nullptr ;
74
76
@@ -259,19 +261,33 @@ class ForwardingOperation {
259
261
case SILInstructionKind::LinearFunctionInst:
260
262
case SILInstructionKind::DifferentiableFunctionInst:
261
263
return nullptr ;
264
+ case SILInstructionKind::MarkDependenceInst:
265
+ return &forwardingInst->getOperandRef (MarkDependenceInst::Value);
266
+ case SILInstructionKind::RefToBridgeObjectInst:
267
+ return
268
+ &forwardingInst->getOperandRef (RefToBridgeObjectInst::ConvertedOperand);
269
+ case SILInstructionKind::TuplePackExtractInst:
270
+ return &forwardingInst->getOperandRef (TuplePackExtractInst::TupleOperand);
271
+ case SILInstructionKind::SelectEnumInst:
272
+ // ignore trailing case operands
273
+ return &forwardingInst->getOperandRef (0 );
262
274
default :
263
- if (forwardingInst->getNumRealOperands () == 0 ) {
275
+ int numRealOperands = forwardingInst->getNumRealOperands ();
276
+ if (numRealOperands == 0 ) {
264
277
// This can happen with enum instructions that have no payload.
265
278
return nullptr ;
266
279
}
280
+ assert (numRealOperands == 1 );
267
281
return &forwardingInst->getOperandRef (0 );
268
282
}
269
283
}
270
284
271
285
ArrayRef<Operand> getForwardedOperands () const {
286
+ // Some instructions have multiple real operands but only forward one.
272
287
if (auto *singleForwardingOp = getSingleForwardingOperand ()) {
273
288
return *singleForwardingOp;
274
289
}
290
+ // All others forward all operands (for enum, this may be zero operands).
275
291
return forwardingInst->getAllOperands ();
276
292
}
277
293
0 commit comments