Commit Graph

326 Commits

Author SHA1 Message Date
Tim Kientzle
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Kuba Mracek
b0f3da65eb [embedded] Skip EagerSpecializer on embedded Swift 2024-06-17 08:58:46 -07:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -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
4f73008177 PassPipeline: add a few utility passes in the low-level pipeline
To be able to remove lazy initialization of global read-only arrays
2024-05-16 21:34:36 +02:00
Erik Eckstein
af5037a531 PassPipeline: fix a wrong indentation 2024-05-16 21:34:36 +02:00
Kshitij
fd609846ae Makes the swift-based closure-spec pass an experimental frontend feature 2024-05-02 09:14:05 -07:00
Michael Gottesman
c4f7076baf [region-isolation] When RegionIsolation is enabled, delay the preconcurrency import not used diagnostic to the SIL pipeline.
The reason why I am doing this is that I am going to be adding support for
preconcurrency imports to TransferNonSendable. That implies that we can have
preconcurrency import suppression in the SIL pipeline and thus that emitting the
diagnostic in Sema is too early.

To do this, I introduced a new module pass called
DiagnoseUnnecessaryPreconcurrencyImports that runs after the SILFunction pass
TransferNonSendable. The reason why I use a module pass is to ensure that
TransferNonSendable has run on all functions before we attempt to emit these
diagnostics. Then in that pass, we iterate over all of the modules functions and
construct a uniqued array of SourceFiles for these functions. Then we iterate
over the uniqued SourceFiles and use the already constructed Sema machinery to
emit the diagnostic using the source files.

rdar://126928265
2024-04-23 12:42:43 -05:00
Artem Chikin
69fdc1356c Revert "Revert "Add mandatory SIL pass implementing '@_alwaysEmitConformanceMetadata' protocol attribute"" 2024-04-03 09:29:51 -07:00
Andrew Trick
6b776f57fb Move lifetime diagnostics after consume operator diagnostics.
This fixes bugs when ~Escapable types depended on values that are passed to 'consume'.

The consume operator diagnostics are broken when dependent values are
present. This sidesteps the problem for lifetime dependence. And we
generally want to diagnose lifetime dependence after all move-only
related diagnostics. That way, using a dependent value after consume
provides a more informative diagnostic about the dependent value and
its scope.
2024-03-27 09:13:24 -07:00
Andrew Trick
093aed967c Enable lifetime dependence diagnostics for Nonescapable types.
Adds -Xfrontend -disable-lifetime-dependence-diagnostics.

Removes -Xllvm -enable-lifetime-dependence-insertion

Removes -Xllvm -enable-lifetime-dependence-diagnostics
2024-03-07 13:40:25 -08:00
Michael Gottesman
3236bc26fa [region-isolation] Refactor out the stubify dead function if no longer used functionality from move only checker into its own pass and put it before region based isolation.
I am doing this since region based isolation hit the same issue that the move
checker did. So it makes sense to refactor the functionality into its own pass
and move it into a helper pass that runs before both.

It is very conservative and only stubifies functions that the specialization
passes explicitly mark as this being ok to be done to.
2024-03-01 13:11:07 -08:00
Andrew Trick
9515ab9ed8 Declare local cl::opt flags static 2024-02-25 10:22:06 -08:00
Nate Chandler
5a6873b98f [SILOptimizer] Remove DestroyHoisting pass.
It's no longer used.
2024-02-19 11:41:38 -08:00
Meghana Gupta
75bd5b08dd Add LifetimeDependenceScopeFixup pass 2024-02-13 16:52:01 -08:00
Andrew Trick
b4a5c5c990 Add a temporary flag: -enable-lifetime-dependence-insertion
To bootstrap lit tests until the stdlib builds with ~Escapable.
2024-02-12 20:03:38 -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
Andrew Trick
e0fda801d7 Merge pull request #71538 from atrick/fix-consuming
Lower move-only wrapper types earlier to disable the TrivialMoveOnlyTypeEliminator pass.
2024-02-10 18:49:28 -08:00
Andrew Trick
3caf508494 Disable the TrivialMoveOnlyTypeEliminator pass.
This fixes the `consuming` and `borrowing` keywords for some basic
cases. In particular, if a nontrivial struct contains a trivial 'let'
field, then this pass would result in invalid SIL types:

