2
0
Эх сурвалжийг харах

use DynArray instead of IntMap for var infos

Simon Krajewski 9 жил өмнө
parent
commit
8e8eedfc88
2 өөрчлөгдсөн 33 нэмэгдсэн , 32 устгасан
  1. 30 31
      analyzer.ml
  2. 3 1
      type.ml

+ 30 - 31
analyzer.ml

@@ -693,6 +693,7 @@ module Graph = struct
 
 
 	type var_info = {
 	type var_info = {
 		vi_var : tvar;                            (* The variable itself *)
 		vi_var : tvar;                            (* The variable itself *)
+		vi_extra : tvar_extra;                    (* The original v_extra *)
 		mutable vi_origin : tvar;                 (* The origin variable of this variable *)
 		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_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_value : texpr_lookup option;   (* The value of this variable, if known *)
@@ -707,23 +708,27 @@ 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_infos : var_info IntMap.t;          (* A map of variable information *)
+		mutable g_var_infos : var_info DynArray.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 create_var_info g v =
 		let vi = {
 		let vi = {
 			vi_var = v;
 			vi_var = v;
+			vi_extra = v.v_extra;
 			vi_origin = v;
 			vi_origin = v;
 			vi_writes = [];
 			vi_writes = [];
 			vi_value = None;
 			vi_value = None;
 			vi_ssa_edges = [];
 			vi_ssa_edges = [];
 			vi_reaching_def = None;
 			vi_reaching_def = None;
 		} in
 		} in
-		vi
+		DynArray.add g.g_var_infos vi;
+		let i = DynArray.length g.g_var_infos - 1 in
+		v.v_extra <- Some([],Some (mk (TConst (TInt (Int32.of_int i))) t_dynamic null_pos))
 
 
-	let get_var_info g i =
-		IntMap.find i g.g_var_infos
+	let get_var_info g v = match v.v_extra with
+		| Some(_,Some {eexpr = TConst (TInt i32)}) -> DynArray.get g.g_var_infos (Int32.to_int i32)
+		| _ -> assert false
 
 
 	(* edges *)
 	(* edges *)
 
 
@@ -742,7 +747,7 @@ module Graph = struct
 		end
 		end
 
 
 	let add_ssa_edge g v bb is_phi i =
 	let add_ssa_edge g v bb is_phi i =
-		let vi = get_var_info g v.v_id in
+		let vi = get_var_info g v in
 		vi.vi_ssa_edges <- (bb,is_phi,i) :: vi.vi_ssa_edges
 		vi.vi_ssa_edges <- (bb,is_phi,i) :: vi.vi_ssa_edges
 
 
 	(* nodes *)
 	(* nodes *)
@@ -788,21 +793,20 @@ module Graph = struct
 	(* variables *)
 	(* variables *)
 
 
 	let declare_var g v =
 	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
+		create_var_info g v
 
 
 	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 vi = get_var_info g v.v_id in
+			let vi = get_var_info g v in
 			vi.vi_writes <- bb :: vi.vi_writes;
 			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 =
-		(get_var_info g v.v_id).vi_value <- Some (bb,is_phi,i)
+		(get_var_info g v).vi_value <- Some (bb,is_phi,i)
 
 
 	let get_var_value g v =
 	let get_var_value g v =
-		let value = (get_var_info g v.v_id).vi_value in
+		let value = (get_var_info g v).vi_value in
 		let bb,is_phi,i = match value with
 		let bb,is_phi,i = match value with
 			| None -> raise Not_found
 			| None -> raise Not_found
 			| Some l -> l
 			| Some l -> l
@@ -812,10 +816,10 @@ module Graph = struct
 		| _ -> assert false
 		| _ -> assert false
 
 
 	let add_var_origin g v v_origin =
 	let add_var_origin g v v_origin =
-		(get_var_info g v.v_id).vi_origin <- v_origin
+		(get_var_info g v).vi_origin <- v_origin
 
 
 	let get_var_origin g v =
 	let get_var_origin g v =
-		(get_var_info g v.v_id).vi_origin
+		(get_var_info g v).vi_origin
 
 
 	(* graph *)
 	(* graph *)
 
 
@@ -829,7 +833,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_infos = IntMap.empty;
+			g_var_infos = DynArray.create();
 			g_loops = IntMap.empty;
 			g_loops = IntMap.empty;
 		}
 		}
 
 
@@ -872,13 +876,6 @@ module TexprTransformer = struct
 	open BasicBlock
 	open BasicBlock
 	open Graph
 	open Graph
 
 
-	let save_v_extra ctx v =
-		if not (IntMap.mem v.v_id ctx.saved_v_extra) then
-			ctx.saved_v_extra <- IntMap.add v.v_id v.v_extra ctx.saved_v_extra
-
-	let restore_v_extra ctx v =
-		try v.v_extra <- IntMap.find v.v_id ctx.saved_v_extra with Not_found -> ()
-
 	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;
 		List.iter (fun (v,_) -> declare_var g v) tf.tf_args;
@@ -1095,12 +1092,10 @@ module TexprTransformer = struct
 		and block_element bb e = match e.eexpr with
 		and block_element bb e = match e.eexpr with
 			(* variables *)
 			(* variables *)
 			| TVar(v,None) ->
 			| TVar(v,None) ->
