Skip to content

[WIP] Unbox numbers across static handlers#2162

Closed
alainfrisch wants to merge 1 commit intoocaml:trunkfrom
alainfrisch:unbox_across_jumps2
Closed

[WIP] Unbox numbers across static handlers#2162
alainfrisch wants to merge 1 commit intoocaml:trunkfrom
alainfrisch:unbox_across_jumps2

Conversation

@alainfrisch
Copy link
Copy Markdown
Contributor

This is to resume the discussion on the proposal from #2156 to unbox numbers (floats, boxed ints) when passed as arguments to static handlers.

Static handlers are introduced by the compiler in a number of cases that can benefit from unboxing:

  • Tuple assignments:
let f z x y =
  let a, b =
    if z then (x * 2, y *. 3.)
    else (x, y)
  in
  float a -. b
  • Or-patterns:
type t = {x: float; y: float}
let f = function
  | Some {x; y = 0.} | Some {x = 0.; y = x} -> x +. x
  | _ -> 0.

The unboxing decision for staticcatch parameters (in Cmmgen) is currently only based on value kind annotations (inherit from Lambda). One bad case is when all staticraise sites naturally produce a boxed version (e.g. by calling a float-returning function, or reading from a boxed data structure), and the statichandler can use this boxed version directly. With the new heuristics, those floats will be unboxed and then reboxed when accessed in the handler. This is similar to what happens for float mutable variables, which are always unboxed (independently of the bound expression), and I think one can live with that.

An alternative approach would be to do as for immutable let bindings:

  1. If the bound variable is known to be a boxed number (from its value kind), one checks that unboxing the variable effectively result in removing at least one explicit boxing site when producing the bound value.

  2. If the bound variable is not known to be a boxed number, one needs to be more restrictive (since different sites can produce values of different types), and one checks that the bound value is necessarily a boxed number (all sites resulting in the same kind of boxed numbers).

The equivalent here would be to translate the body of the statichandler, look at all staticraise sites in it matching the current handler, check all possible ways each argument is produced, and determine the unboxing decision as above (and then traversing the compiled body to add unboxing instructions around each unboxed argument, for all staticraise sites).

For let bindings, the check is done on clambda terms. I've tried doing the same, but this misses some cases as in:

  (let
    (f/3
       (closure
         (fun camlFoo__f_3:float 3  z/4 x/5[int] y/6[float]
           (catch
             (if z/4
               (let (b/27 (*. y/6 "camlFoo__1"=3.) a/26 (* x/5 2))
                 (exit 1 b/27 a/26))
               (exit 1 "camlFoo__2"=45. x/5))
            with (1 b/8[float] a/7[int]) (-. (float_of_int a/7) b/8))) ))

This is because the b variable itself it not marked as a float (and this might suggest one could improve further the propagations of value kinds). Even if we managed to annotate the b/27 with Pfloatval, one would need to track the information to the exit 1 b/27 a/26. The alternative is to look instead at the generated cmm (which might benefit from inlining and other optimizations) to detect if a sub-expression is a boxed number. I've started working on that. One trouble is with constants, which are already turned into symbols (so one would need a lookup to check if a symbol represents a boxed number, which is not so nice).

@alainfrisch
Copy link
Copy Markdown
Contributor Author

The alternative is to look instead at the generated cmm (which might benefit from inlining and other optimizations) to detect if a sub-expression is a boxed number. I've started working on that. One trouble is with constants, which are already turned into symbols (so one would need a lookup to check if a symbol represents a boxed number, which is not so nice).

The same problem can already occur with unboxing of let bindings. I'm experimenting in #2165 with basing the unboxing criterion on cmm, not clambda.

@alainfrisch
Copy link
Copy Markdown
Contributor Author

Subsumed by #2165.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant