> On Oct 11, 2016, at 11:02 AM, Joe Groff <jgr...@apple.com> wrote:
> 
> 
>> On Oct 11, 2016, at 10:50 AM, John McCall <rjmcc...@apple.com> wrote:
>> 
>>> On Oct 11, 2016, at 10:10 AM, Joe Groff via swift-dev <swift-dev@swift.org> 
>>> wrote:
>>>> On Oct 10, 2016, at 6:58 PM, Andrew Trick <atr...@apple.com> wrote:
>>>> 
>>>> 
>>>>> On Oct 10, 2016, at 6:23 PM, Joe Groff <jgr...@apple.com> wrote:
>>>>> 
>>>>> 
>>>>>> On Oct 7, 2016, at 11:10 PM, Andrew Trick via swift-dev 
>>>>>> <swift-dev@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.
>>>>> 
>>>>> -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.
>> 
>> As I've pointed out in the past, this doesn't make any semantic sense.  
>> Projecting out a buffer reference as a true r-value creates an independent 
>> value and therefore requires bumping the reference count.  The only query 
>> that makes semantic sense is "does this value hold a unique reference to its 
>> buffer", which requires some sort of language tool for talking abstractly 
>> about values without creating new, independent values.  Our only existing 
>> language tool for that is inout, which allows you to talk about the value 
>> stored in a specific mutable variable.  Ownership will give us a second and 
>> more general tool, borrowing, which allows you abstractly refer to immutable 
>> existing values.
> 
> If we have @owned values, then we also have the ability to do a uniqueness 
> check on that value, don't we? This would necessarily consume the value, but 
> we could conditionally produce a new known-unique value on the path where the 
> uniqueness check succeeds.
> 
> entry(%1: @owned $X):
>  is_uniquely_referenced %1, yes, no
> yes(%2: /*unique*/ @owned $X):
>  // %2 is unique, until copied at least
> no(%3: @owned %X):
>  // %3 is not
> 
> -Joe

You had to copy $X to make it @owned. You could check uniqueness of @borrowed 
$X, but then you’d need to copy to create a new array (mutation) before 
destroying the original that you borrowed from.

-Andy

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to