class C {}

struct BV {
  let p: UnsafeRawPointer
  let c: C
}

func getPointer(bv: consuming BV) -> UnsafeRawPointer {
  return bv.p
}

Ultimately, this pass makes sense, but there is something strange
about the way move-only-ness propagates into fields of aggregates
which needs to be fixed first. Until then, other features are blocked
on basic support for these keywords.

Fixes rdar://122701694 (`consuming` keyword causes verification error on invalid SIL types)
2024-02-10 12:50:33 -08:00
Michael Gottesman
e29e035ab8 [region-analysis] Add a pass that explicitly invalidates RegionAnalysis.
Over time I am going to be using RegionAnalysis for a series of passes that all
use that same information since I am worried about RegionAnalysis computation
time. With that being said, we want to make sure to eliminate the memory that
RegionAnalysis uses once this series of passes have completed. What this commit
does is create a pass that explicitly invalidates region analysis and explicitly
places it in the pass pipeline after the series of passes. This will ensure that
even if we add an additional pass, there is a strong "rattlesnake" signal to the
new code author that the code needs to be placed before the region analysis
invalidation and will prevent mistakes such as having to recompute the region
analysis in that later pass or the later pass forgeting to invalidate the
analysis.
2024-02-09 11:59:04 -08:00
Andrew Trick
5e312cf861 Disable lifetime dependence diagnostics by default.
For testing and experimentation, use:
-Xllvm enable-lifetime-dependence-diagnostics

This will be enabled by default once ~Escapable can be used without
building the standard library with the experimental NonescapableTypes
feature.

For now, we want to enable NonescapableTypes for bootstrapping without
forcing diagnostics to run all the time.
2024-01-31 19:05:45 -08:00
Andrew Trick
ddceffaf3b LifetimeDependenceDiagnostics pass
Initial diagnostic pass to enforce ~Escapable types.
2024-01-30 11:45:55 -08:00
eeckstein
6bf39cccd6 Merge pull request #70787 from eeckstein/boolean-literal-folding
Mandatory optimizations: constant fold boolean literals before the DefiniteInitialization pass
2024-01-11 11:39:44 +01: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
Meghana Gupta
79cc6547a1 Lower OwnershipModelEliminator to just before inlining 2024-01-05 13:20:52 -08:00
Kuba (Brecka) Mracek
b9f7acb8b5 Merge pull request #70309 from kubamracek/embedded-dfe
[embedded] Run DeadFunctionAndGlobalElimination after MandatoryPerformanceOptimizations
2023-12-12 10:21:11 -08:00
Kuba Mracek
df638b0e63 [embedded] Add explaining comment for running DeadFunctionAndGlobalElimination in embedded Swift 2023-12-11 08:48:13 -08:00
Kuba Mracek
bb1ba7c95c [embedded] Run DeadFunctionAndGlobalElimination after MandatoryPerformanceOptimizations 2023-12-09 22:39:55 -08: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
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
Michael Gottesman
d2b5bc33a1 [sil-optimizer] Add a small pass that runs after TransferNonSendable and eliminates tuple addr constructor.
This will limit the number of passes that need to be updated to handle
tuple_addr_constructor.
2023-11-06 15:47:15 -08:00
Michael Gottesman
0bad8f9b67 [region-isolation] Rename SendNonSendable.cpp -> TransferNonSendable.cpp. 2023-10-26 12:01:44 -07:00
Kuba Mracek
28a3d583c8 [embedded] Re-enable ReleaseDevirtualizer and teach it to look for specialized destructors 2023-09-29 16:28:59 -07:00
Kuba Mracek
b2e43f325a [embedded] Avoid a late VTableSpecializer pass in favor of disabling -O/-Osize passes that break embedded Swift assumptions 2023-09-28 10:33:00 -07:00
Kuba Mracek
16f6ca907f [embedded] Fix a compiler crash when using generic classes in -O/-Osize 2023-09-28 09:55:17 -07:00
Kuba Mracek
ff1d177a7c [embedded] Move the DFE pass to getOnonePassPipeline 2023-09-27 12:46:56 -07:00
Kuba Mracek
8b1aca9ff5 [embedded] Only run the late DeadFunctionElimination if embedded mode is on 2023-09-26 22:55:53 -07:00
Kuba Mracek
b049319487 [embedded] Remove unspecialized functions before running IRGen 2023-09-26 22:25:37 -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
Erik Eckstein
5bc036661c SIL optimizer: add the LetPropertyLowering pass
It lowers let property accesses of classes.
Lowering consists of two tasks:

