4 ms·
> Sometimes, the compiler would get too smart for its own good, and recognize that a function that I wrote just copies memory. It would helpfully replace the fu
by MobiusHorizons 2y ago
> Sometimes, the compiler would get too smart for its own good, and recognize that a function that I wrote just copies memory. It would helpfully replace the function body with memcpy to save space.
I would generally expect this optimization to only be done for programs executing in userspace, not os / kernel style programs like this is. I would have expected the equivalent of -nostdlib to handle this automatically. I wonder if the author's build could be tweaked to tell llvm (which zig is based on) not to perform this or other "default to stdlib implementation" style optimizations
- pcwalton 2y agoThis is controllable by customizing TargetLibraryInfo [1] for your target in LLVM. Note, however, that detecting memcpy is always a valid optimization in C, not just in userspace. The C language standard, not POSIX, requires that a function spelled "memcpy" be available. As a side note, the optimization pass that detects and replaces memcpy is called LoopIdiomRecognize [2]. It actually detects quite a bit, not just memcpy. [1]: https://llvm.org/doxygen/TargetLibraryInfo_8cpp_source.html https://llvm.org/doxygen/TargetLibraryInfo_8cpp_source.html [2]: https://llvm.org/doxygen/LoopIdiomRecognize_8cpp.html https://llvm.org/doxygen/LoopIdiomRecognize_8cpp.html
- MobiusHorizons 2y agoVery Interesting! I guess I would still expect the optimization to use the library implementation of memcpy to be invalid when interacting with memory mapped IO. In this case the issue was the size of writes being issued (byte vs word), but you can easily imagine other issues that would not matter something like memcpy. I would have thought volatile might have signaled this, even if the issue here is not related to values being cached in registers. Does zig have a version of volatile?
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- int_19h 2y agohttps://ziglang.org/documentation/master/#volatile https://ziglang.org/documentation/master/#volatile
- NobodyNada 2y agoThe "correct" thing to do here is to use volatile writes to tell the compiler that they must not be torn: https://llvm.org/docs/LangRef.html#volatile-memory-accesses https://llvm.org/docs/LangRef.html#volatile-memory-accesses > IR-level volatile loads and stores cannot safely be optimized into llvm.memcpy or llvm.memmove intrinsics even when those intrinsics are flagged volatile. Likewise, the backend should never split or merge target-legal volatile load/store instructions. Similarly, IR-level volatile loads and stores cannot change from integer to floating-point or vice versa. Even in a baremetal/OS context, the compiler is generally allowed to split, combine, reorder, and eliminate memory access however it likes as long as the end result is consistent. Being able to do that is very important for performance and code size, which especially matters in embedded or OS dev -- for example, inserting memcpy calls can save on code size for things like passing a medium-sized struct to a function. The memory model for any reasonably low-level programming language nowadays requires you to specify whenever you actually need memory access that look exactly like you wrote. The OP suggests: > I know that this is a long shot, but it would be nice if there was some way to specify how memory in certain address ranges need to be addressed. The downside to this approach is that the compiler doesn't usually know what address range an arbitrary pointer will acccess; it's not resolved until link-time or often runtime. So this would require dynamic checks around every single memory access, which would kill performance. Thus, the solution is to use volatile loads and stores for any memory ranges that need special treatment.
- matheusmoreira 2y agoEven GCC emits calls to memcpy. Even for freestanding nostdlib targets. There is no way to turn it off. I had to implement memcpy because of it. Incredibly annoying. https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html > The compiler may generate calls to memcmp, memset, memcpy and memmove.
- tazjin 2y ago> llvm (which zig is based on) Wasn't Zig moving off LLVM?
- brabel 2y agoNo, it is adding an alternative to it. LLVM, last I heard, will still always be an option at least.
- cgh 2y agoHave you been following https://github.com/ziglang/zig/issues/16270 https://github.com/ziglang/zig/issues/16270 ?
- int_19h 2y agoThis says that they are moving off LLVM libraries, but the very first item in the TODO list is about directly outputting LLVM bitcode.
- brabel 2y agoYes, please read the comment linked at the issue description: https://github.com/ziglang/zig/issues/16270#issuecomment-1615388680 https://github.com/ziglang/zig/issues/16270#issuecomment-161...