-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Move canAcceptUnownedValue to SILValue.h. #35401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@swift-ci smoke test |
include/swift/SIL/SILValue.h
Outdated
/// strict. This is handled by separate logic in canAcceptUnownedValue() to | ||
/// avoid complicating the OwnershipKind lattice. | ||
/// strict. This is handled by separate logic below in canAcceptUnownedValue() | ||
/// to avoid complicating the OwnershipKind lattice. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment can be made significantly clearer. My suggestion:
/// Map our semantics providing OperandOwnership to the OwnershipConstraint that
/// is used in OSSA validation.
///
/// DISCUSSION: Unowned Values and the "Missing" OwnershipKind::None
/// constraint. Each OperandOwnership maps to a fixed OwnershipConstraint. The
/// OwnershipConstraint of an OperandOwnership represents the constraint on the
/// types of Values that can be applied to operands that have a specific
/// OperandOwnership. We require that all operand's have the property that its
/// ownership constraint has a valid join with its value ownership kind in terms
/// of the OwnershipKind lattice. Given that, if we:
///
/// 1. Map all of the OperandOwnership that are allowed to take an Unowned value
/// to OwnershipKind::Any.
/// 2. Validate whether or not a use can take an unowned value as a separate
/// query when verifying ownership.
///
/// We get the following properties:
///
/// 1. We can pass owned/guaranteed values to instructions that want to produce
/// an unowned result from a parent operand. This simplifies the IR and makes
/// RAUWing unowned values with owned/guaranteed values a lot easier since
/// one does not need to convert the owned/guaranteed value to unowned. This
/// is a huge simplification.
///
/// 2. By keeping the verification of Unowned in a separate utility, we avoid
/// having to add extra states to the OwnershipKind lattice, simplifying the
/// implementation.
Also, I wonder if you could constexpr this X ). Then it would really be guaranteed to be constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know its a lot more text, but its weird that we never return OwnershipKind::Unowned from here so I think the explanation is warranted and this will answer any/all questions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gottesmm That's great, I had thought the discussion belonged in the definition of OwnershipConstraint
where it's already explained. But it's worth going into more detail here... here's my take
/// Map OperandOwnership to the OwnershipConstraint used in OSSA validation.
///
/// Each OperandOwnership kind maps directly to a fixed OwnershipConstraint. Any
/// value that can be legally passed to this operand must have an ownership kind
/// permitted by this constraint. A constraint permits an ownership kind if,
/// when it is applied to that ownership kind via a lattice join, it returns the
/// same ownership kind, indicating that no restriction exists.
///
/// Consequently, OperandOwnership kinds that are allowed to take either Owned
/// or Guaranteed values map to an OwnershipKind::Any constraint.
///
/// Unowned values are more restricted than then Owned or Guaranteed values in
/// terms of their valid uses, which helps limit the situations where the
/// implementation needs to consider this special case. This additional
/// restriction is validated by `canAcceptUnownedValue`.
///
/// Forwarding instructions that produce Owned or Guaranteed values always
/// forward an operand of the same ownership kind. Each case has a distinct
/// OperandOwnership (ForwardingConsume and ForwardingBorrow), which enforces a
/// specific constraint on the operand's ownership. Forwarding instructions that
/// produce an Unowned value, however, may forward an operand of any
/// ownership. Therefore, ForwardingUnowned is mapped to OwnershipKind::Any.
///
/// This design yields the following advantages:
///
/// 1. Keeping the verification of Unowned in a separate utility avoids
/// the need to add an extra OwnedOrGuaranteed state to the OwnershipKind
/// lattice. That state would be meaningless as a representation of value
/// ownership, would serve no purpose as a data flow state, and would make
/// the basic definition of ownership less approachable to developers.
///
/// 2. Owned or Guaranteed values can be passed to instructions that want to
/// produce an unowned result from a parent operand. This simplifies the IR
/// and makes RAUWing Unowned values with Owned or Guaranteed values much
/// easier since it does not need to introduce operations that convert those
/// values to Unowned. This significantly simplifies the implementation of
/// OSSA utilities.
///
/// Defined inline so the switch is eliminated for constant OperandOwnership.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
323dfbf
to
00dce3d
Compare
Now all the logic for mapping OperandOwnership to operand constraints is defined in one place and fits on a single page.
00dce3d
to
7c3865c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for improving the comment. LGTM
/// Consequently, OperandOwnership kinds that are allowed to take either Owned | ||
/// or Guaranteed values map to an OwnershipKind::Any constraint. | ||
/// | ||
/// Unowned values are more restricted than then Owned or Guaranteed values in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed -> 'than then'. I think it is typo.
@swift-ci smoke test and merge |
Now all the logic for mapping OperandOwnership to operand constraints
is defined in one place and fits on a single page.