Commit Graph

56 Commits

Author SHA1 Message Date
John McCall
bee053f1f0 Switch InitializationPtr to use PossiblyUniquePtr so that we can just
forward existing initializations around when necessary.
2025-08-02 02:13:25 -04:00
Nate Chandler
c35b86a30d [SILGen] Borrow into in_guaranteed.
Don't create a copy in order to pass a value `@in_guaranteed`.  Just
`store_borrow` the value.

rdar://128710064
2024-06-06 15:45:22 -07:00
Nate Chandler
16e080ddb6 [Gardening] Detypo'd. 2024-06-05 11:43:11 -07:00
John McCall
5c2cd18a5b Teach SILGen to try to peephole a function conversion into the emission of
a closure expression, then don't actually do it.  The long term plan is
to actually do this, which should just be a matter of taking some of the
code out of reabstraction thunk emission and using it in prolog/epilog/return
emission.  In the short term, the goal is just to get the conversion
information down to the closure emitter so that we can see that we're
erasing into an `@isolated(any)` type and then actually erase the
closure's isolation properly instead of relying on type-based erasure,
which can't handle parameter/capture isolation correctly.
2024-02-23 02:59:39 -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
Michael Gottesman
543063ef0e [silgen] Make ManagedValue::forUnmanaged private and change users to use other more specific APIs.
I have been doing this over the past couple of days in preparation for changing
ManagedValue to specify the type of scope its cleanup is connected to.
2023-08-19 14:11:44 -07: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
de283f8053 Make BlackHoleInitialization support pack initialization
Fixes rdar://107151145
2023-03-27 18:31: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
John McCall
81f11c19ab Implement the caller side of return types containing variadic packs
This is all relatively nicely abstracted, which is not to say that
it didn't take an awful lot of plumbing to get it to work.  The basic
problem here is inherent: we need to do component-specific setup and
teardown, and unfortunately in the current representation we have to
do that with separate loops and without any dominance relationships.
(This is the same thing preventing us from doing borrows in the
general case.)  The result is that the general case of result emission
is to emit every element of the expansion into a temporary tuple
(requiring a pack loop before the call to initialize the pack), then
process those elements in the body of a second pack loop after the
call.  And that's terrible enough that we really have to do the work
to try to avoid it, which makes all the APIs more complicated.

Anyway, most of the way through the basic plumbing for variadic
generics now.  Next is reabstraction, I think, which I hope will
mostly mean fixing bugs in the infrastructure I've already written.
2023-03-07 03:15:31 -05:00
John McCall
157be3420c Implement the callee side of returning a tuple containing a pack expansion.
This required quite a bit of infrastructure for emitting this kind of
tuple expression, although I'm not going to claim they really work yet;
in particular, I know the RValue constructor is going to try to explode
them, which it really shouldn't.

It also doesn't include the caller side of returns, for which I'll need
to teach ResultPlan to do the new abstraction-pattern walk.  But that's
next.
2023-03-06 04:26:18 -05:00
Michael Gottesman
36306c6a45 [move-only] Treat black hole initialization as a consuming operation.
Otherwise, we don't treat `let _ = x` as a consuming operation.

rdar://102196620
2022-11-10 09:40:32 -08:00
Joe Groff
fdc0e08d60 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-09 13:42:02 -07:00
Joe Groff
3abe16f40f Revert "SILGen: Emit literal closures at the abstraction level of their context. [take 2]" (#39228) 2021-09-09 11:53:43 -05:00
Joe Groff
43506a29a2 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-07 11:55:29 -07:00
Holly Borla
86e1014399 Revert " SILGen: Emit literal closures at the abstraction level of their context." 2021-08-18 09:03:23 -07:00
Joe Groff
309500d4bf SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-08-16 09:39:19 -07:00
Slava Pestov
5d9e704854 SILGen: Move BlackHoleInitialization to Initialization.h 2020-10-11 12:48:30 -04:00
Vedant Kumar
60ec3f1b90 Fix debug description for cases with multiple items (#32282)
* [SILGenFunction] Don't create redundant nested debug scopes

Instead of emitting:

```
sil_scope 4 { loc "main.swift":6:19 parent 3 }
sil_scope 5 { loc "main.swift":7:3 parent 4 }
sil_scope 6 { loc "main.swift":7:3 parent 5 }
sil_scope 7 { loc "main.swift":7:3 parent 5 }
sil_scope 8 { loc "main.swift":9:5 parent 4 }
```

Emit:

```
sil_scope 4 { loc "main.swift":6:19 parent 3 }
sil_scope 5 { loc "main.swift":7:3 parent 4 }
sil_scope 6 { loc "main.swift":9:5 parent 5 }
```

* [IRGenSIL] Diagnose conflicting shadow copies

If we attempt to store a value with the wrong type into a slot reserved
for a shadow copy, diagnose what went wrong.

* [SILGenPattern] Defer debug description of case variables

Create unique nested debug scopes for a switch, each of its case labels,
and each of its case bodies. This looks like:

```
  switch ... { // Enter scope 1.
    case ... : // Enter scope 2, nested within scope 1.
      <body-1> // Enter scope 3, nested within scope 2.

    case ... : // Enter scope 4, nested within scope 1.
      <body-2> // Enter scope 5, nested within scope 4.
  }
```

Use the new scope structure to defer emitting debug descriptions of case
bindings. Specifically, defer the work until we can nest the scope for a
case body under the scope for a pattern match.

This fixes SR-7973, a problem where it was impossible to inspect a case
binding in lldb when stopped at a case with multiple items.

Previously, we would emit the debug descriptions too early (in the
pattern match), leading to duplicate/conflicting descriptions. The only
reason that the ambiguous description was allowed to compile was because
the debug scopes were nested incorrectly.

rdar://41048339

* Update tests
2020-06-10 13:31:10 -07:00
Andrew Trick
34a968c334 Update some comments that are related to formal access. 2018-02-15 11:26:54 -08:00
John McCall
7f22faf968 Substantially rework how SILGen handles bridging as part of laying the
ground work for the syntactic bridging peephole.

- Pass source and dest formal types to the bridging routines in addition
  to the dest lowered type.  The dest lowered type is still necessary
  in order to handle non-standard abstraction patterns for the dest type.

- Change bridging abstraction patterns to store bridged formal types
  instead of the formal type.

- Improve how SIL type lowering deals with import-as-member patterns.

- Fix some AST bugs where inadequate information was being stored in
  various expressions.

- Introduce the idea of a converting SGFContext and use it to regularize
  the existing id-as-Any conversion peephole.

- Improve various places in SILGen to emit directly into contexts.
2017-07-11 12:45:13 -04:00
John McCall
305c94fc5b Pare down the Initialization interface and allow implementations
to insert code before performing an in-place initialization.

Intended to be NFC, but some of the clients needed more rewriting
than others.
2017-03-31 18:55:09 -04:00
Michael Gottesman
5cbf589524 Small ease of use convenience APIs. NFC. 2017-03-27 16:00:34 -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
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
John McCall
e249fd680e Destructure result types in SIL function types.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.

The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results.  It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.

The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*.  The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list.  The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.

A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple.  It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.

Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction.  It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
2016-02-18 01:26:28 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
John McCall
36c605f7dc Remove ScalarToTupleExpr in favor of a flag on TupleShuffleExpr.
Also, implement in-place initialization through tuple shuffles.

Swift SVN r28227
2015-05-06 23:44:26 +00:00
Chris Lattner
d1351e221f completely remove the 'Kind' field/enum of Initialization. NFC.
Swift SVN r27464
2015-04-19 04:50:20 +00:00
Chris Lattner
fa6f078d0a Continue tidying up Initialization, NFC:
- Privatize "kind" in the base Initialization class.
 - Simplify canForwardInBranch() to just isSingleBuffer().
   There is only one client of it (which avoids emitting the
   formation of an optional temporary) and the only cases we're
   dropping is for "_" patterns and single element tuple patterns,
   which are not worth optimizing for.
 - Change getSubInitializationsForTuple() into a virtual method
   since it has wildly different behavior based on the subclass and
   requires otherwise private implementation details of those subclasses
   to implement it.
 - Simplify subclasses based on these changes.



Swift SVN r27463
2015-04-19 04:47:02 +00:00
Chris Lattner
020fe7835d Various cleanups for the initialization logic:
- Use virtual dispatch to localize some predicates instead
   of having special cases for LetValue inits in global places.
 - Improve 'const'ness of methods.
 - Introduce a common "KnownAddressInitialization" class to centralize
   the notion of an initialization corresponding to a specific physical
   address that is known up front.  Consolidate dupes of this concept into
   uses of it.

NFC.



Swift SVN r27462
2015-04-19 04:12:02 +00:00
Chris Lattner
3118f09856 Add SILGen support for Conditional PBD's and add the first example
refutable pattern (expr patterns) to show that this works, this enables
weird things like:

	let 1...40 = foo() else { ... }

:-)



Swift SVN r27050
2015-04-07 00:56:36 +00:00
Chris Lattner
0c35b2e8d4 refactor a bunch of stuff around Initialization to simplify the code and
make it easier to extend, NFC.

 3 files changed, 196 insertions(+), 238 deletions(-)



Swift SVN r27029
2015-04-06 06:00:30 +00:00
Joe Groff
07a47a02d0 SILGen: Remove InOutInitialization and its related "AddressBinding" initialization kind.
We don't need these now that we don't set up argument bindings via initializations.

Swift SVN r24413
2015-01-14 05:51:01 +00:00
John McCall
372d6513bb Don't propagate let-binding Initializations down into
conditional-executed initializers.

Swift SVN r16033
2014-04-08 01:12:56 +00:00
Chris Lattner
1344319677 Rename the internal compiler lexicon from val -> let.
Swift SVN r14408
2014-02-26 21:21:18 +00:00
Chris Lattner
28903887e7 Rename the internal compiler lexicon from let -> val.
Swift SVN r13992
2014-02-17 16:48:21 +00:00
Chris Lattner
827acad533 Various inout improvements:
- purge @inout from comments in the compiler except for places talking about
   the SIL argument convention.
 - change diagnostics to not refer to @inout
 - Change the astprinter to print InoutType without the @, so it doesn't show
   up in diagnostics or in closure argument types in code completion.
 - Implement type parsing support for the new inout syntax (before we just 
   handled patterns).
 - Switch the last couple of uses in the stdlib (in types) to inout.
 - Various testcase updates (more to come).



Swift SVN r13564
2014-02-06 06:22:27 +00:00
Chris Lattner
e57f8e436d simplify tuple processing code. We only want to do tuple element operations
in memory of the available type is address only, so simplify a check and
remove the predicate (which happens to be out of date anyway).


Swift SVN r12814
2014-01-22 23:36:49 +00:00
Chris Lattner
7db7d4a813 Three changes:
- constify the Initialization::getAddressOrNull/hasAddress functions.
 - Teach the initialization logic that 'let' initializations can be
   split into tuple subelements by address (i.e. i
   getSubInitializationsForTuple works on them) when the let decl has
   a backing memory allocation.
 - Teach LetValueInitialization to produce a backing memory object
   for address-only tuple arguments, since they are passed as multiple
   SILArguments and need some place in memory to reassemble them.

The collection fixes a bad miscompilation where the RValue logic emitted
a temporary (through getSingleValue) which we then accidentally lifetime
extended for the duration of the argument.  This led to bad things when
the temporary got destroyed too early.

Thanks to MichaelG for helping narrow down this problem, it initially looked
like a sil optimizer bug.


Swift SVN r12234
2014-01-13 17:24:40 +00:00
Chris Lattner
ed7a3fd4ae tweak comment.
Swift SVN r11928
2014-01-06 17:12:52 +00:00
Chris Lattner
5faf530cf2 implement restructuring assignment of let decls, repurposing the existing
implosion logic.  This resolves rdar://15716277


Swift SVN r11679
2013-12-27 22:30:28 +00:00
Chris Lattner
1788421e5d Change SILGen to lower and bind non-address-only 'let' variables
as values, without a box at all.  This generalizes some of the
previous hacks I had for silgen'ing 'self' as a value instead of
a box, and capturing them with CaptureKind::Constant.




Swift SVN r11360
2013-12-16 20:36:16 +00:00
John McCall
20e58dcf93 Change the type of function values in SIL to SILFunctionType.
Perform major abstraction remappings in SILGen.  Introduce
thunking functions as necessary to map between abstraction
patterns.

Swift SVN r10562
2013-11-19 22:55:09 +00:00
John McCall
298577676e Introduce the monadic ? operator.
A ? operator is interpreted as this if it's left-bound,
so ternary operators now have to be spaced on the left.

Swift SVN r8832
2013-10-02 01:27:45 +00:00
John McCall
a1867380d0 Distinguish the "cleanup handle" and "scope" use-cases
of CleanupsDepth.

Only with different typedefs for now, but the communicative
effect is significant.

Swift SVN r8831
2013-10-02 01:27:41 +00:00
John McCall
916b566fa6 Push and invalidate uninitialized-local cleanups.
No effect currently; just resolves a FIXME.

Swift SVN r8830
2013-10-02 01:27:39 +00:00
Joe Groff
3d4c1251f1 Rename 'byref' attribute to 'inout'.
Swift SVN r8661
2013-09-25 20:56:52 +00:00
Joe Groff
d69eb660a6 SILGen: Emit shadow copies of byref arguments.
Create a local box for byref arguments that can be closed over. The box receives the value of the byref at function entry, and the value in the box at function exit is written back to the byref. This will allow us to eliminate the no-capture restriction on byrefs, allowing them to be used in auto closures and other HOFs, and doing the right thing in the 99% case where closures are effectively nocapture without requiring user annotation. <rdar://problem/14732389>

There are a couple of loose ends:

- The type-checker can lose its restriction on byref captures. I'll do that next.
- Debug info needs to learn how to represent local byref boxes. Adrian is better qualified to decide how to do that.
- Byref shadow copies completely defeat the copy-on-write optimization for String, making append sequences ridiculously slow. Memory promotion needs to learn to eliminate shadow copies completely when it promotes away byref boxes in order to solve this regression.

Swift SVN r8630
2013-09-25 17:19:00 +00:00