Commit Graph

203 Commits

Author SHA1 Message Date
Michael Gottesman
13d01394d4 [region-isolation] Change the region -> transferring operand map to use a MapVector instead of a DenseMap.
This ensures that we can efficiently iterate over the map which we will need to
do for equality queries.

I am going to add the equality queries in a subsequent commit. Just chopping off
a larger commit.
2024-04-09 10:56:19 -07:00
Michael Gottesman
6844b995a4 [region-isolation] Wire up history diagnostics through the checker, but do not use it to emit diagnostics yet.
Specifically:

1. I copy the history that we have been tracking from the transferring operand
value at the transfer point. This is then available for use to emit diagnostics.

2. I added the ability for SILIsolationInfo to not only track the ActorIsolation
of an actor isolated value, but also if we have a value, we can track that as
well. Since we now track a value for task isolated and actor isolated
SILIsolationInfo, I just renamed the field to isolatedValue and moved it out of
the enum.

In a subsequent commit, I am going to wire it up to a few diagnostics.

rdar://123479934
2024-04-06 00:58:10 -07:00
Michael Gottesman
d6b4f16382 [region-isolation] Add a SILLocation to SequenceBoundary in IsolationHistory.
We package all isolation history nodes from a single instruction by placing a
sequence boundary at the bottom. When ever we pop, we actually pop a PartitionOp
at a time meaning that we pop until we see a SequenceBoundary. Thus the sequence
boundary will always be the last element visited when popping meaning that it is
a convenient place to stick the SILLocation associated with the entire
PartitionOp. As a benefit, there was some unused space in IsolationHistory::Node
for that case since we were not using the std::variant field at all.
2024-04-06 00:58:10 -07:00
Michael Gottesman
aee5a37d9d [region-isolation] Add isolation history support but do not wire it up to the checker.
This means that I added an IsolationHistory field to Partition. Just upstreaming
the beginning part of this work. I added some unittests to exercise the code as
well. NOTE: This means that I did need to begin tracking an
IsolationHistoryFactory and propagating IsolationHistory in the pass
itself... but we do not use it for anything.

A quick overview of the design.

IsolationHistory is the head of an immutable directed acyclic graph. It is
actually represented as an immutable linked list with a special node that ties
in extra children nodes. The users of the information are expected to get a
SmallVectorImpl and process those sibling nodes afterwards. The reason why we
use an immutable approach is that it fits well with the problem and saves space
since different partitions could be pointing at the same linked list
node. Operations occur on an isolation history by pushing/popping nodes. It is
assumed that the user will push nodes in batches with a sequence boundary at the
bottom of the addition which signals to stop processing nodes.

Tieing this together, each Partition within it contains an IsolationHistory. As
the PartitionOpEvaluator applies PartitionOps to Partition in
PartitionOpEvaluator::apply, the evaluator also updates the isolation history in
the partition by first pushing a SequenceBoundary node and then pushing nodes
that will undo the operation that it is performing. This information is used by
the method Partition::popHistory. This pops linked list nodes from its history,
performing the operation in reverse until it hits a SequenceBoundary node.

This allows for one to rewind Partition history. And if one stashes an isolation
history as a target, one can even unwind a partition to what its state was at a
specific transfer point or earlier. Once we are at that point, we can begin
going one node back at a time and see when two values that we are searching for
no longer are apart of the same region. That is a place where we want to emit a
diagnostic. We then process until we find for both of our values history points
where they were the immediate reason why the two regions merge.

rdar://123479934
2024-04-06 00:58:05 -07:00
Michael Gottesman
c2350dfe7e [region-isolation] Change SILIsolationInfo to only traffic in ActorIsolation instead of that or nominal type decls.
This should be NFC since the only case where I used this was with self... and I
found another way of doing that using the API I added in the previous commit.
2024-04-04 10:58:57 -07:00
Michael Gottesman
1cf4e99454 Propagate global actor-ness of functions/closures.
I fixed a bunch of small issues around here that resulted in a bunch of radars
being fixed. Specifically:

