Skip to content

[sil] Add a move_value instruction. #39267

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

Conversation

gottesmm
Copy link
Contributor

This is a new instruction that can be used by SILGen to perform a semantic move
in between two entities that are considered separate variables at the AST
level. I am going to use it to implement an experimental borrow checker.

This PR contains the following:

  1. I define move_value, setup parsing, printing, serializing, deserializing,
    cloning, and filled in all of the visitors as appropriate.
  2. I added createMoveValue and emitMoveValueOperation SILBuilder
    APIs. createMoveValue always creates a move and asserts is passed a trivial
    type. emitMoveValueOperation in contrast, will short circuit if passed a
    trivial value and just return the trivial value.
  3. I added IRGen tests to show that we can push this through the entire system.

This is all just scaffolding for the instruction to live in SIL land and as of
this PR doesn't actually do anything.

This is a new instruction that can be used by SILGen to perform a semantic move
in between two entities that are considered separate variables at the AST
level. I am going to use it to implement an experimental borrow checker.

This PR contains the following:

1. I define move_value, setup parsing, printing, serializing, deserializing,
   cloning, and filled in all of the visitors as appropriate.
2. I added createMoveValue and emitMoveValueOperation SILBuilder
   APIs. createMoveValue always creates a move and asserts is passed a trivial
   type. emitMoveValueOperation in contrast, will short circuit if passed a
   trivial value and just return the trivial value.
3. I added IRGen tests to show that we can push this through the entire system.

This is all just scaffolding for the instruction to live in SIL land and as of
this PR doesn't actually do anything.
@gottesmm gottesmm requested review from jckarter and atrick September 12, 2021 18:08
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

@gottesmm gottesmm merged commit fe321ca into swiftlang:main Sep 12, 2021
@gottesmm gottesmm deleted the pr-c8321c6af93e6ad619f35474eb2a74f181c17384 branch September 12, 2021 22:07
%1 = move_value %0 : $@_moveOnly A

Performs a move of the operand, ending its lifetime. When ownership is enabled,
it always takes in an `@owned T` and produces a new `@owned @_moveOnly T`.
Copy link
Contributor

Choose a reason for hiding this comment

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

@gottesmm Both the operand and result of move_value may be either moveOnly or copyable.
Whether either value is moveOnly depends on its type. The important thing about this operation is that it can do a type conversion in either direction between 'moveOnly T' and 'T'. It can also simply perform a move without doing any type conversion.

For the purpose of SIL ownership, it simply forwards an owned value. It has no special properties.

@@ -249,6 +249,9 @@ OPERAND_OWNERSHIP(DestroyingConsume, EndLifetime)
OPERAND_OWNERSHIP(DestroyingConsume, BeginCOWMutation)
OPERAND_OWNERSHIP(DestroyingConsume, EndCOWMutation)

// TODO: Should this be a forwarding consume.
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it should be ForwardingConsume, so why isn't it!

require(mvi->getOperand()->getType().isObject(),
"Operand value should be an object");
require(mvi->getType() == mvi->getOperand()->getType(),
"Result and operand must have the same type, today.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Clearly this type restriction needs to be relaxed once you have moveOnly SIL types

// CHECK-NEXT: } // end sil function 'test_movevalue_parsing'
sil [ossa] @test_movevalue_parsing : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = move_value %0 : $Builtin.NativeObject
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: %1 should be copyable since there's no moveOnly on its SIL type.

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.

2 participants