← Back to context

Comment by NobleExpress

3 years ago

I've always heard of the "Swift elides reference counts" statements but I've never seen it substantiated. I don't claim to be a Swift GC expert by any means, but the impression I get from the two Swift GC papers I've read [1, 2] is that Swift has a very simple implementation of RC. The RC optimization document (albeit the document is incomplete) [3] also doesn't give me the impression that Swift is doing much eliding of reference counts (I'm sure it is doing it for simple cases).

Do you have any links which might explain what kind of eliding Swift is doing?

EDIT: The major RC optimizations I have seen which elide references are deferral and coalescing and I'm fairly certain that Swift is doing neither.

[1]: https://dl.acm.org/doi/abs/10.1145/3170472.3133843

[2]: https://doi.org/10.1145/3243176.3243195

[3]: https://github.com/apple/swift/blob/main/docs/ARCOptimizatio...

Swift's compiler elides obviously useless RC operations at compile time. It doesn't do anything at runtime though.

  • That is correct. Like Objective-C the compiler statically removes ARC when it can prove it doesn’t need it (or when you annotate it because where you’re getting it from is manually managing and giving you ownership of the reference). So within a function or cross function with LTO (although it looks like swift doesn’t yet have LTO [1] so I’m not sure about cross-module optimizations).

    > When receiving a return result from such a function or method, ARC releases the value at the end of the full-expression it is contained within, subject to the usual optimizations for local values.

    Quote from [2] (section 6 has the full details about optimizations). I believe [3] might be the compiler pass.

    There actually is some elision that happens at runtime if you install an autoreleasepool if I recall correctly.

    I did actually work at Apple so that’s where my recollection comes from although it’s been 8 years since then and I didn’t work on the compiler side of things so my memory could be faulty.

    [1] https://github.com/apple/swift/pull/32233

    [2] https://opensource.apple.com/source/lldb/lldb-112/llvm/tools...

    [3] https://llvm.org/doxygen/group__ARCOpt.html

    • > So within a function or cross function with LTO (although it looks like swift doesn’t yet have LTO [1] so I’m not sure about cross-module optimizations).

      I'm not sure Swift supports "static library modules" so in practice any linked object consists of a single module.

      > There actually is some elision that happens at runtime if you install an autoreleasepool if I recall correctly.

      There is a trick in the ObjC ABI that elides autorelease-returns, but it's deterministic after compilation time so I wouldn't call it a runtime optimization.

      3 replies →