Commit Graph

9409 Commits

Author SHA1 Message Date
nate-chandler
126022f6e9 Merge pull request #70054 from nate-chandler/rdar118059326
[SIL] Key consume checking off var_decl attr.
2023-11-28 11:47:04 -08:00
Michael Gottesman
18f91c0acd [region-isolation] Add support for async let.
Specifically:

1. If the value is transferred such that it becomes part of an actor region, the
value is permanently part of the actor region as one would normally have.

2. If the value is just used in an async let or is used by a nonisolated async
function within the async let then while the async let is alive it cannot be
used. But once the async let has been awaited upon, we allow for it to be used
again.

rdar://117506395
2023-11-28 09:39:04 -08:00
Nate Chandler
9861422eeb [SIL] Key consume checking off var_decl attr.
Previously, the lexical attribute on begin_borrow instructions was used.
This doesn't work for values without lexical lifetimes which are
consumed, e.g. stdlib CoW types.  Here, the new var_decl attribute on
begin_borrow is keyed off of instead.  This flag encodes exactly that a
value corresponds to a source-level VarDecl, which is the condition
under which checking needs to run.

rdar://118059326
2023-11-28 07:26:09 -08:00
Nate Chandler
9bb0187be1 [SILGen] Add begin_borrow [var_decl] lifetimes. 2023-11-28 07:26:09 -08:00
Kshitij
cc3c51ecb9 [sil-optimizer] Don't constant fold eq comparisons b/w inf and non-inf
This commit modifes the constant folder to not handle equality comparisons b/w
infinity and non-infinity operands. In such comparisons, special floating point
types - Float80 and Float16, may come into play and pattern matching againt them
complicates the constant folding logic more than we'd like.
2023-11-27 11:32:28 -08:00
Kshitij
97a5a83ae6 [sil-optimizer] Add FP comparison support in constant folder 2023-11-27 11:32:28 -08:00
eeckstein
67ebbee39e Merge pull request #69955 from eeckstein/deinit-devirtualizer
Optimizer: de-virtualize deinits of non-copyable types
2023-11-27 12:41:49 +01:00
eeckstein
587a52701b Merge pull request #70000 from eeckstein/specialize-typed-throws
GenericSpecializer: support specializing typed throws
2023-11-27 12:39:24 +01:00
Erik Eckstein
17f246e219 Remove the old MoveOnlyDeinitDevirtualization.cpp pass 2023-11-27 09:21:34 +01:00
Erik Eckstein
96e57d62f6 Optimizer: de-virtualize deinits of non-copyable types
In regular swift this is a nice optimization. In embedded swift it's a requirement, because the compiler needs to be able to specialize generic deinits of non-copyable types.
The new de-virtualization utilities are called from two places:

* from the new DeinitDevirtualizer pass. It replaces the old MoveOnlyDeinitDevirtualization, which is very basic and does not fulfill the needs for embedded swift.

* from MandatoryPerformanceOptimizations for embedded swift
2023-11-27 09:21:34 +01:00
Erik Eckstein
8458481f0e GenericSpecializer: support specializing typed throws
This means to support specializing functions with indirect error results.
Also, when specializing (and the concrete error type is loadable), convert the indirect error to a direct error.

rdar://118532113
2023-11-27 08:51:13 +01:00
Erik Eckstein
d4c1638f7f GenericCloner: remove FunctionExits
It's not used
2023-11-27 08:51:12 +01:00
Erik Eckstein
3ba935605e SimplifyCFG: fix try_apply -> apply transformation for indirect error results
Indirect error results must not be included in the final apply arguments which they are not present in the callee.
2023-11-27 08:51:12 +01:00
Michael Gottesman
1166e229c8 [region-isolation] Clean up diagnostics to use helper functions.
Just makes things a little cleaner than invoking the methods on ASTContext
directly.
2023-11-26 17:13:04 -08:00
Erik Eckstein
0d596fd8c7 ABCOpts: fix a miscompile in case a value is added to the array index
For example: `array[i + x]`. In this case the addition of `x` was misinterpreted as pre-increment of the induction variable

rdar://118026862
2023-11-20 11:20:55 +01:00
Michael Gottesman
7653552b2d [region-isolation] Loosen handling around fields that are safe to access concurrently.
Specifically:

1. Classes. We allow for access to Sendable let fields.
2. Structs. We allow for access to Sendable let/var fields.
3. Tuples. We allow for access to Sendable let/var fields.

I am going to finish enums in a subsequent PR since I found that I need to mark
a bunch more instructions as look through to get that to work (e.x.:
load/load_borrow need to be viewed as a cast from address -> object so that we
can emit errors on the uses of the load instead of the load itself). These are
more invasive so I want to do it a little later.

