Commit Graph

682 Commits

Author SHA1 Message Date
Michael Gottesman
62d554669c [ownership] Rename OwnershipForwardingMixin::{get,set}OwnershipKind() -> {get,set}ForwardingOwnershipKind().
TLDR: This is just an NFC rename in preparation for changing
SILValue::getOwnershipKind() of any forwarding instructions to return
OwnershipKind::None if they have a trivial result despite forwarding ownership
that isn't OwnershipKind::None (consider an unchecked_enum_data of a trivial
payload from a non-trivial enum).

This ensures that one does not by mistake use this routine instead of
SILValue::getOwnershipKind(). The reason why these two things must be
distinguished is that the forwarding ownership kind of an instruction that
inherits from OwnershipForwardingMixin is explicitly not the ValueOwnershipKind
of the result of the instruction. Instead it is a separate piece of state that:

1. For certain forwarding instructions, defines the OwnershipConstraint of the
forwarding instruction.

2. Defines the ownership kind of the result of the value. If the result of the
value is non-trivial then it is exactly the set ownership kind. If the result is
trivial, we use OwnershipKind::None instead. As an example of this, consider an
unchecked_enum_data that extracts from a non-trivial enum a trivial payload:

```
enum Either {
case int(Int)
case obj(Klass)
}

%1 = load_borrow %0 : $*Either
%2 = unchecked_enum_data %1 : $Either, #Either.int!enumelt.1 // Int type
end_borrow %1 : $Either
```

If we were to identify the forwarding ownership kind (guaranteed) of
unchecked_enum_data with the value ownership kind of its result, we would
violate ownership since we would be passing a guaranteed value to the operand of
the unchecked_enum_data that will only accept values with
OwnershipKind::None. =><=.
2021-02-04 16:53:50 -08:00
Erik Eckstein
34ae1d911a SILCombine: remove release_value of a value_to_bridge_object
Needed to remove unneeded reference counting for String literals.
2021-02-04 07:53:32 +01:00
Michael Gottesman
ed368ab7d9 [sil-combine] Update COWBufferForReading for OSSA.
I was able to use the interior pointer operand API to great effect here.
2021-02-02 15:54:44 -08:00
Erik Eckstein
d33ea9f350 SIL: remove the JointPostDominanceSetComputer helper struct.
Instead make `findJointPostDominatingSet` a stand-alone function.
There is no need to keep the temporary SmallVector alive across multiple calls of findJointPostDominatingSet for the purpose of re-using malloc'ed memory. The worklist usually contains way less elements than its small size.
2021-02-02 10:20:35 +01:00
Michael Gottesman
c32df33393 [sil-combine] Enable alloc_ref_dynamic -> alloc_ref canonicalization
This involves folding a metatype into the alloc_ref_dynamic and we always
replace the alloc_ref_dynamic with an alloc_ref so this is always safe from an
ownership perspective.
2021-01-28 12:10:16 -08:00
Michael Gottesman
ddba98d51e [sil-combine] Enable mark_dependence simplifications. 2021-01-28 12:10:16 -08:00
Michael Gottesman
2fad943df0 [sil-combine] Update convert_function canonicalization for ownership.
Some notes:

1. I moved the identity round-trip case to InstSimplify since that is where
   optimizations like that are.

2. I did not update in this commit the code that eliminates convert_function
   when it is only destroyed. In a subsequent commit I am going to implement
   that in a general way and apply it to all forwarding instructions.

3. I implemented eliminating convert_function with ownership only uses in a
   utility so that I can reuse it for other similar optimizations in SILCombine.
2021-01-28 12:10:16 -08:00
Michael Gottesman
7d5c60b87d [sil-combine] Implement simple alloc_existential_box removal. 2021-01-28 12:10:16 -08:00
Michael Gottesman
35f941f8bb [sil-combine] Update unchecked_take_enum_data_addr -> unchecked_enum_data promotion for ownership. 2021-01-28 12:10:15 -08:00
Michael Gottesman
ac2ef83951 [sil-combine] Enable cond_br canonicalizations in ossa.
The key thing is that all of these while they do modify the branches of the CFG
do not invalidate block level CFG analyses like dominance and dead end
blocks.
2021-01-28 12:10:15 -08:00
Michael Gottesman
6c960af9fa [sil-combine] Enable unchecked_ref_cast formation from rawpointer_to_ref round trips when compiling with ownership. 2021-01-28 12:10:15 -08:00
Michael Gottesman
29d2458876 [sil-combine] Enable unchecked_addr_cast formation in ownership mode. 2021-01-28 12:10:15 -08:00
Meghana Gupta
c7b6ec8e92 Merge pull request #35609 from meg-gupta/ossabugs3
Minor bug fixes in SILCombine, Canonicalization and LoadBorrowImmutabilityChecker
2021-01-27 13:55:24 -08:00
Erik Eckstein
f48191966c SILOptimizer: use BasicBlockSet instead of SmallPtrSet in various transformations.
It reduces compile time.
2021-01-27 10:31:17 +01:00
Meghana Gupta
514cd9cfc3 Handle empty case in SILCombine's
SingleBlockOwnedForwardingInstFolder::add function's  assert
2021-01-26 19:56:32 -08:00
Michael Gottesman
04ba6c6d96 [sil-combine] Enable select_enum canonicalization in OSSA. 2021-01-25 20:30:39 -08:00
Michael Gottesman
68b4671a78 [sil-combine] Enable sil-combine simplifications for {thick_to_objc,objc_to_thick}_metatype.
Metatype always have none ownership, so we can just perform this.

I also removed a test (peephole_thick_to_objc_metatype.sil) that I had in a
previous commit renamed to sil_combine_peephole_thick_to_objc_metatype.sil. This
was os that this matched the rest of the sil_combine tests that have the
'sil_combine_*' prefix.
2021-01-25 20:20:14 -08:00
Michael Gottesman
bf5ac43a66 [sil-combine] Enable unreachable pruning for ownership.
This doesn't mess with ownership, so we can just enable it.
2021-01-25 18:46:45 -08:00
Michael Gottesman
2abd7e8604 [sil-combine] Update unchecked_bitwise_cast canonicalizations for ownership.
The only interesting thing that I did in this commit is I added a parameter to
OwnershipRAUWHelper::perform that lets one pass in a transformed version of
newValue. The assumption is that the transformation if it is done is done at the
location of oldValue.
2021-01-25 18:05:26 -08:00
Michael Gottesman
d6ffddc63f [sil-combine] Add ownership support for switch_enum_addr transforms.
I implemented specifically the promotion from switch_enum_addr -> switch_enum
for loadable types.

NOTE: I did not add support for the inject_enum_addr based conversion to br since that
optimization deletes an edge from the CFG, potentially invalidating CFG
properties. Since OSSA needs to use DeadEndBlocks, we want to avoid changing
reachability in any way with our SILCombine transforms.
2021-01-25 16:00:32 -08:00
Michael Gottesman
f39df1d73b [sil-combine] Address comments from post-commit review of cd7c9e97e4. 2021-01-22 14:26:59 -08:00
Michael Gottesman
cd7c9e97e4 [sil-combine] Fix cast optimizer based optimizations for ownership. 2021-01-20 13:19:02 -08:00
Michael Gottesman
34c008951e [ownership] Fix build due to a missing code change dependency in between two PRs. 2021-01-20 11:29:18 -08:00
Michael Gottesman
2243ffefa4 Merge pull request #35461 from gottesmm/ossa-interior-ptr-fixup
[ownership] Implement Interior Pointer handling API for RAUWing addresses
2021-01-20 09:53:48 -08:00
Michael Gottesman
43d254cf6a Merge pull request #35501 from gottesmm/sil-combine-apply-visitors
[sil-combine] Enable ownership on all of the apply visitors.
2021-01-20 09:52:36 -08:00
Erik Eckstein
cf17fd4df4 SILOptimizer: Use BasicBlockData in the StackNesting utility 2021-01-20 16:09:01 +01:00
Michael Gottesman
94c643cb27 [sil-combine] Enable ownership on all of the apply visitors.
All of the non-SILCombiner specific helpers have already been updated for OSSA,
so this was not too bad.

NOTE: I also added two small combines that delete copy_value, destroy_value with
.none arguments. The reason why I added this is that this is a pretty small
addition and many of the tests of this code rely on SILCombine being able to
eliminate such operations on thin_to_thick_function.

