Commit Graph

33 Commits

Author SHA1 Message Date
Slava Pestov
9ec80df97e SIL: Remove curried SILDeclRefs 2020-03-19 02:20:21 -04:00
Michael Gottesman
ac1f956ac0 Split predictable mem opts into two different passes, one that runs before diagnostics and one that runs after diagnostics.
I discovered while updating PMO for ownership that for ~5 years there has been a
bug where we were treating copy_addr of trivial values like an "Assign" (in PMO
terminology) of a non-trivial value and thus stopping allocation
elimination. When I fixed this I discovered that this caused us to no longer
emit diagnostics in a predictable way. Specifically, consider the following
swift snippet:

  var _: UInt = (-1) >> 0

Today, we emit a diagnostic that -1 can not be put into a UInt. This occurs
since even though the underlying allocation is only stored into, the copy_addr
assign keeps it alive, causing the diagnostics pass to see the conversion. With
my fix though, we see that we are only storing into the allocation, causing the
allocation to be eliminated before the constant propagation diagnostic pass
runs, causing the diagnostic to no longer be emitted.

We should truly not be performing this type of DCE before we emit such
diagnostics. So in this commit, I split the pass into two parts:

1. A load promotion pass that performs the SSA formation needed for SSA based
diagnostics to actually work.

2. An allocation elimination passes that run /after/ SSA based diagnostics.

This should be NFC since the constant propagation SSA based diagnostics do not
create memory operations so the output should be the same.
2019-01-17 14:48:03 -08:00
Michael Gottesman
be475827db [pmo] Move handling of releases: ElementUseCollector::{collectFrom,collectContainerUses}()
Since:

1. We only handle alloc_stack, alloc_box in predictable memopts.
2. alloc_stack can not be released.

We know that the release collecting in collectFrom can just be done in
collectContainerUses() [which only processes alloc_box].

This also let me simplify some code as well and add a defensive check in case
for some reason we are passed a release_value on the box. NOTE: I verified that
previously this did not result in a bug since we would consider the
release_value to be an escape of the underlying value even though we didn't
handle it in collectFrom. But the proper way to handle release_value is like
strong_release, so I added code to do that as well.
2019-01-05 23:47:07 -08:00
Michael Gottesman
fd4828e40a Eliminate -assume-parsing-unqualified-ownership-sil from tests.
I am doing this separately from the actual change to eliminate the option to
make it easier to review.
2018-12-19 12:54:13 -08:00
Michael Gottesman
b9f69cb0ea [pmo] Eliminate incomplete support for promoting enums.
This was never implemented correctly way back in 2013-2014. It was originally
added I believe so we could DI checks, but the promotion part was never added.

Given that DI is now completely split from PMO, we can just turn this off and if
necessary add it back on master "properly".

rdar://41161408
2018-06-26 18:49:08 -07:00
Michael Gottesman
659d8638da Add newline at end of test file.
As requested by @shajrawi in https://github.com/apple/swift/pull/16545.
2018-05-11 12:50:07 -07:00
Michael Gottesman
269f8e8d56 [pred-memopts] Rather than asserting on recursive initialization, just return false and bail.
Until the beginning of the ownership transition, DI and predictable mem opts
used the same memory use collector. I split them partially since I need to turn
on ownership for predictable mem opts at one time, but also b/c there was a huge
amount of special code that would only trigger if it was used by DI or used by
predictable mem opts. After I did the copy some of the asserts that were needed
for DI remained in the predictable mem opts code. When pred-memopts was only run
in the mandatory pipeline keeping these assertions were ok, but pred-memopts was
recently added to the perf pipeline meaning that it may see code that breaks
these DI invariants (and thus hit this assertion).

We should remove this limitation on predictable-memopts but that would require
some scheduled time to read the code (more than I have to fix this bug = p). So
instead I changed the code to just bail in these cases.

rdar://40032102
2018-05-11 09:50:32 -07:00
Arnold Schwaighofer
fac09e985b SIL : Use the enum 's generic signature and the payloads type for an indirect enum payload's box type.
i.e for:

enum Indirect<T> {
  indirect cast payload(first: T, second :T)
}

let _ = Indirect<X>

The payload's SIL box type will be:

$<t_0_0> { var (first: t_0_0, second: t_0_0) } <X>

rdar: //36799330
2018-01-27 15:33:47 -08:00
Michael Gottesman
e74367f2b3 [pred-memopt] Only promote destroy_addr if we know that otherwise the allocation is dead.
Previously, we just always promoted destroy_addr. With ownership, this does not
work as well since we need to be able to reason about the take operation that we
are performing. In the general case, this would require adding code to
pred-memopts for tracking reads and for compensation store code since we would
need to eliminate the store of the taken value to prevent a double use.

I am going to loop back around later in the year and add back this code once the
time is available. I filed SR-6341. In case any third party contributor is
interested in looking at re-enabling this optimization before I get back to it.

rdar://31521023
2017-11-10 13:01:22 -08:00
Michael Gottesman
b17935aff2 [pred-memopt] Rather than extracting values at the load site, extract at the store site.
Previously in PredMemOpts, we would insert any extracts at the load site, i.e.:

  store %foo to %0
  ...
  %1 = struct_element_addr %0, $Type, $Type.field
  %2 = load %1
  ...
  apply %use(%2)

would transform to:

  store %foo to %0
  ...
  %2 = struct_extract %foo
  apply %use(%2)

This framework will not work with Ownership enabled since the value stored is
considered consumed by the store. This change fixes the issue by moving such
non-destructive extracts to occur while %foo is considered live, i.e. before the
store:

  %2 = struct_extract %foo
  store %foo to %0
  ...
  apply %use(%2)

This means that we have to store insertion points for each store that provides
us with available values and insert the extracts at those points. This creates
some complications in the case where we have multiple stores since we need to
deal with phi nodes. Rather than dealing with it by hand, we just insert the
extracts at each point and then use the SSA updater to insert the relevant phi
nodes.

rdar://31521023
2017-11-08 10:40:39 -08:00
Michael Gottesman
f08553a49d [PMOpt] Add some more tests around geps.
This is to ensure that when I add the destructive code when ownership is
enabled, the non-ownership variant doesn't break. I have to move the rest of the
pipeline to -Onone at the same time. Once that is done, I will remove more code.

NFC.

rdar://31521023
2017-11-06 12:55:56 -08:00
Michael Gottesman
c6696cee07 [pred-memopts] Eliminate all dead references to AssignInst.
AssignInst is eliminated by DI so we should /never/ see any AssignInst once DI
runs. So this code is dead.

Just shaved off of a larger commit to make it easier to review the larger
commit.

rdar://31521023
2017-10-29 16:49:19 -07:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
Erik Eckstein
f8034ac7bf PredictableMemOpt: be more conservative about address_to_pointer
Handling address_to_pointer as a plain inout missed some mutations and lead to miscompiles.
We now treat address_to_pointer as escaping address.

Fixes SR-3554
2017-01-10 09:25:51 -08:00
Joe Groff
277608a69b Print and parse SILBoxTypes with a new syntax.
Use a syntax that declares the layout's generic parameters and fields,
followed by the generic arguments to apply to the layout:

  { var Int, let String } // A concrete box layout with a mutable Int
                          // and immutable String field
  <T, U> { var T, let U } <Int, String> // A generic box layout,
                                        // applied to Int and String
                                        // arguments
2016-12-02 13:44:22 -08:00
Joe Groff
e1e7e19248 SIL: Construct alloc_box insns with the type of the box.
This becomes necessary with generalized boxes, since the box type isn't derivable from a single field type.
2016-11-03 19:26:42 -07:00
Michael Gottesman
20dd563efb [semantic-arc] Update tests for qualified/unqualified ownership and SILGen emission of copy_value, destroy_value. 2016-10-29 20:11:09 -07:00
practicalswift
f44686d825 [gardening] Fix trailing whitespace in *.cfg.in, *.html, *.mm and *.sil files 2016-10-29 14:06:43 +02:00
Joe Groff
e4c67e2d5a SIL: Give project_box a field index operand.
Allow project_box to get the address of any field in a multi-field box.
2016-10-24 13:10:41 -07:00
Dmitri Gribenko
d175b3b66d Migrate FileCheck to %FileCheck in tests 2016-08-10 23:52:02 -07:00
Joe
3938d5682a [SE-0095] [Runtime], [Demangler], & AST printer updated to new composition syntax
- All parts of the compiler now use ‘P1 & P2’ syntax
- The demangler and AST printer wrap the composition in parens if it is
in a metatype lookup
- IRGen mangles compositions differently
    - “protocol<>” is now “swift.Any”
    - “protocol<_TP1P,_TP1Q>” is now “_TP1P&_TP1Q”
- Tests cases are updated and added to test the new syntax and mangling
2016-07-19 12:01:37 -07:00
Chris Lattner
af30ae3222 Remove the last parts of the Boolean protocol, finishing up:
SE-0109: Remove the Boolean protocol.

We still love you George, even if we forgot your e.
2016-07-17 22:18:17 -07:00
practicalswift
c760f6dfbf [gardening] Add whitespace: "foo,bar" → "foo, bar" 2016-04-12 22:31:46 +02:00
Dmitri Gribenko
0f36bec31f Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-02-18 16:41:35 -08: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
Max Moiseev
9a018bd77d Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-01-20 14:38:22 -08:00
Erik Eckstein
8110b1ebc8 [SIL] Let alloc_box return a single value.
And use project_box to get to the address value.
SILGen now generates a project_box for each alloc_box.
And IRGen re-uses the address value from the alloc_box if the operand of project_box is an alloc_box.
This lets the generated code be the same as before.

Other than that most changes of this (quite large) commit are straightforward.
2016-01-19 08:59:24 -08:00
Max Moiseev
08e1e4a043 Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-01-11 16:51:11 -08:00
Erik Eckstein
6ff2f09796 [SIL] Let alloc_stack return a single value.
Having a separate address and container value returned from alloc_stack is not really needed in SIL.
Even if they differ we have both addresses available during IRGen, because a dealloc_stack is always dominated by the corresponding alloc_stack in the same function.

Although this commit quite large, most changes are trivial. The largest non-trivial change is in IRGenSIL.

This commit is a NFC regarding the generated code. Even the generated SIL is the same (except removed #0, #1 and @local_storage).
2016-01-06 17:35:27 -08:00
Max Moiseev
f51e708a8f Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-01-04 12:25:25 -08:00
practicalswift
fa0b339a21 Fix typos. 2015-12-26 17:51:59 +01:00
Max Moiseev
806be29941 Merge remote-tracking branch 'origin' into swift-3-api-guidelines 2015-12-14 12:05:35 -08:00
Andrew Trick
bd35b4789c Move test/SILOptimizer files to reflect lib/SILOptimizer. 2015-12-11 15:53:22 -08:00