Commit Graph

44 Commits

Author SHA1 Message Date
Nadav Rotem
d78b376d07 [passes] Replace the old invalidation lattice with a new invalidation scheme.
The old invalidation lattice was incorrect because changes to control flow could cause changes to the
call graph, so we've decided to change the way passes invalidate analysis.  In the new scheme, the lattice
is replaced with a list of traits that passes preserve or invalidate. The current traits are Calls and Branches.
Now, passes report which traits they preserve, which is the opposite of the previous implementation where
passes needed to report what they invalidate.

Node: I tried to limit the changes in this commit to mechanical changes to ease the review. I will cleanup some
of the code in a following commit.

Swift SVN r26449
2015-03-23 21:18:58 +00:00
Dave Abrahams
e88572391e Revert "Make sure that we do not try to create shared versions of stdlib_binary_only functions when specializing."
This reverts commit r26001; it broke validation-tests/stdlib/String.swift

Swift SVN r26005
2015-03-12 00:52:38 +00:00
Michael Gottesman
d88f3767c3 Make sure that we do not try to create shared versions of stdlib_binary_only functions when specializing.
This can only happen in the closure specializer and the generic
specializer since all other specializations either copy the linkage of
the original function (function signature opts) or clone closures/thunks
which have shared linkage.

I put in a verifier check that makes sure we do not create shared
versions of these functions. The real problem has to do with serializing
these sorts of functions, but since we always serialize shared
functions, it makes sense to just ban it.

rdar://20082696

Swift SVN r26001
2015-03-11 23:18:56 +00:00
Dmitri Hrybenko
61286f0260 Fix warnings produced by a newer version of Clang
Swift SVN r25257
2015-02-12 23:50:47 +00:00
Michael Gottesman
f164dd5615 [closure-spec] Use a proper cleanup location instead of a SILFileLocation.
This is checked by the verifier.

Swift SVN r25133
2015-02-10 20:22:03 +00:00
Michael Gottesman
cf11a16da5 [closure-spec] Use a SILFileLocation(SourceLoc()) instead of a ImplicitReturn location to appease the verifier.
Swift SVN r25128
2015-02-10 19:12:29 +00:00
Michael Gottesman
0d0285bc53 [closure-specializer] Fix various parts of the closure specializer.
Before this commit the closure specializer was broken in the following ways:

1. We assumed that the closure was always passed in at +1. This meant that we
would leak the closure in guaranteed contexts.

2. For correctness reasons we were relying on the closure having only one user,
the apply to the function we were going to specialize.

This was important since we reused the retain of the partial apply's captured
arguments as the @owned retain for each of the captured variables at the
specialized callsite. If one has multiple such specializations then one needs to
insert additional retains for each capture for each specialization.

Since the partial_apply only had one use and consumed the captured arguments,
the partial_apply could always be eliminated and we could rely on the new
partial apply in the specialized function to consume the captured arguments. If
a partial_apply has multiple uses then there are extra retain, releases. We need
to be able to identify the set of post-dominating releases of the closure and
insert releases of the captured arguments at those points.

3. The captured parameters signature in the specialized function was not being
set appropriately to be +1. If it was passed in @guaranteed or unowned into the
closure's callee function, we would reuse that signature instead of changing it
to @owned. We /were/ balancing the ref counts correctly though as mentioned
before by reusing the retains resulting from the captured arguments being passed
into the partial apply.

Now the algorithm works as follows:

1. We are no longer attempting to perform a "move" of the closure into the
specialized function. Instead we now perform a "copy". This means that we have
two phases to our algorithm. First we "copy" the closure into the specialized
function and balance out all of the relevant reference counts for the original
closure and the closure's captured arguments.

2. Then we attempt to eliminate the original closure if it is dead.

For more information see the large comment at the top of ClosureSpecialization.

I also consolidated some tests as well.

rdar://19723829

Swift SVN r25052
2015-02-06 21:59:53 +00:00
Michael Gottesman
250cc9affe [closure-spec] Explicitly disable support for closures that close over address types.
I will re-enable this when I implement the general support for handling both
concrete and address only address types.

Swift SVN r25002
2015-02-05 19:11:31 +00:00
Erik Eckstein
9dfd349faf Add a new Thunk-flag in SILFunction which specifies that a function is a thunk.
This will have an effect on inlining into thunks.
Currently this flag is set for witness thunks and thunks from function signature optimization.
No change in code generation, yet.



Swift SVN r24998
2015-02-05 16:45:05 +00:00
Michael Gottesman
478dc31893 [closure-spec] Remove unused SILLoopAnalysis.
Swift SVN r24964
2015-02-04 18:21:52 +00:00
Michael Gottesman
904586381a [closure-spec] Remove restriction on handling closures with multiple uses.
<rdar://problem/18143825>

Swift SVN r24774
2015-01-28 02:20:53 +00:00
Michael Gottesman
359d67274e [closure-spec] Add support for propagating thin_to_thick_function closures.
<rdar://problem/18995320>

Swift SVN r24770
2015-01-28 01:36:38 +00:00
Michael Gottesman
e06dc22976 [closure-spec] Refactor closure spec so that we can in a subsequent commit handle both partial_apply and thin_to_thick_function.
Since this is just a refactoring, it should be NFC.

This is to fix a dumb bug where we will propagate closures if the
closure captures variables (i.e. partial_apply), but we will not
propagate closures that do not capture any values (i.e.
thin_to_thick_function).

  a.map {
    return $0 + v
  }

But this will not be:

  a.map {
    return $0 + 1
  }

This will also give us the flexibility in the future to support the
propagation of function pointers (at which point we should probably
rename this pass).

Swift SVN r24759
2015-01-27 21:34:30 +00:00
Michael Gottesman
897325b096 Codebase Gardening. NFC.
1. Eliminate unused variable warnings.
2. Change field names to match capitalization of the rest of the field names in the file.
3. Change method names to match rest of the file.
4. Change get,set method for a field to match the field type.

Swift SVN r24501
2015-01-19 00:34:07 +00:00
Andrew Trick
86044dc707 Reapply "Fix the closure specializer's handling of indirect result types."
This fix had nothing to do with any of the build failures.

This reverts commit 86650e8d8298c5337c19786eef863025636d2eea.

Swift SVN r24330
2015-01-09 23:11:16 +00:00
Andrew Trick
a50cbc9fb2 Revert "Fix the closure specializer's handling of indirect result types."
This reverts commit 2cba2a400037431e787a1422a6a5bb1a65433037.

I'm speculatively backing this out because the builds are in terrible
shape and I can't tell if this caused an issue.

I can't easily verify because my builds are now breaking for a
different reason.

Swift SVN r24272
2015-01-08 06:59:04 +00:00
Andrew Trick
4f34737c8e Fix the closure specializer's handling of indirect result types.
Fixes <rdar://problem/19321284> SIL Verification failure with performance inliner disabled

Swift SVN r24255
2015-01-08 02:27:40 +00:00
Michael Gottesman
7e39f33f98 [mangle] Include a pass id in the mangling, just to be careful.
I am starting to reuse manglings for different passes. I want to make sure that
when we reuse functions we actually get a function created by the same pass.

Swift SVN r23924
2014-12-14 10:29:11 +00:00
Michael Gottesman
1d637f510b [mangle] Convert FunctionSignatureSpecializationMangler::setArgumentClosureProp to use an ArgNo index instead of SILArgument *.
This matches the rest of the methods on FunctionSignatureSpecializationMangler.

Swift SVN r23921
2014-12-14 08:17:30 +00:00
Erik Eckstein
14af3a57e8 Enable elimination of dead methods which are in classes of higher visibility.
The underlying problem is that e.g. even if a method is private but its class is public, the method can be referenced from another module - from the vtable of a derived class.
So far we handled this by setting the SILLinkage of such methods according to the visibility of the class. But this prevented dead method elimination.
Now I set the SILLinkage according to the visibility of the method. This enables dead method elimination, but it requires the following:
1) Still set the linkage in llvm so that it can be referenced from outside.
2) If the method is dead and eliminated, create a stub for it (which calls swift_reportMissingMethod).



Swift SVN r23889
2014-12-12 17:35:40 +00:00
Michael Gottesman
355f791621 [mangle] Add support for function signature specialization mangling and teach closure specialization how to use it.
Swift SVN r23816
2014-12-09 23:21:08 +00:00
Michael Gottesman
1afc987739 Refactor the SILArgument API on SILBasicBlock so we can insert bb arguments anywhere in the argument list. Also clean up the API names so that they all match.
Swift SVN r23543
2014-11-22 00:24:40 +00:00
Ben Langmuir
e9e1666ab0 Update for upstream LLVM changes
* removal of StringMap's GetOrCreateValue
* SmallSet::insert now returns a pair like std::set

Swift SVN r23435
2014-11-19 16:49:30 +00:00
Adrian Prantl
c41b30299f Audit all SILPasses to ensure that new instructions are never created
without a valid SILDebugScope. An assertion in IRGenSIL prevents future
optimizations from regressing in this regard.
Introducing SILBuilderWithScope and SILBuilderwithPostprocess to ease the
transition.

This patch is large, but mostly mechanical.
<rdar://problem/18494573> Swift: Debugger is not stopping at the set breakpoint

Swift SVN r22978
2014-10-28 01:49:11 +00:00
Erik Eckstein
c16c510167 Set SILLinkage according to visibility.
Now the SILLinkage for functions and global variables is according to the swift visibility (private, internal or public).

In addition, the fact whether a function or global variable is considered as fragile, is kept in a separate flag at SIL level.
Previously the linkage was used for this (e.g. no inlining of less visible functions to more visible functions). But it had no effect,
because everything was public anyway.

For now this isFragile-flag is set for public transparent functions and for everything if a module is compiled with -sil-serialize-all,
i.e. for the stdlib.

For details see <rdar://problem/18201785> Set SILLinkage correctly and better handling of fragile functions.

The benefits of this change are:
*) Enable to eliminate unused private and internal functions
*) It should be possible now to use private in the stdlib
*) The symbol linkage is as one would expect (previously almost all symbols were public).

More details:

Specializations from fragile functions (e.g. from the stdlib) now get linkonce_odr,default
linkage instead of linkonce_odr,hidden, i.e. they have public visibility.
The reason is: if such a function is called from another fragile function (in the same module),
then it has to be visible from a third module, in case the fragile caller is inlined but not
the specialized function.

I had to update lots of test files, because many CHECK-LABEL lines include the linkage, which has changed.

The -sil-serialize-all option is now handled at SILGen and not at the Serializer.
This means that test files in sil format which are compiled with -sil-serialize-all
must have the [fragile] attribute set for all functions and globals.

The -disable-access-control option doesn't help anymore if the accessed module is not compiled
with -sil-serialize-all, because the linker will complain about unresolved symbols.

A final note: I tried to consider all the implications of this change, but it's not a low-risk change.
If you have any comments, please let me know.



Swift SVN r22215
2014-09-23 12:33:18 +00:00
Michael Gottesman
6ff318b9fa Remove dead code.
Swift SVN r22155
2014-09-21 03:25:27 +00:00
Michael Gottesman
77caabca83 Fix a bug in capture propagation and closure specializer where we were not checking if functions were external declarations.
Swift SVN r22149
2014-09-20 00:25:39 +00:00
Michael Gottesman
79890eeb1a [closure-spec] Do not specialize a closure into a callee passed the closure if the callee takes multiple closures.
The pass does not support this properly and given where we are in the schedule
it makes no sense to each the closure specializer how to do this at this time.

Swift SVN r22130
2014-09-19 14:50:53 +00:00
Michael Gottesman
10b5accfff [closure-spec] Teach closure specialization to not specialize closures with indirect return and re-enable it.
It is possible to teach the closure specializer to handle these cases but given
where we are in the schedule it makes no sense to try to teach the optimizer how
to handle it.

Keep in mind though that we *will* handle the case where the function being
passed the closure has out parameters. This means that generic functions like
reduce will still be able to be specialized if the closure being passed in does
not have generics in it at the AST level. This implies that we will not handle
specialized closures with indirect results either which is unfortunate.

Swift SVN r22126
2014-09-19 13:44:46 +00:00
Michael Gottesman
8d9e358ad4 [closure-spec] Use the signature of the closure's function_ref instead of the
arguments of the closure since if the closure is an external declaration, it
wont have a first BB.

Swift SVN r22114
2014-09-19 02:33:58 +00:00
Michael Gottesman
2e86b69325 [closure-spec] Refactor all logic determining if we should specialize into the gatherCallSites method.
This creates a nice separation in between the analysis and the dynamic part of
the specialization. Thus gatherCallSites only returns call sites that are legal
to specialize.