rdar://115124361
2023-11-16 15:10:39 -08:00
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
eeckstein
16b0f2c6a3 Merge pull request #69886 from eeckstein/fix-predictable-memopt
PredictableMemOpt: fix wrong handling of re-borrows of a load_borrow
2023-11-16 07:36:10 +01:00
Meghana Gupta
6ccbd8bb8e Merge pull request #69898 from nate-chandler/bug/20231115/1/dce_instdeleter_loadtake
[DCE] Process instructions added during deletion.
2023-11-15 21:54:31 -08:00
Michael Gottesman
46c4da307e Delete new dead code 2023-11-15 18:58:06 -08:00
Michael Gottesman
c0b3efedbf [region-isolation] Instead of using the complex logic to emit all possible requires... just emit a diagnostic on the first require that we see.
This involved me removing the complex logic for emitting diagnostics we have
today in favor of a simple diagnostic that works by:

1. Instead of searching for transfer instructions, we use the transfer
instruction that we propagated by the dataflow... so there is no way for us to
possible not identify a transfer instruction... we always have it.

2. Instead of emitting diagnostics for all requires, just emit a warning for the
first require we see along a path. The reason that we need to do this is that in
certain cases we will have multiple "require" instructions from slightly
different source locations (e.x.: differing by column) but on the same line. I
saw this happen specifically with print where we treat stores into the array as
a require as well as the actual call to print itself where we pass the array.

An additional benefit of this is that this allowed me to get rid of the
cache of already seen require instructions. By doing this, we now emit errors
when the same apply needs to be required by different transfer instructions for
different arguments.

NOTE: I left in the original implementation code to make it easier to review
this new code. I deleted it in the next commit. Otherwise the git diff for this
patch is too difficult to read.
2023-11-15 18:58:06 -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
Michael Gottesman
fc73210f67 [region-isolation] Do not look through type casts from a non-Sendable to a Sendable value.
This came up while I was debugging test cases from the other parts of this
work. The specific issue was around a pointer_to_address from a
RawPointer (which is considered non-Sendable) to a Sendable type. We were
identifying the RawPointer as being the representative of the Sendable value
implying we were processing Sendable values like they were
non-Sendable. =><=. I wish we had SIL test cases for region isolation since I
would add one for this...
2023-11-15 18:58:06 -08:00
Michael Gottesman
9e3f0b068f Rename SILApplyCrossesIsolation -> isIsolationBoundaryCrossingApply.
Just a better name with better camelCasing.
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
Joe Groff
f126b714bf MoveOnlyChecker: Properly insert cleanup for dead try_apply def.
When a address-only noncopyable value is dead-def'ed by an indirect return from a `try_apply`,
the cleanup should be inserted on the normal return successor block. Fixes rdar://118255228.
2023-11-15 08:42:07 -08:00
Erik Eckstein
c551ae0746 PredictableMemOpt: fix wrong handling of re-borrows of a load_borrow
When promoting a load_borrow, the re-borrows were not considered which lead to leaked values.
Now, just bail if a load_borrow has re-borrows.

rdar://118402432
2023-11-15 16:44:08 +01:00
Michael Gottesman
ca663b1583 [region-isolation] Make it possible to "lookThrough" multiple result instructions and use it to lookthrough destructures.
Currently when one says that an instruction is not a "look through" instruction,
each of its results gets a separate element number and we track these results as
independent entities that can be in a region. The one issue with this is
whenever we perform this sort of operation we actually are at the same time
performing a require on the operand of the instruction. This causes us to emit
errors on non-side effect having instructions when we really want to emit an
error on their side-effect having results. As an example of the world before
this patch, the following example would force the struct_element_addr to have a
require so we would emit an error on it instead of the apply (the thing that we
actually care about):

```
%0 = ...

// We transferred %0, so we cannot use it again.
apply %transfer(%0)

// We track %1 and %0 as separate elements and we treat this as an assignment of
// %0 into %1 which forces %0 to be required live at this point causing us to
// emit an error here...
%1 = struct_element_addr %0

// Instead of in the SIL here on the actual side-effect having instruction.
apply %actualUse(%1)
```

the solution is to make instructions like struct_element_addr lookthrough
instructions which force their result to just be the same element as their
operand. As part of doing this, we have to ensure that getUnderlyingTrackedValue
knows how to look through these types. This ensures that they are not considered
roots.

----

