|
@@ -134,7 +134,10 @@ let rec expr_eq e1 e2 = match e1.eexpr,e2.eexpr with
|
|
| _ -> false
|
|
| _ -> false
|
|
|
|
|
|
let is_unbound v =
|
|
let is_unbound v =
|
|
- v.v_name <> "`trace" && Meta.has Meta.Unbound v.v_meta
|
|
|
|
|
|
+ Meta.has Meta.Unbound v.v_meta
|
|
|
|
+
|
|
|
|
+let is_really_unbound v =
|
|
|
|
+ v.v_name <> "`trace" && is_unbound v
|
|
|
|
|
|
let is_ref_type = function
|
|
let is_ref_type = function
|
|
| TType({t_path = ["cs"],("Ref" | "Out")},_) -> true
|
|
| TType({t_path = ["cs"],("Ref" | "Out")},_) -> true
|
|
@@ -460,7 +463,7 @@ module TexprFilter = struct
|
|
let e2 = replace e2 in
|
|
let e2 = replace e2 in
|
|
let e1 = replace e1 in
|
|
let e1 = replace e1 in
|
|
{e with eexpr = TBinop(op,e1,e2)}
|
|
{e with eexpr = TBinop(op,e1,e2)}
|
|
- | TCall({eexpr = TLocal v},_) when is_unbound v ->
|
|
|
|
|
|
+ | TCall({eexpr = TLocal v},_) when is_really_unbound v ->
|
|
e
|
|
e
|
|
| _ ->
|
|
| _ ->
|
|
Type.map_expr replace e
|
|
Type.map_expr replace e
|
|
@@ -519,7 +522,7 @@ module TexprFilter = struct
|
|
in
|
|
in
|
|
let el = fuse_loop el in
|
|
let el = fuse_loop el in
|
|
{e with eexpr = TBlock el}
|
|
{e with eexpr = TBlock el}
|
|
- | TCall({eexpr = TLocal v},_) when is_unbound v ->
|
|
|
|
|
|
+ | TCall({eexpr = TLocal v},_) when is_really_unbound v ->
|
|
e
|
|
e
|
|
| _ ->
|
|
| _ ->
|
|
Type.map_expr loop e
|
|
Type.map_expr loop e
|
|
@@ -686,7 +689,15 @@ module Graph = struct
|
|
|
|
|
|
type texpr_lookup = BasicBlock.t * bool * int
|
|
type texpr_lookup = BasicBlock.t * bool * int
|
|
type tfunc_info = BasicBlock.t * Type.t * pos * tfunc
|
|
type tfunc_info = BasicBlock.t * Type.t * pos * tfunc
|
|
- type var_write = tvar * BasicBlock.t list
|
|
|
|
|
|
+ type var_write = BasicBlock.t list
|
|
|
|
+
|
|
|
|
+ type var_info = {
|
|
|
|
+ vi_var : tvar; (* The variable itself *)
|
|
|
|
+ mutable vi_origin : tvar; (* The origin variable of this variable *)
|
|
|
|
+ mutable vi_writes : var_write; (* A list of blocks that assign to this variable *)
|
|
|
|
+ mutable vi_value : texpr_lookup option; (* The value of this variable, if known *)
|
|
|
|
+ mutable vi_ssa_edges : texpr_lookup list; (* The expressions this variable influences *)
|
|
|
|
+ }
|
|
|
|
|
|
type t = {
|
|
type t = {
|
|
mutable g_root : BasicBlock.t; (* The unique root block *)
|
|
mutable g_root : BasicBlock.t; (* The unique root block *)
|
|
@@ -695,13 +706,23 @@ module Graph = struct
|
|
mutable g_functions : tfunc_info IntMap.t; (* A map of functions, indexed by their block IDs *)
|
|
mutable g_functions : tfunc_info IntMap.t; (* A map of functions, indexed by their block IDs *)
|
|
mutable g_nodes : BasicBlock.t IntMap.t; (* A map of all blocks *)
|
|
mutable g_nodes : BasicBlock.t IntMap.t; (* A map of all blocks *)
|
|
mutable g_cfg_edges : cfg_edge list; (* A list of all CFG edges *)
|
|
mutable g_cfg_edges : cfg_edge list; (* A list of all CFG edges *)
|
|
- mutable g_var_writes : var_write IntMap.t; (* A map tracking which blocks write which variables *)
|
|
|
|
- mutable g_var_values : texpr_lookup IntMap.t; (* A map containing expression lookup information for each variable *)
|
|
|
|
- mutable g_ssa_edges : texpr_lookup list IntMap.t; (* A map containing def-use lookup information for each variable *)
|
|
|
|
- mutable g_var_origins : tvar IntMap.t; (* A map keeping track of original variables for SSA variables *)
|
|
|
|
|
|
+ mutable g_var_infos : var_info IntMap.t; (* A map of variable information *)
|
|
mutable g_loops : BasicBlock.t IntMap.t; (* A map containing loop information *)
|
|
mutable g_loops : BasicBlock.t IntMap.t; (* A map containing loop information *)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ let create_var_info g v =
|
|
|
|
+ let vi = {
|
|
|
|
+ vi_var = v;
|
|
|
|
+ vi_origin = v;
|
|
|
|
+ vi_writes = [];
|
|
|
|
+ vi_value = None;
|
|
|
|
+ vi_ssa_edges = []
|
|
|
|
+ } in
|
|
|
|
+ vi
|
|
|
|
+
|
|
|
|
+ let get_var_info g i =
|
|
|
|
+ IntMap.find i g.g_var_infos
|
|
|
|
+
|
|
(* edges *)
|
|
(* edges *)
|
|
|
|
|
|
let set_syntax_edge g bb se =
|
|
let set_syntax_edge g bb se =
|
|
@@ -714,12 +735,13 @@ module Graph = struct
|
|
if bb_from.bb_id > 0 then begin
|
|
if bb_from.bb_id > 0 then begin
|
|
let edge = { cfg_from = bb_from; cfg_to = bb_to; cfg_kind = kind; cfg_flags = [] } in
|
|
let edge = { cfg_from = bb_from; cfg_to = bb_to; cfg_kind = kind; cfg_flags = [] } in
|
|
g.g_cfg_edges <- edge :: g.g_cfg_edges;
|
|
g.g_cfg_edges <- edge :: g.g_cfg_edges;
|
|
- bb_from.bb_outgoing <- edge :: bb_from.bb_outgoing;
|
|
|
|
|
|
+ bb_from.bb_outgoing <- edge :: bb_from.bb_outgoing;
|
|
bb_to.bb_incoming <- edge :: bb_to.bb_incoming;
|
|
bb_to.bb_incoming <- edge :: bb_to.bb_incoming;
|
|
end
|
|
end
|
|
|
|
|
|
let add_ssa_edge g v bb is_phi i =
|
|
let add_ssa_edge g v bb is_phi i =
|
|
- g.g_ssa_edges <- IntMap.add v.v_id (try (bb,is_phi,i) :: IntMap.find v.v_id g.g_ssa_edges with Not_found -> [bb,is_phi,i]) g.g_ssa_edges
|
|
|
|
|
|
+ let vi = get_var_info g v.v_id in
|
|
|
|
+ vi.vi_ssa_edges <- (bb,is_phi,i) :: vi.vi_ssa_edges
|
|
|
|
|
|
(* nodes *)
|
|
(* nodes *)
|
|
|
|
|
|
@@ -763,27 +785,35 @@ module Graph = struct
|
|
|
|
|
|
(* variables *)
|
|
(* variables *)
|
|
|
|
|
|
|
|
+ let declare_var g v =
|
|
|
|
+ let vi = create_var_info g v in
|
|
|
|
+ g.g_var_infos <- IntMap.add v.v_id vi g.g_var_infos
|
|
|
|
+
|
|
let add_var_def g bb v =
|
|
let add_var_def g bb v =
|
|
if bb.bb_id > 0 then begin
|
|
if bb.bb_id > 0 then begin
|
|
bb.bb_var_writes <- v :: bb.bb_var_writes;
|
|
bb.bb_var_writes <- v :: bb.bb_var_writes;
|
|
- let l = try snd (IntMap.find v.v_id g.g_var_writes) with Not_found -> [] in
|
|
|
|
- g.g_var_writes <- IntMap.add v.v_id (v,bb :: l) g.g_var_writes;
|
|
|
|
|
|
+ let vi = get_var_info g v.v_id in
|
|
|
|
+ vi.vi_writes <- bb :: vi.vi_writes;
|
|
end
|
|
end
|
|
|
|
|
|
let set_var_value g v bb is_phi i =
|
|
let set_var_value g v bb is_phi i =
|
|
- g.g_var_values <- IntMap.add v.v_id (bb,is_phi,i) g.g_var_values
|
|
|
|
|
|
+ (get_var_info g v.v_id).vi_value <- Some (bb,is_phi,i)
|
|
|
|
|
|
let get_var_value g v =
|
|
let get_var_value g v =
|
|
- let bb,is_phi,i = IntMap.find v.v_id g.g_var_values in
|
|
|
|
|
|
+ let value = (get_var_info g v.v_id).vi_value in
|
|
|
|
+ let bb,is_phi,i = match value with
|
|
|
|
+ | None -> raise Not_found
|
|
|
|
+ | Some l -> l
|
|
|
|
+ in
|
|
match (get_texpr g bb is_phi i).eexpr with
|
|
match (get_texpr g bb is_phi i).eexpr with
|
|
| TVar(_,Some e) | TBinop(OpAssign,_,e) -> e
|
|
| TVar(_,Some e) | TBinop(OpAssign,_,e) -> e
|
|
| _ -> assert false
|
|
| _ -> assert false
|
|
|
|
|
|
let add_var_origin g v v_origin =
|
|
let add_var_origin g v v_origin =
|
|
- g.g_var_origins <- IntMap.add v.v_id v_origin g.g_var_origins
|
|
|
|
|
|
+ (get_var_info g v.v_id).vi_origin <- v_origin
|
|
|
|
|
|
let get_var_origin g v =
|
|
let get_var_origin g v =
|
|
- try IntMap.find v.v_id g.g_var_origins with Not_found -> v
|
|
|
|
|
|
+ (get_var_info g v.v_id).vi_origin
|
|
|
|
|
|
(* graph *)
|
|
(* graph *)
|
|
|
|
|
|
@@ -797,10 +827,7 @@ module Graph = struct
|
|
g_functions = IntMap.empty;
|
|
g_functions = IntMap.empty;
|
|
g_nodes = IntMap.add bb_root.bb_id bb_root IntMap.empty;
|
|
g_nodes = IntMap.add bb_root.bb_id bb_root IntMap.empty;
|
|
g_cfg_edges = [];
|
|
g_cfg_edges = [];
|
|
- g_var_writes = IntMap.empty;
|
|
|
|
- g_var_values = IntMap.empty;
|
|
|
|
- g_ssa_edges = IntMap.empty;
|
|
|
|
- g_var_origins = IntMap.empty;
|
|
|
|
|
|
+ g_var_infos = IntMap.empty;
|
|
g_loops = IntMap.empty;
|
|
g_loops = IntMap.empty;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -852,6 +879,7 @@ module TexprTransformer = struct
|
|
|
|
|
|
let rec func ctx bb tf t p =
|
|
let rec func ctx bb tf t p =
|
|
let g = ctx.graph in
|
|
let g = ctx.graph in
|
|
|
|
+ List.iter (fun (v,_) -> declare_var g v) tf.tf_args;
|
|
let create_node kind bb t p =
|
|
let create_node kind bb t p =
|
|
let bb = Graph.create_node g kind ctx.scopes bb t p in
|
|
let bb = Graph.create_node g kind ctx.scopes bb t p in
|
|
bb.bb_loop_groups <- ctx.loop_stack;
|
|
bb.bb_loop_groups <- ctx.loop_stack;
|
|
@@ -919,7 +947,7 @@ module TexprTransformer = struct
|
|
bind_to_temp bb false e
|
|
bind_to_temp bb false e
|
|
| TFor _ | TWhile _ ->
|
|
| TFor _ | TWhile _ ->
|
|
assert false
|
|
assert false
|
|
- | TCall({eexpr = TLocal v},el) when is_unbound v ->
|
|
|
|
|
|
+ | TCall({eexpr = TLocal v},el) when is_really_unbound v ->
|
|
check_unbound_call v el;
|
|
check_unbound_call v el;
|
|
bb,e
|
|
bb,e
|
|
| TCall(e1,el) ->
|
|
| TCall(e1,el) ->
|
|
@@ -1006,6 +1034,7 @@ module TexprTransformer = struct
|
|
bb,List.rev values
|
|
bb,List.rev values
|
|
and bind_to_temp bb sequential e =
|
|
and bind_to_temp bb sequential e =
|
|
let v = alloc_var "tmp" e.etype in
|
|
let v = alloc_var "tmp" e.etype in
|
|
|
|
+ declare_var g v;
|
|
begin match ctx.com.platform with
|
|
begin match ctx.com.platform with
|
|
| Cpp when sequential && not (Common.defined ctx.com Define.Cppia) -> ()
|
|
| Cpp when sequential && not (Common.defined ctx.com Define.Cppia) -> ()
|
|
| _ -> v.v_meta <- [Meta.CompilerGenerated,[],e.epos];
|
|
| _ -> v.v_meta <- [Meta.CompilerGenerated,[],e.epos];
|
|
@@ -1065,10 +1094,12 @@ module TexprTransformer = struct
|
|
(* variables *)
|
|
(* variables *)
|
|
| TVar(v,None) ->
|
|
| TVar(v,None) ->
|
|
save_v_extra ctx v;
|
|
save_v_extra ctx v;
|
|
|
|
+ declare_var g v;
|
|
add_texpr g bb e;
|
|
add_texpr g bb e;
|
|
bb
|
|
bb
|
|
| TVar(v,Some e1) ->
|
|
| TVar(v,Some e1) ->
|
|
save_v_extra ctx v;
|
|
save_v_extra ctx v;
|
|
|
|
+ declare_var g v;
|
|
declare_var_and_assign bb v e1
|
|
declare_var_and_assign bb v e1
|
|
| TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) ->
|
|
| TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) ->
|
|
let assign e =
|
|
let assign e =
|
|
@@ -1224,6 +1255,7 @@ module TexprTransformer = struct
|
|
set_syntax_edge g bb (SESubBlock(bb_try,bb_next))
|
|
set_syntax_edge g bb (SESubBlock(bb_try,bb_next))
|
|
else begin
|
|
else begin
|
|
let catches = List.map (fun (v,e) ->
|
|
let catches = List.map (fun (v,e) ->
|
|
|
|
+ declare_var ctx.graph v;
|
|
let scope = increase_scope() in
|
|
let scope = increase_scope() in
|
|
let bb_catch = create_node BKNormal bb_exc e.etype e.epos in
|
|
let bb_catch = create_node BKNormal bb_exc e.etype e.epos in
|
|
add_cfg_edge g bb_exc bb_catch CFGGoto;
|
|
add_cfg_edge g bb_exc bb_catch CFGGoto;
|
|
@@ -1273,7 +1305,7 @@ module TexprTransformer = struct
|
|
add_terminator bb {e with eexpr = TThrow e1};
|
|
add_terminator bb {e with eexpr = TThrow e1};
|
|
end
|
|
end
|
|
(* side_effects *)
|
|
(* side_effects *)
|
|
- | TCall({eexpr = TLocal v},el) when is_unbound v ->
|
|
|
|
|
|
+ | TCall({eexpr = TLocal v},el) when is_really_unbound v ->
|
|
check_unbound_call v el;
|
|
check_unbound_call v el;
|
|
add_texpr g bb e;
|
|
add_texpr g bb e;
|
|
bb
|
|
bb
|
|
@@ -1437,9 +1469,9 @@ module TexprTransformer = struct
|
|
assert(bb.bb_closed);
|
|
assert(bb.bb_closed);
|
|
let el = block_to_texpr_el ctx bb in
|
|
let el = block_to_texpr_el ctx bb in
|
|
let rec loop e = match e.eexpr with
|
|
let rec loop e = match e.eexpr with
|
|
- | TLocal v ->
|
|
|
|
|
|
+ | TLocal v when not (is_unbound v) ->
|
|
{e with eexpr = TLocal (get_var_origin ctx.graph v)}
|
|
{e with eexpr = TLocal (get_var_origin ctx.graph v)}
|
|
- | TVar(v,eo) ->
|
|
|
|
|
|
+ | TVar(v,eo) when not (is_unbound v) ->
|
|
let eo = Option.map loop eo in
|
|
let eo = Option.map loop eo in
|
|
let v' = get_var_origin ctx.graph v in
|
|
let v' = get_var_origin ctx.graph v in
|
|
restore_v_extra ctx v';
|
|
restore_v_extra ctx v';
|
|
@@ -1507,9 +1539,10 @@ module Ssa = struct
|
|
DynArray.add bb.bb_phi e
|
|
DynArray.add bb.bb_phi e
|
|
|
|
|
|
let insert_phi ctx =
|
|
let insert_phi ctx =
|
|
- IntMap.iter (fun i (v,bbl) ->
|
|
|
|
|
|
+ IntMap.iter (fun i vi ->
|
|
|
|
+ let v = vi.vi_var in
|
|
let done_list = ref IntMap.empty in
|
|
let done_list = ref IntMap.empty in
|
|
- let w = ref bbl in
|
|
|
|
|
|
+ let w = ref vi.vi_writes in
|
|
while !w <> [] do
|
|
while !w <> [] do
|
|
let x = List.hd !w in
|
|
let x = List.hd !w in
|
|
w := List.tl !w;
|
|
w := List.tl !w;
|
|
@@ -1517,12 +1550,12 @@ module Ssa = struct
|
|
if not (IntMap.mem y.bb_id !done_list) then begin
|
|
if not (IntMap.mem y.bb_id !done_list) then begin
|
|
add_phi ctx.graph y v;
|
|
add_phi ctx.graph y v;
|
|
done_list := IntMap.add y.bb_id true !done_list;
|
|
done_list := IntMap.add y.bb_id true !done_list;
|
|
- if not (List.memq y bbl) then
|
|
|
|
|
|
+ if not (List.memq y vi.vi_writes) then
|
|
w := y :: !w
|
|
w := y :: !w
|
|
end
|
|
end
|
|
) x.bb_df;
|
|
) x.bb_df;
|
|
done
|
|
done
|
|
- ) ctx.graph.g_var_writes
|
|
|
|
|
|
+ ) ctx.graph.g_var_infos
|
|
|
|
|
|
let set_reaching_def v vo =
|
|
let set_reaching_def v vo =
|
|
let eo = match vo with
|
|
let eo = match vo with
|
|
@@ -1542,7 +1575,7 @@ module Ssa = struct
|
|
bb_dom == bb || bb.bb_dominator == bb_dom || (bb.bb_dominator != bb && dominates bb_dom bb.bb_dominator)
|
|
bb_dom == bb || bb.bb_dominator == bb_dom || (bb.bb_dominator != bb && dominates bb_dom bb.bb_dominator)
|
|
|
|
|
|
let dominates ctx r bb =
|
|
let dominates ctx r bb =
|
|
- let _,l = IntMap.find r.v_id ctx.graph.g_var_writes in
|
|
|
|
|
|
+ let l = (get_var_info ctx.graph r.v_id).vi_writes in
|
|
List.exists (fun bb' -> dominates bb' bb) l
|
|
List.exists (fun bb' -> dominates bb' bb) l
|
|
|
|
|
|
let update_reaching_def ctx v bb =
|
|
let update_reaching_def ctx v bb =
|
|
@@ -1593,6 +1626,7 @@ module Ssa = struct
|
|
let write_var v is_phi i =
|
|
let write_var v is_phi i =
|
|
update_reaching_def ctx v bb;
|
|
update_reaching_def ctx v bb;
|
|
let v' = alloc_var (v.v_name) v.v_type in
|
|
let v' = alloc_var (v.v_name) v.v_type in
|
|
|
|
+ declare_var ctx.graph v';
|
|
v'.v_meta <- v.v_meta;
|
|
v'.v_meta <- v.v_meta;
|
|
v'.v_capture <- v.v_capture;
|
|
v'.v_capture <- v.v_capture;
|
|
add_var_def ctx.graph bb v';
|
|
add_var_def ctx.graph bb v';
|
|
@@ -1603,15 +1637,15 @@ module Ssa = struct
|
|
v'
|
|
v'
|
|
in
|
|
in
|
|
let rec loop is_phi i e = match e.eexpr with
|
|
let rec loop is_phi i e = match e.eexpr with
|
|
- | TLocal v ->
|
|
|
|
|
|
+ | TLocal v when not (is_unbound v) ->
|
|
let v' = local ctx e v bb in
|
|
let v' = local ctx e v bb in
|
|
add_ssa_edge ctx.graph v' bb is_phi i;
|
|
add_ssa_edge ctx.graph v' bb is_phi i;
|
|
{e with eexpr = TLocal v'}
|
|
{e with eexpr = TLocal v'}
|
|
- | TVar(v,Some e1) ->
|
|
|
|
|
|
+ | TVar(v,Some e1) when not (is_unbound v) ->
|
|
let e1 = (loop is_phi i) e1 in
|
|
let e1 = (loop is_phi i) e1 in
|
|
let v' = write_var v is_phi i in
|
|
let v' = write_var v is_phi i in
|
|
{e with eexpr = TVar(v',Some e1)}
|
|
{e with eexpr = TVar(v',Some e1)}
|
|
- | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) ->
|
|
|
|
|
|
+ | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) when not (is_unbound v) ->
|
|
let e2 = (loop is_phi i) e2 in
|
|
let e2 = (loop is_phi i) e2 in
|
|
let v' = write_var v is_phi i in
|
|
let v' = write_var v is_phi i in
|
|
{e with eexpr = TBinop(OpAssign,{e1 with eexpr = TLocal v'},e2)};
|
|
{e with eexpr = TBinop(OpAssign,{e1 with eexpr = TLocal v'},e2)};
|
|
@@ -1664,7 +1698,7 @@ module DataFlow (M : DataFlowApi) = struct
|
|
open BasicBlock
|
|
open BasicBlock
|
|
|
|
|
|
let get_ssa_edges_from g v =
|
|
let get_ssa_edges_from g v =
|
|
- try IntMap.find v.v_id g.g_ssa_edges with Not_found -> []
|
|
|
|
|
|
+ (get_var_info g v.v_id).vi_ssa_edges
|
|
|
|
|
|
let run ctx =
|
|
let run ctx =
|
|
let g = ctx.graph in
|
|
let g = ctx.graph in
|
|
@@ -1997,7 +2031,7 @@ module CopyPropagation = DataFlow(struct
|
|
(* This restriction is in place due to how we currently reconstruct the AST. Multiple SSA-vars may be turned back to
|
|
(* This restriction is in place due to how we currently reconstruct the AST. Multiple SSA-vars may be turned back to
|
|
the same origin var, which creates interference that is not tracked in the analysis. We address this by only
|
|
the same origin var, which creates interference that is not tracked in the analysis. We address this by only
|
|
considering variables whose origin-variables are assigned to at most once. *)
|
|
considering variables whose origin-variables are assigned to at most once. *)
|
|
- let writes = try snd (IntMap.find v''.v_id ctx.graph.g_var_writes) with Not_found -> [] in
|
|
|
|
|
|
+ let writes = (get_var_info ctx.graph v''.v_id).vi_writes in
|
|
begin match writes with
|
|
begin match writes with
|
|
| [_] -> ()
|
|
| [_] -> ()
|
|
| _ -> leave()
|
|
| _ -> leave()
|
|
@@ -2058,7 +2092,7 @@ module CodeMotion = DataFlow(struct
|
|
| TConst ct ->
|
|
| TConst ct ->
|
|
Const ct
|
|
Const ct
|
|
| TLocal v ->
|
|
| TLocal v ->
|
|
- let bb_def = match IntMap.find v.v_id ctx.graph.g_var_writes with _,[bb] -> bb | _ -> raise Exit in
|
|
|
|
|
|
+ let bb_def = match (get_var_info ctx.graph v.v_id).vi_writes with [bb] -> bb | _ -> raise Exit in
|
|
Local(v,bb_def)
|
|
Local(v,bb_def)
|
|
| TBinop(op,e1,e2) ->
|
|
| TBinop(op,e1,e2) ->
|
|
let lat1 = transfer ctx bb e1 in
|
|
let lat1 = transfer ctx bb e1 in
|
|
@@ -2124,6 +2158,7 @@ module CodeMotion = DataFlow(struct
|
|
v
|
|
v
|
|
end else begin
|
|
end else begin
|
|
let v' = alloc_var "tmp" v.v_type in
|
|
let v' = alloc_var "tmp" v.v_type in
|
|
|
|
+ declare_var ctx.graph v';
|
|
v'.v_meta <- [Meta.CompilerGenerated,[],p];
|
|
v'.v_meta <- [Meta.CompilerGenerated,[],p];
|
|
v'
|
|
v'
|
|
end in
|
|
end in
|
|
@@ -2221,9 +2256,9 @@ module LocalDce = struct
|
|
end
|
|
end
|
|
end
|
|
end
|
|
and expr e = match e.eexpr with
|
|
and expr e = match e.eexpr with
|
|
- | TLocal v ->
|
|
|
|
|
|
+ | TLocal v when not (is_unbound v) ->
|
|
use v;
|
|
use v;
|
|
- | TBinop(OpAssign,{eexpr = TLocal v},e1) | TVar(v,Some e1) ->
|
|
|
|
|
|
+ | TBinop(OpAssign,{eexpr = TLocal v},e1) | TVar(v,Some e1) when not (is_unbound v) ->
|
|
if has_side_effect e1 || keep v then expr e1
|
|
if has_side_effect e1 || keep v then expr e1
|
|
else ()
|
|
else ()
|
|
| _ ->
|
|
| _ ->
|
|
@@ -2393,18 +2428,18 @@ module Debug = struct
|
|
nodes := PMap.add n true !nodes;
|
|
nodes := PMap.add n true !nodes;
|
|
n
|
|
n
|
|
in
|
|
in
|
|
- IntMap.iter (fun i l ->
|
|
|
|
|
|
+ IntMap.iter (fun i vi ->
|
|
begin try
|
|
begin try
|
|
- let (bb,is_phi,i) = IntMap.find i g.g_var_values in
|
|
|
|
|
|
+ let (bb,is_phi,i) = match vi.vi_value with None -> raise Not_found | Some i -> i in
|
|
let n1 = node_name2 bb is_phi i in
|
|
let n1 = node_name2 bb is_phi i in
|
|
List.iter (fun (bb',is_phi',i') ->
|
|
List.iter (fun (bb',is_phi',i') ->
|
|
let n2 = node_name2 bb' is_phi' i' in
|
|
let n2 = node_name2 bb' is_phi' i' in
|
|
Printf.fprintf ch "%s -> %s;\n" n1 n2
|
|
Printf.fprintf ch "%s -> %s;\n" n1 n2
|
|
- ) l
|
|
|
|
|
|
+ ) vi.vi_ssa_edges
|
|
with Not_found ->
|
|
with Not_found ->
|
|
()
|
|
()
|
|
end
|
|
end
|
|
- ) g.g_ssa_edges;
|
|
|
|
|
|
+ ) g.g_var_infos;
|
|
IntMap.iter (fun _ bb ->
|
|
IntMap.iter (fun _ bb ->
|
|
let f is_phi acc i e =
|
|
let f is_phi acc i e =
|
|
let n = node_name bb is_phi i in
|
|
let n = node_name bb is_phi i in
|