-				save_v_extra ctx v;
 				declare_var g 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;
 				declare_var g 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) ->
@@ -1476,7 +1471,7 @@ module TexprTransformer = struct
 			| TVar(v,eo) when not (is_unbound v) ->
 			| 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'; *)
 				{e with eexpr = TVar(v',eo)}
 				{e with eexpr = TVar(v',eo)}
 			| TBinop(OpAssign,e1,({eexpr = TBinop(op,e2,e3)} as e4)) ->
 			| TBinop(OpAssign,e1,({eexpr = TBinop(op,e2,e3)} as e4)) ->
 				let e1 = loop e1 in
 				let e1 = loop e1 in
@@ -1543,7 +1538,7 @@ 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 vi ->
+		DynArray.iter (fun vi ->
 			let v = vi.vi_var in
 			let v = vi.vi_var in
 			let done_list = ref IntMap.empty in
 			let done_list = ref IntMap.empty in
 			let w = ref vi.vi_writes in
 			let w = ref vi.vi_writes in
@@ -1562,17 +1557,17 @@ module Ssa = struct
 		) ctx.graph.g_var_infos
 		) ctx.graph.g_var_infos
 
 
 	let set_reaching_def g v vo =
 	let set_reaching_def g v vo =
-		let vi = get_var_info g v.v_id in
+		let vi = get_var_info g v in
 		vi.vi_reaching_def <- vo
 		vi.vi_reaching_def <- vo
 
 
 	let get_reaching_def g v =
 	let get_reaching_def g v =
-		(get_var_info g v.v_id).vi_reaching_def
+		(get_var_info g v).vi_reaching_def
 
 
 	let rec dominates bb_dom bb =
 	let rec dominates bb_dom bb =
 		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 = (get_var_info ctx.graph r.v_id).vi_writes in
+		let l = (get_var_info ctx.graph r).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 =
@@ -1695,7 +1690,7 @@ module DataFlow (M : DataFlowApi) = struct
 	open BasicBlock
 	open BasicBlock
 
 
 	let get_ssa_edges_from g v =
 	let get_ssa_edges_from g v =
-		(get_var_info g v.v_id).vi_ssa_edges
+		(get_var_info g v).vi_ssa_edges
 
 
 	let run ctx =
 	let run ctx =
 		let g = ctx.graph in
 		let g = ctx.graph in
@@ -2028,7 +2023,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 = (get_var_info ctx.graph v''.v_id).vi_writes in
+					let writes = (get_var_info ctx.graph v'').vi_writes in
 					begin match writes with
 					begin match writes with
 						| [_] -> ()
 						| [_] -> ()
 						| _ -> leave()
 						| _ -> leave()
@@ -2089,7 +2084,7 @@ module CodeMotion = DataFlow(struct
 			| TConst ct ->
 			| TConst ct ->
 				Const ct
 				Const ct
 			| TLocal v ->
 			| TLocal v ->
-				let bb_def = match (get_var_info ctx.graph v.v_id).vi_writes with [bb] -> bb | _ -> raise Exit in
+				let bb_def = match (get_var_info ctx.graph v).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
@@ -2425,7 +2420,7 @@ module Debug = struct
 			nodes := PMap.add n true !nodes;
 			nodes := PMap.add n true !nodes;
 			n
 			n
 		in
 		in
-		IntMap.iter (fun i vi ->
+		DynArray.iter (fun vi ->
 			begin try
 			begin try
 				let (bb,is_phi,i) = match vi.vi_value with None -> raise Not_found | Some i -> i 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
@@ -2463,6 +2458,7 @@ end
 
 
 module Run = struct
 module Run = struct
 	open Config
 	open Config
+	open Graph
 
 
 	let with_timer s f =
 	let with_timer s f =
 		let timer = timer s in
 		let timer = timer s in
@@ -2478,6 +2474,9 @@ module Run = struct
 	let back_again ctx =
 	let back_again ctx =
 		let e = with_timer "analyzer-to-texpr" (fun () -> TexprTransformer.to_texpr ctx) in
 		let e = with_timer "analyzer-to-texpr" (fun () -> TexprTransformer.to_texpr ctx) in
 		let e = with_timer "analyzer-filter-unapply" (fun () -> TexprFilter.unapply ctx.com ctx.config e) in
 		let e = with_timer "analyzer-filter-unapply" (fun () -> TexprFilter.unapply ctx.com ctx.config e) in
+		DynArray.iter (fun vi ->
+			vi.vi_var.v_extra <- vi.vi_extra;
+		) ctx.graph.g_var_infos;
 		e
 		e
 
 
 	let roundtrip com config e =
 	let roundtrip com config e =

+ 3 - 1
type.ml

@@ -69,12 +69,14 @@ and tconstant =
 	| TThis
 	| TThis
 	| TSuper
 	| TSuper
 
 
+and tvar_extra = (type_params * texpr option) option
+
 and tvar = {
 and tvar = {
 	mutable v_id : int;
 	mutable v_id : int;
 	mutable v_name : string;
 	mutable v_name : string;
 	mutable v_type : t;
 	mutable v_type : t;
 	mutable v_capture : bool;
 	mutable v_capture : bool;
-	mutable v_extra : (type_params * texpr option) option;
+	mutable v_extra : tvar_extra;
 	mutable v_meta : metadata;
 	mutable v_meta : metadata;
 }
 }