Commit Graph

11193 Commits

Author SHA1 Message Date
Meghana Gupta
adb809369f Reland #79707
Revert "Merge pull request #80767 from meg-gupta/reverttransparent"

This reverts commit 198a802719, reversing
changes made to 8eb43af590.
2025-04-21 11:23:00 -07:00
Michael Gottesman
636aa31192 [sil-isolation-info] When determining isolation of a function arg, use its VarDecl.
Otherwise, we can be inconsistent with isolations returned by other parts of the
code. Previously we were just treating it always as self + nom decl, which is
clearly wrong if a type is not self (e.x.: if it is an isolated parameter).

rdar://135459885
(cherry picked from commit 0ece31e4f6)
2025-04-21 10:57:48 -07:00
Michael Gottesman
3b21613ad1 Merge pull request #80903 from gottesmm/release/6.2-149414471
[6.2][rbi] When checking for partial apply reachability of a value at a user, include the user itself in case the user is the actual partial apply
2025-04-21 10:49:50 -07:00
Joe Groff
4fd61eeed6 Merge pull request #80854 from jckarter/moveonly-trivial-field-as-reinitialize-6.2
[6.2] MoveOnlyChecker: Treat trivial stores as reinitializations rather than initializations.
2025-04-21 09:48:50 -07:00
Michael Gottesman
338ad04ed2 [rbi] When checking for partial apply reachability of a value at a user, include the user itself in case the user is the actual partial apply
The specific issue was when we were walking instructions looking to see if there
was a partial apply escaping instruction, we were not including the user
itself. That means that if the user was the partial apply escaping instruction,
we would return that no escape occured.

rdar://149414471
(cherry picked from commit 6eee52fb01)
2025-04-17 18:08:23 -07:00
eeckstein
16804e6050 Merge pull request #80849 from eeckstein/copy-block-optimization-6.2
[6.2] Optimizer: remove redundant copy_block instructions
2025-04-17 14:22:56 +02:00
Michael Gottesman
d1470fe55b Merge pull request #80840 from gottesmm/release/6.2-149019222
[6.2][rbi] Teach RBI how to handle non-Sendable bases of Sendable values
2025-04-16 14:24:55 -07:00
Joe Groff
66764a3fc3 MoveOnlyChecker: Treat trivial stores as reinitializations rather than initializations.
A trivial store is allowed to occur on an existing live value, and should not
trigger an attempt to destroy the original value completely. Fixes rdar://147791932.
2025-04-16 07:44:53 -07:00
Erik Eckstein
d8fddc9dcc Optimizer: remove redundant copy_block instructions
Removes a `copy_block` if its only uses, beside ownership instructions, are callees of function calls
```
  %2 = copy_block %0
  %3 = begin_borrow [lexical] %2
  %4 = apply %3() : $@convention(block) @noescape () -> ()
  end_borrow %3
  destroy_value %2
```
->
```
  %4 = apply %0() : $@convention(block) @noescape () -> ()
```

rdar://118521396
2025-04-16 14:33:26 +02:00
Michael Gottesman
46926720a9 [rbi] Make it so that we correctly do not error on uses of Sendable values that are projected from non-Sendable bases.
Specifically, we only do this if the base is a let or if it is a var but not
captured by reference.

rdar://149019222
(cherry picked from commit 23b6937cbc)
2025-04-15 14:58:04 -07:00
Michael Gottesman
a93e994593 [rbi] Add the ability to add flags to PartitionOp.
I am doing this so I can mark requires as being on a mutable non-Sendable base
from a Sendable value.

I also took this as an opportunity to compress the size of PartitionOp to be 24
bytes instead of 40 bytes.

(cherry picked from commit a045c9880a)
2025-04-15 14:57:57 -07:00
Michael Gottesman
68f8585eaa [rbi] Implement support for non-Sendable base values.
There are a few major changes here:

1. We now return a TrackableValue from getTrackableValue() if we have either a
non-Sendable value or a non-Sendable base. This means that we /will/ return
TrackableValues that may have a Sendable value or a Sendable base. To make it
easier to work with this, I moved the isSendable check and the do I have a base
check into PartitionOpBuilder. So, most of the actual code around emitting
values does not need to reason about this. They can just call addRequire or
addSend and pass in either TrackableValue::value or TrackableValue::base without
needing to check if the former is non-Sendable or if the latter is non-Sendable
and non-nil.

2. I searched all of the places where we were grabbing trackable values and
inserted require checks for the base value as appropriate.

Both of these together have prevented the code from becoming too heavy.

This fixes https://forums.swift.org/t/lets-debug-missing-rbi-data-race-diagnostics/78910

rdar://149019222
(cherry picked from commit 6d8b9b048a)
2025-04-15 14:57:52 -07:00
Michael Gottesman
ed98efa08a [rbi] Refactor getUnderlyingTrackedValue so that for addresses we return both a value and a base in certain situations.
Previously, when we saw any Sendable type and attempted to look up an underlying
tracked value, we just bailed. This caused an issue in situations like the
following where we need to emit an error:

```swift
func test() {
  var x = 5
  Task.detached { x += 1 }
  print(x)
}
```

The problem with the above example is that despite value in x being Sendable,
'x' is actually in a non-Sendable box. We are passing that non-Sendable box into
the detached task by reference causing a race against the read from the
non-Sendable box later in the function. In SE-0414, this is explicitly banned in
the section called "Accessing Sendable fields of non-Sendable types after weak
transferring". In this example, the box is the non-Sendable type and the value
stored in the box is the Sendable field.

To properly represent this, we need to change how the underlying object part of
our layering returns underlying objects and vends TrackableValues to the actual
analysis for addresses. NOTE: We leave the current behavior alone for SIL
objects.

By doing this, in situations like the above, despite have a Sendable value (the
integer), we are able to ensure that we require that the non-Sendable box
containing the integer is not used after we have sent it into the other Task
despite us not actually using the box directly.

Below I describe the representation change in more detail and describe the
various cases here. In this commit, I only change the representation and do not
actually use the new base information. I do that in the next commit to make this
change easier for others to read and review. I made sure that change was NFC by
leaving RegionAnalysis.cpp:727 returning an optional.none if the value found was
a Sendable value.

----

The way we modify the representation is that we instead of just returning a
single TrackedValue return a pair of tracked values, one for the base and one
for the "value". We return this pair in what is labeled a
"TrackableValueLookupResult":

```c++
struct TrackableValueLookupResult {
  TrackableValue value;

  std::optional<TrackableValue> base;

  TrackableValueLookupResult(TrackableValue value)
    : value(value), base() {}
  TrackableValueLookupResult(TrackableValue value, TrackableValue base)
    : value(value), base(base) {}
};
```

In the case where we are accessing a projection path out of a non-Sendable type
that contains all non-Sendable fields, we do not do anything different than we
did previously. We just walk up from use->def until we find the access path base
which we use as the representative of the leaf of the chain and return
TrackableValueLookupResult(access path base).

In the case where we are accessing a Sendable leaf type projected from a
non-Sendable base, we store the leaf type as our value and return the actual
non-Sendable base in TrackableValueLookupResult. Importantly this ensures that
even though our Sendable value will be ignored by the rest of the analysis, the
rest of the analysis will ensure that our base is required if our base is a var
that had been escaped into a closure by reference.

