Commit Graph

198 Commits

Author SHA1 Message Date
Emil Pedersen aa4de7a348 [DebugInfo] Add getOrCreateDebugReconstructionBlock function
This function is used by passes and salvages to facilitate adding
instructions to reconstruction blocks, even if no block exists on the
debug value yet.
2026-05-16 18:23:44 +01:00
Emil Pedersen b563de2da4 [DebugInfo] Rename debug basic blocks to reconstruction blocks 2026-05-15 16:42:53 +01:00
Emil Pedersen d149ac2728 [DebugInfo] Rewrite integer literal salvage using debug basic block
Instead of using an op_constu/consts in the DIExpr, the integer literal
salvage now uses a debug basic block using a typed integer_literal.

This also has the effect of supporting integer literals bigger than
64 bits (such as an Int128 being salvaged) correctly.

Assisted-by: Claude
2026-05-13 16:29:18 +01:00
Emil Pedersen 9850711a74 Merge pull request #89034 from Snowy1803/remove-create-debug-fragments
[DebugInfo] Remove createDebugFragments function
2026-05-12 19:41:07 +01:00
Emil Pedersen bc79a45bb8 Merge pull request #89031 from Snowy1803/remove-index-addr-salvage
[DebugInfo] Remove salvage for IndexAddrInst
2026-05-12 17:24:42 +01:00
Emil Pedersen 017252c455 [DebugInfo] Remove createDebugFragments function
This function used to be called by CanonicalizeInstruction, but it
hasn't been called since 2023.
2026-05-12 14:29:34 +01:00
Emil Pedersen 43f43e0f14 [DebugInfo] Remove salvage for IndexAddrInst
The salvage for this instruction was wrong as it didn't multiply the
index by the element stride.
As this salvage is rare, only was correct for byte sized elements, and
will be rewritten in the future, remove it rather than fix it.
2026-05-12 12:19:10 +01:00
Emil Pedersen 855bc127d5 [DebugInfo] Add implicit op_deref to AllocStackInst
The VarInfo for an alloc_stack will always have an op_deref, so that they can
get copied along when the VarInfo is moved to a debug_value. This op_deref is
not printed by the SILPrinter.

This commit also updates uses of AllocStackInst's getVarInfo to strip this
op_deref at places where it is not needed, and uses of createDebugValueAddr
where the extra op_deref is no longer needed.

The only change at the IR level is for undef values that now have a DW_OP_deref
for move-only values.

This fixes most of the inconsitencies with op_deref at the SIL level. All
debug_values with addresses should always have an op_deref.

Assisted-by: Claude Opus 4.6 (Updated tests)
2026-05-12 11:24:39 +01:00
Emil Pedersen 04bc8bd05e Merge pull request #88871 from Snowy1803/complete-vartype
[DebugInfo] Add getCompleteVarInfo to DebugValueInst to include the vartype (NFC)
2026-05-11 11:39:36 +01:00
Emil Pedersen d5c1f6a338 [DebugInfo] Add getCompleteVarInfo to DebugValueInst to include the vartype (NFC) 2026-04-30 17:33:21 +01:00
Meghana Gupta 24232b8746 Merge pull request #88728 from meg-gupta/borrowsilbug1
Remove usePoints parameter from swift::castValueToABICompatibleType
2026-04-29 11:40:29 -07:00
Meghana Gupta 8ca4d46219 Remove usePoints parameter from swift::castValueToABICompatibleType
usePoints is an artifact of the time when we didn't have guaranteed forwarding phis.
It is no longer used and triggered an unnecessary assert for borrow accessors.
2026-04-28 20:57:24 -07:00
Joe Groff 097b0d3400 SIL: Split unchecked_*_enum_data_addr according to ownership and effects.
We cannot use spare bits or other overlapping storage layout tricks with fundamentally
address-only enums, and we can take advantage of this to do borrowing switches or other
in-place projections without copying the value. However, for resilient enums, the
implementation may use spare bit packing, but the type must be handled address-only
outside of its defining module, and we didn't have a way to express that with
borrowing switch. Optimization passes have also been running into problems with the
complexity that we were using `unchecked_take_enum_data_addr` sometimes as a pure
operation. This patch splits the instruction into three:

- `unchecked_inplace_enum_data_addr` represents a nondestructive in-place enum
  projection. It is only allowed for enums whose projection operation is
  nondestructive.
- `unchecked_take_enum_data_addr` represents a destructive enum projection,
  invalidating the enum and leaving the payload to be further consumed.
  This matches the current instruction's semantics.
- `unchecked_borrow_enum_data_addr` represents a borrowing enum projection.
  The instruction takes a second operand for "scratch" space, which the
  enum representation may be copied into in order to avoid invalidating the
  enum value, so the result is dependent on the lifetime of both the
  original enum and the scratch buffer. This allows for borrowing switches
  over resilient enums.

`unchecked_borrow_enum_data_addr` is implemented by taking advantage of the
"address-only enums can't do spare bit optimization" property at runtime.
We inspect the operand type's bitwise-borrowability from its metadata. If
the type is bitwise-borrowable, then we are allowed to bitwise-copy the
enum to the scratch space and apply the projection to the scratch space,
preserving the original value. If the type is not bitwise-borrowable, then
we cannot use spare bit optimization in its layout, so we apply the
projection in-place.

Fixes rdar://174952822.
2026-04-27 15:40:37 -07:00
Gábor Horváth 154028ae58 Merge pull request #88610 from Xazax-hun/unreferencable-storage
[cxx-interop] Fix an optimizer crash for some single field structs
2026-04-23 14:59:06 +01:00
Gabor Horvath 49d853487a [cxx-interop] Fix an optimizer crash for some single field structs
There is some logic to figure out if a type is unreferencable but that
did not handle tuple fields. C arrays are imported as Swift tuples, so
in case a C array had unreferenceable element type we can end up taking
the wrong path in the optimizer and trigger a crash.

rdar://175037688
2026-04-22 18:21:02 +01:00
Meghana Gupta 1e7ee5f784 Add a new utility canDeleteDeadMoveOnlyOwnedDestructureInst and explicitly handle forwarding operations that destructure 2026-04-21 16:27:52 -07:00
Meghana Gupta 607e1f3a6e Don't delete dead instructions that forward move-only values in ossa
A dead forwarding operation (e.g. `unchecked_enum_data`,
`unchecked_value_cast`, `destructure_struct`) with an owned move-only operand
must not be deleted because it ends the lifetime of its operand.

Previously, only `destructure_struct` was guarded against deletion. This
change uses `ForwardingOperation` and `getSingleForwardingOperand()` to
cover all single-operand forwarding instructions uniformly.

Resolves rdar://175150849
2026-04-21 11:28:45 -07:00
Erik Eckstein c20593cd58 Optimizer: better support of OSSA in various optimizations
Mainly:
* look through ownership instructions in more places
* support `load_borrow` and `store_borrow` where `load` and `store`s are expected
* support `destructure_struct` where `struct_extract` is expected
* enable inout-keypath optimization for OSSA
* OSSA support in StringOptimization
2026-03-10 07:56:51 +01:00
Erik Eckstein 16cb80b60d Optimizer: implement all of cond_fail simplification as instruction simplification
Inserts an unreachable after an unconditional fail:
```
  %0 = integer_literal 1
  cond_fail %0, "message"
  // following instructions
```
->
```
  %0 = integer_literal 1
  cond_fail %0, "message"
  unreachable
deadblock:
  // following instructions
```

Remove the old SILCombine implementation because it's not working well with OSSA lifetime completion.
This also required to move the `shouldRemoveCondFail` utility function from SILCombine to InstOptUtils.
2026-01-22 17:41:22 +01:00
Meghana Gupta f30b5841c4 Tolerate undef closure captures in ClosureLifetimeFixup
We may see undef closure captures in ClosureLifetimeFixup since
it is a mandatory pass that runs on invalid code as well.

This could sometimes hang the compiler while running `insertDeallocOfCapturedArguments`
in release builds.

This change adds a bailout when we see an undef closure capture to avoid running into this issue.
2025-12-11 12:16:12 -08:00
Erik Eckstein 2ac69f3c55 SILCombine: fix propagation of concrete existentials in enums
This peephole optimization didn't consider that an alloc_stack of an enum can be overridden by another value.
The fix is to remove this peephole optimization at all because it is already covered by `optimizeEnum` in alloc_stack simplification.