1. I made it so that we treat function_refs that are from an actor isolated
function as actor isolated instead of sendable.

2. I made it so that autoclosures which return global actor isolated functions
are treated as producing a global actor isolated function.

3. I made it so that we properly handle SILGen code patterns produced by
Sendable GlobalActor isolated things.

rdar://125452372
rdar://121954871
rdar://121955895
rdar://122692698
2024-03-29 14:39:34 -07:00
Michael Gottesman
8243b5cb74 [region-isolation] If a value is dynamically actor isolated, do not consider it transferred if the transfer statically was to that same actor isolation.
This issue can come up when a value is initially statically disconnected, but
after we performed dataflow, we discovered that it was actually actor isolated
at the transfer point, implying that we are not actually transferring.

Example:

```swift
@MainActor func testGlobalAndGlobalIsolatedPartialApplyMatch2() {
  var ns = (NonSendableKlass(), NonSendableKlass())
  // Regions: (ns.0, ns.1), {(mainActorIsolatedGlobal), @MainActor}

  ns.0 = mainActorIsolatedGlobal
  // Regions: {(ns.0, ns.1, mainActorIsolatedGlobal), @MainActor}

  // This is not a transfer since ns is already main actor isolated.
  let _ = { @MainActor in
    print(ns)
  }

  useValue(ns)
}
```

To do this, I also added to SILFunction an actor isolation that SILGen puts on
the SILFunction during pre function visitation. We don't print it or serialize
it for now.

rdar://123474616
2024-03-25 22:58:17 -07:00
Michael Gottesman
b19081daad [region-isolation] Change printing of values before dataflow to dump the full value state of the value instead of just the representative.
Just makes it easier to debug.
2024-03-25 20:17:26 -07:00
Michael Gottesman
357a53ab48 [region-isolation] Clean up use after transfer error to use the dynamic isolation information of the transfered operand value in its diagnostic message.
As an example of the change:

-  // expected-note @-1 {{'x' is transferred from nonisolated caller to main actor-isolated callee. Later uses in caller could race with potential uses in callee}}
+  // expected-note @-1 {{transferring disconnected 'x' to main actor-isolated callee could cause races in between callee main actor-isolated and local nonisolated uses}}

Part of the reason I am doing this is that I am going to be ensuring that we
handle a bunch more cases and I wanted to fix this diagnostic before I added
more incaranations of it to the tests.
2024-03-22 13:12:51 -07:00
Michael Gottesman
6a32284634 [region-isolation] Use SILRegionInfo::get to compute actor isolation of non-isolation crossing apply. 2024-03-21 14:16:20 -07:00
Michael Gottesman
608493c15c [region-isolation] Move computation of SILIsolationInfo for a SILFunctionArgument onto SILIsolationInfo::get(...). 2024-03-21 14:16:20 -07:00
Michael Gottesman
c2dcdb915f [region-isolation] Remove an assert that doesnt add anything.
Just doing a little cleaning.
2024-03-21 14:16:20 -07:00
Michael Gottesman
c09b9f811b [region-isolation] Add a helper for getting an ApplyIsolationCrossing from an instruction.
I am making this specific API since I am going to make it so that
SILIsolationInfo::get(SILInstruction *) can infer isolation info from self even
from functions that are not apply isolation crossing points. For example, in the
following, we need to understand that test is main actor isolated and we
shouldn't emit an error.

