Without this fix, the new 'consuming' and 'borrowing' keywords cannot
be used with trivial types. Which means, for example, they can't be
used in macro expansions that work on various types.
Fixes patterns like:
public func test1(i: consuming Int) -> Int {
takeClosure { [i = copy i] in i }
}
public func test2(i: borrowing Int) -> Int {
takeClosure { [i = copy i] in i }
}
public func test3(i: consuming Int) -> Int {
takeClosure { i }
}
// Sadly, test4 is still incorrectly diagnosed.
public func test4(i: borrowing Int) -> Int {
takeClosure { i }
}
Fixes rdar://112795074 (Crash compiling function that has a macro annotation and uses `consuming`)
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.
SILGen introduces a copy of the capture, because the semantics of escaping partial_apply's
requires the closure to take ownership of the parameters. We don't know when a closure is
strictly nonescaping or its final lifetime until ClosureLifetimeFixup runs, but that replaces
the consume of the copy with a borrow of the copy normally, hoping later passes fix it up.
We can't wait that long for move-only types, which can't be copied, so try to remove the
copy up front when the copy lives long enough and has no interfering uses other than the
partial_apply. rdar://110137169
And replace them with explicit `metatype` instruction in the entry block.
This allows such metatype instructions to be deleted if they are dead.
This was already done for performance-annotated functions. But now do this for all functions.
It is essential that performance-annotated functions are specialized in the same way as other functions.
Because otherwise it can happen that the same specialization has different performance characteristics in different modules.
And it's up to the linker to select one of those ODR functions when linking.
Also, dropping metatype arguments is good for performance and code size in general.
This change also contains a few bug fixes for dropping metatype arguments.
rdar://110509780
Before deleting a load, simply rewrite its debug info to refer to the
loaded address:
%l = load %a
debug_value %l, loc0, scope0, var0
--->
debug_value %a, loc0, scope0, var0, expr op_deref
%l = load %a
Note that alloc_stack addresses do not require the addition of
op_deref because they are already special-cased in IRGen.
This will be called from salvageDebugInfo when it is supported by
optmizations. Until then, it is only called selectively at -Onone.
This is a fundamental abstraction over loads. It was in
OwnershipOptUtils because load_borrow happens to be restricted by
OSSA. Passes should not include OwnershipOptUtils just because they
work with loads.
* move the apply of partial_apply transformation from simplify-apply to simplify-partial_apply
* delete dead partial_apply instructions
* devirtualize apply, try_apply and begin_apply
Now that we handle inlined global initializers in LICM, CSE and the StringOptimization, we don't need to have a separate mid-level inliner pass, which treats global accessors specially.
to work with aggregates containing unknown values. Such aggregates
can be generated when an instruction is skipped during constant
evaluation and its results are used to create a struct.
Previously, the utility bailed out on lexical lifetimes because it
didn't respect deinit barriers. Here, deinit barriers are found and
added to liveness if the value is lexical. This enables copies to be
propagated without hoisting destroys over deinit barriers.
rdar://104630103
Use BasicBlockBitfield to record per-block liveness state. This has
been the intention since BasicBlockBitfield was first introduced.
Remove the per-field bitfield from PrunedLiveBlocks. This
(re)specializes the data structure for scalar liveness and drastically
simplifies the implementation.
This utility is fundamental to all ownership utilities. It will be on
the critical path in many areas of the compiler, including at
-Onone. It needs to be minimal and as easy as possible for compiler
engineers to understand, investigate, and debug.
This is in preparation for fixing bugs related to multi-def liveness
as used by the move checker.