ocaml-flambda / flambda-backend

The Flambda backend project for OCaml
106 stars 76 forks source link

Optimize `(x mod pow2) = 0` #2187

Open xclerc opened 9 months ago

xclerc commented 9 months ago

As shown on this godbolt page, the following two functions are compiled differently, while the compiler could essentially rewrite is_divisible_by_128 into is_divisible_by_128_manual.

let is_divisible_by_128 x = (x mod 128) = 0

let is_divisible_by_128_manual x = (x land 127) = 0

The difficulty is that x mod 128 cannot be rewritten to x land 127; the optimization is valid iff the result is compared to 0.

This means that we need to match over a small expression tree to know whether to apply the rewrite. Since the flambda2 middle-end is let-binding all primitive applications, there seems to be two solutions:

The former is easy to do in Lambda_to_flambda, but looks like it will not scale. I am not exactly sure how to do the latter, but @mshinwell suggested @Gbury may have some ideas.

Gbury commented 9 months ago

This seems to fall into the kind of peephole optimizations that we may want to do in flambda2, using a dedicated engine to efficiently match potential expressions. I'll open a dedicated issue where we can have a list of all such optimisations that we might want to do.

xclerc commented 9 months ago

(also tagging @Svetlitski, because he is interested in having the rewrite)

Gbury commented 9 months ago

See #2188 : in short: it is possible to do that in flambda2 (we already do similar things), but it would require a bit of work to do properly (about one or two months I'd guess ?)

xclerc commented 9 months ago

Thanks; it is indeed quite similar to #1851.