Commit Graph

238 Commits

Author SHA1 Message Date
Erik Eckstein
50c23a1640 Optimizer: implement the SILCombine peephole optimizations for retain_value and release_value in Swift 2023-06-07 14:18:38 +02:00
Erik Eckstein
d02765fd54 Swift SIL: some new APIs and some refactoring 2023-05-25 16:28:41 +02:00
Erik Eckstein
4284dc10d0 Optimizer: implement the ObjectOutliner pass in Swift 2023-05-22 15:34:26 +02:00
Erik Eckstein
f3851f7503 Optimizer: implement load simplification in Swift 2023-05-22 15:34:26 +02:00
Erik Eckstein
585395b67c Swift Optimizer: add Context.lookupStdlibFunction 2023-05-22 15:34:26 +02:00
Erik Eckstein
38de5b1ab5 Swift SIL/Optimizer: implement cloning of static init values of globals in Swift
* add the StaticInitCloner utility
* remove bridging of `copyStaticInitializer` and `createStaticInitializer`
* add `Context.mangleOutlinedVariable` and `Context.createGlobalVariable`
2023-05-22 15:34:26 +02:00
Erik Eckstein
dc3cb18029 Swift Optimizer: add the MandatoryPerformanceOptimizations pass
As a replacement for the old MandatoryGenericSpecializer

The pass it not enabled yet in the pass pipeline
2023-05-11 08:11:44 +02:00
Erik Eckstein
b9169064c6 Swift SIL: add some APIs
* `Options.assertConfiguration`
* `Argument.isIndirectResult`
* in `Function`: `selfArgument`, `isTransparent`, `performanceConstraints` and `inlineStrategy`
* `BuiltinInst.substitutionMap`
* `SubstitutionMap.replacementTypes`
* `Type.canBeClass`
2023-05-11 08:11:44 +02:00
Erik Eckstein
82734b6ac2 Swift Optimizer: simplification for apply, try_apply, begin_apply and partial_apply
* move the apply of partial_apply transformation from simplify-apply to simplify-partial_apply
* delete dead partial_apply instructions
* devirtualize apply, try_apply and begin_apply
2023-05-11 08:11:44 +02:00
Erik Eckstein
6eff928989 Swift Optimizer: add a message to an assert 2023-05-11 08:11:44 +02:00
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