Commit Graph

23 Commits

Author SHA1 Message Date
Nadav Rotem
240ff14db1 Split DominanceAnalysis into Dom and PDom using FunctionAnalysisBase.
This commit splits DominanceAnalysis into two analysis (Dom and PDom) that
can be cached and invalidates using the common FunctionAnalysisBase interface
independent of one another.

Swift SVN r26643
2015-03-27 20:54:28 +00:00
Nadav Rotem
f0fa502d56 Split the RCIdentityAnalysis analysis to allow per-function invalidation.
Before the change the RCIdentityAnalysis kept a single map that contained
the module's RC information. When function passes needed to invalidate the
analysis they had to clear the RC information for the entire module. The
problem was mitigated by the fact that we process one function at a time, and
we start processing a new function less frequently.

II adopted the DominanceAnalysis structure. We should probably implement
this functionality as CRTP.

Swift SVN r26636
2015-03-27 16:55:36 +00:00
Michael Gottesman
e36661b8b5 [rc-id] Be conservative and remove the notion of ARCExitUser. This was too aggressive.
We can still ignore non-overlapping extract users.

Swift SVN r26609
2015-03-26 23:02:43 +00:00
Michael Gottesman
0688dbf607 [rcid] Teach RCIdentityAnalaysis::getRCUses() how to ignore certain uses that are inert from its perspective.
This includes:

1. Extract instructions which extracts a trivial part of an aggregate that has
one RCIdentity.
2. Instructions which take a pointer out of ARC's control by converting it to a
trivial type. This is safe to do since we can assume that the object that is
convered is alive when the conversion happens. So assuming that we can
conservatively find all RC users, we will have at least one RC user that
post dominates the use (since otherwise we would be touching a dangling
pointer). We leave it to the user of the pass to determine what is safe to do
with this information. Potentially in the future it might make sense to return
this information as well so that a user can use that information directly.

rdar://20305817

Swift SVN r26583
2015-03-26 07:19:41 +00:00
Michael Gottesman
254c784c94 [+0 self][pin removal] Teach pinremoval how to use RCIdentityAnalysis when removing pins.
Previously, we were being very conservative and were not trying to look through
any RCId uses. Now we understand how to look through RCIdentical instructions to
pair a pin and unpin. We also understand how to use the new getRCUses API on
RCIdentityAnalysis to get all uses of a value, looking through RCIdentical
instructions.

I also added some code to COWArrayOpts to teach it how to look through enum insts (which I needed).

Additionally I got stuck and added support for automatic indentation in Debug
statements. This is better than having to indent by hand every time.

There were no significant perf changes since this code was not being emitted by
the frontend. But without this +0 self causes COW to break.

rdar://20267677

Swift SVN r26529
2015-03-25 06:21:11 +00:00
Michael Gottesman
6f8b468cb6 Change switches and selects to use NullablePtr<EnumElementDecl> instead of EnumElementDecl * when their API explicitly requires the user to check for nullptr. NFC.
This is just good to do and hopefully will help prevent people from forgetting
to check in the future by annotating the API explicitly as returning a
potentially nullptr.

Swift SVN r25364
2015-02-18 02:11:57 +00:00
Andrew Trick
17c7c7937b Fix a variable name from a failed rebase.
Swift SVN r25363
2015-02-18 00:59:06 +00:00
Andrew Trick
d6016759e7 Tweaked RCIdentity comments during review.
Swift SVN r25360
2015-02-18 00:41:36 +00:00
Michael Gottesman
cdb1ff6152 [rc-id] Address Andy's comments to r25339.
The only substantial change is that I was iterating over instructions to look
for unchecked_enum_data. The only reason really to do that is to stop phase
ordering issues with simplify-cfg, but it is really not necessary.

Swift SVN r25359
2015-02-18 00:14:15 +00:00
Michael Gottesman
4cb9eb72f4 [rc-id] Ensure that the reforming enum analysis properly handles no-payload incoming values.
One common problem in swift code is the "reforming enum problem". What
happens here is that we have some enum %0 : $Optional<T> and we break it
apart and reform it as a new enum as in the following:

   bb9:
     ...
     switch_enum %0 : $Optional<T>, #Optional.None: bb10,
                                    #Optional.Some: bb11

   bb10:
     %1 = enum $Optional<U>, #Optional.None
     br bb12(%1 : $Optional<U>)

   bb11:
     %2 = some_cast_to_u %0 : ...
     %3 = enum $Optional<U>, #Optional.Some, %2 : $U
     br bb12(%3 : $Optional<U>)

   bb12(%4 : $Optional<U>):
     retain_value %0 : $Optional<T> // id %5
     release_value %4 : $Optional<U> // id %6

We really would like to know that a retain on %4 is equivalent to a
retain on %0 so we can eliminate the retain, release pair. To be able to
do that safely, we need to know that along all paths %0 and %4 either:

1. Both refer to the same RCIdentity directly. An example of this is the
edge from bb11 -> bb12).
2. Both refer to the "null" RCIdentity (i.e. do not have a payload). An
example of this is the edge from bb10 -> bb12.

Only in such cases is it safe to match up %5, %6 and eliminate them. If
this is not true along all paths like in the following:

   bb9:
     ...
     cond_br %foo, bb10, bb11

   bb10:
     %1 = enum $Optional<U>, #Optional.None
     br bb12(%1 : $Optional<U>)

   bb11:
     %2 = some_cast_to_u %0 : ...
     %3 = enum $Optional<U>, #Optional.Some, %2 : $U
     br bb12(%3 : $Optional<U>)

   bb12(%4 : $Optional<U>):
     retain_value %0 : $Optional<T> // id %5
     release_value %4 : $Optional<U> // id %6

then we may have that %0 is always non-payloaded coming into bb12. Then
by matching up %0 and %4, if we go from bb9 -> bb11, we will lose a
retain.

Perf Changes:

TITLE..................OLD...........NEW...........NEW/OLD
LevenshteinDistance....1398195.00....1177397.00....0.84
Memset.................26541.00......23701.00......0.89
CaptureProp............5603.00.......5031.00.......0.90
ImageProc..............1281.00.......1196.00.......0.93
InsertionSort..........109828.00.....104129.00.....0.95
StringWalk.............6813.00.......7456.00.......1.09
Chars..................27182.00......30443.00......1.12

The StringWalk, Chars are both reproducible for me. When I turn back on parts of
the recursion (I took the recursion out to make this change more conservative),
the Chars regression goes away, but the StringWalk stays. I have not had a
chance to look at what is going on with StringWalk.

rdar://19724405

Swift SVN r25339
2015-02-17 01:30:19 +00:00
Michael Gottesman
24bb8191c8 [rc-id] Add an option that stops RCIdentityAnalysis from stripping off arguments.
Swift SVN r25338
2015-02-17 01:30:19 +00:00
Arnold Schwaighofer
08015deced RefToBridgeObjectInst and BridgeObjectToRefInst are rc identity preserving
rdar://19006443

Swift SVN r23411
2014-11-18 21:23:07 +00:00
Michael Gottesman
e9790e7f27 [rc-id] init_existential_ref and open_existential_ref do not change rc identity.
rdar://18831577

Swift SVN r23024
2014-10-31 02:14:58 +00:00
Michael Gottesman
5bd06b1c16 [rc-id] Strip off instructions (not arguments) before checking dominance. This resolves the recent regressions resulting from my fix commit.
Swift SVN r22903
2014-10-23 23:38:26 +00:00
Michael Gottesman
af10399976 [rc-id] Teach RCId how to strip off StructInst, TupleInst, and TupleExtractInst.
Specifically:

1. Given a struct literal with only one stored non-trivial field, a ref count
operation on the struct is equivalent to a ref count operation on the field.

2. Given a tuple literal with only one non-trivial elt , a ref count
operation on the tuple is equivalent to a ref count operation on the elt.

3. Given a tuple_extract, if the tuple_extract is extracting the only
non-trivial element of the tuple, a ref count on the tuple_extract is equivalent
to a ref count on the original type.

rdar://18499023

Swift SVN r22902
2014-10-23 23:38:26 +00:00
Michael Gottesman
1f6238f0c5 [rc-id] Check dominance before recursively stripping instead of vis-a-versa.
Before this change, given a CFG like the following:

bb0:
  %0 = enum $Optional<Cls>, #Optional.None!enumelt
  br bb1(%0 : $Optional<Cls>)

bb1(%1 : $Optional<Cls>):
  %2 = alloc_ref $Cls
  retain_value %2 : $Cls
  release_value %1 : $Optional<Cls>
  %3 = enum $Optional<Cls>, #Optional.Some!enumelt.1, %2 : $Cls
  cond_br undef, bb1(%3 : $Optional<Cls>), bb2

bb2:
  ...

We would pair up the retain, release even though they are from different
iterations. The reason we were doing this is that we were recursively
stripping off the Phi node before checking dominance instead of
vis-a-versa.

rdar://18367606

Swift SVN r22892
2014-10-23 20:17:02 +00:00
Michael Gottesman
37daef2b9e Reapply "[rc-id] Enable RCIdentity analysis."
This reverts r22044, reapplying commit r22006.

I think Arnold found the bug behind why this originally was failing (that we
were too aggressive with stripping off certain types of pointers). Re-enable
it.

This gives us another 5% on Richards.

Swift SVN r22809
2014-10-17 02:14:06 +00:00
Arnold Schwaighofer
fec872aeb1 RCIdentifyAnalysis: Don't strip raw_pointer_to_ref
Instructions that change between RawPointer and a non-trivial type are not RC
identical.

rdar://18540783

Swift SVN r22540
2014-10-06 18:16:33 +00:00
Michael Gottesman
31df902675 Revert "[rc-id] Enable RCIdentity analysis."
This reverts commit r22006. Turns out this did expose other issues. I am just
going to revert it for now since I don't have time to mess with it now. *sigh*.

Swift SVN r22044
2014-09-17 22:28:02 +00:00
Michael Gottesman
e47d5f574c [rc-id] Enable RCIdentity analysis.
Swift SVN r22006
2014-09-17 05:16:26 +00:00
Michael Gottesman
04d9f968fd [rc-id] Make sure when stripping off arguments that the resulting stripped value dominates the argument.
This is important since to be more aggressive we are ignoring incoming values
that are no-payload enums since as far as we are concerned they do not matter
since retains, releases on those values are no-ops.

Swift SVN r21932
2014-09-12 22:21:06 +00:00
Michael Gottesman
4609513593 Remove SILValue::stripRCIdentityPreservingArgs and teach all uses of that method to use the new RCIdentityAnalysis.
Currently, the pass just calls a local version of that function. After OzU, I
will enable the full pass (which is currently disabled behind a flag).

Swift SVN r21894
2014-09-11 22:29:31 +00:00
Michael Gottesman
4647eb9601 Create RCIdentityAnalysis a cache for stripRCIdentityPreservingOps.
The cache is needed to ensure we do not run into compile time problems once we
start looking through Phi Nodes.

The analysis is currently disabled and just returns
SILValue::stripRCIdentityPreservingOps. I am going to thread it through the rest
of the passes that use that call. Then I am going to hide
stripRCIdentityPreservingArgs. Finally post OzU, I am going to enable the pass.

rdar://18300069

Swift SVN r21891
2014-09-11 21:51:29 +00:00