A pass is skipped if no other pass changed the function since the previous run of the same pass.
Don't do this is if a pass depends on the function bodies of called functions, e.g. the inliner.
Other passes might change the callees, e.g. function signature opts, which makes it worth to run the inliner
again, even if the function itself didn't change.
Optimizations can rely on alias analysis to know that an in-argument (or parts of it) is not actually read.
We have to do the same in the verifier: if alias analysis says that an in-argument is not read, there is no need that the memory location is initialized.
Fixes a false verifier error.
rdar://106806899
* for testing: add the option `-simplify-instruction=<instruction-name>` to only run simplification passes for that instruction type
* on the swift side, add `Options.enableSimplification`
The pass to decide which functions should get stack protection was added in https://github.com/apple/swift/pull/60933, but was disabled by default.
This PR enables stack protection by default, but not the possibility to move arguments into temporaries - to keep the risk low.
Moving to temporaries can be enabled with the new frontend option `-enable-move-inout-stack-protector`.
rdar://93677524
This invalidation kind is used when a compute-effects pass changes function effects.
Also, let optimization passes which don't change effects only invalidate the `FunctionBody` and not `Everything`.
To add a module pass in `Passes.def` use the new `SWIFT_MODULE_PASS` macro.
On the swift side, create a `ModulePass`.
It’s run function receives a `ModulePassContext`, which provides access to all functions of a module.
But it doesn't provide any APIs to modify functions.
In order to modify a function, a module pass must use `ModulePassContext.transform(function:)`.
When enabling the option `-sil-opt-profile-repeat=<n>`, the optimizer runs passes n times and reports the total runtime at the end of the pass pipeline.
This is useful to profile a specific optimization pass with `sil-opt`.
For example, to profile the stack promotion pass:
```
sil-opt -stack-promotion -sil-opt-profile-repeat=10000 -o /dev/null test.sil
```
These sets are _much_ more efficient than `Set<Value>` and `Set<Instruction>` because they bridge to the efficient `NodeSet`.
Insertions/deletions are just bit operations.
* split the PassUtils.swift file into PassContext.swift and Passes.swift
* rework `Builder` bridging allowing more insertion point variations, e.g. inserting at the end of a block.
* add Builder.create functions for more instructions
* add `PassContext.splitBlock`
* move SIL modification functions from PassContext to extensions of the relevant types (e.g. instructions).
* rename `Location.bridgedLocation` -> `Location.bridged`
* C++: add a function `getDestructors(SILType type, bool isExactType)’: if the type is a final class or `isExactType` is true, then return the one and only destructor of that class.
* swift: add `getDestructor(ofExactType type: Type)` and `getIncompleteCallees`
* swift: remove `getDestructor` from the PassContext. The API of the `calleeAnalysis` can be used instead.
Allow other compilation units to refer to isFunctionSelectedForPrinting
by declaring it extern. Maybe at some point it might be nice to put
this into a header related to printing.
* Add the possibility to bisect the individual transforms of SILCombine and SimplifyCFG.
To do so, the `-sil-opt-pass-count` option now accepts the format `<n>.<m>`, where `m` is the sub-pass number.
The sub-pass number limits the number of individual transforms in SILCombine or SimplifyCFG.
* Add an option `-sil-print-last` to print the SIL of the currently optimized function before and after the last pass, which is specified with `-sil-opt-pass-count`.