NOTE: I also disabled TypePropagation in OSSA, we are going to redo that code
when we bring up opaque values.
2021-01-19 22:47:18 -08:00
Michael Gottesman
b16dfcd5e1 Merge pull request #35434 from gottesmm/pr-60b428d117d8f41f7543a7a536081dff5f507ff5
[ownership] Some more comment post-commit fixes for ffa55937c4 0e946321e151fe54c0f4060
2021-01-19 15:57:21 -08:00
Michael Gottesman
a3f172884e [sil-combine] Enable classify_bridge_object folding when ownership is enabled.
From an ownership perspective, this is just eliminating a non-lifetime ending
use. The new instructions we create are not connecting to the underlying object
anymore.
2021-01-18 14:00:48 -08:00
Michael Gottesman
364cee87aa [sil-combine] Enable elimination of simple tuple results from overflow functions when ownership is enabled.
This doesn't actually touch non-trivial values, so from an ownership perspective
it is inert. It is tested by the pattern in the next commit.
2021-01-18 13:55:56 -08:00
Michael Gottesman
1e7990c9af [sil-combine] Enable cond_fail elimination for ownership. 2021-01-18 13:47:24 -08:00
Michael Gottesman
5572d04010 [sil-combine] Enable optimized nested index_addr optimization in ownership.
This just works with transitive addresses meaning that there aren't any
ownership issues we need to think about.
2021-01-18 10:48:38 -08:00
Michael Gottesman
73ba521e56 [ownership] Add a new API to OwnershipFixupContext::replaceAllAddressUsesFixingInteriorPointerOwnership.
In OSSA, we enforce that addresses from interior pointer instructions are scoped
within a borrow scope. This means that it is invalid to use such an address
outside of its parent borrow scope and as a result one can not just RAUW an
address value by a dominating address value since the latter may be invalid at
the former. I foresee that I am going to have to solve this problem and so I
decided to write this API to handle the vast majority of cases.

The way this API works is that it:

1. Computes an access path with base for the new value. If we do not have a base
value and a valid access path with root, we bail.

2. Then we check if our base value is the result of an interior pointer
instruction. If it isn't, we are immediately done and can RAUW without further
delay.

3. If we do have an interior pointer instruction, we see if the immediate
guaranteed value we projected from has a single borrow introducer value. If not,
we bail. I think this is reasonable since with time, all guaranteed values will
always only have a single borrow introducing value (once struct, tuple,
destructure_struct, destructure_tuple become reborrows).

4. Then we gather up all inner uses of our access path. If for some reason that
fails, we bail.

5. Then we see if all of those uses are within our borrow scope. If so, we can
RAUW without any further worry.

6. Otherwise, we perform a copy+borrow of our interior pointer's operand value
at the interior pointer, create a copy of the interior pointer instruction upon
this new borrow and then RAUW oldValue with that instead. By construction all
uses of oldValue will be within this new interior pointer scope.
2021-01-17 20:08:24 -08:00
Michael Gottesman
3acb7df298 [ownership] Some more comment post-commit fixes for ffa55937c4. 2021-01-14 13:30:47 -08:00
Michael Gottesman
f92b75cafa [sil-combine] Enable unchecked_trivial_bitcast for ownership.
Instruction just deals with trivial values.
2021-01-13 10:43:41 -08:00
Michael Gottesman
2ff6fdfd0a [sil-combine] Update ownership for bridge_object_to_ref.
This just uses the infrastructure in place from fixing
upcast/unchecked_ref_cast.
2021-01-13 10:43:41 -08:00
Michael Gottesman
7ecee99097 [sil-combine] Implement a new class SingleBlockOwnedForwardingInstFolder to help eliminate chains of owned forwarding insts and use it to update upcast and unchecked_ref_cast for ownership.
b644c80f90fb7099ec956bb44065b50e432c5146 caused all owned forwarding
instructions to be sunk to their uses in the exact cases where we could
eliminate the parent forwarding inst (namely that the value we want to fold has
no non-debug, non-consuming users). So I was able to implement this just by
implementing a single basic block algorithm that works via a planner struct
using said canonicalization. One initializes the planner struct with the
instruction that is going to either be eliminated or have its forwarding operand
set. Then one adds each of the individual chains that lead to the use that we
wish to fold, each time checking that we can eliminate the instruction.

Once the user has added all of the intermediate forwarding instructions, by
construction (see paragraph above), we know we can optimize. So we eliminate all
intermediate values and then depending on whether the user called the set value
or replace value method we either set front's operand to be the passed in value
or we RAUW/erase front with that value. It is important to note that before we
do one of those two operations, front's operand is undef, so we need to perform
one of these two operations.
2021-01-13 10:43:41 -08:00
Michael Gottesman
279d058bfe [sil-combine] Canonicalize owned forwarding insts without non-debug non-consuming uses by sinking to their uses.
There are a bunch of optimizations in SILCombine where we try to fold an
ownership forwarding instruction A into another ownership forwarding instruction
B without deleting A. Consider the upcasts in the example below:

```
  %0 = upcast %x : $X->Y
  %1 = upcast %0 : $Y->Z
```

These sorts of optimizations fold the first instruction into the second like so:

```
  %0 = upcast %x : $X->Y
  %1 = upcast %x : $X->Z
```

This creates a problem when we are dealing with owned values since we have just
introduced two consumes for %x. To work around this, we have two options:

1. Introduce extra copies.

2. We recognize the situations where we can guarantee that we can delete the
   first upcast.

