Commit Graph

128 Commits

Author SHA1 Message Date
John McCall
46be95847b Extract TypeLowering's recursive type properties into a header, add
functions to compute them directly without a TypeLowering object, and
change a lot of getTypeLowering call sites to just use that.

There is one subtle change here that I think is okay: SILBuilder used to
use different TypeExpansionContexts when inserting into a global:
- getTypeLowering() always used a minimal context when inserting into
  a global
- getTypeExpansionContext() always returned a maximal context for the
  module scope
The latter seems more correct, as AFAIK global initializers are never
inlinable. If they are, we probably need to configure the builder with
an actual context properly rather than making global assumptions.

This is incremental progress towards computing this for most types
without a TypeLowering, and hopefully eventually removing TL entirely.
2025-08-01 15:00:57 -04:00
Slava Pestov
763f9c8923 SILGen: Fix RValue::elementsToBeAdded bookkeeping
This incorrect assert was added in 2013 and somehow it worked
until now.

Fixed rdar://problem/145478336.
2025-02-25 12:21:27 -05:00
Joe Groff
44b431690d SILGen: Materialize addressor bases for the formal access scope of the entire access.
The return pointer may point into the materialized base value, so if the base needs
materialization, ensure that materialization covers any futher projection of the
value.
2025-01-31 18:08:53 -08: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
Ben Barham
f292ec9784 Use the new template deduction guides rather than makeArrayRef
LLVM has removed `make*ArrayRef`, migrate all references to their
constructor equivalent.
2024-02-23 20:04:51 -08:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Nate Chandler
5a71b61f82 [OpaqueValues] Assign tuple into tuple.
In address-lowered mode, to initialize tuple-typed memory in a single
step, tuple_addr_constructor must generally be used because it's not
possible to construct a tuple any of whose fields are address-only.  In
opaque values mode, there is no problem constructing such a tuple.  So
construct the tuple and then assign it into the tuple-typed memory; the
single instruction that initializes the memory will be the assign.
2024-01-05 13:28:37 -08:00
Michael Gottesman
b1f69030fc [region-isolation] When assigning RValues into memory, use tuple_addr_constructor instead of doing it in pieces.
I also included changes to the rest of the SIL optimizer pipeline to ensure that
the part of the optimizer pipeline before we lower tuple_addr_constructor (which
is right after we run TransferNonSendable) work as before.

The reason why I am doing this is that this ensures that diagnostic passes can
tell the difference in between:

```
x = (a, b, c)
```

and

```
x.0 = a
x.1 = b
x.2 = c
```

This is important for things like TransferNonSendable where assigning over the
entire tuple element is treated differently from if one were to initialize it in
pieces using projections.

rdar://117880194
2023-11-07 15:38:33 -08:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
John McCall
3332ce7d1e [NFC] Add a utility for this load take/borrow dance 2023-06-14 21:29:21 -04:00
Adrian Prantl
3a97766bb3 Avoid emitting variable debug info for closure captures.
Variable debug info is triggered by pattern bindings, however, inside a closure
capture list, this should be avoided by setting the appropriate flag in the
initializer object.

rdar://110329894
2023-06-08 16:33:14 -07:00
Andrew Trick
ea7b8055bc Rewrite some isPlusOne calls to isPlusOneOrTrivial.
Whenever we want to forward to a +1 value but don't need to destroy
the original memory, use isPlusOneOrTrivial.

This follows the existing naming scheme.

Fixes rdar://108001491 (SIL verification failed: Found mutating or
consuming use of an in_guaranteed parameter?!:
!ImmutableAddressUseVerifier().isMutatingOrConsuming(fArg))
2023-05-01 23:24:29 -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
John McCall
3faee07bbe Teach RValue to not recursively expand tuples with pack expansions
Arguably, it would be more consistent with the current design to
figure out a representation for pack-expansion components so that
we can keep them around in whatever storage.  But honestly, I
don't like the current design; I think the eager explosion is an
over-complicated mistake.  So this is partly just me finding an
excuse to not extend that to more cases.
2023-03-09 02:22:24 -05:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01: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
f16c4ba203 [ownership] Convert ValueOwnershipKind to have an Invalid state instead of using optional.
At Andy's request. If it creates too much noise in covered switches, we may go
back to the original.
2020-11-10 10:34:44 -08:00
Michael Gottesman
26a734e58e [sil] Rename ValueOwnershipKind::{Any,None} 2019-10-25 10:28:25 -07:00
Doug Gregor
bb4d0c8bc3 [SILGen] Consistently call makeUsed() in RValue::getAsSingleValue().
Fixes rdar://problem/50711880.
2019-06-17 15:21:32 -07:00
Slava Pestov
16d5716e71 SIL: Use the best resilience expansion when lowering types
This is a large patch; I couldn't split it up further while still
keeping things working. There are four things being changed at
once here:

- Places that call SILType::isAddressOnly()/isLoadable() now call
  the SILFunction overload and not the SILModule one.

- SILFunction's overloads of getTypeLowering() and getLoweredType()
  now pass the function's resilience expansion down, instead of
  hardcoding ResilienceExpansion::Minimal.

- Various other places with '// FIXME: Expansion' now use a better
  resilience expansion.

- A few tests were updated to reflect SILGen's improved code
  generation, and some new tests are added to cover more code paths
  that previously were uncovered and only manifested themselves as
  standard library build failures while I was working on this change.
2019-04-26 22:47:59 -04:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04:00
Slava Pestov
396007da2f SILGen: Fix partial application of enum case with one-element labeled tuple
Fixes <rdar://problem/46748491>.
2018-12-19 15:15:04 -05: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
John McCall
dd77a2037e Pass the indices for writeback-conflict diagnostics on coroutines.
To do this, I had to introduce a way to unsafely copy an argument
list for the purposes of diagnostics.

rdar:://43802132
2018-08-31 04:20:47 -04:00
John McCall
7eb703bd74 Switch subscript index emission to use SILGenApply. NFC.
As always, most of the work here went into working around the AST
representations of parameter and argument lists.
2018-08-27 02:14:21 -04:00
Slava Pestov
1eed99db7d SILGen: Remove unused variable 2018-08-20 16:34:35 -07:00
Michael Gottesman
a57ad403ec [silgen] Now that we have destructure, use it in RValue to reduce copies emitted by SILGen.
rdar://43493020
2018-08-20 08:52:51 -07:00
Slava Pestov
734488e1a3 SILGen: Fix emission of materializeForSet for subscripts with weird index types
The index type might be a one-element tuple, either with a label
or a vararg element. We have to deal with these cases explicitly
since getLoweredType() doesn't.

Fixes <rdar://problem/43237821>.
2018-08-13 16:37:51 -07:00
Ben Cohen
a1adf9f347 Squash a few more unused warnings (#17743) 2018-07-05 08:24:17 -07:00
Michael Gottesman
2c1920333c [+0-normal-args] Turn on ensurePlusOne for RValues.
ManagedValue::ensurePlusOne is already enabled.

I also tightened up the implementation a little bit by:

1. Fixed a typo in ManagedValue::isPlueZero(). I forgot to negate a boolean
=/. Luckily, I have been using isPlusOne() instead of isPlusZero for all queries
I have needed so far.

2. I added code to ManagedValue/RValue so that if we have SILUndef, we do not
emit copies on SILUndef when we perform ensurePlusOne().

3. I changed isPlusOne() and isPlusZero() to return true for SILUndef. SILUndef
has "any" ownership so it is compatible with all forms of ownership.

rdar://34222540
2018-02-23 13:44:43 -08:00
Michael Gottesman
941b74f649 [+0-normal-args] Change tuple implosion code to use ManagedValue/Initializations so we do not leak memory from ensurePlusOne.
This was found by the ownership verifier in the tuple shuffle test. The specific
problem was that we were performing an ensurePlusOne and forwarding that
value. The rvalue code was expecting this to be a "true" forward. Rather than
relying on the rvalue code's assumptions, this commit refactors the tuple
implosion code to just return an explicit ManagedValue with the proper cleanup
upon it.

Bug caught by the ownership verifier running on the argument shuffle SILGen test
with +0 enabled.

*NOTE* This is not a problem on any of the release branches, since ensurePlusOne
is a no-op on those branches (I just turned it on a couple of days ago).

rdar://34222540
2018-02-16 13:12:58 -08: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
bd8350930c [+0-normal-args] Enforce assigning to RValues to only occur with +1 RValues.
We already enforce in the same constraint RValue::forwardInto(...).

rdar://34222540
2018-02-12 14:28:03 -08:00
Michael Gottesman
8022b10918 [silgen] When forwarding a tuple value, make sure that it is at +1.
In the code, we assume generally that a value that is "forwarded" into memory is
forwarded at +1. This isn't enforced and when I tried to enforce it at +0, I
quickly hit assertion failures. So rather than fix the myriad places, I am using
ensurePlusOne to handle such cases without needing to change a bunch of the
code.

rdar://34222540
2018-01-11 18:18:11 -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
Davide Italiano
3b800aa11f [gardening] Remove unused lambda capture(s). NFCI. 2017-09-10 21:44:38 -07:00
Michael Gottesman
f79b1db1fb [silgen] Add ArgumentSource::Kind::DelayedBorrowedRValue.
I am currently changing Callee to use an ArgumentSource instead of a SILValue to
represent self. Due to uncurrying/etc in certain cases, we need to communicate
that a value needs to be borrowed later before use. To do that in a clean way, I
am introducing a new form of ArgumentSource::Kind, DelayedBorrowedRValue.

This type of ArgumentSource can only be produced by calling
ArgumentSource::delayedBorrow(...). Such an argument source acts like a normal
RValue, except when you perform asKnownRValue, a borrow is performed before
returning the known rvalue.

Once uncurrying is ripped out/redone, this code can be removed in favor of just
using a borrowed ArgumentSource.

rdar://33358110
2017-08-25 20:30:16 -07:00
Michael Gottesman
afe402ff86 [silgen] Begin splitting emitRValue into two different APIs: SILGenFunction::emitPlus{One,Zero}RValue(...).
Today, SILGenFunction::emitRValue assumes the caller will create any cleanup
scopes that are needed to cleanup side-effects relating to the rvalue
evaluation.  The API also provides the ability for the caller to specify that a
+0 rvalues is an "ok" result. The API then tries to produce a +0 rvalue and
returns a +1 rvalue otherwise. These two properties create conflicting
requirements on the caller since the caller does not know whether or not it
should create a scope (if a +1 rvalue will be returned) or not (if a +0 rvalue
would be returned).

The key issue here is the optionality of returning a +0 rvalue. This change
begins to resolve this difference by creating two separate APIs that guarantee
to the caller whether or not a +0 or a +1 rvalue is returned and also creates
local scopes for the caller as appropriate. So by using these APIs, the caller
knows that the +0 or +1 rvalue that is returned has properly been put into the
caller scope. So the caller no longer needs to create its own scopes anymore.

emitPlusOneRValue is emitRValue except that it scopes the rvalue emission and
then *pushes* the produced rvalue through the scope. emitPlusZeroRValue is
currently a stub implementation that just calls emitPlusOneRValue and then
borrows the resulting +1 RValue in the outer scope, creating the +0 RValue that
was requested by the caller.

rdar://33358110
2017-08-14 13:24:43 -07:00
Michael Gottesman
3907c49748 [silgen] Teach SILGen how to push a +1 rvalue through a scope like we already can do for +1 managed values.
rdar://33358110
2017-08-08 13:13:40 -07:00
Michael Gottesman
e512174bb3 [silgen] Delete dead code.
EmitBBArguments is not used anymore in this file. Now we have one class named
EmitBBArguments in SILGen ; ).

rdar://33358110
2017-08-08 12:53:27 -07:00
Michael Gottesman
7cf4cdf9d9 [silgen] Verify that all ManagedValues in all RValues that are loadable are actual loaded (i.e. have object type).
This is already an RValue invariant that used to be enforced upon RValue
construction. We put in a hack to work around a bug where that was not occuring
and changed RValue constructors to instead load stored objects when they needed
to. But the problem is that since then we have added more constructors that
provide other manners to create such an invalid RValue.

I added verification to many parts of RValue and exposed an additional verify
method that we can invoke at the end of emitRValue() eventually to verify our
invariants. This will give me the comfort to make that assumption in other parts
of SILGen without worry.

I also performed a small amount of cleanup of RValue construction.

rdar://33358110
2017-08-08 00:43:33 -07:00
Michael Gottesman
b639db8170 [silgen] When exploding a non-tuple when forming an RValue, load the value to preserve RValue invariants.
rdar://33358110
2017-08-08 00:43:32 -07:00
Michael Gottesman
e7de7ac36c [silgen] When exploding tuple values into RValues, use a load_borrow instead of a load [take].
This can only come up if you have a tuple that is part address only and part
non-trivial, but loadable. Previously, the non-trivial value would be taken but
no cleanup would be created. This would trip the ownership verifier. Now we
properly model this via a load_borrow.

*NOTE* Due to us modeling a take as not-copying a value, after ownership is
stripped we have the same underlying singular load, so this is not a bug, but a
semantic violation of the model (i.e. taking a +0 self value).

rdar://33358110
2017-08-07 22:50:21 -07:00
Michael Gottesman
f04399608e [silgen] Clean up RValue::isPlus{One,Zero}(). 2017-07-26 14:46:07 -07:00
Michael Gottesman
4557d925ad [silgen] Add RValue::isPlus{One,Zero} to distinguish +0 from +1 rvalues.
I already in a previous commit forced all rvalues to have consistent cleanups
and consistent value ownership kinds. Now that we know all constructed RValues
are consistent, we can safely query that information.

rdar://33358110
2017-07-26 11:04:41 -07:00
Michael Gottesman
7bad32491d [silgen] Assert that rvalues always have consistent ownership and cleanups.
This means that all non-trivial ManagedValues must:

1. All have a cleanup or all not have a cleanup.
2. Have the same ValueOwnershipKind.

Semantic SIL requires this of tuple values. So it makes sense to catch this bug
as early as possible.

rdar://33358110
2017-07-25 22:41:02 -07: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
c005618219 Improve dumping facilities for various types in SILGen. 2017-07-15 01:12:55 -04:00
John McCall
f4a181bc21 Various improvements to RValue. 2017-06-11 01:39:50 -04:00
practicalswift
437a186032 [gardening] Remove redundant repetition of type names (DRY): RepeatedTypeName foo = dyn_cast<RepeatedTypeName>(bar) 2017-05-09 11:26:07 +02:00