Commit Graph

36 Commits

Author SHA1 Message Date
Andrew Trick 1ed083be0c LifetimeDependenceDiagnostics: add Builtin.makeBorrow support
Code like this currently looks like a lifetime escape:

  struct Ref<T: ~Copyable & ~Escapable>: ~Escapable {
    private let ref: Builtin.Borrow<T>

    @_lifetime(borrow target)
    init(_ target: borrowing T) {
      self.ref = Builtin.makeBorrow(target)
    }
  }

This is blocking the implementation of `Ref<~Escapable>`.

Fixes rdar://176564359 ([nonescapable] support Builtin.makeBorrow in
lifetime diagnostics)
2026-05-08 12:26:42 -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
Joe Groff 5f49668577 Builtin.dereferenceBorrow should maintain the memory location of addressable values. 2026-01-23 08:02:09 -08:00
Joe Groff 4479b49fd8 SIL: Handle address ReturnInsts from borrow accessors as yielding uses.
This avoids a spurious lifetime error when an address-only borrow accessor returns a
non-`Escapable` value from a non-`Escapable` aggregate.
2025-12-10 11:44:41 -08:00
Andrew Trick 6e0eeb00e3 Fix LifetimeDependenceDefUseWalker for @inout reassignment 2025-10-23 23:34:24 -07:00
Andrew Trick ce153a85ea [NFC] extend AddressInitializationWalker to report address reads 2025-10-23 23:34:24 -07:00
Andrew Trick 432e31612a [NFC] Extend AddressInitializationWalker.findSingleInitializer
Handle applies that reassign the lifetime of their operand vs. the value of
their operand.
2025-10-23 23:34:24 -07:00
JanBaig 4c61096be7 [SIL] Remove AssignByWrapper handling from analysis and utils 2025-08-22 23:15:16 -04:00
Andrew Trick 239255b8bc Improve LocalVariableUtils.gatherKnownLifetimeUses; dead ends
Add a fake use for dead-end blocks. This allows gatherKnownLifetimeUses to be
used for local liveness by considering an "unreachable" instruction to generate
liveness. This is important when liveness is used as a boundary within which
access scopes may be extended. Otherwise, we are unable to extend access scopes
into dead-end blocks.

Fixes rdar://154406790 (Lifetime-dependent variable 'X' escapes its
scope but only if actor/class is final)
2025-07-03 21:30:37 -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
Meghana Gupta 35d62a4a36 Introduce end_cow_mutation_addr instruction 2025-04-30 13:39:45 -07:00
Andrew Trick c9279d9899 Fix AddressOwnershipLiveRange to include the full range.
This allows further extension of access scopes.

Fixes rdar://143992296 (Use of `RawSpan` in switch context causes compiler crash
in AddressOwnershipLiveRange)
2025-04-11 23:49:07 -07:00
Andrew Trick 69b6b1d309 LifetimeDependenceDefUseWalker: handle addressable dependencies 2025-03-25 23:02:45 -07:00
Andrew Trick d9dd93560d Support mark_dependence_addr in SIL passes. 2025-03-25 23:02:45 -07:00
Andrew Trick 6c99017588 Minor comment cleanup and code formatting.
Extracted from the functional changes for clarity.
2025-02-25 23:08:53 -08:00
Andrew Trick eae2f06dc7 Extend and improve AccessBase.findSingleInitializer
Return an Initializer rather than a tuple. This makes it easier and more robust
for clients to track dependencies on initialized memory.
2025-02-10 09:11:22 -08:00
Andrew Trick a8caedfbec LifetimeDependenceInsertion: fix dependence on store_borrow.
For a lifetime dependent call that depends on a temporary store_borrow, the
generated mark_dependendence should be on the stored value, not the stack
location.

  %temp = alloc_stack $AnyObject
  %sb = store_borrow %arg to %temp
  apply %10(%out, %sb)
  mark_dependence [unresolved] %out on %arg
  end_borrow %sb

