Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pre-processor macros and includes #406

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

pelletier
Copy link

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.

@klauspost
Copy link
Contributor

LGTM. That would solve #235 for me.

@mmcloughlin
Copy link
Owner

Thanks for this PR! I've posted some thoughts on the issue #235.

@pelletier
Copy link
Author

@mmcloughlin as discussed in #235, I've updated this PR to provide functions such as preproc.Ifndef, preproc.Else etc. as opposed to the original generic Preprocessor function. These functions insert their own node types in the IR. The intent is that the IR can then be checked for invalid constructions without having to do some string parsing of a generic node type.

I've also renamed Include to IncludeHeader to hopefully better convey that this function can be used anywhere to add a header, and is not a simple #include preprocessor macro insertion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants