Commit Graph

57 Commits

Author SHA1 Message Date
Joe Groff
dc043cf05d SILGen: Track original variable's cleanup state for addressable buffer cleanups.
Don't try to delete the value on paths where the value hasn't yet been deleted.
2025-08-13 16:51:12 -07: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
Joe Groff
ba4f42420b SILGen: Move error values into indirect error returns in proper order with cleanups.
There's an unfortunate layering difference in the cleanup order between address-only
and loadable error values during `catch` pattern matching: for address-only values,
the value is copied into a temporary stack slot, and the stack slot is cleaned up
on exit from the pattern match, meaning the value must be moved into the error return
slot on the "no catch" case before cleanups run. But if it's a loadable value, then
we borrow it for the duration of the switch, and the borrow is released during cleanup
on exit from the pattern match, so the value must be forwarded after running cleanups.

The way the code is structured, it handles these cases properly when the convention of
the function being emitted is in sync with the fundamental properties of the error type
(when the error type is loadable and the error return is by value, or when the error
type is address-only and the error return is indirect, in other words). But when
a closure literal with a loadable error type is emitted in an argument context that
expects a function with an indirect error return, we would try to forward the loadable
error value into the error return slot while a borrow is still active on it, leading
to verifier errors. Defer forwarding the value into memory until after cleanups are
popped, fixing rdar://126576356.

A tidier solution might be to always emit the function body to use a bbarg on the
throw block to pass the error value from the body emission to the epilog when the
type is loadable, deferring the move into memory to the epilog block. This would
make the right behavior fall out of the existing implementation, but would require
a bit more invasive changes (pretty much everywhere that checks IndirectErrorReturn
would need to check a different-tracked AddressOnlyErrorType bit instead or in
addition). This change is more localized.
2024-04-17 14:13:42 -07:00
John McCall
7b3415aa23 Properly erase closure isolation to @isolated(any).
We do this by pushing the conversion down to the emission of the
closure expression, then teaching closure emission to apply the isolation
to the closure.  Ideally, we combine the isolation along with the rest of
the conversion peephole, but if necessary, we make sure we emit the
isolation.
2024-02-26 22:50:58 -05: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
Joe Groff
c4bdc97d9c SILGen: Separate borrow from consume phase for destructive pattern matches.
We don't want the dispatch phase of a pattern match to invalidate the subject,
because we don't define the order in which patterns are evaluated, and if a
particular match attempt fails, we need to still have an intact subject value
on hand to try a potentially arbitrary other pattern against it. For
noncopyable types, this means we have to always emit the match phase as a
borrow, including the variable bindings for a guard expression if any.
For a consuming pattern match, end the borrow scope and reproject the variable
bindings by using consuming destructuring operations on the subject in the
match block.

For now, this new code path only handles single-case-label-per-block switches
without fallthroughs.
2024-01-29 18:01:55 -08:00
Michael Gottesman
a897257d06 [silgen] Add a new private API on CleanupManager called isFormalAccessCleanup.
I am going to use this in ManagedValue.
2023-08-16 11:12:20 -07:00
John McCall
c0777e611d Handle vanishing and variadic tuple results in reabstraction thunks.
Fixes rdar://110391963
2023-06-30 02:08:57 -04: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
a05fef5122 Implement parameter arity reabstraction.
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.
2023-03-20 20:06:08 -04:00
John McCall
239777aacb Fix parameter binding for tuples containing pack expansions
More missing infrastructure.  In this case, it's really *existing*
missing infrastructure, though; we should have been imploding tuples
this way all along, given that we're doing it in the first place.

I don't like that we're doing all these extra tuple copies.  I'm not
sure yet if they're just coming out of SILGen and eliminated immediately
after in practice; maybe so.  Still, it should be obvious that they're
unnecessary.
2023-03-09 02:28:29 -05:00
Ben Barham
68296c9037 [next] Remove LLVM_ATTRIBUTE_DEPRECATED
`LLVM_ATTRIBUTE_DEPRECATED` was removed in llvm/llvm-project
903c30f4d1f3bc0d1aae9ca83af17c0062d02b40. Use `[[deprecated]]` directly.
2022-05-05 16:25:10 -07:00
Nate Chandler
a3be84610c [SILGen] NFC: Moved EndBorrowCleanup to header.
Previously the declaration and definition of EndBorrowCleanup were both
within SILGenExpr.cpp.  That prevented the usage of cleanups which end
borrow scopes within other files.  Here, the declaration is moved to
Cleanup.h.  The necessary changes are made to SILGenExpr.cpp to keep the
definition of member functions in place.
2021-09-30 18:32:51 -07:00
Michael Gottesman
178804cfc1 [silgen] Mark CleanupManager::dump() as used and wrap it in a debugger only warning. 2021-08-24 20:37:29 -07:00
Michael Gottesman
f0a59a25ea [silgen] Ensure that cleanup cloner clones formal access cleanups to formal access cleanups.
This has been a long standing issue that we have been hacking around in various
points in SILGen. Now CleanupCloner just does the right thing.

I was unable to cause any issues to pop up in tree (since I believe we hacked
around this and converged on correctness). But it does come up in combination
with new code in https://github.com/apple/swift/pull/31779.

rdar://63514765
2020-10-19 14:15:48 -07:00
Michael Gottesman
f57a6cfd6d [silgen] Teach CleanupCloner how to handle OwnedValueWritebackCleanups correctly.
Previously we would just forward the cleanup and create a normal "destroy"
cleanup resulting in early deallocation and use after frees along error paths.

As part of this I also had to tweak how DI recognizes self init writebacks to
not use SILLocations. This is approach is more robust (since we aren't relying
on SourceLocs/have verifiers to make sure we don't violate SIL) and also avoids
issues from the write back store not necessarily have the same SILLocation.

<rdar://problem/59830255>
2020-05-19 16:15:33 -07:00
Michael Gottesman
05667e4e45 [silgen] Instead of creating a single CleanupCloner for an RValue, use a helper routine that stores into an outarray a cloner for each ManagedValue in the RValue.
This simplifies CleanupCloner so that it only needs to model the cleanup of a
single managed value. It also eliminates a tie in between RValue and
CleanupCloner which is not needed.
2020-05-03 12:30:49 -07:00
Adrian Prantl
ff63eaea6f Remove \brief commands from doxygen comments.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.

Patch produced by

      for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
2018-12-04 15:45:04 -08:00
John McCall
b08a3f35b0 [NFC] Add a utility to DiverseStack to simplify stable iteration 2018-11-03 01:00:17 -04:00
John McCall
3162b513a9 Strengthen some assertions with cleanup scopes; NFC. 2018-10-25 21:50:00 -07:00
Joe Groff
15e4094544 Merge pull request #18937 from jckarter/mutating-opened-existential-covariant-return
SILGen: Fix order of operations when a mutating existential method returns Self.
2018-08-28 18:21:45 -07:00
Joe Groff
7f14a3bf48 SILGen: Fix order of operations when invoking a mutating method on an existential that returns Self.
Delay allocating the result buffer for an opened Self return until right before it's needed. When a mutating method is invoked on an existential, the Self type won't be opened until late, when the formal access to the mutable value begins. Fixes rdar://problem/43507711.
2018-08-28 09:52:04 -07:00
John McCall
fae2ec3b38 Assorted minor improvements to the cleanup system. 2018-08-22 01:55:10 -04:00
John McCall
af1fbee3de Thread ForUnwind_t into emitCleanupsForReturn.
Some "return" edges are for unwinding due to errors and some aren't.
They'll need to be distinguished if we ever want to support throwing
cleanups.
2018-08-16 02:27:54 -04:00
John McCall
7a4aeed570 Implement generalized accessors using yield-once coroutines.
For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.

`_read` accessors do not make any effort yet to avoid copying the
value being yielded.  I'll work on it in follow-up patches.

Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.

SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.

rdar://35399664
2018-07-23 18:59:58 -04:00
John McCall
a3bdc89d47 Tell cleanups whether they're being emitted for the normal or unwind path.
NFC, but this may become semantically important for coroutines, because
an active coroutine must be aborted instead of ended on the unwind path.
2018-07-05 02:48:41 -04:00
Arnold Schwaighofer
e36655fddc SILGen: Remove PostponedCleanup in favor or the SIL pass that fixes
closure lifetimes.

SILGen will now unconditionally emit

  %cvt = convert_escape_to_noescape [guaranteed] %op

instructions. The mandatory ClosureLifetimeFixup pass ensures that %op's
lifetime spans %cvt's uses.

The code in DefiniteInitialization that handled a subset of cases is
removed.
2018-04-13 13:44:09 -07:00
Arnold Schwaighofer
025a8b909a Fix PostponedCleanup and use it in more places.
It can't be moved because there are pointers to it
2018-02-13 04:19:59 -08:00
Michael Gottesman
8d32122ed2 [silgen] Move CleanupCloner from SILGenBuilder.{h,cpp} => Cleanup.{h,cpp}
CleanupCloner never seemed like it should be in SILGenBuilder.{h,cpp}.
2017-08-18 22:05:10 -07:00
Michael Gottesman
84f5fe6a48 [silgen] Create FormalEvaluationScope::verify().
This method verifies that all non-dead cleanup handles that a formal evaluation
scope would pop have not been popped yet.

The body of the function is if-defed out when asserts are disabled.

rdar://31313534
2017-03-30 13:20:50 -07:00
Michael Gottesman
16c67f5f48 [gardening] Change Cleanup.{h,cpp} to match SILGen ivar naming conventions. 2017-03-15 15:47:15 -07:00
Michael Gottesman
68c581f729 [gardening] As per discussion, begin standardizing in SILGen that the SILGenFunction variable is passed around as SGF.
The reason that this is being done is that:

1. SILGenFunction is passed around all throughout SILGen, including in between
APIs some of which call the SILGenFunction variable SGF and others that call it
gen.
2. Thus when one is debugging code in SILGen, one wastes time figuring out what
the variable name of SILGenFunction is in the current frame.

I did not do this by hand. I did this by:

1. Grepping for "SILGenFunction &gen".
2. By hand inspecting that the match was truly a SILGenFunction &gen site.
3. If so, use libclang tooling to rename the variable to SGF.

So I did not update any use sites.
2017-03-11 23:38:17 -08:00
Michael Gottesman
784d5d16fc [silgen] Change emitClassConstructorInitializer to use ownership and make calling designated/chaining initializes use proper ownership.
rdar://29791263
2017-02-23 08:48:58 -08:00
Michael Gottesman
03a926b256 [silgen] When emitting lvalue gets into temporaries, cleanup the temporaries as early as possible.
Previously, we were emitting these cleanups at the end of the lexical scope
instead of at the end of the formal evaluation scope. This change ensures that
we always emit the cleanup immediately at the end of the formal evaluation
scope.

Previously in most cases we got away with this due to the +0 self
hack. Basically we would emit a get for a self parameter and then immediately
use that self parameter as a guaranteed parameter. Then the hack would insert
the destroy value forwarding the lexical scope level cleanup at the same time.

rdar://29791263
2017-02-17 23:26:13 -08:00
Michael Gottesman
c345f417c9 [silgen] Add CleanupManager::dump(CleanupHandle) to ease debugging.
We already have CleanupManager::dump() that dumps the entire cleanup
stack. Sometimes though when debugging you want to dump a specific cleanup. This
API provides such functionality.
2017-02-17 23:19:16 -08:00
Michael Gottesman
78a514cdb1 [silgen] Use the name FormalAccess to refer to state related to accesses in a single formal evaluation context. 2017-02-17 19:19:35 -08:00
Michael Gottesman
58c3959e90 [silgen] Remove ManagedBorrowedValue in favor of the usage of FormalEvaluationScopes.
rdar://29791263
2017-02-15 15:28:14 -08:00
Michael Gottesman
906763f545 [silgen] Add a SILGenFunction & argument to Cleanup::dump().
This enables LValueWritebackCleanup and a future version of EndBorrowCleanup to
dump their values which have to be looked up from SILGenFunction.
2017-02-14 13:34:46 -08:00
Michael Gottesman
e192b56a88 [silgen] Create CleanupManager::dump and the relevant dump methods to dump the current cleanups.
This is useful to discover when a specific cleanup is being eliminated while
debugging. The implementation is compiled out when assertions are disabled.

rdar://29791263
2017-02-05 18:38:41 -08:00
Michael Gottesman
9d5d163b11 [silgen] Add a class called BorrowedManageValue.
I am using this for implementing tight scopes around specific call sites. The
way that it works is that the class performs the copy and asserts if one has not
called the cleanup method before end of scope has occured.

rdar://29791263
2017-02-05 16:13:17 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Slava Pestov
d919b45937 SILGen: DiverseStack defines stable iterators; let's use them
DeferCleanup pushes a new temporary cleanup to catch non-local returns
from the defer block, so we have to use stable iterators while emitting
cleanups.

There's no good deterministic test case for this -- it would manifest
as memory corruption if the underlying storage of the DiverseStack
grew beyond the inline storage. Add a reduced version of the original
user-reported test case that triggers it reliably -- I had a hard time
coming up with anything simpler.

Fixes <rdar://problem/21437203>.

Swift SVN r29658
2015-06-25 05:00:50 +00:00
Chris Lattner
6dc6ecddf3 factor some code for cleanup emission (which avoids creating an empty block
in a common case) out into CleanupManager, where it can be used by lots of 
clients.  NFC.


Swift SVN r27044
2015-04-06 21:40:43 +00:00
Chris Lattner
e2fe7704ad Reimplement emission of StmtCondition (e.g. if/let & while/let) to be
in terms of the pattern binding/emission facilities that are currently
used for switches.  They are more general (handling all patterns,
not hacked up just for optionals).

This leads to us producing better code for if/let bindings, because we 
don't alloc_stack a temporary and deal with memory for non-address-only
types (e.g. the common case of an optional pointer).  Instead, the code 
emits a select_enum{_addr} on the value.

While this changes the generated code in the compiler, there is no exposed
behavioral change to the developer.




Swift SVN r26142
2015-03-14 20:31:23 +00:00
David Farler
182792cada Reinstate multi-pattern conditions in if/while
rdar://problem/19450969

Undo reverts r24381..24384 with one fix: pull cleanup blocks from the
back of the list. When breaking out of a while loop, an extra release
could over-release a reference.

Swift SVN r24553
2015-01-20 09:59:44 +00:00
Nadav Rotem
11d1a22ec2 Revert "Remove the "to" argument from emitActiveCleanups as Joe requests."
This reverts commit 24378 that depends on 24348 that broke the build.

Swift SVN r24382
2015-01-13 00:24:48 +00:00
Chris Lattner
ba455964c3 Remove the "to" argument from emitActiveCleanups as Joe requests.
Dont' emit destroy_addr if the element type is a class ref or is classbound.




Swift SVN r24378
2015-01-12 23:44:02 +00:00
Chris Lattner
413bf32a48 add a method to emit a range of cleanups out of the cleanup stack at
the current insertion point.  NFC.


Swift SVN r24359
2015-01-11 03:53:39 +00:00