Commit Graph

70 Commits

Author SHA1 Message Date
Michael Gottesman
0e0665bfbd [concurrency] Add support for HopToMainActorIfNeededThunk.
It is behind the experimental flag GenerateForceToMainActorThunks.
2024-10-17 13:31:39 -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
Joe Groff
c4bdc97d9c SILGen: Separate borrow from consume phase for destructive pattern matches.
We don't want the dispatch phase of a pattern match to invalidate the subject,
because we don't define the order in which patterns are evaluated, and if a
particular match attempt fails, we need to still have an intact subject value
on hand to try a potentially arbitrary other pattern against it. For
noncopyable types, this means we have to always emit the match phase as a
borrow, including the variable bindings for a guard expression if any.
For a consuming pattern match, end the borrow scope and reproject the variable
bindings by using consuming destructuring operations on the subject in the
match block.

For now, this new code path only handles single-case-label-per-block switches
without fallthroughs.
2024-01-29 18:01:55 -08:00
Joe Groff
960938f87e SILGen: Always match noncopyable values by borrowing.
Even if the final pattern ends up consuming the value, the match itself
must be nondestructive, because any match condition could fail and cause
us to have to go back to the original aggregate. For copyable values,
we can always copy our way out of consuming operations, but we don't
have that luxury for noncopyable types, so the entire match operation
has to be done as a borrow.

For address-only enums, this requires codifying part of our tag layout
algorithm in SIL, namely that an address-only enum will never use
spare bits or other overlapping storage for the enum tag. This allows
us to assume that `unchecked_take_enum_data_addr` is safely non-side-
effecting and match an address-only noncopyable enum as a borrow.
I put TODOs to remove defensive copies from various parts of our
copyable enum codegen, as well as to have the instruction report
its memory behavior as `None` when the projection is nondestructive,
but this disturbs SILGen for existing code in ways SIL passes aren't
yet ready for, so I'll leave those as is for now.

This patch is enough to get simple examples of noncopyable enum switches
to SILGen correctly. Additional work is necessary to stage in the binding
step of the pattern match; for a consuming switch, we'll need to end
the borrow(s) and then reproject the matched components so we can
consume them moving them into the owned bindings. The move-only checker
also needs to be updated because it currently always tries to convert
a switch into a consuming operation.
2024-01-19 13:59:04 -08:00
John McCall
5d588012f4 Add an explicit test for an invalid ManagedValue. 2023-08-28 12:25:15 -04:00
Michael Gottesman
543063ef0e [silgen] Make ManagedValue::forUnmanaged private and change users to use other more specific APIs.
I have been doing this over the past couple of days in preparation for changing
ManagedValue to specify the type of scope its cleanup is connected to.
2023-08-19 14:11:44 -07:00
Michael Gottesman
cece84f345 [silgen] Rename forTrivialRValue -> forRValueWithoutOwnership and use it in a few places to eliminate more forUnmanaged.
With this commit, we have now eliminated ~55% of all forUnmanaged in the code
base.
2023-08-08 11:15:06 -07:00
Michael Gottesman
5095bd31b0 [silgen] Convert a few instances of ManagedValue::forUnmanaged(*).copy() -> ManagedValue::forCopyOwnedObjectRValue.
Just removing more ManagedValue::forUnmanaged.
2023-08-08 11:15:06 -07:00
Michael Gottesman
2208caac32 [silgen] Convert a bunch of forUnmanaged -> forObjectRValueWithoutOwnership.
NFCI.
2023-08-07 13:36:02 -07:00
Michael Gottesman
7dbcdfb126 [silgen] Rename forTrivialObjectRValue -> forObjectRValueWithoutOwnership.
The reason to do this rename is that this is also used for objects that while
non-trivial have .none ownership. Example: enum instance without a case.
2023-08-07 13:36:02 -07:00
Andrew Trick
42e2652529 Fix SILGen comments for isPlusOne and isPlusOneOrTrivial. 2023-05-03 22:01:49 -07:00
Andrew Trick
dc95b112cd Fix ManagedValue::isPlusOne for addresses
In-memory values cannot be reused after deinitialization.

Add ManagedValue::isPlusOneOrTrivial() for situations where we want to
forward a value without destroying the original memory.

Fixes rdar://108001491 (SIL verification failed: Found mutating or
consuming use of an in_guaranteed parameter?!:
!ImmutableAddressUseVerifier().isMutatingOrConsuming(fArg))
2023-05-01 23:23:42 -07:00
Michael Gottesman
8a194fa7cf [move-only] Chopping off two helper functions from a larger commit. 2023-02-17 16:04:47 -08:00
Meghana Gupta
196994fc11 Fix store_borrow generation in SILGen
This change ensures all store_borrows are ended with an end_borrow, and uses of the store_borrow
destination are all in the enclosing store_borrow scope and via the store_borrow return address.

Fix tests to reflect new store_borrow pattern
2022-08-16 15:08:22 -07:00
Michael Gottesman
1e6187c4f4 [sil] Update all usages of old API SILValue::getOwnershipKind() in favor of new ValueBase::getOwnershipKind().
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
2022-07-26 11:46:23 -07:00
Kavon Farvardin
6f86e2980a Revert "Revert "Simplify lifetime extension for async ObjC calls.""
This reverts commit 8441e07c0b.
2022-04-27 14:11:36 -07:00
Kavon Farvardin
8441e07c0b Revert "Simplify lifetime extension for async ObjC calls."
This reverts commit 01d470ce32.

Just to be safe, I'm reverting this part of https://github.com/apple/swift/pull/41571
as well, until it can be reimplemented in light of issues where a hop
can appear between a get_continuation and an await_continuation

resolves rdar://91502776
2022-04-25 12:12:26 -07:00
Kavon Farvardin
01d470ce32 Simplify lifetime extension for async ObjC calls.
Since the clean-up is not unwind only, we can rely on the
clean-ups to be emitted on both result and throw paths.

This does slightly change when the hop_to_executor is emitted,
in those paths, but that shouldn't matter.

refactors solution for rdar://78982371
2022-02-25 18:32:13 -07:00
Andrew Trick
8f53a927b0 SILGen OSSA support for switch_enum/checked_cast_br, related cleanup
Use APIs for creating terminator results that handle forwarding
ownership consistently.

Add ManagedValue::forForwardedRValue(SILValue) to handle cleanups
consistently based on ownership forwarding.

Add SILGenBuilder::createForwardedTermResult(SILType type) for
creating termator results with the correct ownership and cleanups.

Add SILGenBuilder::createTermResult(SILType type, ValueOwnershipKind
ownership) that handles cleanup based on terminator result ownership.

Add SILGenBuilder::createOptionalSomeResult(SwitchEnumInst) so a lot
of code doesn't need to deal with unwrapping Optional types,
terminator results, and ownership rules.

Replace the existing "phi" APIs with a single
SILGenBuilder::createPhi(SILType, ValueOwnershipKind) that handles
cleanup based on phi ownership.

Phis and terminator results are fundamentally different and need to be handled differently everywhere. Remove the confusion where terminator results were generated with a "phi argument" API.
2021-09-07 22:50:46 -07:00
Meghana Gupta
3372ab7a39 Fix arg cleanup for objc continuations
Current SILGen for objc continuations, can end the lifetime of args
before await_async_continuation.
This PR fixes it by extending the lifetime of the args until await_async_continuation
by creating copies. And then inserts manual cleanup with fix_lifetime + destroy

Fixes rdar://78982371
2021-07-22 15:23:57 -07:00
Michael Gottesman
c026e95cce [ownership] Extract out SILOwnershipKind from ValueOwnershipKind into its own type and rename Invalid -> Any.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
2020-11-10 14:29:11 -08:00
Michael Gottesman
c217262a59 [silgen] Rename DelegateInitSelfWritebackCleanup -> OwnedValueWritebackCleanup.
This cleanup is meant to be used with a value that is temporarily taken from a
memory location for a lexical scope. At end of scope, the value is returned back
to the original memory location.

It is used to implement in SILGen "move only loadable values". Note, a "move
only loadable value" is not a "move only type". It is just an abstraction for
working with a single copy of a loadable value as if that single copy was a move
only value.

This is currently only being used in initializer emission since we treat self in
such a context as a "move only value" before we delegate to a
super/convenience/peer initializer since we have to allow for such initializers
to change the underlying class we have stored which in certain use cases require
self to be guaranteed as /never/ being retained. The move only value
representation makes this easy to do/enforce.

My hope is that by changing the name of this cleanup it is more obvious what it
is meant to do and can become (hopefully) generally useful.
2020-05-15 22:34:48 -07:00
Michael Gottesman
26a734e58e [sil] Rename ValueOwnershipKind::{Any,None} 2019-10-25 10:28:25 -07:00
Michael Gottesman
adcfda6f6d [silgenpattern] When binding values, use a ManagedValue instead of an RValue to avoid implicitly exploding tuples.
In SILGenPattern, we need to be able to unforward cleanups when we explode
tuples. Thus we can't use RValue in SILGenPattern since it may implicitly
explode tuples (which without modifying RValue itself we can not
unforward). This patch removes a specific RValue usage that we can replace with
the use of a ManagedValue instead.

rdar://49903264
2019-05-16 12:41:08 -07:00
Michael Gottesman
dccd6eb0d6 [silgen] Change ManagedValue::copyInto to have same paramter order as ManagedValue::{forward,assign}Into.
ManagedValue::{forward,assign}Into both have the signature SILGenFunction &,
SILLocation, SILValue. For some reason copyInto has SILLocation and SILValue
swapped. This commit standardizes copyInto to match the others.
2019-05-15 13:47:39 -07:00
Michael Gottesman
0af0d5fddc [ownership] Replace ValueOwnershipKind::Trivial with ValueOwnershipKind::Any.
In a previous commit, I banned in the verifier any SILValue from producing
ValueOwnershipKind::Any in preparation for this.

This change arises out of discussions in between John, Andy, and I around
ValueOwnershipKind::Trivial. The specific realization was that this ownership
kind was an unnecessary conflation of the a type system idea (triviality) with
an ownership idea (@any, an ownership kind that is compatible with any other
ownership kind at value merge points and can only create). This caused the
ownership model to have to contort to handle the non-payloaded or trivial cases
of non-trivial enums. This is unnecessary if we just eliminate the any case and
in the verifier separately verify that trivial => @any (notice that we do not
verify that @any => trivial).

NOTE: This is technically an NFC intended change since I am just replacing
Trivial with Any. That is why if you look at the tests you will see that I
actually did not need to update anything except removing some @trivial ownership
since @any ownership is represented without writing @any in the parsed sil.

rdar://46294760
2018-12-04 23:01:43 -08:00
Michael Gottesman
8d7a26c711 [silgenpattern] Unconditionally use the +0 code path to emit enum element dispatch on loadable enum types
This is the enum element analogue of the tuple fixup in:
359eda52e5. Additionally as a nice fixup I can now
enable ownership verification on most of the switch code.

I ran into commit ordering issues with cleaning up the address only part of the
emitEnumElement so I included it in this commit. Specifically this was because I
realized that it was possible to get a copy_on_success with an object from this
code and I wanted to enforce the invariant that ConsumptionManagedValues only
have copy_on_success with addresses and borrow_always with objects. It was less
convoluted to just fix the address only code to fit that formulation rather than
shoe-horn the old code into the new form.

rdar://29791263
2018-10-15 20:18:13 -07:00
Michael Gottesman
713e5f98bf [silgen] Require ManagedValue::{forward,assign}Into to only accept plusOne ManagedValues.
We already have this requirement on RValues, so it is natural to extend it to
ManagedValue. The main reason why I am doing this though is to tighten up SILGen
asserts to help me catch places where we forward +0 arguments into memory
without a copy/cleanup.

rdar://34222540
2018-02-14 14:00:04 -08:00
Michael Gottesman
c31cd631a2 [silgen] Add {ManagedValue,RValue}::ensurePlusOne(...).
This helper function returns *this if the value is already at +1. Otherwise, if
the value is a +0 value, we copy the value. Since I am using this initially for
some experiments, I am hiding it behind the enable guaranteed normal arguments
flag.

rdar://34222540
2017-11-19 15:59:11 -08:00
Michael Gottesman
c33abb7633 [silgen] Add support for borrowing an RValue.
I also changed the way RValues are copied API wise to match how borrows are
copied.

rdar://33358110
2017-07-25 20:27:12 -07:00
John McCall
80b180a9a1 Implement a syntactic peephole to recognize explicit bridging
conversions that reverse an implicit conversion done to align
foreign declarations with their imported types.

For example, consider an Objective-C method that returns an NSString*:
  - (nonnull NSString*) foo;
This will be imported into Swift as a method returning a String:
  func foo() -> String
A call to this method will implicitly convert the result to String
behind the scenes.  If the user then casts the result back to NSString*,
that would normally be compiled as an additional conversion.  The
compiler cannot simply eliminate the conversion because that is not
necessarily semantically equivalent.

This peephole recognizes as-casts that immediately reverse a bridging
conversion as a special case and gives them special power to eliminate
both conversions.  For example, 'foo() as NSString' will simply return
the original return value.  In addition to call results, this also
applies to call arguments, property accesses, and subscript accesses.
2017-07-15 01:13:41 -04:00
John McCall
c005618219 Improve dumping facilities for various types in SILGen. 2017-07-15 01:12:55 -04:00
John McCall
338825e73d Fix the emission of r-value pointer conversions to delay the
conversions and extend lifetimes over the call.

Apply this logic to string-to-pointer conversions as well as
array-to-pointer conversions.

Fix the AST verifier to not blow up on optional pointer conversions,
and make sure we SILGen them correctly.  There's still an AST bug
here, but I'll fix that in a follow-up patch.
2017-04-26 14:15:44 -04:00
Michael Gottesman
6de8e56cbe [silgen] Add APIs for dumping/printing ManagedValues.
Saves a few key strokes in the debugger.
2017-03-29 15:36:12 -07:00
Michael Gottesman
5cbf589524 Small ease of use convenience APIs. NFC. 2017-03-27 16:00:34 -07:00
Michael Gottesman
68c581f729 [gardening] As per discussion, begin standardizing in SILGen that the SILGenFunction variable is passed around as SGF.
The reason that this is being done is that:

1. SILGenFunction is passed around all throughout SILGen, including in between
APIs some of which call the SILGenFunction variable SGF and others that call it
gen.
2. Thus when one is debugging code in SILGen, one wastes time figuring out what
the variable name of SILGenFunction is in the current frame.

I did not do this by hand. I did this by:

1. Grepping for "SILGenFunction &gen".
2. By hand inspecting that the match was truly a SILGenFunction &gen site.
3. If so, use libclang tooling to rename the variable to SGF.

So I did not update any use sites.
2017-03-11 23:38:17 -08:00
Michael Gottesman
87ca878870 [silgen] Fix another tuple explosion -> borrow + copy since we do not have the destructure operation yet.
rdar://29791263
2017-03-05 11:44:11 -08:00
Michael Gottesman
6920290de6 [silgen] Add an assert to ManagedValue::ManagedValue saying that objects with trivial ownership should never have a cleanup.
rdar://29791263
2017-03-05 11:44:08 -08:00
Slava Pestov
0611d663b8 SIL: Remove SILType::getSwiftType() 2017-02-27 20:01:35 -08:00
Michael Gottesman
5a15f880ee [silgen] Change a bunch of self accesses to use true formal evaluation scopes and formal accesses.
This is in preparation for removing the +0 self hack.

This commit in more detail does the following:

1. It adds Formal Evaluation Scopes to certain places where the scopes were
missing. Specifically:

   a. The SILGenLValue cases are places where we are invoking accessors. In each
      one of these cases, we had a formal evaluation scope in the accessor
      itself, but we did not have a scope that closed over the base access and
      the accessor access. The base access is a formal evaluation in the sense
      that just like with inout bases, we must create a new reference to the
      base and re-destroy the base in a chain of accesses. This is to ensure
      that we do not extend the lifetime of the base inappropriately.

   b. The SILGenPoly case is a place where we have never properly placed a
      Formal Evaluation Scope and have completely been relying on the +0 self
      hack to make sure that archetype callees are properly destroyed
      immediately after a +0 call.

2. It changes all of the places in SILGen that emit self to using formal access
cleanups instead of normal cleanups.

rdar://29791263
2017-02-23 10:36:48 -08:00
Michael Gottesman
5717eeba67 [silgen] Create a ManagedValue::formalAccessCopy(SILGenFunction &, SILLocation).
This is the same as the current ManagedValue::copy(...) convenience API except
that the cleanups are formal evaluation scoped.

rdar://29791263
2017-02-19 08:03:33 -08:00
Michael Gottesman
6b05692d31 [silgen] Remove incorrect assumptions in ManagedValue::copy(SILGenFunction &gen, SILLocation loc).
It was wrongly assumed that no cleanup meant a type must be trivial. This is not
true for shared borrow types.
2017-02-19 08:01:45 -08:00
Michael Gottesman
bdb4195de8 [silgen] ManagedValue::{formalEvaluationBorrow,formalAccessBorrow}()
NFC.
2017-02-19 07:58:03 -08:00
Michael Gottesman
58c3959e90 [silgen] Remove ManagedBorrowedValue in favor of the usage of FormalEvaluationScopes.
rdar://29791263
2017-02-15 15:28:14 -08:00
Michael Gottesman
7135ad3740 [silgen] Change ManagedValue::borrow to perform a *real* shared borrow and add a
new API called ManagedValue::unmanagedBorrow() for places where we were really trying to model
an exclusive borrow.

ManagedValue::unmanagedBorrow() is just the old implementation.

rdar://29791263
2017-02-05 17:07:42 -08:00
Michael Gottesman
9d5d163b11 [silgen] Add a class called BorrowedManageValue.
I am using this for implementing tight scopes around specific call sites. The
way that it works is that the class performs the copy and asserts if one has not
called the cleanup method before end of scope has occured.

rdar://29791263
2017-02-05 16:13:17 -08:00
Michael Gottesman
bcb755ef97 [silgen] Fix some parameter translation code in SILGenPoly for SILOwnership.
Everything here should be NFC after the ownership model eliminator except for 1
change where translation of unowned parameters is made more
correct. Specifically:

1. In manageParam, we make it so that if we allow PlusZero, we begin an actual
begin_borrow, end_borrow sequence. We can do this unconditionally since if the
passed in SILValue is already borrowed, we just return early.

2. In TranslateArguments::translateSingle(), we used to handle owned, unowned,
and guaranteed parameters all the same way. This is of course incorrect. Now we
do the following:

  a. If our final translated value is guaranteed, but we want an unowned or
  owned parameter, then we perform a copyUnmanaged().

  b. If our final translated value is unowned and our argument must be a
  guaranteed value, then we first transition the unowned value to an owned value
  using SILGen::emitManagedRetain() and then transition from owned to guaranteed
  using a emitBeginBorrow().

  c. If our final translated value is owned and our argument must be a
  guaranteed value, then we perform an emitBeginBorrow().

3. In forwardFunctionArguments(), if our argument requires a guaranteed
argument, we begin a begin borrow sequence.

rdar://29791263
2017-02-04 15:44:13 -08:00
Michael Gottesman
d9c2f22d9a [silgen] Add a new isa<...> API for ManagedValue.
This lets you do isa<AllocRefInst> to determine if the underlying ManagedValue
contains within it an AllocRefInst without needing to call getValue(). I would
like to restrict the number of places where getValue() needs to be called as
much as possible.
2017-02-04 13:40:26 -08:00
Michael Gottesman
4a6df2740b [semantic-sil] Remove CleanupHandle from forBorrowed*RValue methods.
I realized over the weekend the follie of storing a borrowed cleanup on
ManagedValues themselves. The reasons for this are:

1. We assume all over SILGen that ManagedValue::hasCleanup() => Owned. I would
have to fix all of those parts of the compiler.
2. The reason for having a cleanup handle on ManagedValue is to be able to
forward owned arguments, so there is really no purpose since we never want to be
able to forward these arguments.
2017-01-19 14:02:00 -08:00
Michael Gottesman
2c78ca99ac [semantic-sil] Introduce new specific static constructors for ManagedValue.
This is the first step towards eliminating:

* ManagedValue::forUnmanaged(SILValue)
* ManagedValue::ManagedValue(SILValue, CleanupHandle).

The reason why these two methods must be eliminated is that:

1. Currently non-trivial values are "borrowed" using
ManagedValue::forUnmanaged. With Semantic SIL, we are now able to represent
borrows via begin_borrow and end_borrow. This will make the semantics that
SILGen is trying to describe more accurate.

2. ManagedValue::ManagedValue can be used to add arbitrary cleanups. We want
methods that add cleanups, but that at the same time allow the caller to specify
what it expects the ownership of the given SILValue to be. This would then cause
an assertion to trip giving greater clarity.

rdar://29791263
2017-01-15 21:42:42 -08:00