While materializing one metadata pack, another pack may need to be
materialized. When that happens, the inner pack's dynamically sized
allocation must be deallocated within the same dominance scope.
The CFG within which the inner dynamically sized pack is allocated isn't
visible from SIL; that explains why the existing infrastructure around
`de`/`alloc_pack_metadata` instructions fails to produce a deallocation
at the appropriate point.
In the fullness of time, this emitted code should be optimized such that
the inner loop is hoisted out of its current outer loop.
rdar://141718098
Rather than the block that we _think_ we're emitting into, use the block
we're actually emitting into. These aren't the same because callees
can and do introduce control flow.
Some requirement machine work
Rename requirement to Value
Rename more things to Value
Fix integer checking for requirement
some docs and parser changes
Minor fixes
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)
When the SelfMetadata in a witness thunk is the tuple type (repeat each Self),
we can fulfill the pack shape and type metadata for Pack{repeat each Self}
from tuple metadata.
The length is trivially projected; the type metadata pack is slightly more
involved, because tuple metadata stores a list of element/offset pairs, so
we must stack allocate a pack and fill it in.
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.
Deallocate dynamic allocas done for metadata/wtable packs. These
stackrestore calls are inserted on the dominance frontier and then stack
nesting is fixed up. That was achieved as follows:
Added a new IRGen pass PackMetadataMarkerInserter; it
- determines if there are any instructions which might allocate on-stack
pack metadata
- if there aren't, no changes are made
- if there are, alloc_pack_metadata just before instructions that could
allocate pack metadata on the stack and dealloc_pack_metadata on the
dominance frontier of those instructions
- fixup stack nesting
During IRGen, the allocations done for metadata/wtable packs are
recorded and IRGenSILFunction associates them with the instruction that
lowered. It must be the instruction after some alloc_pack_metadata
instruction. Then, when visiting the dealloc_pack_metadata instructions
corresponding to that alloc_pack_metadata, deallocate those packs.
When allocating, the shape is computed, and it (its constant value if
any) is needed when deallocating, so return the shape along with the
address. And when deallocating, accept the shape, which the client
received during allocation, rather than requiring that the caller
compute the fixed size.
When a metadata pack is heap allocated, the pointer's LSB is set.
But lldb is expecting a real pointer. So mask it off.
Companion PR has a test: https://github.com/apple/llvm-project/pull/6961
rdar://110195273
For now these are completely resilient blobs, which is wrong
because it prevents us from being able to model something like
(Int, repeat each T, String).
But one step at a time...
I'm not really convinced that the existing implementation here is
correct in general; it might work for the type checker's use cases,
but I don't think we can rely on not seeing opened element archetypes
from other expansions in the type we're processing here. But we can
at least tread water while offering a more convenient API.
This simplifies the representation and allows clients to handle fewer
cases. It also removes an ambiguity in the representation which could
lead us to have two canonical types for the same type.
This is definitely not working yet, but I'm not making progress on
it quickly enough to unblock what we need to unblock; it'll have to
be fixed in parallel.
Previously, only the element archetypes that corresponded to the
relevant pack generic parameters were bound, and the wtables that were
bound for them were based on looking up what they conform to. Here, the
requirements of the generic signature are used to find which archetypes
must be bound to metadata and which conformances must be bound to
wtables.
Previously wtable packs were never forwarded because pack types
consisting of a single element which was itself a pack archetype were
never canonicalized into that.
In the forwarding scenario, gepped and loaded from wtable when lowering
open_pack_element.