Commit Graph

1683 Commits

Author SHA1 Message Date
Aidan Hall
90e12147e0 Merge pull request #85456 from aidan-hall/pack-opt-fix-weather-swb
PackSpecialization: Fix result & type parameter handling
2025-12-02 15:38:32 +00:00
Arnold Schwaighofer
36a3c6e611 Merge pull request #85644 from aschwaighofer/wip_embedded_exits_with_eriks_changes_v1
[embedded] Fix associated type conformances for specialized witness tables
2025-12-01 16:40:31 -08:00
Aidan Hall
96dca43eb9 Merge pull request #85244 from aidan-hall/fixing-debug-info-rebase
Retain more debug info in optimized builds
2025-12-01 20:49:40 +00:00
Michael Gottesman
24c69c674d Merge pull request #85604 from gottesmm/alloc_stack_non_nested
[irgen] Implement support for alloc_stack non_nested.
2025-12-01 09:38:06 -08:00
Arnold Schwaighofer
0c882d42ce Merge pull request #85625 from aschwaighofer/wip_embedded_cast_tuples
[embedded] Allow casting to tuples and tighten the check which existentials we support in embedded with existentials
2025-12-01 08:27:43 -08:00
eeckstein
9304ce951c Merge pull request #85707 from eeckstein/embedded-witness-method-specialization
embedded: change the function representation of directly called witness methods
2025-12-01 09:36:45 +01:00
eeckstein
46c69e40c1 Merge pull request #85533 from eeckstein/fix-access-simplification
SILOptimizer: don't remove empty conflicting access scopes
2025-12-01 09:35:48 +01:00
eeckstein
c8b5df5129 Merge pull request #85647 from eeckstein/fix-embedded-cpp-classes
embedded: don't try to specialize vtables of C++ imported reference-counted classes
2025-12-01 09:35:19 +01:00
Aidan Hall
a95d2979f9 [DebugInfo] Salvage more in -O builds
Specifically, improved debug info retention in:
* tryReplaceRedundantInstructionPair,
* splitAggregateLoad,
* TempLValueElimination,
* Mem2Reg,
* ConstantFolding.

The changes to Mem2Reg allow debug info to be retained in the case tested by
self-nostorage.swift in -O builds, so we have just enabled -O in that file
instead of writing a new test for it.

We attempted to add a case to salvageDebugInfo for unchecked_enum_data, but it
caused crashes in Linux CI that we were not able to reproduce.
2025-11-28 17:42:18 +00:00
Aidan Hall
97b7c35647 PackSpecialization: Fix result & type parameter handling
Refactor certain functions to make them simpler. and avoid calling
AST.Type.loweredType, which can fail. Instead, access the types of the
function's (SIL) arguments directly.

Correctly handle exploding packs that contain generic or opaque types by using
AST.Type.mapOutOfEnvironment().

@substituted types cause the shouldExplode predicate to be unreliable for AST
types, so restrict it to just SIL.Type. Add test cases for functions that have
@substituted types.

Re-enable PackSpecialization in FunctionPass pipeline.

Add a check to avoid emitting a destructure_tuple of the original function's
return tuple when it is void/().
2025-11-28 17:39:41 +00:00
Erik Eckstein
d7b75b6819 Optimizer: register explicit-copy instruction simplifications for SILCombine
Usually `explicit_copy_addr` and `explicit_copy_value` don't survive until the first SILCombine pass run anyway.
But if they do, the simplifications need to be registered, otherwise SILCombine will complain.
2025-11-27 19:40:31 +01:00
Erik Eckstein
64dd574bea embedded: change the function representation of directly called witness methods
This is needed in Embedded Swift because the `witness_method` convention requires passing the witness table to the callee.
However, the witness table is not necessarily available.
A witness table is only generated if an existential value of a protocol is created.

This is a rare situation because only witness thunks have `witness_method` convention and those thunks are created as "transparent" functions, which means they are always inlined (after de-virtualization of a witness method call).
However, inlining - even of transparent functions - can fail for some reasons.

This change adds a new EmbeddedWitnessCallSpecialization pass:
If a function with `witness_method` convention is directly called, the function is specialized by changing the convention to `method` and the call is replaced by a call to the specialized function:

```
  %1 = function_ref @callee : $@convention(witness_method: P) (@guaranteed C) -> ()
  %2 = apply %1(%0) : $@convention(witness_method: P) (@guaranteed C) -> ()
...
sil [ossa] @callee : $@convention(witness_method: P) (@guaranteed C) -> () {
  ...
}
```
->
```
  %1 = function_ref @$e6calleeTfr9 : $@convention(method) (@guaranteed C) -> ()
  %2 = apply %1(%0) : $@convention(method) (@guaranteed C) -> ()
...
// specialized callee
sil shared [ossa] @$e6calleeTfr9 : $@convention(method) (@guaranteed C) -> () {
  ...
}
```

Fixes a compiler crash
rdar://165184147
2025-11-26 16:23:47 +01:00
Erik Eckstein
78cb4ca197 Optimizer: extract replacing an apply into a utility function ApplySite.replace(withCallTo:) 2025-11-26 16:23:47 +01:00
Erik Eckstein
17ca4d9787 Optimizer: add FunctionPassContext.mangle(withChangedRepresentation original: Function) 2025-11-26 16:23:47 +01:00
Erik Eckstein
ab2345a2ed FunctionPassContext: support setting arbitrary function type representations when creating specialized functions 2025-11-26 16:23:47 +01:00
Erik Eckstein
4920ace11e AST: add enum FunctionTypeRepresentation and TypeProperties.functionTypeRepresentation 2025-11-26 16:23:46 +01:00
Erik Eckstein
9a124742b0 Optimizer: add the DeadAccessScopeElimination optimization pass
It eliminates dead access scopes if they are not conflicting with other scopes.

Removes:
```
  %2 = begin_access [modify] [dynamic] %1
  ...                                       // no uses of %2
  end_access %2
```

However, dead _conflicting_ access scopes are not removed.
If a conflicting scope becomes dead because an optimization e.g. removed a load, it is still important to get an access violation at runtime.
Even a propagated value of a redundant load from a conflicting scope is undefined.

```
  %2 = begin_access [modify] [dynamic] %1
  store %x to %2
  %3 = begin_access [read] [dynamic] %1    // conflicting with %2!
  %y = load %3
  end_access %3
  end_access %2
  use(%y)
```
After redundant-load-elimination:
```
  %2 = begin_access [modify] [dynamic] %1
  store %x to %2
  %3 = begin_access [read] [dynamic] %1    // now dead, but still conflicting with %2
  end_access %3
  end_access %2
  use(%x)                                  // propagated from the store, but undefined here!
```
In this case the scope `%3` is not removed because it's important to get an access violation error at runtime before the undefined value `%x` is used.

This pass considers potential conflicting access scopes in called functions.
But it does not consider potential conflicting access in callers (because it can't!).
However, optimizations, like redundant-load-elimination, can only do such transformations if the outer access scope is within the function, e.g.

```
bb0(%0 : $*T):     // an inout from a conflicting scope in the caller
  store %x to %0
  %3 = begin_access [read] [dynamic] %1
  %y = load %3     // cannot be propagated because it cannot be proved that %1 is the same address as %0
  end_access %3
```

All those checks are only done for dynamic access scopes, because they matter for runtime exclusivity checking.
Dead static scopes are removed unconditionally.
2025-11-24 14:49:45 +01:00
Erik Eckstein
d2dc3de7f4 SIL: add the WorklistWithPayload utility
It is like `Worklist` but can store an additional arbitrary payload per element.
2025-11-24 14:49:45 +01:00
Erik Eckstein
7d79179818 SIL: add the IterableSet utility
It is a set which supports iterating over its elements.
2025-11-24 14:49:45 +01:00
Erik Eckstein
2c5d8237bc SIL: add var Instruction.mayCallFunction
It checks if arbitrary functions may be called by an instruction.
This can be either directly, e.g. by an `apply` instruction, or indirectly by destroying a value which might have a deinitializer which can call functions.
2025-11-24 14:49:45 +01:00
Arnold Schwaighofer
b9f6454386 [embedded] Add support for storing/casting function types 2025-11-21 14:55:32 -08:00
Michael Gottesman
c876c1ee88 [sil-verifier] Split SILVerifier verificationFailure into separate functions for Instructions, Arguments, and add a variant for Values.
This also required me to change how we handled which instruction/argument we
emit an error about in the verifier. Previously we were using two global
variables that we made nullptr to control which thing we emitted an error about.
This was unnecessary. Instead I added a little helper struct that internally
controls what we will emit an error about and an external "guard" RAII struct
that makes sure we push/pop the instruction/argument we are erroring upon
correctly.
2025-11-21 11:21:15 -08:00
Erik Eckstein
fa3bfa3b10 embedded: don't try to specialize vtables of C++ imported reference-counted classes
Fixes a false compiler error

rdar://165209061
2025-11-21 16:33:49 +01:00
Erik Eckstein
a371aecb95 AST: add var ClassDecl.isForeign 2025-11-21 16:33:06 +01:00
Arnold Schwaighofer
1b6da50ed9 Merge pull request #85602 from aschwaighofer/wip_embedded_exit_cast
[embedded] Implement swift_dynamicCast suport for casts from existential to concrete type
2025-11-20 21:01:41 -05:00
Erik Eckstein
4191543855 MandatoryPerformanceOptimizations: specialize witness tables for general existentials 2025-11-20 10:56:22 -08:00
Erik Eckstein
1486d009b0 AST: add var ProtocolDecl.isMarkerProtocol 2025-11-20 10:56:05 -08:00
Erik Eckstein
b218d9ab5c SIL: add some APIs for InitExistentialAddrInst
* `var conformances: ConformanceArray`
* `var formalConcreteType: CanonicalType`
2025-11-20 10:55:47 -08:00
Erik Eckstein
60a28cd570 embedded: don't re-abstract witness method calls for existentials
Don't convert indirect to direct arguments. This is needed to support general existentials in embedded swift.
2025-11-20 10:54:37 -08:00
Arnold Schwaighofer
8beaad60bd [embedded] Allow casting to tuples 2025-11-20 10:03:39 -08:00
Arnold Schwaighofer
0197784625 [embedded] Tighten the check which existentials we support in embedded with existentials 2025-11-20 07:55:51 -08:00
Aidan Hall
2c9013b2a4 Merge pull request #84648 from swiftlang/users/kovdan01/ast-bridges-for-autodiff-closure-spec
Bridging: Implement bridges required for ongoing AutoDiff changes
2025-11-20 14:45:28 +00:00
Arnold Schwaighofer
3cff05d540 [embedded] Implement swift_dynamicCast suport for casts from existential to concrete type 2025-11-19 14:41:37 -08:00
Erik Eckstein
50c299e0bf LoopInvariantCodeMotion: don't reuse existing instructions in the loop pre-header
This is wrong for hoisted load instructions because we don't check for aliasing in the pre-header.
And for side-effect-free instructions it's not really necessary, because that can cleanup CSE afterwards.

Fixes a miscompile
rdar://164034503
2025-11-18 21:23:13 +01:00
Daniil Kovalev
a172134162 Address review comments 2025-11-18 01:46:49 +03:00
Daniil Kovalev
c12819f881 Address review comments 2025-11-17 14:13:09 +03:00
Daniil Kovalev
c1f4bcfd98 Merge branch 'main' into users/kovdan01/ast-bridges-for-autodiff-closure-spec 2025-11-17 10:22:24 +03:00
Yuta Saito
8748213d52 Merge pull request #85524 from kateinoigakukun/yt/fix-non-reg2mem-rle-crash 2025-11-16 23:10:20 +09:00
Yuta Saito
e259a257e6 RedundantLoadElim: Fix invalid destructure_struct emission without aggressive reg2mem
The `shouldExpand` in `OptUtils.swift` was incorrectly returning `true`
unconditionally when `useAggressiveReg2MemForCodeSize` was disabled. The
expansion might be invalid for types with addr-only types and structs
with deinit, but we didn't check them before. This could lead to invalid
`destructure_struct` instructions without `drop_deinit` being emitted.
2025-11-15 19:22:33 +00:00
Meghana Gupta
827c30f13c Merge pull request #85482 from meg-gupta/reduceendcowmutation
Avoid inserting end_cow_mutation_addr in some common cases
2025-11-13 19:07:45 -08:00
Meghana Gupta
1dc03fea25 Add early exit for Escapable and copyable types from mayHaveMutableSpan 2025-11-13 10:36:34 -08:00
Meghana Gupta
5e88f38152 Avoid inserting end_cow_mutation_addr in some common cases 2025-11-13 09:58:08 -08:00
Slava Pestov
819738c83e AST: Rename mapTypeIntoContext() => mapTypeIntoEnvironment(), mapTypeOutOfContext() => mapTypeOutOfEnvironment() 2025-11-12 14:48:19 -05:00
Andrew Trick
b28cd59dfc [NFC] TypeLowering: add CustomDeinit.
Teach SIL type lowering to recursively track custom vs. default deinit status.

Determine whether each type recursively only has default deinitialization. This
includes any recursive deinitializers that may be invoked by releasing a
reference held by this type.

If a type only has default deinitialization, then the deinitializer cannot
have any semantically-visible side effects. It cannot write to any memory
2025-11-11 17:29:45 -08:00
Adrian Prantl
11356acd44 Merge pull request #85397 from adrian-prantl/163167975
[SILOptimzer] Fix a crash caused by SILCombine mishandling inlined variables
2025-11-10 18:41:07 -08:00
Meghana Gupta
e2123e1b3b Merge pull request #85362 from meg-gupta/moreborrow
Add SIL verification for borrow and mutate accessors and some other minor fixes
2025-11-10 09:04:28 -08:00
Daniil Kovalev
f0bf57a269 Resolve merge conflicts & address review comments 2025-11-10 19:18:25 +03:00
Daniil Kovalev
72431dbd2d Merge branch 'main' into users/kovdan01/ast-bridges-for-autodiff-closure-spec 2025-11-10 18:46:04 +03:00
Adrian Prantl
99cf35cdce [SILOptimzer] Fix a crash caused by SILCombine mishandling inlined variables
This showed up on and off again on the source-compatibility testsuite project hummingbird.

The gist of the problem is that transformations may not rewrite the
type of an inlined instance of a variable without also createing a
deep copy of the inlined function with a different name (and e.g., a
specialization suffix). Otherwise the modified inlined variable will
cause an inconsistency when later compiler passes try to create the
abstract declaration of that inlined function as there would be
conflicting declarations for that variable.

Since SILDebugScope isn't yet available in the SwiftCompilerSources
this fix just drop these variables, but it would be absolutely
possible to preserve them by using the same mechanism that SILCloner
uses to create a deep copy of the inlined function scopes.

rdar://163167975
2025-11-07 17:06:33 -08:00
Erik Eckstein
62786b01e2 Optimizer: add the mandatory destroy hoisting pass
It hoists `destroy_value` instructions for non-lexical values.

```
  %1 = some_ownedValue
  ...
  last_use(%1)
  ... // other instructions
  destroy_value %1
```
->
```
  %1 = some_ownedValue
  ...
  last_use(%1)
  destroy_value %1    // <- moved after the last use
  ... // other instructions
```

In contrast to non-mandatory optimization passes, this is the only pass which hoists destroys over deinit-barriers.
This ensures consistent behavior in -Onone and optimized builds.
2025-11-06 21:00:44 +01:00