Compile-time calculation: Difference between revisions

Content added Content deleted
(OCaml: Add flambda compile-time reductions)
Line 792: Line 792:
grep 172801 sec.s
grep 172801 sec.s
movl $<span style="color:red">172801</span>, camlSec
movl $<span style="color:red">172801</span>, camlSec
<br/>
<br/>
However, with the introduction of [https://github.com/ocaml-flambda/flambda-backend Flambda] (an alternative intermediate language, inliner, and optimiser), OCaml compilers which equip this backend have a limited ability to reduce pure and annotated function calls to constants:

<lang ocaml>let fact10 =
let rec factorial n =
if n = 1 then n else n * factorial (n-1)
in
(factorial[@unrolled 10]) 10

(* The unrolled annotation is what allows flambda to keep reducing the call
* Beware that the number of unrollings must be greater than or equal to the
* number of iterations (recursive calls) for this to compile down to a constant. *)</lang>

The assembler output (cleaned up and demangled a little) shows exactly what's expected, stored as data
Example:
.quad <span style="color:red">7257601</span>
Example.entry:
movl $1, %eax
ret

And converting the tagged int to regular int we get
# 7257601 lsr 1 ;;
- : int = 3628800
<code>example.ml</code> is compiled with <code>ocaml.4.12.0+flambda</code> (2021); the unrolling annotation is older than that, compilers as old as <code>4.03.0+flambda</code> (2016) support it.


=={{header|Oforth}}==
=={{header|Oforth}}==