[NFC] OwnershipUtils: Add a UsePoint type.

The type is a union of an Operand (a real use) and a SILInstruction (an
implicit use).  Such a type is needed to reflect the fact that with
incomplete lifetimes, values can be implicitly destroyed at the
terminators of blocks in dead end regions (along the vaule's
availability boundary).
This commit is contained in:
Nate Chandler
2025-08-08 15:04:45 -07:00
parent 99091c93ae
commit cbe383524c
2 changed files with 40 additions and 0 deletions

View File

@@ -1441,6 +1441,43 @@ bool isRedundantMoveValue(MoveValueInst *mvi);
/// `forEndBorrowValue`, which is the operand value of an `end_borrow`.
void updateReborrowFlags(SILValue forEndBorrowValue);
/// A location at which a value is used. Abstracts over explicit uses
/// (operands) and implicit uses (instructions).
struct UsePoint {
using Value = llvm::PointerUnion<SILInstruction *, Operand *>;
Value value;
UsePoint(Operand *op) : value(op) {}
UsePoint(SILInstruction *inst) : value(inst) {}
UsePoint(Value value) : value(value) {}
SILInstruction *getInstruction() const {
if (auto *op = dyn_cast<Operand *>(value)) {
return op->getUser();
}
return cast<SILInstruction *>(value);
}
Operand *getOperandOrNull() const { return dyn_cast<Operand *>(value); }
Operand *getOperand() const { return cast<Operand *>(value); }
};
struct UsePointToInstruction {
SILInstruction *operator()(const UsePoint point) const {
return point.getInstruction();
}
};
using UsePointInstructionRange =
TransformRange<ArrayRef<UsePoint>, UsePointToInstruction>;
struct PointToOperand {
Operand *operator()(const UsePoint point) const { return point.getOperand(); }
};
using PointOperandRange = TransformRange<ArrayRef<UsePoint>, PointToOperand>;
} // namespace swift
#endif