```swift
@MainActor func test(_ x: NonSendable) {}

@OtherActor func doSomething() {
  let x = NonSendable()
  Task.init { @MainActor in print(x) }
  test(x)
}
```
2024-03-21 14:16:20 -07:00
Michael Gottesman
5b8171240d [region-isolation] Rename IsolationRegionInfo -> SILIsolationInfo.
That is really what IsolationRegionInfo is.
2024-03-21 14:16:20 -07:00
Michael Gottesman
e00fbfa6b6 [region-isolation] Refactor RegionAnalysis AST pattern matching onto a helper factory method on IsolationRegionInfo.
Long term I would like to get region analysis and transfer non sendable out of
the business of directly interpreting the AST... but if we have to do it now, I
would rather us do it through a helper struct. At least the helper struct can be
modified later to work with additional SIL concurrency support when it is added.
2024-03-21 14:16:20 -07:00
Michael Gottesman
f796f11c97 [region-isolation] Rename ValueIsolationRegionInfo -> IsolationRegionInfo. 2024-03-18 12:24:34 -07:00
Michael Gottesman
afbcf85727 [region-isolation] Change named transfer non transferable error to use the dynamic merged IsolationRegionInfo found during dataflow.
I also eliminated the very basic "why is this task isolated" part of the warning
in favor of the larger, better, region history impl that I am going to land
soon. The diagnostic wasn't that good in the first place and also was fiddly. So
I removed it for now.

rdar://124960994
2024-03-18 12:13:36 -07:00
Michael Gottesman
465bb230c4 [region-isolation] Rename callback handleFailure -> handleLocalUseAfterTransfer.
Now that we have other forms of error callbacks, having such a general name for
any specific failure is misleading and hinds intent.
2024-03-18 12:13:30 -07:00
Michael Gottesman
683e94f30d Merge pull request #72368 from gottesmm/pr-14b84426e480f5b5049c09df01c9445308dd19c5
[region-isolation] Change semantics of function_extract_isolation from AssertingIfNonSendable -> Require.
2024-03-15 20:13:53 -07:00
Michael Gottesman
dd156f36d0 Merge pull request #72366 from gottesmm/pr-12358c24eb38a655a2275f9b947625a9c72ab016
[region-isolation] Fix assert.
2024-03-15 19:02:10 -07:00
Michael Gottesman
e2ddb088cb [region-isolation] Change semantics of function_extract_isolation from AssertingIfNonSendable -> Require.
The reason why I am doing this is that:

1. function_extract_isolation can take as a parameter a non-Sendable function
today in SIL so in such a case, we crash.
2. It returns an Optional<any Actor> which always must be Sendable.

So it makes sense for it to just require that its non-Sendable parameter not be
transferred at that point.
2024-03-15 17:30:29 -07:00
Michael Gottesman
9fe64cd319 [region-isolation] Fix assert.
This assert validates that look through parameters only have a single operand
(the one we are going to lookthrough). It did not take into account though that
some of these lookthrough instructions /do/ have type dependent operands (which
we should ignore for the assert). I changed the assert to ignore those.
2024-03-15 16:18:56 -07:00
Michael Gottesman
c2c4f13392 [region-isolation] Fix crasher.
The specific problem is that instead of just using the parent type of the
ref_element_addr (which is guaranteed to be a class), we used the base of the
storage... the base doesn't have to be the ref_element_addr's operand. The
crasher occured when that base was a class existential that we cast to a super
class whose field we access.
2024-03-15 12:51:29 -07:00
Michael Gottesman
acca7353db [transferring] Make async let take a transferring result if its result is non-Sendable.
Some notes:

1. If the result is non-Sendable and we didn't infer something that is
transferring, we still emit the current sema error that says that one cannot
assign a non-Sendable value to an async let.

2. When region isolation is enabled, but transferring args and results are
disabled, we leave the async let semantics alone. This means that the async let
closure is still @Sendable and one cannot pass in non-Sendable values to it.
2024-03-13 15:30:54 -07:00
Michael Gottesman
4422eb5d56 [region-isolation] When inferring AST arg nums from SIL operand numbers, ignoring indirect operands.
Otherwise, we get off by one errors.

NOTE: I removed the assert that this originally hit since it is possible for us
to perhaps hit other issues and it would be better to just emit a suboptimal
error than crashing. With time, I will probably make it so if we miss we emit a
"compiler couldn't understand error".

