Commit Graph

2503 Commits

Author SHA1 Message Date
Michael Gottesman
f43911b30f [region-isolation] Given a .none #isolation parameter, infer the isolation from the callee rather than the isolated parameter.
Otherwise, we will have differing isolation from other parameters since
the isolations will look different since one will have the .none value
as an instance and the other will not have one and instead will rely on
the AST isolation info. That is the correct behavior here since we do
not actually have an actor here.

I also removed some undefined behavior in the merging code. The way the
code should work is that we should check if the merge fails and in such
a case emit an unknown pattern error... instead of not checking
appropriately on the next iteration and hitting undefined behavior.

rdar://130396399
2024-06-25 14:12:15 -07:00
Erik Eckstein
718ea4b018 replace require with the new ASSERT macro 2024-06-25 10:45:55 +02:00
Michael Gottesman
c01f551ebe [transfer-non-sendable] Teach SILIsolationInfo how to handle "look through instructions" when finding actor instances.
From the perspective of the IR, we are changing SILIsolationInfo such that
inferring an actor instance means looking at equivalence classes of values where
we consider operands to look through instructions to be equivalent to their dest
value. The result is that cases where the IR maybe puts in a copy_value or the
like, we consider the copy_value to have the same isolation info as using the
actor directly. This prevents a class of crashes due to merge failings. Example:

```swift
actor MyActor {
  init() async {

  init(ns: NonSendableKlass) async {
    self.k = NonSendableKlass()
    self.helper(ns)
  }

  func helper(_ newK: NonSendableKlass) {}
}
```

Incidently, we already had a failing test case from this behavior rather than
the one that was the original genesis. Specifically:

1. If a function's SILIsolationInfo is the same as the isolation info of a
SILValue, we assume that no transfer actually occurs.

2. Since we were taking too static of a view of actor instances when comparing,
we would think that a SILIsolationInfo of a #isolation parameter to as an
argument would be different than the ambient's function isolation which is also
that same one. So we would emit a transfer non transferrable error if we pass in
any parameters of the ambient function into another isolated function. Example:

```swift
actor Test {

  @TaskLocal static var local: Int?

  func withTaskLocal(isolation: isolated (any Actor)? = #isolation,
                     _ body: (consuming NonSendableValue, isolated (any Actor)?) -> Void) async {
    Self.$local.withValue(12) {

      // We used to get these errors here since we thought that body's isolation
      // was different than the body's isolation.
      //
      //  warning: sending 'body' risks causing data races
      //  note: actor-isolated 'body' is captured by a actor-isolated closure...
      body(NonSendableValue(), isolation)
    }
  }
}
```

rdar://129400019
2024-06-24 18:16:11 -07:00
Michael Gottesman
baec06ed23 [variable-name-inference] Add support for handling EndInitLetRefInst. 2024-06-24 18:16:11 -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
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Michael Gottesman
e3de3da703 Merge pull request #74529 from gottesmm/pr-4f6b5f5b9db8d8885b36c19ba57b8de45e93cc80
[region-isolation] Check if we have a self param before attempting to get the self type.
2024-06-18 17:37:08 -07:00
Michael Gottesman
d032bc033a [region-isolation] Check if we have a self param before attempting to get the self type.
Otherwise in asserts builds we get an assert and in no-asserts we get a crash.

rdar://129975097
2024-06-18 13:39:20 -07:00
Akira Hatanaka
d92f181ace Create two versions (for caller and callee) of the functions that answer questions about parameter convention (#74124)
Create two versions of the following functions:

isConsumedParameter
isGuaranteedParameter
SILParameterInfo::isConsumed
SILParameterInfo::isGuaranteed
SILArgumentConvention::isOwnedConvention
SILArgumentConvention::isGuaranteedConvention

These changes will be needed when we add a new convention for
non-trivial C++ types as the functions will return different answers
depending on whether they are called for the caller or the callee. This
commit doesn't change any functionality.
2024-06-18 09:06:09 -07:00
Erik Eckstein
532535faad SIL: enable some SIL linkage related asserts in release builds
To catch wrong linkage bugs with a release-built compiler

related to rdar://129318806
2024-06-14 11:55:14 +02:00
Erik Eckstein
d80813ee3b SIL: update borrowed-from instructions when cloning a basic block
Cloning blocks might split CFG edges which can "convert" terminator result arguments to phi-arguments.
In this case a borrowed-from instruction must be inserted.

Fixes a SIL verifier crash caused by SimplifyCFG's jump threading.
rdar://129187525
2024-06-12 12:56:34 +02:00
Michael Gottesman
f035590784 [region-isolation] Dont crash when processing global actor isolated init accessors.
This just means that I stopped treating it like an actor instance isolated
thing. This was fun to track down since ActorIsolation has a union in it that
was being misinterpreted, leading to memory corruption... my favorite! = ).

rdar://129256560
2024-06-11 22:15:37 -07:00
Nate Chandler
5dc3cf1296 [LifetimeCompletion] Removed "with leaks" mode.
Now that the two known issues which resulted in invalid SIL being
provided to lifetime completion have been addressed, tighten up the
completion done on the availability boundary not to allow leaks.
2024-06-06 16:48:46 -07: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
Nate Chandler
84da0ed4c5 [LifetimeCompletion] Add extend_lifetimes.
The new instructions are inserted after every "user" (according to
InteriorLiveness' SSAPrunedLiveness instance) outside the linear
liveness boundary.
2024-06-05 16:28:28 -07:00
Nate Chandler
a52cc7ae19 [NFC] LifetimeCompletion: Note boundary kind.
When visiting an availability boundary, note what kind of end is
involved.  For now, there's only one.
2024-06-05 16:28:28 -07:00
Nate Chandler
2a5d07522d [SIL] Add extend_lifetime instruction.
It indicates that the value's lifetime continues to at least this point.
The boundary formed by all consuming uses together with these
instructions will encompass all uses of the value.
2024-06-05 16:28:26 -07:00
Nate Chandler
77d26e1eff [NFC] LifetimeCompletion: Rename helper fn.
It visits the availability boundary, so call it
`visitAvailabilityBoundary`.  It's not clear what "unreachable lifetime
ends" are.
2024-06-05 16:27:45 -07:00
Nate Chandler
9d7db52bed [NFC] PrunedLiveness: Tweaked enum wrapper.
Clarify methods.  Unfortunately, without other changes I haven't
identified, the `enum class` can't be made an `enum` for ideal usage.
2024-06-05 16:27:45 -07:00
Nate Chandler
8a933bfa97 [Gardening] Detypo'd. 2024-06-05 16:27:45 -07:00
nate-chandler
23915e8075 Merge pull request #74109 from nate-chandler/rdar113142446
[ConsumeObjectChecker] End lifetimes at consumes.
2024-06-04 18:17:36 -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
Nate Chandler
04ffbe8a6e [NFC] OwnedValueCan: Add support for end markers.
Enhance the utility with the ability to end lifetimes of lexical values
at indicated instructions, overriding the usual behavior of maintaining
such lifetimes' previous endpoints (modulo non-deinit-barrier
instructions).
2024-06-03 15:45:29 -07:00
Nate Chandler
dc9baba586 [NFC] OwnedValueCan: Extracted extension visitor.
Parameterized `extendUnconsumedLiveness` on the ends of interest and the
action to take when visiting the extended boundary and named the
resulting function `visitExtendedUnconsumedBoundary`.
2024-06-03 15:45:26 -07:00
Nate Chandler
aa3cbe0c67 [NFC] OwnedValueCan: Typed maximizeLifetime. 2024-06-03 15:45:23 -07:00
Nate Chandler
df008924da [NFC] OwnedValueCan: Typed pruneDebugMode. 2024-06-03 15:45:20 -07:00
Michael Gottesman
c7124e431a [sending] Fix recent alloc_stack as indirect result isolation inference to infer disconnected if the alloc stack is used as a sending indirect result.
I also fixed an issue that I found where we were not substituting SILResultInfo
flags which was causing us to drop when substituting sil_sending. I added a
SILVerifier check to make sure that we do not break this again.
2024-06-01 23:25:16 -07:00
Michael Gottesman
0cd0868f52 [region-isolation] Recognize sil_isolated parameters that are global actors as global actors rather than actor instance.
The specific example I ran into was in sendable_continuation.swift where we were
passing in the @MainActor instance as a sil_isolated parameter. We were thinking
it was an actor instance so we emitted the wrong message.
2024-06-01 23:25:16 -07:00
Michael Gottesman
1d8ea84fa3 [region-isolation] When determining isolation of a full apply site... use the isolated parameter, not self.
This was ok in the small since most of the time we were processing a self
parameter as isolated... but that isn't always true...
2024-06-01 23:25:16 -07:00
Michael Gottesman
4c2dc5eac4 Merge pull request #73930 from gottesmm/nonisolatedunsafe-rdar128299305
[region-isolation] Add missing support for nonisolated(unsafe)
2024-05-28 20:46:00 -07:00
Michael Gottesman
06c32d74ff [region-isolation] Teach SIL isolation inference how to infer applies isolation from their callee's isolation.
This fixes a few issues I missed in the past bit of commits.

I need to fix one issue around async let, but I am going to fix it when I do a
sweep across async let.
2024-05-28 17:31:09 -07:00
Michael Gottesman
74ac12c9d2 [region-isolation] Make temporary alloc_stack that we form for returning values from a non-final class field take on the class method's isolation.
The reason why we are doing this is that otherwise, we have that the alloc_stack
formed for the result is disconnected and despite the fact that we merge it into
the actor region of the class method, we do not have that the alloc_stack
specifically is marked when we attempt to squelch Please.

This patch fixes that problem by detecting when an alloc_stack is being used as
a temporary for an out parameter and makes the alloc_stack initially isolated as
appropriate. It only does this in the specific cases where we can pattern match
it which in my limited testing has handled everything.
2024-05-28 17:31:08 -07:00
Tim Kientzle
65f78e6268 Merge pull request #73675 from tbkka/tbkka-assertions-v2
New assertions support
2024-05-28 17:25:21 -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
2de13df909 [region-isolation] Use SILIsolationInfo::initializeTrackableValue instead of SILIsolationInfo::mergeIsolationRegionInfo to fix last issue
When merging SILIsolationInfo for regions, we want to drop
nonisolated(unsafe). This is important since nonisolated(unsafe) should only
apply to the specific "value" that it belongs to, not the entire region.

This creates a problem since in a few places in the code base we initialize a
value (producing a disconnected value) and then initialize it by merging in an
actor isolation. This no longer work since we will then always have
nonisolated(unsafe) stripped, so no values would ever be considered to be
nonisolated(unsafe). After analyzing the use case, I realized that these were
just initialization patterns and in this commit, I added a specific
initialization operation called SILIsolationInfo::initializeTrackableValue and
eliminated those calls to SILIsolationInfo::mergeIsolationRegionInfo.

Since SILIsolationInfo no longer has any merge operation on it, I then
eliminated that code in this commit. This completes the behavior split that I
put into the type system in the last commit. Specifically, I defined a
composition type called SILDynamicMergedIsolationInfo. It represents a
SILIsolationInfo that has been merged... that is why I called it the
DynamicMergedIsolationInfo. It could probably use a better name = (.

This fixes one of the last weird test case that I wrote where we were not letting through valid
nonisolated(unsafe) code.

At the same time, I discovered an additional issue (which can be seen in the
TODOs in this commit), where we are being too conservative around a non-Sendable
class var field. I am going to fix that in the next commit.

rdar://128299305
2024-05-27 21:42:15 -07:00
Michael Gottesman
1bef011e48 [region-isolation] Add the ability for the analysis to emit "unknown error" partition ops in case we detect a case we cannot pattern match.
DISCUSSION: The analysis itself is unable to emit errors. So we achieve the same
functionality by in such cases emitting a partition op that signals to our user
that when they process that partition op they should emit an "unknown pattern"
error at the partition op's instructions.

I have wanted this for a long time, but I never got around to it.
2024-05-27 21:42:04 -07:00
Michael Gottesman
741244e16b [region-isolation] Split in the type system SILIsolationInfo that has been merged and those that haven't.
Specifically, I introduced a new composition type called
SILDynamicMergedIsolationInfo that just contains a
SILIsolationInfo. Importantly, whenever one merges a SILIsolationInfo with
another SILIsolationInfo, one gets back a SILDynamicMergedIsolationInfo.

The reason why I am doing this is that we drop nonisolated(unsafe) when merging
so I want to ensure that parts of the code that use merging (where the dropping
occurs) and normal SILIsolationInfo where we do not want to merge is
distinguished.
2024-05-27 21:41:54 -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
Michael Gottesman
89a2cfce0b [region-isolation] Initialize TrackableValueState's regionInfo with a .none instead of a disconnected region.
The design change here is that instead of just initializing the regionInfo with
disconnected, we set it as .none and if we see .none, just return a newly
construct disconnected isolation region info when getIsolationRegionInfo() is
called.

This enables us to provide a setIsolationRegionInfo() helper for
RegionAnalysisValueMap::getTrackableValue that does not perform a merge. This is
important since for nonisolated(unsafe), we want to not have nonisolated(unsafe)
propagate through merging. So if we use merging to initialize the internal
regionInfo state of a SILIsolationInfo, we will never have a SILIsolationInfo
with that bit set since it will be lost in the merge. So we need some sort of
other assignment operator. Noting that we should only compute a value's
SILIsolationInfo once in RegionAnalysisValueMap before we cache it in the map,
it made sense to just represent it as an optional that way we can guarantee that
the regionInfo is only ever set exactly once by that routine.
2024-05-27 21:28:34 -07:00
Michael Gottesman
3f26d08ee4 [region-isolation] Add the ability in SILIsolationInfo to represent a disconnected value that is nonisolated(unsafe). 2024-05-27 21:25:44 -07:00
Michael Gottesman
3597006200 [region-isolation] Move SILIsolationInfo out of PartitionUtils into its own header/cpp file.
SILIsolationInfo is conceptually a layer that composes with PartitionUtils so it
makes sense for it to be in a different file.
2024-05-27 20:37:08 -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
Slava Pestov
a1462ef184 SIL: Promote removeDeadBlock() from SILOptimizer to a method on SILBasicBlock 2024-05-21 13:52:58 -04:00
Michael Gottesman
d759ec97ea Merge pull request #73696 from gottesmm/rdar128216574
[sending] Add support for 'sending'
2024-05-18 05:42:41 -04:00
Tim Kientzle
f09fb7dfa4 Update a couple of files to pull assertion helpers from the new header 2024-05-16 12:50:23 -07:00
Michael Gottesman
e3e78ad6bb [sending] Change the internals of sending to be based around 'sending' instead of 'transferring'.
We still only parse transferring... but this sets us up for adding the new
'sending' syntax by first validating that this internal change does not mess up
the current transferring impl since we want both to keep working for now.

rdar://128216574
2024-05-16 12:20:45 -07:00
Ellie Shin
1257db7342 Merge pull request #73566 from apple/elsh/sil-new-attr
[SIL] Add [serialized_for_package] to control package-wide resilience domain in Package-CMO.
2024-05-16 10:17:35 -07:00
Ellie Shin
2d81d0f2c7 [SIL] Add a new attribute [serialized_for_package] to support
package-wide resilience domain if Package CMO is enabled.

The purpose of the attribute includes:
- Indicates that certain types such as loadable types are
allowed in serialized functions in resiliently built module
if the optimization is enabled, which are otherwise disallowed.
- Used during SIL deserialization to determine whether such
functions are allowed.
- Used to determine if a callee can be inlined into a caller
that's serialized without package-cmo, e.g. with an explicit
annotation like @inlinable, where the callee was serialized
due to package-cmo.

Resolves rdar://127870822
2024-05-15 12:43:15 -07:00
nate-chandler
4cf63a9394 Merge pull request #73576 from nate-chandler/gardening/20240510/1
[Gardening] SIL: Spelling of live range.
2024-05-14 15:50:08 -07:00