Commit Graph

215 Commits

Author SHA1 Message Date
Emil Pedersen 3fc296ee27 Merge pull request #89596 from Snowy1803/salvage-pointer-to-address
[DebugInfo] Support salvaging pointer_to_address
2026-06-09 14:05:20 +01:00
Emil Pedersen 7ba2e4faae [DebugInfo] Fix forwarding ownership of salvaged unary instructions
Enum, struct and tuple instructions should not have a forwarding
ownership within a debug reconstruction block.

Enum instructions (via salvageUnaryInst) and struct salvaging now reset
the forwarding ownership to None. Tuple instructions don't force the
forwarding ownership to owned for move-only types, so no fix was needed
for those, but tests have been added for all cases.
2026-06-08 17:17:58 +01:00
Emil Pedersen 51a47de4a1 [DebugInfo] Implement salvage for pointer_to_address 2026-06-08 12:39:19 +01:00
Emil Pedersen 2f034af299 Merge pull request #89659 from Snowy1803/salvage-enum-inst
[DebugInfo] Implement enum salvage
2026-06-05 14:34:49 +01:00
Emil Pedersen 5171973423 [DebugInfo] Implement enum salvage
Salvage `enum` instruction using a debug reconstruction block.
2026-06-04 19:24:36 +01:00
Aidan Hall cd47e29f3e [DebugInfo] Clean up salvagePackElementSetDebugInfo
- Do not set the scope, which should already be correct.
- Assert that the `debug_value` instruction has no attached reconstruction block, to avoid silently dropping it.
- Note that this will eventually have to transition from using tuple fragments to reconstruction blocks.
2026-06-04 18:31:09 +01:00
Emil Pedersen 7ad7dde372 Merge pull request #89511 from Snowy1803/salvage-address-to-pointer
[DebugInfo] Support salvaging address_to_pointer
2026-06-04 11:58:45 +01:00
Aidan Hall 17b9ba32f9 Merge pull request #89260 from aidan-hall/pack-opt-simplify-alloc-pack
Eliminate Unnecessary `alloc_pack` instructions
2026-06-03 10:20:49 +01:00
Emil Pedersen d6d7b9224f [DebugInfo] Refactor debug block salvaging (NFC)
Add salvageNullaryInst and salvageUnaryInst to salvage instructions
of their respective operand counts.
2026-06-02 11:00:53 +02:00
Emil Pedersen 43d175290a [DebugInfo] Support salvaging address_to_pointer
This allows us to salvage debug values when using UnsafePointer types.

Assisted-by: Claude
2026-06-02 11:00:53 +02:00
Emil Pedersen 370d0dc771 [DebugInfo] Fix salvage tuple when a debug block exists
This tuple salvage logic is the same as the struct salvage logic.

Assisted-by: Claude
2026-06-01 11:37:41 +02:00
Emil Pedersen c51c3d2b71 [DebugInfo] Fix salvage struct when a debug block exists
When a debug reconstruction block exists, adding a fragment is invalid.
Instead, salvage the struct instruction into the existing block. As
these blocks don't support multiple inputs, only one element is
salvaged, but this works well for single-element structs.

Additionally, to avoid crashes, a special case is added for empty
structs, which don't require any input.

Assisted-by: Claude
2026-06-01 11:37:35 +02:00
Emil Pedersen 01c1f668ee [DebugInfo] Clone reconstruction blocks in salvageStoreDebugInfo
When a store was being salvaged, the reconstruction block was dropped,
which could cause invalid debug values to be created. Reconstruction
blocks are now cloned with the debug values, and the uses of the address
removed by stripDeref.

Assisted-by: Claude
2026-06-01 11:34:29 +02:00
Aidan Hall b112540676 Packs: Salvage debug info when eliminating alloc_pack 2026-05-29 10:50:25 +01:00
Emil Pedersen 7e65702d64 Merge pull request #89355 from Snowy1803/salvage-float-literal
[DebugInfo] Add salvage for float literals
2026-05-26 16:25:05 +01:00
Emil Pedersen 2ad49ce5b1 [DebugInfo] Add salvage for float literals
The salvage for float literals works the same way as the one for integer
literals: clone the instruction into debug reconstruction block.

Assisted-by: Claude (for tests)
2026-05-22 17:51:54 +01:00
Emil Pedersen 1311b5c03a [DebugInfo] Use prependDeref in salvageLoadDebugInfo
Replace the use of createDebugValueAddr in salvageLoadDebugInfo, that
was used to rewrite debug value instructions with a prepended deref, to
use the prependDeref function to prepend it in place, and move it to the
correct place.
2026-05-22 12:18:51 +01:00
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