Commit Graph

2631 Commits

Author SHA1 Message Date
Kavon Farvardin
4a943d464d sil: provide ability to run CopyPropagation in -Onone
This does not enable it by default. Use either of the flags:

```
-enable-copy-propagation
-enable-copy-propagation=always
```

to enable it in -Onone. The previous frontend flag
`-enable-copy-propagation=true` has been renamed to
`-enable-copy-propagation=optimizing`, which is currently default.

rdar://107610971
2025-09-19 16:23:19 -07:00
Meghana Gupta
6665cd5d46 [NFC] hasGuaranteedAddressResults -> hasGuaranteedAddressResult and hasGuaranteedResults -> hasGuaranteedResult 2025-09-14 23:38:06 -07:00
Meghana Gupta
29f5dad72f Disable GenericSpecializer for borrow accessors in OSSA temporarily 2025-09-14 23:38:05 -07:00
nate-chandler
b3af244c46 Merge pull request #84022 from nate-chandler/rdar158139991
[Mem2Reg] Add end_lifetime for more trivial case non-trivial enums.
2025-09-01 06:56:26 -07:00
Jakub Florek
eae7864370 Merge pull request #83988 from MAJKFL/new-sil-licm-pass-copy
New SIL LICM pass
2025-09-01 10:28:17 +01:00
Nate Chandler
1c52364d28 [Mem2Reg] Complete single-block trivial enum cases
Add `end_lifetime` for values of non-trivial enum type which aren't
destroyed in non-dead-end blocks.
2025-08-29 15:47:10 -07:00
Nate Chandler
4b3588c9b9 [NFC] Mem2Reg: Delete this dead code.
Since the time that lifetimes in `alloc_stack [lexical]` began to be
represented after promotion by `move_value [lexical]`s, the
`endOwnedLexicalLifetimeBeforeInst` is just an assertion.  In the
future, lifetimes of values never destroyed that leak into dead end
blocks should be completed by OSSACompleteLifetime.  For now, just
delete this code.
2025-08-29 15:45:23 -07:00
Nate Chandler
69abf25f3a [NFC] Mem2Reg: Restructured conditional.
In preparation for adding other cases.  Also improved comments.
2025-08-29 15:45:19 -07:00
Nate Chandler
1f7432dedb [Mem2Reg] Don't skip write-only enum locations.
The lifetimes of the values stored into these locations may need to be
completed: if a trivial case of a non-trivial enum is written to the
location, its lifetime must be completed.

rdar://158139991
2025-08-29 15:45:14 -07:00
Nate Chandler
63a3c65147 [Mem2Reg] Fix isStorageValid.
In a few places, it wasn't getting set to false: `end_borrow`s of
`store_borrow`s and `load [take]`s.
2025-08-29 15:45:12 -07:00
Nate Chandler
09b1c3109d [NFC] Mem2Reg: Remove unused parameter. 2025-08-28 15:32:50 -07:00
nate-chandler
9fe43836f6 Merge pull request #83907 from nate-chandler/rdar158149082
[AllocBoxToStack] Don't destroy in dead-ends.
2025-08-28 13:36:28 -07:00
Jakub Florek
bc86fe5a38 Hoist ArrayCallKind to a separate file 2025-08-28 20:50:33 +01:00
Nate Chandler
1eafced6a2 [AllocBoxToStack] Don't destroy in dead-ends.
It is valid to leak a value on paths into dead-end regions.
Specifically, it is valid to leak an `alloc_box`.  Thus, "final
releases" in dead-end regions may not destroy the box and consequently
may not release its contents.  Therefore it's invalid to lower such final
releases to `dealloc_stack`s, let alone `destroy_addr`s.  The in-general
invalidity of that transformation results in miscompiling whenever a box
is leaked and its projected address is used after such final releases.

Fix this by not treating final releases as boundary markers of the
`alloc_box` and not lowering them to `destroy_addr`s and
`dealloc_stack`s.

