Commit Graph

2768 Commits

Author SHA1 Message Date
Michael Gottesman
2e5b3bc257 [region-isolation] Do not treat functions/class_methods that are isolated to a #isolated as being globally isolated to that.
Instead, we need to consider the isolation at the apply site.

rdar://126285681
rdar://125078448
2024-04-11 16:00:55 -07:00
Michael Gottesman
a9c163f8e2 [region-isolation] Emit the correct error for closures that capture actor self.
rdar://122501400
2024-04-11 15:41:18 -07:00
Michael Gottesman
51ef67d7df [variable-name-utils] Refactor inferName/inferNameAndRoot helpers onto VariableNameInferrer.
I have been using these in TransferNonSendable and they are useful in terms of
reducing the amount of code that one has to type to use this API. I am going to
need to use it in SILIsolationInfo, so it makes sense to move it into
SILOptimizer/Utils.

NFCI.
2024-04-11 15:41:18 -07:00
Michael Gottesman
d8f39f70d9 [region-isolation] Begin tracking in SILIsolationInfo the actorInstance that a value is isolated to if we are dealing with an actor instance.
This will let us distinguish in between values derived from two actor instances
of the same type and to emit better errors.
2024-04-11 15:41:18 -07:00
Michael Gottesman
b407b21e9a [region-isolation] Finish moving isolation computation into SILIsolationInfo::get. 2024-04-11 15:41:18 -07:00
Michael Gottesman
2a7714abd4 [region-isolation] Move computation of SILIsolationInfo for FunctionRefInst/ClassMethodInst into SILIsolationInfo::get instead of handrolling in RegionAnalysis. 2024-04-11 15:41:18 -07:00
Michael Gottesman
513ab78602 [region-isolation] Move SILIsolationInfo determining code for ref_element_addr and global_addr onto SILIsolationInfo and call that instead. 2024-04-11 15:41:18 -07:00
Michael Gottesman
20c24293e5 [region-isolation] Do not look through begin_borrow or move_value if they are marked as a var_decl.
The reason why we do this is that we want to treat this as a separate value from
their operand since they are the result of defining a new value.

This has a few nice side-effects, one of which is that if a let results in just
a begin_borrow [var_decl], we emit names for it.

I also did a little work around helping variable name utils to lookup names from
applies that are fed into a {move_value,begin_borrow} [var_decl] which then has
the debug_value we are searching for.
2024-04-11 15:41:18 -07:00
Michael Gottesman
b80faee2a7 [region-isolation] Rename Partition::{fresh_label,freshLabel}. 2024-04-11 15:41:18 -07:00
Michael Gottesman
df4fb64ea1 Merge pull request #72955 from gottesmm/rdar126170014
[region-isolation] Include the region -> transferring operand map in the dataflow convergence.
2024-04-10 17:20:55 -07:00
Michael Gottesman
ca8179aa7c [region-isolation] Track operand info in a separate map rather than inline in a TransferringOperand data structure.
This is backing out an approach that I thought would be superior, but ended up
causing problems.

Originally, we mapped a region number to an immutable pointer set containing
Operand * where the region was tranferred. This worked great for a time... until
I began to need to propagate other information from the transferring code in the
analysis to the actual diagnostic emitter.

To be able to do that, my thought was to make a wrapper type around Operand
called TransferringOperand that contained the operand and the other information
I needed. This seemed to provide me what I wanted but I later found that since
the immutable pointer set was tracking TransferringOperands which were always
newly wrapped with an Operand *, we actually always created new pointer
sets. This is of course wasteful from a memory perspective, but also prevents me
from tracking transferring operand sets during the dataflow since we would never
converge.

