Skip to content

Commit

Permalink
Distinguish float field accesses in the Code IR
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierNicole committed Aug 28, 2024
1 parent f96b7a0 commit fab177e
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 79 deletions.
20 changes: 14 additions & 6 deletions compiler/lib/code.ml
Original file line number Diff line number Diff line change
Expand Up @@ -459,14 +459,18 @@ type mutability =
| Immutable
| Maybe_mutable

type field_type =
| Non_float
| Float

type expr =
| Apply of
{ f : Var.t
; args : Var.t list
; exact : bool
}
| Block of int * Var.t array * array_or_not * mutability
| Field of Var.t * int
| Field of Var.t * int * field_type
| Closure of Var.t list * cont
| Constant of constant
| Prim of prim * prim_arg list
Expand All @@ -475,7 +479,7 @@ type expr =
type instr =
| Let of Var.t * expr
| Assign of Var.t * Var.t
| Set_field of Var.t * int * Var.t
| Set_field of Var.t * int * field_type * Var.t
| Offset_ref of Var.t * int
| Array_set of Var.t * Var.t * Var.t

Expand Down Expand Up @@ -619,7 +623,8 @@ module Print = struct
Format.fprintf f "; %d = %a" i Var.print a.(i)
done;
Format.fprintf f "}"
| Field (x, i) -> Format.fprintf f "%a[%d]" Var.print x i
| Field (x, i, Non_float) -> Format.fprintf f "%a[%d]" Var.print x i
| Field (x, i, Float) -> Format.fprintf f "FLOAT{%a[%d]}" Var.print x i
| Closure (l, c) -> Format.fprintf f "fun(%a){%a}" var_list l cont c
| Constant c -> Format.fprintf f "CONST{%a}" constant c
| Prim (p, l) -> prim f p l
Expand All @@ -629,7 +634,10 @@ module Print = struct
match i with
| Let (x, e) -> Format.fprintf f "%a = %a" Var.print x expr e
| Assign (x, y) -> Format.fprintf f "(assign) %a = %a" Var.print x Var.print y
| Set_field (x, i, y) -> Format.fprintf f "%a[%d] = %a" Var.print x i Var.print y
| Set_field (x, i, Non_float, y) ->
Format.fprintf f "%a[%d] = %a" Var.print x i Var.print y
| Set_field (x, i, Float, y) ->
Format.fprintf f "FLOAT{%a[%d]} = %a" Var.print x i Var.print y
| Offset_ref (x, i) -> Format.fprintf f "%a[0] += %d" Var.print x i
| Array_set (x, y, z) ->
Format.fprintf f "%a[%a] = %a" Var.print x Var.print y Var.print z
Expand Down Expand Up @@ -903,7 +911,7 @@ let invariant { blocks; start; _ } =
let check_expr = function
| Apply _ -> ()
| Block (_, _, _, _) -> ()
| Field (_, _) -> ()
| Field (_, _, _) -> ()
| Closure (l, cont) ->
List.iter l ~f:define;
check_cont cont
Expand All @@ -917,7 +925,7 @@ let invariant { blocks; start; _ } =
define x;
check_expr e
| Assign _ -> ()
| Set_field (_, _i, _) -> ()
| Set_field (_, _i, _, _) -> ()
| Offset_ref (_x, _i) -> ()
| Array_set (_x, _y, _z) -> ()
in
Expand Down
8 changes: 6 additions & 2 deletions compiler/lib/code.mli
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,18 @@ type mutability =
| Immutable
| Maybe_mutable

type field_type =
| Non_float
| Float