rdar://124478890
2024-03-12 14:36:26 -07:00
Michael Gottesman
806cd7940e [region-isolation] Fix actor isolated parameters to get an actor isolated error instead of a task isolated error.
Now that we actually know the region that non transferrable things belong to, we
can use this information to give a better diagnostic here.

A really nice effect of this is that we now emit that actor isolated parameters
are actually actor isolated instead of task isolated.
2024-03-10 22:08:40 -07:00
Michael Gottesman
b2c85a8294 [region-isolation] Rather than tracking task isolated values via a separate non-transferrable array... just track it by using ValueIsolationRegionInfo on a value.
In a subsequent commit, this is going to let me begin handling parameters with
actor regions in a nice way (and standardize all of the errors).

This is meant to be a refactoring commit that uses the current tests in tree to
make sure I did it correctly, so no tests need to be updated.
2024-03-10 22:08:40 -07:00
Michael Gottesman
f2355ea1cf [region-isolation] Eliminate partial_apply code that tries to push actor isolation when we do not have an isolated parameter.
This is unnecessary since I added support for sil_isolated on captures of
partial applies.
2024-03-10 22:08:40 -07:00
Michael Gottesman
93844934f9 [region-isolation] Begin tracking region information instead of just whether a value is actor derived.
To keep this as an NFC commit, I only modeled initially actor isolated using
this. I am going to make it so that we properly treat global actor isolated
values as actor isolated/etc in a subsequent commit.
2024-03-10 22:08:40 -07:00
Michael Gottesman
d8b2631f5f [region-isolation] Make fields of global actor guarded types that are non-Sendable be considered as actor isolated.
rdar://123488540
2024-03-08 12:42:15 -08:00
Michael Gottesman
f06244f397 [region-isolation] Take into account that Swift's RPO order doesn't include blocks that are dead.
When we run RegionAnalysis, since it uses RPO order, we do not visit dead
blocks. This can create a problem when we emit diagnostics since we may merge in
a value into the region that was never actually defined. In this patch, if we
actually visit the block while performing dataflow, I mark a bit in its state
saying that it was live. Then when we emit diagnostics, I do not visit blocks
that were not marked live.

rdar://124042351
2024-03-04 17:09:51 -08:00
Michael Gottesman
2f353b815e [region-isolation] Only make partial_apply actor derived if we capture an isolated parameter... not just any actor.
Before I couldn't do this since, @sil_isolated was not represented on
partial_applies. Since in the previous commit, I added support to the compiler
to represent this, I can now limit this query so now one can pass an actor
instance outside of its method to a nonisolated non-Sendable partial apply.
Since it is Sendable, it is always safe to do this since we are passing the
actor.

rdar://123881277
2024-03-01 11:54:16 -08:00
Michael Gottesman
6eb31b42b1 [region-isolation] Assigning into a transferring parameter should be a store, not a transfer.
rdar://123865943
2024-02-29 16:20:00 -08:00
Michael Gottesman
1776ce4820 [region-isolation] Make sure that we can handle an async let without any captures correctly.
Previously, we assumed we would always have a partial_apply. In the case where
we do not capture any values this is not true since we instead have a
thin_to_thick_function.
2024-02-27 14:10:15 -08:00
Michael Gottesman
3b9d4523cc [transferring] Make sure to enable strict-concurrency on the tests as well as our experimental features.
Just noticed this while trying to write some tests that validated that we were
properly ignoring strict-concurrency features. I put in asserts to validate that
when either of these are enabled, we have strict-concurrency set as well.
2024-02-27 13:35:22 -08:00
Ben Barham
f292ec9784 Use the new template deduction guides rather than makeArrayRef
LLVM has removed `make*ArrayRef`, migrate all references to their
constructor equivalent.
2024-02-23 20:04:51 -08:00
Nate Chandler
6b0fc181d5 [NFC] Removed imports of MemoryLocations.h.
Make it clear that this is only used by the MemoryVerifier (and the
disabled old DestroyHoisting).
2024-02-19 11:41:38 -08:00
Nate Chandler
600164257a [NFC] Moved SmallBitVector dumping to Basic.
Moved out of MemoryLocations.h and merged the implementations of <<,
keeping the version from MemoryLocations with its brackets and commas
available via a flag but defaulting the implementation previously in the
header.
2024-02-19 11:41:38 -08:00
Michael Gottesman
40cd98794d [region-isolation] Always require before transferring.
We purposely do not treat a PartitionOpKind::Transfer as a require since that
would cause us to error when we weakly transfer the same parameter multiple
times to the same function. This is safe since all of the function parameters
will be in the same region.

