Commit Graph

228 Commits

Author SHA1 Message Date
Erik Eckstein
92a17f8a01 Optimizer: extract the NamedReturnValueOptimization from CopyForwarding to a separate function pass
This allows to run the NamedReturnValueOptimization only late in the pipeline.
The optimization shouldn't be done before serialization, because it might prevent predictable memory optimizations in the caller after inlining.
2023-05-11 08:11:44 +02:00
Erik Eckstein
08e75f2c50 Swift SIL: add the Operand.set API
as a shortcut for `Instruction.setOperand`
2023-05-11 08:03:19 +02:00
Erik Eckstein
fa1ecff143 Swift Optimizer: rewrite the MemBehaviorDumper test pass in swift. 2023-05-09 08:25:09 +02:00
Erik Eckstein
960ca70def Swift Optimizer: add the module pass ReadOnlyGlobalVariables
It marks global `var` variables as `let` if they are never written.
2023-05-08 21:23:36 +02:00
Erik Eckstein
6d6b94e430 Swift Optimizer: add the InitializeStaticGlobals function pass
It converts a lazily initialized global to a statically initialized global variable.

When this pass runs on a global initializer `[global_init_once_fn]` it tries to create a static initializer for the initialized global.
```
  sil [global_init_once_fn] @globalinit {
    alloc_global @the_global
    %a = global_addr @the_global
    %i = some_const_initializer_insts
    store %i to %a
  }
```

The pass creates a static initializer for the global:
```
  sil_global @the_global = {
    %initval = some_const_initializer_insts
  }
```

and removes the allocation and store instructions from the initializer function:
```
  sil [global_init_once_fn] @globalinit {
    %a = global_addr @the_global
    %i = some_const_initializer_insts
  }
```

The initializer then becomes a side-effect free function which let's the builtin-simplification remove the `builtin "once"` which calls the initializer.
2023-05-08 21:23:36 +02:00
Erik Eckstein
2b117fd3ee Swift Optimizer: add APIs to copy from or to a global static initializer
* `Context.copyStaticInitializer(fromInitValue:, to:)`
* `FunctionPassContext.createStaticInitializer(for:,initValue:)`
2023-05-08 21:23:36 +02:00
Erik Eckstein
3e04b8681c make ModulePassContext conform to CustomStringConvertible
and let its description return a dump of the whole module.
This is useful for debugging
2023-05-08 21:23:36 +02:00
Erik Eckstein
e95c6425f2 Swift SIL: add some APIs for global variables 2023-05-08 21:23:36 +02:00
Erik Eckstein
9b51e69dac Swift Optimizer: constant fold builtins in the simplification passes 2023-05-08 21:23:36 +02:00
Erik Eckstein
010efc1ca6 Swift Bridging: use C++ instead of C bridging for the optimizer 2023-03-21 15:33:09 +01:00
Erik Eckstein
4445373808 Swift Bridging: use C++ instead of C bridging for BridgedInstruction 2023-03-21 15:33:09 +01:00
Erik Eckstein
c4f5bab5b7 Swift Bridging: use C++ instead of C bridging for BridgedBasicBlock 2023-03-21 15:33:09 +01:00
Erik Eckstein
ae7770d911 Swift Bridging: use C++ instead of C bridging for BridgedFunction 2023-03-21 15:33:09 +01:00
Erik Eckstein
598644fb92 Swift Bridging: use C++ instead of C bridging for the bridged witness table classes 2023-03-21 15:33:09 +01:00
Erik Eckstein
151f09769f Swift Bridging: use C++ instead of C bridging for BridgedVTable and BridgedVTableEntry 2023-03-21 15:33:09 +01:00
Erik Eckstein
eecea088e7 Swift Bridging: use C++ instead of C bridging for BridgedOperand and BridgedValue 2023-03-21 15:33:09 +01:00
Erik Eckstein
7eb2cb82e4 Swift Optimizer: add a pass to cleanup debug_step instructions
If a `debug_step` has the same debug location as a previous or succeeding instruction it is removed.
It's just important that there is at least one instruction for a certain debug location so that single stepping on that location will work.
2023-02-09 06:50:05 +01:00
Erik Eckstein
67ed6cfff8 Swift Optimizer: add Simplification passes
Those passes are a framework for instruction simplifications (which are not yet included in this commit).
Comparable to SILCombine
2023-02-09 06:49:58 +01:00
Erik Eckstein
3645becada PassManager: infrastructure to disable or enable a specific instruction simplification
* 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`
2023-01-16 19:00:09 +01:00
Erik Eckstein
230c93df30 SIL Optimizer: add some SIL modification APIs
* `MutatingContext.notifyInvalidatedStackNesting` and `MutatingContext.needFixStackNesting`
* `MutatingContext.tryDeleteDeadClosure`
* `MutatingContext.erase(block:)`
* `Undef.get`
* `BasicBlock.moveAllInstructions`
* `BasicBlock.eraseAllArguments`
* `BasicBlock.moveAllArguments`
* `TermInst.replaceBranchTarget`
2023-01-16 19:00:09 +01:00
Erik Eckstein
393d1a1488 SIL Builder: rename insert(at:) -> insert(before:)
It matches with `insert(after:)` and the intent should be clearer now
2023-01-16 15:11:34 +01:00
Erik Eckstein
cc68bd98c9 Swift Optimizer: rework pass context types and instruction passes
* split the `PassContext` into multiple protocols and structs: `Context`, `MutatingContext`, `FunctionPassContext` and `SimplifyContext`
* change how instruction passes work: implement the `simplify` function in conformance to `SILCombineSimplifyable`
* add a mechanism to add a callback for inserted instructions
2023-01-16 15:11:34 +01:00
Erik Eckstein
6c35258f83 Swift SIL: rename parent accessors to parentX, e.g. Instruction.parentBlock
It makes it easier to read
2023-01-16 15:11:34 +01:00
Erik Eckstein
beb46eb624 Use the new escape and side effects in alias analysis 2022-12-21 17:41:46 +01:00
Erik Eckstein
d4d1620f28 Swift SIL: rework Instruction and BasicBlock lists to support deleting instructions during iteration
Replace the generic `List` with the (non-generic) `InstructionList` and `BasicBlockList`.
The `InstructionList` is now a bit different than the `BasicBlockList` because it supports that instructions are deleted while iterating over the list.
Also add a test pass which tests instruction modification while iteration.
2022-12-12 19:08:57 +01:00
Erik Eckstein
ef302ce4ac SILOptimizer: enable stack protection by default
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
2022-11-11 17:14:08 +01:00
Erik Eckstein
ecbcacdecf SIL Analysis: Rename InvalidationKind::FunctionData to InvalidationKind::Effects
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`.
2022-10-20 09:20:28 +02:00
Nate Chandler
7ea336367d [NFC] Port isDeinitBarrier to Swift.
Added new C++-to-Swift callback for isDeinitBarrier.

And pass it CalleeAnalysis so it can depend on function effects.  For
now, the argument is ignored.  And, all callers just pass nullptr.

Promoted to API the mayAccessPointer component predicate of
isDeinitBarrier which needs to remain in C++.  That predicate will also
depends on function effects.  For that reason, it too is now passed a
BasicCalleeAnalysis and is moved into SILOptimizer.

Also, added more conservative versions of isDeinitBarrier and
maySynchronize which will never consider side-effects.
2022-10-18 21:23:22 -07:00
Erik Eckstein
741c6c38df Swift Optimizer: add the ComputeSideEffects pass.
Computes the side effects for a function, which consists of argument- and global effects.
This is similar to the ComputeEscapeEffects pass, just for side-effects.
2022-10-05 07:38:11 +02:00
Erik Eckstein
e1c65bd1d6 Swift Optimizer: rename the ComputeEffects pass to ComputeEscapeEffects 2022-10-05 07:38:11 +02:00
Erik Eckstein
81ac311c83 Swift Optimizer: add the DeadEndBlocks utility for finding dead-end blocks.
Dead-end blocks are blocks from which there is no path to the function exit (`return`, `throw` or unwind).
These are blocks which end with an unreachable instruction and blocks from which all paths end in "unreachable" blocks.
2022-10-05 07:37:41 +02:00
Erik Eckstein
4554939dc4 SwiftCompilerSources: consistently use assert instead of precondition
It's better to use the new assert implementation (defined in the "Basic" module) than Swift's `precondition`
2022-09-14 14:16:26 +02:00
Erik Eckstein
b2b44c0d83 Swift Optimizer: add the StackProtection optimization
It decides which functions need stack protection.

It sets the `needStackProtection` flags on all function which contain stack-allocated values for which an buffer overflow could occur.

Within safe swift code there shouldn't be any buffer overflows.
But if the address of a stack variable is converted to an unsafe pointer, it's not in the control of the compiler anymore.
This means, if there is any `address_to_pointer` instruction for an `alloc_stack`, such a function is marked for stack protection.
Another case is `index_addr` for non-tail allocated memory.
This pattern appears if pointer arithmetic is done with unsafe pointers in swift code.