In the case where we are accessing a non-Sendable leaf type projected from a
Sendable type (which we may have continued to be projected subsequently out of
additional Sendable types or a non-Sendable type), we make the last type on the
projection path before the Sendable type, the value of the leaf type. We return
the eventual access path base as our underlying value base. The logic here is
that since we are dealing with access paths, our access path can only consist of
projections into a recursive value type (e.x.: struct/tuple/enum... never a
class). The minute that we hit a pointer or a class, we will no longer be along
the access path since we will be traversing a non-contiguous piece of
memory (consider a class vs the class's storage) and the traversal from use->def
will stop. Thus, we know that there are only two ways we can get a field in that
value type to be Sendable and have a non-Sendable field:

1. The struct can be @unchecked Sendable. In such a case, we want to treat the
leaf field as part of its own disconnected region.

2. The struct can be global actor isolated. In such a case, we want to treat the
leaf field as part of the global actor's region rather than whatever actor.

The reason why we return the eventual access path base as our tracked value base
is that we want to ensure that if the var value had been escaped by reference,
we can require that the var not be sent since we are going to attempt to access
state from the var in order to get the global actor guarded struct that we are
going to attempt to extract our non-Sendable leaf value out of.

(cherry picked from commit c846c2279e)
2025-04-15 14:57:47 -07:00
Michael Gottesman
3fe578611f [rbi] Add the ability to test in SIL RegionAnalysisValueMap::getTrackableValue().
I also added some basic tests of its functionality. I am doing this in
preparation for making some more invasive changes to getTrackableValue and I
want to be able to test it out very specifically in SIL.

(cherry picked from commit 8f458cd029)
2025-04-15 14:57:41 -07:00
Michael Gottesman
3c6c436c42 [rbi] Fix an iterator invalidation issue.
Due to compile time issues, I added a cache into
getUnderlyingTrackedValue(). This caused an iterator invalidation issue when we
recursed in the case when we had an underlying object since we would recurse
into getUnderlyingTrackedValue() instead of getUnderlyingTrackedValueHelper()
potentially causing us to cache another value and thus causing the underlying
DenseMap to expand. Now we instead just call getUnderlyingTrackedValueHelper()
so that we avoid the invalidation issue. This may cause us to use slightly more
compile time but we are still only ever going to compute the underlying value
once for any specific value.

(cherry picked from commit 5499734ed4)
2025-04-15 14:57:10 -07:00
Michael Gottesman
536377b3a7 [rbi] Remove a dead field, rename a class, and add some comments.
Specifically,

1. UseDefChainVisitor::actorIsolation is dead. I removed it to prevent any
confusion/thoughts that it actually found isolation. I also removed it from
UnderlyingTrackedValue since that was the only place where we were using it. I
left UnderlyingTrackedValue there in case I need to add additional state there
in the future.

2. Now that UseDefChainVisitor is only used to find the base of a value (while
not looking through Sendable addresses), I renamed it to
AddressBaseComputingVisitor.

3. I renamed UseDefChainVisitor::isMerge to isProjectedFromAggregate. That is
actually what we use it for. I also added a comment explaining what it is used
for.

(cherry picked from commit 98984a2678)
2025-04-15 14:57:05 -07:00
Michael Gottesman
033274e41b Fix require operand to also include trackableDest.
(cherry picked from commit 69ee33a25a)
2025-04-15 14:56:58 -07:00
nate-chandler
bddc926d37 Merge pull request #80781 from nate-chandler/cherrypick/release/6.2/rdar149007151
6.2: [DCE] Don't delete instructions which consume escaping values.
2025-04-15 11:04:09 -07:00
Nate Chandler
593bcb3636 [DCE] Verify liveness of completed lifetimes. 2025-04-11 17:24:50 -07:00
Nate Chandler
1b515d156d [DCE] Keep insts which consume escaping values.
When DCE deletes instructions as dead, if the instruction ends one of
its operands lifetimes, it must insert a compensating lifetime end.
When the def block of the value and the parent block of the instruction
are different, it uses lifetime completion.  Lifetime completion relies
on complete liveness, which doesn't and can't exist for values with
pointer escapes.  The result is ending lifetimes too early.

Avoid this scenario by marking such instructions live.

In the fullness of time, it may be possible to track the deleted
instruction's "location" even in the face of deletions of adjacent
instructions and parent blocks and to insert the lifetime end at that
location.

rdar://149007151
2025-04-11 17:24:50 -07:00
Meghana Gupta
c22acc530e [6.2] Revert #79707
Revert "Merge pull request #79707 from DougGregor/transparent-integer-conversions"

This reverts commit 9c2c4ea07f, reversing
changes made to 829e03c104.
2025-04-11 10:57:14 -07:00
Andrew Trick
4608c06f78 Fix GenericSpecializer for addressable parameters.
Addressable parameters must remain indirect.

Incidentally also fixes an obvious latent bug in which all specialization was
disabled if any metatypes could not be specialized.

Fixes rdar://145687827 (Crash of inline-stored Span properties with optimizations)

(cherry picked from commit 935b5e7ea2)
2025-04-08 14:02:19 -07:00
Andrew Trick
da2894ba2c [NFC] fix a dropUnusedArguments parameter name
(cherry picked from commit 6898e33edd)
2025-04-08 14:02:18 -07:00
Erik Eckstein
575388e188 CastOptimizer: handle isolated conformances
Check the isolation of conformances to avoid wrong folding of dynamic casts
rdar://147417762
2025-04-07 10:58:02 +02:00
Erik Eckstein
8f2c17a149 CastOptimizer: pass the SIL function to the cast-classify APIs, instead of the module decl
NFC
2025-04-07 10:58:02 +02:00
eeckstein
ff14828c7f Merge pull request #80463 from eeckstein/fix-sil-combine
SILCombine: fix an ownership violation when replacing open existential apply arguments
2025-04-03 23:00:00 +02:00
Joe Groff
367ad789c5 Merge pull request #80470 from jckarter/trivial-borrow-transitive-uses
MoveOnlyChecker: Don't follow trivial transitive uses of borrows.
2025-04-03 13:13:24 -07:00
Joe Groff
b5d242ad2c MoveOnlyChecker: Don't follow trivial transitive uses of borrows.
Trivial values don't have ownership tracked, so their uses can't affect the
lifetime of the original borrow. Fixes rdar://148457155.
2025-04-02 13:25:46 -07:00
Erik Eckstein
dff855034c SILCombine: fix a wrong assert in the SingleBlockOwnedForwardingInstFolder 2025-04-02 17:33:30 +02:00
Erik Eckstein
f7f5f9ad96 SILCombine: fix an ownership violation when replacing open existential apply arguments
The value of the opened existential must outlive the apply. Otherwise the optimization creates invalid SIL.

rdar://148259849
2025-04-02 17:33:30 +02:00
Erik Eckstein
4d1df28de0 ConstantFolding: add constant folding for some floating point intrinsics
* `sitofp` signed integer to floating point
* `rint` round floating point to integral
* `bitcast` between integer and floating point

Constant folding `bitcast`s also made it necessary to rewrite constant folding for Nan and inf values, because the old code explicitly checked for `bitcast` intrinsics.
Relying on constant folded `bitcast`s makes the new version much simpler.

It is important to constant fold these intrinsics already in SIL because it enables other optimizations.
2025-04-01 18:13:01 +02:00
Erik Eckstein
6e17385325 add a semantic attribute "optimize.sil.inline.constant.arguments"
This forces inlining the annotated function if its arguments are constant.
2025-04-01 18:12:45 +02:00
Erik Eckstein
e1f4057ffc ConstantFolding: only print a warning for infinity floating point literals if it has an AST node
This avoids false alarms for floating point literals which are imported from the `var infinity` getter of floating point types.
2025-04-01 18:12:45 +02:00
Artem Chikin
66334f8f1b Merge pull request #79290 from artemcm/ConstProtoSIL
[Compile Time Values] Implement a mandatory SIL pass to verify '@const' values
2025-04-01 00:12:27 -07:00
Pavel Yaskevich
0897962d27 Merge pull request #80373 from xedin/rdar-146101172-narrow
[SILOptimizer] Prevent devirtualization of call to distributed witnes…
2025-03-31 09:29:37 -07:00
Allan Shortlidge
8f2d5a759e Merge pull request #80321 from tshortli/warnings 2025-03-30 16:14:21 -07:00
Pavel Yaskevich
585b687103 [SILOptimizer] Prevent devirtualization of call to distributed witness requirements
This is a narrow fix, we are going to work on fixing this properly
and allowing both devirtualization and specialization for distributed
requirement witnesses.

Anything that uses an ad-hoc serialization requirement scheme cannot
be devirtualized because that would result in loss of ad-hoc conformance
in new substitution map.

Resolves: https://github.com/swiftlang/swift/issues/79318
Resolves: rdar://146101172
2025-03-29 19:27:46 -07:00
Arnold Schwaighofer
0222f90cf0 Merge pull request #80256 from aschwaighofer/disable_cond_fail_by_function
Disable cond_fail instructions by filtering the instruction's parent function
2025-03-28 13:18:19 -07:00
Allan Shortlidge
43fcb2cecd SIL/SILOptimizer: Fix unused variable warnings. 2025-03-28 12:33:39 -07:00
Artem Chikin
281f84da0f [Compile Time Values] Rewrite the 'Diagnose Unknown Compile Time Values' diagnostic pass in Swift 2025-03-28 10:30:07 -07:00
Artem Chikin
72a420919a [Compile Time Values] Add mandatory optimization pipeline driver for '@const' globals 2025-03-27 14:33:38 -07:00
Artem Chikin
ac60612242 [Compile Time Values] Emit diagnostic note with parameter location on a non-@const argument to a @const parameter 2025-03-27 14:33:38 -07:00
Artem Chikin
608e068a7a [Compile Time Values] Restrict the check for local variables to not apply to parameter value declarations
And remove some debug prints
2025-03-27 14:33:38 -07:00
Artem Chikin
114af54875 [Compile Time Values] Rebase on top of newly-added experimental feature for the '@const' attribute 2025-03-27 14:33:38 -07:00
Artem Chikin
d484ec7c1f [Compile Time Values] Implement a mandatory SIL pass to verify '@const' values 2025-03-27 14:33:35 -07:00
Doug Gregor
e0b52cd20e [SIL] Extend checked-cast instructions with "prohibit isolated conformances" flag
When performing a dynamic cast to an existential type that satisfies
(Metatype)Sendable, it is unsafe to allow isolated conformances of any
kind to satisfy protocol requirements for the existential. Identify
these cases and mark the corresponding cast instructions with a new flag,
`[prohibit_isolated_conformances]` that will be used to indicate to the
runtime that isolated conformances need to be rejected.
2025-03-26 22:31:47 -07:00
Andrew Trick
97b249bd11 Merge pull request #80263 from atrick/markdep-addr
SIL: add mark_dependence_addr
2025-03-26 10:33:42 -07:00
Arnold Schwaighofer
cc76edea15 Add a -print-cond-fail-messages-include-function-name option
Additionally, also consider the function name as the key to base cond_fail
removal on under `-cond-fail-config-file`.
2025-03-26 08:12:35 -07:00
Erik Eckstein
8b2d27007f DiagnoseInfiniteRecursion: re-implement the pass in swift and fix a bug
Fixes a false alarm in case of recursive calls with different type parameters.
For example:

```
protocol P {
  associatedtype E: P
}

func noRecursionMismatchingTypeArgs1<T: P>(_ t: T.Type) {
  if T.self == Int.self {
    return
  }
  noRecursionMismatchingTypeArgs1(T.E.self)
}
```
2025-03-26 09:14:38 +01:00
Andrew Trick
d9dd93560d Support mark_dependence_addr in SIL passes. 2025-03-25 23:02:45 -07:00