Fixes rdar://142847915 (Crash during lifetime checking while
building new swift standard library `Span`-related features)
2025-01-14 00:11:17 -08:00
Andrew Trick dc4e4665f9 AddressUtils: handle address initialization inside _modify.
We can assume that memory is already initialized at the point of a 'yield'; a
yield use does not need to invalidate the single-initialization property for
temporary stack allocations.
2024-12-16 15:28:00 -08:00
Andrew Trick 05c501a8f6 Add AddressOwnershipLiveRangeTest 2024-12-14 22:46:55 -08:00
Erik Eckstein f0633d5638 AccessUtils: support computing "constant" access paths
Add `Value.constantAccessPath`. It is like `accessPath`, but ensures that the projectionPath only contains "constant" elements.
This means: if the access contains an `index_addr` projection with a non-constant index, the `projectionPath` does _not_ contain the `index_addr`.
Instead, the `base` is an `AccessBase.index` which refers to the `index_addr`.
2024-11-04 19:26:44 +01:00
Alexander Cyon c18a24e499 [SwiftCompilerSources] Fix typos 2024-08-08 22:22:39 -07:00
Andrew Trick 11ba799cd4 LifetimeDependence: diagnose yield and store-to-yield. 2024-07-30 16:27:48 -07:00
Andrew Trick f6d147855f AddressUtils comment 2024-07-29 23:44:02 -07:00
Nate Chandler 06921cfe84 [SIL] Hollow out Builtin.copy, deprecate _copy.
The copy operator has been implemented and doesn't use it.  Remove
`Builtin.copy` and `_copy` as much as currently possible.

Source compatibility requires that `_copy` remain in the stdlib.  It is
deprecated here and just uses the copy operator.

Handling old swiftinterfaces requires that `Builtin.copy` be defined.
Redefine it here as a passthrough--SILGen machinery will produce the
necessary copy_addr.

rdar://127502242
2024-05-03 15:56:25 -07:00
Andrew Trick a1bb9f401a Fix SILVerifier and AddressUtils handling of addr casts.
These core utils did not handle UnconditionalCheckedCastAddrInst or
UncheckedRefCastAddrInst correctly.
2024-04-01 21:46:10 -07:00
Andrew Trick a0b2ae9c2c Add AccessBase.storeBorrow.
Don't treat StoreBorrow addresses as unknown bases. While they are never the base of a formal access, they are returned
as the AccessBase when querying the enclosing scope of an address.
2024-03-22 11:51:58 -07:00
Andrew Trick 3e7d9dba71 AddressUseVisitor: follow mark_dependence [nonescaping].
Treat mark_dependence [nonescaping] as a dependent value even if the dependence base does not have a recognizable
scope (e.g. a multiply-defined alloc_stack). This happens because ClosureLifetimeFixup creates redundant mark_dependence
instructions for partial_apply captures. We constantly need to work around this broken representation of nonescaping closures.
2024-03-18 17:45:33 -07:00
Andrew Trick 009bc58045 Disable verbose AddressUtils 2024-03-18 17:45:28 -07:00
Andrew Trick bdabc2145a Add computeKnownLiveness utility
To fix LifetimeDependenceScopeFixup in the presense of pointer escapes.
2024-03-18 17:38:12 -07:00
Andrew Trick aa208bbf91 Add SILType::containsNoEscapeFunction()
Add PartialApplyInst.hasNoescapeCapture
Add PartialApplyInst.mayEscape

Refactor DiagnoseInvalidEscapingCaptures. This may change functionality because tuples containing a noescape closure are now correctly recognized. Although I'm not sure such tupes can ever be captured directly.
2024-03-18 17:38:12 -07:00
Andrew Trick 75f2f88bce Add AddressOwnershipLiveRange
A live range representing the ownership of addressible memory.

This live range represents the minimal guaranteed lifetime of the object being addressed. Uses of derived addresses
may be extended up to the ends of this scope without violating ownership.

.liveOut objects (@in_guaranteed, @out and globals) have no instruction range.

.local objects (alloc_stack, yield, @in, @inout) report the single live range of the full assignment that reaches
this address.

.owned values (boxes and references) simply report OSSA liveness.

.borrow values report each borrow scope's range. The effective live range is their intersection. A valid use must
lie within
2024-03-05 17:08:13 -08:00
Andrew Trick 5fc50a0092 AddressUtils: refactor the findSingleInitializer API. 2024-02-25 10:29:15 -08:00
Andrew Trick 2e7c29cdf5 Restrict findSingleInitializer @out arguments.
The client should handle @in/@inout arguments differently.
2024-02-12 20:03:38 -08:00
Andrew Trick b08f2dedf1 Add AccessBase.findSingleInitializer 2024-02-12 09:57:14 -08:00
Andrew Trick 17319fa843 Improve the AddressUtils and OwnershipLiveness APIs 2024-01-30 08:38:57 -08:00
Andrew Trick 3bf7e715e7 Add AddressUtils.swift 2024-01-22 23:42:54 -08:00