To ensure that this fixed the multiple strong transferring issue (which is
exposed by requiring before transferring), I also had to muck around a little
with how we emit errors to ensure that we emit errors if the transfer
instruction is also the require.
2024-02-14 14:39:02 -08:00
Michael Gottesman
f3edb5730a [transferring] Add support for transferring results.
rdar://121324697
2024-02-14 14:39:02 -08:00
Michael Gottesman
bf2ec7eb85 [transferring] Change transferring to no longer be a ParamSpecifier.
Instead it is a bit on ParamDecl and SILParameterInfo. I preserve the consuming
behavior by making it so that the type checker changes the ParamSpecifier to
ImplicitlyCopyableConsuming if we have a default param specifier and
transferring is set. NOTE: The user can never write ImplicitlyCopyableConsuming.

NOTE: I had to expand the amount of flags that can be stored in ParamDecl so I
stole bits from TypeRepr and added some logic for packing option bits into
TyRepr and DefaultValue.

rdar://121324715
2024-02-14 13:04:46 -08:00
John McCall
d5142668f4 SIL and IRGen support for @isolated(any). SILGen to come. 2024-02-13 03:04:13 -05:00
Michael Gottesman
1795f7f661 Merge pull request #71429 from gottesmm/fixes-for-stdlib
[region-isolation] Fixes that enable the stdlib to build with region based isolation
2024-02-07 09:47:11 -08:00
Michael Gottesman
1e4fe6c4ea [region-isolation] Do not transfer @out parameters!
Instead treat them as actual results.
2024-02-06 18:14:34 -08:00
Michael Gottesman
501158450e [region-isolation] Handle (project_box (load %boxAddr)) correctly.
I thought that we would never actually hit this test case, but since we do not
have opaque values this pattern is treated like a projection in certain cases. I
updated the code as appropriate and added a test.
2024-02-06 18:05:05 -08:00
Michael Gottesman
6200a3bc4c [region-isolation] Fix a thinko.
project_box's type is not a box type... it is the type contained in the box.
2024-02-06 17:49:58 -08:00
Michael Gottesman
b2f1c41213 [region-isolation] get_async_continuation{,_addr} can take a parameter, so we need to treat it as a require.
We should make this as a transfer... but this is just temporary until I get
around to it. For now this is always an out parameter, so we should be safe.
2024-02-06 17:49:03 -08:00
Michael Gottesman
e34dc59cea [region-isolation] When asserting about a bad inst, print the inst out to ease debugging. 2024-02-06 16:57:47 -08:00
Michael Gottesman
dd7f5ec11d [region-isolation] Handle ref_to_bridge_object especially.
I was correct that it is lookthrough, but it has multiple parameters, so the
normal "baked" implementation cannot be used since the "baked" implementation
assumes that any insts it handles has a single operand.
2024-02-06 16:57:34 -08:00
Nate Chandler
b535725647 [NFC] SIL: Renamed SpecifyTestInst.
The instruction's spelling was changed to `specify_test` but the class
name wasn't updated from `TestSpecificationInst`.  Update it here.
2024-02-06 16:29:09 -08:00