Introduce evaluator::SideEffect, the type of a request that performs
some operation solely to execute its side effects. Thankfully, there are
precious few requests that need to use this type in practice, but it's
good to call them out explicitly so we can get around to making them
behave much more functionally in the future.
Add ExecuteSILPipelineRequest which executes a
pipeline plan on a given SIL (and possibly IRGen)
module. This serves as a top-level request for
the SILOptimizer that we'll be able to hang
dependencies off.
Rather than registering individual IRGen passes
when we want to execute them, store function
pointers to all the pass constructors on the
ASTContext. This will make it easier to requestify
the execution of pass pipelines.
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
I believe that these were in SILInstruction for historic reasons. This is a
separate API on top of SILInstruction so it makes sense to pull it out into its
own header.
This helps speed up triaging failures caught by -sil-verify-all since this
allows one to trigger the -sil-verify-all verification around specific passes in
the pipeline rather than after every pass run. Was useful for me when tracking
down missing pass manager notification.
This is a verification routine that is only invoked in PassManager
destructors. I am going to use this to ensure that the
PassManagerVerifierAnalysis only runs at such points (even when sil-verify-all
is enabled) since it is too expensive to run otherwise.
NOTE: The default implementation of verifyFull in this commit is a no-op. I
wanted to have verify() be the default implementation of verifyFull(), but I do
not have more time to invest in this and it seems to catch /real/ bugs, albeit
bugs unrelated to pass manager notification verification. Instead I am going to
file an SR for someone to look at it since I need to move on from this work back
to semantic SIL. At least we will not have notification failure issues anymore
and thus a large correctness issue in the compiler has been fixed. Forward
progress!
rdar://42301529
* rename "Name" to "Description" in the pass definition, because it's not really the pass name, but the description of a pass
* remove the getName() from Transforms (which actually returned the description of a pass)
* in debug printing, print the pass ID and not the pass description. It makes it easier to correlate the debug output to the actual pass implementation.
* remove the iteration numbering in the pass manager, because we only run a single iteration anyway.
This commit is mostly refactoring.
*) Introduce a new OptimizationMode enum and use that in SILOptions and IRGenOptions
*) Allow the optimization mode also be specified for specific SILFunctions. This is not used in this commit yet and thus still a NFC.
Also, fixes a minor bug: we didn’t run mandatory IRGen passes for functions with @_semantics("optimize.sil.never")
In the crash output 'While running pass #x SILFunctionTransform "T" on SILFunction "@F".' we printed the previous function which was handled by the pass instead of the current one.
introduce a common superclass, SILNode.
This is in preparation for allowing instructions to have multiple
results. It is also a somewhat more elegant representation for
instructions that have zero results. Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction. Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.
A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.
Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
This patch implements collection and dumping of statistics about SILModules, SILFunctions and memory consumption during the execution of SIL optimization pipelines.
The following statistics can be collected:
* For SILFunctions: the number of SIL basic blocks, the number of SIL instructions, the number of SIL instructions of a specific kind, duration of a pass
* For SILModules: the number of SIL basic blocks, the number of SIL instructions, the number of SIL instructions of a specific kind, the number of SILFunctions, the amount of memory used by the compiler, duration of a pass
By default, any collection of statistics is disabled to avoid affecting compile times.
One can enable the collection of statistics and dumping of these statistics for the whole SILModule and/or for SILFunctions.
To reduce the amount of produced data, one can set thresholds in such a way that changes in the statistics are only reported if the delta between the old and the new values are at least X%. The deltas are computed as using the following formula:
Delta = (NewValue - OldValue) / OldValue
Thresholds provide a simple way to perform a simple filtering of the collected statistics during the compilation. But if there is a need for a more complex analysis of collected data (e.g. aggregation by a pipeline stage or by the type of a transformation), it is often better to dump as much data as possible into a file using e.g. -sil-stats-dump-all -sil-stats-modules -sil-stats-functions and then e.g. use the helper scripts to store the collected data into a database and then perform complex queries on it. Many kinds of analysis can be then formulated pretty easily as SQL queries.
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.
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.