Just the $*T -> $*@moveOnly T variant for addresses. Unlike the object version
this acts like a cast rather than something that provides semantics from the
frontend to the optimizer.
The reason why I am using a different instruction for addresses and objects here
is that the object checker doesnt have to deal with things like initialization.
drop_deinit ultimately only affects the semantics of its
destroy_value. Avoid generating releases for destroys in which the
deinit has been dropped. Instead, individually release the members.
The value `self` is mutable (i.e., var-bound) in
a `consuming` method. Since you're allowed to
reinitialize a var after consuming, that means
you were also naturally allowed to reinitialize
self after `discard self`. But that capability was
not intended; after you discard self you shouldn't
be reinitializing it, as that's probably a mistake.
This change makes reinitialization of `self`
reachable from a `discard self` statement an error.
rdar://106098163
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.
The new alloc_pack_metadata and dealloc_pack_metadata are inserted as
part of IRGen lowering. The former indicates that the next instruction
might result in on-stack pack metadata being emitted. The latter
indicates that this is the position at which metadata emitted on behalf
of its operand should be cleaned up.
As part of SE-390, you're required to write either:
- `consume self`
- pass self as a `consuming` parameter to a function
- `discard self`
before the function ends in a context that contains a
`discard self` somewhere. This prevents people from accidentally
invoking the deinit due to implicit destruction of `self` before
exiting the function.
rdar://106099027
Pattern matching as currently implemented is consuming, but that's not
necessarily what we want to be the default behavior when borrowing pattern
matching is implemented. When a binding of noncopyable type is pattern-matched,
require it to be annotated with the `consume` operator explicitly. That way,
when we introduce borrowing pattern matching later, we have the option to make
`switch x` do the right thing without subtly changing the behavior of existing
code. rdar://110073984
When `debug_value`s are visited, if their operand is the stack address,
they are rewritten as `debug_value`s of the stored value, provided it is
known.
Previously, the check for whether the operand is the stack address,
however, just compared the `debug_value`'s operand with the
`alloc_stack`. For owned `alloc_stack`s (i.e. those that are not
"store_borrow locations"), that was correct. For guaranteed
`alloc_stack`s (i.e. those that are "store_borrow locations"), however,
this failed to recognize the the values produced by the `store_borrow`
instructions (which amount to aliases for the `alloc_stack`) as the
stack address.
Here, this is fixed by checking whether the `debug_value`'s operand is
either (1) the `alloc_stack` itself or (2) some `store_borrow` whose
destination is the `alloc_stack`.
rdar://109894792
When a specialization is created, in the original function, releases are
added in two different places:
(1) `ClosureSpecCloner::populateCloned`
(2) `rewriteApplyInst`
In the former, releases are added for closures which are guaranteed or
trivial noescape (but with owned convention).
In the latter, releases are added for closures that are owned.
Previously, when emitting releases at (2), whether the closure was
trivial noescape wasn't considered. The result was inserting the
releases twice, an overrelease.
Here, fix (2) to recognize trivial noescape as not +1.
rdar://110115795
When a specialization is created, in the original function, releases are
added in two different places:
(1) `ClosureSpecCloner::populateCloned`
(2) `rewriteApplyInst`
In the former, releases are added for closures which are guaranteed or
trivial noescape (but with owned convention).
In the latter, releases are added for closures that are owned.
Previously, when emitting releases at (2), whether the closure was
trivial noescape wasn't considered. The result was inserting the
releases twice, an overrelease.
Here, fix (2) to recognize trivial noescape as not +1.
rdar://110058964
Some notes:
1. I put in both a swiftpm like test case and a library evolution test case. I
also updated the moveonly_deinit serialization swift test to show that we
actually serialize the deinit.
2. I changed when we emit the deinit table to only be when we have a type with
an actual value type destructor. Notably this doesn't include classes today so
as a side-effect, we no longer attempt to devirtualize moveonly class deinits.
This doesn't affect anything we are trying to actually do since we do not
support noncopyable classes today. With that in mind, I changed one test that
was showing that deinit devirtualization worked to use a struct with deinit
instead of a class.
rdar://109679168
* Add @_used and @_section attributes for global variables and top-level functions
This adds:
- @_used attribute that flags as a global variable or a top-level function as
"do not dead-strip" via llvm.used, roughly the equivalent of
__attribute__((used)) in C/C++.
- @_section("...") attribute that places a global variable or a top-level
function into a section with that name, roughly the equivalent of
__attribute__((section("..."))) in C/C++.
Before the previous commit, we didn't see load [take] very often since it occurs
mostly on temporaries where we treat the copy_addr as the relevant take. Now
that we are checking temporaries though, we need to support this behavior.
The release needs to be preserved in case a user-defined deinit is
present in the released type. Checking for move-only is slightly
conservative.
Fixes rdar://109846094 ([move-only] SILCombine eliminates struct deinitialization)
this also fixes a bug where sometimes we simply emit
'consumed here' twice and other times we'd said 'other
consume here' for the same "consumed more than once"
message. so I went through and changed all of the 2nd
consumes into "consumed again".
rdar://109281444
- refer to a "consuming use" as simply a "consume", to reserve "use" for non-consuming uses.
- refer to "non-consuming uses" as just a "use".
- don't call it a "user defined deinit" and instead a "deinitializer" to match Sema
- be specific about what binding a closure is capturing that is preventing consumption.
rdar://109281444
- replaces "move-only" terminology with "noncopyable"
- replaces compiler jargon like "guaranteed parameters"
and "lvalue" with corresponding language-level notions
- simplifies diagnostics about closures.
and probably more.
rdar://109281444