Commit Graph

1615 Commits

Author SHA1 Message Date
swift_jenkins
189718aaef Merge remote-tracking branch 'origin/main' into next 2021-01-05 09:01:24 -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
0de00d1ce4 [sil-inst-opt] Improve performance of InstModCallbacks by eliminating indirect call along default callback path.
Specifically before this PR, if a caller did not customize a specific callback
of InstModCallbacks, we would store a static default std::function into
InstModCallbacks. This means that we always would have an indirect jump. That is
unfortunate since this code is often called in loops.

In this PR, I eliminate this problem by:

1. I made all of the actual callback std::function in InstModCallback private
   and gave them a "Func" postfix (e.x.: deleteInst -> deleteInstFunc).

2. I created public methods with the old callback names to actually call the
   callbacks. This ensured that as long as we are not escaping callbacks from
   InstModCallback, this PR would not result in the need for any source changes
   since we are changing a call of a std::function field to a call to a method.

3. I changed all of the places that were escaping inst mod's callbacks to take
   an InstModCallback. We shouldn't be doing that anyway.

4. I changed the default value of each callback in InstModCallbacks to be a
   nullptr and changed the public helper methods to check if a callback is
   null. If the callback is not null, it is called, otherwise the getter falls
   back to an inline default implementation of the operation.

All together this means that the cost of a plain InstModCallback is reduced and
one pays an indirect function cost price as one customizes it further which is
better scalability.

P.S. as a little extra thing, I added a madeChange field onto the
InstModCallback. Now that we have the helpers calling the callbacks, I can
easily insert instrumentation like this, allowing for users to pass in
InstModCallback and see if anything was RAUWed without needing to specify a
callback.
2021-01-04 12:51:55 -08:00
swift_jenkins
11993fd1cf Merge remote-tracking branch 'origin/main' into next 2020-12-23 10:53:57 -08:00
Meghana Gupta
b99533aced Merge pull request #34895 from meg-gupta/cseossa
Enable CSE on OSSA
2020-12-23 09:58:46 -08:00
Meghana Gupta
42c031985c Enable CSE on OSSA 2020-12-22 23:20:06 -08:00
Meghana Gupta
d1f8c04e28 Do not include transitive uses with none ownership during ownership rauw of guaranteed values
When we are populating transitive users while handling guaranteed values
in ownership rauw, we were including values with none ownership.

Example : rauw of %2 with a dominating value
   Here %arg1 was also considered a transitive use

   %2 = struct_extract %0 : $StructWithEnum2, #StructWithEnum2.val
   %copy = copy_value %2 : $FakeOptional2
   switch_enum %2 : $FakeOptional2, case #FakeOptional2.some1!enumelt:bb5, case #FakeOptional2.some2!enumelt:bb6

  bb5(%arg1 : $UInt):
   br bb7(%arg1 : $UInt)

  bb6(%arg2 : @guaranteed $Klass):
   %4 = unchecked_trivial_bit_cast %arg2 : $Klass to $UInt
   br bb7(%4 : $UInt)

This is incorrect because %arg1 is a trivial value, and this also
leads to ValueLifetimeAnalysis needing a split for finding a frontier
for the use of %arg1 in the branch instruction. In ossa, we should never
have to split edges for finding frontiers, because we do not have critical
edges.
2020-12-22 22:21:01 -08:00
Meghana Gupta
8431ceb586 Support MultipleValueInstruction in swift::getInsertAfterPoint 2020-12-22 22:04:58 -08:00
Meghana Gupta
68ec810b32 Rename stripOwnershipInsts to lookThroughCopyValueInsts 2020-12-22 22:01:55 -08:00
Slava Pestov
e675bee26c AST: Split off DependencyCollector.h from EvaluatorDependencies.h
Also remove some unnecessary #includes from DependencyCollector.h,
which necessitated adding #includes in various other files.
2020-12-23 00:00:25 -05:00
Meghana Gupta
c7fe3933d2 In OSSA rauw utilities use auto generated location for creating copy_value/destroy_value etc
Branch instructions and frontiers can have
LocationKind::ReturnKind/ImplicitReturnKind which are not correct
locations to use for copy_value/destroy_value etc
2020-12-21 14:01:27 -08:00
swift_jenkins
0e93fae704 Merge remote-tracking branch 'origin/main' into next 2020-12-19 06:08:32 -08:00
Alex Hoppen
fd932a6b42 [SILOpt] Fix build by only accessing seenUse in non-assert builds 2020-12-19 12:23:58 +01:00
swift_jenkins
4df7dbcdce Merge remote-tracking branch 'origin/main' into next 2020-12-18 21:36:24 -08:00
Andrew Trick
bab19976a6 Add a PrunedLiveness utility.
This bare-bones utility will be the basis for
CanonicalizeOSSALifetime. It is maximally flexible and can be adopted
by any analysis that needs SSA-based liveness expressed in terms of
the live blocks. It's meant to be layered underneath various
higher-level analyses.

We could consider revamping ValueLifetimeAnalysis and layering it on
top of this. If PrunedLiveness is adopted widely enough, we can
combine it with a block numbering analysis so we can micro-optimize
the internal data structures.
2020-12-18 18:49:59 -08:00
swift_jenkins
fe6e5da9e2 Merge remote-tracking branch 'origin/main' into next 2020-12-09 23:17:15 -08:00
Michael Gottesman
041ecba21c Canonicalize single value forwarding insts that only have debug_value and destroy_value uses.
E.x.:

```
  %1 = unchecked_ref_cast %0
  destroy_value %1
->
  destroy_value %0
```

I am doing this only in non-Raw SIL to ensure that I do not disturb the
mandatory passes.
2020-12-09 19:17:03 -08:00
swift_jenkins
66b43c58b2 Merge remote-tracking branch 'origin/main' into next 2020-12-09 15:10:38 -08:00
Michael Gottesman
1ca55774b2 Merge pull request #34559 from gottesmm/ossa-inst-simplify
[inst-simplify] Update for OSSA
2020-12-09 14:31:15 -08:00
Michael Gottesman
259d2bb182 [ownership] Commit a generic replaceAllUsesAndEraseFixingOwnership api and enable SimplifyInstruction on OSSA.
This is a generic API that when ownership is enabled allows one to replace all
uses of a value with a value with a differing ownership by transforming/lifetime
extending as appropriate.

This API supports all pairings of ownership /except/ replacing a value with
OwnershipKind::None with a value without OwnershipKind::None. This is a more
complex optimization that we do not support today. As a result, we include on
our state struct a helper routine that callers can use to know if the two values
that they want to process can be handled by the algorithm.

My moticiation is to use this to to update InstSimplify and SILCombiner in a
less bug prone way rather than just turn stuff off.

Noting that this transformation inserts ownership instructions, I have made sure
to test this API in two ways:

1. With Mandatory Combiner alone (to make sure it works period).

2. With Mandatory Combiner + Semantic ARC Opts to make sure that we can
   eliminate the extra ownership instructions it inserts.

As one can see from the tests, the optimizer today is able to handle all of
these transforms except one conditional case where I need to eliminate a dead
phi arg. I have a separate branch that hits that today but I have exposed unsafe
behavior in ClosureLifetimeFixup that I need to fix first before I can land
that. I don't want that to stop this PR since I think the current low level ARC
optimizer may be able to help me here since this is a simple transform it does
all of the time.
2020-12-09 11:53:56 -08:00
swift_jenkins
15b104f002 Merge remote-tracking branch 'origin/main' into next 2020-12-09 11:07:45 -08:00
Michael Gottesman
8a6f6cbe20 [ownership][canonicalize] Canonicalize load_borrow the same we we canonicalize load. 2020-12-08 20:35:34 -08:00
swift_jenkins
787df6b119 Merge remote-tracking branch 'origin/main' into next 2020-12-08 02:11:12 -08:00
Erik Eckstein
9e43f493f3 GenericSpecializer: use an alternative mangling if the function has re-abstracted resilient type parameters.
If the specialized function has a re-abstracted (= converted from indirect to direct) resilient argument or return types, use an alternative mangling: "TB" instead of "Tg".
Resilient parameters/returns can be converted from indirect to direct if the specialization is created within the type's resilience domain, i.e. in its module (where the type is loadable).
In this case we need to generate a different mangled name for the specialized function to distinguish it from specializations in other modules, which cannot re-abstract this resilient type.

This fixes a miscompile resulting from ODR-linking specializations from different modules, which in fact have different function signatures.

https://bugs.swift.org/browse/SR-13900
rdar://71914016
2020-12-07 17:23:46 +01:00
Erik Eckstein
f702be94b7 SIL: cleanup the GenericSpecializationMangler API
NFC
2020-12-07 17:23:46 +01:00
swift_jenkins
827a60500f Merge remote-tracking branch 'origin/main' into next 2020-12-06 15:13:52 -08:00
Michael Gottesman
c6525fd5ac [ownership] end_borrow/destroy_value with an operand that has OwnershipKind::None are trivially dead, so make isInstructionTriviallyDead return true for those cases! 2020-12-04 16:47:40 -08:00
swift_jenkins
5978c71851 Merge remote-tracking branch 'origin/main' into next 2020-12-04 15:06:33 -08:00
Michael Gottesman
16b63b15f8 [cfgoptutils] Add a new overload of addNewEdgeValueToBranch that takes an InstModCallback.
I reimplemented the original addNewEdgeValueToBranch to just call the new
overload with a default InstModCallbacks, so nothing changed and now we can plug
in callbacks to this utility!
2020-12-04 01:07:07 -08:00
swift_jenkins
33063d8e99 Merge remote-tracking branch 'origin/main' into next 2020-12-02 20:33:50 -08:00
Michael Gottesman
ec71713fb0 [ownership] Teach CanonicalizeInstruction how to eliminate trivial copies/borrows.
I am going to be using in inst-simplify/sil-combine/canonicalize instruction a
RAUW everything against everything API (*). This creates some extra ARC
traffic/borrows. It is going to be useful to have some simple peepholes that
gets rid of some of the extraneous traffic.