If the origin of an unsafe pointer can only be tracked to a function argument, the pass tries to find the root stack allocation for such an argument by doing an inter-procedural analysis.
If this is not possible, the fallback is to move the argument into a temporary `alloc_stack` and do the unsafe pointer operations on the temporary.

rdar://93677524
2022-09-08 08:42:25 +02:00
Erik Eckstein
3e1ff0a5b7 IRGen: move the EnableStackProtector option from IRGenOptions to SILOptions.
... because we need it in the SIL pass pipeline, too.
Also, add Swift bridging for that option.
2022-09-08 08:42:24 +02:00
Erik Eckstein
fdca208335 SIL: add the SILFunction.needsStackProtection flag
Indicates that stack protectors are inserted into this function to detect stack related buffer overflows.
2022-09-08 08:37:21 +02:00
Erik Eckstein
9795f4b944 Swift Optimizer: add bridging for command line options 2022-09-02 07:11:49 +02:00
Erik Eckstein
f6e6b2ecf3 Swift SIL: add the possibility to pass a custom location to Builder initializers.
And add the static property `Location.autoGeneratedLocation`
2022-08-26 18:00:11 +02:00
Erik Eckstein
a12e33e9e9 Swift Optimizer: add the FunctionUses utility
Provides a list of instructions, which reference a function.

A function "use" is an instruction in another (or the same) function which references the function.
In most cases those are `function_ref` instructions, but can also be e.g. `keypath` instructions.

'FunctionUses' performs an analysis of all functions in the module and collects instructions which reference other functions.
This utility can be used to do inter-procedural caller-analysis.
2022-08-24 17:55:02 +02:00
Erik Eckstein
fbb694bcde Swift SIL: add bridging for witness and default witness tables 2022-08-24 17:55:02 +02:00
Erik Eckstein
7816513f0d Swift SIL: add bridging for vTables 2022-08-24 17:55:02 +02:00
Erik Eckstein
87f2f41d51 Swift Optimizer: add infrastructure for module passes.
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:)`.
2022-08-24 17:55:02 +02:00
Erik Eckstein
c2ef10661a Swift Optimizer: move function passes which are only used for unit testing to their own TestPasses directory. 2022-08-24 17:54:46 +02:00
Erik Eckstein
beebd5a920 PassManager: add a invalidation kind for non-body function data
E.g. used if function effects are changed. This tells the passmanager that something changed, but no SIL-specific analysis have to be invalidated.
2022-08-24 17:54:46 +02:00
Anxhelo Xhebraj
7a20bc3ea6 Swift Optimizer: add AccessUtils
This set of utilities introduce concepts such as `AccessBase`,
`AccessPath` and `AccessStoragePath` useful to analyze memory accesses.
2022-08-12 09:42:13 -07:00
Egor Zhdan
0e2d438c5b [cxx-interop][SwiftCompilerSources] Use llvm::StringRef instead of BridgedStringRef
rdar://83361000
2022-07-21 16:32:16 +01:00
eeckstein
b3d9b873a9 Merge pull request #58888 from eeckstein/objc-string-opt
Optimizer: add the ObjCBridgingOptimization to optimize ObjectiveC bridging operations.
2022-06-09 06:48:36 +02:00
Erik Eckstein
ec3d9dd9c7 Optimizer: add the ObjCBridgingOptimization to optimize ObjectiveC bridging operations.
Removes redundant ObjectiveC <-> Swift bridging calls.
Basically, if a value is bridged from ObjectiveC to Swift an then back to ObjectiveC again, then just re-use the original ObjectiveC value.

Also in this commit: add an additional DCE pass before ownership elimination. It can cleanup dead code which is left behind by the ObjCBridgingOptimization.

rdar://89987440
2022-06-08 22:51:57 +02:00
Rintaro Ishizaki
9f4ce612a2 [SwiftCompilerModules] Link lib_InternalSwiftSyntaxParser to libswift
To use _RegexParser from SwiftSyntax.

* Create 'libswiftCompilerModules_SwiftSyntax.a' which is a subset of
  'libswiftCompilerModules.a'
* Link 'lib_InternalSwiftSyntaxParser' to
  'libswiftCompilerModules_SwiftSyntax.a'
* Factor out swift runtime linking logic in CMake so that dynamic
  libraries can link to Swift runtime, in addition to executables
* Link 'lib_InternalSwiftSyntaxParser' to swift runtime
2022-06-02 12:23:03 -07:00
Erik Eckstein
3b43da9637 Swift Optimizer: improve ergonomics of Builder and PassContext
* 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`
2022-05-12 21:48:37 +02:00
Erik Eckstein
cad646b283 re-implement the StackPromotion pass in swift
It uses the new EscapeInfo.
2022-05-02 14:22:27 +02:00