Commit Graph

393 Commits

Author SHA1 Message Date
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
Meghana Gupta
5d2454f3e3 Merge pull request #68180 from meg-gupta/lowerb4inline
Lower OwnershipModelEliminator to just before inlining
2024-01-10 13:53:34 -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
fa3a959524 ObjectOutliner: support outlining of classes in global let variables
```
  let c = SomeClass()
```

is turned into

```
  private let outlinedVariable = SomeClass()  // statically initialized and allocated in the data section
  let c = outlinedVariable
```

rdar://111021230
rdar://115502043

Also, make the ObjectOutliner work for OSSA. Though, it currently doesn't run in the OSSA pipeline.
2024-01-10 09:34:01 +01:00
Erik Eckstein
cee4505840 SimplifyLoad: improve simplification of load of global variable
Inline the initialization code of a global initializer if the load is a global_addr with a builtin "once" dependency.
2024-01-10 09:34:01 +01:00
Erik Eckstein
3229749257 SwiftCompilerSources: move some private utilities of passes into OptUtils
* `var Function.initializedGlobal`
* `func getGlobalInitialization`

and add `var CollectionLikeSequence.singleElement`
2024-01-10 09:34:01 +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
nate-chandler
7365f9f36b Merge pull request #70774 from nate-chandler/nfc/20240108/1/deinit-barrier-component-predicates
[NFC] SIL: Clarified deinit barrier APIs.
2024-01-08 23:11:38 -08:00
Nate Chandler
82b7495bb1 [NFC] SIL: Clarified deinit barrier APIs.
An instruction is a deinit barrier whenever one of three component
predicates is true for it.  In the case of applies, it is true whenever
one of those three predicates is true for any of the instructions in any
of its callees; that fact is cached in the side-effect analysis of every
function.

If side-effect analysis or callee analysis is unavailable, in order to
define each of those three component predicates on a
`FullApplySite`/`EndApplyInst`/`AbortApplyInst`, it would be necessary
to define them to conservatively return true: it isn't known whether any
of the instructions in any of the callees were deinit barriers.