rdar://158149082
2025-08-27 17:03:48 -07:00
Anthony Latsis
2bfe2bd587 SIL: Treat -1 as signed when using it to construct an "all bits set" llvm::APInt
This should enable us to revert
73c70ee338.
2025-08-27 15:22:30 +01:00
Erik Eckstein
bdea6063d7 Mem2Reg: Fix lifetime completion for enum case values.
Enum types may have incomplete lifetimes in address form for trivial case values. When promoted to value form, they will end up with incomplete ossa lifetimes.
Because we know that the incomplete enum values are trivial enum cases we complete their lifetimes with `end_lifetime` instead of `destroy_value`.
This is especially important for Embedded Swift where we are not allowed to insert destroys which were not there before.

Fixes a compiler crash in Embedded Swift caused by de-virtualizing such an inserted destroy and ending up with a non-specialized generic function.

rdar://158807801
2025-08-25 09:35:46 +02:00
Nate Chandler
5da38cb04b [NFC] OSSACanonicalizeGuaranteed: Renamed. 2025-08-18 09:45:27 -07:00
Nate Chandler
8f1d6616af [NFC] OSSACanonicalizeOwned: Renamed. 2025-08-18 09:45:21 -07:00
Nate Chandler
aa85694237 [NFC] OSSACompleteLifetime: Renamed. 2025-08-18 09:45:19 -07:00
Erik Eckstein
adc5d67a9a DeadObjectElimination: handle the builtin "prepareInitialization"
which allows e.g. eliminating dead `Atomic` values
2025-08-03 11:06:14 +02:00
Anthony Latsis
fec049e5e4 Address llvm::PointerUnion::{is,get} deprecations
These were deprecated in
https://github.com/llvm/llvm-project/pull/122623.
2025-07-29 18:37:48 +01:00
Slava Pestov
ee440f3c91 AST: Remove MakeAbstractConformanceForGenericType
While the intent behind this functor was noble, it has grown in complexity
considerably over the years, and it seems to be nothing but a source of
crashes in practice. I don't want to deal with it anymore, so I've decided
to just subsume all usages with LookUpConformanceInModule instead.
2025-07-15 16:34:11 -04:00
Meghana Gupta
b8fcd72f4d Disable retain and release sinking when rc root values are ~Copyable 2025-07-10 13:16:50 -07:00
nate-chandler
4c1dbd74c7 Merge pull request #82784 from nate-chandler/rdar153693915
[Mem2Reg] Don't promote proj(unchecked_addr_cast).
2025-07-04 02:02:16 -07:00
Nate Chandler
41877ae7b7 [Mem2Reg] Don't promote proj(unchecked_addr_cast).
In OSSA, the result of an `unchecked_bitwise_cast` must immediately be
copied or `unchecked_bitwise_cast`'d again.  In particular, it is not
permitted to borrow it.  For example, the result can't be borrowed for
the purpose of performinig additional projections (`struct_extract`,
`tuple_extract`) on the borrowed value.  Consequently, we cannot promote
an address if such a promotion would result in such a pattern.  That
means we can't promote an address `%addr` which is used like
`struct_element_addr(unchecked_addr_cast(%addr))` or
`tuple_element_addr(unchecked_addr_cast(%addr))`.  We can still promote
`unchecked_addr_cast(unchecked_addr_cast(%addr))`.

In ownership-lowered SIL, this doesn't apply and we can still promote
address with such projections.

rdar://153693915
2025-07-03 14:52:23 -07:00
nate-chandler
d2f4e84889 Merge pull request #82696 from nate-chandler/rdar154652254
[CSE] Fix combine of type_value.
2025-07-02 15:42:46 -07:00
Nate Chandler
429de09f87 [CSE] Fix combine of type_value.
The instruction has no operands but has a param type.  Hash and compare
the type and the type and the param type.

rdar://154652254
2025-07-01 14:26:21 -07:00
Erik Eckstein
606f7693d4 MandatoryPerformanceOptimizations: don't de-virtualize a generic class method call to specialized method
This results in wrong argument/return calling conventions.
First, the method call must be specialized. Only then the call can be de-virtualized.
Usually, it's done in this order anyway, because the `class_method` instruction is located before the `apply`.
But when inlining functions, the order (in the worklist) can be the other way round.

Fixes a compiler crash.
rdar://154631438
2025-07-01 09:44:47 +02:00
nate-chandler
991eb45432 Merge pull request #82557 from nate-chandler/rdar154407327
[DestroyAddrHoisting] Don't fold into read access.
2025-06-27 15:36:22 -07:00
Nate Chandler
2e2dee7a41 [DestroyAddrHoisting] Don't fold into read access.
Narrowly fix a long-standing bug where destroy_addrs would be hoisted
into read access scopes, leaving the scope as a read despite the fact
that it modifies memory.  This is a problem for utilities which expect
access scopes to provide correct summaries.  Do this by refusing to fold
into access scopes which are marked `[read]`.

In a follow-up, we can reenable this folding, promoting each access
scope to a modify.  Doing so requires checking that there are no access
scopes which overlap with any of the access scopes which would be
promoted to modify.

rdar://154407327
2025-06-26 17:40:03 -07:00
Erik Eckstein
6714a72256 Optimizer: re-implement and improve the AllocBoxToStack pass
This pass replaces `alloc_box` with `alloc_stack` if the box is not escaping.
The original implementation had some limitations. It could not handle cases of local functions which are called multiple times or even recursively, e.g.

```
public func foo() -> Int {
  var i = 1

  func localFunction() { i += 1 }

  localFunction()
  localFunction()
  return i
}

```

The new implementation (done in Swift) fixes this problem with a new algorithm.
It's not only more powerful, but also simpler: the new pass has less than half lines of code than the old pass.

The pass is invoked in the mandatory pipeline and later in the optimizer pipeline.
The new implementation provides a module-pass for the mandatory pipeline (whereas the "regular" pass is a function pass).
This is required because the mandatory pass needs to remove originals of specialized closures, which cannot be done from a function-pass.
In the old implementation this was done with a hack by adding a semantic attribute and deleting the function later in the pipeline.

I still kept the sources of the old pass for being able to bootstrap the compiler without a host compiler.

rdar://142756547
2025-06-20 08:15:04 +02:00
Stephen Canon
9259c3eec4 Add new interleave and deinterleave builtins (#81689)
Ideally we'd be able to use the llvm interleave2 and deinterleave2
intrinsics instead of adding these, but deinterleave currently isn't
available from Swift, and even if you hack that in, the codegen from
LLVM is worse than what shufflevector produces for both x86 and arm. So
in the medium-term we'll use these builtins, and hope to remove them in
favor of [de]interleave2 at some future point.
2025-06-12 12:01:53 -04:00
eeckstein
a33ff9879a Merge pull request #81969 from eeckstein/temp-lvalue-elimination
Optimizer: improve TempLValueOpt
2025-06-06 15:30:29 +02:00
Erik Eckstein
2b9b2d243c Optimizer: improve TempLValueOpt
* re-implement the pass in swift
* support alloc_stack liveranges which span over multiple basic blocks
* support `load`-`store` pairs, copying from the alloc_stack (in addition to `copy_addr`)

Those improvements help to reduce temporary stack allocations, especially for InlineArrays.

rdar://151606382
2025-06-05 06:45:18 +02:00
Doug Gregor
bc4cf1236b [SIL] Generalize CastingIsolatedConformances to CheckedCastInstOptions
We are going to need to add more flags to the various checked cast
instructions. Generalize the CastingIsolatedConformances bit in all of
these SIL instructions to an "options" struct that's easier to extend.

Precursor to rdar://152335805.
2025-06-04 17:12:28 -07:00
Nate Chandler
c41fd47f1f [DestroyAddrHoisting] Skip init_enum_data_addrs.
A destroy of an `init_enum_data_addr` is not equivalent to a destroy of
the whole enum's address.  Treat such destroys just like destroys of
`struct_element_addr`s are treated: by bailing out.

rdar://152431332
2025-06-03 15:32:42 -07:00
nate-chandler
dd75d2ed82 Merge pull request #81854 from nate-chandler/rdar152195094
[DestroyAddrHoisting] Don't destructure NE aggs.
2025-05-30 11:32:12 -07:00
Nate Chandler
f7ca26ce93 [NFC] SIL: This utility takes a func not a module.
In preparation to use the function in the implementation.
2025-05-29 15:36:15 -07:00
Arnold Schwaighofer
7ac551636b Merge pull request #81714 from aschwaighofer/se0460
SE-0460: Introduce @specialized attribute
2025-05-28 12:03:48 -07:00
Erik Eckstein
ed8922bc8e PerformanceInliner: always inline synthesized enum comparisons if one of the operands is a constant enum
If there is a "constant" enum argument to a synthesized enum comparison, we can always inline it, because most of it will be constant folded anyway.
This ensures the compiler is not creating terrible code for very simple enum comparisons, like
```
   if someEnum == .someCase {
      ...
   }
```

rdar://85677499
2025-05-27 12:11:03 +02:00
Arnold Schwaighofer
13ff5abdb8 Introduce @specialized attribute
Implements SE-0460 -- the non-underscored version of @specialized.

It allows to specify "internal" (not abi affecting) specializations.

rdar://150033316
2025-05-23 13:12:47 -07:00
Erik Eckstein
9052652651 add the prepareInitialization builtin.
It is like `zeroInitializer`, but does not actually initialize the memory.
It only indicates to mandatory passes that the memory is going to be initialized.
2025-05-20 20:46:33 +02:00
Erik Eckstein
3cbe94d7d1 inliner: tune the heuristic for constructors to be inlined into global initializer functions.
Inlining constructors into global initializers increase the changes that the global can be initialized statically.
2025-05-20 20:46:33 +02:00
Stephen Canon
3aa7b592b6 Implement Builtin.select binding llvm select instruction (#81598)
Not used (yet), but needed to implement SIMD.replacing(with:where:) idiomatically, and probably useful otherwise.
2025-05-20 13:30:59 -04:00
Erik Eckstein
c6b1e3e854 TempRValueElimination: re-implement the pass in swift
Beside cleaning up the source code, the motivation for the translation into Swift is to make it easier to improve the pass for some InlineArray specific optimizations (though I'm not sure, yet if we really need those).
Also, the new implementation doesn't contain the optimize-store-into-temp optimization anymore, because this is covered by redundant load elimination.
2025-05-06 13:08:09 +02:00
Kuba (Brecka) Mracek
3f61189657 Merge pull request #80914 from kubamracek/inliner-knobs
[SILOptimizer] Expose SIL inliner heuristics/constants as -Xllvm configurable knobs
2025-04-30 09:37:39 -07:00
Slava Pestov
3b83ac30a1 SILOptimizer: Clean up existential archetype remapping in CSE 2025-04-28 13:47:53 -04:00
nate-chandler
c2ed51ec63 Merge pull request #81059 from nate-chandler/rdar149896608
Revert "[DCE] Verify liveness of completed lifetimes."
2025-04-24 11:31:33 -07:00
Nate Chandler
fdd896e021 Revert "[DCE] Verify liveness of completed lifetimes."
This reverts commit 3ec9b269f5.

rdar://149896608
2025-04-23 16:59:26 -07:00
Evan Wilde
bca1378fdb SILOptimizer: Disable invalid passes in C++-only compiler
The SimplifyCFG and LoopRotate passes result in verification failures
when built in a compiler that is not built with Swift sources enabled.

Fixes: rdar://146357242
2025-04-21 12:46:01 -07:00