[swift-dev] Reducing array abstraction

Chris Lattner clattner at nondot.org
Tue Oct 10 00:42:55 CDT 2017


On Oct 9, 2017, at 9:55 PM, Slava Pestov via swift-dev <swift-dev at swift.org> wrote:
>> On Oct 7, 2017, at 2:01 PM, Chris Lattner <clattner at nondot.org> wrote:
>> Right.  If we ignore source compatibility for the moment, it seems clear that the best callee side representation for varargs is a borrowing array slice (like llvm::ArrayRef or UnsafeBufferPointer).  This provides the essential abstraction needed by varargs without forcing an onerous representation on the caller, and without implying any reference counting operations.  This would allow passing an Array, an ArraySlice, a StaticArray, or anything else with contiguous elements.
>> 
>>> What if I declare my vararg as shared:
>>> 
>>> func takesArgs(_ xs: shared Int…)
>> 
>> This seems like a great way to address the source compatibility issue: a normal varargs argument could be passed as an Array<T> for compatibility with existing source, and a “borrowed Int…” could be passed more efficiently, allowing folks to opt into that.
> 
> I talked about this with Joe today and he came up with an excellent idea.
> 
> We could still change the ABI for varargs so that at the SIL level, the caller passes an UnsafePointer<T> to a stack allocated buffer together with an element count, instead of a reference to the array. Then, as a transitional step, we could have the callee just always first box the varargs into a heap-allocated Swift.Array on entry into the function.

That makes perfect sense to me.  What are the tradeoffs vs passing an UnsafeBufferPointer?

> This has the advantage that it gives us a better ABI going forward without impacting source compatibility. Then we can design “tear-off arrays” or whatever we want to do there later, and stage the new behavior in with a new keyword, -swift-version flag or some implementation that maintains perfect backward compatibility with the current semantics.

+1.  I think the common case is to pass the array down the stack or immediately consume it (e.g. through a foreach loop), so the array should never have to be materialized in a the common case.

> Also, even without the language change, constructing the vararg array inside the callee will theoretically allow the optimizer to optimize it better, eliminating the heap allocation or performing scalar replacement on array elements.

Yep.

> What do you think? It would be a great project for an external contributor who is already familiar with the code base ;-)

That would be great.  I don’t expect to have time to do that myself, but I’d love to see it!  :-)

-Chris



More information about the swift-dev mailing list