Commit Graph

152 Commits

Author SHA1 Message Date
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
Kshitij
74166a4ab6 [Autodiff] Moves bridging code accesses in closure-spec opt behind APIs
Addresses some other surfacial feedback as well.
2024-05-13 15:37:30 -07:00
Kshitij
ab751d57ab [Autodiff] Adds logic to generate specialized functions in the closure-spec pass 2024-05-13 11:16:42 -07:00
Kshitij
fd609846ae Makes the swift-based closure-spec pass an experimental frontend feature 2024-05-02 09:14:05 -07:00
Kshitij
c8375c06ae [Autodiff] Adds part of the closure-specialization optimization pass
Changes in this CR add part of the, Swift based, Autodiff specific
closure specialization optimization pass. The pass does not modify any
code nor does it even exist in any of the optimization pipelines. The
rationale for pushing this partially complete optimization pass upstream
is to keep up with the breaking changes in the underlying Swift based
compiler infrastructure.
2024-05-02 09:14:05 -07:00
Erik Eckstein
e14c1d1f62 SIL, Optimizer: update and handle borrowed-from instructions
Compute, update and handle borrowed-from instruction in various utilities and passes.
Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`.
Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
2024-04-10 13:38:10 +02:00
Kuba Mracek
b642d771be [embedded] Compile-time (literal) KeyPaths for Embedded Swift
Enable KeyPath/AnyKeyPath/PartialKeyPath/WritableKeyPath in Embedded Swift, but
for compile-time use only:

- Add keypath optimizations into the mandatory optimizations pipeline
- Allow keypath optimizations to look through begin_borrow, to make them work
  even in OSSA.
- If a use of a KeyPath doesn't optimize away, diagnose in PerformanceDiagnostics
- Make UnsafePointer.pointer(to:) transparent to allow the keypath optimization
  to happen in the callers of UnsafePointer.pointer(to:).
2024-03-20 15:35:46 -07:00
Meghana Gupta
7508a90af0 Enable destructure_struct/destructure_tuple simplifications in silcombine 2024-02-26 10:58:08 -08:00
Erik Eckstein
71fcae7fe8 SwiftCompilerSources: add the ability to implement SIL verification in swift 2024-02-22 07:12:10 +01:00
Meghana Gupta
75bd5b08dd Add LifetimeDependenceScopeFixup pass 2024-02-13 16:52:01 -08:00
Andrew Trick
8c092911ef Add the LifetimeDependenceInsertion pass.
Insert mark_dependence [nonescaping] markers at every lifetime
introducer that produces a lifetime-dependent value.
2024-02-12 09:57:14 -08:00
Erik Eckstein
86f23b089f SIL: add the [perf_constraint] flag in SILFunction
Specifies that the optimizer and IRGen must not add runtime calls which are not in the function originally.
This attribute is set for functions with performance constraints or functions which are called from functions with performance.
2024-02-05 12:26:30 +01:00
Erik Eckstein
7fb4fc0f36 MandatoryPerformanceOptimizations: fix the linkage of function-signature-specialized functions
We need to keep the original linkage because it would be illegal to call a shared not-serialized function from a serialized function.

Also, rename the API to create the specialized function.
2024-02-02 07:27:38 +01:00
Erik Eckstein
3b239b25f3 swift SIL: add Function thunk APIs
* `var thunkKind`
* `set(thunkKind:)`
2024-01-31 17:16:13 +01:00
Erik Eckstein
250e2680aa SwiftCompilerSources: add some module-level APIs
* `Context.lookupFunction`
* `ModulePassContext.loadFunction`
* `ModulePassContext.createSpecializedFunctionDeclaration`
* `ModulePassContext.moveFunctionBody`
* `ModulePassContext.mangle(withDeadArguments:)`
2024-01-31 17:16:13 +01:00
Erik Eckstein
fa0be3c10f SwiftCompilerSources: bridge some SIL APIs
* `TryApplyInst.specializationInfo`
* `BasicBlock.addFunctionArgument`
* `Function.appendNewBlock`
2024-01-31 17:16:12 +01:00
Erik Eckstein
7a62f15dae pass Context: verify that only the currently transformed function is modified 2024-01-31 17:16:12 +01:00
Andrew Trick
ddceffaf3b LifetimeDependenceDiagnostics pass
Initial diagnostic pass to enforce ~Escapable types.
2024-01-30 11:45:55 -08:00
Erik Eckstein
c89df9ec98 Mandatory optimizations: constant fold boolean literals before the DefiniteInitialization pass
Add a new mandatory BooleanLiteralFolding pass which constant folds conditional branches with boolean literals as operands.

```
  %1 = integer_literal -1
  %2 = apply %bool_init(%1)   // Bool.init(_builtinBooleanLiteral:)
  %3 = struct_extract %2, #Bool._value
  cond_br %3, bb1, bb2
```
->
```
  ...
  br bb1
```

This pass is intended to run before DefiniteInitialization, where mandatory inlining and constant folding didn't run, yet (which would perform this kind of optimization).
This optimization is required to let DefiniteInitialization handle boolean literals correctly.
For example in infinite loops:

```
   init() {
     while true {           // DI need to know that there is no loop exit from this while-statement
       if some_condition {
         member_field = init_value
         break
       }
     }
   }
```
2024-01-10 16:15:57 +01:00
Erik Eckstein
543fe31e8f SwiftCompilerSources: add Context.notifyDependency(onBodyOf:)
It notifies the pass manager that the optimization result of the current pass depends on the body (i.e. SIL instructions) of another function than the currently optimized one.
2024-01-10 09:34:00 +01:00
Erik Eckstein
bc99986cf9 SIL: add a dependency token operand to global_addr
Optionally, the dependency to the initialization of the global can be specified with a dependency token `depends_on <token>`.
This is usually a `builtin "once"` which calls the initializer for the global variable.
2024-01-10 09:33:58 +01:00
Andrew Trick
2128c21106 Migrate SwiftCompilerSources to FunctionConvention.
Layers:
- FunctionConvention: AST FunctionType: results, parameters
- ArgumentConventions: SIL function arguments
- ApplyOperandConventions: applied operands

The meaning of an integer index is determined by the collection
type. All the mapping between the various indices (results,
parameters, SIL argument, applied arguments) is restricted to the
collection type that owns that mapping. Remove the concept of a
"caller argument index".
2024-01-03 12:24:50 -08:00
Meghana Gupta
06f0d15c45 Use OSSALifetimeCompletion in PredictableMemOpt
The current algorithm to complete lifetimes is incorrect in a few cases.
Use OSSALifetimeCompletion instead.

Fixes rdar://119204768
2023-12-15 15:16:55 -08:00
Erik Eckstein
773d6b179d SwiftCompilerSources: remove the redundant BridgedPassContext.Feature enum
And replace it with the existing BridgedFeature
2023-12-13 13:28:17 +01:00
Erik Eckstein
ae278058e6 Add an experimental pass to lower allocateVector builtins
By default it lowers the builtin to an `alloc_vector` with a paired `dealloc_stack`.
If the builtin appears in the initializer of a global variable and the vector elements are initialized,
a statically initialized global is created where the initializer is a `vector` instruction.
2023-12-09 18:49:58 +01:00
Erik Eckstein
ca20ebc158 SwiftCompilerSources: add bridging to hasFeature 2023-12-09 18:49:57 +01:00
Erik Eckstein
9514b3450c SwiftCompilerSources: add some context APIs
* `Context.moduleIsSerialized`
* `Context.getBuiltinIntegerType`
* `Instruction.move(before:)`
2023-12-09 18:48:50 +01:00
Erik Eckstein
96e57d62f6 Optimizer: de-virtualize deinits of non-copyable types
In regular swift this is a nice optimization. In embedded swift it's a requirement, because the compiler needs to be able to specialize generic deinits of non-copyable types.
The new de-virtualization utilities are called from two places:

* from the new DeinitDevirtualizer pass. It replaces the old MoveOnlyDeinitDevirtualization, which is very basic and does not fulfill the needs for embedded swift.

* from MandatoryPerformanceOptimizations for embedded swift
2023-11-27 09:21:34 +01:00
Erik Eckstein
89aa1d3751 SwiftCompilerSources: reintroduce DiagnosticEngine 2023-11-27 09:21:34 +01:00
Erik Eckstein
b948ccf1ae SwiftCompilerSources: add more APIs to create new basic blocks
* rename `Context.splitBlock(at:)` -> `Context.splitBlock(before:)`
* add `Context.splitBlock(after:)`
* add `Context.createBlock(after:)`
2023-11-27 09:21:33 +01:00
Rintaro Ishizaki
47f18d492e [ASTGen] Move regex literal parsing from SwiftCompilerSources to ASTGen
ASTGen always builds with the host Swift compiler, without requiring
bootstrapping, and is enabled in more places. Move the regex literal
parsing logic there so it is enabled in more host environments, and
makes use of CMake's Swift support. Enable all of the regex literal
tests when ASTGen is built, to ensure everything is working.

Remove the "AST" and "Parse" Swift modules from SwiftCompilerSources,
because they are no longer needed.
2023-11-16 10:59:23 -08:00
Erik Eckstein
1f85ee1593 SwiftCompilerSources: add Context.erase(instructionIncludingAllUsers:) 2023-11-13 20:18:07 +01:00
Erik Eckstein
0509a056fb SwiftCompilerSources: improve APIs for UseList
Make filter APIs for UseList chainable by adding them to Sequence where Element == Operand

For example, it allows to write:
```
let singleUse = value.uses.ignoreDebugUses.ignoreUsers(ofType: EndAccessInst.self).singleUse
```

Also, add `UseList.getSingleUser(notOfType:)`
2023-11-13 20:18:07 +01:00
Erik Eckstein
eb597cb6d8 Swift SIL: add a few ownership APIs to ForwardingInstruction
* `canForwardGuaranteedValues`
* `canForwardOwnedValues`
* `setForwardingOwnership`
* `Operand.canAccept(ownership:)`
2023-11-13 20:18:07 +01:00
Hamish Knight
ce23252a3f [Basic] Improve some bridging APIs
Improve APIs for BridgedStringRef,
BridgedOwnedString, and BridgedSourceLoc.
2023-10-30 23:49:53 +00:00
Erik Eckstein
e718bfe8ed Optimizer: reimplement simplifications for copy_value and destroy_value in swift
So that they can run in the OnoneSimplification pass
2023-10-27 10:47:07 +02:00
Andrew Trick
e2333cdcfc SwiftCompilerSources: diagnostics bridging. 2023-10-12 14:33:37 -07:00
Erik Eckstein
2dbd6cc56b SwiftCompilerSources: rework bridging
Introduce two modes of bridging:
* inline mode: this is basically how it worked so far. Using full C++ interop which allows bridging functions to be inlined.
* pure mode: bridging functions are not inlined but compiled in a cpp file. This allows to reduce the C++ interop requirements to a minimum. No std/llvm/swift headers are imported.

This change requires a major refactoring of bridging sources. The implementation of bridging functions go to two separate files: SILBridgingImpl.h and OptimizerBridgingImpl.h.
Depending on the mode, those files are either included in the corresponding header files (inline mode), or included in the c++ file (pure mode).

The mode can be selected with the BRIDGING_MODE cmake variable. By default it is set to the inline mode (= existing behavior). The pure mode is only selected in certain configurations to work around C++ interop issues:
* In debug builds, to workaround a problem with LLDB's `po` command (rdar://115770255).
* On windows to workaround a build problem.
2023-10-09 09:52:52 +02:00
Nate Chandler
ae1f950315 [SwiftCompilerSources] Moved Test into Optimizer.
And changed the type of the context argument to FunctionPassContext.
2023-10-07 21:23:13 -07:00
Andrew Trick
2a604e2ab0 Merge pull request #68814 from atrick/blockarg
SwiftCompilerSources: Replace BlockArgument with Phi and TermResult.
2023-09-29 15:51:00 -07:00
Nate Chandler
dab8c146a6 [SwiftCompilerSources] Bridged in-IR testing.
Added the bridging types involved and the basic functionality.
2023-09-28 11:33:50 -07:00
Andrew Trick
a5d8aafb23 SwiftCompilerSources: Replace BlockArgument with Phi and TermResult.
All SILArgument types are "block arguments". There are three kinds:
1. Function arguments
2. Phis
3. Terminator results

In every situation where the source of the block argument matters, we
need to distinguish between these three. Accidentally failing to
handle one of the cases is an perpetual source of compiler
bugs. Attempting to handle both phis and terminator results uniformly
is *always* a bug, especially once OSSA has phi flags. Even when all
cases are handled correctly, the code that deals with data flow across
blocks is incomprehensible without giving each case a type. This
continues to be a massive waste of time literally every time I review
code that involves cross-block control flow.

Unfortunately, we don't have these C++ types yet (nothing big is
blocking that, it just wasn't done). That's manageable because we can
use wrapper types on the Swift side for now. Wrapper types don't
create any more complexity than protocols, but they do sacrifice some
usability in switch cases.

There is no reason for a BlockArgument type. First, a function
argument is a block argument just as much as any other. BlockArgument
provides no useful information beyond Argument. And it is nearly
always a mistake to care about whether a value is a function argument
and not care whether it is a phi or terminator result.
2023-09-27 18:47:46 -07:00
Kavon Farvardin
b688a1f4a1 [SILOpt] experimental async demotion pass
For chains of async functions where suspensions can be statically
proven to never be required, this pass removes all suspensions and
turns the functions into synchronous functions.

For example, this function does not actually require any suspensions,
once the correct executor is acquired upon initial entry:

```
func fib(_ n: Int) async -> Int {
  if n <= 1 { return n }
  return await fib(n-1) + fib(n-2)
}
```

So we can turn the above into this for better performance:

```
func fib() async -> Int {
  return fib_sync()
}

func fib_sync(_ n: Int) -> Int {
  if n <= 1 { return n }
  return fib(n-1) + fib(n-2)
}
```

while rewriting callers of `fib` to use the `sync` entry-point
when we can prove that it will be invoked on a compatible executor.

This pass is currently experimental and under development. Thus, it
is disabled by default and you must use
`-enable-experimental-async-demotion` to try it.
2023-09-21 12:21:02 -07:00
Kuba Mracek
efd8f08ea0 [embedded] Add notifyCallsChanged() to specializeClassMethodInst 2023-09-20 09:49:57 -07:00
Kuba Mracek
f0c8a59486 [embedded] Drop notifyInstructionsChanged() from specializeVTable() as we're not changing any instructions 2023-09-20 09:48:31 -07:00
Kuba Mracek
89df0426e0 [embedded] Specialize vtables when processing instructions, not bulk 2023-09-20 09:41:09 -07:00
Kuba Mracek
03f927eca1 [embedded] Perform VTable specialization iteratively as part of MandatoryPerformanceOptimizations 2023-09-20 09:41:09 -07:00