Commit Graph

283 Commits

Author SHA1 Message Date
Michael Gottesman
ac1f956ac0 Split predictable mem opts into two different passes, one that runs before diagnostics and one that runs after diagnostics.
I discovered while updating PMO for ownership that for ~5 years there has been a
bug where we were treating copy_addr of trivial values like an "Assign" (in PMO
terminology) of a non-trivial value and thus stopping allocation
elimination. When I fixed this I discovered that this caused us to no longer
emit diagnostics in a predictable way. Specifically, consider the following
swift snippet:

  var _: UInt = (-1) >> 0

Today, we emit a diagnostic that -1 can not be put into a UInt. This occurs
since even though the underlying allocation is only stored into, the copy_addr
assign keeps it alive, causing the diagnostics pass to see the conversion. With
my fix though, we see that we are only storing into the allocation, causing the
allocation to be eliminated before the constant propagation diagnostic pass
runs, causing the diagnostic to no longer be emitted.

We should truly not be performing this type of DCE before we emit such
diagnostics. So in this commit, I split the pass into two parts:

1. A load promotion pass that performs the SSA formation needed for SSA based
diagnostics to actually work.

2. An allocation elimination passes that run /after/ SSA based diagnostics.

This should be NFC since the constant propagation SSA based diagnostics do not
create memory operations so the output should be the same.
2019-01-17 14:48:03 -08:00
swift-ci
cd8f565adc Merge pull request #21822 from gottesmm/pr-8d2416681ea41244ae3c2bd3d3d3bb35fcc1eade 2019-01-14 12:46:16 -08:00
Michael Gottesman
4fd45930f8 [sil-optimizer] At -Onone serialize when running the Onone optimization pipeline instead of after running SIL passes.
NOTE: This is not in the mandatory passes (which run before this). This will
enable me to strip out ownership after we serialize without touching frontend
code. It also makes Onone and O use the same code paths for serialization
instead of one happening in the driver (Onone today) and the other in a SIL pass
(-O, -Osize).

The reason that I updated the sil-func-extractor test is that I found a bug in
how we emit sib files, namely if you try to emit a sib file to stdout, the
llvm-bcanalyzer flags it as malformed. If I output the .sib into a file rather
than trying to use stdout, everything works.
2019-01-14 10:33:58 -08:00
Michael Gottesman
b2ffe1a4c1 Only run predictable mem opts in the guaranteed pipeline. 2019-01-11 13:55:16 -08:00
Erik Eckstein
130f1629bb SILOptimizer: add an earlier DeadStoreElimination pass to fix a phase ordering problem
GlobalOpt was blocked by a not eliminated dead store, introduced in an integer expression in the initializer.
2019-01-04 14:47:36 -08:00
Michael Gottesman
7d9ec8d742 [semantic-arc-opts] Make sure to only run this pass when optimization is enabled even though it is running during the mandatory passes (for now).
The idea is that eventually down the line we will split this pass into a
mandatory/performance parts once ownership SSA is eliminated after the
guaranteed passes run. For now though, just run this when optimization is
enabled.

This pass only runs on the stdlib/overlays so far so there shouldn't have been
any slow downs in non-stdlib -Onone builds.
2018-12-16 12:39:35 -08:00
Harlan Haskins
2e50a431b1 Merge pull request #20986 from harlanhaskins/clogged-pipes
[SILOptimizer] Stop optimization after serialization if only emitting a module
2018-12-06 15:49:11 -08:00
Harlan Haskins
b137928ff5 [SILOptimizer] Add flag to stop optimization after serialization 2018-12-04 16:44:01 -08:00
Adrian Prantl
ff63eaea6f Remove \brief commands from doxygen comments.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.

Patch produced by

      for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
2018-12-04 15:45:04 -08:00
Michael Gottesman
82c73b3793 [semantic-arc] Move semantic arc opts past definite initialization.
To be clear this only runs on the stdlibs/overlays since it is gated behind a
flag that is set in our cmake.

