[swift-dev] [discussion notes] SIL address types and borrowing
atrick at apple.com
Mon Oct 10 20:58:04 CDT 2016
> On Oct 10, 2016, at 6:23 PM, Joe Groff <jgroff at apple.com> wrote:
>> On Oct 7, 2016, at 11:10 PM, Andrew Trick via swift-dev <swift-dev at swift.org> wrote:
>> ** World 1: SSA @inout
>> Projecting an element produces a new SILValue. Does this SILValue have
>> it's own ownership associated with it's lifetime, or is it derived
>> from it's parent object by looking through projections?
>> Either way, projecting any subelement requires reconstructing the
>> entire aggregate in SIL, through all nesting levels. This will
>> generate a massive amount of SILValues. Superficially they all need
>> their own storage.
>> [We could claim that projections don't need storage, but that only
>> solves one side of the problem.]
>> [I argue that this actually obscures the producer/consumer
>> relationship, which is the opposite of the intention of moving to
>> SSA. Projecting subelements for mutation fundamentally doesn't make
>> sense. It does make sense to borrow a subelement (not for
>> mutation). It also makes sense to project a mutable storage
>> location. The natural way to project a storage location is by
>> projecting an address...]
> I think there's a size threshold at which SSA @inout is manageable, and might lead to overall better register-oriented code, if the aggregates can be exploded into a small number of individual values. The cost of reconstructing the aggregate could be mitigated somewhat by introducing 'insert' instructions for aggregates to pair with the projection instructions, similar to how LLVM has insert/extractelement. "%x = project_value %y.field; %x' = transform(%x); %y' = insert %y.field, %x" isn't too terrible compared to the address-oriented formulation. Tracking ownership state through projections and insertions might tricky; haven't thought about that aspect.
We would have to make sure SROA+mem2reg could still kick in. If that happens, I don’t think we need to worry about inout ownership semantics anymore. A struct_extract is then essentially a borrow. It’s parent’s lifetime needs to be guaranteed, but I don’t know if the subobject needs explicit scoping in SIL since there’s no inout scopes to worry about and nothing for the runtime to do when the scope ends .
(Incidentally, this would never happen to a CoW type that has a uniqueness check—to mutate a CoW type, it’s value needs to be in memory).
More information about the swift-dev