; Bench fixture: pure-compute integer loop, no heap.
;
; Tail-recursive accumulator loop. Each step does one multiply and one
; add; no heap allocation, no closure capture, no pattern matching.
; The point is to isolate codegen quality on tight integer loops:
; under all three allocators the wall-time should be essentially
; identical (no allocator pressure to differentiate them), so any
; observed gc/bump/rc delta on this fixture is signal about codegen,
; not about memory management.
;
; Workload: intsum_loop(n, 0) with n iterations, each contributing
; i * 7 to the accumulator.
;
; Closed form: sum_{i=1..N} i * 7 = 7 * N * (N+1) / 2
;   N =     1_000_000  ->        3_500_003_500_000
;   N =    10_000_000  ->      350_000_035_000_000
;   N =    50_000_000  ->    8_750_000_175_000_000
;
; All three results fit comfortably in i64 (max 9.22e18).

(module bench_compute_intsum

  (fn intsum_loop
    (doc "Tail-recursive: acc += i*7 for i in [n, n-1, ..., 1]. Returns final acc.")
    (type
      (fn-type
        (params (con Int) (con Int))
        (ret (con Int))))
    (params i acc)
    (body
      (if (app == i 0)
        acc
        (tail-app intsum_loop
          (app - i 1)
          (app + acc (app * i 7))))))

  (fn run_one
    (type (fn-type (params (con Int)) (ret (con Unit)) (effects IO)))
    (params n)
    (body (do io/print_int (app intsum_loop n 0))))

  (fn main
    (type (fn-type (params) (ret (con Unit)) (effects IO)))
    (params)
    (body
      (seq (app run_one 1000000)
      (seq (app run_one 10000000)
           (app run_one 50000000))))))
