New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flambda: No unboxing of float in simple local recursive function #7289
Comments
Comment author: @alainfrisch
|
Comment author: @gasche This issue is also discussed at: OCamlPro/flambda-task-force#158 Quoting Mark Shinwell's reply below:
|
Comment author: ybarnoy By definition, there will always be limits to the FLambda inlining approach, since the more is inlined, the fewer GC safe-spots there will be. As an example, if the recursive function allocates inside, I don't think it can be inlined, since allocation could cause GC calls, which will not have a safe-spot. (Let me know if I'm wrong about this logic). I therefore thing it would be nice to use a universal approach for passing unboxed floats and ints. |
Comment author: @alainfrisch
Indeed, I think you are :-) (1) There is really no relation between inlining and "GC safe-spots". (2) A function that allocates can certainly be inlined. (3) Turning a recursive function into a loop is not really "inlining" (or a very special form of it). |
Comment author: ybarnoy Alain, can you explain how GC safe-spots work, then? A function may have pointers inside not pointing to a header. Additionally, it may have unboxed ints and floats. If the GC is called in these situations, it would fail. So how do we handle it? |
Comment author: @alainfrisch A place in the machine code is GC safe if it is safe to trigger the GC at this place, i.e. the GC must have enough information to track all heap-allocated OCaml values and update them if they are moved. The compiler arrange so that whenever the GC can run, it knows this information. Given the current design of the OCaml GC, this means for instance that no pointer can point to the middle of a block at such place. In practice, the compiler produces data structures (frame descriptors) that tell the GC about which stack slots and machine register hold OCaml values. A function can indeed hold unboxed floats and untagged ints. The compiler simply does not insert the location that hold these values (stack/register) in the frame descriptor. Pointers (that will be follower later) never point to the middle of a block (except very locally, but certainly not when the GC can run, and in particular not before a function call). But all that has really nothing to do with inlining, which happens at a higher level (symbolic rewriting of expressions to replace a reference to an identifier with its identifier, and to reduce a function immediately applied to its arguments). In a first approximation, inlining could be expressed as source-to-source translation, and of course, any valid source code can be compiled to machine code "where the GC only runs when this is safe". |
Comment author: ybarnoy I see. So really, the only places boxing is absolutely required from the GC's perspective is inside heap data structures. Everything else can be removed from the GC's view, and boxing is only required for generic functions (either the OCaml ones or primitives). |
Comment author: @mshinwell I don't think this is a bug. We have a roadmap for a comprehensive treatment of unboxing (including unboxed floats being passed as function arguments, for what it's worth) in forthcoming Flambda versions. |
Original bug ID: 7289
Reporter: ybarnoy
Assigned to: @chambart
Status: closed (set by @mshinwell on 2017-03-07T11:45:24Z)
Resolution: not a bug
Priority: normal
Severity: minor
Version: 4.03.0
Target version: 4.05.0 +dev/beta1/beta2/beta3/rc1
Category: back end (clambda to assembly)
Monitored by: @gasche
Bug description
With 4.03+flambda, -O3, in
let _ =
let f = 100. in
let [@inline always] rec loop x =
if x <= 0. then 0.
else loop (x -. 5.)
in
loop f
I would expect x to be unboxed, but it isn't. Instead I get
(function camlTest__loop_4 (x_6/1203: val)
(if (<=f (load float64u x_6/1203) 0.) "camlTest__const_float_39"
(app{test.ml:5,9-23} "camlTest__loop_4"
(alloc 1277 (-f (load float64u x_6/1203) 5.)) val)))
The text was updated successfully, but these errors were encountered: