Skip to content

Commit 5a92dfb

Browse files
authored
Merge pull request #35401 from atrick/move-canacceptunowned
2 parents 377a225 + 7c3865c commit 5a92dfb

File tree

2 files changed

+63
-27
lines changed

2 files changed

+63
-27
lines changed

include/swift/SIL/SILValue.h

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -757,12 +757,45 @@ struct OperandOwnership {
757757
llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
758758
const OperandOwnership &operandOwnership);
759759

760-
/// Defined inline so the switch is eliminated for constant OperandOwnership.
760+
/// Map OperandOwnership to the OwnershipConstraint used in OSSA validation.
761+
///
762+
/// Each OperandOwnership kind maps directly to a fixed OwnershipConstraint. Any
763+
/// value that can be legally passed to this operand must have an ownership kind
764+
/// permitted by this constraint. A constraint permits an ownership kind if,
765+
/// when it is applied to that ownership kind via a lattice join, it returns the
766+
/// same ownership kind, indicating that no restriction exists.
767+
///
768+
/// Consequently, OperandOwnership kinds that are allowed to take either Owned
769+
/// or Guaranteed values map to an OwnershipKind::Any constraint.
770+
///
771+
/// Unowned values are more restricted than then Owned or Guaranteed values in
772+
/// terms of their valid uses, which helps limit the situations where the
773+
/// implementation needs to consider this special case. This additional
774+
/// restriction is validated by `canAcceptUnownedValue`.
775+
///
776+
/// Forwarding instructions that produce Owned or Guaranteed values always
777+
/// forward an operand of the same ownership kind. Each case has a distinct
778+
/// OperandOwnership (ForwardingConsume and ForwardingBorrow), which enforces a
779+
/// specific constraint on the operand's ownership. Forwarding instructions that
780+
/// produce an Unowned value, however, may forward an operand of any
781+
/// ownership. Therefore, ForwardingUnowned is mapped to OwnershipKind::Any.
782+
///
783+
/// This design yields the following advantages:
784+
///
785+
/// 1. Keeping the verification of Unowned in a separate utility avoids
786+
/// the need to add an extra OwnedOrGuaranteed state to the OwnershipKind
787+
/// lattice. That state would be meaningless as a representation of value
788+
/// ownership, would serve no purpose as a data flow state, and would make
789+
/// the basic definition of ownership less approachable to developers.
761790
///
762-
/// Here, an Any ownership constraint is used to allow either Owned or
763-
/// Guaranteed values. However, enforcement of Unowned values is more
764-
/// strict. This is handled by separate logic in canAcceptUnownedValue() to
765-
/// avoid complicating the OwnershipKind lattice.
791+
/// 2. Owned or Guaranteed values can be passed to instructions that want to
792+
/// produce an unowned result from a parent operand. This simplifies the IR
793+
/// and makes RAUWing Unowned values with Owned or Guaranteed values much
794+
/// easier since it does not need to introduce operations that convert those
795+
/// values to Unowned. This significantly simplifies the implementation of
796+
/// OSSA utilities.
797+
///
798+
/// Defined inline so the switch is eliminated for constant OperandOwnership.
766799
inline OwnershipConstraint OperandOwnership::getOwnershipConstraint() {
767800
switch (value) {
768801
case OperandOwnership::TrivialUse:
@@ -788,6 +821,31 @@ inline OwnershipConstraint OperandOwnership::getOwnershipConstraint() {
788821
}
789822
}
790823

824+
/// Return true if this use can accept Unowned values.
825+
///
826+
/// This extra restriction is applied on top of the OwnershipConstraint to limit
827+
/// the spread of Unowned values.
828+
inline bool canAcceptUnownedValue(OperandOwnership operandOwnership) {
829+
switch (operandOwnership) {
830+
case OperandOwnership::NonUse:
831+
case OperandOwnership::UnownedInstantaneousUse:
832+
case OperandOwnership::ForwardingUnowned:
833+
case OperandOwnership::PointerEscape:
834+
case OperandOwnership::BitwiseEscape:
835+
return true;
836+
case OperandOwnership::TrivialUse:
837+
case OperandOwnership::InstantaneousUse:
838+
case OperandOwnership::Borrow:
839+
case OperandOwnership::DestroyingConsume:
840+
case OperandOwnership::ForwardingConsume:
841+
case OperandOwnership::InteriorPointer:
842+
case OperandOwnership::ForwardingBorrow:
843+
case OperandOwnership::EndBorrow:
844+
case OperandOwnership::Reborrow:
845+
return false;
846+
}
847+
}
848+
791849
/// Return the OperandOwnership for a forwarded operand when the forwarded
792850
/// result has this ValueOwnershipKind. \p allowUnowned is true for a subset
793851
/// of forwarding operations that are allowed to propagate Unowned values.

lib/SIL/IR/SILValue.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -319,28 +319,6 @@ SILFunction *Operand::getParentFunction() const {
319319
return self->getUser()->getFunction();
320320
}
321321

322-
/// Return true if this use can accept Unowned values.
323-
static bool canAcceptUnownedValue(OperandOwnership operandOwnership) {
324-
switch (operandOwnership) {
325-
case OperandOwnership::NonUse:
326-
case OperandOwnership::UnownedInstantaneousUse:
327-
case OperandOwnership::ForwardingUnowned:
328-
case OperandOwnership::PointerEscape:
329-
case OperandOwnership::BitwiseEscape:
330-
return true;
331-
case OperandOwnership::TrivialUse:
332-
case OperandOwnership::InstantaneousUse:
333-
case OperandOwnership::Borrow:
334-
case OperandOwnership::DestroyingConsume:
335-
case OperandOwnership::ForwardingConsume:
336-
case OperandOwnership::InteriorPointer:
337-
case OperandOwnership::ForwardingBorrow:
338-
case OperandOwnership::EndBorrow:
339-
case OperandOwnership::Reborrow:
340-
return false;
341-
}
342-
}
343-
344322
bool Operand::canAcceptKind(ValueOwnershipKind kind) const {
345323
auto operandOwnership = getOperandOwnership();
346324
auto constraint = operandOwnership.getOwnershipConstraint();

0 commit comments

Comments
 (0)