Compile-time calculation: Difference between revisions
Content added Content deleted
Puppydrum64 (talk | contribs) |
(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}}== |