Commit Graph

60 Commits

Author SHA1 Message Date
Xin Tong
64e2710102 Move LSBase.x to SILOptimizer/Utils/. NFC. 2016-03-07 22:07:13 -05:00
Xin Tong
ba0249c924 Rename SILValueProjection.x to LSBase.x. NFC 2016-03-07 21:26:56 -05:00
Xin Tong
55377e727a Move createExtract to ProjectionPath::createExtract. NFC. 2016-03-07 21:26:56 -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
Kevin Yu
8f193c856e [gardening] Fix typos "cant" -> "can't", "dont" -> "don't" 2016-03-06 00:25:14 +00:00
Xin Tong
ddb9bba50e Improve the compilation time of redundant load elimination
For forwarding on allocstacks, we can invalidate the forwable bit when we
hit the deallocate stack.

This helps compilation time as we do not need to propagate these bits down
to subsequent basic blocks.
2016-02-29 10:11:40 -08:00
Xin Tong
19c528e59d Make more passes respect no.optimize 2016-02-26 16:03:17 -08:00
Xin Tong
a48584ccbc Create a fast path for not-final release instruction.
For a release on a guaranteed function paramater, we know right away
that its not the final release and therefore does not call deinit.

Therefore we know it does not read or write memory other than the reference
count.

This reduces the compilation time of dead store and redundant load elim. As
we need to go over alias analysis to make sure tracked locations do not alias
with it.
2016-02-20 22:00:36 -08:00
Xin Tong
95f3280461 Remove a double negative. NFC 2016-02-19 20:45:23 -08:00
Xin Tong
84a6ff1d98 And lastly rename NewProjection to Projection. This is a NFC. rdar://24520269 2016-02-09 22:20:10 -08:00
Xin Tong
dd8244f1a7 Set the kill bit for the store at the end of the basic block where the stored location is de-allocated.
rdar://24354423
2016-01-26 20:05:46 -08:00
Erik Eckstein
9f83c43a02 SIL: remove unused functions from SILValue 2016-01-26 09:37:08 -08:00
Xin Tong
f5bd3eab49 Optimize compilation time for RLE and DSE with respective
to the new projection path. We do not need to trace from the accessed field
to the base object when we've done it before in enumerateLSLOcations

Stdlib -O

=== Before ===

Running Time        Self (ms)           Symbol Name
25137.0ms   37.3%   0.0         swift::runSILOptimizationPasses(swift::SILModule&)
24939.0ms   37.0%   0.0         swift::SILPassManager::runOneIteration()
20226.0ms   30.0%   29.0        swift::SILPassManager::runFunctionPasses(llvm::ArrayRef<swift::SILFunctionTransform*>)
19241.0ms   28.5%   83.0        swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
3214.0ms    4.7%    10.0        (anonymous namespace)::SimplifyCFGPass::run()
3005.0ms    4.4%    14.0        (anonymous namespace)::ARCSequenceOpts::run()
2438.0ms    3.6%    7.0         (anonymous namespace)::SILCombine::run()
2217.0ms    3.2%    54.0        (anonymous namespace)::RedundantLoadElimination::run()
2212.0ms    3.2%    131.0       (anonymous namespace)::SILCSE::run()
1195.0ms    1.7%    11.0        (anonymous namespace)::GenericSpecializer::run()
1168.0ms    1.7%    39.0        (anonymous namespace)::DeadStoreElimination::run()
853.0ms    1.2%     150.0               (anonymous namespace)::DCE::run()
499.0ms    0.7%     7.0                 (anonymous namespace)::SILCodeMotion::run()

=== After ===

Running Time    Self (ms)               Symbol Name
22955.0ms   38.2%       0.0       swift::runSILOptimizationPasses(swift::SILModule&)
22777.0ms   37.9%       0.0       swift::SILPassManager::runOneIteration()
18447.0ms   30.7%       30.0      swift::SILPassManager::runFunctionPasses(llvm::ArrayRef<swift::SILFunctionTransform*>)
17510.0ms   29.1%       67.0      swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
2944.0ms    4.9%        5.0       (anonymous namespace)::SimplifyCFGPass::run()
2884.0ms    4.8%        12.0      (anonymous namespace)::ARCSequenceOpts::run()
2277.0ms    3.7%        1.0       (anonymous namespace)::SILCombine::run()
1951.0ms    3.2%        117.0     (anonymous namespace)::SILCSE::run()
1803.0ms    3.0%        54.0      (anonymous namespace)::RedundantLoadElimination::run()
1096.0ms    1.8%        10.0      (anonymous namespace)::GenericSpecializer::run()
911.0ms    1.5% 53.0              (anonymous namespace)::DeadStoreElimination::run()
795.0ms    1.3% 135.0             (anonymous namespace)::DCE::run()
453.0ms    0.7% 9.0               (anonymous namespace)::SILCodeMotion::run()
2016-01-25 20:10:04 -08:00
Xin Tong
546471ac4d Port dead store elimination and redundant load elimination to use the new projection.
This patch also implements some of the missing functions used by RLE and DSE in new projection
that exist in the old projection.

New projection provides better memory usage, eventually we will phase out the old projection code.

New projection is now copyable, i.e. we have a proper constructor for it.  This helps make the code
more readable.

We do see a bit increase in compilation time in compiling stdlib -O, this is a result of the way
we now get types of a projection path, but I expect this to go down (away) with further improvement
on how memory locations are constructed and cached with later patches.

=== With the OLD Projection. ===

Total amount of memory allocated.
--------------------------------
Bytes Used	Count		   Symbol Name
13032.01 MB      50.6%	2158819    swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
2879.70 MB      11.1%	3076018    (anonymous namespace)::ARCSequenceOpts::run()
2663.68 MB      10.3%	1375465	   (anonymous namespace)::RedundantLoadElimination::run()
1534.35 MB       5.9%	5067928	   (anonymous namespace)::SimplifyCFGPass::run()
1278.09 MB       4.9%	576714	   (anonymous namespace)::SILCombine::run()
1052.68 MB       4.0%	935809	   (anonymous namespace)::DeadStoreElimination::run()
 771.75 MB       2.9%	1677391	   (anonymous namespace)::SILCSE::run()
 715.07 MB       2.7%	4198193	   (anonymous namespace)::GenericSpecializer::run()
 434.87 MB       1.6%	652701	   (anonymous namespace)::SILSROA::run()
 402.99 MB       1.5%	658563	   (anonymous namespace)::SILCodeMotion::run()
 341.13 MB       1.3%	962459	   (anonymous namespace)::DCE::run()
 279.48 MB       1.0%	415031	   (anonymous namespace)::StackPromotion::run()

Compilation time breakdown.
--------------------------
Running Time	Self (ms)	    Symbol Name
25716.0ms   35.8%	0.0	    swift::runSILOptimizationPasses(swift::SILModule&)
25513.0ms   35.5%	0.0	    swift::SILPassManager::runOneIteration()
20666.0ms   28.8%	24.0	    swift::SILPassManager::runFunctionPasses(llvm::ArrayRef<swift::SILFunctionTransform*>)
19664.0ms   27.4%	77.0	    swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
3272.0ms    4.5%	12.0	    (anonymous namespace)::SimplifyCFGPass::run()
3266.0ms    4.5%	7.0	    (anonymous namespace)::ARCSequenceOpts::run()
2608.0ms    3.6%	5.0	    (anonymous namespace)::SILCombine::run()
2089.0ms    2.9%	104.0	    (anonymous namespace)::SILCSE::run()
1929.0ms    2.7%	47.0	    (anonymous namespace)::RedundantLoadElimination::run()
1280.0ms    1.7%	14.0	    (anonymous namespace)::GenericSpecializer::run()
1010.0ms    1.4%	45.0	    (anonymous namespace)::DeadStoreElimination::run()
966.0ms    1.3%	191.0	 	    (anonymous namespace)::DCE::run()
496.0ms    0.6%	6.0	 	    (anonymous namespace)::SILCodeMotion::run()

=== With the NEW Projection. ===

Total amount of memory allocated.
--------------------------------
Bytes Used	Count		    Symbol Name
11876.64 MB      48.4%	22112349    swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
2887.22 MB      11.8%	3079485	    (anonymous namespace)::ARCSequenceOpts::run()
1820.89 MB       7.4%	1877674	    (anonymous namespace)::RedundantLoadElimination::run()
1533.16 MB       6.2%	5073310	    (anonymous namespace)::SimplifyCFGPass::run()
1282.86 MB       5.2%	577024	    (anonymous namespace)::SILCombine::run()
 772.21 MB       3.1%	1679154	    (anonymous namespace)::SILCSE::run()
 721.69 MB       2.9%	936958	    (anonymous namespace)::DeadStoreElimination::run()
 715.08 MB       2.9%	4196263	    (anonymous namespace)::GenericSpecializer::run()

Compilation time breakdown.
--------------------------
Running Time	Self (ms)	    Symbol Name
25137.0ms   37.3%	0.0	    swift::runSILOptimizationPasses(swift::SILModule&)
24939.0ms   37.0%	0.0	    swift::SILPassManager::runOneIteration()
20226.0ms   30.0%	29.0	    swift::SILPassManager::runFunctionPasses(llvm::ArrayRef<swift::SILFunctionTransform*>)
19241.0ms   28.5%	83.0	    swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
3214.0ms    4.7%	10.0	    (anonymous namespace)::SimplifyCFGPass::run()
3005.0ms    4.4%	14.0	    (anonymous namespace)::ARCSequenceOpts::run()
2438.0ms    3.6%	7.0	    (anonymous namespace)::SILCombine::run()
2217.0ms    3.2%	54.0	    (anonymous namespace)::RedundantLoadElimination::run()
2212.0ms    3.2%	131.0	    (anonymous namespace)::SILCSE::run()
1195.0ms    1.7%	11.0	    (anonymous namespace)::GenericSpecializer::run()
1168.0ms    1.7%	39.0	    (anonymous namespace)::DeadStoreElimination::run()
853.0ms    1.2%	150.0	 	    (anonymous namespace)::DCE::run()
499.0ms    0.7%	7.0	 	    (anonymous namespace)::SILCodeMotion::run()
2016-01-25 20:08:29 -08:00
Erik Eckstein
74d44b74e7 SIL: remove SILValue::getDef and add a cast operator to ValueBase * as a repelacement. NFC. 2016-01-25 15:00:49 -08:00
practicalswift
71e00fefa1 [gardening] Fix typos: "word word" (two spaces) → "word word" (one space) 2016-01-24 21:27:16 +01:00
Xin Tong
894aa621cd Make Fix_lifetime instruction inert from a store prospective 2016-01-20 16:52:53 -08:00
Michael Gottesman
e25cd8860c Remove all uses of ilist_node::getNextNode() and ilist_node::getPrevNode() in favor of just using iterators.
This change is needed for the next update to ToT LLVM. It can be put
into place now without breaking anything so I am committing it now.

The churn upstream on ilist_node is neccessary to remove undefined
behavior. Rather than updating the different ilist_node patches for the
hacky change required to not use iterators, just use iterators and keep
everything as ilist_nodes. Upstream they want to eventually do this, so
it makes sense for us to just do it now.

Please do not introduce new invocations of
ilist_node::get{Next,Prev}Node() into the tree.
2016-01-19 14:44:58 -06:00
practicalswift
7b2bc2a0f4 Fix recently introduced typos. 2016-01-04 21:22:33 +01:00
Xin Tong
ba40b3f1a7 Take a more displined approach in DSE as to how to a function is optimized.
Now we have 3 cases.

1. OptimizeNone (for functions with too many basicblocks and too many locations). Simply return.
2. Pessimisitc single iteration data flow (for functions with many basic blocks and many locations).
3. Optimistic multiple iteration data flow (for functions with some basic blocks and some locations
   and require iterative data flow).

With this change stdlib and stdlibunittest has some changes in dead store(DS)
eliminated.

stdlib: 202 -> 203 DS.
stdlibunittest: 42 - 39 DS.

Compilation time improvement: with this change on a RELEASE+ASSERT compiler for stdlibunittest.

Running Time        Self (ms)               Symbol Name
5525.0ms    5.3%    25.0                     (anonymous namespace)::ARCSequenceOpts::run()
3500.0ms    3.4%    25.0                     (anonymous namespace)::RedundantLoadElimination::run()
3050.0ms    2.9%    25.0                     (anonymous namespace)::SILCombine::run()
2700.0ms    2.6%    0.0                      (anonymous namespace)::SimplifyCFGPass::run()
2100.0ms    2.0%    75.0                     (anonymous namespace)::SILCSE::run()
1450.0ms    1.4%    0.0                      (anonymous namespace)::DeadStoreElimination::run()
750.0ms    0.7%     75.0                     (anonymous namespace)::DCE::run()

Compilation time improvement: with this change on a DEBUG compiler for stdlibunittest.

