Commit Graph

951 Commits

Author SHA1 Message Date
Michael Gottesman
7680332b93 Merge pull request #69906 from gottesmm/use-tracked-transfer-inst
[region-isolation] Since we now propagate the transferred instruction, use that to emit the error instead of attempting to infer the transfer instruction for a requires
2023-11-16 10:06:03 -08:00
Michael Gottesman
95669c5e9c [region-isolation] Instead of passing around an expression to get the original type, just derive the type from the transfer operand when we emit the error. 2023-11-15 18:58:06 -08:00
Michael Gottesman
957a79f82a [region-isolation] Track operands instead of SILInstructions for Transfer instructions.
This is another NFC refactor in preparation for changing how we emit
errors. Specifically, we need access to not only the instruction, but also the
specific operand that the transfer occurs at. This ensures that we can look up
the specific type information later when we emit an error rather than tracking
this information throughout the entire pass.
2023-11-15 18:58:06 -08:00
Nate Chandler
ae6868a296 [DCE] Process instructions added during deletion.
In cea0f00598, `InstructionDeleter` began
deleting `load [take]` instructions.  Analogous to how it creates a
`destroy_value` when deleting an instruction which consumes a value, in
the case of deleting a `load [take]` the `InstructionDeleter` inserts a
compensating `destroy_addr`.

Previously, `DeadCodeElimination` did not observe the creation of any
instructions created by the `InstructionDeleter`.  In the case of the
newly created `destroy_addr`, DCE didn't mark that the `destroy_addr`
was live and so deleted it.  The result was a leak.

Here, this is fixed by passing an `InstModCallbacks`--with an
`onCreateNewInst` implementation--down into `erasePhiArgument` that
eventually invokes the `InstructionDeleter`.  When the
`InstructionDeleter` creates a new instruction, DCE marks it live.
2023-11-15 15:03:24 -08:00
Michael Gottesman
c5259ad172 [region-isolation] Remove getExprForPartitionOp and instead just use SILLocation.
getExprForPartitionOp(...) just returned the expression from the loc of op.currentInst:

  SILInstruction *sourceInstr = op.getSourceInst(/*assertNonNull=*/true);
  Expr *expr = sourceInstr->getLoc().getAsASTNode<Expr>();

Instead of mucking around with exprs, just use the SILLocation from the
SILInstruction.

I also changed how we unique transfer instructions to just use the transfer
instruction itself instead of the AST/Expr of the transfer instruction.
2023-11-10 12:48:45 -08:00
Michael Gottesman
cf780b23a1 [region-isolation] Remove two sources of copying PartitionOps.
Was experimenting with making PartitionOps a noncopyable type and I discovered
these places where we copy PartitionOps when we could use a const reference. It
is good not to copy PartitionOps since they potentially contain a heap allocated
array.

Sadly, my change to make PartitionOps noncopyable will have to wait until a
forthcoming commit here I overhaul how we emit errors since that older code
copies PartitionOps a lot and I would rather just delete that code and then fix
PartitionOps. But these are on the surface safe changes that makes sense to get
in separately to make that next patch easier to review.
2023-11-10 12:48:45 -08:00
Michael Gottesman
c336f3a47e [region-isolation] Track transferring separately from region information.
What this does is really split the one dataflow we are performing into two
dataflows we perform at the same time. The first dataflow is the region dataflow
that we already have with transferring never occurring. The second dataflow is a
simple gen/kill dataflow where we gen on a transfer instruction and kill on
AssignFresh. What it tracks are regions where a specific element is transferred
and propagates the region until the element is given a new value. This of course
means that once the dataflow has converged, we have to emit an error not if the
value was transferred, but if any value in its region was transferred.
2023-11-10 12:48:45 -08:00
Kuba Mracek
afced311f9 [embedded] Fix class_method devirtualizer to consider specialized VTables 2023-11-06 17:08:12 -08:00
Erik Eckstein
d6e86a8cd4 Fix specialization of class method calls in embedded swift.
Unlike in regular swift, The class_method instruction references the specialized version of a class method.
This must be handled in ReabstractionInfo: it needs to work without a concrete callee SIL function.