Refactored the two versions of the deinit barrier predicate (namely
`Instruction.isDeinitBarrier(_:) and
`swift::mayBeDeinitBarrierNotConsideringSideEffects`) to handle
`FullApplySite`/`EndApplyInst`/`AbortApplyInst`s specially first (to
look up the callees' side-effect and to conservatively bail,
respectively).  Asserted that the three component predicates are not
called with `FullApplySite`/`EndApplyInst`/`AbortApplyInst`s.  Callers
should instead use the `isDeinitBarrier` APIs.

An alternative would be to conservatively return true from the three
components.  That seems more likely to result in direct calls to these
member predicates, however, and at the moment at least there is no
reason for such calls to exist.  If some other caller besides the
deinit-barrier predicates needs to call this function, side-effect
analysis should be updated to cache these three properties separately at
that point.
2024-01-08 15:25:24 -08:00
Nate Chandler
77fd37be99 [NFC] SIL: Renamed maySynchronize.
Dropped the NotConsideringSideEffects suffix.
2024-01-08 13:35:20 -08:00
Meghana Gupta
df3468fd6c Follow up of #68180
Remove unnecessary cases
2024-01-05 13:20:52 -08:00
Meghana Gupta
9dbf7ccec2 Address review comments from #68150 2024-01-05 13:20:52 -08: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
Erik Eckstein
85be96354f SimplifyBuiltin: fix simplification of is_same_metatype with dynamic_self types
Dynamic self types are not the same as non-dynamic self types.

Fixes a miscompile with dynamic self type comparisons.

rdar://119943508
2024-01-02 09:23:42 +01:00
Erik Eckstein
16697882e8 SimplifyBeginBorrow: fix isDestroyed(after:)
The previous implementation just checked that a value's only uses besides the begin_borrow were destroys. That's insufficient to say the value is destroyed after the borrow (i.e. that all its destroys are dominated by the borrow). Add the relevant dominance check.

Fixes a compiler crash

rdar://119873930
2023-12-20 11:41:40 +01:00
Andrew Trick
7dc3d72483 Merge pull request #70485 from atrick/bridge-util
[NFC] Bridging and utilities for SwiftCompilerSources required by lifetime dependence utilities.
2023-12-19 13:07:45 -08:00
Andrew Trick
a396cc3c2a [SIL] InstructionRange API; exitBlocks 2023-12-19 02:05:16 -08:00
Andrew Trick
c1f0f06907 [SIL] Add FunctionConvention.swift
Bridge information about the AST function type that does not require a
SIL function body.

Support querying the function type's ResultInfo.
2023-12-18 09:43:18 -08:00
Andrew Trick
b637f06acd [SIL] Bridge findPointerEscape() and fix OnoneSimplifyable
Do not bridge the hasPointerEscape flag until it is implemented.
2023-12-18 09:16:55 -08:00
eeckstein
4eddc1d70b Merge pull request #70494 from eeckstein/instruction-simplifications
Add some instruction simplifications
2023-12-17 16:39:02 +01: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
691fa9e755 SimplifyBuiltin: add constant folding of null pointer checks against string literals
A pointer to a string literal is never null
2023-12-15 17:11:50 +01:00
Erik Eckstein
94b6e511ba Optimizer: add simplification for switch_enum
Replace
```
    %1 = enum $E, #someCase, %payload
    switch_enum %1, case #someCase: bb1, ...
  bb1(%payloadArgument):
```
->
```
  br bb1(%payload)
  bb1(%payloadArgument):
```
2023-12-15 17:11:49 +01:00
Erik Eckstein
11c74317a9 deinit-devirtualization: completely de-compose non-copyable destroys
Even if the destroyed value doesn't have a deinit.
This fixes a false alarm when a non-copyable value ends its lifetime in a function with performance annotations.

rdar://117002721
2023-12-13 20:03:02 +01: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
ded20d3c11 SwiftCompilerSources: add Value.isValidGlobalInitValue and FullApplySite.isSemanticCall
`Value.isValidGlobalInitValue` was privately used by the ObjectOutliner. Make it a generally usable utility.
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
dd9ce40ba1 add the allocVector builtin 2023-12-09 18:49:57 +01:00
Erik Eckstein
2a54f98c62 SimplificationPasses: add @discardableResult to runSimplification
NFC
2023-12-09 18:48:50 +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
Meghana Gupta
86b651330b Revert "Merge pull request #69807 from apple/revert-69450-uninarrayfix"
This reverts commit cabb5e109f, reversing
changes made to 09688abb02.
2023-12-06 08:29:50 -08:00
Erik Eckstein
c829d5bd77 SimplifyBeginCOWMutation: don't eliminate end_cow_mutation instructions with the [keep_unique] flag
This flag is important for following optimizations. Therefore such `end_cow_mutation` instructions must not be removed.
Also, keep the flag in a SILCombine transformation.

rdar://119178823
2023-12-06 08:59:58 +01:00
Meghana Gupta
956acc1560 Merge pull request #70243 from meg-gupta/enableedgecase
Handle `unchecked_ref_cast` in ObjectOutliner
2023-12-05 23:46:55 -08:00
Meghana Gupta
a228a8859a Handle unchecked_ref_cast in ObjectOutliner 2023-12-05 13:06:36 -08:00
Erik Eckstein
ec4c815506 SwiftCompilerSources: move WalkUtils and AccessUtils from the Optimizer module to the SIL module
Those utilities are conceptually part of the SIL definition.
2023-12-01 19:20:13 +01:00
Erik Eckstein
285c60d959 deinit-devirtualization: correctly handle drop_deinit for address types
Make it clear that drop_deinit cannot be used to prevent a deinit called from a destroy_addr.
This is more a refactoring and clarification than a bug fix, because a destroy_addr cannot have a drop_deinit as operand, anyway.
2023-11-30 14:33:02 +01:00
Erik Eckstein
3ffd4fe552 LetPropertyLowering: handle store_borrow and re-borrows
Handling of re-borrows is only done for completeness. Currently they don't occur for root-selfs at this stage in SIL.
2023-11-27 16:20:47 +01:00
Erik Eckstein
9eb5da4a0f SwiftCompilerSources: add the InstructionRange.insert(borrowScopeOf:) utility
Adds the instruction range of a borrow-scope by transitively visiting all (potential) re-borrows.
2023-11-27 16:20:47 +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
Erik Eckstein
fc534e1c28 SwiftCompilerSources: better APIs for handling resilient nominal types
* add `NominalTypeDecl.isResilient`

* make the return type of `Type.getNominalFields` optional and return nil in case the nominal type is resilient.
This forces users of this API to think about what to do in case the nominal type is resilient.
2023-11-27 09:21:33 +01:00
Erik Eckstein
186f1b39e4 InitializeStaticGlobals: don't merge stores to non-copyable types
A transformation must not create a `struct` instruction with a non-copyable type because this would apply that a (potential) deinit would be called for that struct.
2023-11-27 09:21:32 +01:00
Erik Eckstein
bdde6d3ba0 initializeStaticGlobalsPass: don't crash if there was a preceding error
In case of a preceding error, there is no guarantee that the SIL is valid. Therefore just bail in this case.

rdar://118521842
2023-11-17 16:14:36 +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
3bfabf6e8a SimplifyBeginBorrow: don't remove begin_borrow instructions which have the [point_escape] flag set. 2023-11-14 12:26:23 +01:00
Erik Eckstein
4f09d29afd Optimizer: add simplification for begin_borrow
Try to replace a begin_borrow with its owned operand.

This is either possible if the borrowed value (or a forwarded value if it) is copied:

```
  %1 = begin_borrow %0
  %2 = struct_extract %1     // a chain of forwarding instructions
  %3 = copy_value %1
  // ... uses of %3
  end_borrow %1
```
->
```
  %1 = copy_value %0
  %3 = destructure_struct %0 // owned version of the forwarding instructions
  // ... uses of %3
```

Or if the borrowed value is destroyed immediately after the borrow scope:

```
  %1 = begin_borrow %0
  %2 = struct_extract %1     // a chain of forwarding instructions
  // ... uses of %2
  end_borrow %1
  destroy_value %1           // the only other use of %0 beside begin_borrow
```
->
```
  %2 = destructure_struct %0 // owned version of the forwarding instructions
  // ... uses of %2
  destroy_value %2
```
2023-11-13 20:18:07 +01:00
Erik Eckstein
1f85ee1593 SwiftCompilerSources: add Context.erase(instructionIncludingAllUsers:) 2023-11-13 20:18:07 +01:00