type expr =
| Apply of
{ f : Var.t
; args : Var.t list
; exact : bool (* if true, then # of arguments = # of parameters *)
}
| Block of int * Var.t array * array_or_not * mutability
| Field of Var.t * int
| Field of Var.t * int * field_type
| Closure of Var.t list * cont
| Constant of constant
| Prim of prim * prim_arg list
Expand All @@ -234,7 +238,7 @@ type expr =
type instr =
| Let of Var.t * expr
| Assign of Var.t * Var.t
| Set_field of Var.t * int * Var.t
| Set_field of Var.t * int * field_type * Var.t
| Offset_ref of Var.t * int
| Array_set of Var.t * Var.t * Var.t

Expand Down
8 changes: 4 additions & 4 deletions compiler/lib/deadcode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ and mark_expr st e =
mark_var st f;
List.iter args ~f:(fun x -> mark_var st x)
| Block (_, a, _, _) -> Array.iter a ~f:(fun x -> mark_var st x)
| Field (x, _) -> mark_var st x
| Field (x, _, _) -> mark_var st x
| Closure (_, (pc, _)) -> mark_reachable st pc
| Special _ -> ()
| Prim (_, l) ->
Expand All @@ -91,7 +91,7 @@ and mark_reachable st pc =
match i with
| Let (_, e) -> if not (pure_expr st.pure_funs e) then mark_expr st e
| Assign _ -> ()
| Set_field (x, _, y) -> (
| Set_field (x, _, _, y) -> (
match st.defs.(Var.idx x) with
| [ Expr (Block _) ] when st.live.(Var.idx x) = 0 ->
(* We will keep this instruction only if x is live *)
Expand Down Expand Up @@ -124,7 +124,7 @@ and mark_reachable st pc =
let live_instr st i =
match i with
| Let (x, e) -> st.live.(Var.idx x) > 0 || not (pure_expr st.pure_funs e)
| Assign (x, _) | Set_field (x, _, _) -> st.live.(Var.idx x) > 0
| Assign (x, _) | Set_field (x, _, _, _) -> st.live.(Var.idx x) > 0
| Offset_ref _ | Array_set _ -> true

let rec filter_args st pl al =
Expand Down Expand Up @@ -201,7 +201,7 @@ let f ({ blocks; _ } as p : Code.program) =
match i with
| Let (x, e) -> add_def defs x (Expr e)
| Assign (x, y) -> add_def defs x (Var y)
| Set_field (_, _, _) | Array_set (_, _, _) | Offset_ref (_, _) -> ());
| Set_field (_, _, _, _) | Array_set (_, _, _) | Offset_ref (_, _) -> ());
match fst block.branch with
| Return _ | Raise _ | Stop -> ()
| Branch cont -> add_cont_dep blocks defs cont
Expand Down
4 changes: 2 additions & 2 deletions compiler/lib/duplicate.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ let expr s e =
| Apply { f; args; exact } ->
Apply { f = s f; args = List.map args ~f:(fun x -> s x); exact }
| Block (n, a, k, mut) -> Block (n, Array.map a ~f:(fun x -> s x), k, mut)
| Field (x, n) -> Field (s x, n)
| Field (x, n, field_type) -> Field (s x, n, field_type)
| Closure _ -> failwith "Inlining/Duplicating closure is currenly not supported"
| Special x -> Special x
| Prim (p, l) ->
Expand All @@ -41,7 +41,7 @@ let instr s i =
match i with
| Let (x, e) -> Let (s x, expr s e)
| Assign (x, y) -> Assign (s x, s y)
| Set_field (x, n, y) -> Set_field (s x, n, s y)
| Set_field (x, n, typ, y) -> Set_field (s x, n, typ, s y)
| Offset_ref (x, n) -> Offset_ref (s x, n)
| Array_set (x, y, z) -> Array_set (s x, s y, s z)

Expand Down
11 changes: 6 additions & 5 deletions compiler/lib/eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ let shift l f =
| [ Int i; Int j ] -> Some (Int (f i (Int32.to_int j land 0x1f)))
| _ -> None

let float_binop_aux l f =
let float_binop_aux (l : constant list) (f : float -> float -> 'a) : 'a option =
let args =
match l with
| [ Float i; Float j ] -> Some (i, j)
Expand All @@ -54,12 +54,12 @@ let float_binop_aux l f =
| None -> None
| Some (i, j) -> Some (f i j)

let float_binop l f =
let float_binop (l : constant list) (f : float -> float -> float) : constant option =
match float_binop_aux l f with
| Some x -> Some (Float x)
| None -> None

let float_unop l f =
let float_unop (l : constant list) (f : float -> float) : constant option =
match l with
| [ Float i ] -> Some (Float (f i))
| [ Int i ] -> Some (Float (f (Int32.to_float i)))
Expand Down Expand Up @@ -433,10 +433,11 @@ let rec do_not_raise pc visited blocks =
let b = Addr.Map.find pc blocks in
List.iter b.body ~f:(fun (i, _loc) ->
match i with
| Array_set (_, _, _) | Offset_ref (_, _) | Set_field (_, _, _) | Assign _ -> ()
| Array_set (_, _, _) | Offset_ref (_, _) | Set_field (_, _, _, _) | Assign _ ->
()
| Let (_, e) -> (
match e with
| Block (_, _, _, _) | Field (_, _) | Constant _ | Closure _ -> ()
| Block (_, _, _, _) | Field (_, _, _) | Constant _ | Closure _ -> ()
| Apply _ -> raise May_raise
| Special _ -> ()
| Prim (Extern name, _) when Primitive.is_pure name -> ()
Expand Down
10 changes: 5 additions & 5 deletions compiler/lib/flow.ml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ let expr_deps blocks vars deps defs x e =
List.iter l ~f:(fun x -> add_param_def vars defs x);
cont_deps blocks vars deps defs cont
| Block (_, a, _, _) -> Array.iter a ~f:(fun y -> add_dep deps x y)
| Field (y, _) -> add_dep deps x y
| Field (y, _, _) -> add_dep deps x y

let program_deps { blocks; _ } =
let nv = Var.count () in
Expand Down Expand Up @@ -148,7 +148,7 @@ let propagate1 deps defs st x =
match e with
| Constant _ | Apply _ | Prim _ | Special _ | Closure _ | Block _ ->
Var.Set.singleton x
| Field (y, n) ->
| Field (y, n, _) ->
var_set_lift
(fun z ->
match defs.(Var.idx z) with
Expand Down Expand Up @@ -254,7 +254,7 @@ let program_escape defs known_origins { blocks; _ } =
match i with
| Let (x, e) -> expr_escape st x e
| Assign _ -> ()
| Set_field (x, _, y) | Array_set (x, _, y) ->
| Set_field (x, _, _, y) | Array_set (x, _, y) ->
Var.Set.iter
(fun y -> Var.ISet.add possibly_mutable y)
(Var.Tbl.get known_origins x);
Expand All @@ -278,7 +278,7 @@ let propagate2 ?(skip_param = false) defs known_origins possibly_mutable st x =
| Expr e -> (
match e with
| Constant _ | Closure _ | Apply _ | Prim _ | Block _ | Special _ -> false
| Field (y, n) ->
| Field (y, n, _) ->
Var.Tbl.get st y
|| Var.Set.exists
(fun z ->
Expand Down Expand Up @@ -401,7 +401,7 @@ let the_native_string_of info x =
(*XXX Maybe we could iterate? *)
let direct_approx (info : Info.t) x =
match info.info_defs.(Var.idx x) with
| Expr (Field (y, n)) ->
| Expr (Field (y, n, _)) ->
get_approx
info
(fun z ->
Expand Down
4 changes: 2 additions & 2 deletions compiler/lib/freevars.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ let iter_expr_free_vars f e =
f x;
List.iter ~f args
| Block (_, a, _, _) -> Array.iter ~f a
| Field (x, _) -> f x
| Field (x, _, _) -> f x
| Closure _ -> ()
| Special _ -> ()
| Prim (_, l) ->
Expand All @@ -46,7 +46,7 @@ let iter_expr_free_vars f e =
let iter_instr_free_vars f i =
match i with
| Let (_, e) -> iter_expr_free_vars f e
| Set_field (x, _, y) ->
| Set_field (x, _, _, y) ->
f x;
f y
| Offset_ref (x, _) -> f x
Expand Down
4 changes: 2 additions & 2 deletions compiler/lib/generate.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@ let rec translate_expr ctx queue loc x e level : _ * J.statement_list =
| NotArray | Unknown -> Mlvalue.Block.make ~tag ~args:contents
in
(x, prop, queue), []
| Field (x, n) ->
| Field (x, n, _) ->
let (px, cx), queue = access_queue queue x in
(Mlvalue.Block.field cx n, or_p px mutable_p, queue), []
| Closure (args, ((pc, _) as cont)) ->
Expand Down Expand Up @@ -1378,7 +1378,7 @@ and translate_instr ctx expr_queue instr =
expr_queue
prop
(instrs @ [ J.variable_declaration [ J.V x, (ce, loc) ], loc ]))
| Set_field (x, n, y) ->
| Set_field (x, n, _, y) ->
let loc = source_location_ctx ctx pc in
let (_px, cx), expr_queue = access_queue expr_queue x in
let (_py, cy), expr_queue = access_queue expr_queue y in
Expand Down
21 changes: 11 additions & 10 deletions compiler/lib/global_deadcode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ let definitions prog =
match i with
| Let (x, e) -> set_def x (Expr e)
| Assign (x, _) -> set_def x Param
| Set_field (_, _, _) | Offset_ref (_, _) | Array_set (_, _, _) -> ())
| Set_field (_, _, _, _) | Offset_ref (_, _) | Array_set (_, _, _) -> ())
block.body)
prog.blocks;
defs
Expand Down Expand Up @@ -128,7 +128,7 @@ let usages prog (global_info : Global_flow.info) :
~f:(fun a -> if variable_may_escape a global_info then add_use Compute x a)
args
| Block (_, vars, _, _) -> Array.iter ~f:(add_use Compute x) vars
| Field (z, _) -> add_use Compute x z
| Field (z, _, _) -> add_use Compute x z
| Constant _ -> ()
| Special _ -> ()
| Closure (_, cont) -> add_cont_deps cont
Expand All @@ -149,7 +149,7 @@ let usages prog (global_info : Global_flow.info) :
| Let (x, e) -> add_expr_uses x e
(* For assignment, propagate liveness from new to old variable like a block parameter *)
| Assign (x, y) -> add_use Propagate x y
| Set_field (_, _, _) | Offset_ref (_, _) | Array_set (_, _, _) -> ())
| Set_field (_, _, _, _) | Offset_ref (_, _) | Array_set (_, _, _) -> ())
block.body;
(* Add uses from block branch *)
match fst block.branch with
Expand All @@ -175,7 +175,7 @@ let expr_vars e =
List.fold_left ~f:(fun acc x -> Var.Set.add x acc) ~init:vars args
| Block (_, params, _, _) ->
Array.fold_left ~f:(fun acc x -> Var.Set.add x acc) ~init:vars params
| Field (z, _) -> Var.Set.add z vars
| Field (z, _, _) -> Var.Set.add z vars
| Prim (_, args) ->
List.fold_left
~f:(fun acc v ->
Expand Down Expand Up @@ -225,14 +225,14 @@ let liveness prog pure_funs (global_info : Global_flow.info) =
~f:(fun x -> if variable_may_escape x global_info then add_top x)
args
| Block (_, _, _, _)
| Field (_, _)
| Field (_, _, _)
| Closure (_, _)
| Constant _
| Prim (_, _)
| Special _ ->
let vars = expr_vars e in
Var.Set.iter add_top vars)
| Set_field (x, i, y) ->
| Set_field (x, i, _, y) ->
add_live_field x i;
add_top y
| Array_set (x, y, z) ->
Expand Down Expand Up @@ -294,12 +294,12 @@ let propagate uses defs live_vars live_table x =
if Var.equal v x && IntSet.mem i fields then found := true)
vars;
if !found then Top else Dead
| Expr (Field (_, i)) -> Live (IntSet.singleton i)
| Expr (Field (_, i, _)) -> Live (IntSet.singleton i)
| _ -> Top)
(* If y is top and y is a field access, x depends only on that field *)
| Top -> (
match Var.Tbl.get defs y with
| Expr (Field (_, i)) -> Live (IntSet.singleton i)
| Expr (Field (_, i, _)) -> Live (IntSet.singleton i)
| _ -> Top))
(* If x is used as an argument for parameter y, then contribution is liveness of y *)
| Propagate -> Var.Tbl.get live_table y
Expand Down Expand Up @@ -358,8 +358,9 @@ let zero prog sentinal live_table =
| Apply ap ->
let args = List.map ~f:zero_var ap.args in
Let (x, Apply { ap with args })
| Field (_, _) | Closure (_, _) | Constant _ | Prim (_, _) | Special _ -> instr)
| Assign (_, _) | Set_field (_, _, _) | Offset_ref (_, _) | Array_set (_, _, _) ->
| Field (_, _, _) | Closure (_, _) | Constant _ | Prim (_, _) | Special _ -> instr
)
| Assign (_, _) | Set_field (_, _, _, _) | Offset_ref (_, _) | Array_set (_, _, _) ->
instr
in
let zero_block block =
Expand Down
8 changes: 4 additions & 4 deletions compiler/lib/global_flow.ml
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ let expr_deps blocks st x e =
| Closure (l, cont) ->
List.iter l ~f:(fun x -> add_param_def st x);
cont_deps blocks st cont
| Field (y, _) -> add_dep st x y
| Field (y, _, _) -> add_dep st x y