Also, the SILVerifier must handle the case that a class_method instruction references a specialized method.
2023-11-06 21:08:22 +01:00
Doug Gregor
53c8e84a1f [Typed throws] Handle throw_addr in the same places as throw. 2023-11-03 19:02:58 -07:00
Michael Gottesman
edb5d6a1db Merge pull request #69619 from gottesmm/rdar117273952
[region-isolation] Fix semantics around assigning into projections
2023-11-03 12:31:02 -07:00
Michael Gottesman
dbc3deb382 [region-isolation] Improve logging.
Specifically:

1. I changed Partition::apply so that it has an emitLog flag. The reason why I
did this is we run apply in a few different situations sometimes when we want to
emit logging other times when we really don't. For instance, we want to emit
logging when walking instructions and updating the entry partition. On the other
hand, we do not want to emit logging if we apply a value to a partition while
attempting to determine why an error needed to be emitted.

2. When we create an assign partition op and we see that our destination and
source are the same representative, we do not create the actual assign. Before
we did not log this so it looked like there was a logic error that was stopping
us from emitting a partition op when visiting said instructions. Now, we emit a
small logging message so it isn't possible to be confused.

3. Since I am adding another parameter to Partition::apply, I decided to
refactor Partition::apply to be in a separate PartitionOpEvaluator data
structure that contains the options that we used to pass into Partition::apply.
This prevents any mistakes around configuring Partition::apply since the fields
provide nice names/common sense default values.
2023-11-01 21:35:32 -07:00
Slava Pestov
05ccd9734c SIL: Introduce ThrowAddrInst 2023-10-31 16:58:54 -04:00
eeckstein
8a1eefae07 Merge pull request #69212 from jkshtj/main
[AutoDiff] Modify inlining logic to award inlining benefits to VJPs
2023-10-30 07:51:09 +01:00
Kshitij
12e3a6ecfb [AutoDiff] Modify inlining logic to award inlining benefits to VJPs
Similar to #69029 but for VJPs.
2023-10-27 06:43:59 -10:00
Michael Gottesman
382609e3ac [region-isolation] More consuming -> transferring. 2023-10-26 12:29:23 -07:00
Michael Gottesman
c9e750ba18 [region-isolation] Clean up/standardize comments. 2023-10-26 12:25:21 -07:00
Michael Gottesman
6718dbf17e [region-isolation] Change how we compute max in separateRegions as we loop rather than using a functional 2nd loop before the main loop. 2023-10-26 12:01:44 -07:00
Michael Gottesman
a46025d040 [region-isolation] Remove Partition::getRegion().
This was a piece of code that I added early while adding better unittesting for
Partition. Instead in that patch I added a forward declared class in Partition
called PartitionTester that could implement getRegion. I just forgot to remove
this.
2023-10-26 12:01:44 -07:00
Michael Gottesman
0bad8f9b67 [region-isolation] Rename SendNonSendable.cpp -> TransferNonSendable.cpp. 2023-10-26 12:01:44 -07:00
Michael Gottesman
4c7e13d3cb [region-isolation] Fix join to be a true union operation including the symmetric difference.
We were performing a union on the intersection of the lhs/rhs but were dropping
the parts of lhs/rhs that were in the symmetric difference of the two sets.

Without this, we would not diagnose cases like this where we had elements on the
lhs/rhs that were not in the intersection.

```
var closure: () -> () = {}

await transferToMain(closure)

if await booleanFlag {
   closure = {
     print(self.klass)
   }
} else {
   closure = {}
}
// At this point we would lose closure since they were different elements

await transferToMain(closure) // We wouldn't error on this!
```

