Skip to content

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

Merged
merged 1 commit into from
Jan 14, 2021

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Jan 13, 2021

Now all the logic for mapping OperandOwnership to operand constraints
is defined in one place and fits on a single page.

@atrick atrick requested a review from gottesmm January 13, 2021 03:39
@atrick
Copy link
Contributor Author

atrick commented Jan 13, 2021

@swift-ci smoke test

/// 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.
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

@atrick atrick Jan 13, 2021

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@atrick atrick force-pushed the move-canacceptunowned branch from 323dfbf to 00dce3d Compare January 13, 2021 18:49
Now all the logic for mapping OperandOwnership to operand constraints
is defined in one place and fits on a single page.
@atrick atrick force-pushed the move-canacceptunowned branch from 00dce3d to 7c3865c Compare January 13, 2021 18:51
Copy link
Contributor

@gottesmm gottesmm left a 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
Copy link
Contributor

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.

@atrick
Copy link
Contributor Author

atrick commented Jan 13, 2021

@swift-ci smoke test and merge

@swift-ci swift-ci merged commit 5a92dfb into swiftlang:main Jan 14, 2021
@atrick atrick deleted the move-canacceptunowned branch January 30, 2021 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants