This was an annoying change, but mostly mechanical. The goal here is
to create parallel structure between the two paths so that it isn't
utterly confusing to share common CRTP paths between them. The renaming
of translate->process is just to make sure that all of the call sites
get correctly rewritten.
I'm trying to create more parallel structure between the param
and result reabstraction code so that, hopefully, some of the
basic explosion reasoning can be shared.
Moving the query implementation up to the AST library from SIL will allow
conveniences to be written on specific AST element classes. For instance, this
will allow `EnumDecl` to expose a convenience that enumerates element decls
that are available during lowering.
Also, improve naming and documentation for these queries.
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
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.
This is largely a matter of changing the main loop over subst
params in TranslateArguments to use the generators I added,
then plugging back into the general reabstraction infrastructure.
Because we don't have pack coroutines, we're kind of stuck in
the code generation for pack reabstraction: we have to write
+1 r-values into a temporary tuple and then write those tuple
element addresses into the output pack. It's not great. We
also have lifetime problems with things like non-escaping
closures --- we have that problem outside of reabstraction
thunks, too.
Other than that glaring problem, I'm feeling relatively good
about the code here. It's missing some peepholes, but it should
work. But that that's not to say that arity reabstraction works
in general; my attempts to test it have been exposing some
problems elsewhere, and in particular the closure case crashes,
which is really bad. But this gets a few more things working,
and this PR is quite large already.
- SILPackType carries whether the elements are stored directly
in the pack, which we're not currently using in the lowering,
but it's probably something we'll want in the final ABI.
Having this also makes it clear that we're doing the right
thing with substitution and element lowering. I also toyed
with making this a scalar type, which made it necessary in
various places, although eventually I pulled back to the
design where we always use packs as addresses.
- Pack boundaries are a core ABI concept, so the lowering has
to wrap parameter pack expansions up as packs. There are huge
unimplemented holes here where the abstraction pattern will
need to tell us how many elements to gather into the pack,
but a naive approach is good enough to get things off the
ground.
- Pack conventions are related to the existing parameter and
result conventions, but they're different on enough grounds
that they deserve to be separated.
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
When opaque values are enabled, when yielding a value with an indirect
convention, a value whose type's category is "object" must be yielded.
Previously, if a value's type was loadable, an attempt was made to yield
a value whose type's category was "address". Here, that's fixed.
Additionally, handling for trivial types yielded via @in_guaranteed is
added.
`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
These still get verified as part of SILGenModule's verification during
SILGenModule's destructor. But moving this earlier catches the error earlier and
makes it easier to debug any SIL issues immediately in the debugger rather than
having to backtrack from the SILGenModule's destructor.
A function can be actor instance-isolated to one of its parameters.
Make sure that this is reflected in ActorIsolation, so such a function
doesn't get a different actor isolation.
These will never appear in the source language, but can arise
after substitution when the original type is a tuple type with
a pack expansion type.
Two examples:
- original type: (Int, T...), substitution T := {}
- original type: (T...), substitution T := {Int}
We need to model these correctly to maintain invariants.
Callers that previously used to rely on TupleType::get()
returning a ParenType now explicitly check for the one-element
case instead.
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.
[Distributed] generic and inner test; without one edge case
[Distributed] fix distributed_thunk test; unsure about those extra hops, could remove later
[Distributed] Remove type pretending in getSILFunctionType; it is not needed
It seems our constant replacement in the earlier phases is enough, and
we don't need this trick at all.
[Distributed] Use thunk when calling cross-actor on DA protocols