Commit Graph

198 Commits

Author SHA1 Message Date
Erik Eckstein
9aff288be4 Optimizer: re-implement the pointer_to_address SILCombine peephole optimizations in swift
Which consists of
* removing redundant `address_to_pointer`-`pointer_to_address` pairs
* optimize `index_raw_pointer` of a manually computed stride to `index_addr`
* remove or increase the alignment based on a "assumeAlignment" builtin

This is a big code cleanup but also has some functional differences for the `address_to_pointer`-`pointer_to_address` pair removal:

* It's not done if the resulting SIL would result in a (detectable) use-after-dealloc_stack memory lifetime failure.
* It's not done if `copy_value`s must be inserted or borrow-scopes must be extended to comply with ownership rules (this was the task of the OwnershipRAUWHelper).

Inserting copies is bad anyway.
Extending borrow-scopes would only be required if the original lifetime of the pointer extends a borrow scope - which shouldn't happen in save code. Therefore this is a very rare case which is not worth handling.
2024-12-21 08:28:22 +01:00
Erik Eckstein
1856d4e94c SIL: add APIs to set and get the alignment of a pointer_to_address instruction.
Also add a getter for the `isInvariant` property.
2024-12-21 08:28:21 +01:00
Ben Barham
8111fe9343 Merge pull request #78262 from bnbarham/skip-non-wmo-diag
[Embedded] Do not produce `cannot_specialize_class` for live issues
2024-12-20 10:40:07 -08:00
Ben Barham
a2fda1d9f3 [Embedded] Do not produce cannot_specialize_class for live issues
SourceKit explicitly disables WMO, silence the diagnostic in this case
(but leave it enabled for explicit non-WMO builds otherwise).
2024-12-19 15:31:41 -08:00
Hamish Knight
f728466273 [SwiftCompilerSources] Use interpolation instead of String(describing:)
`String(describing:)` does a bunch of dynamic casts
that can be pretty slow. Use interpolation instead,
which bypasses them.

For `swift-frontend`, this brings the time taken
for type-checking an empty file down from ~100ms
to ~70ms.

For `swift build`, this brings the time taken for
a null build down from ~600ms to ~450ms (the
larger delta is presumably due to the fact that
there's much more Swift code in `swift-package`).
2024-12-19 15:33:39 +00:00
Erik Eckstein
bf496aa4f6 Optimizer: add simplification for fix_lifetime
Canonicalize a `fix_lifetime` from an address to a `load` + `fix_lifetime`:
```
   %1 = alloc_stack $T
   ...
   fix_lifetime %1
```
->
```
   %1 = alloc_stack $T
   ...
   %2 = load %1
   fix_lifetime %2
```

This transformation is done for `alloc_stack` and `store_borrow` (which always has an `alloc_stack` operand).
The benefit of this transformation is that it enables other optimizations, like mem2reg.

This peephole optimization was already done in SILCombine, but it didn't handle store_borrow.
A good opportunity to make an instruction simplification out of it.

This is part of fixing regressions when enabling OSSA modules:
rdar://140229560
2024-12-13 12:06:20 +01:00
Erik Eckstein
6990a195a3 Optimizer: rename GuaranteedPhiUpdater -> PhiUpdater
Because it now has the replacePhisWithIncomingValues utility, which works for all kind of phis.
2024-12-12 09:09:11 +01:00
Erik Eckstein
3e35df0983 Simplification: run begin_borrow simplification in SILCombine 2024-12-11 12:32:34 +01:00
Erik Eckstein
6b38f2aab4 Optimizer: simplify load_borrow
* Remove dead `load_borrow` instructions (replaces the old peephole optimization in SILCombine)
* If the `load_borrow` is followed by a `copy_value`, combine both into a `load [copy]`
2024-12-11 12:32:33 +01:00
eeckstein
81c65758e3 Merge pull request #78059 from eeckstein/destroy-hoisting
Optimizer: add a new destroy-hoisting optimization
2024-12-11 06:18:05 +01:00
Erik Eckstein
5be781a9a0 Optimizer: add a new destroy-hoisting optimization
It hoists `destroy_value` instructions  without shrinking an object's lifetime.
This is done if it can be proved that another copy of a value (either in an SSA value or in memory) keeps the referenced object(s) alive until the original position of the `destroy_value`.
```
  %1 = copy_value %0
  ...
  last_use_of %0
  // other instructions
  destroy_value %0       // %1 is still alive here
```
->
```
  %1 = copy_value %0
  ...
  last_use_of %0
  destroy_value %0
  // other instructions
```

The benefit of this optimization is that it can enable copy-propagation by moving destroys above deinit barries and access scopes.
2024-12-10 16:28:11 +01:00
Erik Eckstein
dd78dc722b Optimizer: add an optimization to remove copy_value of a borrowed value.
It removes a `copy_value` where the source is a guaranteed value, if possible:

```
  %1 = copy_value %0   // %0 = a guaranteed value
  // uses of %1
  destroy_value %1     // borrow scope of %0 is still valid here
```
->
```
  // uses of %0
```

This optimization is very similar to the LoadCopyToBorrow optimization.
Therefore I merged both optimizations into a single file and renamed it to "CopyToBorrowOptimization".
2024-12-09 20:01:07 +01:00
Erik Eckstein
b4ba750481 Optimizer: move Context.erase(instructions:) from Outliner to Context 2024-12-09 19:59:05 +01:00
eeckstein
ca50c55eb5 Merge pull request #77806 from eeckstein/rle-of-array-elements
Optimizer: remove the ArrayElementPropagation optimization
2024-12-02 07:13:08 +01:00
Erik Eckstein
6a0b7d1f8c ObjectOutliner: create outlined arrays as let variables
This will allow load-simplification to replace a load of such an array.
2024-11-28 09:40:12 +01:00
Erik Eckstein
9279a2c0d6 Devirtualization: make sure to de-serialize the body of shared deinit functions.
Sometimes it can happen that a deinit function, which is imported from another module, has shared linkage.
In this case it is important to de-serialize the function body. Otherwise it would be illegal SIL.

Unfortunately I don't have a test case for this.
2024-11-27 18:05:36 +01:00
Erik Eckstein
99ef6f727d Optimizer: replace unchecked_enum_data simplification in SILCombine with the corresponding instruction simplification from SwiftCompilerSources
The optimization in SILCombine had a bug (which is already fixed in the instruction simplification).
2024-11-14 09:18:29 +01:00
Erik Eckstein
51e3e5ed80 Optimizer: rename BorrowArgumentsUpdater -> GuaranteedPhiUpdater
NFC
2024-11-12 09:26:59 +01:00
Erik Eckstein
f7d49a9680 SIL: add the Argument.set(reborrow:) and Argument.hasBorrowEndingUse APIs 2024-11-12 09:26:58 +01:00
Erik Eckstein
6b8c6a3c3b SIL: rename updateBorrowedFrom to updateBorrowArguments
NFC
2024-11-12 09:26:58 +01:00
Arnold Schwaighofer
787c996394 LargeTypesReg2Mem: Add a new heuristic that trys harder to keep large
values on the stack

This heuristic can be enabled by passing -Xfrontend
-enable-aggressive-reg2mem.

rdar://123916109
2024-10-31 13:22:06 -07:00
Erik Eckstein
b8026d74e6 Revert "Revert "Optimizer: improve the load-copy-to-borrow optimization and implement it in swift""
This reverts commit 0666c446ec.
2024-10-22 08:40:18 +02:00
Erik Eckstein
0666c446ec Revert "Optimizer: improve the load-copy-to-borrow optimization and implement it in swift"
This reverts commit eed8645610.
2024-10-18 10:36:06 +02:00
Erik Eckstein
e0533e6125 SIL: add an API to replace all entries of a VTable
* add `ModulePassContext.replaceVTableEntries()`
* add `ModulePassContext.notifyFunctionTablesChanged()`
2024-10-14 14:43:11 +02:00
Erik Eckstein
eed8645610 Optimizer: improve the load-copy-to-borrow optimization and implement it in swift
The optimization replaces a `load [copy]` with a `load_borrow` if possible.

```
  %1 = load [copy] %0
  // no writes to %0
  destroy_value %1
```
->
```
  %1 = load_borrow %0
  // no writes to %0
  end_borrow %1
```

The new implementation uses alias-analysis (instead of a simple def-use walk), which is much more powerful.

rdar://115315849
2024-10-11 09:41:37 +02:00
Erik Eckstein
52deb58251 Optimizer: add the FunctionPassContext.completeLifetime(of: Value) utility
Implemented by bridging the OSSALifetimeCompletion utility
2024-10-11 09:41:37 +02:00
Erik Eckstein
6ecb85a863 Swift SIL: add Operand.changeOwnership 2024-10-11 09:41:36 +02:00
Erik Eckstein
c97502374b Optimizer: add constant folding of classify_bridge_object
Constant fold `classify_bridge_object` to `(false, false)` if the operand is known to be a swift class.
2024-10-08 16:24:46 +02:00
Erik Eckstein
c05234e677 MandatoryPerformanceOptimizations: specialize witness_method instructions
In Embedded Swift, witness method lookup is done from specialized witness tables.
For this to work, the type of witness_method must be specialized as well.
Otherwise the method call would be done with wrong parameter conventions (indirect instead of direct).
2024-10-07 09:00:31 +02:00
Erik Eckstein
f7aaf5874e SwiftCompilerSources: add Context.getSpecializedConformance 2024-10-07 08:49:56 +02:00
Erik Eckstein
10782cf42b SwiftCompilerSources: introduce the AST module
As the optimizer uses more and more AST stuff, it's now time to create an "AST" module.
Initially it defines following AST datastructures:
* declarations: `Decl` + derived classes
* `Conformance`
* `SubstitutionMap`
* `Type` and `CanonicalType`

Some of those were already defined in the SIL module and are now moved to the AST module.
This change also cleans up a few things:
* proper definition of `NominalTypeDecl`-related APIs in `SIL.Type`
* rename `ProtocolConformance` to `Conformance`
* use `AST.Type`/`AST.CanonicalType` instead of `BridgedASTType` in SIL and the Optimizer
2024-10-02 07:10:29 +02:00
Erik Eckstein
701a7f7275 SwiftCompilerSources: don't make anything public in the Optimizer module
The Optimizer module is a leave module. No other modules depend on it. Therefore nothing must be public in this module.
2024-10-02 07:10:28 +02:00
Erik Eckstein
ec44600869 SwiftCompilerSources: workaround a host-compiler crash on Windows
Workaround for https://github.com/swiftlang/swift/issues/73253
2024-09-25 19:32:15 +02:00
Erik Eckstein
7ffd270008 embedded: move the VTableSpecializer pass into MandatoryPerformanceOptimizations
MandatoryPerformanceOptimizations already did most of the vtable specialization work.
So it makes sense to remove the VTableSpecializerPass completely and do everything in MandatoryPerformanceOptimizations.
2024-09-25 19:32:14 +02:00
Erik Eckstein
3775a3548e ModulePassContext: add some utility functions
* `specialize(function:)`
* `deserializeCallees(of:)`
* `createWitnessTable()`
* `createSpecializedVTable`
* `Function.set(isSerialized:)`
2024-09-25 19:32:08 +02:00
Erik Eckstein
46d3909471 SIL: improve VTable and WitnessTable
* add missing APIs
* bridge the entries as values and not as pointers
* add lookup functions in `Context`
* make WitnessTable.Entry.Kind enum cases lower case
2024-09-25 19:32:07 +02:00
Erik Eckstein
897ef2c5d4 SIL: add label to SubstitutionMap.init's bridged argument 2024-09-25 19:31:39 +02:00
Kuba (Brecka) Mracek
ecce6ac3a9 Merge pull request #76046 from kubamracek/fix-optimize-assert-config
Fix flipped 0/1 values in SimplifyBuiltin.optimizeAssertConfig
2024-09-18 14:18:19 -07:00
Kuba Mracek
4b164798ab Avoid return-less switch expression (doesn't compile on old Swift compilers) 2024-09-17 09:35:06 -07:00
Alejandro Alonso
b35ac50d3c Optimize TypeValueInst in Swift 2024-09-04 15:13:48 -07:00
Kuba Mracek
50fa83b237 Fix flipped 0/1 values in SimplifyBuiltin.optimizeAssertConfig 2024-08-22 14:46:02 -07:00
Erik Eckstein
c96b196ffa SwiftCompilerSources: bridge SILLinkage
Make SILLInkage available in SIL as `SIL.Linkage`.
Also, rename the misleading Function and GlobalVariable ABI `isAvailableExternally` to `isDefinedExternally`
2024-08-22 08:56:27 +02:00
Alexander Cyon
c18a24e499 [SwiftCompilerSources] Fix typos 2024-08-08 22:22:39 -07:00
Andrew Trick
d065a3e576 Merge pull request #75562 from atrick/nfc-lifedep
[nfc] LifetimeDiagnostics cleanup
2024-07-30 09:03:24 -07:00
Andrew Trick
103c59b273 [SwiftCompilerSources] Add assert to Builder.init(after:)
This API is incorrect for terminators. Assert that it isn't used
incorrectly. Later, we should rename it.
2024-07-29 23:44:02 -07:00
Erik Eckstein
f9b524b1cb AliasAnalysis: a complete overhaul of alias- and memory-behavior analysis
The main changes are:

*) Rewrite everything in swift. So far, parts of memory-behavior analysis were already implemented in swift. Now everything is done in swift and lives in `AliasAnalysis.swift`. This is a big code simplification.

*) Support many more instructions in the memory-behavior analysis - especially OSSA instructions, like `begin_borrow`, `end_borrow`, `store_borrow`, `load_borrow`. The computation of end_borrow effects is now much more precise. Also, partial_apply is now handled more precisely.

*) Simplify and reduce type-based alias analysis (TBAA). The complexity of the old TBAA comes from old days where the language and SIL didn't have strict aliasing and exclusivity rules (e.g. for inout arguments). Now TBAA is only needed for code using unsafe pointers. The new TBAA handles this - and not more. Note that TBAA for classes is already done in `AccessBase.isDistinct`.

*) Handle aliasing in `begin_access [modify]` scopes. We already supported truly immutable scopes like `begin_access [read]` or `ref_element_addr [immutable]`. For `begin_access [modify]` we know that there are no other reads or writes to the access-address within the scope.

*) Don't cache memory-behavior results. It turned out that the hit-miss rate was pretty bad (~ 1:7). The overhead of the cache lookup took as long as recomputing the memory behavior.
2024-07-29 17:33:46 +02:00
Emil Pedersen
531469f70e Merge pull request #73864 from Snowy1803/scs-builder-skip-meta
Skip meta instructions for Builder.init with automatic location
2024-05-30 09:50:48 -07:00
Emil Pedersen
d39d838c2b Skip meta instructions for Builder.init with automatic location 2024-05-24 16:01:11 -07:00
Kshitij
12faf79911 [Autodiff] Adds logic to rewrite call-sites using functions specialized by the closure-spec optimization 2024-05-21 12:02:28 -07:00
Erik Eckstein
cc78c8f094 Optimizer: add Context.canMakeStaticObjectReadOnly API 2024-05-16 21:34:35 +02:00