Commit Graph

134 Commits

Author SHA1 Message Date
Kuba Mracek
c7a5569c4f [embedded] Add support for ManagedBuffer to Embedded Swift
This makes ManagedBuffer available and usable in Embedded Swift, by:

- Removing an internal consistency check from ManagedBuffer that relies on metatypes.
- Making the .create() API transparent (to hoist the metatype to the callee).
- Adding a AllocRefDynamicInst simplification to convert `alloc_ref_dynamic` to `alloc_ref`, which removes a metatype use.
- Adding tests for the above.
2024-09-23 13:32:50 -07: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
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
Alexander Cyon
c18a24e499 [SwiftCompilerSources] Fix typos 2024-08-08 22:22:39 -07:00
Erik Eckstein
e3de408716 Simplification: remove builtin "destroyArray" with trivial element types 2024-08-01 13:38:39 +02:00
Erik Eckstein
f388361885 SimplifyBuiltin: fix a wrong constant folding of the is_same_metatype builtin for function types
We need to compare the not lowered types, because function types may differ in their original version but are equal in the lowered version, e.g.
```
  ((Int, Int) -> ())
  (((Int, Int)) -> ())
```

Fixes a miscompile
2024-07-29 17:33:42 +02:00
Erik Eckstein
04e0907ab0 SIL: rename Type.instanceTypeOfMetatype -> Type.loweredInstanceTypeOfMetatype
The same for SILType

It needs to be made clear that this is not the "original", but the lowered SIL type.

NFC
2024-07-29 17:33:36 +02:00
Ellie Shin
c3ded85c4f Update SILBridgedFunction APIs.
Add isAnySerialized() and canBeInlinedIntoCaller(SerializedKind).
2024-05-29 15:54:36 -07:00
Erik Eckstein
cd59a5e1d0 SimplifyCheckedCast: only simplify if source and destination address types match
Fixes a crash when creating a copy_addr with mismtaching types.
rdar://128195403
2024-05-17 15:07:40 +02:00
Erik Eckstein
af68435d90 Optimizer: support static initialization of global arrays
The buffer of global arrays could already be statically initialized.
The missing piece was the array itself, which is basically a reference to the array buffer.
For example:
```
var a = [1, 2, 3]
```
ends up in two statically initialized globals:
1. the array buffer, which contains the elements
2. the variable `a` which is a single reference (= pointer) of the array buffer

This optimization removes the need for lazy initialization of such variables.

rdar://127757554
2024-05-16 21:34:36 +02:00
Erik Eckstein
d9fc62e54a SimplifyKeyPath: remove dead keypath instructions also in non-OSSA
which means: handle of strong_release instructions
2024-05-16 09:32:08 +02:00
eeckstein
7bf193e764 SwiftCompilerSources: workaround a compiler crash on windows by disabling convert_function simplification 2024-04-29 10:52:25 +02:00
Kuba Mracek
33e89c0aad [embedded] Consider move_value/copy_value as removable for keypath optimization 2024-04-22 13:33:24 -07:00
nate-chandler
7bcedc91da Merge pull request #72992 from nate-chandler/simplify-tuple
[OnoneSimplify] Handle tuple(destructure_tuple()).
2024-04-12 09:09:36 -07:00
Nate Chandler
5004e93144 [OnoneSimplify] Handle tuple(destructure_tuple()). 2024-04-11 15:20:41 -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 (Brecka) Mracek
89cd62604b Merge pull request #72472 from kubamracek/embedded-keypaths
[embedded] Compile-time (literal) KeyPaths for Embedded Swift
2024-03-25 10:58:51 -07:00
Kuba Mracek
796554f55d [embedded] Respect ownership in SimplifyKeyPath, emit destroy_value instructions for keypath operands 2024-03-21 17:54:05 -07: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
Erik Eckstein
1d4054ca32 Optimizer: add simplification for checked_cast_addr_br instructions 2024-03-19 11:58:15 +01:00
Erik Eckstein
d34dec835c SimplifyBuiltin: use dynamic cast utilities in folding metatype comparisons 2024-03-19 11:58:15 +01:00
John McCall
0a282c044f Unify all of the task-creation builtins coming out of SILGen.
We've been building up this exponential explosion of task-creation
builtins because it's not currently possible to overload builtins.
As long as all of the operands are scalar, though, it's pretty easy
to peephole optional injections in IRGen, which means we can at
least just use a single builtin in SIL and then break it apart in
IRGen to decide which options to set.

I also eliminated the metadata argument, which can easily be recreated
from the substitutions.  I also added proper verification for the builtin,
which required (1) getting `@Sendable` right more consistently and (2)
updating a bunch of tests checking for things that are not actually
valid, like passing a function that returns an Int directly.
2024-03-06 22:21:12 -05:00
Meghana Gupta
7508a90af0 Enable destructure_struct/destructure_tuple simplifications in silcombine 2024-02-26 10:58:08 -08: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
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
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
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
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
dd9ce40ba1 add the allocVector builtin 2023-12-09 18:49:57 +01: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
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
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
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
6ff3b91fe4 SimplifyDestructure: support simplifying a destructure_struct with a copy_value in place
Replace
```
  %s = struct (%0, %1, %2)
  %c = copy_value %s           // can also be a chain of multiple copies
  (%3, %4, %5) = destructure_struct %c
```
with
```
  %c0 = copy_value %0
  %c1 = copy_value %1
  %c2 = copy_value %2
  %s = struct (%0, %1, %2)    // keep the original struct
```
and replace the results %3, %4, %5 with %c0, %c1, %c2, respectively.
2023-11-09 18:34:53 +01: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
Erik Eckstein
b6938475b9 Optimizer: add simplification for the convert_escape_to_noescape instruction
Including the required bridging stuff.

  %2 = thin_to_thick_function %1 to $() -> ()
  %3 = convert_escape_to_noescape %2 : $() -> () to $@noescape () -> ()
->
  %3 = thin_to_thick_function %1 to $@noescape () -> ()
2023-10-27 10:47:07 +02:00
Erik Eckstein
8b9f2a73d0 SimplifyApply: optimize thick calls where the callee is a thin_to_thick_function
```
   %2 = thin_to_thick_function %1
   %3 = apply %2(...) : @callee_guaranteed
 ->
   %2 = thin_to_thick_function %1
   %3 = apply %1(...): @convention(thin)
```
2023-10-27 10:47:07 +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
Kuba Mracek
5d8c55eacb [embedded] Initial Swift Concurrency for embedded Swift 2023-10-06 20:04:03 -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
Kuba Mracek
6a0bfa267d [embedded] Handle thick->thin metatype conversion on IsPOD builtin too 2023-09-20 15:49:13 -07:00
Kuba Mracek
51792d8a31 [embedded] Simplify optimizeArrayBuiltin, avoid needing a single use of the metatype inst 2023-09-15 10:40:19 -07:00
Kuba Mracek
350107e153 [embedded] Also cover DestroyArray builtin in embedded Swift mode 2023-09-15 06:56:11 -07:00
Kuba Mracek
50f6430a27 [embedded] Convert thick->thin metatypes on array builtins (copy, take, assign) in mandatory optimizations 2023-09-14 18:09:08 -07:00
Erik Eckstein
d9826f6043 SimplifyBranch: don't leave an empty block after merging two basic blocks
Although empty blocks are cleaned up at the end of every Simplification pass, it's not legal SIL to have empty blocks and subsequent simplification passes may crash because of this.

rdar://115169880
2023-09-11 14:11:46 +02:00