The first choice I believe is not a choice since breaking a forwarding chain of
ownership in favor of extra copies is a less canonical form. That leaves us with
the second form. What are the necessary/sufficient conditions for deleting the
first upcast. Simply it is that the upcast cannot have any non-debug,
non-consuming uses! In such a case, we know that along all paths through the
program the value has exactly one non-debug use, one of its consuming uses. If
when optimizing upcasts we could recognize that pattern, duplicate the inst
along paths not through our 2nd upcast and thus delete the original upcast
fixing the ownership error!

While this is all nice and good there is a problem with this: it doesn't
scale. As I was writing a few optimizations like this I began to note that I had
to write different versions of this same helper for many of the visitors (they
generally varied by how many forwarding instructions they looked through).

As I pondered the above, I chatted a bit with @atrick and during our
conversation, we both realized that it is much easier to solve this problem in
one block and that the condition above would allow us to sink these instructiosn
into the same block and thus if we could check for this condition and
canonicialize the IR to sink these instructions before we visiting, we could use
a single helper to handle all of these cases.
2021-01-13 10:43:41 -08:00
Michael Gottesman
56e9ca4543 [sil-combine] Update unchecked_addr_cast simplifications for ownership. 2021-01-13 10:43:41 -08:00
Michael Gottesman
cff4e504cd [sil-combine] Update pointer_to_address canonicalizations for OSSA.
For now I am not performing the [strict] elimination until I bring up the
interior pointer OSSA utilities. I want to make further progress before I loop
back around to that.
2021-01-13 10:43:41 -08:00
Michael Gottesman
542cacfa6a [sil-combine] Enable builtin visitors. 2021-01-13 10:43:41 -08:00
Michael Gottesman
4db2aa6b79 [sil-combine] Add an OwnershipFixupContext to SILCombine. 2021-01-13 10:43:41 -08:00
Michael Gottesman
1ab36330a6 Revert "[sil-combine] Update switch_enum_addr -> switch_enum for loadable types for ownership."
This reverts commit 0a0f8cffc1.

Currently the memory lifetime verifier (I believe due to the switch_enum) is not
caring that we are not emitting destroy_addr for an enum address along paths
where we know the underlying enum case is trivial.

This transform eliminated that switch_enum_addr causing the memory lifetime
verifier to then trigger.

Disabling to unblock the bots!
2021-01-05 13:08:53 -08:00
Michael Gottesman
409ad6e8fd Merge pull request #35256 from gottesmm/pr-9c2c0f1fec0527092a68ca8fd955d6a5dc77799d
[sil-inst-opt] Change InstModCallbacks to specify a setUseValue callback instead of RAUW callbacks.
2021-01-04 21:14:25 -08:00
Michael Gottesman
2f6ffae4b0 [sil-inst-opt] Change InstModCallbacks to specify a setUseValue callback instead of RAUW callbacks.
This allows for me to do a couple of things improving quality/correctness/ease of use:

1. I reimplemented InstMod's RAUW and RAUW/erase helpers on top of
   setUseValue/deleteInst. Beyond allowing the caller to specify less things, we
   gain an orthogonality preventing bugs like overriding erase/RAUW but not
   overriding erase or having the erase used in erase/RAUW act differently than
   the erase for deleteInst.

2. There were a bunch of places using InstModCallback that also were setting
   uses without having the ability for InstModCallbacks perform it (since it
   only supported RAUW). This is an anti-pattern and could cause subtle bugs to
   be introduced by appropriate state in the caller not being updated.
2021-01-04 16:47:13 -08:00
Michael Gottesman
560483114d [sil-combine] Enable switch_value to be optimized in OSSA.
This routine never touches values with non-trivial ownership, so I just removed
the early exit and updated the style.
2021-01-04 15:44:58 -08:00
Michael Gottesman
2413f5fe7c [sil-combine] Update select_enum_addr canonicalization to use OSSA. 2021-01-04 15:44:58 -08:00
Michael Gottesman
0a0f8cffc1 [sil-combine] Update switch_enum_addr -> switch_enum for loadable types for ownership. 2021-01-04 15:44:58 -08:00
Michael Gottesman
a5e7c3f271 [sil-combine] Update LoadInst opts for OSSA and expand opts to also support LoadBorrow.
NOTE: The stdlib count/capacity propagation code is tested in an end<->end
fashion in a separate Swift test. Once I flip the switch, that test will run.
The code is pretty simple, so I feel relatively confident with it.
2021-01-04 15:44:58 -08:00
Michael Gottesman
e1a616f1d4 Merge pull request #35198 from gottesmm/pr-0d922ed7f7078d21e2bbfc5273730703a61d7c08
[sil-combine] Update RefToRawPointer simplifications for ossa.
2020-12-22 21:28:24 -08:00