Commit Graph

83 Commits

Author SHA1 Message Date
Xin Tong
8eedb43c4c Implement partially dead argument elimination.
This change includes an option on how IsLive is defined/computed. the ProjectionTree
can now choose to ignore epilogue releases and mark a node as dead if its only non-debug
user is epilogue release.

It can also mark a node as alive even its only user is epilogue release as before.

Imagine a case where one passes in an array and not access its owner
besides to release it. In such a case, we *do* want to be able to eliminate
that argument even though there is a release in the function epilogue.

This will help to get rid of the retain and release pair at the callsite. i.e.
the guaranteed paramter is elimininated.

rdar://21114206
2016-03-08 23:12:38 -05:00
Xin Tong
cf7614eeb6 Remove a small whitespace. NFC
I do not know how it got into there.

Thanks @gottesmm  for catching this.
2016-03-07 21:59:54 -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
Michael Gottesman
375a7bfde8 [gardening] Fix doxygen comment. NFC. 2016-02-18 01:10:51 -08:00
Xin Tong
99ca08e4af Check whether epilogue releases cover all non-trivial fields.
When we have all the epilogue releases. Make sure they cover all the non-trivial
parts of the base. Otherwise, treat as if we've found no releases for the base.

Currently. this is a NFC other than epilogue dumper. I will wire it up with
function signature with next commit.

This is part of rdar://22380547
2016-02-15 16:00:02 -08:00
Xin Tong
4f66bc88b4 Move ProjectionTree::isRedundantRelease to ConsumedArgToEpilogueReleaseMatcher::isRedundantRelease.
NFC.
2016-02-15 10:22:47 -08:00
Xin Tong
40ff0895d6 Improve epilogue release matcher to handle exploded release_value.
So instead of only being able to match %1 and release %1 in (1). we
can also match %1 with (release %2, and release%3, i.e. exploded release_value)
in (2).

(1)
foo(%1)
  strong_release %1

(2)
foo(%1)
  %2 = struct_extract %1, field_a
  %3 = struct_extract %1, field_b
  strong_release %2
  strong_release %3

This will allow function signature to better move the release instructions to
the callers.

Currently, this is a NFC other than testing using the epilogue match dumper.
2016-02-12 15:22:13 -08:00
Xin Tong
81c69fee4d Rename LeafIndices to LiveLeafIndices in ProjectionTree. NFC 2016-02-11 09:56:06 -08:00
Xin Tong
d59d567a77 Clean up the newly created Projection. NFC.
- Update comments.
- Correct 80 col violations mostly due to renaming NewProjection to Projection.
- Remove dead functions
2016-02-10 14:46:08 -08:00
Xin Tong
f22239b8f1 Remove 2 unused fields in ProjectionTreeNode. NFC. 2016-02-09 22:48:29 -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
042c6e033d And finally get rid of old projection. This is a NFC. rdar://24520269 2016-02-09 22:20:10 -08:00
Xin Tong
d9671f5b0e Migrate SILCombiner to new projection. This should be a NFC 2016-02-09 22:20:09 -08:00
Xin Tong
111af0322f Using ProjectionTree to create NewProjectionTree and wire NewProjectionTree up
with function signature optimizations to make sure it passes some basic testing.

We are one step closer to get rid of the old projection.
2016-02-09 22:20:09 -08:00
Xin Tong
51e89de905 [function-signature-opt] Explode argument level by level and lazily.
Previously, we exploded argument to the most-derived fields, i.e. the field that
can no longer be exploded further. And in the spliced (newly created) function,
we form aggregates if necessary.

Changing this to explode only to the deepest level accessed, this enables us to
create the projection tree nodes for fields of which its level is accessed, instead of
all fields on all levels.

Note: this also changes the definition of a leaf node. Leaf node now means the node
which does not have children based on current explosion (it however could have children
if exploded further).

I am refining the old projection tree first before (mostly copying) it to create the
new projection tree.
2016-02-09 14:52:10 -08:00
Xin Tong
d5dfe57e14 Migrate to use new projection for COWArrayOpt. This should be a NFC.
This is part of rdar://24520269
2016-02-07 13:56:12 -08:00
Xin Tong
17e3f35758 Migrate to use new projection for PerformanceInliner. This should be a NFC.
This is part of rdar://24520269
2016-02-07 13:56:12 -08:00
Xin Tong
0258e8e816 Migrate to use new projection for SimplifyCFG. This should be a NFC.
This is part of rdar://24520269
2016-02-06 08:27:05 -08:00
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