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.
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.
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.
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.
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.
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
This is very beneficial because many class_method/witness_method instructions may get concrete types after specialization. Doing it this way improves compilation times.
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
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.
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.
In raw SIL, access markers are unconditionally retained. In canonical SIL,
markers are still removed prior to optimization.
A new flag, -sil-optimized-access-markers, allows testing access markers in
optimized builds, but it is not yet fully supported.
This consists of just removing support from OME for ensuring that all uses of a
box go through the project_box that has as its user a mark_uninitialized. Since
the lowering of mark_uninitialized onto the relevant project_box is done by
MarkUninitializedFixup pass, I can just rip out the hacks from the OME!
rdar://31521023
I put in a simple fixup pass (MarkUninitializedFixup) for staging purposes. I
don't expect it to be in tree long. I just did not feel comfortable fixing up in
1 commit all of the passes up to DI.
rdar://31521023
At some point, pass definitions were heavily macro-ized. Pass
descriptive names were added in two places. This is not only redundant
but a source of confusion. You could waste a lot of time grepping for
the wrong string. I removed all the getName() overrides which, at
around 90 passes, was a fairly significant amount of code bloat.
Any pass that we want to be able to invoke by name from a tool
(sil-opt) or pipeline plan *should* have unique type name, enum value,
commend-line string, and name string. I removed a comment about the
various inliner passes that contradicted that.
Side note: We should be consistent with the policy that a pass is
identified by its type. We have a couple passes, LICM and CSE, which
currently violate that convention.
I am going to run it very early and use it to ensure that extra copies due to my
refactoring of SILGenPattern do not cause COW copies to be introduced.
For now, it does a very simple optimization, namely, it eliminates a copy_value,
with only a destroy_value user on a guaranteed parameter.
It is now disabled behind a flag.
if the argument is an array literal.
For example:
arr += [1, 2, 3]
is replaced by:
arr.append(1)
arr.append(2)
arr.append(3)
This gives considerable speedups up to 10x (for our micro-benchmarks which test this).
This is based on the work of @ben-ng, who implemented the first version of this optimization (thanks!).
This is important in case the inline restarts the pass pipeline.
In a sub-sequent invocation of the inlined it should receive a cleaned-up function so that it can make better estimations for further inlining.
As a compensation, reduce the caller-block limit of the inliner.
And add an overall block limit which is also taken into account for always-inline functions.
Hoist alloc_stack instructions of 'generic' or resilient type to the entry
block. At the same time also perform a very simple stack coloring analysis.
This does not use a true liveness-analysis yet but rather employs some simple
conservative checks to see whether the live ranges of two alloc_stacks might
interfere.
AllocStackHoisting is an IRGen SIL pass. This allows for using IRGen's type
lowering information. Furthermore, hoisting and merging the alloc_stack
instructions this late does not interfere with SIL optimizations because the
resulting SIL never gets serialized.
This pipeline is run as part of IRGen and has access to the IRGenModule.
Passes that run as part of this pipeline can query for the IRGenModule.
We will use it for the AllocStackHoisting pass. It wants to know if a type is of
non-fixed size.
To break the cyclic dependency between IRGen -> SILOptimizer -> IRGen that would
arise from the SILPassManager having to know about the createIRGENPASS()
function IRGen passes instead of exposing this function dynamically have to add
themselves to the pass manager.
This enables one to dump the various passpipelines in a yaml format. Other
pretty print formats can be added in the future as well if desired. Its intended
usage is to provide a source of pass pipeline information for external python
bug-reducing tools. By integrating this as a compiler-tool, we are guaranteed to
never have to update any of these tools in the face of passpipeline changes.
This commit adds the functionality, but does not change SILPassManager to use
it. The reason why I am doing this is so I can implement sil-opt pass bisecting
functionality in python using a tool that dumps the current pass pipelines
out. This will ensure that even in the face of changes to the pass pipelines,
everything should just work.