Commit Graph

312 Commits

Author SHA1 Message Date
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
Erik Eckstein
462e58d3cb SILLocation: a big refactoring and reducing its size from 3 to 2 words
My goal was to reduce the size of SILLocation. It now contains only of a storage union, which is basically a pointer and a bitfield containing the Kind, StorageKind and flags. By far, most locations are only single pointers to an AST node. For the few cases where more data needs to be stored, this data is allocated separately: with the SILModule's bump pointer allocator.

While working on this, I couldn't resist to do a major refactoring to simplify the code:

* removed unused stuff
* The term "DebugLoc" was used for 3 completely different things:
    - for `struct SILLocation::DebugLoc` -> renamed it to `FilePosition`
    - for `hasDebugLoc()`/`getDebugSourceLoc()` -> renamed it to `hasASTNodeForDebugging()`/`getSourceLocForDebugging()`
    - for `class SILDebugLocation` -> kept it as it is (though, `SILScopedLocation` would be a better name, IMO)
* made SILLocation more "functional", i.e. replaced some setters with corresponding constructors
* replaced the hand-written bitfield `KindData` with C bitfields
* updated and improved comments
2021-01-29 20:28:21 +01:00
Erik Eckstein
b7351780f7 SIL: move all the block-list modifying APIs to SILFunction.
... and remove SILFunction::getBlocks().

It's just a cleanup, NFC.
2021-01-14 17:35:31 +01:00
Michael Gottesman
4801fe1966 Fix a typo in a comment. 2020-12-15 13:52:08 -08:00
Michael Gottesman
3de8263b26 [silgenpattern] When emitting address only enum element dispatch, do not leak the switch's operand along the default path.
For the following discussion, let OP be the switch's operand. This is
implemented by:

* Modeling switch_enum_addr as not forwarding OP and instead delegate the
  forwarding of OP to be done by each enum case. This matches what SILGen is
  actually doing since the actual taking of the address in SIL is done in each
  enum case block by an unchecked_take_enum_data_addr.

* In each enum case, I treat OP as being forwarded into an irrefutable
  sub-tree. I follow the pattern of other places this is done by creating a
  CleanupStateRestorationScope and using forwardIntoIrrefutableSubTree. This
  ensures that if I forward OP in the enum case, it just becomes dormant instead
  of being thrown away.

* Inside each case, there is a bunch of code that does some final preparations
  to src before dispatching to the inner dispatch. This code was written using
  old low-level SILValue APIs where ownership is done by hand. I replaced all of
  that by hand ownership with higher level Managed Value APIs that automatically
  handle ownership for the user. This simplified the implementation and ensured
  correctness via SILGenBuilder API invariants.

The end result of all of these together is that:

1. The cleanup on OP is still live when we emit the default case later than the
   cleanups. This eliminates the leak that I am fixing.

2. We have greater correctness since the SILGenBuilder APIs automatically handle
   ownership for us.

3. We have eliminated some brittle logic that could in the future introduce
   bugs. Specifically, I noticed that if we were ever given a
   ConsumableManagedValue that was CopyOnSuccess or BorrowAlways but its
   ManagedValue was a +1 value, we would leak. I could not figure out how to
   create a Swift test case that would go down this code path though = (. But
   that being said, it is one new language feature away from being broken. I
   added some asserts to ConsumableManagedValue that ensures this invariant, so
   we are safe. If it is inconvenient, we can also cause ConsumableManagedValue
   to create a new ManagedValue when it detects this condition without the
   cleanup. But lets see how difficult it is to keep this invariant.

In terms of testing, I put in both a SILGen test and also an end<->end
interpreter test to ensure this doesn't break again.

rdar://71992652
SR-13926
2020-12-14 21:09:20 -08:00
Michael Gottesman
f7e6aa5847 [silgenpattern] Rename an EnumElementDecl value from elt -> eltDecl.
Since we are working with values here, it can be confusing when reading the code
that elt is an EnumElementDecl. The rename to eltDecl will make it much clearer.
2020-12-14 21:09:20 -08:00
Michael Gottesman
c026e95cce [ownership] Extract out SILOwnershipKind from ValueOwnershipKind into its own type and rename Invalid -> Any.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
2020-11-10 14:29:11 -08:00
Suyash Srijan
6a7b38d7ef [SILGenPattern] Silence redundant unreachable enum case warning (#33336) 2020-08-22 01:58:44 +01:00
Michael Gottesman
092edd6621 [ast] Rename VarPattern -> BindingPattern.
VarPattern is today used to implement both 'let' and 'var' pattern bindings, so
today is already misleading. The reason why the name Var was chosen was done b/c
it is meant to represent a pattern that performs 'variable binding'. Given that
I am going to add a new 'inout' pattern binding to this, it makes sense to
give it now a better fitting name before I make things more confusing.
2020-07-16 18:56:01 -07:00
Robert Widmann
426d930d10 Merge pull request #32301 from CodaFi/location-location-location
Strip TypeLoc out of Patterns
2020-06-10 19:25:56 -07: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
Robert Widmann
fc9070c072 Strip TypeLoc from IsPattern 2020-06-10 13:29:39 -07:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Owen Voorhees
43e2d107e1 [SE-0276] Implement multi-pattern catch clauses
Like switch cases, a catch clause may now include a comma-
separated list of patterns. The body will be executed if any
one of those patterns is matched.

This patch replaces `CatchStmt` with `CaseStmt` as the children
of `DoCatchStmt` in the AST. This necessitates a number of changes
throughout the compiler, including:
- Parser & libsyntax support for the new syntax and AST structure
- Typechecking of multi-pattern catches, including those which
  contain bindings.
- SILGen support
- Code completion updates
- Profiler updates
- Name lookup changes
2020-04-04 09:28:26 -07:00
Michael Gottesman
6c5c853339 [ownership] Change guaranteed args from transformation terminators to not require end_borrows.
For those who are unaware, a transformation terminator is a terminator like
switch_enum/checked_cast_br that always dominate their successor blocks. Since
they dominate their successor blocks by design and transform their input into
the args form, we can validate that they obey guaranteed ownership semantics
just like a forwarding instruction.

Beyond removing unnecessary code bloat, this also makes it significantly more
easier to optimize/work with transformation terminators when converting @owned
-> @guaranteed since we do not need to find end_borrow points when the owned
value is consumed.

<rdar://problem/59097063>
2020-02-02 16:59:57 -08:00
Saleem Abdulrasool
7d8aac60ca disambiguate some type shadowing (NFCI)
Adjust the type shadowing identified by GCC 7.  The declaration shadows
a type which changes the meaning of the identifier subsequently.
2019-12-23 15:34:55 -08:00
Arnold Schwaighofer
33f4f57cc4 SILGen: Add TypeExpansionContext to SILGen 2019-11-11 14:21:52 -08:00
Robert Widmann
8a69f886ad Merge pull request #27955 from AnthonyLatsis/bracestmt_cleanup
NFC: Solidify and tidy up the BraceStmt interface
2019-10-31 13:48:40 -07:00
Anthony Latsis
6325915b4b NFC: Solidify and tidy up the BraceStmt interface 2019-10-30 16:43:59 +03:00
Michael Gottesman
26a734e58e [sil] Rename ValueOwnershipKind::{Any,None} 2019-10-25 10:28:25 -07:00
Robert Widmann
5a8d0744c3 [NFC] Adopt TypeBase-isms for GenericSignature
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase.  In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
2019-09-30 14:04:36 -07:00
Joe Groff
7adfc52447 SILGen: Emit bb args for shared loadable case bindings that come after address-only ones.
Looks like a think-o; even if we see an address-only binding in a shared pattern block, we still
expect bb args in the lowered basic block for anything that comes after it. rdar://problem/53956564
2019-08-06 15:09:01 -07:00
Saleem Abdulrasool
731c31f9a5 MSVC: litter the code with llvm_unreachable (NFC)
Add `llvm_unreachable` to mark covered switches which MSVC does not
analyze correctly and believes that there exists a path through the
function without a return value.
2019-06-01 19:02:46 -07:00
Michael Gottesman
adcfda6f6d [silgenpattern] When binding values, use a ManagedValue instead of an RValue to avoid implicitly exploding tuples.
In SILGenPattern, we need to be able to unforward cleanups when we explode
tuples. Thus we can't use RValue in SILGenPattern since it may implicitly
explode tuples (which without modifying RValue itself we can not
unforward). This patch removes a specific RValue usage that we can replace with
the use of a ManagedValue instead.

rdar://49903264
2019-05-16 12:41:08 -07:00
Slava Pestov
16d5716e71 SIL: Use the best resilience expansion when lowering types
This is a large patch; I couldn't split it up further while still
keeping things working. There are four things being changed at
once here:

- Places that call SILType::isAddressOnly()/isLoadable() now call
  the SILFunction overload and not the SILModule one.

- SILFunction's overloads of getTypeLowering() and getLoweredType()
  now pass the function's resilience expansion down, instead of
  hardcoding ResilienceExpansion::Minimal.

- Various other places with '// FIXME: Expansion' now use a better
  resilience expansion.

- A few tests were updated to reflect SILGen's improved code
  generation, and some new tests are added to cover more code paths
  that previously were uncovered and only manifested themselves as
  standard library build failures while I was working on this change.
2019-04-26 22:47:59 -04:00
Michael Gottesman
14d39c0cf9 [silgenpattern] Fix ownership error which could result in a use-after-free.
Specifically, in order to generate runtime errors when we do not handle an enum
appropriately, we form a metatype from the input of the switch. The problem is
that by the time we get to the leaf of the emission tree where this metatype is
created, the input of the switch may have already been consumed. This means
creating the metatype could be a use after free.

This patch fixes the problem by emitting the value_metatype after we emit the
subject of the switch, but before we emit the switch itself.

rdar://49562761
2019-04-10 08:48:27 -07:00
Michael Gottesman
564b4fc11a [silgenpattern] Fix some stack-use-after-free errors caused by iterating over an Optional<ArrayRef<T>>.
Specifically the bad pattern was:

```
   for (auto *vd : *caseStmt->getCaseBodyVariables()) { ... }
```

The problem is that the optional is not lifetime extended over the for loop. To
work around this, I changed the API of CaseStmt's getCaseBodyVariable methods to
never return the inner Optional<MutableArrayRef<T>>. Now we have the following 3
methods (ignoring const differences):

1. CaseStmt::hasCaseBodyVariables().

2. CaseStmt::getCaseBodyVariables(). Asserts if the case body variable array was
   never specified.

3. CaseStmt::getCaseBodyVariablesOrEmptyArray(). Returns either the case body
   variables array or an empty array if we were never given any case body
   variable array.

This should prevent anyone else in the future from hitting this type of bug.

radar://49609717
2019-04-04 13:34:36 -07:00
Michael Gottesman
dc7879d48f Fix ASAN error caused by assigning/getting from the same DenseMap in one statement.
The problem would occur if after we accessed the value, we grew the DenseMap to
insert the value again. But putting in an extra auto I avoid the problem here.

rdar://49609717
2019-04-04 13:34:36 -07:00
Michael Gottesman
7b0d8455ca [ast][silgen] Wire up the case body var decls and use them in SILGenPattern emission to fix the evil fallthrough bug.
rdar://47467128
2019-04-03 23:51:06 -07:00
Michael Gottesman
7b27b4b502 [silgenpattern] Change SILGenPattern to use CaseStmt::hasFallthroughDest() instead of computing this itself.
rdar://47467128
2019-03-14 11:25:41 -07:00
Michael Gottesman
85ee550669 [silgenpattern] When we switch on an enum with an associated type that is empty, create a phi argument for it.
Previously we were handling this like we did not have any associated type. This
caused us to break the requirement in [ossa] that all switch_enum successors
associated with payloaded enums must have arguments. We still emit the empty
tuple value (or an undef tuple) if we do not have any associated type.
2019-03-12 14:59:50 -07:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04:00
Slava Pestov
c791c4a137 SIL: SILUndef must be aware of the resilience expansion
The ownership kind is Any for trivial types, or Owned otherwise, but
whether a type is trivial or not will soon depend on the resilience
expansion.

This means that a SILModule now uniques two SILUndefs per type instead
of one, and serialization uses two distinct sentinel IDs for this
purpose as well.

For now, the resilience expansion is not actually used here, so this
change is NFC, other than changing the module format.
2019-03-12 00:30:35 -04:00
Michael Gottesman
87604fedc7 Merge pull request #23161 from gottesmm/pr-a5f2826a8beda8910e2b0dc7efba52dce1379f8d
[silgenpattern] Only emit a shared case if we have a fallthrough/mult…
2019-03-07 17:04:07 -08:00
Michael Gottesman
6113566089 [silgenpattern] Convert two Pattern::forEachVariables() to instead use Pattern::collectVariables().
This maps more cleanly onto CaseStmt::getCaseBodyVariables() and cleans up the
diff for changing to use said method instead.
2019-03-07 12:01:48 -08:00
Michael Gottesman
9f0375e3c9 [silgenpattern] Only emit a shared case if we have a fallthrough/multiple cast items.
There was a bug here where we were emitting a shared case if we had arguments.
That is why we needed the hacked in deletion of that block when we emitted
shared blocks. I was able to replace that with an assert to make sure that we do
not regress.

This additionally improved our code generation by eliminating a potential extra
copy when we had such a case. That is where the test updates come from.
2019-03-07 11:54:07 -08:00
Michael Gottesman
4fefea5cbf [silgenpattern] Reduce indentation and clean up code by inverting an if condition and using an early exit. 2019-03-06 12:45:03 -08:00
Michael Gottesman
99c62ea5da [silgenpattern] Extract out the large completion handler lambda into its own function.
This makes it easier to read/reason about SILGenPattern::emitSwitchStmt().
2019-03-06 12:33:58 -08:00
Michael Gottesman
c8cdc46f02 [silgenpattern] Reduce indentation by inverting a condition. 2019-03-06 11:28:05 -08:00
Michael Gottesman
0f1510bfdf Merge pull request #22723 from gottesmm/pr-4c62ddbcb693de79222f5cd1f86a2a89f0d879bd
[silgen] Eliminate more unneeded indentation by inverting an if state…
2019-02-19 16:46:20 -08:00
Michael Gottesman
c04afbd4a6 [silgen] Eliminate more unneeded indentation by inverting an if statement. 2019-02-19 15:05:14 -08:00
Michael Gottesman
7989d3f48c Merge pull request #22720 from gottesmm/pr-92e66215cb00ac99f0a42ba2235807d017811217
[silgen] Remove some unnecessary indentation from SILGenPattern::emitSwitchStmt
2019-02-19 14:59:21 -08:00
Michael Gottesman
9b9d01ea5d [silgen] Eliminate another level of indentation by inverting an if statement and using a continue. 2019-02-19 13:31:52 -08:00
Michael Gottesman
cd2fbfcd81 [silgen] Use early exits and invert an if condition to reduce indentation. 2019-02-19 13:31:52 -08:00
Michael Gottesman
0b3aba4c82 [silgen] Eliminate another level of indentation by inverting an if condition in a for loop. 2019-02-19 13:04:28 -08:00
Michael Gottesman
af40fcfe6b [silgen] Use early breaks in an if-else-if block instead of having a break at the end.
Just reducing indentation more.
2019-02-19 13:04:28 -08:00
Michael Gottesman
9570384646 [silgen] Use an early exit to reduce indentation. NFC. 2019-02-19 13:04:28 -08:00
Andrew Trick
f3f5848e29 Remove a stale UnenforcedAccess marker from SILGenPattern.
NFC unless -enable-verify-exclusivity is on.

Boxed (indirect) enum loads are not formal accesses so they should not
have access markers. For a while, we used UnenforcedAccess in this
case to signal to the verifier that this is actually a safe load. But
that isn't needed. The verifier just ignores loads from unidentified
storage instead.

There are two code paths that had this UnenforcedAccess marker. One
was cleaned up, and the other was not. So finish the cleanup and add a
unit test for both SILGen code paths.
2019-02-13 19:00:51 -08:00
Michael Gottesman
d364bb359b [silgenpattern] Fix the box handling in the old silgenpattern enum code to not pass a load_borrow payload as BorrowAlways instead of TakeAlways.
Thanks to Luiz Fernando Silva for the test case!

SR-9871
rdar://problem/47852446
2019-02-07 12:35:28 -08:00
Michael Gottesman
a53e351d37 [silgenpattern] Fix a leak in tuple pattern emission.
Today SILGenPattern maintains the following invariants:

1. All values passed into a switch must be either TakeAlways or BorrowAlways and
   loadable input values will be loaded.

2. Loadable types passed to a subtree must be loaded.

3. TakeOnSuccess can only occur with address only types and only in subtrees.

4. A TakeOnSuccess value must go through "fake borrowing"
   (i.e. forward/unforwarding) to ensure that along failing cases, we properly
   re-enable the cleanup on the aggregate. This means that TakeOnSuccess can
   never be handled as a loadable value with ownership enabled and that any
   take_on_success value since the original cleanup on the parent value was
   disabled must be at +1.

5. We use BorrowAlways instead of TakeOnSuccess for objects to express the
   notion that the object is not owned by the sub-tree.

The bug in this tuple code occured at the a place in the code where we go from
an address only parent type to a loadable subtype via TakeOnSuccess. I was
trying to follow (5) and thus I converted the subvalue to use a {load_borrow,
BorrowAlways}. The problem with this is that I lost the cleanup from the tuple
subvalue since take_on_success is just simulating +0 and thus entails having a
cleanup for each of the underlying tuple values.

The fix here was to:

* Create a cleanup for the loadable subvalue leaving it in memory. This address
  version of the subvalue we use for the purposes of unforwarding. This avoids
  (4).
* load_borrow the subvalue and pass that off to the subtree. This ensures that
  we respect (2), (3), (4).
* Unforward in the failure case the in memory subvalue.

This gives us both characteristics as well as in the future the possibility of
enforcing via the ownership verifier that the borrow ends before the
destroy_addr.

I also sprinkled some assertions liberally to maintain invariants.

rdar://47034816
2019-01-09 15:14:15 -08:00