As an aside to implement this I needed to compose some functionality ontop of
getUnderlyingObject (specifically the look through behavior on destructures) in
a new helper routine called getUnderlyingTrackedObjectValue(). It just in a loop
calls getUnderlyingObject() and looks through destructures until its iterator
doesn't change.
2023-11-13 19:59:31 -08:00
Doug Gregor
273937a9fd Merge pull request #69824 from DougGregor/typed-throws-fixes
Yet more typed throws fixes
2023-11-13 19:30:48 -08:00
Doug Gregor
84a078b361 Teach the speculative devirtualize to deal with error basic blocks without args 2023-11-13 14:51:14 -08:00
Doug Gregor
8c079c3e43 Teach ForEachLoopUnroll to deal with error basic blocks without arguments 2023-11-13 14:51:14 -08:00
Doug Gregor
27b6a64761 Teach TransferNonSendable that not all Error BB's have arguments 2023-11-13 14:24:13 -08:00
Michael Gottesman
44e1e54e13 Merge pull request #69787 from gottesmm/region-isolation-track-consumption-separately
[region-isolation] Track elements -> regions and regions -> consuming separately.
2023-11-13 11:15:46 -08:00
Mishal Shah
e8de333daf Revert "Add a mark_dependence while emitting SIL for uninitialized array allocation " 2023-11-12 09:43:13 -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
389078d4fa [region-isolation] Remove count of emitted diagnostics from main diagnostic.
These are not actionable to the user.
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
Michael Gottesman
b760fecd2b [region-isolation] Just iterate directly over a block state's partition ops rather than use a callback.
There isn't a strong reason to use a callback here since we aren't ever
composing transformations on partition ops. Better instead to go for simplicity
and just iterate directly. If we start doing complex transformations over
partition ops with composable APIs, we can always add this back in later. As a
nice benefit, one doesn't need to worry that the callback API is hiding actual
complexity... since just by using a for loop we communicate that nothing
interesting is happening here.

Just reducing the amount of code surface area in the pass.
2023-11-10 12:48:45 -08:00
Michael Gottesman
332ba1f7d1 [region-isolation] Simplifying how we emit diagnostic by inlining diagnoseFailures.
This is only used in one place in partition analysis which is a data structure
that does computation. In contrast, we want BlockPartitionState to be more of a
POD type of data that each BasicBlock has mapped to it.

Simplifying the code.

This also let me get rid of the translator field in BasicBlockState. We only
need to pass it in as an argument to the constructor to initialize our
translation. It doesn't need to be stored anymore.
2023-11-10 12:48:45 -08:00
Michael Gottesman
80e1ebe623 [region-isolation] Add some MARK: to make the file a little easier to read. NFC. 2023-11-10 12:48:45 -08:00
Doug Gregor
446dfbff3e Merge pull request #69741 from DougGregor/typed-throws-minor-fixes
Typed throws minor fixes
2023-11-09 10:17:58 -08:00
Doug Gregor
0042201f1f Merge pull request #69700 from DougGregor/typed-throws-reabstraction-thunks
[Typed throws] Implement reabstraction thunks that change the error
2023-11-08 21:01:49 -08:00
Doug Gregor
3c5e9cb739 [SIL] Clone throw_addr instructions by branching to the error basic block
This is the same way we handle `throw` instructions, but without the
operand.
2023-11-08 14:27:28 -08:00
Doug Gregor
9f890004dd [SIL] Disable optimizations that aren't ready for indirect error results 2023-11-08 13:10:25 -08:00
Daniel Rodríguez Troitiño
36a15ceaf4 [sil] Fix the no-assert build by not calling an ifndef NDEBUG method (part 2) (#69716)
PR #69652 protected one call of `printID` but left another two in the
file. Create two small lambdas to print the ID with `printID` or just
print `NOASSERTS` depending on `NDEBUG` being defined. Change all the
callsites of `printID` to use that lambda.
2023-11-08 03:25:09 -08:00
Michael Gottesman
48b4ca0b24 Merge pull request #69686 from gottesmm/rdar117880194
[region-isolation] When assigning RValues into memory, use tuple_addr_constructor instead of doing it in pieces.
2023-11-07 20:15:58 -08:00
Michael Gottesman
b1f69030fc [region-isolation] When assigning RValues into memory, use tuple_addr_constructor instead of doing it in pieces.
I also included changes to the rest of the SIL optimizer pipeline to ensure that
the part of the optimizer pipeline before we lower tuple_addr_constructor (which
is right after we run TransferNonSendable) work as before.

The reason why I am doing this is that this ensures that diagnostic passes can
tell the difference in between:

```
x = (a, b, c)
```

and

```
x.0 = a
x.1 = b
x.2 = c
```

This is important for things like TransferNonSendable where assigning over the
entire tuple element is treated differently from if one were to initialize it in
pieces using projections.

rdar://117880194
2023-11-07 15:38:33 -08:00
Kuba (Brecka) Mracek
71612e6e58 Merge pull request #69678 from kubamracek/embedded-devirt
[embedded] Fix class_method devirtualizer to consider specialized VTables
2023-11-07 09:08:56 -08:00