Commit Graph

170 Commits

Author SHA1 Message Date
Michael Gottesman
f9f3f53420 [ownership] Add support for adding {end,abort}_apply to the regular user list of owned parameters passed as guaranteed parameters to a begin_apply.
This just follows automagically from the recent work that I did with introducing
BorrowScopeIntroducingOperands.

I confirmed locally that the negative tests do not fail as expected when
visiting the destroys of the guaranteed parameters.
2019-09-25 19:06:59 -07:00
Michael Gottesman
59a57ed044 [ownership] Introduce a new BorrowScopeIntroducingOperand that is used to work with implicit uses of owned parameters implied by their use by a borrow scope introducing value.
For now this only is used for ensuring that an owned value that has a
begin_borrow use, adds the end_borrows matched to the begin_borrow to the owned
values implicit regular user list.

I am going to use this same functionality to model the requirements around
begin_apply and mark_dependence (when I add an end_mark_dependence instruction).
2019-09-25 19:06:59 -07:00
Michael Gottesman
12aa95ac1e [ownership] Only allow BranchPropagatedUser to be constructed from Operands.
This commit only changes how BranchPropagatedUser is constructed and does not
change the internal representation. This is a result of my noticing that
BranchPropagatedUser could also use an operand internally to represent its
state. To simplify how I am making the change, I am splitting the change into
two PRs that should be easy to validate:

1. A commit that maps how the various users of BranchPropagatedUser have been
constructing BPUs to a single routine that takes an Operand. This leaves
BranchPropagatedUser's internal state alone as well as its user the Linear
Lifetime Checker.

2. A second commit that changes the internal bits of the BranchPropagatedUser to
store an Operand instead of a PointerUnion.

This will allow me to use the first commit to validate the second.
2019-09-23 17:24:55 -07:00
Michael Gottesman
7e3608e007 [ownership] Add a new checkValue overload to LinearLifetimeChecker that validates the linear lifetime of the passed in value and returns bool to indicate success/failure.
This is the first in a series of patches that begin to hide the underlying
linear lifetime implementation underneath the facade of the linear lifetime
checker. I only updated the users that this applies to.
2019-09-17 14:41:30 -07:00
Michael Gottesman
dceca2bc3b [ownership] Create a context structure for the linear lifetime checker.
This is just a simple refactoring commit in preparation for hiding more of the
details of the linear lifetime checker. This is NFC, just moving around code.
2019-09-16 20:13:56 -07:00
Michael Gottesman
bb4df032e7 [ownership] Add a new class BorrowScopeIntroducingValue that enables code to work abstractly with values that introduce a new borrow scope.
The idea is that this can be used to work with things like load_borrow,
begin_borrow, SILFunctionArgument, results of begin_apply(in the future) and the like in a
generic way using exhaustive switches to make sure this code stays up to date.

I refactored code in SemanticARCOpts and some utilities in OwnershipUtils.cpp to
use these new APIs. The code looks a lot nicer and should be quite easy to
expand to handle new borrow introducers (e.x.: end_apply).
2019-09-16 09:33:49 -07:00
Andrew Trick
207a4f714b Add LoadBorrow::getEndBorrows() and minor cleanup.
Instructions that start a scope should have a (discoverable) method
that retrieves the end of scope. This is a basic structural property
of the instruction.

I removed the makeEndBorrowRange helper because it adds overall
complexity and doesn't provide any value. If some code wants to be
generic over BeginBorrow/LoadBorrow, then that code should have it's
own trivial generic helper:

EndBorrowRange getEndBorrows<T>(T *beginBorrow) {
  return beginBorrow->getEndBorrows()
}
2019-05-07 11:35:10 -07:00
Michael Gottesman
f2d7dcaffd [ownership] Create a generic makeEndBorrowRange that can find end_borrow of {begin,load}_borrow.
We had a version of this specially for BeginBorrow. Makes sense to generalize
it.
2019-04-02 16:00:24 -07:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04:00
Michael Gottesman
a310f23b8a [ownership] Add support for load_borrow in predictable mem opt.
This reduces the diff in between -Onone output when stripping before/after
serialization.

We support load_borrow by translating it to the load [copy] case. Specifically,
for +1, we normally perform the following transform.

  store %1 to [init] %0
  ...
  %2 = load [copy] %0
  ...
  use(%2)
  ...
  destroy_value %2

=>

  %1a = copy_value %1
  store %1 to [init] %0
  ...
  use(%1a)
  ...
  destroy_value %1a

We analogously can optimize load_borrow by replacing the load with a
begin_borrow:

  store %1 to [init] %0
  ...
  %2 = load_borrow %0
  ...
  use(%2)
  ...
  end_borrow %2

=>

  %1a = copy_value %1
  store %1 to [init] %0
  ...
  %2 = begin_borrow %1a
  ...
  use(%2)
  ...
  end_borrow %2
  destroy_value %1a