* In class initializers, insert `end_init_let_ref` instructions at places where all let-fields are initialized.
  This strictly separates the life-range of the class into a region where let fields are still written during
  initialization and a region where let fields are truly immutable.

* Add the `[immutable]` flag to all `ref_element_addr` instructions (for let-fields) which are in the "immutable"
  region. This includes the region after an inserted `end_init_let_ref` in an class initializer, but also all
  let-field accesses in other functions than the initializer and the destructor.

This pass should run after DefiniteInitialization but before RawSILInstLowering (because it relies on `mark_uninitialized` still present in the class initializer).
Note that it's not mandatory to run this pass. If it doesn't run, SIL is still correct.

Simplified example (after lowering):

  bb0(%0 : @owned C):                           // = self of the class initializer
    %1 = mark_uninitialized %0
    %2 = ref_element_addr %1, #C.l              // a let-field
    store %init_value to %2
    %3 = end_init_let_ref %1                    // inserted by lowering
    %4 = ref_element_addr [immutable] %3, #C.l  // set to immutable by lowering
    %5 = load %4
2023-09-19 15:10:30 +02:00
Kuba Mracek
56085205d8 [embedded] specialize generic classes based on MetatypeInst too, fix lazy emit assert 2023-09-12 21:24:14 -07:00
Kuba Mracek
d0c2a4ccf8 [embedded] Initial support for generic classes in embedded Swift
- VTableSpecializer, a new pass that synthesizes a new vtable per each observed concrete type used
- Don't use full type metadata refs in embedded Swift
- Lazily emit specialized class metadata (LazySpecializedClassMetadata) in IRGen
- Don't emit regular class metadata for a class decl if it's generic (only emit the specialized metadata)
2023-09-12 09:44:54 -07:00
Kuba Mracek
25eb997a28 [embedded] Add basics of module serialization, importing and validation in embedded Swift.
- Add a flag to the serialized module (IsEmbeddedSwiftModule)
- Check on import that the mode matches (don't allow importing non-embedded module in embedded mode and vice versa)
- Drop TBD support, it's not expected to work in embedded Swift for now
- Drop auto-linking backdeploy libraries, it's not expected to backdeploy embedded Swift for now
- Drop prespecializations, not expected to work in embedded Swift for now
- Use CMO to serialize everything when emitting an embedded Swift module
- Change SILLinker to deserialize/import everything when importing an embedded Swift module
- Add an IR test for importing modules
- Add a deserialization validation test
2023-09-06 20:06:36 -07:00
Meghana Gupta
848466acbe Ensure no module transform is added in the function pipeline 2023-08-08 11:04:46 -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
jturcotti
aa9f1a3584 add an experimental feature DeferSendableChecking to defer the sendable checking of some sites. For now, only diagnostics corresponding to non-sendable arguments passed to calls with unsatisfied isolation are deferred. A SIL pass SendNonSendable is added to emit the deferred diagnostics, and ApplyExpr is appropriately enriched to make that deferral possible. 2023-07-03 09:52:11 -07:00
Erik Eckstein
55c8c433c0 SILOptimizer: add the StripObjectHeader optimization pass
It sets the `[bare]` attribute for `alloc_ref` and `global_value` instructions if their header (reference count and metatype) is not used throughout the lifetime of the object.
2023-06-29 06:57:05 +02:00
Erik Eckstein
0bf643d0c6 Optimizer: add an additional DeadObjectElimination at the end of the pipeline
The last dead-store-elimination pass can expose opportunities for dead object elimination.

rdar://110846405
2023-06-16 18:14:45 +02:00
Andrew Trick
62b0899500 [move-only] Disable move-only devirtualization.
It is not needed for correctness and hides most of the deinit related
optimizer bugs.
2023-06-06 09:17:53 -07:00
Andrew Trick
0bbd92a446 [move-only] Rename MoveOnlyDeinitInsertion
to MoveOnlyDeinitDevirtualization
2023-06-06 09:17:53 -07:00