Issue #634: May the compiler run a call with constant arguments at build time as an optimisation, where no comptime asks for it?
Open and answer this issue on GitHub.
decision · opened 2026-10-17 · updated 2026-10-17 · 0 comments
Where this comes from
The owner split this off from #633 (October 17, 2026). #633 decides that a call with constant arguments is compiled and run at build time where a claim needs its value (ADR-359 D11-D13, the ADR-321 path). What is left open is the other use: running such a call at build time only to save work at run time, where neither a comptime nor a claim asks for it.
The question
let table = build_table(256) is a sync call that touches nothing and has constant arguments. The program does not write comptime. May the compiler, on its own, run it while building and put the value into the program, the way ADR-321 runs a comptime?
What is known
- Who pays. At run time, every user pays on every run. At build time, the developer pays once per build, and with ADR-321 D4’s cache, only when something changed. For a program that runs often, the shift pays off; for code that is rarely or never reached at run time, it is pure cost.
- The meaning does not change. ADR-321 D1 runs the code compiled by the same implementation, so an overflow or an abort behaves the same. A call that stops at build time would have stopped the program wherever it is reached. Whether it is reached is exactly what an optimisation does not know, so a stop there may not refuse the build.
- LLVM already folds small cases in a release build (
example(2)). The gain lies where LLVM gives up: large loops, allocation, tables.
- Bounds: ADR-321 D7 (step budget, counted), D10 (memory), D11 (raised per
comptime). Without a comptime there is no place to raise them.
- Determinism: only a body whose touch set is empty qualifies.
args read means the builder’s arguments at build time and the user’s at run time.
Still owed before a decision round
- Options: never (the program writes
comptime when it wants the shift); a hint (comptime would move this to the build); automatic within a budget; automatic only in a release build.
- For each option: who pays, the effect on build time and on the cache, what happens when the budget runs out (silently left to run time?), and how the user sees it.
- How others do it: C++ (
constexpr is evaluated only where required; optimisers fold), Zig (comptime only where written), Rust (const only; LLVM folds), GraalVM/partial evaluation.
- A count: how many calls in the corpus would qualify, and what they cost at run time (callgrind, counted).
- A recommendation (CLAUDE.md, Decision rounds with the owner).
Back to Open Issues