Commit Graph

339 Commits

Author SHA1 Message Date
Slava Pestov
b246d09470 SILOptimizer: Don't inline functions that directly reference the metatype of $Self
Formerly SILGen would never emit this sequence. In fact in most places
we lower away dynamic Self, replacing it with the concrete Self type
instead.

However, with an upcoming change, I'm using 'metatype $Self' as a handy
way to grab IRGenSILFunction::LocalSelfMetadata, since that's what it
already does.

Note that the tests for this are in the next patch.
2016-06-27 18:37:53 -07:00
Slava Pestov
98a0e73b02 AST: Merge BoundGenericType::getSubstitutions() with TypeBase::gatherAllSubstitutions(), NFC 2016-06-13 00:57:09 -07:00
Xin Tong
e06e1be1ad Merge pull request #2950 from trentxintong/SCM
Remove last bit of retain release code motion in SILCodeMotion.
2016-06-08 13:41:20 -07:00
Xin Tong
500acb98e0 Rename LSBase.h to LoadStoreOptUtils.h 2016-06-08 10:57:27 -07:00
Xin Tong
be793d26eb Remove last bit of retain release code motion in SILCodeMotion. All these code are
replaced by retain release code motion. This code has been disabled for sometime now.

This should bring the retain release code motion into a close. The retain release
code motion pipeline looks like this. There could be some minor cleanups after this though.

1. We perform a global data flow for retain release code motion in RRCM (RetainReleaseCodeMotion)
2. We perform a local form of retain release code motion in SILCodeMotion. This is more
for cases which can not be handled in RRCM. e.g. sinking into a switch is more efficiently
done in a local form, the retain is not needed on the None block. Release on SILArgument needs
to be split to incoming values, this can not be done in RRCM and other cases.
3. We do not perform code motion in ASO, only elimination which are very important.

Some modifications to test cases, they look different, but functionally the same.
RRCM has this canonicalization effect, i.e. it uses the rc root, instead of
the SSA value the retain/release is currently using. As a result some test cases need
to be modified.

I also removed some test cases that do not make sense anymore and lot of duplicate test
cases between earlycodemotion.sil and latecodemotion.sil. These tests cases only have retains
and should be used to test early code motion.
2016-06-08 10:49:33 -07:00
Xin Tong
c758848c92 Share a few createIncrement/createDecrement functions 2016-05-26 12:55:25 -07:00
Xin Tong
fb3eb0b646 Simplify function signature optimzation.
Several functionalities have been added to FSO over time and the logic has become
muddled.

We were always looking at a static image of the SIL and try to reason about what kind of
function signature related optimizations we can do.

This can easily lead to muddled logic. e.g. we need to consider 2 different function
signature optimizations together instead of independently.

Split 1 single function to do all sorts of different analyses in FSO into several
small transformations, each of which does a specific job. After every analysis, we produce
a new function and eventually we collapse all intermediate thunks to in a single thunk.

With this change, it will be easier to implement function signature optimization as now
we can do them independently now.

Small modifications to the test cases.
2016-05-25 11:12:27 -07:00
Roman Levenstein
73b6a38edc [sil-devirtualizer] Do not perform a speculative devirtualization for no-opt callees. 2016-05-11 16:28:50 -07:00
Roman Levenstein
28f7b09c1d Add a more strict check for conversions between metatypes.
Now it is more inline with the check performed by the verifier.
2016-05-11 15:25:08 -07:00
Roman Levenstein
f200dfdc72 Addresses are always ABI compatible.
Now it is more inline with the check performed by the verifier.
2016-05-11 15:25:08 -07:00
Roman Levenstein
7a9b05babf [sil-devirtualizer] Fix some bugs in the devirtualizer.
- Don't crash if a class_method instruction could not be devirtualized.
- Improve devirtualization of methods with generic parameters and using dependent types.
- Fix a bug in isBindableToSuperclassOf, uncovered while fixing the original bug reported in SR-1206.
  This bug could lead in certain cases to invocations of a wrong method from the base class, instead
  of using a method from a derived class.

rdar://25891588   and SR-1206
2016-04-28 22:40:47 -07:00
Dmitri Gribenko
0984f81a50 Merge remote-tracking branch 'origin/master' into swift-3-indexing-model 2016-04-22 18:56:35 -07:00
Slava Pestov
2e52338d7c SIL: Rename long form of getOrCreateFunction() to createFunction(), NFC
This made call sites confusing to read because it doesn't actually
check if the function already exists.

Also fix some minor formatting issues. This came up while I was working
on a fix for a bug that turned out to not be a bug.
2016-04-21 17:58:10 -07:00
Erik Eckstein
c52b933bdb ValueLifetimeAnalysis: fix the case if the last use of the value is a terminator instruction.
This bug let the ClosureSpecializer insert a release after a try_apply in the same basic block.
Fixes SR-1252
2016-04-20 13:02:06 -07:00
Slava Pestov
41a9543648 SIL Optimizer: Fix pre-specialization [fragile] mismatch assert
Applying this patch triggered an assert while building libswiftOnoneSupport:

--- a/lib/SILOptimizer/PassManager/Passes.cpp
+++ b/lib/SILOptimizer/PassManager/Passes.cpp
@@ -283,6 +283,9 @@ void swift::runSILOptimizationPasses(SILModule &Module) {
   PM.setStageName("HighLevel+EarlyLoopOpt");
   // FIXME: update this to be a function pass.
   PM.addEagerSpecializer();
+
+  AddSimplifyCFGSILCombine(PM);
+
   AddSSAPasses(PM, OptimizationLevelKind::HighLevel);
   AddHighLevelLoopOptPasses(PM);
   PM.runOneIteration();

I don't have a reduced testcase, but presumably Erik will commit the above
change soon.

Fixes <rdar://problem/25646947>.
2016-04-19 17:23:48 -07:00
Xin Tong
bfc9683b49 Use a SmallPtrSet instead of a DenseSet. More memory efficient 2016-04-18 14:54:39 -07:00
Dmitri Gribenko
cfea1a3f58 Merge remote-tracking branch 'origin/master' into swift-3-indexing-model 2016-04-14 17:00:46 -07:00
Dmitri Gribenko
3e708a9328 Merge commit '8e292daec1bc790c96b5ee39b8d55dadcac6ce1b' into swift-3-indexing-model 2016-04-14 15:10:26 -07:00
Xin Tong
31b6c65039 Fix a logic error in eraseUseOfValue.
I failed to create a test case. And we hav existing tests in FSO that will
exercise this.

rdar://25559780
2016-04-13 20:53:28 -07:00
swiftix
46e359041d Merge pull request #2176 from swiftix/master
Improve the implementation of pre-specializations
2016-04-13 19:16:20 -07:00
Roman Levenstein
27bcabcde3 Improve handling of pre-specializations.
This commit does not result in any visible functionality changes yet.
This is a preparation for some changes on the swift-3-indexing branch.
2016-04-13 15:49:36 -07:00
Roman Levenstein
932108b073 [pre-specializations] Update the whitelist to match the recent stdlib's re-factoring.
Fix for a test failure reported in rdar://25664645.
2016-04-13 15:23:07 -07:00
Roman Levenstein
e4f0338b40 Improve handling of pre-specializations.
This commit does not result in any visible functionality changes yet.
This is a preparation for some changes on the swift-3-indexing branch.
2016-04-13 14:04:28 -07:00
Erik Eckstein
3e52d24853 add a debug dump function for ValueLifetimeAnalysis 2016-04-13 13:22:30 -07:00
Erik Eckstein
911b05ab71 Fix comment 2016-04-08 10:20:47 -07:00
Slava Pestov
d8e1e2e289 SILOptimizer: Fixes for non-fragile references in fragile functions
Two fixes to optimization passes to maintain restrictions about what
[fragile] functions can reference:

- When devirtualizing witness methods, don't devirtualize if the caller
  is fragile and the callee is not. This matches existing logic in
  class devirtualization.

- When performing generic or function signature specialization, don't
  specialize non-fragile functions referenced from fragile functions.

Since @_transparent functions are allowed to call 'static inline'
imported functions, also be sure to mark the foreign-to-native thunk
for such a function as [fragile].

With this patch, the standard library and performance test suite
now build with -enable-resilience.

No new tests for this stuff here -- the existing tests together
with an -enable-resilience build provide coverage.

Closes out <https://bugs.swift.org/browse/SR-267> and
<https://bugs.swift.org/browse/SR-268>.
2016-04-08 02:14:33 -07:00
Slava Pestov
5aa99fa346 SILOptimizer: Create non-[fragile] specializations of [fragile] functions where possible
Change the optimizer to only make specializations [fragile] if both the
original callee is [fragile] *and* the caller is [fragile].

Otherwise, the specialized callee might be [fragile] even if it is never
called from a [fragile] function, which inhibits the optimizer from
devirtualizing calls inside the specialization.

This opens up some missed optimization opportunities in the performance
inliner and devirtualization, which currently reject fragile->non-fragile
references:

TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
DictionaryRemoveOfObjects                               | 38391   | 35859   | -6.6%     | **1.07x**
Hanoi                                                   | 5853    | 5288    | -9.7%     | **1.11x**
Phonebook                                               | 18287   | 14988   | -18.0%    | **1.22x**
SetExclusiveOr_OfObjects                                | 20001   | 15906   | -20.5%    | **1.26x**
SetUnion_OfObjects                                      | 16490   | 12370   | -25.0%    | **1.33x**

Right now, passes other than performance inlining and devirtualization
of class methods are not checking invariants on [fragile] functions
at all, which was incorrect; as part of the work on building the
standard library with -enable-resilience, I added these checks, which
regressed performance with resilience disabled. This patch makes up for
these regressions.

Furthermore, once SIL type lowering is aware of resilience, this will
allow the stack promotion pass to make further optimizations after
specializing [fragile] callees.
2016-04-08 02:10:31 -07:00
Jordan Rose
52b961de61 Revert "Fix post-dominator tree in stack promotion"
This broke the test suite under optimizations with a SIL verifier error: "stack dealloc does
not match most recent stack alloc".

This reverts commit 7a2ca23bc2, reversing
changes made to 4c55e8d7a7.
2016-04-06 16:02:20 -07:00
Erik Eckstein
936b0acbef fix a comment 2016-04-06 11:11:13 -07:00
Roman Levenstein
2e77b3990b Add [nonatomic] attribute to all SIL reference counting instructions. 2016-04-06 01:52:43 -07:00
practicalswift
b01c615e0d Merge pull request #2053 from practicalswift/spacing
[gardening] if ([space]…[space]) → if (…), for(…) → for (…), while(…) → while (…), [[space]x, y[space]] → [x, y]
2016-04-05 00:01:14 +02:00
Adrian Prantl
1dff26abb8 Remove accidentally committed debug code. 2016-04-04 14:08:43 -07:00
practicalswift
abfecfde17 [gardening] if ([space]…[space]) → if (…), for(…) → for (…), while(…) → while (…), [[space]x, y[space]] → [x, y] 2016-04-04 16:22:11 +02:00
practicalswift
a7acb1a12a [gardening] Fix file header formatting. 2016-04-01 23:14:16 +02:00
practicalswift
fa1d5d231a [gardening] Fix recently introduced typo: "althouth" → "although" 2016-04-01 23:14:16 +02:00
Xin Tong
89bc2a46ef Merge pull request #1888 from trentxintong/RLE
remove an empty test case and pretty up some other and rename LSBase.cpp
2016-03-31 22:27:59 -07:00
Xin Tong
63d04a8713 Rename LSBase.cpp to LoadStoreOptUtils.cpp 2016-03-31 20:09:55 -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
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
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
8e624a655b remove unneeded allocation in swift::splitAllCriticalEdges 2016-03-27 10:59:29 -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
practicalswift
d00a5ef814 [gardening] Weekly gardening: typos, duplicate includes, header formatting, etc. 2016-03-24 22:41:10 +01: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
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
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
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
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