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

core/compiler_hints: add assume() hint #19354

Merged
merged 2 commits into from
Apr 27, 2023

Conversation

benpicco
Copy link
Contributor

@benpicco benpicco commented Mar 6, 2023

Contribution description

This behaves like an assert() with DEVELHELP=1, but when DEVELHELP=0 it still gives the compiler a hint that the condition is guaranteed to be true and that it can optimize the code accordingly.

Testing procedure

Issues/PRs references

alternative to #19337

@benpicco benpicco requested a review from kaspar030 as a code owner March 6, 2023 18:26
@benpicco benpicco requested review from maribu and chrysn March 6, 2023 18:26
@github-actions github-actions bot added the Area: core Area: RIOT kernel. Handle PRs marked with this with care! label Mar 6, 2023
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 6, 2023
Copy link
Member

@chrysn chrysn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Do you have any good example for testing where the use of assume() makes a difference, or do you plan to switch some initial hot candidates over in the original PR already?

core/lib/include/compiler_hints.h Outdated Show resolved Hide resolved
@benpicco benpicco force-pushed the compiler_hints-assume branch from ee6ffd9 to c1f63ca Compare March 6, 2023 19:24
Copy link
Contributor

@kfessel kfessel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we name this macro assume, what will a macro pointing to https://clang.llvm.org/docs/AttributeReference.html#id468 / https://en.cppreference.com/w/cpp/language/attributes/assume ,which do not check the assumption, be called?

maybe our assume is just safer in the debug case?

@chrysn
Copy link
Member

chrysn commented Mar 6, 2023

If compilers provide any specialized form, it'd be possible to implement the (non-debug ... in debug mode it's probably helpful to check) assume function through their builtins. But outside corner cases, I doubt they'd make any difference: The one provided here is only evaluated if there's an external function or side effect invoked (why would one do that in an assume?), otherwise it may look like evaluating something, but by the outcome going into the unreachable, the compiler doesn't have to (and won't) emit code but just use the learned properties of the affected variables.

@riot-ci
Copy link

riot-ci commented Mar 6, 2023

Murdock results

✔️ PASSED

a5bc1b3 core/compiler_hints: fix detection of __builtin_unreachable()

Success Failures Total Runtime
6931 0 6931 10m:33s

Artifacts

@kfessel
Copy link
Contributor

kfessel commented Mar 6, 2023

wouldn't the preprocessor rewrite [[assume(x > 0)]] to [[assert(x > 0)]]?

https://godbolt.org/z/xojhj9ab8
the assume macro is expanded and then the attribute syntax goes wrong

@chrysn
Copy link
Member

chrysn commented Mar 7, 2023 via email

@maribu
Copy link
Member

maribu commented Mar 7, 2023

+1 for giving static inline a try.

IMO we should also provide a semantic patch to let the CI insist on assume() being used over assert(). Every quarter or so @gschorcht fixes compilation with NDEBUG and it is a a few dozen instances of function arguments not being used (well, they are used by assert() without NDEBUG) every time. That issue would be solved once and for all with switching to assume(). In addition it would be crystal clear that error handling with assume() is not to be done and hopefully everyone doea proper error handling (where recovery is possible and sensible) or uses expect() (where bringing thr chip into a stopped state is the most sensible thing to do).

@benpicco
Copy link
Contributor Author

The reason why a define is nicer is that it doesn't care about types.

If I have a static inline void assume(bool cond) that won't work with assume(ptr) - OK, maybe it would be better to write assme(ptr != NULL) , but I see several assert(ptr) so this is not something very unusual.

But this is not a mayor thing, if you really prefer the static inline function over the define, I'm fine with this slight inconvenience.

@maribu
Copy link
Member

maribu commented Apr 27, 2023

OK, let's have a define. It would be good to have this as a drop-in replacement as much as possible.

@benpicco benpicco added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Apr 27, 2023
@benpicco benpicco force-pushed the compiler_hints-assume branch from 05bc635 to a5bc1b3 Compare April 27, 2023 14:15
@maribu
Copy link
Member

maribu commented Apr 27, 2023

bors merge

@bors
Copy link
Contributor

bors bot commented Apr 27, 2023

Build succeeded:

@bors bors bot merged commit 7213c0a into RIOT-OS:master Apr 27, 2023
@benpicco benpicco deleted the compiler_hints-assume branch April 28, 2023 03:19
@benpicco benpicco added this to the Release 2023.07 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: core Area: RIOT kernel. Handle PRs marked with this with care! CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants