Commit Graph

871 Commits

Author SHA1 Message Date
Xin Tong
524ed34583 Make sure epilogue releases do not kill redundant loads
I did not measure a performance improvements with this.
2016-03-23 23:59:54 -07:00
Xin Tong
9a020c8c7a Minor refactoring in epilogue retain matcher 2016-03-23 22:16:49 -07:00
Xin Tong
b1c7bc5e4b Reinstate "Minor refactoring in epilogue retain matcher" 2016-03-23 22:16:34 -07:00
Andrew Trick
482b264afc Reapply "Merge pull request #1725 from atrick/specialize"
This was mistakenly reverted in an attempt to fix buildbots.
Unfortunately it's now smashed into one commit.

---
Introduce @_specialize(<type list>) internal attribute.

This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.

This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.

The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.

This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.

e.g.

struct S<T> {
var x: T
@_specialize(Int, Float)
mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
x = t
return (u, x)
}
}
// Substitutes: <T, U> with <Int, Float> producing:
// S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)

---
[SILOptimizer] Introduce an eager-specializer pass.

This pass finds generic functions with @_specialized attributes and
generates specialized code for the attribute's concrete types. It
inserts type checks and guarded dispatch at the beginning of the
generic function for each specialization. Since we don't currently
expose this attribute as API and don't specialize vtables and witness
tables yet, the only way to reach the specialized code is by calling
the generic function which performs the guarded dispatch.

In the future, we can build on this work in several ways:
- cross module dispatch directly to specialized code
- dynamic dispatch directly to specialized code
- automated specialization based on less specific hints
- partial specialization
- and so on...

I reorganized and refactored the optimizer's generic utilities to
support direct function specialization as opposed to apply
specialization.
2016-03-21 12:43:05 -07:00
Xin Tong
6e07c5ec60 Revert "Minor refactoring in epilogue release matcher. NFC"
This reverts commit a191ae72a7.

Broke Opt+Assert, Stdlib DebInfo+Assert.
2016-03-21 11:08:31 -07:00
Xin Tong
b2b5247ba9 Merge pull request #1756 from trentxintong/FSO
Minor refactoring in epilogue release matcher
2016-03-21 07:59:46 -07:00
Xin Tong
a191ae72a7 Minor refactoring in epilogue release matcher. NFC 2016-03-20 23:13:50 -07:00
Xin Tong
570c19b9c6 Merge pull request #1754 from trentxintong/FSO
Remove function signature optimization module pass.
2016-03-20 15:55:50 -07:00
Xin Tong
53888e12b5 Remove FunctionSignatureOpts.cpp.
This optimization pass has been replaced by FunctionSigatureOptCloner.cpp
and FunctionSigatureOptRewriter.cpp in cff61d7fe7
2016-03-20 15:05:02 -07:00
Xin Tong
e3ec0703fd Merge pull request #1744 from trentxintong/FSO
Implement a function signature cloner and rewriter.
2016-03-20 11:44:54 -07:00
practicalswift
a0d494c143 [gardening] Fix recently introduced typos: "fucntion" → "function", "functio" → "function", "mergable" → "mergeable", "mistmatched" → "mismatched" 2016-03-20 10:34:32 +01:00
Xin Tong
cff61d7fe7 Implement a function signature cloner and rewriter.
This split the function signature module pass into 2 functin passes.

By doing so,  this allows us to rewrite to using the FSO-optimized
function prior to attempting inlining, but allow us to do a substantial
amount of optimization on the current function before attempting to do
FSO on that function.

And also helps us to move to a model which module pass is NOT used unless
necesary.

I do not see regression nor improvement for on the performance test suite.

functionsignopts.sil and functionsignopt_sroa.sil are modified because the
mangler now takes into account of information in the projection tree.
2016-03-19 23:57:37 -07:00
Andrew Trick
5bda28e1cb Revert "Merge pull request #1725 from atrick/specialize"
Temporarily reverting @_specialize because stdlib unit tests are
failing on an internal branch during deserialization.

This reverts commit e2c43cfe14, reversing
changes made to 9078011f93.
2016-03-18 22:31:29 -07:00
Erik Eckstein
6d654aa3e8 Debugging on SIL level.
This change follows up on an idea from Michael (thanks!).
It enables debugging and profiling on SIL level, which is useful for compiler debugging.

There is a new frontend option -gsil which lets the compiler write a SIL file and generated debug info for it.
For details see docs/DebuggingTheCompiler.rst and the comments in SILDebugInfoGenerator.cpp.
2016-03-18 14:02:06 -07:00
Andrew Trick
e2c43cfe14 Merge pull request #1725 from atrick/specialize
@_specialize attribute
2016-03-18 13:24:31 -07:00
Andrew Trick
295dc96fb6 [SILOptimizer] Introduce an eager-specializer pass.
This pass finds generic functions with @_specialized attributes and
generates specialized code for the attribute's concrete types. It
inserts type checks and guarded dispatch at the beginning of the
generic function for each specialization. Since we don't currently
expose this attribute as API and don't specialize vtables and witness
tables yet, the only way to reach the specialized code is by calling
the generic function which performs the guarded dispatch.

In the future, we can build on this work in several ways:
- cross module dispatch directly to specialized code
- dynamic dispatch directly to specialized code
- automated specialization based on less specific hints
- partial specialization
- and so on...

I reorganized and refactored the optimizer's generic utilities to
support direct function specialization as opposed to apply
specialization.
2016-03-18 10:18:55 -07:00
Xin Tong
fd353df19e Remove some of unneeded functionality in CallerAnalysis
We really only need the analysis to tell whether a function has caller
inside the module or not. We do not need to know the callsites.

Remove them for now to make the analysis more memory efficient.

Add a note to indicate it can be extended.
2016-03-17 21:16:24 -07:00
Xin Tong
f543c336e7 Use SetVector instead of a SmallVector+DenseMap in CallerAnalysis 2016-03-17 17:31:38 -07:00
Xin Tong
991fc1a5fc Add comments on how CallerAnalysis work 2016-03-17 14:01:21 -07:00
Xin Tong
f5511da774 Get rid of an non-determinism in CallerAnalysis
RecomputeFunctionList should really be a SmallVector instead of a
DenseSet. A DenseSet gives rise to a nondeterminstic way of iterating over
all functions.
2016-03-17 11:28:25 -07:00
Xin Tong
eefacd198b Make fields in CallerAnalysisFunctionInfo private and use friend class
This allows us to vend only a determinstic getCallSites interface to users
while internal implementation is protected.
2016-03-17 10:57:59 -07:00
Xin Tong
eab029d795 Add CallerAnalysis Printer.
This provides some basic testing on CallerAnalysis before hooking it
up to function signature opts.
2016-03-17 10:51:16 -07:00
Xin Tong
1603b0f153 Handle dead functions in CallerAnalysis.
Add an invalidateAnalysisForDeadFunction API. This API calls the invalidateAnalysis
by default unless overriden by analysis pass themselves. This API passes the extra
information that this function is dead and going to be removed from the module.

CallerAnalysis overrides this API and only invalidate caller/callee relations but
does not push this into the recompute list.

We also considered the possibility of keeping a computed list, instead of recompute
list but that would introduce a O(n^2) complexity as every time we try to complete
the computed list, we need to walk over all the functions that currently exist in the
module to make sure the computed list is complete.

I feel eventually we can do a handleDeleteNotification for function deletion and we
wont need the API added in this change.
2016-03-17 09:55:12 -07:00
Xin Tong
cca9c2521a Improve CallerAnalysis.
Address the comments from 0acc0a8464

I still have not made up my mind how to handle deleted functions.

CallerAnalysis is not hooked up to anything yet.
2016-03-16 17:49:34 -07:00
practicalswift
356b843c1b [gardening] Fix recently introduced typo: "invaldiated" → "invalidated" 2016-03-16 23:15:45 +01:00
practicalswift
1147753a94 [gardening] Fix formatting of recently introduced header files 2016-03-16 22:51:11 +01:00
Xin Tong
0acc0a8464 Implement a Caller Analysis.
The analysis can tell all the callsites which calls a function in the module.

The analysis is computed and kept up-to-date lazily.

At the core of it, it keeps a list of functions that need to be recomputed for
the Caller/Callee relation to be precise and on every query, the analysis makes
sure to recompute them and clear the list before any query.

This is NFC right now. I am going to wire it up to function signature analysis
eventually.
2016-03-16 09:33:22 -07:00
Xin Tong
5f7f05da9b Reinstate "Moves SignatureAnalyzer and ArgumentDescriptor/ResultDescriptor into
a separate analysis pass.

This pass is run on every function and the optimized signature is return'ed through the
getArgDescList and getResultDescList.

Next step is to split to cloning and callsite rewriting into their own function passes.

rdar://24730896
"
2016-03-16 07:00:57 -07:00
Xin Tong
48ed191ca4 Revert "Moves SignatureAnalyzer and ArgumentDescriptor/ResultDescriptor into a separate"
This reverts commit 069612bccc.

Reverts because it

Breaks compiling the stdlib (optimized, no stdlib assertions), while i try to reproduce and fix.
2016-03-15 14:17:01 -07:00
Xin Tong
069612bccc Moves SignatureAnalyzer and ArgumentDescriptor/ResultDescriptor into a separate
analysis pass.

This pass is run on every function and the optimized signature is return'ed through the
getArgDescList and getResultDescList.

Next step is to split to cloning and callsite rewriting into their own function passes.

rdar://24730896
2016-03-15 12:21:20 -07:00
Michael Gottesman
406a7c9962 [loop-region] Track the backedges of all loop regions.
We already computed this information so this is just storing information
we were already computing.

One thing to note is that in code with canonicalized loops, we will
always only have one backedge. But we would like loop region to be
correct even in the case of non-canonicalized code so we support having
multiple back edges. But since the common case is 1 backedge, we
optimize for that case.

This commit contains updated tests and also updates to the loop region graph
viewer so that it draws backedges as green arrows from the loop to its backedge
subregions. The test updates were done by examining each test case by hand.
2016-03-14 22:37:06 -07:00
Michael Gottesman
3fd5e80b39 [loop-region] Change LoopRegion::getParentID() to return the optional ParentID instead of attempting to use the value and asserting. 2016-03-14 22:37:06 -07:00
Arnold Schwaighofer
7405512dcb Fix the cast optimizer to remove instructions after inserting unreachable
Also insert the store and dealloc_stack instructions before the trap the cast
optimizer inserts.

rdar://24761530
2016-03-09 20:05:59 -08:00
Arnold Schwaighofer
3676671b7f Merge pull request #1587 from aschwaighofer/stack_promote_with_unsafe_mutable_buffer_pointer
Mark Array.withUnsafeMutableBuffer as not escaping the array storage.
2016-03-08 19:39:28 -08:00
Arnold Schwaighofer
b5f018a4b1 Mark Array.withUnsafeMutableBuffer as not escaping the array storage.
This is safe because the closure is not allowed to capture the array according
to the documentation of 'withUnsafeMutableBuffer' and the current implementation
makes sure that any such capture would observe an empty array by swapping self
with an empty array.

Users will get "almost guaranteed" stack promotion for small arrays by writing
something like:

  func testStackAllocation(p: Proto) {
    var a = [p, p, p]
    a.withUnsafeMutableBufferPointer {
      let array = $0
      work(array)
    }
  }

It is "almost guaranteed" because we need to statically be able to tell the size
required for the array (no unspecialized generics) and the total buffer size
must not exceed 1K.
2016-03-08 19:37:47 -08:00
Michael Gottesman
bb15808554 Convert some trivial std::count_if invocations on ranges to use the provided range adaptor. 2016-03-08 14:58:13 -08:00
Michael Gottesman
5f72810ad3 Add a range adaptor for std::count and update various trivial usages in the compiler to use this API instead. 2016-03-08 14:58:13 -08:00
practicalswift
37bf58399a [gardening] Fix formatting of two recently introduced file headers 2016-03-08 11:23:45 +01:00
Xin Tong
2fe08d9cda Move LSBase.cpp to lib/SILOptimzer/Utils/ 2016-03-07 22:04:15 -05:00
Xin Tong
56a09b67da Update some comments and delete abit dead code. NFC 2016-03-07 21:26:57 -05:00
Xin Tong
bfc258f628 Simplify LSValue::reduce for redundant load elimination
LSValue::reduce reduces a set of LSValues (mapped to a set of LSLocations) to
a single LSValue.

It can then be used as the forwarding value for the location.

Previously, we expand into intermediate nodes and leaf nodes and then go bottom
up, trying to create a single LSValue out of the given LSValues.

Instead, we now use a recursion to go top down. This simplifies the code. And this
is fine as we do not expect to run into type tree that are too deep.

Existing test cases ensure correctness.
2016-03-07 21:26:56 -05:00
naoyashiga
803bb1ba54 fix typo 2016-03-04 22:14:38 +09:00
practicalswift
9b1d73fcac [gardening] Fix recently introduced typo: "exit exit" → "exit" 2016-03-02 09:34:21 +01:00
Xin Tong
5176173cc8 Rename ConsumedReturnValueToEpilogueRetainMatcher.
Rename to ConsumedResultToEpilogueRetainMatcher

Also remove some dead code in ConsumedResultToEpilogueRetainMatcher.

NFC.
2016-03-01 20:21:00 -08:00
Xin Tong
6c0186b61c Reinstate "Improve funciton signature @owned return result to "not owned" conversion"
This enables function signature handles a case of self-recursion.

With this change we convert 11 @owned return value to "not owned", while
we convert 179 @owned parameter to @guanrateed.

rdar://24022375
2016-03-01 17:25:16 -08:00
Erik Eckstein
115c50a5c7 DeadObjectElimination: Fix a problem with dead array elimination.
With the new ValueLifetimeAnalysis DOE did not handle case where a dead array is not released on a path at all (because it leads to an unreachable).
2016-03-01 12:30:52 -08:00
Xin Tong
d72ad28b08 Revert "Improve funciton signature @owned return result to "not owned" conversion"
This reverts commit c6de7c0123.

Broke OSS linux and OSX builds.
2016-03-01 11:17:06 -08:00
Xin Tong
c6de7c0123 Improve funciton signature @owned return result to "not owned" conversion
More specifically, this handles a case of self-recursion.

With this change we convert 11 @owned return value to "not owned", while
we convert 179 @owned parameter to @guanrateed.

rdar://24022375
2016-03-01 10:58:32 -08:00
Erik Eckstein
68f0d5c202 Reinstate "GenericSpecializer: When specializing a generic function, convert indirect parameters/result to direct parameters/result.""
This reinstates commit 4187959e66.

It was reverted because of a bug in ValueLifetimeAnalysis which is now fixed.
2016-02-29 07:42:59 -08:00
Erik Eckstein
1730b90ae4 Reinstate "Rewrite the ValueLifetimeAnalysis."
Reinstates commit 0c2ca94ef7

With two bug fixes:
*) use after free asan crash
*) wrong check in ValueLifetimeAnalysis::isWithinLifetime
And some refactoring
2016-02-29 07:42:59 -08:00