> On Oct 10, 2017, at 9:50 AM, Erik Eckstein <eeckst...@apple.com> wrote:
> 
> 
> 
>> On Oct 9, 2017, at 9:46 PM, Chris Lattner <clatt...@nondot.org 
>> <mailto:clatt...@nondot.org>> wrote:
>> 
>> On Oct 8, 2017, at 3:30 PM, Erik Eckstein <eeckst...@apple.com 
>> <mailto:eeckst...@apple.com>> wrote:
>>>>> We definitely already have a heap->stack for classes in the guise of the 
>>>>> StackPromotion optimization is that what you are talking about with the 
>>>>> "array outlining" optimization? (outlining to me is referring to 
>>>>> specifically code outlining). IIRC Erik (+CC) do special work to make it 
>>>>> work for fixed size array. I would ask why that optimization is not 
>>>>> kicking in for varargs. Perhaps, we could add a special recognition that 
>>>>> the given array will not escape through a varargs? Or provide some way of 
>>>>> saying, trust me this doesn't escape.
>>> 
>>> We already do heap->stack promotion for array buffers. This is done in the 
>>> StackPromotion pass. It uses interprocedural escape analysis to check if it 
>>> can be done. So if the callee is known it should work with the varargs 
>>> array. BTW it also works in your example, in testAPI():
>>> 
>>> %1 = alloc_ref [stack] [tail_elems $Int * %0 : $Builtin.Word] 
>>> $_ContiguousArrayStorage<Int>
>>> 
>>> But it’s not zero cost, because we initialize the metadata pointer + 
>>> refcount in a runtime function. Also we do ref-count operations on the 
>>> array in the callee (this will improve as soon as we have a ref count 
>>> representation for immortal objects).
>> 
>> This is fantastic, I didn’t notice the [stack] marker there!  I’m thrilled 
>> you’re on top of this.  It looks like you have a well-developed framework 
>> here, which I haven’t fully ingested.  As such, I have a few questions for 
>> you:
>> 
>> 1) With a debug build of the stdlib, the “isNative” and other sanity checks 
>> in the stdlib create a lot of bridge_object_to_word -> zext to i64 -> 
>> and-with-magic-arch-specific-constant checks to validate that the array is 
>> properly in a native state.  Have you considered introducing a 
>> “bridge_object_classify” SIL instruction which translates a bridge object 
>> value into a tuple of bits (isNative, isObjC, etc)  + unbitmangled value?  
>> It seems super weird to me that there are a bunch of architecture-specific 
>> magic constants in stdlib/public/core/Builtin.swift.  It seems that these 
>> should be encapsulated into a SIL instruction, which would then allow the 
>> SIL optimizer to eliminate these checks.  
>> 
>> Particularly with a debug stdlib, it is super common to see an 
>> “array.uninitialized” call which then gets bitwise queried through a 
>> super-verbose series of SIL instructions that are opaque to the SIL 
>> optimizer (because they are arch specific).  Encapsulating this into SIL 
>> seems like a good call both from putting the arch-specific bits into the SIL 
>> layer which can expand it in IRGen (if it survives that long) and also 
>> optimize it away in the common case when it is knowable if these bits are 0 
>> or 1 (as when coming from an array literal or other common known-native 
>> construct). 
>> 
>> 
>> 2) You have an apparently great infra for escape analysis of arrays.  Have 
>> you considered adding one more check?  If the only uses of the reference 
>> counted object is a single release in the current function (common when 
>> passing array literals to C functions) then you can eliminating the heap 
>> allocation AND all the refcounting instructions and use a simple alloc_stack 
>> (of an array of tuples?) and put the dealloc stack where the single release 
>> is.  This seems like it would be a particularly bit win for the simple case 
>> of things like:
>> 
>>      memcpy(dest, [1,2,3,4], sizeof(Int)*4) 
>> 
>> among others.  Because the array literal would turn into the C-equivalent 
>> construct with zero overhead.
>> 
> 
> Sounds like the ReleaseDevirtualizer

Perhaps similar, but it really isn’t.  I’m specifically talking about replacing 
the alloc_ref [stack] with an alloc_stack.

>> 3) There are other optimizations like ArrayElementValuePropagation, which 
>> don’t handle the BridgeObjectToWordInst or AddressToPointer or 
>> UncheckedRefCastInst, and thus give up.  This causes a number of limitations 
>> (though I have no idea if they are important in practice or not): since 
>> conversions to UnsafePointer cannot mutate the array, they should not 
>> prevent element optimizations, count propagation optimizations, etc.
> 
> 1) and 3) 
> There are some discussions ongoing regarding array bridging. So things may 
> change anyway.

Ok, sounds promising but also mysterious.  Can you elaborate?

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

Reply via email to