(*) Noting that we are not going to support replacing non-trivial
OwnershipKind::None values with non-trivial OwnershipKind::* values. This is a
corner case that only comes up with non-trivial enums that have a non-payloaded
or trivial enum case. It is much more complex to implement that transform, but
it is an edge case, so we are just not going to support those for now.

----

I also eliminated the dependence of SILGenCleanup on Swift/SwiftShims. This
speeds up iterating on the test case with a debug compiler since we don't need
those modules.
2020-12-02 17:25:13 -08:00
swift_jenkins
29d5832c14 Merge remote-tracking branch 'origin/main' into next 2020-11-17 09:46:42 -08:00
Andrew Trick
71acf8dc7a Fix SimplifyCFG CheckedCastBrJumpThreading.
This pass was rewriting branches using the orignal branch target
instead of the new branch target. It used to not matter when the pass
was mannually splitting critical edges later. Now the splitting
is handled automatically.

Fixes rdar://71447520 (SILVerifier error after SimplifyCFG
"Instruction does not dominate all uses!")
2020-11-17 01:47:38 -08:00
swift_jenkins
de3fb8bd01 Merge remote-tracking branch 'origin/main' into next 2020-11-15 20:46:34 -08:00
Michael Gottesman
d2de176264 [sil][value-lifetime] Add ValueLifetimeAnalysis::FrontierImpl = SmallVectorImpl<SILInstruction *>
Otherwise, one is always forced to use ValueLifetimeAnalysis::Frontier, a
SmallVector<SILInstruction *, 4>. This may not be a size appropriate for every
problem, so it makes sense to provide Frontier as a good rule of thumb, but use
FrontierImpl on the actual API boundary to loosen the constraint if the user
wishes to do so.
2020-11-15 16:41:47 -08:00
swift_jenkins
d5be531a83 Merge remote-tracking branch 'origin/main' into next 2020-11-10 19:07:28 -08:00
Michael Gottesman
c026e95cce [ownership] Extract out SILOwnershipKind from ValueOwnershipKind into its own type and rename Invalid -> Any.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
2020-11-10 14:29:11 -08:00
swift_jenkins
a54d817b95 Merge remote-tracking branch 'origin/main' into next 2020-11-09 09:07:45 -08:00
Andrew Trick
c2b13cdd51 Merge pull request #34635 from atrick/verify-critedge
Verify non-critical edges in OSSA
2020-11-09 08:59:08 -08:00
swift_jenkins
27e2ffef81 Merge remote-tracking branch 'origin/main' into next 2020-11-09 00:07:47 -08:00
Michael Gottesman
6f60a17cc7 Merge pull request #34633 from gottesmm/pr-200203a48964c3efb090a7f4f2389b115a88b607
[ownership] Change switch_enum to be a true forwarding instructions.
2020-11-08 23:54:50 -08:00
Andrew Trick
34c48f1ee2 Add isNonCriticalEdge fast check for a specific edge. 2020-11-08 21:34:24 -08:00
swift_jenkins
b75f1b80ce Merge remote-tracking branch 'origin/main' into next 2020-11-08 21:33:38 -08:00
Andrew Trick
36fa93a3bf Merge pull request #34610 from atrick/eager-critedge
Fix EagerSpecializer to avoid critical edges.
2020-11-08 21:08:05 -08:00
Michael Gottesman
f36e8561f1 [ownership] Use a new ADT SwitchEnumBranch instead of SwitchEnumInstBase for generic operations on SwitchEnum{,Addr}Inst.
I have a need to have SwitchEnum{,Addr}Inst have different base classes
(TermInst, OwnershipForwardingTermInst). To do this I need to add a template to
SwitchEnumInstBase so I can switch that BaseTy. Sadly since we are using
SwitchEnumInstBase as an ADT type as well as an actual base type for
Instructions, this is impossible to do without introducing a template in a ton
of places.

Rather than doing that, I changed the code that was using SwitchEnumInstBase as
an ADT to instead use a proper ADT SwitchEnumBranch. I am happy to change the
name as possible see fit (maybe SwitchEnumTerm?).
2020-11-08 19:52:02 -08:00
swift_jenkins
7f5c6c924d Merge remote-tracking branch 'origin/main' into next 2020-11-08 19:00:40 -08:00
Michael Gottesman
642a993702 [ownership] Rename Operand::isConsumingUse() -> Operand::isLifetimeEnding().
This makes it clearer that isConsumingUse() is not an owned oriented API and
returns also for instructions that end the lifetime of guaranteed values like
end_borrow.
2020-11-08 13:23:17 -08:00
Andrew Trick
903697675b Fix EagerSpecializer to avoid critical edges. 2020-11-06 08:31:23 -08:00
swift_jenkins
c145199093 Merge remote-tracking branch 'origin/main' into next 2020-11-04 15:00:00 -08:00
Arnold Schwaighofer
97e5e01fe2 Merge remote-tracking branch 'origin/main' into next 2020-11-04 12:20:35 -08:00