rdar://117437059
2023-10-25 17:05:11 -07:00
Michael Gottesman
cfd00e842f [region-isolation] Fix header in PartitionUtils.h
NFC.
2023-10-25 13:17:20 -07:00
Michael Gottesman
c10c4fc10f Merge pull request #69387 from gottesmm/more-region-stuff
[region-isolation] Fix actor region propagation and some other smaller issues.
2023-10-25 11:46:19 -07:00
Michael Gottesman
30933db69f [region-isolation] When printing PartitionOps, print the instruction that they are derived from.
Otherwise, it is hard to tell what one is looking at when looking at the
pseudo-ir.
2023-10-24 16:36:02 -07:00
Michael Gottesman
9dfc9b6a2d [region-isolation] Track if a non-Sendable value was derived from an actor and treat its region as being within an actor's isolation domain.
Importantly, we determine at the error stage if a specific value that is
transferred is within the same region of a value that is Actor derived. This
means that we can in a flow insensitive manner determine the values that are
actor derived and then via propagating those values into various regions
determine the issue... using our region analysis to handle the flow sensitivity.

One important case to reason about here is that since we are relying on the
region propagation for flow sensitivity is that this solves the var case for
us. A var when declared is never marked as actor derived. Var uses only become
actor derived if the var was merged into a region that contain is actor
derived. That means that re-assigning to a non-actor derived value, eliminates
the actor derived bit.

As part of this, I also discovered I could just get rid of the captured uniquely
identified array in favor of just passing in an actor derived flag.

rdar://115656589
2023-10-24 16:35:00 -07:00
Michael Gottesman
d069169c0d Fix some typos. 2023-10-24 12:47:11 -07:00
Michael Gottesman
2c0efe6b8b [region-isolation] Go through the implementation again changing Consume -> Transfer.
I just missed these.
2023-10-23 13:52:14 -07:00
Michael Gottesman
578eafdb46 [region-isolation] Eliminate a temporary std::vector.
We can just pass in an ArrayRef here. I missed this inefficiency when I was
going through the pass earlier.
2023-10-23 12:24:17 -07:00
Michael Gottesman
fb7b4a3a32 [region-isolation] Add verbose logging to PartitionUtils behind a flag.
One needs to pass in the explicit flag to enable this as well as
-debug-flag=send-non-sendable. This makes it easier to debug the affect of
applying specific partition ops.
2023-10-23 12:24:17 -07:00
swift-ci
46c67c20cf Merge remote-tracking branch 'origin/main' into rebranch 2023-10-10 02:35:18 -07:00
Hamish Knight
ccd32eb452 NFC: Remove ClangModuleLoader.h include from ExtInfo.h
This was unnecessarily pulling in a whole bunch
of Clang headers when all was needed was a
forward declaration.
2023-10-09 20:29:03 +01:00
swift-ci
b684ade6c2 Merge remote-tracking branch 'origin/main' into rebranch 2023-10-05 13:54:30 -07:00
Nate Chandler
ad33b5de34 [OSSALifetimeCompletion] Handle available boundary
Not every block in a region which begins with the non-lifetime-ending
boundary of a value and ending with unreachable-terminated blocks has
the value available.  If the unreachable-terminated blocks in this
boundary are not available, it is incorrect to insert destroys of the
value in them: it is an overconsume on some paths.  Previously,
however, destroys were simply being inserted at the unreachable.

Here, this is fixed by finding the boundary of availability within that
region and inserting destroys before the terminators of the blocks on
that boundary.