Running Time        Self (ms)               Symbol Name
42300.0ms    4.9%   50.0                      (anonymous namespace)::ARCSequenceOpts::run()
35875.0ms    4.1%   0.0                       (anonymous namespace)::RedundantLoadElimination::run()
30475.0ms    3.5%   0.0                       (anonymous namespace)::SILCombine::run()
19675.0ms    2.3%   0.0                       (anonymous namespace)::SILCSE::run()
18150.0ms    2.1%   25.0                      (anonymous namespace)::SimplifyCFGPass::run()
12475.0ms    1.4%   0.0                       (anonymous namespace)::DeadStoreElimination::run()
5775.0ms    0.6%    0.0                       (anonymous namespace)::DCE::run()

I do not see a compilation time change in stdlib.

Existing tests ensure correctness.
2016-01-04 10:04:54 -08:00
practicalswift
1339b5403b Consistent use of header comment format.
Correct format:
//===--- Name of file - Description ----------------------------*- Lang -*-===//
2016-01-04 13:26:31 +01:00
practicalswift
50baf2e53b Use consistent formatting in top of file headers. 2016-01-04 02:17:48 +01:00
practicalswift
6c32688275 Fix recently introduced typos. 2016-01-03 21:16:23 +01:00
Xin Tong
4ea79fec2b There are simply too many locations and too many basic blocks in some
functions for dead store elimination to handle.  In the worst case, The number of
memory behavior or alias queries we need to do is roughly linear to
the # BBs x(times) # of locations.

Put in some heuristic to trade off accuracy for compilation time.

NOTE: we are not disabling DSE for these offending functions. instead we are running
a one iteration pessimistic data flow as supposed to the multiple iteration optimistic
data flow we've done previously.

With this change. I see compilation time on StdlibUnitTest drops significantly.
50%+ drop in time spent in DSE in StdlibUnit with a release compiler.

I will update more Instruments data post-commit once i get close to my desktop.

I see a slight drop in # of dead stores (DS) elimination in stdlib and stdlibUnit test.

stdlib: 203 DS -> 202 DS. (RLE is affected slightly as well. 6313 -> 6295 RL).

stdlibunittest :  43 DS -> 42. (RLE is not affected).

We are passing all existing dead store tests.
2016-01-03 10:48:02 -08:00
Xin Tong
013d08d439 Add a bailout location # threshold in DSE.
In StdlibUnitTest, there is this function that has too many (2450) LSLocations
and the data flow in DSE takes too long to converge.

StdlibUnittest.TestSuite.(addForwardRangeReplaceableCollectionTests <A, B where A: Swift.RangeReplaceableCollectionType, B: Swift.RangeReplaceableCollectionType, A.SubSequence: Swift.CollectionType, B.Generator.Element: Swift.Equatable, A.SubSequence == A.SubSequence.SubSequence, A.Generator.Element == A.SubSequence.Generator.Element> (Swift.String, makeCollection : ([A.Generator.Element]) -> A, wrapValue : (StdlibUnittest.OpaqueValue<Swift.Int>) -> A.Generator.Element, extractValue : (A.Generator.Element) -> StdlibUnittest.OpaqueValue<Swift.Int>, makeCollectionOfEquatable : ([B.Generator.Element]) -> B, wrapValueIntoEquatable : (StdlibUnittest.MinimalEquatableValue) -> B.Generator.Element, extractValueFromEquatable : (B.Generator.Element) -> StdlibUnittest.MinimalEquatableValue, checksAdded : StdlibUnittest.Box<Swift.Set<Swift.String>>, resiliencyChecks : StdlibUnittest.CollectionMisuseResiliencyChecks, outOfBoundsIndexOffset : Swift.Int) -> ()).(closure #18)

This function alone takes ~20% of the total amount of time spent in DSE in StdlibUnitTest.

And DSE does not eliminate any dead store in the function either. I added this threshold
to abort on functions that have too many LSLocations.

I see no difference in # of dead store eliminated in the Stdlib.
2016-01-02 17:37:53 -08:00
Xin Tong
310f48eab0 Improve dead store elimination compilation time.
If we know a function is not a one iteration function which means its
its BBWriteSetIn and BBWriteSetOut have been computed and converged,
and a basic block does not even have StoreInsts, there is no point
in processing every instruction in the last iteration of the data flow
again as no store will be eliminated.

We can simply skip the basic block and rely on the converged BBWriteSetIn
to process its predecessors.

Compilation time improvement: 1.7% to 1.5% of overall compilation time.
on stdlib -O. This represents a 4.0% of all SILOptimzations(37.2%)

Existing tests ensure correctness.
2016-01-01 10:16:42 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
practicalswift
6dac32e416 Fix typos in code merged today 2015-12-29 23:19:48 +01:00
Xin Tong
be4bf816bd Update some comments and rename runIterativeDF -> runIterativeDSE,
mergeSuccessorStates -> mergeSuccessorLiveIns in DSE. Also fix some includes.
2015-12-29 10:13:02 -08:00
Xin Tong
7c43b47bd0 revert some WIP code 2015-12-28 14:41:16 -08:00
Xin Tong
0c05064429 Speculative disable escape analysis in local variable DSE. There is test case failure
on the real device, but not on simulators. The failure could be a result of this change.
2015-12-28 14:39:54 -08:00
Xin Tong
7e49985b00 Turn a function into early exit sytle. NFC 2015-12-27 17:35:24 -08:00
Xin Tong
656894567f Some of the functions do not really need the iterative data flow in DSE. i.e. for function
of which a single post-order would be enough for DSE. In this case, we do not really
need to compute the genset and killset (which is a costly operation).

On stdlib, i see 93% of the functions are "OneIterationFunction".

With this change, i see the compilation time of DSE drops from 2.0% to 1.7% of the entire compilation.
This represents 4.3% of all the time spent in SILOptimizations (39.5%).
2015-12-26 20:33:35 -08:00
Chris Lattner
bee0d955ff Merge pull request #784 from practicalswift/a-vs-an-again
Fix typos: "a" vs. "an"
2015-12-26 17:45:36 -08:00
Xin Tong
173fc871ff Use a SmallBitVector instead of BitVector in DSE. I observed that most functions
do not have over 64 locations which makes SmallBitVector a more suitable choice
than BitVector.

I see a ~10% drop in compilation time in DSE. i.e. 1430ms to 1270ms (2.2% to 2.0% of
overall compilation time).
2015-12-26 12:30:49 -08:00
Xin Tong
8be2c51875 Merge 2 steps in data flow in DSE into 1. The more we iterate over the instructions in the function,
the more compilation time DSE take.

I see a ~10% drop in DSE compilation time, from 2.4% to 2.2%.

(Last time (~1 week ago) i checked DSE was taking 1.4% of the compilation time.  Now its taking 2.2%.
I will look into where the increase come from later).
2015-12-26 11:06:52 -08:00
practicalswift
fa0b339a21 Fix typos. 2015-12-26 17:51:59 +01:00
practicalswift
22e10737e2 Fix typos 2015-12-26 01:19:40 +01:00
Xin Tong
ed7ef800ab More refactoring in DSE. Split 1 more function and update some comments. 2015-12-24 16:11:19 -08:00
Xin Tong
30ed2f15aa Move local variable store checks into helper function. NFC 2015-12-24 15:26:37 -08:00
Xin Tong
1dd13b5d92 Optimize how basic blocks are processed in DSE. I do not see a real compilation time improvement 2015-12-24 15:10:39 -08:00
Xin Tong
6a942d2d20 Split bigger functions into multiple smaller functions in DSE. NFC 2015-12-24 14:58:44 -08:00
Xin Tong
32dc903339 Enable local variable dead store elimination
If a variable can not escape the function, we mark the store to it as dead before
the function exits.

It was disabled due to some TBAA and side-effect analysis changes.

We were removing 8 dead stores on the stdlib. With this change, we are now removing
203 dead stores.

I only see noise-level performance difference on PerfTestSuite.

I do not see real increase on compilation time either.
2015-12-24 14:18:36 -08:00
Erik Eckstein
dd204e68ef DSE: Use escape analysis for checking if memory locations are dead at the end of a function.
Currently NFC as local DSE is still disabled.
2015-12-23 16:43:11 -08:00
ken0nek
fcd8fcee91 Convert [Cc]an not -> [Cc]annot 2015-12-23 00:55:48 +09:00
Xin Tong
a95e25c887 Refactor in DSE
1. Add some comments regarding how the pass builds and uses genset and killset
2. Merge some similar functions.
3. Rename DSEComputeKind to DSEKind.
4. Some other small comment changes.
2015-12-20 14:19:47 -08:00
Xin Tong
cb94f5fdd1 Update some comments and remove dead code in dead store elimination 2015-12-18 10:18:36 -08:00
Xin Tong
4491d86dc3 Optimize how gen and kill sets are computed in dead store elimination. Existing tests ensure correctness 2015-12-18 09:50:48 -08:00
Dmitri Gribenko
6a66b3cff8 Merge pull request #561 from practicalswift/typos-again
[Typo] Replace PR#514-525 with one large PR
2015-12-18 03:37:02 -08:00
practicalswift
8ab8847684 Fix typos. 2015-12-16 22:09:32 +01:00