> On Oct 11, 2016, at 10:33 AM, Andrew Trick <[email protected]> wrote:
>
>
>> On Oct 11, 2016, at 10:10 AM, Joe Groff <[email protected]> wrote:
>>
>>
>>> On Oct 10, 2016, at 6:58 PM, Andrew Trick <[email protected]> wrote:
>>>
>>>
>>>> On Oct 10, 2016, at 6:23 PM, Joe Groff <[email protected]> wrote:
>>>>
>>>>
>>>>> On Oct 7, 2016, at 11:10 PM, Andrew Trick via swift-dev
>>>>> <[email protected]> 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.
>>>>
>>>> -Joe
>>>
>>> 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).
>>
>> Does a uniqueness check still need to be associated with a memory location
>> once we associate ownership with SSA values? It seems to me like it wouldn't
>> necessarily need to be. One thing I'd like us to work toward is being able
>> to reliably apply uniqueness checks to rvalues, so that code in a "pure
>> functional" style gets the same optimization benefits as code that
>> explicitly uses inouts.
>>
>> -Joe
>
> We could have an is_unique instruction that returns a “new” reference to
> storage. But our model for CoW data types relies mutating methods so I don't
> really know what you have in mind.
It doesn't fundamentally have to be tied to mutating methods. After all, you
ought to be able to take a value parameter you received as uniquely-referenced,
and work on that in-place:
func appendTwoArrays(a: [Int], b: [Int]) -> [Int] {
var a2 = __move__ a // fake syntax to force a move of ownership
if isUniquelyReferenced(&a2) {
a2.buffer._appendInPlace(b.buffer)
} else {
a2.buffer = Array(buffer: ArrayBuffer(appending: a2.buffer, and: b.buffer)
}
return a2
}
-Joe
_______________________________________________
swift-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-dev