Commit Graph

114 Commits

Author SHA1 Message Date
Xin Tong
ae86ef2b72 Implement more conservative debugging value support on function arguments in
function signature opt.

Instead of replacing %1 with UNDEF in debugvalueinst %1, we form an aggregate,
taking the alive part of %1 and fill the dead part with undef.

rdar://23727705
2016-02-04 10:50:26 -08:00
Xin Tong
8ce00e3989 Implement index_addr in alias analysis. We make use the new projection code
to disamuguite index_address with same base but different indices.

But the indices here have to be constant. This is a limitation/design choice
made in the projection code.

In order to handle non-constant indices, we need an analysis to compute the index
difference.

rdar://22484392
2016-01-26 20:41:10 -08:00
Erik Eckstein
250cac1a91 Remove some function overloads for SILValue/ValueBase*
They are not needed anymore because now SILValue is nothing more than a wrapper around ValueBase*
2016-01-26 09:37:08 -08:00
Xin Tong
8a1dd8abc8 Optimize how most derived type is computed in the new projection path Instead of walking the
entire projection path to find the most derived type, we cache it and invalidate when the projectionpath is
append'ed to.

stdlib -O

=== Before ===
Running Time        Self (ms)               Symbol Name
25741.0ms   37.3%   0.0                 swift::runSILOptimizationPasses(swift::SILModule&)
25523.0ms   37.0%   0.0                  swift::SILPassManager::runOneIteration()
20654.0ms   29.9%   36.0                  swift::SILPassManager::runFunctionPasses(llvm::ArrayRef<swift::SILFunctionTransform*>)
19663.0ms   28.5%   87.0                   swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
3279.0ms    4.7%    5.0                     (anonymous namespace)::SimplifyCFGPass::run()
3205.0ms    4.6%    11.0                    (anonymous namespace)::ARCSequenceOpts::run()
2550.0ms    3.7%    7.0                     (anonymous namespace)::SILCombine::run()
2177.0ms    3.1%    42.0                    (anonymous namespace)::RedundantLoadElimination::run()
2151.0ms    3.1%    115.0                   (anonymous namespace)::SILCSE::run()
1255.0ms    1.8%    18.0                    (anonymous namespace)::GenericSpecializer::run()
1080.0ms    1.5%    49.0                    (anonymous namespace)::DeadStoreElimination::run()
926.0ms    1.3%     189.0                   (anonymous namespace)::DCE::run()
488.0ms    0.7%     3.0                     (anonymous namespace)::SILCodeMotion::run()

=== After ===
Running Time        Self (ms)               Symbol Name
24065.0ms   36.8%   0.0                 swift::runSILOptimizationPasses(swift::SILModule&)
23865.0ms   36.5%   0.0                  swift::SILPassManager::runOneIteration()
19245.0ms   29.4%   42.0                  swift::SILPassManager::runFunctionPasses(llvm::ArrayRef<swift::SILFunctionTransform*>)
18273.0ms   27.9%   65.0                   swift::SILPassManager::runPassesOnFunction(llvm::ArrayRef<swift::SILFunctionTransform*>, swift::SILFunction*)
3096.0ms    4.7%    10.0                    (anonymous namespace)::ARCSequenceOpts::run()
3081.0ms    4.7%    9.0                     (anonymous namespace)::SimplifyCFGPass::run()
2381.0ms    3.6%    8.0                     (anonymous namespace)::SILCombine::run()
1990.0ms    3.0%    128.0                   (anonymous namespace)::SILCSE::run()
1828.0ms    2.8%    65.0                    (anonymous namespace)::RedundantLoadElimination::run()
1200.0ms    1.8%    10.0                    (anonymous namespace)::GenericSpecializer::run()
918.0ms    1.4%     58.0                    (anonymous namespace)::DeadStoreElimination::run()
867.0ms    1.3%     140.0                   (anonymous namespace)::DCE::run()
479.0ms    0.7%     11.0                    (anonymous namespace)::SILCodeMotion::run()
294.0ms    0.4%     1.0                     (anonymous namespace)::ConstantPropagation::run()
2016-01-25 20:12:37 -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
845b3fe08e SIL: remove isValid() from SILValue. NFC 2016-01-25 15:00:49 -08:00
Erik Eckstein
506ab9809f SIL: remove getTyp() from SILValue 2016-01-25 15:00:49 -08:00
Erik Eckstein
1383612ad6 Projection: project_box is an address projection 2016-01-25 10:37:03 -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
63713e044e Port alias analysis to use the NewProjection from the (old) Projection. This passes all validation
tests, including alias analysis SIL tests based on AAdumper.
2016-01-21 09:29:08 -08:00
Erik Eckstein
d6a95a6b81 SIL: handle project_box in Projection 2016-01-15 12:35:29 -08:00
Michael Gottesman
1c5ffe6dea Change PointerIntEnum to a new better representation.
The big differences here are that:

1. We no longer use the 4096 trick.

2. Now we store all indices inline so no mallocing is required and the
value is trivially copyable. We allow for much larger indices to be
stored inline which makes having an unrepresentable index a much smaller
issue. For instance on a 32 bit platform, in NewProjection, we are able
to represent an index of up to (1 << 26) - 1, which should be more than
enough to handle any interesting case.

3. We can now have up to 7 ptr cases and many more index cases (with each extra
bit needed to represent the index cases lowering the representable range of
indices).

The whole data structure is much simpler and easier to understand as a
bonus. A high level description of the ADT is as follows:

1. A PointerIntEnum for which bits [0, (num_tagged_bits(T*)-1)] are not all
set to 1 represent an enum with a pointer case. This means that one can have
at most ((1 << num_tagged_bits(T*)) - 2) enum cases associated with
pointers.

2. A PointerIntEnum for which bits [0, (num_tagged_bits(T*)-1)] are all set
is either an invalid PointerIntEnum or an index.

3. A PointerIntEnum with all bits set is an invalid PointerIntEnum.

4. A PointerIntEnum for which bits [0, (num_tagged_bits(T*)-1)] are all set
but for which the upper bits are not all set is an index enum. The case bits
for the index PointerIntEnum are stored in bits [num_tagged_bits(T*),
num_tagged_bits(T*) + num_index_case_bits]. Then the actual index is stored
in the remaining top bits. For the case in which this is used in swift
currently, we use 3 index bits meaning that on a 32 bit system we have 26
bits for representing indices meaning we can represent indices up to
67_108_862. Any index larger than that will result in an invalid
PointerIntEnum. On 64 bit we have many more bits than that.

By using this representation, we can make PointerIntEnum a true value type
that is trivially constructable and destructable without needing to malloc
memory.

In order for all of this to work, the user of this needs to construct an
enum with the appropriate case structure that allows the data structure to
determine what cases are pointer and which are indices. For instance the one
used by Projection in swift is:

   enum class NewProjectionKind : unsigned {
     // PointerProjectionKinds
     Upcast = 0,
     RefCast = 1,
     BitwiseCast = 2,
     FirstPointerKind = Upcast,
     LastPointerKind = BitwiseCast,

     // This needs to be set to ((1 << num_tagged_bits(T*)) - 1). It
     // represents the first NonPointerKind.
     FirstIndexKind = 7,

     // Index Projection Kinds
     Struct = PointerIntEnumIndexKindValue<0, EnumTy>::value,
     Tuple = PointerIntEnumIndexKindValue<1, EnumTy>::value,
     Index = PointerIntEnumIndexKindValue<2, EnumTy>::value,
     Class = PointerIntEnumIndexKindValue<3, EnumTy>::value,
     Enum = PointerIntEnumIndexKindValue<4, EnumTy>::value,
     LastIndexKind = Enum,
   };
2016-01-06 18:20:26 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
practicalswift
3d2997fe01 Fix recently introduced typos. 2015-12-30 12:39:07 +01:00
Michael Gottesman
a06cacbfcb [projection] Introduce two new types NewProjection and NewProjectionPath.
NewProjection is a re-architecting of Projection that supports all of
the same functionality as Projection but in 1/3 of the original size (in
the common case). It is able to accomplish this by removing the base
type out of NewProjection itself and into users such as
NewProjectionPath. Thus NewProjection is now strictly an index from some
parent type rather than being a parent type and an index.

NewProjectionPath also has all of the same functionality as
ProjectionPath, but due to NewProjection being smaller than Projection
is smaller than ProjectionPath.

Used together NewProjection/NewProjectionPath yields the same output as
Projection/ProjectionPath when evaluating the LSLocation dumping tests.

Additionally, NewProjection is more flexible than Projection and will
for free give us the ability to perform AA on index_addr/index_raw_addr
as well as be able to integrate casts into the projection paradigm.