Fixes a miscompile
https://github.com/swiftlang/swift/issues/85687
rdar://165374568
2025-11-25 09:42:19 +01:00
Erik Eckstein f57278f941 SILCombine: be careful about deleting trivially dead destructure_struct instructions
A dead `destructure_struct` with an owned argument can appear for a non-copyable or non-escapable struct which has only trivial elements.
The instruction is not trivially dead because it ends the lifetime of its operand.

Fixes an ownership verification error.
2025-10-08 08:23:40 +02:00
John McCall 64d020ec45 [NFC] Introduce a convenience specialization of CanTypeVisitor that
forwards the paired nominal type methods to common implementations.
2025-09-05 14:02:36 -04: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
Erik Eckstein 2c27963ea1 SILCombine: handle mark_dependence in dead-closure elimination
rdar://150686370
2025-05-06 19:42:01 +02:00
Meghana Gupta c528afccf2 Fix ClosureLifetimeFixup to insert destroys at leaking blocks 2025-03-14 15:48:44 -07:00
Andrew Trick 727aed3a86 Fix ClosureLifetimeFixup to handle pointer escapes.
Fix insertDeallocOfCapturedArguments to conservatively sink deallocs over
pointer escapes.
2025-03-02 23:51:34 -08:00
Arnold Schwaighofer 7a251af60c AccessEnforcement: Fix analysis to include mayReleases as potentially
executing unknown code

This means we have to claw back some performance by recognizing harmless
releases.

Such as releases on types we known don't call a deinit with unknown
side-effects.

rdar://143497196
rdar://143141695
2025-02-07 15:10:13 -08:00
Anthony Latsis a84dfc8387 [Gardening] Fix some set but not used variables 2025-01-30 21:34:38 +00:00
eeckstein 4934b79bed Merge pull request #77527 from eeckstein/fix-reborrow-flag
Fix the computation of the re-borrow flags for guaranteed phi arguments
2024-11-13 07:21:13 +01:00
Erik Eckstein 63141b6a8b Optimizer: when propagating the concrete type of an existential, make sure to not violate dominance order
Make sure that an enum is only initialized once before it is taken. This implies that the initialization must dominate the take.

Fixes a verifier crash: rdar://139381701
2024-11-12 21:34:58 +01:00
Erik Eckstein 51e3e5ed80 Optimizer: rename BorrowArgumentsUpdater -> GuaranteedPhiUpdater
NFC
2024-11-12 09:26:59 +01:00
Erik Eckstein 6b8c6a3c3b SIL: rename updateBorrowedFrom to updateBorrowArguments
NFC
2024-11-12 09:26:58 +01:00
Arnold Schwaighofer dc3c19164a PMO: Don't block pmo for large types - rather only block expansion of tuples 2024-11-04 17:06:24 -08:00
swift-ci 54d8c9feb0 Merge remote-tracking branch 'origin/main' into rebranch 2024-09-29 14:55:02 -07:00
Hamish Knight 91ae5d6345 [AST] NFC: Rename getArgumentInterfaceType -> getPayloadInterfaceType
IMO this is a slightly clearer name, many of its
uses already use the term "payload".
2024-09-29 17:05:14 +01:00
swift-ci 6c7325fc89 Merge remote-tracking branch 'origin/main' into rebranch 2024-09-24 21:20:14 -07:00
Nate Chandler 14f9088094 [SILCombine] Destroy unowned with unowned_release.
Don't create strong_release of sil_unowned values when removing
partial_apply instructions.

rdar://136609584
2024-09-24 15:40:38 -07:00
swift-ci e072d4635c Merge remote-tracking branch 'origin/main' into rebranch 2024-07-04 20:53:57 -07:00
Anton Korobeynikov 080a82ba5f Ensure we emit strong_release only for scalar values inside emitDestroyOperation (#74965) 2024-07-04 20:52:10 -07:00
Ben Barham aa7a3a8268 Cleanup std includes
Remove `deque` from files it isn't actually used in. Add it and `stack`
to files that it is - presumably they were previously transitively found
through other includes.
2024-07-02 16:13:49 -07:00
Erik Eckstein 864c1434e8 Devirtualizer: fix a crash due to a not supported bitcast of ABI compatible types
When devirtualizing witness method calls, it can happen that we need a cast between ABI compatible return types.
We were missing supporting type casts between nominal types which are ABI compatible.

This comes from whole-module reasoning of protocol conformances.
If a protocol only has a single conformance where the associated type (`ID`) is some concrete type (e.g. `Int`), then the devirtualizer knows that `p.get()` can only return an `Int`:
```
public struct X2<ID> {
  let p: any P2<ID>
  public func testit(i: ID, x: ID) -> S2<ID> {
    return p.get(x: x)
  }
}
```
and after devirtualizing the `get` function, its result must be cast from `Int` to `ID`.

The `layoutIsTypeDependent` utility is basically only used here to assert that this cast can only happen between layout compatible types.

rdar://129004015
2024-06-21 17:28:33 +02:00
Erik Eckstein 9cb011322d SILOptimizer: add a utility to check if a generic nominal type's layout is dependent on its generic parameters
This is usually the case. Some examples, where they layout is _not_ dependent:
```
   struct S<T> {
     var x: Int // no members which depend on T
   }

   struct S<T> {
     var c: SomeClass<T> // a class reference does not depend on the layout of the class
   }
```
2024-06-21 17:28:33 +02: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
Ellie Shin 6216ec648f Merge pull request #73902 from apple/elsh/pkg-cmo-inline
[SIL][PackageCMO] Allow optimizing [serialized_for_pkg] functions
2024-06-04 11:39:19 -07:00
Ellie Shin 4ecfc96578 [SIL][PackageCMO] Allow optimizing [serialized_for_pkg] functions during SIL
inlining, generic/closure specialization, and devirtualization optimization passes.

SILFunction::canBeInlinedIntoCaller now exlicitly requires a caller's SerializedKind_t arg.
isAnySerialized() is added as a convenience function that checks if [serialized] or [serialized_for_pkg].

Resolves rdar://128704752
2024-05-27 23:05:56 -07:00
Michael Gottesman 3a1f58a72a [region-isolation] Make sure that nonisolated(unsafe) works in all cases.
I made sure we match what we get without region isolation by turning off region
isolation in one of the test runs on the test for this.

There is one problem where for non-final classes with nonisolated(unsafe) var
fields, we currently do not properly squelch since I need to do more
infrastructure work. I am going to do that in the next commit.

rdar://128299305
2024-05-27 21:41:32 -07:00
Ellie Shin 5ccc4cd394 SIL function can be serialized with different kinds: [serialized] or
[serialized_for_package] if Package CMO is enabled. The latter kind
allows a function to be serialized even if it contains loadable types,
if Package CMO is enabled. Renamed IsSerialized_t as SerializedKind_t.

The tri-state serialization kind requires validating inlinability
depending on the serialization kinds of callee vs caller; e.g. if the
callee is [serialized_for_package], the caller must be _not_ [serialized].
Renamed `hasValidLinkageForFragileInline` as `canBeInlinedIntoCaller`
that takes in its caller's SerializedKind as an argument. Another argument
`assumeFragileCaller` is also added to ensure that the calle sites of
this function know the caller is serialized unless it's called for SIL
inlining optimization passes.

The [serialized_for_package] attribute is allowed for SIL function, global var,
v-table, and witness-table.

Resolves rdar://128406520
2024-05-23 15:53:02 -07:00
Emil Pedersen 0be63d0422 [DebugInfo] Return complete variable info from getVarInfo by default
getVarInfo() now always returns a variable with a location and scope.
To opt out of this change, getVarInfo(false) returns an incomplete variable.
This can be used to work around bugs, but should only really be used for
printing.

The complete var info will also contain the type, except for debug_values,
as its type depends on another instruction, which may be inconsistent if
called mid-pass.

All locations in debug variables are now also stripped of flags, to avoid
issues when comparing or hashing debug variables.
2024-05-10 16:12:56 -07:00
Emil Pedersen 16c57aefcd [DebugInfo] Salvage integer literals 2024-04-26 16:31:16 -07:00