3 ms·
I am not fully understanding how fat-pointers allow LLVM to devirtualize the function calls. If the allocators are polymorphic then a particular piece of code d
by celeritascelery 5y ago
I am not fully understanding how fat-pointers allow LLVM to devirtualize the function calls. If the allocators are polymorphic then a particular piece of code doesn't know which vtable it will get at run time correct?
- ayende 5y agoYou aren't modifying the same object When you have a fat pointer, llvm can tell you are modifying the ptr, bot the vtable You can then cache the function call When your vtable is in the object you are mutating, it needs to read each time
- celeritascelery 5y agoDoes LLVM do the inline caching itself? Or does it just enable zig to do this optimization?
- ayende 5y agoWhat happens is likely that the code gen can do the virtual lookup once, instead on each loop iteration This is llvm, bit zig
- Spex_guy 5y agoIt depends a lot, but in practice in Zig devirtualization is effectively constant propagation. The compiler needs to see the place where the vtable is created, and follow that to the place where virtual functions are called, ensuring along the way that nothing modifies the vtable. This is not possible for all uses of interfaces, but it is possible for many of them, especially ones where the interface is sort of "temporary" and you are usually passing around the implementation. These are the cases targeted by this change. The difference in results has to do with pointer provenance tracking and aliasing. With both approaches, the first call to an interface function will almost definitely be devirtualized. The problem is that that first call will also modify implementation state. If the implementation function is not inlined (which is common), this is tracked as a modification to the memory region containing the implementation state. But with the fieldParentPtr model, that's the same memory region containing the vtable! So this breaks constant propagation on the vtable and any later calls must always be fully virtual, even if the optimizer can see the whole way from vtable creation to virtual call.
- celeritascelery 5y agoSo does this optimization only work when the declaration of the allocator and its uses are in the same codegen unit? Otherwise the vtable of the allocator can’t be known at compile time.
- Spex_guy 5y agoZig's build model is mostly to combine everything into one compilation unit (from multiple files). Since Zig doesn't have a preprocessor, the compiler can reason about incremental compilation and avoid rebuilding everything for every change. Incremental optimization is an open question that we will need to tackle at some point, but the focus for now is on getting the language to a point where it can be stable first. You can introduce intentional graph cuts if you want, and build multiple objects, but you are limited to the C ABI at these boundaries.