Difference in normal ocaml and flambda ocaml

Hello camlers,

I have a program that fails with (warning 55 [inlining-impossible] Function information unavailable) on an [@inline] annotation, But that compiles without problem when I use ocaml with flambda. Should this be considered a bug and reported as such on github ?

Remark: I must compile with dune --release because otherwise I have in both cases (with or without flambda)
: the optimizer did not know what function was being applied.

(Note: I’m assuming that the problematic annotation is an [@inlined] on a function application, not a [@inline] on a function definition)

It’s not a bug. The non-flambda compiler uses inlining settings that are fast (in terms of compile time) and don’t need to store much information in cmx files, but the drawback is that there are lots of situations where it can’t inline because it has already made a decision not to inline when seeing the function definition and cannot revert it at the application site.

The solution is usually to replace the [@inlined] annotation with [@inlined hint], which will tell the optimiser to inline if it can but not complain if it cannot. This is used in contexts where only the flambda version is supposed to be fast, and the non-flambda compiles and runs but without performance guarantees.
If you really need the function to be inlined even in non-flambda mode, you could try to add an [@inline] annotation to the corresponding function definition, but that is not guaranteed to work (some function are just too complex for the non-flambda inlining heuristic).

5 Likes

Thanks for your reply. and indeed I was using inlined

I explain what I am trying to achieve with flambda:

I have a bunch of signatures, structures and functors:

  • fieldBase : basic operation of fields, implemented for float, gmp and zarith ratioanl
  • a field functor that implements things like trichotomie and dighotomie above FieldBase
  • a vector and multivariate polynomial functors build on top of that.
  • I do not use polymorphic comparison but dedicated comparison in the structures/signatures (compare, =., <., …)

With flambda, I manage to inline all functors applications in the case of float.

It yelds a runtime of 14.5s on one of my example.

If I use a dune rule for all functors, adding only a type information for all functors:

(rule
   (target FVector.ml)
   (deps Vector.ml)
   (action (with-stdout-to %{target}
     (run sed "s/Make(R:S)/Make(R:S with type t = float)/" %{deps}))))

I go down to 11.5s (25% speed increase). This is not due to specialising the polymorphic operation as I do not use them.

I wonder why the type information is not propagated fully by inlining automatically ?

Anyway, my sed trick is reasonable and allows for using flambda and functor without loosing perormance.

The compiler drops most type information early during the compilation process. By the time we start making inlining decisions, most types have been erased, and we can’t re-infer them.

In your particular case, I can see two reasons why you would gain performance with the extra type annotation:

  • You’re using a lot of arrays, and the type annotation tells the compiler that it doesn’t have to check at runtime whether the arrays are regular arrays or flat float arrays (a 25% speed increase due to only that seems unlikely though).
  • You’re using a fair number of records, and benefit from the more compact layout of float-only records.

For arrays, we do have some code in the experimental flambda 2 compiler to rediscover array specialisation after inlining, but for float-only records it is not possible to do the same (you are not allowed to transform a record { x : 'a; y : 'a } into a float-only record even when you know that 'a is float unless you can prove that this record never escapes to another context).

Out of curiosity, is there an annotation which will cause a warning when it is not inlined by flambda? Essentially an annotation that says "I know the default optimiser might not be able to inline this, but in case the optimiser is flambda I really want this to be inlined.”

No, I don’t think so. The feature wouldn’t be particularly hard to implement, so if you want it you could either sumbit a feature request or a pull request. Although it should be fairly straightforward to implement as an external ppx too.

1 Like