Skip to content

Commit d07335c

Browse files
committed
Assume for the GCC bounds checks
1 parent 880833d commit d07335c

3 files changed

Lines changed: 29 additions & 0 deletions

File tree

include/prism/compiler/assume.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @file compiler/assume.h
3+
*/
4+
#ifndef PRISM_COMPILER_ASSUME_H
5+
#define PRISM_COMPILER_ASSUME_H
6+
7+
/**
8+
* Tell the compiler that the given expression can be assumed to be true. Unlike
9+
* assert, this emits no runtime check — it only feeds the optimizer's value
10+
* range analysis so it can prune impossible paths. Use it to communicate an
11+
* invariant the caller guarantees but that the compiler cannot otherwise prove.
12+
*/
13+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L /* C23 or later */
14+
#define PRISM_ASSUME(expr_) [[assume(expr_)]]
15+
#elif defined(__clang__)
16+
#define PRISM_ASSUME(expr_) __builtin_assume(expr_)
17+
#elif defined(_MSC_VER)
18+
#define PRISM_ASSUME(expr_) __assume(expr_)
19+
#elif defined(__GNUC__)
20+
#define PRISM_ASSUME(expr_) ((expr_) ? (void) 0 : __builtin_unreachable())
21+
#else
22+
#define PRISM_ASSUME(expr_) ((void) 0)
23+
#endif
24+
25+
#endif

prism.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Gem::Specification.new do |spec|
4848
"include/prism.h",
4949
"include/prism/compiler/accel.h",
5050
"include/prism/compiler/align.h",
51+
"include/prism/compiler/assume.h",
5152
"include/prism/compiler/exported.h",
5253
"include/prism/compiler/fallthrough.h",
5354
"include/prism/compiler/filesystem.h",

templates/src/diagnostic.c.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "prism/internal/diagnostic.h"
22

3+
#include "prism/compiler/assume.h"
34
#include "prism/compiler/inline.h"
45

56
#include "prism/internal/allocator.h"
@@ -446,6 +447,7 @@ pm_diagnostic_id_name(pm_diagnostic_id_t diag_id) {
446447
static PRISM_INLINE const char *
447448
pm_diagnostic_id_message(pm_diagnostic_id_t diag_id) {
448449
assert(diag_id < PM_DIAGNOSTIC_ID_MAX);
450+
PRISM_ASSUME(diag_id < PM_DIAGNOSTIC_ID_MAX);
449451

450452
const char *message = diagnostic_messages[diag_id].message;
451453
assert(message);
@@ -456,6 +458,7 @@ pm_diagnostic_id_message(pm_diagnostic_id_t diag_id) {
456458
static PRISM_INLINE uint8_t
457459
pm_diagnostic_id_level(pm_diagnostic_id_t diag_id) {
458460
assert(diag_id < PM_DIAGNOSTIC_ID_MAX);
461+
PRISM_ASSUME(diag_id < PM_DIAGNOSTIC_ID_MAX);
459462

460463
return (uint8_t) diagnostic_messages[diag_id].level;
461464
}

0 commit comments

Comments
 (0)