Commit Graph

231 Commits

Author SHA1 Message Date
Erik Eckstein
57b345035e SILPassManager: make -sil-print-function more convenient
Also match a function name if the specified function doesn't contain the $-prefix.
This is convenient when invoking the compiler from a shell, where a `$`-function name has to be single-quoted.
2023-11-30 14:24:36 +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
Hamish Knight
5d99fe63e9 Rename get() -> unbridged() on bridging wrappers 2023-10-31 11:06:39 +00:00
Hamish Knight
5853304da1 Remove BridgingUtils.h headers
These are now empty, and it seems like generally
we ought to prefer putting the bridging logic on
the BridgedXXX wrappers.
2023-10-30 23:50:00 +00:00
Erik Eckstein
3a0f635830 Move the optimizer bridging back to PassManager.cpp
Putting it into a separate source file OptimizerBridging.cpp caused linker errors for sourcekitd-test in sourcekit tests on linux.
2023-10-09 10:10:20 +02: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
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
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
Erik Eckstein
8223b3e210 MandatoryPerformanceOptimizations: fix some problems with inilning
* don't inline functions if it's not possible - by checking `SILInliner::canInlineApplySite`
* fix stack nesting after inlining a `begin_apply`
2023-08-10 15:01:47 +02:00
Kuba Mracek
ae6129cf69 Cache the IRGenModule even between SIL passes 2023-07-31 11:57:28 -07:00
Kuba Mracek
5dac59ce71 Move TargetConstantFolding pass to the simplification passes in Swift, enable using MemoryLayout's .size, .stride, .alignment fields in forced-const global initializers 2023-07-31 10:54:07 -07:00
Erik Eckstein
2e9de24e2a Swift Optimizer: add the SSAUpdater utility 2023-07-21 07:19:12 +02:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07: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
b707b5a595 Swift SIL: improve the Builder
* add new create-functions for instructions
* allow the Builder to build static initializer instructions for global variables
* some refactoring to simplify the implementation
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
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
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
260e68b102 Passmanager: fix a problem with skipping the inliner pass
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.
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
9b51e69dac Swift Optimizer: constant fold builtins in the simplification passes 2023-05-08 21:23:36 +02:00
Erik Eckstein
4b33b99ee2 MemoryLifetimeVerifier: be more precise with indirect function arguments.
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
2023-05-03 14:33:45 +02:00
Erik Eckstein
34972489cd PassManager: add an option -sil-min-pass-time to only print long running passes 2023-03-27 16:10:45 +02:00
Erik Eckstein
67299b4471 SIL bridging: work around an unresolved symbol linker error
Works around  problem https://github.com/apple/swift/issues/64502
2023-03-21 15:33:09 +01: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
a092ecb5c2 remove SILBridgingUtils.h 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
e469c16744 Swift Bridging: remove BridgedType and directly use the C++ SILType instead 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
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
swift-ci
ec2d7fc847 Merge pull request #62198 from nate-chandler/opaque-values/3/20221118
[AddressLowering] Don't end_borrow trivial args.
2022-11-29 17:07:24 -08:00
Erik Eckstein
096f02b3ef SILOptimizer: rename ANALYSIS macro to SIL_ANALYSIS
Avoids a conflict with clang's `ANALYSIS` macro.

Fixes a macro redefinition warning.
2022-11-21 19:22:15 +01:00
Nate Chandler
42aa21cc81 [NFC] Moved inlining printing to PassManager. 2022-11-18 16:29:51 -08:00
Erik Eckstein
1f4ac2b542 A few more deprecated iterator fixes
std::iterator is deprecated in C++17
2022-11-14 20:37:00 +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
Egor Zhdan
710443ae6f [cxx-interop][SwiftCompilerSources] Use swift::SubstitutionMap instead of BridgedSubstitutionMap
rdar://83361087
2022-09-15 14:18:31 +01: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
e090bc492a PassManager: cleanup the analysis-invalidation mechanism for swift passes
This fixes a bug with module passes.
2022-08-26 18:00:10 +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
de6e539a0a Swift Optimizer: make the set's insert functions return a Bool.
Returning true if the element was not contained in the set before inserting
2022-08-24 17:54:46 +02:00