In this commit, I fix that issue by again tracking just an Operand * in the
TransferringOperandSet and instead map each operand to a state structure which
we merge dataflow state into whenever we visit it. This provides us with
everything we need to in the next commit to including a region -> transferring
operand set equality check in our dataflow equations and always converge.
2024-04-10 10:30:10 -07:00
Erik Eckstein
e14c1d1f62 SIL, Optimizer: update and handle borrowed-from instructions
Compute, update and handle borrowed-from instruction in various utilities and passes.
Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`.
Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
2024-04-10 13:38:10 +02:00
Erik Eckstein
ac4bc89c9a SIL: add the borrowed-from instruction.
It declares from which enclosing values a guaranteed phi argument is borrowed from.
2024-04-10 13:38:10 +02:00
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
518f8f7c76 [region-isolation] Fix asan error.
rdar://126060540
2024-04-08 12:33:31 -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
Emil Pedersen
512ac6cc31 Merge pull request #72860 from Snowy1803/salvage-debug-info-tuple
[DebugInfo] Salvage debug info for tuples
2024-04-05 20:16:24 -07:00
Emil Pedersen
1e7dc51cd6 [DebugInfo] Add salvageDebugInfo support for tuples 2024-04-05 15:34:36 -07:00
Emil Pedersen
efa09088ac Revert "[DebugInfo][SIL] Introduce the 'implicit' attribute for debug variable"
This reverts commit e63632fda8.

rdar://125939953
2024-04-04 17:23:32 -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
Andrew Trick
581010d00c SIL: Make drop_deinit a ForwardingInstruction.
drop_deinit forwards ownership while effectively stripping the deinitializer. It is similar to a type cast.

Fixes rdar://125590074 ([NonescapableTypes] Nonescapable types
cannot have deinits)
2024-04-03 18:53:18 -07:00
Doug Gregor
e5d7885fc8 Merge pull request #72788 from DougGregor/metadata-runtime-inverse-conformances-assoctype
Runtime checking for associated types conforming to invertible protocols
2024-04-03 08:30:50 -07:00
Doug Gregor
ae01d20428 Runtime checking for associated types conforming to invertible protocols
Emit metadata for runtime checks of conformances of associated types to
invertible protocols, e.g., `T.Assoc: Copyable`. This allows us to
correctly handle, e.g., dynamic casting involving conditional
conformances that have such constraints.

The model we use here is to emit an invertible-protocol constraint
that leaves only the specific bit clear in the invertible protocol
set.
2024-04-02 16:42:16 -07:00
Ben Barham
1fdda023b3 Rename StringRef::endswith references to StringRef::ends_with
Missed this when doing the `startswith` renaming. `endswith` has also
been deprecated upstream (and presumably soon to be removed).
2024-04-01 10:59:16 -07:00
Michael Gottesman
ce27305279 [sil] Teach variable name utils how to handle init_existential_addr temporaries.
Just eliminating more cases of the typed errors in favor of named errors.
2024-03-29 18:48:04 -07:00
Michael Gottesman
77dccacbd3 Make ActorIsolation on SILFunction non-optional.
ActorIsolation already has a "I have no value case": unspecified. Lets just use
that.

Just a mistake I made that I am trying to fix before anything further depends on
this code.
2024-03-29 14:39:26 -07:00
Anton Korobeynikov
d84847ac9d Reland Allow normal function results of @yield_once coroutines (#71645)
* Allow normal function results of @yield_once coroutines

* Address review comments

* Workaround LLVM coroutine codegen problem: it assumes that unwind path never returns.
This is not true to Swift coroutines as unwind path should end with error result.
2024-03-27 13:09:02 -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
0b13da8fa6 Merge pull request #72572 from gottesmm/pr-26c22d031b70b00c14d7990ff90f70b64f91e0f9
[region-isolation] Shrink PartitionUtils.h by moving large functions to cpp file.
2024-03-25 17:14:50 -07:00
Michael Gottesman
901c7c2b6c [region-isolation] Shrink PartitionUtils.h by moving large functions to cpp file.
Just making PartitionUtils.h a little easier to walk through by moving more of
the impl into the .cpp file. This reduces the header from ~1500 lines to ~950
lines which is more managable. This is especially important since I am going
to be adding IsolationHistory to the header file which will expand it even
further.
2024-03-25 14:15:10 -07:00
Kuba (Brecka) Mracek
89cd62604b Merge pull request #72472 from kubamracek/embedded-keypaths
[embedded] Compile-time (literal) KeyPaths for Embedded Swift
2024-03-25 10:58:51 -07:00
Andrew Trick
d7b9149ee5 Fix visitNonEscapingLifetimeEnds to handle mark_dependence uses
Now it visits unknown uses separately rather than asserting.
2024-03-22 14:29:57 -07:00
Meghana Gupta
50b358c64f Merge pull request #72359 from meg-gupta/skiphismdi
Fix utilities that may see phis of mark_dependence [nonescaping]
2024-03-21 18:28:08 -07:00
Kuba Mracek
3aab1b083b [embedded] Use load_borrow/end_borrow in KeyPathProjector when in OSSA 2024-03-21 18:04:50 -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
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
Meghana Gupta
1cccd796ad Merge pull request #72479 from meg-gupta/fixsilcombineagain
Fix SILCombine of inject_enum_addr to correctly check for unreferenceable storage
2024-03-21 10:14:14 -07:00
Meghana Gupta
3d8f714ed4 Add a new api findUnreferenceableStorage to check if struct or its fields have unreferenceable storage 2024-03-20 20:06:43 -07:00
Meghana Gupta
3ebef80261 Fix utilities that may see phis of mark_dependence [nonescaping] 2024-03-20 15:44:11 -07:00
Kuba Mracek
b642d771be [embedded] Compile-time (literal) KeyPaths for Embedded Swift
Enable KeyPath/AnyKeyPath/PartialKeyPath/WritableKeyPath in Embedded Swift, but
for compile-time use only:

- Add keypath optimizations into the mandatory optimizations pipeline
- Allow keypath optimizations to look through begin_borrow, to make them work
  even in OSSA.
- If a use of a KeyPath doesn't optimize away, diagnose in PerformanceDiagnostics
- Make UnsafePointer.pointer(to:) transparent to allow the keypath optimization
  to happen in the callers of UnsafePointer.pointer(to:).
2024-03-20 15:35:46 -07:00
Michael Gottesman
f02565719e Merge pull request #72435 from gottesmm/pr-89ce065b7f50a41a58d8fb358d0145913d8b53a3
[region-isolation] Convert more diagnostics from type isolation form to named variable form
2024-03-19 16:32:36 -07:00
Michael Gottesman
29e3069a50 [region-isolation] Teach variable name utils how to handle more tuple patterns.
Just slicing off from a larger patch.
2024-03-19 13:19:09 -07:00
Michael Gottesman
8b899b8f71 [region-isolation] Teach variable_name_inference how to infer through store_borrow initialized variables.
This eliminates a bunch of cases where we couldn't infer the name of a variable
and used the type based diagnostic.

It also eliminates an 'unknown' case for move checking.
2024-03-19 13:19:09 -07:00
Andrew Trick
2e82db8e1b ClosureLifetimeFixup; emit mark_dependence [nonescaping].
It is safe to do so because the on_stack transformation already checks that the closure has a single known apply use.
2024-03-18 17:45:33 -07:00
Ben Barham
cbcfc85777 Merge pull request #72323 from bnbarham/rename-startswith
Rename startswith to starts_with
2024-03-14 09:06:54 -07:00
Ben Barham
9779c18da3 Rename startswith to starts_with
LLVM is presumably moving towards `std::string_view` -
`StringRef::startswith` is deprecated on tip. `SmallString::startswith`
was just renamed there (maybe with some small deprecation inbetween, but
if so, we've missed it).

The `SmallString::startswith` references were moved to
`.str().starts_with()`, rather than adding the `starts_with` on
`stable/20230725` as we only had a few of them. Open to switching that
over if anyone feels strongly though.
2024-03-13 22:25:47 -07:00