rdar://22484381
2015-12-29 22:31:09 -06:00
ken0nek
fcd8fcee91 Convert [Cc]an not -> [Cc]annot 2015-12-23 00:55:48 +09:00
Michael Gottesman
5447cfa140 Fix infinite loop in Projection.
This was necessary for compilation purposes but was never executed. It was
caught by a clang warning.
2015-12-20 23:40:52 -08:00
Dmitri Gribenko
6aa0e0f1d7 Revert "Fix infinite loop in Projection."
This reverts commit a630f5942e.
Seems to cause a compiler crash on Linux.
2015-12-20 19:33:58 -07:00
Michael Gottesman
a630f5942e Fix infinite loop in Projection.
This was necessary for compilation purposes but was never executed. It was
caught by a clang warning.
2015-12-20 20:02:09 -06:00
practicalswift
ebd87f3e3b Fix typo: immeditely → immediately 2015-12-14 00:11:52 +01:00
Michael Gottesman
a8c12d0564 [proj] Change SubSeqRelation_t::Unrelated => SubSeqRelation_t::Unknown
This more correctly describes what the enum case means semantically.
2015-12-09 14:40:22 -08:00
Xin Tong
fc477ed65d Break type tree expansion with/without intermediate nodes into 2 different functions. Makes the logic easier to understand 2015-12-09 13:06:23 -08:00
Xin Tong
840342b920 Update some comments for expandTypeIntoLeafProjectionPaths in Projection.h 2015-12-09 12:17:22 -08:00
Xin Tong
f1d4ef7fc2 [RLE-DSE] Create a superclass for MemLocation and LoadStoreValue. These two share a lot
of identical fields, e.g. Base, ProjectionPath and Kind.

This is a refactoring change. Existing tests ensures correctness
2015-11-10 13:46:33 -08:00
Xin Tong
9cb86737fd [RLE-DSE] Implement LoadStoreValue in MemLocation.cpp. LoadStoreValue represents
the value residing in a given MemLocation. In RLE, we create a map between
MemLocation and its corresponding LoadStoreValue.
2015-11-05 10:03:31 -08:00
Michael Gottesman
a2a6a32983 Fix leak in function signature opts.
rdar://23346077
2015-11-02 11:07:56 -08:00
Xin Tong
562f417ff9 Use address projection instead of projection when expanding projection paths
for a SILType in MemLocation.

We get a sequence of address projections when initializing a memory location, i.e.
trace back to the base and then call getAddrProjectionPath.

To keep it consistent, we use address projections when we expand the projection
tree for a specific SILType as well.

By doing so, to get the type of the MemLocation, we can get just the first entry
in the projectionpath and get its object type.

Swift SVN r32775
2015-10-20 17:07:26 +00:00
Xin Tong
073b131bd5 Add a test case for type expansion on a class reference.
Swift SVN r32742
2015-10-17 18:38:12 +00:00
Xin Tong
895509ad8c Refactor how expand and reduce are implemented in MemLocation. BreadthFirstList now
takes a SILType instead of a MemLocation, BreadthFirstList will be used to expand
memory values in RLE as well.

Existing test cases make sure refactoring did not break anything.

Swift SVN r32739
2015-10-17 15:25:55 +00:00
Xin Tong
c6c43c69b5 Check memlocation projection path in MemLocationDumper
Swift SVN r32485
2015-10-07 01:29:46 +00:00
Xin Tong
1a38d9af8e Add printing capability for Projection and ProjectionPath.
Swift SVN r32483
2015-10-07 01:20:49 +00:00
Xin Tong
aba0903a16 Use new API in Projection.cpp(getFirstLevelProjection) to enumerate individual
fields in SILType in dead store elimination.

Swift SVN r32423
2015-10-03 18:43:03 +00:00
Xin Tong
b7e600104f Implement more type support for getFirstLevelProjection
Swift SVN r32380
2015-10-01 21:20:54 +00:00
Xin Tong
e8102449d7 Replace getHashCode() function with hash_value overload for ProjectionPath
Swift SVN r32364
2015-10-01 05:15:36 +00:00
Xin Tong
0a4841a526 Adding projection path into dead store elimination. With projection path, dead
store elimination can more precisely tell which 2 stores are to the same
location.

Swift SVN r32360
2015-10-01 02:48:12 +00:00
Mark Lacey
3563cbf577 Revert "Adding projection path into dead store elimination. With projection path, dead store elimination can more precisely tell which 2 stores are to the same location."
This reverts commit r32338 because it appears to have broken Havlak
under the leaks runner, as well as Dictionary and Set on the iOS
simulator.

Swift SVN r32341
2015-09-30 18:42:31 +00:00
Xin Tong
f1c5cd2859 Adding projection path into dead store elimination. With projection path, dead
store elimination can more precisely tell which 2 stores are to the same
location.

Swift SVN r32338
2015-09-30 16:32:11 +00:00
Michael Gottesman
add135a176 [proj] Add support to projection for getting all first level projections of an aggregate type and reforming from that type.
I am using this for SROAing BB arguments.

Swift SVN r31754
2015-09-08 00:55:41 +00:00
Michael Gottesman
5b6a76d4a9 [func-sig-opts] Expand the definition of a singleton tree to include trees with multiple levels of single field types.
This means that we will not explode things like:

struct A { var b: B }
struct B { var c: C }
struct C { var leaf: LeafType }

This does not add anything since all of the types are layout
compatible.

In terms of effect on dylib size, there is a small reduction (i.e. < 1%) over
all dylibs. The only really significant change is to Foundation which shrinks by
3%.

rdar://21114206

Swift SVN r29780
2015-06-29 06:26:25 +00:00
Michael Gottesman
d6721fc7d0 [ls-opts] Remove ForwardingAnalysis failable initializers in favor of just using constructors.
We know if the analysis fails by calling the canForward method instead of using
the failable static initializers. I am worried about unnecessary copies resulting
from the failable initializers.

Swift SVN r29466
2015-06-17 23:14:23 +00:00
Andrew Trick
e017e039e8 SIL/Projection: support for index_addr.
Moved the lightweight access path helper into a ProjectionIndex utility.
Added support to it and the kitchen-sink Projection utility.

Add a ProjectionIndex utility that supports IndexAddr and does only what it needs to do.

While I'm at it, add IndexAddr support to Projection and
ProjectionPath so that other passes can make use of it.
Unfortunately, LoadStore optimization is still not strong enough to
benefit, so I don't have a test case yet.

Note that we have to be very careful now not to assume that when one
projection path is a subsequence of another it must address an
containing region of memory. The implicit index_addr #0 is not part of
the projection path!

Swift SVN r29167
2015-05-30 04:37:01 +00:00
Mark Lacey
16041fe87b Re-enable function argument explosion in limited cases.
Re-enable function argument explosion during function signature
optimization in the case where there are between one and three live leaf
elements of the projection tree for the argument.

Three is an arbitrary limit, which we can consider tuning later, or
replacing with a better heuristic.

There are many limitations in what we can do at the SIL level to make a
good choice for this transformation, and this is just an attempt to keep
the transformation firing in some limited use cases where it is
relatively likely to be worthwhile rather than disabling it entirely.

I attempted to re-enable most of the test case that was disabled in
r29047.

This appears to eliminate or at least greatly reduce the regression
measured in the CaptureProp benchmark from the change in r29047.

Swift SVN r29062
2015-05-27 07:01:21 +00:00
Erik Eckstein
8aca63b2fc Don't delete debug_value/debug_value_addr in dead code elimination unless their definitions are dead.
And also adapt a whole set of SIL passes so that they can deal with (the not deleted) debug_value instructions.
This was required to prevent perforamnce and code size regressions.
Now the generated code is (almost) the same as before.

The effect of this change is that we keep debug_value/debug_value_addr also in optimized code (more or less).
Fixes rdar://problem/18709125.




Swift SVN r28872
2015-05-21 13:34:47 +00:00
Michael Gottesman
3ec2d151f6 Shrink Projection to 24 bytes and Add some static assertions to make sure that SILValue and Projection stay the same size and standard layout.
Swift SVN r26526
2015-03-25 06:21:08 +00:00
Michael Gottesman
0ac649d87b [proj-tree] Use a passed in BumpPtrAllocator instead of SmallVector for memory.
Previously I was using a large SmallVector to create Nodes for the
ProjectionTree. This created an issue when the SmallVector would convert
from small to large representation in the middle of a method on an
object that is stored in the SmallVector. Thus the 'this' pointer will
be invalidated and all sorts of fun times will occur.

I switched now to using a BumpPtrAllocator which is passed into the tree
and used in FunctionSignatureOptimization for all projection trees.

<rdar://problem/19534462>

Swift SVN r24706
2015-01-24 09:12:50 +00:00
Erik Eckstein
5cffa73bbd Refactoring: extract some code of the inliner to the projection classes.
Michael, thanks for your comments!

This also adds support for tuples and enums in Projection::getOperandForAggregate().



Swift SVN r24112
2014-12-23 16:26:08 +00:00
Michael Gottesman
6d61aad42e [proj] Add a new data structure called a "Projection Tree".
A "Projection Tree" takes in a type and constructs a tree where each non-leaf
node represents an aggregate that can be split up and all leaf nodes represent a
subtype of the original type that we can not split.

It additionally provides the capability to propagate usage information
and liveness information through the tree, making it trivial to perform
SROA + partial dead use elimination. I am using this in function
signature opts for that purpose.

Swift SVN r23586
2014-11-28 20:38:55 +00:00
Michael Gottesman
2d703a28f5 [proj] Add Projection::create{Addr,Value}Projection so one can create Projections without knowing what the internal state of the projection is.
Swift SVN r23371
2014-11-17 17:52:16 +00:00
Michael Gottesman
eeab468c8e [proj] Prepare Projection so that I can add generic create{Addr,Value}Projection.
I want to cleanup some code paths in SILCombine and LoadStoreOpts to use
generic create{Addr,Value}Projection methods which create the
appropriate projection instruction for a Projection method. Also this
will allow me to start to hide more of the internal state of Projection.

Swift SVN r23366
2014-11-17 06:43:37 +00:00
Michael Gottesman
06724fce02 [projection] Add comment to explain what projection path is.
Swift SVN r23357
2014-11-16 04:19:34 +00:00