The store from outside a loop being used by a load_borrow inside a loop is a
similar transformation as the +0 version except that we use a begin_borrow
inside the loop instead of a copy_value (making it even more efficient).
2019-02-11 00:54:28 -08:00
Michael Gottesman
a8dfac4788 [ownership] Use the new LinearLifetimeError to propagate back to callers why the checker failed. 2019-01-28 15:23:15 -08:00
Michael Gottesman
224c8a5801 [ownership] Use a richer error result than bool.
I am starting to use the linear lifetime checker in an optimizer role where it
no longer asserts but instead tells the optimizer pass what is needed to cause
the lifetime to be linear. To do so I need to be able to return richer
information to the caller such as whether or not a leak, double consume, or
use-after-free occurs.
2019-01-28 12:47:40 -08:00
Michael Gottesman
6f767f8b34 [sil] Delete dead code.
Originally I wanted to try to use this code to optimize on ownership sil without
assuming verification passed (since the utility would check verification). In
the end, this was not useful.
2019-01-24 20:02:02 -08:00
Michael Gottesman
f8f11fadf6 [ownership] Allow for callers of the linear lifetime checker to ask it to return leaking blocks instead of erroring.
A common pattern when working in ossa is the introduction of a copy for lifetime
reasons at a dominating point in a program with a single use that may not
post-dominate the use. This API gives a "tight lifetime" bound by returning the
blocks where the value needs to be destroyed to prevent leaks.

NOTE: I was not 100% sure if consume errors should still assert. It seems like a
double consume error would be user error, so an assert is probably fine.
2019-01-22 01:34:39 -08:00
Michael Gottesman
099cae5692 [semantic-arc-opts] Handle arg extract + copy + borrow + use.
Specifically, now the optimizer can take the following code:

sil @foo: $@convention(thin) (@guaranteed NativeObjectPair) -> () {
bb0(%0 : @guaranteed $NativeObjectPair):
  %1 = struct_extract %0 : $NativeObjectPair, #NativeObjectPair.obj1
  %2 = copy_value %1 : $Builtin.NativeObject
  %3 = begin_borrow %2 : $Builtin.NativeObject
  %foo = function_ref ...
  apply %foo(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
  end_borrow %3 : $Builtin.NativeObject
  destroy_value %2 : $Builtin.NativeObject
  ...
}

and eliminate all ownership instructions. I.e.:

sil @foo: $@convention(thin) (@guaranteed NativeObjectPair) -> () {
bb0(%0 : @guaranteed $NativeObjectPair):
  %1 = struct_extract %0 : $NativeObjectPair, #NativeObjectPair.obj1
  %foo = function_ref ....
  apply %foo(%1)
  ...
}

Before this the optimizer could only eliminate 200 insts in the stdlib. With
this change, we now can eliminate ~7000.
2018-11-13 12:07:48 -08:00
Michael Gottesman
1baf38cb07 [sil] Split operand ownership classification from SILOwnershipVerifier.cpp into OperandOwnership.cpp.
Last week I split out operand ownership classification from the
SILOwnershipVerifier into the OperandOwnershipKindClassifier. Now move that
classifier code to another file so that SILOwnershipVerifier.cpp just consists
of the actual checker code. This makes sense since this type of classifier is
describing a separate structural aspect of SIL rather than something intrinsic
to the ownership verifier.

Keep in mind that this is not the final form of this classifier. Just an
incremental step forward.
2018-10-10 17:24:53 -07:00
Michael Gottesman
157091d5c6 [ownership] Extract out from SILOwnershipVerifier the OperandOwnershipKindMapClassifier
NOTE: This is not the final form of how operand ownership restraints will be
represented. This patch is instead an incremental change that extracts out this
functionality from the ownership verifier as a pure refactor.

rdar://44667493
2018-10-01 22:14:41 -07:00
Michael Gottesman
c599539044 [sil] Eliminate the src parameter from end_borrow.
This does not eliminate the entrypoints on SILBuilder yet. I want to do this in
two parts so that it is functionally easier to disentangle changing the APIs
above SILBuilder and changing the underlying instruction itself.

rdar://33440767
2018-09-04 16:38:24 -07:00
Michael Gottesman
fa157871f0 [func-sig-opts][+0->+1] Extract out the LinearLifetimeChecker from the Ownership verifier.
I am doing this for two reasons:

1. I am going to use this in function signature opts to prove that a guaranteed
parameter is "consumed".
2. It puts the ownership verifier on a diet.

rdar://38196046
2018-05-08 16:47:17 -07:00
Michael Gottesman
0de2b76ec9 [func-sig-opts][+0->+1] Rename OwnershipChecker.h => OwnershipUtils.h
I am going to be expanding this to contain more general utilities so naming the
file OwnershipChecker.h really doesn't make sense.

rdar://38196046
2018-05-08 11:21:06 -07:00