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()
}
I have been meaning to do this change for a minute, but kept on putting it off.
This describes what is actually happening and is a better name for the option.
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.
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.
In a previous commit, I banned in the verifier any SILValue from producing
ValueOwnershipKind::Any in preparation for this.
This change arises out of discussions in between John, Andy, and I around
ValueOwnershipKind::Trivial. The specific realization was that this ownership
kind was an unnecessary conflation of the a type system idea (triviality) with
an ownership idea (@any, an ownership kind that is compatible with any other
ownership kind at value merge points and can only create). This caused the
ownership model to have to contort to handle the non-payloaded or trivial cases
of non-trivial enums. This is unnecessary if we just eliminate the any case and
in the verifier separately verify that trivial => @any (notice that we do not
verify that @any => trivial).
NOTE: This is technically an NFC intended change since I am just replacing
Trivial with Any. That is why if you look at the tests you will see that I
actually did not need to update anything except removing some @trivial ownership
since @any ownership is represented without writing @any in the parsed sil.
rdar://46294760
This is in preparation for verifying that when ownership verification is enabled
that only enums and trivial values can have any ownership. I am doing this in
preparation for eliminating ValueOwnershipKind::Trivial.
rdar://46294760
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.
We already allow for "instantaneous borrowing" for passing @owned values as
@guaranteed arguments. There is no reason why we shouldn't do this for
partial_apply as well.
rdar://29791263
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
This silences the instances of the warning from Visual Studio about not all
codepaths returning a value. This makes the output more readable and less
likely to lose useful warnings. NFC.
Now we properly enforce that all guaranteed phi arguments's lifetime is
completely enclosed by the lifetimes of the phi argument's inputs. This is
implemented by inserting an "implicit" regular use into the use stream of the
phi argument's inputs. This is nice since it ensures that when we are verifying
ownership of a specific argument, we will not walk through all
subarguments... instead we just need to verify that the end_borrow is completely
enclosed within the lifetime of the input guaranteed value.
I also fixed a case where we were bailing early out of the SIL Ownership
Verifier causing us to emit an incorrect error. This error would only occur if
we already diagnosed an error.
I also re-added all of the tests that I removed when I replaced
end_borrow_argument with end_borrow.
rdar://33440767
I changed all of the places that used end_borrow_argument to use end_borrow.
NOTE: I discovered in the process of this patch that we are not verifying
guaranteed block arguments completely. I disabled the tests here that show this
bad behavior and am going to re-enable them with more tests in a separate PR.
This has not been a problem since SILGen does not emit any such arguments as
guaranteed today. But once I do the SILGenPattern work this will change.
rdar://33440767
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
For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.
`_read` accessors do not make any effort yet to avoid copying the
value being yielded. I'll work on it in follow-up patches.
Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.
SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.
rdar://35399664
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
Mandatory pass will clean it up and replace it by a copy_block and
is_escaping/cond_fail/release combination on the %closure in follow-up
patches.
The instruction marks the dependence of a block on a closure that is
used as an 'withoutActuallyEscaping' sentinel.
rdar://39682865
Since the functions produce pointers with tightly-scoped lifetimes there's no formal reason these have to only work on `inout` things. Now that arguments can be +0, we can even do this without copying values that we already have at +0.
Will be used to verify that withoutActuallyEscaping's block does not
escape the closure.
``%escaping = is_escaping_closure %closure`` tests the reference count. If the
closure is not uniquely referenced it prints out and error message and
returns true. Otherwise, it returns false. The returned result can be
used with a ``cond_fail %escaping`` instruction to abort the program.
rdar://35525730
I have a bunch of work that I have done on a side branch some time ago to split
determining what value ownership kinds are able to be associated with a specific
operand.
This PR just upstreams a small part of the larger change.
The ownership verifier diagnoses leaks of owned objects in two different
places/ways:
1. If the owned value does not have any "consuming" uses, we bail early without
performing dataflow verification.
2. If the owned value has at least 1 "consuming" uses, we perform dataflow to
determine the blocks where the leaked value escapes without being destroyed.
In the latter case, we give a nice error message saying that a leak occured. In
contrast in the former, we go down a "generic error" path that just says that a
"lifetime ending use" is required. This commit changes that generic error
message for owned parameters to say that the value was leaked, resulting in a
clearer message. The other cases are still left along though.
I also added a test file to specifically test leaks/leak error messages. I added
a few tests to make sure this error message is correct and a few more tests just
for fun.