let program_deps st { blocks; _ } =
Addr.Map.iter
Expand All @@ -242,7 +242,7 @@ let program_deps st { blocks; _ } =
add_expr_def st x e;
expr_deps blocks st x e
| Assign (x, y) -> add_assign_def st x y
| Set_field (x, _, y) | Array_set (x, _, y) ->
| Set_field (x, _, _, y) | Array_set (x, _, y) ->
possibly_mutable st x;
do_escape st Escape y
| Offset_ref _ -> ());
Expand Down Expand Up @@ -275,7 +275,7 @@ let program_deps st { blocks; _ } =
List.iter
~f:(fun (i, _) ->
match i with
| Let (y, Field (x', _)) when Var.equal b x' ->
| Let (y, Field (x', _, _)) when Var.equal b x' ->
Hashtbl.add st.known_cases y tags
| _ -> ())
block.body)
Expand Down Expand Up @@ -403,7 +403,7 @@ let propagate st ~update approx x =
(* A constant cannot contain a function *)
Domain.bot
| Closure _ | Block _ -> Domain.singleton x
| Field (y, n) -> (
| Field (y, n, _) -> (
match Var.Tbl.get approx y with
| Values { known; others } ->
let tags =
Expand Down
Loading

0 comments on commit fab177e

Please sign in to comment.