avo
avo copied to clipboard
Support pre-processor macros and includes
Hello! I've been trying to express CPU-feature guards with avo, using the new microarchitecture level groups. Here's an example from the Go standard library:
#ifndef hasAVX2
CMPB internal∕cpu·X86+const_offsetX86HasAVX2(SB), $1
JEQ big_loop_avx2
JMP big_loop
#else
JMP big_loop_avx2
#endif
https://github.com/golang/go/blob/f79c99fe8ae4a5e4380af22ee6cb38c3eb3a0416/src/internal/bytealg/compare_amd64.s#L48-L54
As far as I can tell, the main thing missing from Avo to achieve this today is the ability to emit calls pre-processor macros (#ifndef
, #else
, etc.) The other missing piece is to provide custom includes to the file to use the constants referenced in these macros, so I also added a helper for that.
I'm submitting this PR as a concrete basis to discuss achieving this capability. I'm sorry if I missed something, and this is already possible!
Other options I've considered:
Allow emitting arbitrary text. A function like RAW("#ifndef hasAVX2")
would create a literal IR node which would be printed as-is. This felt too low-level compared to the rest of Avo. However, it would be nice to have this escape hatch.
Another option was to narrow the problem to this specific macro: #ifndef CPU feature
. For example (fictitious Avo code):
import ".../avo/guards"
IFNOTGUARD(guards.HasAVX2)
// instructions if not present
ELSE()
// instructions if present
ENDIF()
It would provide a higher level abstraction, and avoid exposing includes. I think it would add too much complexity to Avo to validate the control flow of those expressions.