Commit Graph

395 Commits

Author SHA1 Message Date
Doug Gregor
4ed45ec830 Revert "Generic specializer: don't allow specialization if it uses an incomplete conformance."
This reverts r27886; a better solution is coming.

Swift SVN r27895
2015-04-29 00:08:26 +00:00
Andrew Trick
a174aa4dfe Add AST and SILGen support for Builtin.isUnique.
Preparation to fix <rdar://problem/18151694> Add Builtin.checkUnique
to avoid lost Array copies.

This adds the following new builtins:

    isUnique : <T> (inout T[?]) -> Int1
    isUniqueOrPinned : <T> (inout T[?]) -> Int1

These builtins take an inout object reference and return a
boolean. Passing the reference inout forces the optimizer to preserve
a retain distinct from what’s required to maintain lifetime for any of
the reference's source-level copies, because the called function is
allowed to replace the reference, thereby releasing the referent.

Before this change, the API entry points for uniqueness checking
already took an inout reference. However, after full inlining, it was
possible for two source-level variables that reference the same object
to appear to be the same variable from the optimizer's perspective
because an address to the variable was longer taken at the point of
checking uniqueness. Consequently the optimizer could remove
"redundant" copies which were actually needed to implement
copy-on-write semantics. With a builtin, the variable whose reference
is being checked for uniqueness appears mutable at the level of an
individual SIL instruction.

The kind of reference count checking that Builtin.isUnique performs
depends on the argument type:

    - Native object types are directly checked by reading the
      strong reference count:
      (Builtin.NativeObject, known native class reference)

    - Objective-C object types require an additional check that the
      dynamic object type uses native swift reference counting:
      (Builtin.UnknownObject, unknown class reference, class existential)

    - Bridged object types allow the dymanic object type check to be
      bypassed based on the pointer encoding:
      (Builtin.BridgeObject)

Any of the above types may also be wrapped in an optional.  If the
static argument type is optional, then a null check is also performed.

Thus, isUnique only returns true for non-null, native swift object
references with a strong reference count of one.

isUniqueOrPinned has the same semantics as isUnique except that it
also returns true if the object is marked pinned regardless of the
reference count. This allows for simultaneous non-structural
modification of multiple subobjects.

In some cases, the standard library can dynamically determine that it
has a native reference even though the static type is a bridge or
unknown object. Unsafe variants of the builtin are available to allow
the additional pointer bit mask and dynamic class lookup to be
bypassed in these cases:

    isUnique_native : <T> (inout T[?]) -> Int1
    isUniqueOrPinned_native : <T> (inout T[?]) -> Int1

These builtins perform an implicit cast to NativeObject before
checking uniqueness. There’s no way at SIL level to cast the address
of a reference, so we need to encapsulate this operation as part of
the builtin.

Swift SVN r27887
2015-04-28 22:54:24 +00:00
Doug Gregor
152de6bb34 Generic specializer: don't allow specialization if it uses an incomplete conformance.
Semantic analysis should be guaranteeing that all conformances that
show up in the AST are complete. Until that day, work around the crash
in rdar://problem/20700616 by not specializing.

Swift SVN r27886
2015-04-28 22:34:40 +00:00
Arnold Schwaighofer
bfcc1fface Make splitBasicBlock public.
Swift SVN r27841
2015-04-27 23:44:55 +00:00
Arnold Schwaighofer
ea6e5e71de InlineCost: expect intrinsics should be free
Swift SVN r27837
2015-04-27 23:43:40 +00:00
Michael Gottesman
9006fca42b Rename SILBuilder::emitDestroyAddr => SILBuilder::emitDestroyAddrAndFold.
Now it matches SILBuilder::emit{StrongRelease,ReleaseValue}AndFold which perform
the same operation but on object types.

Swift SVN r27806
2015-04-27 17:29:50 +00:00
Michael Gottesman
a3aa89d4c4 Remove Callback from SILBuilder and instead rename
emit{StrongRelease,ReleaseValue} => emit{StrongRelease,ReleaseValue}AndFold.
Then introduce a new method emit{StrongRelease,ReleaseValue} that returns a
PointerUnion containing the increment to be deleted if it exists. This obviates
the need for the callback.

Swift SVN r27804
2015-04-27 07:29:13 +00:00
Michael Gottesman
583d7aa30a Add a delete callback to SILBuilder so that if we delete retains and releases in emitStrongRelease, emitReleaseValue, passes (like SILCombine) can update their state. Also teach the closure deletion code how to detect such a case and not send a notification message if no new instruction is created.
Swift SVN r27803
2015-04-27 05:37:09 +00:00
Michael Gottesman
d494735329 Teach capture promotion how to handle all types of partial apply arguments. We technically don't need it now but it would be technical debt to leave it unfixed.
rdar://19552593

Swift SVN r27798
2015-04-27 01:59:46 +00:00
Michael Gottesman
abb34fa1b0 Teach mandatory inlining how to use closure deletion infrastructure.
rdar://19552593

Swift SVN r27751
2015-04-26 05:11:57 +00:00
Michael Gottesman
eed6317da2 Add a callback struct to tryDeleteDeadClosure() that clients can use to be notified of instruction insertion and deletion.
rdar://19552593

Swift SVN r27749
2015-04-26 05:11:54 +00:00
Michael Gottesman
6891258151 Teach tryDeleteDeadClosure how to properly delete all types of captured arguments.
Previously, we relied on certain types not being passed in by the users of the
given function. Since I had a lot on my plate on the time and I knew it was safe
I left it in. Now I am going to be using this function in more places so it
needs to handle everything correctly.

rdar://19552593

Swift SVN r27748
2015-04-26 05:11:52 +00:00
Roman Levenstein
212c6e3be2 [sil-devirtualizer] Improve devirtualization of generics classes with dependent types.
radar://20337006

Swift SVN r27608
2015-04-22 22:29:02 +00:00
Mark Lacey
014602d583 Reenable some devirtualization cases disabled in r26152.
In r26152 a crash was fixed that had been introduced by previous
improvements, but as a result of fixing the crash some cases where we
previously devirtualized were disabled with the intent that they would
be reenabled after further refactoring work was completed.

This commit restores that functionality and reenables the tests.

Swift SVN r27575
2015-04-22 08:24:33 +00:00
Mark Lacey
60311dab22 Coding style clean-ups.
Remove else after return, reduce indentation, etc.

Noticed while reviewing code that uses various SILValue::strip*Casts()
functions.

Swift SVN r27574
2015-04-22 08:24:10 +00:00
Mark Lacey
1859b476d4 Further integration of inlining, devirtualization, and specialization.
This updates the performance inliner to iterate on inlining in cases
where devirtualization or specialization after the first pass of
inlining expose new opportunities for inlining. Similarly, in some cases
inlining exposes new opportunities for devirtualization, e.g. when we
inline an initializer and can now see an alloc_ref that allows us to
devirtualize some class_methods.

The implementation currently has some inefficiencies which increase the
swift compilation time for the stdlib by around 3% (this is swift-time
only, no LLVM time, so overall time does not grow by this much).

Unfortunately the (unchanged) current implementation of the core
inlining trades off improved estimates of code growth for increased
compile time, and that plays a part in why compile time increases as
much as it does. Despite this, I have some ideas on how to win some of
that time back in future patches.

Performance differences are mixed, and this will likely require some
further inliner tuning to reduce or remove some of the losses seen here
at -O. I will open radars for the losses.

Wins:
DeltaBlue                        10.2%
EditDistance                     13.8%
SwiftStructuresInsertionSort     32.6%
SwiftStructuresStack             34.9%

Losses:
PopFrontArrayGeneric            -12.7%
PrimeNum                        -19.0%
RC4                             -30.7%
Sim2DArray                      -14.6%

There were a handful of wins and losses at Onone and Ounchecked as
well. I'll review the perf testing output and open radars accordingly.

The new test case shows an example of the power of the closer
integration here. We are able to completely devirtualize and inline a
series of class_method applies (10 deep in this case, but in theory
substantially deeper) in a single pass of the inliner, whereas before we
could only do a single level per pass of inlining & devirtualization.

Swift SVN r27561
2015-04-22 04:48:13 +00:00
Nadav Rotem
32211041d2 Rename @semantics -> @_semantics.
Swift SVN r27533
2015-04-21 17:10:06 +00:00
Chris Lattner
42b4a966b0 Introduce a new null_class SIL instruction for forming a null pointer
reference to something of class type.  This is required to model
RebindSelfInConstructorExpr correctly to DI, since in the class case, 
self.init and super.init *take* a value out of class box so that it 
can pass the +1 value without performing an extra retain.  Nothing
else in the compiler uninitializes a DI-controlled memory object
like this, so nothing else needs this.  DI really doesn't like something
going from initialized to uninitialized.

Yes, I feel super-gross about this and am really unhappy about it.  I
may end up reverting this if I can find an alternate solution to this
problem.



Swift SVN r27525
2015-04-21 05:56:55 +00:00
Arnold Schwaighofer
722fa41435 splitEdge: Fix dominator tree update
Swift SVN r27484
2015-04-20 16:53:17 +00:00
Roman Levenstein
aa07bc3d90 Lower bridged casts always, when the outcome is not provably failing.
Even when we don't know for sure if a bridged cast would succeed, we still want to lower it to produce a more efficient code that does not performs conformance checks at run-time.

This is useful when performing casts optimizations as a guaranteed optimization.

Swift SVN r27377
2015-04-16 20:28:15 +00:00
Roman Levenstein
0f88c56b23 If a result of unconditional_checked_cast is not used, simply remove the cast.
This is useful when performing casts optimizations as a guaranteed optimization.

Swift SVN r27376
2015-04-16 20:28:15 +00:00
Roman Levenstein
12b1e88d3f Fix a bug in a peephole for checked_cast_addr_br.
It was producing a checked_cast_add_br, which took a metatype inst as it's argument, which is simply wrong, as it is not an address type. SILVerifier was complaining about it. Now we produce an equivalent peephole, but with a correct instruction sequence, which makes SILVerifier happy.

Swift SVN r27375
2015-04-16 20:28:12 +00:00
Roman Levenstein
7fe82963f0 Bail early on casts involving unbound generic types. It is too early to optimize them.
Swift SVN r27374
2015-04-16 20:28:11 +00:00
Roman Levenstein
a8cf05343f Don't try to optimize non-addr types in simplifyCheckedCastAddrBranchInst.
Sometimes, during intermediate optimization steps, the operands of produced checked_cast_addr_br instructions do not actually have address types.
Don't try to optimize further in such cases. Let the optimizer clean-up those instructions.

Swift SVN r27373
2015-04-16 20:28:10 +00:00
Roman Levenstein
782a4120a4 If kind of the instruction was changed by the optimizeCheckedCast*BranchInst, bail.
This avoids segfaults due to de-referencing of a nullptr.

Swift SVN r27372
2015-04-16 20:28:10 +00:00
Roman Levenstein
185e96ce8c Clean-up of retain/release insertion during bridged casts optimizations.
I noticed under Instruments that the bridged casts opts produced a code that was leaking in some cases. Therefore I took the change to re-visit the code and to clean-up the logic for insertion of retains and releases.

Swift SVN r27371
2015-04-16 20:28:09 +00:00
Roman Levenstein
0b6b907a0a Do not produce an intermediate cast between the same ObjC types as it will get eliminated anyways.
When casts optimizations were lowering bridged casts from ObjC to Swift, they were producing internally an intermediate cast from an ObjC type into the expected ObjC type of a bridged cast, before converting this expected ObjC type into a Swift type. In many cases, this resulted in a useless intermediate cast where both types were the same and such a cast would be eliminated afterwards. E.g.

unconditional_checked_cast A to B  // where A is ObjC type and B is a Swift type

was lowered into:

unconditional_checked_cast A to B. _ObjectiveCType // Often useless as A is equal to B. _ObjectiveCType already.
unconditional_checked_cast B._ObjectiveCType to B

This small inefficiency is fixed now. This problem was no observable from outside the optimization pass, it just required additional processing, therefore there is no test-case.

Swift SVN r27370
2015-04-16 20:28:07 +00:00
Erik Eckstein
0c5a97ebc5 SimplifyCFG: fix condition equivalence checking in checked-cast jump threading.
It was wrong in case two checked_cast_br have select_enum (with identical enum operands) as conditions.



Swift SVN r27356
2015-04-16 11:37:39 +00:00
Nadav Rotem
e03d09dd79 Fix a bug in the SIL inliner that prevented the inlining of TryApply instructions.
The inliner sil-builder insertion point has to be before the Apply/TryApply inst,
because TryApply instructions are terminators.

Swift SVN r27332
2015-04-15 21:22:56 +00:00
Mark Lacey
f6ec796780 Integrate generic specialization into the inliner.
During inlining we'll now attempt to first devirtualize and specialize
within the function that we're going to inline into. If we're successful
devirtualizing and inlining, and we'll attempt to inline into the newly
exposed callees first, before inlining into the function we began with.

This does not remove any existing passes of devirtualization or
specialization yet, partially because we don't completely handle all
cases that they handle at this point (e.g. specializing partial
applies).

We do end up specializing deeper into the call graph with this approach
than we did prior to this commit.

I will have some follow-on changes that integrate things further,
allowing us to devirtualize in more cases after inlining into a given
function.

I will also add some directed tests in a future commit.

I tested the stdlib build and this made no difference in build
times. Perhaps after removing other existing phases we'll recapture some
build time.

I'm not seeing reproducible performance differences with this change,
which is not a big surprise at this point. This sets us up for being
able to improve the compilation pipeline in a future release.

Swift SVN r27327
2015-04-15 21:08:51 +00:00
Joe Groff
b03795e5f7 Add a '@convention(xxx)' attribute for specifying function conventions.
This is new attribute we're using to coalesce @thin, @objc_block, and @cc, and to extend to new uses like C function pointer types. Parse the new attribute, but preserve support for the old attributes, and print with the old attributes for now to separate out test changes. Migration fixits and test updates to come. I did take the opportunity here to kill off the '@cc(cdecl)' hack for AST-level function pointer types, which are now only spelt with @convention(c).

Swift SVN r27247
2015-04-13 04:27:02 +00:00
Roman Levenstein
d1698ba1cb Use a _bridgeable suffix for newly introduced fast bridging functions. NFC.
Dave explained that stdlib usually uses the suffix notation in such cases. This change follows his advice.

Swift SVN r27177
2015-04-09 20:59:42 +00:00
Roman Levenstein
39ad4c996b Fix a spelling error. Calleee -> Callee. NFC.
Swift SVN r27173
2015-04-09 18:16:04 +00:00
Roman Levenstein
cd08e967f9 [sil-devirtualizer] Better handling of methods that have their own generic parameters.
Fixed the logic in getSubstitutionsForSuperclass and renamed it into getSubstitutionsForCalleee to better reflect what it does.

rdar://20440616

Swift SVN r27166
2015-04-09 15:28:49 +00:00
Roman Levenstein
57c41a0e00 [sil-devirtualizer] If class contains archetypes, consider it unbound.
We should not try to devirtualize in such cases yet.

Swift SVN r27165
2015-04-09 15:28:48 +00:00
Roman Levenstein
90e5f932c7 Simplify the lookup of a compiler-known library function. NFC.
Swift SVN r27157
2015-04-09 02:35:27 +00:00
Roman Levenstein
7c5717d3ad Address Joe's comments on my r27102 commit. NFC.
Swift SVN r27154
2015-04-09 01:51:59 +00:00
Roman Levenstein
2dd38eee0e [sil-combine] Teach the optimizer how to optimize bridged casts.
If a conformance to _BridgedToObjectiveC is statically known, generate a more efficient code by using the newly introduced library functions for bridging casts.
This covers the casts resulting from SIL optimizations.

Tests are included. I tried to cover most typical casts from ObjC types into Swift types and vice versa and to check that we always generate something more efficient than a checked_cast or unconditional_checked_cast. But probably even more tests should be written or generated by means of gyb files to make sure that nothing important is missing.

The plan is to make the bridged casts SIL optimization a guaranteed optimization. Once it is done, there is no need to lower the bridged casts in a special way inside Sema, because they all can be handled by the optimizer in a uniform way. This would apply to bridging of Error types too.

With this change, no run-time conformance checks are performed at run-time if conformances are statically known at compile-time.
As a result, the performance of rdar://19081345 is improved by about 15%. In the past, conformance checks in this test took 50% of its execution time, then after some improvements 15% and now it is 0%, as it should be.

Swift SVN r27102
2015-04-07 22:53:57 +00:00
Joe Groff
ad0d20c07a Fold "AbstractCC" into SILFunctionType::Representation.
These aren't really orthogonal concerns--you'll never have a @thick @cc(objc_method), or an @objc_block @cc(witness_method)--and we have gross decision trees all over the codebase that try to hopscotch between the subset of combinations that make sense. Stop the madness by eliminating AbstractCC and folding its states into SILFunctionTypeRepresentation. This cleans up a ton of code across the compiler.

I couldn't quite eliminate AbstractCC's information from AST function types, since SIL type lowering transiently created AnyFunctionTypes with AbstractCCs set, even though these never occur at the source level. To accommodate type lowering, allow AnyFunctionType::ExtInfo to carry a SILFunctionTypeRepresentation, and arrange for the overlapping representations to share raw values.

In order to avoid disturbing test output, AST and SILFunctionTypes are still printed and parsed using the existing @thin/@thick/@objc_block and @cc() attributes, which is kind of gross, but lets me stage in the real source-breaking change separately.

Swift SVN r27095
2015-04-07 21:59:39 +00:00
Mark Lacey
fea3321f59 Update the generic specializer to maintain the call graph.
Swift SVN r27024
2015-04-05 19:27:40 +00:00
Mark Lacey
5adf76b4dd Missed one comment update.
Swift SVN r27019
2015-04-05 07:14:45 +00:00
Mark Lacey
8fad304e02 Fix a leak.
swift::clearBlockBody() in Local.cpp was popping instructions rather
than erasing them, resulting in leaking any instructions removed via
this function (which is reached via removeDeadBlock(), called throughout
SimplifyCFG).

Also tweak a couple comments and remove an assert that cannot fire.

Swift SVN r27018
2015-04-05 07:12:35 +00:00
Mark Lacey
730ef41385 Make devirtualizer clients remove old applies.
This makes it feasible for clients to maintain the call graph.

Swift SVN r26997
2015-04-05 02:27:57 +00:00
Mark Lacey
c1dc4bf76a Reword a couple statistic descriptions.
Swift SVN r26970
2015-04-04 02:29:18 +00:00
Roman Levenstein
55ea9ec0e3 [sil-combine] Minor clean-up of casts optimizations. NFC.
Add more checks and logic into emitSuccessfulIndirectUnconditionalCast and emitSuccessfulScalarUnconditionalCast, so that its clients in sil-combine can be simplified by avoiding looking into special cases.

Swift SVN r26885
2015-04-02 19:57:35 +00:00
Roman Levenstein
a7d0eb17ba [sil-combine] casts to/from existentials cannot be further simplified.
This should fix a bug in Adventure reported in rdar://20396204.

Swift SVN r26875
2015-04-02 17:20:23 +00:00
Roman Levenstein
b0963b443f [sil-simplify-cfg] Fix a bug in checked_cast_br jump-threading.
If current checked_cast_br is reachable via success, failure and unknown at the same time, then we simply don't know the outcome of the dominating check.
No jump-threading should be performed in this case.

I'll commit the test-case tomorrow. The test-case from the radar depends too much on the stdlib internals. We need something smaller and simpler.

rdar://20389307

Swift SVN r26841
2015-04-02 00:49:35 +00:00
Roman Levenstein
0e47a228e1 [sil-simplify-cfg] Fix a stupid copy/paste bug introduced during recent re-factoring. NFC.
This fix is done as part of the rdar://20389307.

Swift SVN r26840
2015-04-02 00:49:33 +00:00
Mark Lacey
13bbd3b11e Move generic specializer cloning code into GenericCloner.h/GenericCloner.cpp.
This leaves nothing but the helper for specializing an ApplySite in
Generics.h/Generics.cpp, and I expect to rename these files accordingly
at some point.

Swift SVN r26827
2015-04-01 22:01:32 +00:00
Mark Lacey
6e02f6bf21 More formatting tweaks needed after previous refactoring.
Swift SVN r26826
2015-04-01 22:01:30 +00:00