Arithmetic on compile-time constants is evaluated at compile time:
const X = 10 + 20 // folded to const X = 30
int y = 5 * 7 // generates: int32_t y = 35
Supports integer and float operations. Prevents runtime computation of known values.
Every fn (except export fn and extern fn) is generated as:
__attribute__((always_inline)) static inline return_type func_name(params);
This gives the C compiler maximum flexibility to inline functions, eliminating call overhead for small functions.
The compiler generates __attribute__((aligned(N))) for float/f64 fields and arrays:
struct Particles {
float positions[4] __attribute__((aligned(16))); // SSE
double velocities[2] __attribute__((aligned(32))); // AVX
};
f32[4] → aligned(16) for SSE/NEONf64[2] → aligned(32) for AVXf32 fields → aligned(16) if adjacent to other floatsgcc -O3The compiler flags unreachable code:
fn test() -> int {
return 42
error("unreachable") // compile warning
}
The C compiler further eliminates dead code at -O3.
The bump allocator is a pointer bump + size check:
static inline void* block_alloc(BlockCtx* ctx, int64_t size) {
void* ptr = ctx->ptr;
ctx->ptr += size;
if (ctx->ptr > ctx->end) {
error("block overflow");
}
return ptr;
}
For types ≤ 64 bytes, the pool allocator provides:
void* pool_alloc(PoolAllocator* pool, int64_t size);
void pool_free(PoolAllocator* pool, void* ptr);
| Allocator | Allocation | Free | Reset | Fragmentation |
|---|---|---|---|---|
| Block (bump) | ~3 cycles | N/A | ~5 ns | None |
| Pool | O(1) | O(1) | O(1) | Internal only |
| malloc | ~100 cycles | ~50 cycles | N/A | Yes |
__thread BlockCtx* block_tls;
block_set_tls(ctx); // thread-local block
void* ptr = block_alloc(block_get_tls(), size);
block_enable_double_buffer(ctx);
// ... allocate in active buffer ...
block_swap_buffers(ctx); // atomic pointer swap (~1 cycle)
Every line of generated C includes a #line directive pointing to the .brc source:
#line 1 "game.brc"
#include <stdint.h>
#include <stddef.h>
#line 5 "game.brc"
int32_t main() {
// ...
This allows:
.brc filesgcc -g preserves source mappingi1–i8 → int8_t (no wasted bits for non-bitfield)u1–u8 → uint8_tbool → uint8_t with explicit 0/1usize → size_t (matches pointer width)BrickString is a contiguous struct:
typedef struct {
char* data;
int64_t len;
} BrickString;
len enables fast length checkstypedef struct {
void (*draw)(void*);
} DrawableVtbl;
typedef struct {
void* data;
const DrawableVtbl* vtbl;
} Drawable;
scons profile=pgo-gen # build instrumented binary
./program --benchmark # collect profile data
scons profile=pgo-use # rebuild with profile
-fprofile-generate-fprofile-usescons profile=release # default: -O3 -march=native -flto
-O3: full optimization-march=native: CPU-specific instructions-flto: link-time optimization (cross-module inlining)-fomit-frame-pointer (when debug off)| Operation | Brick | Plain C | Ratio |
|---|---|---|---|
| int add | 1 cycle | 1 cycle | 1.0× |
| function call (inline) | 0 cycles | 0 cycles | 1.0× |
| struct field access | 1 cycle | 1 cycle | 1.0× |
| block alloc | 3 cycles | n/a | — |
| array index | 1 cycle | 1 cycle | 1.0× |
| match/switch | same as C | same | 1.0× |
| vtbl dispatch | 2-3 cycles | same | 1.0× |