Commit Graph

11224 Commits

Author SHA1 Message Date
Xin Tong
63d04a8713 Rename LSBase.cpp to LoadStoreOptUtils.cpp 2016-03-31 20:09:55 -07:00
eeckstein
045ee83705 Merge pull request #1992 from eeckstein/onfastpath
introduce the onFastPath builtin
2016-03-31 17:41:26 -07:00
Xin Tong
d2c6d93cc1 Merge pull request #1976 from trentxintong/IP
Add an option to disable code motion in ARC
2016-03-31 17:29:16 -07:00
Arnold Schwaighofer
308ce091b7 Actually return the result from the _withUnsafeGuaranteed closure call 2016-03-31 16:43:46 -07:00
Erik Eckstein
a47a62d644 A new onFastPath built-in.
It is a hint to the optimizer that the code, where this builtin is called, is on the fast path.
Specifically, the inliner takes it into account and increases the assumed benefit for code where the builtin is located.

Compared to the fastPath/slowPath builtins, this builtin can be placed into plain linear code and doesn't need to be used in conditions.
Compared to the @inline(__always) attribute, this builtin has also an effect on the caller function. Let's assume
	foo() calls bar() contains onFastPath
and both foo and bar are small functions. Then if bar gets inlined into foo, the builtin also increases the chances that foo gets inlined.
This would not be the case if @inline(__always) is used just for bar.
2016-03-31 12:53:44 -07:00
Erik Eckstein
fd3f343dab SIL: add a utility function to check if a terminator exits a function. NFC 2016-03-31 09:29:15 -07:00
practicalswift
109cf92d17 [gardening] Fix recently introduced typo: "extry" → "entry" 2016-03-31 13:42:47 +02:00
Xin Tong
d7dad7884f Add an option to disable code motion in ARC 2016-03-30 22:14:17 -07:00
Mark Lacey
84473f242a Do not specialize dead apply/partial_apply.
Do not specialize an apply/partial_apply that we've already added to the
set of dead instructions. Doing so can result in creating a new
instruction which we will leave around, and which will have a type
mismatch in its parameter list.

Fixes rdar://problem/25447450.
2016-03-30 21:16:00 -07:00
Mark Lacey
99d4485713 Fix double delete in generic specialization.
We ended up adding the same instruction twice to a SmallVector of
instructions to be deleted. To avoid this, we'll track these
to-be-deleted instructions in a SmallSetVector instead.

We were also failing to add an instruction that we can delete to the set
of instructions to be deleted, so I fixed that as well.

I've added a test case, but it's currently disabled because fixing this
turned up another issue in the same code which I still need to take a
look at.

Fixes rdar://problem/25369617.
2016-03-30 13:10:00 -07:00
Chris Lattner
5b7e030810 Merge pull request #1952 from practicalswift/gardening-20160330
[gardening] Remove unused code, fix typos and improve file header formatting
2016-03-30 10:24:05 -07:00
Xin Tong
4183d972da Merge pull request #1946 from trentxintong/FS
Change FSO heuristic.
2016-03-30 10:11:27 -07:00
practicalswift
74987b2164 [gardening] Remove unused code. 2016-03-30 18:20:49 +02:00
Xin Tong
f95d9b3c92 Change FSO heuristic.
FSO functions that have high potential but does not have caller inside
current module.

The thunk can then be inlined into the module calling the function and
the function would get the benefit of FSO.

The heuristic for selecting such function is
1. Have no indirect caller. This would introduce a thunk.
2. Have potential to give better performance. i.e. function argument can
be O2G.

Regression
TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
BenchLangCallingCFunction                               | 184     | 211     | +14.7%    | **0.87x**
Calculator                                              | 55      | 59      | +7.3%     | **0.93x**
DeadArray                                               | 687     | 741     | +7.9%     | **0.93x**
MonteCarloPi                                            | 39275   | 41669   | +6.1%     | **0.94x**

Improvement
TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
LuhnAlgoLazy                                            | 2478    | 2327    | -6.1%     | **1.06x**
OpenClose                                               | 54      | 51      | -5.6%     | **1.06x**
SortLettersInPlace                                      | 1016    | 946     | -6.9%     | **1.07x**
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced | 149993  | 139755  | -6.8%     | **1.07x**
Phonebook                                               | 9666    | 8992    | -7.0%     | **1.07x**
ObjectiveCBridgeFromNSDictionaryAnyObjectToString       | 222713  | 206538  | -7.3%     | **1.08x**
LuhnAlgoEager                                           | 2393    | 2226    | -7.0%     | **1.08x**
Dictionary                                              | 1307    | 1196    | -8.5%     | **1.09x**
JSONHelperDeserialize                                   | 3808    | 3492    | -8.3%     | **1.09x**
StdlibSort                                              | 7310    | 4084    | -44.1%    | **1.79x**