I can not move it past closure lifetime fixup since the transformation as
written does not express all of the necessary ownership constraints explicitly
in the IR by using addresses.
2018-11-30 11:54:21 -08:00
Joe Shajrawi
32da4f9f45 [Exclusivity] Sink may release release instructions out of access scopes
General case:
begin_access A
...
strong_release / release_value / destroy
end_access

The release instruction can be sunk below the end_access instruction,
This extends the lifetime of the released value, but, might allow us to
Mark the access scope as no nested conflict.
2018-10-31 15:48:08 -07:00
Joe Shajrawi
63b50f65a4 [Exclusivity] Remove dominated access checks with no nested conflict.
General case:

—
begin_access A (may or may not have no_nested_conflict)
load/store
end_access

apply // may have a scoped access that conflicts with A

begin_access A [no_nested_conflict]
load/store
end_access A
—

The second access scope does not need to be emitted.

NOTE: KeyPath access must be identified at the top-level, non-inlinable stdlib entry point.
As such, The sodlib entry pointed is annotated by a new @_semantics that is equivalent to inline(never)
2018-10-25 15:21:06 -07:00
Erik Eckstein
7b16f7f196 SILOptimizer: fix a phase ordering problem, which prevented array optimizations to work in some cases
Introduce an "early redundant load elimination", which does not optimize loads from arrays.
Later array optimizations, like ABCOpt, get confused if an array load in a loop is converted to a pattern with a phi argument.

This problem was introduced with accessors.

rdar://problem/44184763
2018-10-12 09:32:50 -07:00
Raj Barik
89d31be7a5 ExistentialSpecializer Pass (without SILCombine/ConcreteType Propagation) 2018-09-25 14:52:00 -07:00
Erik Eckstein
192431b830 SIL optimizer: remove the RemovePin optimization.
Not useful anymore after removing the pinning adressors
2018-08-23 12:47:56 -07:00
Joe Shajrawi
7281a76deb [AccessEnforcementOpts] Add mergeAccesses optimization 2018-08-09 16:15:25 -07:00
Jordan Rose
cefb0b62ba Replace old DEBUG macro with new LLVM_DEBUG
...using a sed command provided by Vedant:

$ find . -name \*.cpp -print -exec sed -i "" -E "s/ DEBUG\(/ LLVM_DEBUG(/g" {} \;
2018-07-20 14:37:26 -07:00
Andrew Trick
4f13dedc93 Add and enable an AccessEnforcementWMO pass.
Remove dynamic access checks for global variables and and class properties that
have been proven by earlier analysis never to conflict with nested access.

This only applies "-O -enforce-exclusivity=checked" builds. By default, it is
currently NFC.

These are the most important improvements:

RecursiveOwnedParameter                           -93.7%   **15.75x**
ReversedArray                                     -89.1%   **9.17x**
ReversedDictionary                                -81.0%   **5.28x**
ArrayInClass                                      -74.3%   **3.89x**
Ary3                                              -71.7%   **3.54x**
Random                                            -66.2%   **2.96x**
StringWalk                                        -63.5%   **2.74x**
LevenshteinDistance                               -55.4%   **2.24x**
Voronoi                                           -50.0%   **2.00x**
HashTest                                          -47.7%   **1.91x**
Richards                                          -46.7%   **1.88x**
NopDeinit                                         -44.8%   **1.81x**
Rectangles                                        -41.3%   **1.70x**
MultiFileTogether                                 -33.1%   **1.50x**
MultiFileSeparate                                 -32.8%   **1.49x**
SetIntersect_OfObjects                            -26.5%   **1.36x**
Ary2                                              -22.7%   **1.29x**
Prims                                             -21.9%   **1.28x**
PrimsSplit                                        -21.8%   **1.28x**
SetExclusiveOr_OfObjects                          -19.4%   **1.24x**
ObjectAllocation                                  -18.6%   **1.23x**
DropFirstAnySeqCRangeIterLazy                     -17.2%   **1.21x**
DropFirstAnySeqCRangeIter                         -17.2%   **1.21x**
Dictionary4OfObjects                              -16.5%   **1.20x**
SetUnion_OfObjects                                -15.3%   **1.18x**
DropWhileCountableRangeLazy                       -15.3%   **1.18x**
CharIndexing_[*]_Backwards                        -14.6%   **1.17x**
(all 17 variants of CharIndexing are -14%, 1.17x)
CharIteration_[*]_Backwards                       -14.3%   **1.17x**
(all 17 variants of CharIteration take 14%, 1.17x)
RGBHistogramOfObjects                             -14.2%   **1.17x**
DeltaBlue                                         -13.5%   **1.16x**
CharacterPropertiesPrecomputed                    -12.4%   **1.14x**
DictionarySwapOfObjects                           -9.9%    **1.11x**
ClassArrayGetter                                  -9.8%    **1.11x**
DictionaryGroupOfObjects                          -7.9%    **1.09x**
DictionaryRemoveOfObjects                         -7.2%    **1.08x**
Dictionary4OfObjectsLegacy                        -6.8%    **1.07x**
Havlak                                            -6.4%    **1.07x**
COWTree                                           -6.2%    **1.07x**
Radix2CooleyTukeyf                                -5.6%    **1.06x**
2018-06-29 17:56:56 -07:00
Joe Shajrawi
bc59eaad70 [LICM] Refactoring + Improvements + Exclusivity Support
Major refactoring + tuning of LICM. Includes:
Support for hosting more array semantic calls
Remove restrictions for sinking instructions
Add support for hoisting and sinking instruction pairs (begin and end accesses)

Testing with Exclusivity enabled on a couple of benchmarks shows:
ReversedArray 7x improvement
StringWalk 2.6x improvement
2018-06-26 13:26:37 -07:00
Erik Eckstein
bb5fe18300 Add/fix comments as a follow-up to the string constants optimization changes. 2018-06-07 16:22:04 -07:00
Erik Eckstein
ca04efbb44 SIL optimizer: add a few cleanup passes between loop unrolling and GlobalOpt.
Those are needed to fully optimize static String constants.
2018-06-07 13:43:34 -07:00
Michael Gottesman
2872389826 [definite-init] Split raw SIL instruction lowering out of DI into its own pass run after DI.
I am doing this so I can start writing DI tests without this lowering occuring.
There never was a real reason for this code to be in DI beyond convenience. Now
it just makes writing tests more difficult. To prevent any test delta, I changed
all current DI tests to run this pass after DI.
2018-05-22 18:18:22 -07:00
Andrew Trick
cb197d1e45 Enable AccessEnforcementOpts pass.
There are ~100 significant benchmark regressions (of ~350) with -O
-enforce-exclusivity=checked.

This optimization roughly cuts the overhead in half for almost all of those
regressions. These are the top 30 improvements with the optimization enabled.

XorShift....................................................2.83x
ReversedArray...............................................2.76x
RangeIterationSigned........................................2.67x
ExclusivityGlobal...........................................2.57x
Random......................................................2.44x
ReversedDictionary..........................................2.41x
GeekbenchGEMM...............................................2.35x
ArrayInClass................................................2.31x
StringWalk..................................................2.29x
Ary.........................................................2.25x
Ary3........................................................2.25x
Ary2........................................................2.21x
MultiFileTogether...........................................2.17x
MultiFileSeparate...........................................2.17x
RecursiveOwnedParameter.....................................2.14x
LevenshteinDistance.........................................2.04x
HashTest....................................................1.97x
Voronoi.....................................................1.94x
NopDeinit...................................................1.92x
Life........................................................1.89x
Richards....................................................1.84x
Rectangles..................................................1.74x
MatMul......................................................1.71x
LinkedList..................................................1.51x
GeekbenchFFT................................................1.47x
Xcbuild_OutputByteStreamPerfTests...........................1.39x
ObjectAllocation............................................1.33x
MapReduceLazyCollection.....................................1.30x
Prims.......................................................1.28x
CharIndexing_tweet_unicodeScalars_Backwards.................1.28x
2018-05-15 12:29:20 -07:00
Michael Gottesman
b05094fbed Merge pull request #15973 from gottesmm/pr-6a0bf75d9fc53d10ccd9de4251fb9b080f22a6b5
SILCleanup => IRGenPrepare.
2018-04-17 10:45:17 -07:00
Arnold Schwaighofer
7b472f983e Merge pull request #15927 from aschwaighofer/remove_postponed_cleanup
Remove SILGen's PostponedCleanup
2018-04-17 06:19:29 -07:00
Michael Gottesman
5baa90ca4c [irgen-prepare] Move SILCleanup to ./lib/SILOptimizer/Mandatory and rename it to IRGenPrepare.
I am going to be adding logic here to enable apple/swift#1550 to be completed.
The rename makes sense due to precedent from LLVM's codegen prepare and also
since I am going to be expanding what the pass is doing beyond just "cleaning
up". It is really a grab bag pass for performing simple transformations that we
do not want to pollute IRGen's logic with.

