Commit Graph

3 Commits

Author SHA1 Message Date
Erik Eckstein
7cceaff5f3 SIL: don't print operand types in textual SIL
Type annotations for instruction operands are omitted, e.g.

```
  %3 = struct $S(%1, %2)
```

Operand types are redundant anyway and were only used for sanity checking in the SIL parser.

But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:

* if the block with the definition appears after the block where the operand's instruction is located

* if a block or instruction is printed in isolation, e.g. in a debugger

The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
2024-11-21 18:49:52 +01:00
Nate Chandler
ed623d7b64 [NFC] Shortened SIL [init] flag.
Instead of writing out [initalization] for some instructions, use [init]
everywhere.
2022-10-27 10:38:54 -07: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