This makes it easier to track where all of the correctness checks are.

Swift SVN r22049
2014-09-17 22:57:54 +00:00
Michael Gottesman
9957b99a78 [closure-spec] Perform some small cleanups. NFC.
Swift SVN r22047
2014-09-17 22:53:13 +00:00
Michael Gottesman
59992e3e98 [closure-spec] Move closure specialization behind a flag so the test will pass.
Swift SVN r22046
2014-09-17 22:50:19 +00:00
Michael Gottesman
443881679a [closure-spec] Turn off the closure specializer for now. I found additional issues that need to be fixed and I do not want to block the submission while I am fixing them.
Swift SVN r22045
2014-09-17 22:28:03 +00:00
Michael Gottesman
296304b9aa [closure-spec] Teach closure specialization how to handle partial applies with one use.
Also refactor out the gathering of call sites into its own function.

rdar://18143825

Swift SVN r22008
2014-09-17 05:51:53 +00:00
Michael Gottesman
0090ab15d2 [closure-specializer] Use getFunctionCost from SILInliner to determine cost instead of using just the number of instructions.
There are many instructions which do not contribute to the actual size of a
function that getFunctionCost knows to ignore. Thus this is more accurate.

rdar://18143825

Swift SVN r22007
2014-09-17 05:25:12 +00:00
Michael Gottesman
24c138f29c Move SILLoopInfo into swiftSIL from swiftSILAnalysis so that we match the separation in between analysis and IR entities.
This follows the model of dominance info and allows me to create reachability
methods on SILBasicBlock without creating dependencies from swiftSIL to
swiftSILAnalysis.

Swift SVN r21866
2014-09-11 03:03:06 +00:00
Manman Ren
ded2ec05bc [Closure Specializer] fix rdar://18156518
We will specialize when the ApplyInst is on a FunctionRefInst.


Swift SVN r21686
2014-09-03 22:10:53 +00:00
Mark Lacey
9aa7ace51a Move the closure specializer over to using the new call graph.
Swift SVN r21568
2014-08-29 07:22:46 +00:00
Mark Lacey
e515c40af3 Small clean-up in closure specializer.
Swift SVN r21561
2014-08-29 02:58:10 +00:00
Mark Lacey
8d385d4506 Fix 80-column violation.
Swift SVN r21477
2014-08-27 05:56:29 +00:00
Erik Eckstein
99cc7603be Add an @inline(__always) function attribute.
This will let the performance inliner inline a function even if the costs are too high.
This attribute is only a hint to the inliner.
If the inliner has other good reasons not to inline a function,
it will ignore this attribute. For example if it is a recursive function (which is
currently not supported by the inliner).

Note that setting the inline threshold to 0 does disable performance inlining at all and in
this case also the @inline(__always) has no effect.



Swift SVN r21452
2014-08-26 00:56:34 +00:00
Manman Ren
24f14d944f [Closure Specializer] add it to pass manager.
PerfTests -----
Before
Totals,54,93821,93821,93821,0,0
Totals,54,86755,86755,86755,0,0

After
Totals,54,93610,93610,93610,0,0
Totals,54,85780,85780,85780,0,0

We may be able to tune BoostFactor for closure in PerformanceInliner.


Swift SVN r21312
2014-08-20 20:00:40 +00:00
Manman Ren
1f54d024a9 [Closure Specializer] check in a pass to specialize closure.
If we have function A calls function B with a closure C
func A {
  B(...) {
    // closure C
  }
}
and the inliner decides to not inline B into A, it may be beneficial to generate
a specialized version of B to have
func A {
  B_spec_with_C(..., arguments_to_closure_C)
}
 
SILCombine will optimize apply of partial_apply that are both in B_spec_with_C.
Then inliner can inline the closure to B_spec_with_C.

For profitability, we check the relative size of the callee B and the closure C.
We also check hotness of the callsite to B in A and callsites to the closure
inside B. For now, if closure is called inside a loop, we think it is
profitable.

I will add this to the pass manager in a follow-up patch.
rdar://16569736


Swift SVN r21216
2014-08-14 19:45:11 +00:00