For a long time, we have:
1. Created methods on SILArgument that only work on either function arguments or
block arguments.
2. Created code paths in the compiler that only allow for "function"
SILArguments or "block" SILArguments.
This commit refactors SILArgument into two subclasses, SILPHIArgument and
SILFunctionArgument, separates the function and block APIs onto the subclasses
(leaving the common APIs on SILArgument). It also goes through and changes all
places in the compiler that conditionalize on one of the forms of SILArgument to
just use the relevant subclass. This is made easier by the relevant APIs not
being on SILArgument anymore. If you take a quick look through you will see that
the API now expresses a lot more of its intention.
The reason why I am performing this refactoring now is that SILFunctionArguments
have a ValueOwnershipKind defined by the given function's signature. On the
other hand, SILBlockArguments have a stored ValueOwnershipKind. Rather than
store ValueOwnershipKind in both instances and in the function case have a dead
variable, I decided to just bite the bullet and fix this.
rdar://29671437
As promised, we separate the duty of moving retain release pairs with the
task of removing them. Now the task of moving retains and releases are in
Retain Release Code Motion committed in 51b1c0bc68.
We were using a stripCast in some places and getRCIdentityRoot in others.
stripCasts is not identical to getRCIdentityRoot.
In particular, it does not look through struct_extract, tuple_extract,
unchecked_enum_data.
Created a struct and tuple test cases for make sure things are optimized
as they should be.
We have test case for unchecked_enum_data before.
Tested via static assert.
There is no reason for these data structures to not have these properties.
Adding these properties will improve the compile time efficiency of ARC by
allowing for cheaper copying and 0 cost destruction.
This speeds and reduces memory consumption of test cases with large
CFGs. The specific test case that spawned this fix was a large function
with many dictionary assignments:
public func func_0(dictIn : [String : MyClass]) -> [String : MyClass] {
var dictOut : [String : MyClass] = [:]
dictOut["key5000"] = dictIn["key500"]
dictOut["key5010"] = dictIn["key501"]
dictOut["key5020"] = dictIn["key502"]
dictOut["key5030"] = dictIn["key503"]
dictOut["key5040"] = dictIn["key504"]
...
}
This continued for 10k - 20k values.
This commit reduces the compile time by 2.5x and reduces the amount of
memory allocated by ARC by 2.6x (the memory allocation number includes
memory that is subsequently freed).
rdar://24350646
Previously, we relied on a quirk in the ARC optimizer so that we only
need to visit terminators top down. This simplified the dataflow. Sadly,
try_apply changes this since it is a terminator that provides a call
with the value, causing this assumption to break program correctness.
Now during the bottom up traversal, while performing the dataflow for a
block B, we (after visiting all instructions), visit B's predecessors to
see if any of them have a terminator that is a use or decrement. We then
take the most conservative result among all of the terminators and
advance the sequence accordingly.
I do not think that we can have multiple such predecessors today since all
interesting terminators can not have any critical edges to successors. Thus if
our block is a successor of any such block, it can not have any other
predecessors. This is mainly for future proofing if we decide that this is able
to be done in the future.
rdar://23853221
SR-102
(libraries now)
It has been generally agreed that we need to do this reorg, and now
seems like the perfect time. Some major pass reorganization is in the
works.
This does not have to be the final word on the matter. The consensus
among those working on the code is that it's much better than what we
had and a better starting point for future bike shedding.
Note that the previous organization was designed to allow separate
analysis and optimization libraries. It turns out this is an
artificial distinction and not an important goal.