Commit Graph

32 Commits

Author SHA1 Message Date
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
Adrian Prantl
158772c2ab Rebase SILScope generation on top of ASTScope.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.

This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.

This fixes

rdar://88274783

and either fixes or at least partially addresses the following:

rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
2023-04-04 15:20:11 -07:00
Adrian Prantl
5ff139dd6e Wire up mangled macro names in debug info.
rdar://104894694
2023-02-03 10:30:48 -08:00
Adrian Prantl
6335f1dee5 Debug Info: Represent macro expansions as inlined functions.
This allows the debugger to choose whether to display the expanded macro
(inlined) or the original source code (parent frame).

rdar://102916513
2023-01-20 21:43:20 -08:00
Erik Eckstein
ec64f2a255 SILLocation: replace CleanupLocation::get(loc) with CleanupLocation(loc)
No need to have a static get function - the constructor can be used directly.
NFC
2021-01-29 20:28:21 +01:00
Michael Gottesman
0e985be3f4 [silgen] Create a function level scope when open coding implicit value initializers.
The Original Bug
----------------

In ffbfcfa131, we fixed a bug around implicit
value initializers but did not cherry-pick it to 5.3. While investigating a bug
that turned out to be that same bug (no worries!), I noticed that there is
additional code that is "unsafely" correct in this area and that while
ffbfcfa131 is correct in the small, we can expand
on the fix to prevent future bugs.

The Larger Bug
--------------

Here we are still open coding using ManagedValue/Cleanup APIs /without/ a top
level function scope. The code is only correct since we never emit unconditional
cleanups and always manually forward conditional cleanups. If we did not do
either of these things, we would have another instance of this bug, namely a
cleanup that is never actually emitted. So the code on master today is correct,
albeit unsafe, and we already have coverage for this (namely the test case from
ffbfcfa131).

That being said, in general when working with ManagedValue APIs (especially in
utility functions) we assume that we have a scope already created for us by our
caller. So by fixing this issue we are standardizing to safer SILGen invariants.

Building on ffbfcfa131
----------------------------------------------------

This commit builds on the shoulders of ffbfcfa131
by adding the function level scope mentioned in the previous section so that we
are now "safely" correct.

While looking at this I also realized that just using a normal scope when open
coding here may be a bit bugprone for open coding situations like this since:

1. If one just creates a scope in open coding situations, the scope will fire at
   end of the c++ function /after/ one has probably emitted a return.

2. Once one has emitted the return, the insertion point will no longer be set
   implying =><=.

To avoid this, I created a move only composition type on top of Scope called
AssertingManualScope. This type just asserts in its destructor if the scope it
contains has not been popped yet.

While, one can pop it by ones self, I added an overload of createReturnInst on
SILGenBuilder that also takes an AssertingManualScope and pops it at the
appropriate time.

So now when performing simple open coding tasks, we have the ability to in code
tie together the function level scope to the actual creation of return inst,
simulating the hand-off of lifetimes/resources from caller/callee that often
happens in the epilog of functions.

<rdar://problem/63189210>
2020-05-29 14:53:19 -07:00
John McCall
3162b513a9 Strengthen some assertions with cleanup scopes; NFC. 2018-10-25 21:50:00 -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
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
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
64943836ba SILGen: Support for trivial @noescape function types
- Emit a withoutActuallyEscapingClosure partial apply
This is to convert an @noescape closure to an escaping closure.
This needs to be done in preparation of @noescape closure contexts
becoming trivial.

- Insert escaping to noescape conversions

- Fix SILGen for @noescape

- Postpone closure cleanups to outside the argument scope

- Apply postponement recursively for closures passed to subscripts

- Only skip applying escapeness conversions for Swift thick functions

- Fix parameter convention for noescape closures in thunks

Part of:
SR-5441
rdar://36116691
2018-02-13 04:19:59 -08:00
Slava Pestov
fa8d04cd8d SILGen: Remove Scope::popPreservingValues() 2017-11-20 12:59:03 -05:00
Andrew Trick
c6f82f8f85 [sil-opaque-values] Fix SIL ownership in reabstraction thunks.
Emit a borrow scope whenever exploding tuples in to a list of arguments.

I spent a lot of time attempting to refactor the reabstraction thunk generation
code with code that handles RValue. However, there is a subtle difference in how
tuples are handled when they are packed into a single "RValue" as opposed to a
list of arguments.

Eventually, I ditched that effort because of subtle complexity and fell back on
Michael's suggestion of handling the extra thunk-sepcific work inside
Scope.popPreservingValues. This will just go away though once we have the
'destructure' instruction.
2017-09-10 16:01:35 -07:00
Michael Gottesman
3907c49748 [silgen] Teach SILGen how to push a +1 rvalue through a scope like we already can do for +1 managed values.
rdar://33358110
2017-08-08 13:13:40 -07:00
Michael Gottesman
225fd4acfc [silgen] Create Scope::popPreservingValue(ManagedValue).
What this routine does is:

1. "Imprints" a cleanup cloner with the managed value.
2. Forwards the managed value.
3. Pop the scope.
4. Use the imprinted cleanup cloner to recreate the managed value in the scope
outside of the current scope.
2017-03-22 14:55:03 -07:00
Michael Gottesman
572dbd44d0 [silgen] Add a small convenience constructor to Scope that takes a SILGenFunction/SILLocation.
This just automates the work of:

1. Grabbing the cleanup manager from the SGF.
2. Forming a CleanupLocation from a SILLocation.

Much of the time when one creates a scope, that is the information that one has
available. So lets make it... wait for it... convenient to construct a scope
with this data.
2017-03-22 12:39:34 -07:00
Michael Gottesman
fb3817ef29 [gardening] Canonicalize the header guard of Scope.h. NFC. 2017-03-17 18:45:55 -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
6c9eb3fead [gardening] Change Scope, LexicalScope, DebugScope, FullExpr to match ivar naming conventions in SILGen. 2017-03-15 15:47:15 -07:00
Michael Gottesman
e849900a7b [silgen] Add a new API for building switches: SwitchEnumBuilder.
This is a closure based API for creating switches that obey ownership
convensions. The way you use it with objects is as follows:

   SwitchEnumBuilder S(...);

   S.addCase(Decl, Block, [](ManagedValue Arg) -> void {
     ...
   });
   S.addCase(Decl, Block, [](ManagedValue Arg) -> void {
     ...
   });
   S.addDefaultCase(Block, [](ManagedValue Arg) -> void {
     ...
   });
   std::move(S).emit();

What is important is that it sets up the switch_enum destination blocks with the
proper cleanups for code emitted into the destination block and also provides
the default error with the passed in value with the appropriate cleanups.

It does not handle exits from the switch_enum on purpose since diamond
switch_enum APIs form a subset of APIs. It also expects the closure to create
terminators if appropriate.

In the switch_enum_addr case you have to do a bit more work, but it is still a
nicer API than doing it by hand as we do today.

rdar://29791263
2017-03-06 13:58:33 -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
Adrian Prantl
f1315f8b5c Debug Info: Make sure to enter a new SILDebugScope before generating
weak copies for capture list variables. Other wise two variables with
identical names will end up in the same scope.

This fixes a crash in the compiler.

rdar://problem/24150188
SR-526
2016-01-20 15:20:51 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Adrian Prantl
8ab1e2dd50 Unify debug scope and location handling in SILInstruction and SILBuilder.
The drivers for this change are providing a simpler API to SIL pass
authors, having a more efficient of the in-memory representation,
and ruling out an entire class of common bugs that usually result
in hard-to-debug backend crashes.

Summary
-------

SILInstruction

Old                   New
+---------------+     +------------------+    +-----------------+
|SILInstruction |     |SILInstruction    |    |SILDebugLocation |
+---------------+     +------------------+    +-----------------+
| ...           |     | ...              |    | ...             |
|SILLocation    |     |SILDebugLocation *| -> |SILLocation      |
|SILDebugScope *|     +------------------+    |SILDebugScope *  |
+---------------+                             +-----------------+

We’re introducing a new class SILDebugLocation which represents the
combination of a SILLocation and a SILDebugScope.
Instead of storing an inline SILLocation and a SILDebugScope pointer,
SILInstruction now only has one SILDebugLocation pointer. The APIs of
SILBuilder and SILDebugLocation guarantees that every SILInstruction
has a nonempty SILDebugScope.

Developer-visible changes include:

SILBuilder
----------

In the old design SILBuilder populated the InsertedInstrs list to
allow setting the debug scopes of all built instructions in bulk
at the very end (as the responsibility of the user). In the new design,
SILBuilder now carries a "current debug scope" state and immediately
sets the debug scope when an instruction is inserted.
This fixes a use-after-free issue with with SIL passes that delete
instructions before destroying the SILBuilder that created them.

Because of this, SILBuilderWithScopes no longer needs to be a template,
which simplifies its call sites.

SILInstruction
--------------

It is neither possible or necessary to manually call setDebugScope()
on a SILInstruction any more. The function still exists as a private
method, but is only used when splicing instructions from one function
to another.

Efficiency
----------

In addition to dropping 20 bytes from each SILInstruction,
SILDebugLocations are now allocated in the SILModule's bump pointer
allocator and are uniqued by SILBuilder. Unfortunately repeat compiles
of the standard library already vary by about 5% so I couldn’t yet
produce reliable numbers for how much this saves overall.

rdar://problem/22017421
2015-11-19 09:31:26 -08:00
Slava Pestov
60eb9780a1 SILGen: fix generation of switch containing try
When emitting try_apply, don't start a new scope between adding
a cleanup and forwarding the value. This would leave behind a
dead cleanup, which would fire an assertion in emitSharedCaseBlocks().

Fixes <rdar://problem/20923654>.

Swift SVN r28572
2015-05-14 17:22:47 +00:00
Bob Wilson
2df66cf8c4 Implement inline scopes for the performance inliner.
Mandatory-inlined (aka transparent functions) are still treated as if they
had the location and scope of the call site. <rdar://problem/14845844>
Support inline scopes once we have an optimizing SIL-based inliner

Patch by Adrian Prantl.

Swift SVN r18835
2014-06-12 19:48:43 +00:00
Joe Groff
9fe1ab427a Implement 'if let' and 'while let' statements.
Allow IfStmts and WhileStmts to have as their condition either an expression, as usual, or a pattern binding introduced by 'var' or 'let', which will conditionally bind to the value inside an optional. Unlike normal pattern bindings, these bindings require an in-line initializer, which will be required to be Optional type. Parse variable bindings in this position, and type-check them by requiring an Optional on the right-hand side and unwrapping it to form the pattern type. Extend SILGen's lowering of if and while statements to handle conditionally binding variables.

Swift SVN r13146
2014-01-30 10:37:39 +00:00
Chris Lattner
5c8e9bc070 split SILGenFunction & SGFContext out to a new header, to trim down SILGen.h
to being global stuff.


Swift SVN r10926
2013-12-06 18:40:20 +00:00
Anna Zaks
8f3c9002d0 [SIL] Add cleanup locations to SIL instructions.
I've decided to keep only the location of the scope AST node that corresponds to the cleanup. (Currently, there is no user that needs the originator expression, which caused the cleanup. So keeping things simple.)

Added the cleanup location to the Scope and JumpDest classes, which gets assigned on construction of those. The Scope's and JumpDest locations are used when we emit the cleanup instructions.

We now give better location info for 2 existing tests for definitive initialization.

(+ Rather sparse testing of all this.)

Swift SVN r7764
2013-08-29 23:14:22 +00:00
Adrian Prantl
a1c6b653ad Move DebugScopeStack from SILBuilder to SILGenFunction, using the swift new
InsertedInstrs facility.
No functionality change intended.

Swift SVN r7520
2013-08-23 20:11:44 +00:00
Stephen Lin
8d90466523 Reorganize SIL source tree: move lib/SIL/SILGen -> lib/SILGen, move lib/SIL/Passes -> lib/SILPasses, add lib/SILPasses/Utils
Swift SVN r7246
2013-08-14 23:47:29 +00:00