rdar://116255254
2023-10-05 09:15:58 -07:00
Nate Chandler
2824bf3125 [CanOSSALifetime] Record "unreachable" insts.
OSSALifetimeCompletion needs to insert not at unreachable instructions
that appear after the non-lifetime-ending boundary of a value but rather
at the terminators of the availability boundary of the value within that
region.  Once it does so, it will no longer be sufficient to check
whether the insertion point is an unreachable because such terminators
may be another terminator that appears on the availability boundary.
Prepare for that by recording the instructions that were found and
checking whether the destroy insertion point is such an instruction
before bailing rather than specifically checking for `unreachable`.
2023-10-04 16:48:06 -07:00
swift-ci
6c89a2244b Merge remote-tracking branch 'origin/main' into rebranch 2023-09-28 08:58:02 -07:00
Michael Gottesman
8d46cc8c08 [isolation-regions] Rename Consume to Transfer.
Transfer is the terminology that we are using for something be transferred
across an isolation boundary, not consume. This also eliminates confusion with
consume which is a term being used around ownership.
2023-09-22 16:21:46 -05:00
swift-ci
764fecbc01 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-21 20:34:25 -07:00
nate-chandler
397a25c377 Merge pull request #68608 from nate-chandler/rdar115468707
[CanonicalizeOSSALifetime] Extend lexical lifetimes to unreachables.
2023-09-21 20:25:46 -07:00
swift-ci
c55b21f2b5 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-21 16:10:25 -07:00
Nate Chandler
6c6776234a [CanOSSALife] Lexical lifetimes go to unreachables
When canonicalizing the lifetime of a lexical value, deinit barriers are
respected. This is done by walking backwards from lifetime ends and
adding encountered deinit barriers to liveness.

Only destroy lifetime ends were walked back from under the assumption
that lifetimes would be complete. Without complete OSSA lifetimes,
however, it's necessary to also necessary to consider lifetimes that end
with unreachables. Unfortunately, we can't simply walk back from those
unreachables because there may be instructions which are secretly users
of the value being canonicalized (e.g. destroys of `partial_apply`s to
which a `begin_borrow` of the value was passed). Such uses don't appear
in the use list because lifetime canonicalization expects complete
lifetimes and only visits lifetime ends of `begin_borrow`s.

Here, instead, the instructions before the relevant unreachables are
added to liveness. In order to determine which unreachables are
relevant, it's necessary to have a liveness that includes the original
destroys. So a copy of liveness is created and those destroys are added
to it.

rdar://115468707
2023-09-21 14:02:43 -07:00
Kavon Farvardin
d0a9e78da0 [Mangling] Support function specializations that remove async 2023-09-21 12:20:24 -07:00
swift-ci
e59baf89ed Merge remote-tracking branch 'origin/main' into rebranch 2023-09-20 17:56:36 -07:00
Nate Chandler
9006be10e3 [CanOSSALifetime] Respect lexical lifetimes flag.
Don't respect deinit barriers when canonicalizing if lexical lifetimes
are disabled.
2023-09-20 13:40:08 -07:00
Kuba Mracek
89df0426e0 [embedded] Specialize vtables when processing instructions, not bulk 2023-09-20 09:41:09 -07:00
Kuba Mracek
03f927eca1 [embedded] Perform VTable specialization iteratively as part of MandatoryPerformanceOptimizations 2023-09-20 09:41:09 -07:00
swift-ci
ae30cba296 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-13 10:20:48 -07:00
Kuba (Brecka) Mracek
b503f2831b Merge pull request #68461 from kubamracek/embedded-classes-generic
[embedded] Initial support for generic classes in embedded Swift
2023-09-13 10:01:50 -07:00
swift-ci
aeb4460bff Merge remote-tracking branch 'origin/main' into rebranch 2023-09-12 19:34:23 -07:00
Michael Gottesman
82fbde0e04 [send-non-sendable] Ensure that we properly warn if a field of a final actor is transferred.
Previously, we were not recognizing that a ref_element_addr from an actor object
is equivalent to the actor object and we shouldn't allow for it to be consumed.

rdar://115132118
2023-09-12 12:46:37 -05:00
Michael Gottesman
3a377a3e51 [send-non-sendable] When logging the pseudo-ir dump out the root representative value associated with pseudo-ir ids.
Really, we should just be using representative values here in general since it
serves the same purpose and makes it easier to trace back values. But this in
the short term makes the output easier to reason about.
2023-09-12 12:11:44 -05:00