I see 0.15% increase in code size for Benchmark_O.

Thanks @gottesmm for suggesting this opportunity.

rdar://25345056
2016-03-29 23:04:36 -07:00
Erik Eckstein
d581cbdd9d Re-instate "PerformanceInliner: Improve the inlining heuristic to reduce code size."
...with a fix in the shortest-path-analysis

This reinstates commit 4bd1216702
2016-03-29 16:33:47 -07:00
Erik Eckstein
a95979bdd2 SILCombine: fix insertion of dealloc_stacks in the partial_apply-apply -> apply conversion.
rdar://problem/25387206
2016-03-29 16:33:47 -07:00
Erik Eckstein
0ea4fe7b98 EscapeAnalysis: fix a bug in graph merging
This bug can end up in doing wrong stack promotion.
2016-03-29 16:33:47 -07:00
Erik Eckstein
66cd115456 SideEffectAnalysis: fix handling of indirect parameters to partial_apply
Fixes rdar://problem/24960559
2016-03-28 15:59:01 -07:00
practicalswift
ef4306f0ce [gardening] Fix recently introduced typo: "intializer" → "initializer" 2016-03-28 21:52:03 +02:00
practicalswift
363ecaf71c [gardening] Fix recently introduced typo: "mistmatched" → "mismatched" 2016-03-28 21:52:03 +02:00
Erik Eckstein
be8faad792 Revert my recent inliner commits.
There are some failures in the tests.
2016-03-28 11:11:25 -07:00
practicalswift
5004c21c6a Merge pull request #1877 from practicalswift/cleanups-20160325
[gardening] Daily cleanup: typos, header formatting, pep8 fixes.
2016-03-28 09:46:55 +02:00
practicalswift
78ae2bb23b Merge pull request #1898 from practicalswift/cleanups-20160327
[gardening] Daily gardening: unused variables, header formatting, PEP 8, .rst formatting
2016-03-28 09:45:16 +02:00
practicalswift
11a8b6c2ba [gardening] Daily cleanup: typos, header formatting. 2016-03-28 09:29:38 +02:00
practicalswift
881fabd3e0 [gardening] Remove unused variable. 2016-03-28 00:48:08 +02:00
Erik Eckstein
4bd1216702 PerformanceInliner: Improve the inlining heuristic to reduce code size.
It now detects more opportunities for inlining, like some patters with RC instructions or loads/stores from/to stack locations in the caller.
On the other hand a new shortest path analysis limits inlining to those cases where it really gives a benefit.

As the inlining decision now depends on many parameters, the test-threshhold option is removed because it doe not make much sense anymore.
Instead the inliner test files are modified to model the "real" instruction costs.
2016-03-27 10:59:29 -07:00
Erik Eckstein
8e624a655b remove unneeded allocation in swift::splitAllCriticalEdges 2016-03-27 10:59:29 -07:00
Arnold Schwaighofer
255779082e Add a peephole optimization for the builtin "unsafeGuaranteed"
We can remove the retain/release pair preceeding the builtins based on the
knowledge that the lifetime of the reference is guaranteed by someone hanging on
to the reference elsewhere.
2016-03-27 06:47:16 -07:00
Slava Pestov
a9ad760b78 SIL: Clean up duplicated "can be referenced from a fragile function" checks 2016-03-25 22:46:50 -07:00
Roman Levenstein
5893fc2694 [let-properties-opt] Re-factor and simplify the code. Improve correctness.
Based on the review of my previous commit, I did some re-factorings.
The code is now simpler and handles more cases. More tests were added.

The overall idea of this rewrite is that the pass basically tries to check if it can
see all possible writes (i.e. initializations) into a given let property. Only if it can be proven
that the pass sees all possible writes and all those initializations are producing
the same constant, statically known value, the pass propagates this constant value
into uses of a property.

SR-1026 and rdar://25303106
2016-03-25 15:13:10 -07:00
Chris Lattner
e4c7bca43a Merge pull request #1861 from practicalswift/weekly-cleanup-01
[gardening] Weekly gardening: typos, duplicate includes, header formatting, etc.
2016-03-24 22:39:36 -07:00
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