https://github.com/apple/swift/pull/15502

rdar://39335800
2018-04-17 00:07:16 -07:00
Slava Pestov
5bfd8e1da1 Merge pull request #15961 from slavapestov/re-run-predictable-mem-opts
SIL Optimizer: Re-run predictable memory optimizations in performance pipeline
2018-04-16 19:30:21 -07:00
Slava Pestov
3c62cc084b SIL Optimizer: Re-run predictable memory optimizations in performance pipeline 2018-04-16 16:20:43 -07:00
Slava Pestov
8c0f20987c SILOptimizer: Add 'mandatory SIL linker' pass
As a first step to getting mandatory inlining out of the business
of 'linking' (walking the function graph and deserializing all
referenced functions), add a new optimizer pass which links
everything in the mandatory pipeline.

For now this is mostly NFC, except it regresses an optimization
I made recently by linking in bodies of methods of deserialized
vtables eagerly. This will be addressed in upcoming patches.
2018-04-16 16:18:49 -07:00
Andrew Trick
39de8c7aed Revert "Mandatory SIL linker pass" 2018-04-14 16:41:34 -07:00
Slava Pestov
d520d030f5 SILOptimizer: Add 'mandatory SIL linker' pass
As a first step to getting mandatory inlining out of the business
of 'linking' (walking the function graph and deserializing all
referenced functions), add a new optimizer pass which links
everything in the mandatory pipeline.

For now this is mostly NFC, except it regresses an optimization
I made recently by linking in bodies of methods of deserialized
vtables eagerly. This will be addressed in upcoming patches.
2018-04-13 14:18:53 -07:00
Arnold Schwaighofer
e36655fddc SILGen: Remove PostponedCleanup in favor or the SIL pass that fixes
closure lifetimes.

SILGen will now unconditionally emit

  %cvt = convert_escape_to_noescape [guaranteed] %op

instructions. The mandatory ClosureLifetimeFixup pass ensures that %op's
lifetime spans %cvt's uses.

The code in DefiniteInitialization that handled a subset of cases is
removed.
2018-04-13 13:44:09 -07:00
Robert Widmann
5c7b79072b Detect and diagnose infinitely-recursive code
Add a new warning that detects when a function will call itself
recursively on all code paths.  Attempts to invoke functions like this
may cause unbounded stack growth at least or undefined behavior in the
worst cases.

The detection code is implemented as DFS for a reachable exit path in
a given SILFunction.
2018-02-26 16:27:32 -05:00
Andrew Trick
4734920222 Don't rerun diagnostic passes on deserialized SIL. 2018-02-09 09:55:47 -08:00
Erik Eckstein
80a734ab30 DeadObjectElimination: handle objects for which the destructor is de-virtualized and inlined
Also: add an additional DeadObjectElimination pass in the low level pipeline because
redundant load elimination (which runs before) can turn an object into a dead object.
2018-01-19 11:33:26 -08:00
Erik Eckstein
bf87035a36 GlobalOpt: Move the object outlining from GlobalOpt into a separate pass "ObjectOutliner"
We run GlobalOpt multiple times in the pass pipeline but in some cases object outlining shouldn't be done too early.
Having it done in a separate pass enables to run it independently from GlobalOpt.
2018-01-19 11:32:36 -08:00
eeckstein
b126b62256 Revert "Optimization changes to completely fold OptionSet literals" 2018-01-18 22:05:07 -08:00
Erik Eckstein
442171bca6 DeadObjectElimination: handle objects for which the destructor is de-virtualized and inlined
Also: add an additional DeadObjectElimination pass in the low level pipeline because
redundant load elimination (which runs before) can turn an object into a dead object.
2018-01-18 18:27:17 -08:00
Erik Eckstein
1f511ab846 GlobalOpt: Move the object outlining from GlobalOpt into a separate pass "ObjectOutliner"
We run GlobalOpt multiple times in the pass pipeline but in some cases object outlining shouldn't be done too early.
Having it done in a separate pass enables to run it independently from GlobalOpt.
2018-01-18 18:27:17 -08:00
Roman Levenstein
53754a7a69 Add a new simple utility optimization pass for serialization of SILModules 2017-10-13 23:19:19 -07:00
Roman Levenstein
6f3b326d12 IRGen should not emit bodies of public_external functions unless it is a transparent function.
Recent changes that eliminated the -sil-serialize-all mode and adding this check to IRGen allow us to get rid of ExternalFunctionDefinitionsElimination and ExternalDefsToDecls passes, which are not needed anymore.
2017-10-11 08:29:46 -07:00
Michael Gottesman
9e8a712dfa Merge pull request #11808 from gottesmm/pr-ca42038a7bd82a50a8617ca95957e9556d3e8467
[di] Update definite_initialization for ownership.
2017-09-07 17:25:09 -07:00
Michael Gottesman
4c087097f3 [di] Update definite_initialization for ownership.
rdar://31521023
2017-09-07 15:23:22 -07:00
Arnold Schwaighofer
b625d4da8a Osize: Add a SIL Outliner pass that outlines the bridging of objective c calls.
Implements outlining of bridged objective c property and method calls.

rdar://33387700
2017-09-06 08:37:37 -07:00
Michael Gottesman
aa0ac80c85 [ome] Move OME past MarkUninitializedFixup.
Originally, I was going to update DI at the same time for ownership and to fix
the multiple-projectbox di bug. After a bit messing with it, it is a difficult
change to land due to the size. Instead, I am going to do the ownership update
first and then loop back around and then fix the DI bug.

rdar://31521023
2017-08-30 20:39:15 -07:00
Roman Levenstein
4dbdeaa789 Add another round of retain sinking, because not all of possible retains are sunk in one round. 2017-08-22 12:45:22 -07:00
Roman Levenstein
e51626df6e Run the devirtualizer after the generic specializer
This is very beneficial because many class_method/witness_method instructions may get concrete types after specialization. Doing it this way improves compilation times.
2017-08-22 12:45:22 -07:00
Erik Eckstein
6c93798acc SILOptimizer: Add a new TempRValue optimization pass
This is a separate optimization that detects short-lived temporaries that can be eliminated.
This is necessary now that SILGen no longer performs basic RValue forwarding in some cases.

SR-5508: Performance regression in benchmarks caused by removing SILGen peephole for LoadExpr in +0 context
2017-08-05 17:23:51 -07:00
Roman Levenstein
c042058b82 Modify the optimization pipeline to better support custom array iterators
This patch is supposed to recover the performance regressions that would be introduced by yet to be merged PR #9145, which introduces custom, more efficient array iterators.

The crucial part of this patch is running loop unrolling also during the mid-level optimizations phase, because it may catch more loops with constant trip counts. To make trip counts constant, an additional run of constant propagation is helpful.
2017-08-01 17:04:36 -07:00
Andrew Trick
89985ebacd Use the pass's "tag" for command-line options.
A pass has an ID (C++ identifier), Tag (shell identifier),
and Name (human identifier).

Command line options that identify passes should obviously be compatibile with
with the pass' command line identifier. This is also what the user is used to
typing for the -debug-only option.
2017-07-06 14:10:23 -07:00