code wiki / _hdl_build / nx_superopt_strength.nx
nx_superopt_strength.nx
buildroot/runtime/_hdl_build/nx_superopt_strength.nx
about
nx_superopt_strength.nx -- a GENERATOR: it AUTHORS strength-reduction lowerings
for `x * C` by SEARCH, not by me hand-writing each rule. Given a constant C, it
enumerates candidate implementations -- a single shift (x<<a), or a shift-op pair
((x<<a) + (x<<b) / (x<<a) - (x<<b)), or the fallback multiply -- VERIFIES each is
1:1 equal to x*C over many inputs, scores each by the measured cost model
(mul > shift+add, per nx_measure_cost), and RETURNS the cheapest verified one.
THIS is a building capability: the team discovers `x*7 = (x<<3)-x`, `x*9 =
(x<<3)+x`, `x*1024 = x<<10` ITSELF -- I wrote the searcher; the search wrote the
answers. It is the Generator leg the codegen loop consumes (each authored
lowering is a verified, cheaper codegen rewrite). Refs: Warren, Hacker's Delight
2e ch.8 (strength reduction); the e-graph superopt idea (egg, Willsey POPL 2021).
dependencies 1 imports · 2 importers
imports: nx_syscalls.nx
imported by: nx_superopt_govern_test.nxnx_superopt_strength_test.nx
structs
| none |
consts
| 15 | const SO_MAGIC_19088743: i64 = 19088743 |
| 16 | const SO_MAGIC_6364136223846793005: i64 = 6364136223846793005 |
| 17 | const SO_MAGIC_1442695040888963407: i64 = 1442695040888963407 |
| 19 | const SO_PLAN_MUL: i64 = 0 |
| 20 | const SO_PLAN_SHL: i64 = 1 |
| 21 | const SO_PLAN_SHIFTOP: i64 = 2 |
| 22 | const SO_ADD: i64 = 0 |
| 23 | const SO_SUB: i64 = 1 |
| 26 | const SO_MUL_COST: i64 = 4 |
| 27 | const SO_SHL_COST: i64 = 1 |
| 28 | const SO_OP_COST: i64 = 1 |
| 29 | const SO_SHIFT_MAX: i64 = 62 |
functions
| 32 | func so_eval(kind: i64, a: i64, op: i64, b: i64, C: i64, x: i64) -> i64 called by 1: so_verify |
| 42 | func so_cost(kind: i64, a: i64, b: i64) -> i64 called by 1: so_best |
| 52 | func so_verify(kind: i64, a: i64, op: i64, b: i64, C: i64) -> i64 |
| 68 | func so_best(C: i64, out: *i64) -> i64 |