Commit Graph

11193 Commits

Author SHA1 Message Date
Xin Tong
f557a3253d Merge pull request #1857 from trentxintong/FSO
Rename FunctionSignatureOptCloner to FunctionSignatureOpts
2016-03-24 15:57:34 -07:00
practicalswift
d00a5ef814 [gardening] Weekly gardening: typos, duplicate includes, header formatting, etc. 2016-03-24 22:41:10 +01:00
Xin Tong
5907b8a3e2 Rename FunctionSignatureOptCloner to FunctionSignatureOpts
Eventually, we decided to do this

1. Have the function signature opts (used to be called the cloner to create
the optimized function.
2. Mark the thunk as always_inline
3. Rely on the inliner to inline the thunk to get the benefit of calling optimized
function directly.
2016-03-24 12:50:12 -07:00
Xin Tong
e0ba695d17 Merge pull request #1852 from trentxintong/FSO
Remove function signature rewriter and make function signature analysis a Util
2016-03-24 12:42:05 -07:00
Xin Tong
9a3761000c Move function signature analysis to a Util
We really only need this signature analysis in the cloner pass now.
2016-03-24 11:17:47 -07:00
Xin Tong
3f075dfe47 Remove function signature rewriter.
We decided to use the inliner to rewrite the caller's callsites.

And eventually I will turn FunctionSignatureAnalysis into a Utility.
As its data should only be used and kept in the cloner pass.
2016-03-24 10:50:47 -07:00
Xin Tong
c44006aa9d Merge pull request #1824 from trentxintong/RLE
Make sure non-epilogue releases do not kill redundant loads
2016-03-24 10:48:21 -07:00
Xin Tong
0a562b7fe1 Merge pull request #1847 from trentxintong/FSO
Make FSO thunks always_inline.
2016-03-24 10:38:38 -07:00
Xin Tong
2a63907a17 Make FSO thunks always_inline.
This forces the callsites to be rewritten by the inliner.

we have the issue that the thunk changes from the time the its created to
the time its reread to figure out what we have done to the original function

This results in missed opportunities.

This solution solves the problem gracefully, because the thunk carries the information
on how to set up the call to the optimized functions.

Inlining the thunk makes the callsite calling the optimized function for free. i.e.
without any rewriting.

I did not measure any regression with this change.
2016-03-24 09:18:13 -07:00
Xin Tong
7ff5156cc2 Merge pull request #1827 from trentxintong/FSO
Minor refactor in Epilogue Retain/Release matchers
2016-03-24 08:48:04 -07:00
Arnold Schwaighofer
7fb2cceec0 Add a method to _NSContiguousString to facilitate stack promotion
Use it for hashing and comparison.

During String's hashValue and comparison function we create a
_NSContiguousString instance to call Foundation's hash/compare function. This is
expensive because we have allocate and deallocate a short lived object on the
heap (and deallocation for Swift objects is expensive).  Instead help the
optimizer to allocate this object on the stack.

Introduces two functions on the internal _NSContiguousString:
_unsafeWithNotEscapedSelfPointer and _unsafeWithNotEscapedSelfPointerPair that
pass the _NSContiguousString instance as an opaque pointer to their closure
argument. Usage of these functions asserts that the closure will not escape
objects transitively reachable from the opaque pointer.

We then use those functions to call into the runtime to call foundation
functions on the passed strings. The optimizer can promote the strings to the
stack because of the assertion this API makes.

  let lhsStr = _NSContiguousString(self._core) // will be promoted to the stack.
  let rhsStr = _NSContiguousString(rhs._core) // will be promoted to the stack.
  let res = lhsStr._unsafeWithNotEscapedSelfPointerPair(rhsStr) {
    return _stdlib_compareNSStringDeterministicUnicodeCollationPointer($0, $1)
  }

Tested by existing String tests.

We should see some nice performance improvements for string comparison and
dictionary benchmarks.

Here is what I measured at -O on my machine

Name                          Speedup
Dictionary                      2.00x
Dictionary2                     1.45x
Dictionary2OfObjects            1.20x
Dictionary3                     1.50x
Dictionary3OfObjects            1.45x
DictionaryOfObjects             1.40x
SuperChars                      1.60x

rdar://22173647
2016-03-24 05:43:29 -07:00
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
Roman Levenstein
3448b7c0f4 [let-properies-opt] Fix a bug which where a let property was wrongly considered to have a constant value.
The optimization pass was inspecting only init methods to determine if a given let property is defined
in the same way by all initializers. But this is not enough in certain cases, e.g. when some of the
initializers were inlined into the application code and the body of the inlined SIL function representing
such an initializer was removed afterwards by the dead function elimination pass. In such situations,
the Let Properties Optimization pass was assuming that there is only one initializer and considered the
constant let property value defined there as the only possible value of this let property. Therefore it
propagated it into let-property uses, which resulted in an incorrect code.

The right thing to do is to analyze all assignments to a given let property whether they are inside initializer
SIL functions or not. This makes sure that all possible values of a let property are analyzed and compared.
The propagation of a constant let property value can only happen if all found possible values are all the same.

Fixes SR-1026 and rdar://25303106
2016-03-23 22:29:56 -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
practicalswift
04ef7851eb [gardening] Fix recently introduced typo: "cant" → "can't" 2016-03-22 21:35:39 +01:00
Xin Tong
10b108a8f3 Move PerformanceInliner.cpp to SILOptimzer/Transforms as it is a function pass 2016-03-22 11:18:59 -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
practicalswift
a942bb76d0 [gardening] Fix formatting of recently introduced headers. 2016-03-19 00:37:37 +01: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
Andrew Trick
f6a2e7c362 [comment] Clarify RC identity over casts. 2016-03-18 04:01:16 -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
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
6b9cde8ffd Fix typo 2016-03-16 18:00:07 -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
6f53d02f6b [gardening] Fix recently introduced typo: "optimzer" → "optimizer" 2016-03-16 23:17:26 +01:00
practicalswift
a934702d51 [gardening] Fix recently introduced typo: "fucntion" → "function" 2016-03-16 23:17:13 +01:00
practicalswift
1147753a94 [gardening] Fix formatting of recently introduced header files 2016-03-16 22:51:11 +01:00
Xin Tong
0b930234ed Fix use-after-free in DFE 2016-03-16 14:20:45 -07: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
a5b0270ab9 Remove unused variable 2016-03-16 07:38:31 -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
Doug Gregor
a31edf53d0 Simplify the interface to Module::lookupConformance.
Rather than returning a weird PointerIntPair, return an
Optional<ProtocolConformanceRef>. NFC
2016-03-15 22:08:24 -07:00
eeckstein
32d16276f8 Merge pull request #1696 from eeckstein/fix_release_devirtualizer
Fix release devirtualizer
2016-03-15 14:57:38 -07:00
Erik Eckstein
bf87de3bc3 Fix a memory leak caused by the ReleaseDevirtualizer.
This occured if a stack-promoted object with a devirtualized final release is not actually allocated on the stack.
Now the ReleaseDevirtualizer models the procedure of a final release more accurately.
It inserts a set_deallocating instruction and calles the deallocator (instead of just the deinit).

This changes also includes two peephole optimizations in IRGen and LLVMStackPromotion which get rid of
unused runtime calls in case the stack promoted object is really allocated on the stack.

This fixes rdar://problem/25068118
2016-03-15 12:56:54 -07:00
Erik Eckstein
c1bcb0b69d SIL: add new instruction set_deallocating
It will be used by the ReleaseDevirtualizer before calling the deallocator.
So far, this is NFC.
2016-03-15 12:56:54 -07:00
practicalswift
854e82d4dc [SILOptimizer] Remove unused "SuccFilterFnTy" 2016-03-15 13:57:38 +01: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