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.
Previously it was part of swiftBasic.
The demangler library does not depend on llvm (except some header-only utilities like StringRef). Putting it into its own library makes sure that no llvm stuff will be linked into clients which use the demangler library.
This change also contains other refactoring, like moving demangler code into different files. This makes it easier to remove the old demangler from the runtime library when we switch to the new symbol mangling.
Also in this commit: remove some unused API functions from the demangler Context.
fixes rdar://problem/30503344
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.
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
We also either remove or make private the addPass* functions on SILPassManager,
so the only way to execute passes via SILPassManager is by creating a
SILPassPipelinePlan. This beyond adding uniformity ensures that we always
resetAndRemoveTransformations properly after a pipeline is run.
When SILVerifyAll is enabled, individual functions are verified after
function passes are run upon them. This means that any functions created
by a function pass will not be verified after the pass runs. Thus
specialization errors that cause the verifier to trip will be
misattributed to the first pass that makes a change to the specialized
function. This is very misleading and increases triage time.
This change eliminates that problem by ensuring that when SILVerifyAll is
enabled, we always verify newly specialized functions as they are added to the
worklist.
rdar://28706158
An int is already constant and in general in LLVM style we do not create such
const ints. On the other hand, a constexpr I think expresses the intent slightly
better and gives the compiler more freedom anyways.
This adds the typedef and switches uses of NodeType * to NodeRef. This is in
preparation for the eventual NodeRef-ization of the GraphTraits in LLVM. NFC.
This re-instates commit de9622654d
The problem of the infinite loop should be fixed by the previous fix in FunctionSignatureOpts.
In addition this new commit implements a safety check to void such cases, even if buggy optimizations try to keep pushing new functions onto the work list.
Instead the pipeline is continued on the old function. This happens when a pass pushes a new, e.g. specialized function, on the function stack.
There is no need to repeat passes which already did run on a function.
It saves a little of compile time and I didn't see any significant impact on code size or performance.
It also simplifies the pass manager.
This ensures that when one is bisecting on pass counts, regardless of whether or
not one removes code in the test case, the pass counts being run remain the
same.
The option is supposed to be used as follows and takes a comma-seprataed list of SIL pass numbers as input:
-Xllvm -debug-only-pass-number=passnumber1[,passnumber2,..,passnumberN]
It enables the debug printing (i.e. prints inside DEBUG statements ) when one of the mentioned passes is being run.
This commit adds -sil-break-on-function and -sil-break-on-pass, both
-Xllvm options.
-sil-break-on-function stops function pass execution in the debugger
just prior to running each function pass on a particular function.
-sil-break-on-pass stops function pass execution in the debugger just
prior to running a particular pass on each function.
Used together, you can break just prior running a particular pass on a
particular function.
For example:
xcrun lldb -- $(/path/to/my/swiftc -c -O problem.swift -###) -Xllvm -sil-break-on-function=_TF7problem7problemFT_T_ -Xllvm -sil-break-on-pass='Simplify CFG'
Now when running under the debugger, we'll stop execution just prior
to each run of Simplify CFG on the function problem() in
problem.swift.
It's possible to construct programs where the optimization pass manager
will just continually execute, never making progress.
Add a check to the pass manager that only allows us to optimize a
limited number of functions with the function passes before moving on.
Unfortunately even the tiny test case that I have for this takes minutes
before we bail out with the limit I've set (which is not *that* much
bigger than the maximum that I saw in our build). I don't think it would
be prudent to add that test to the test suite, and I haven't managed to
come up with something that finishes in a more reasonable amount of time.
rdar://problem/21260480
Allow function passes to:
1. Add new functions, to be optimized before continuing with the current
function.
2. Restart the pipeline on the current function after the current pass
completes.
This makes it possible to fully optimize callees that are the result of
specialization prior to generating interprocedural information or making
inlining choices about these callees.
It also allows us to solve a phase-ordering issue we have with generic
specialization, devirtualization, and inlining, by rescheduling the
current function after changes happen in one of these passes as opposed
to running all of these as part of the inlining pass as happens today.
Currently this is NFC since we have no passes that use this
functionality.
Begin unbundling devirtualization, specialization, and inlining by
recreating the stand-alone generic specializer pass.
I've added a use of the pass to the pipeline, but this is almost
certainly not going to be the final location of where it runs. It's
primarily there to ensure this code gets exercised.
Since this is running prior to inlining, it changes the order that some
functions are specialized in, which means differences in the order of
output of one of the tests (one which similarly changed when
devirtualization, specialization, and inlining were bundled together).
Add interfaces and update the pass execution logic to allow function
passes to create new functions, or ask for functions to be optimized
prior to continuing.
Doing so results in the pass pipeline halting execution on the current
function, and continuing with newly added functions, returning to the
previous function after the newly added functions are fully optimized.
Make it a std::vector that reserves enough space based on the number of
functions in the initial bottom-up ordering.
This is the first step in making it possible for function passes to
notify the pass manager of new functions to process.