浏览代码

[analyzer] remove explicit dominators when creating blocks

Simon Krajewski 9 年之前
父节点
当前提交
0ce5d6c4ed
共有 1 个文件被更改,包括 34 次插入51 次删除
  1. 34 51
      src/optimization/analyzer.ml

+ 34 - 51
src/optimization/analyzer.ml

@@ -834,10 +834,8 @@ module Graph = struct
 			!r
 		)
 
-	let create_node g kind scopes bb_dom t p =
+	let create_node g kind scopes t p =
 		let bb = BasicBlock._create (alloc_id()) kind scopes t p in
-		bb.bb_dominator <- bb_dom;
-		bb_dom.bb_dominated <- bb :: bb_dom.bb_dominated;
 		Hashtbl.add g.g_nodes bb.bb_id bb;
 		bb
 
@@ -1077,13 +1075,13 @@ module TexprTransformer = struct
 
 	let rec func ctx bb tf t p =
 		let g = ctx.graph in
-		let create_node kind bb t p =
-			let bb = Graph.create_node g kind ctx.scopes bb t p in
+		let create_node kind t p =
+			let bb = Graph.create_node g kind ctx.scopes t p in
 			bb.bb_loop_groups <- ctx.loop_stack;
 			bb
 		in
-		let bb_root = create_node BKFunctionBegin bb tf.tf_expr.etype tf.tf_expr.epos in
-		let bb_exit = create_node BKFunctionEnd bb_root tf.tf_expr.etype tf.tf_expr.epos in
+		let bb_root = create_node BKFunctionBegin tf.tf_expr.etype tf.tf_expr.epos in
+		let bb_exit = create_node BKFunctionEnd tf.tf_expr.etype tf.tf_expr.epos in
 		List.iter (fun (v,_) ->
 			declare_var g v bb_root;
 			add_var_def g bb_root v
@@ -1200,7 +1198,7 @@ module TexprTransformer = struct
 				let e_fun = mk (TConst (TString "fun")) t_dynamic p in
 				let econst = mk (TConst (TInt (Int32.of_int bb_func.bb_id))) ctx.com.basic.tint e.epos in
 				let ec = mk (TCall(e_fun,[econst])) t_dynamic p in
-				let bb_next = create_node BKNormal bb bb.bb_type bb.bb_pos in
+				let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in
 				add_cfg_edge g bb bb_next CFGGoto;
 				set_syntax_edge g bb (SEMerge bb_next);
 				close_node g bb;
@@ -1353,13 +1351,13 @@ module TexprTransformer = struct
 				block_el bb el
 			| TBlock el ->
 				let scope = increase_scope() in
-				let bb_sub = create_node BKSub bb e.etype e.epos in
+				let bb_sub = create_node BKSub e.etype e.epos in
 				add_cfg_edge g bb bb_sub CFGGoto;
 				close_node g bb;
 				let bb_sub_next = block_el bb_sub el in
 				scope();
 				if bb_sub_next != g.g_unreachable then begin
-					let bb_next = create_node BKNormal bb_sub_next bb.bb_type bb.bb_pos in
+					let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in
 					set_syntax_edge g bb (SESubBlock(bb_sub,bb_next));
 					add_cfg_edge g bb_sub_next bb_next CFGGoto;
 					close_node g bb_sub_next;
@@ -1372,12 +1370,12 @@ module TexprTransformer = struct
 			| TIf(e1,e2,None) ->
 				let bb,e1 = bind_to_temp bb false e1 in
 				let scope = increase_scope() in
-				let bb_then = create_node BKConditional bb e2.etype e2.epos in
+				let bb_then = create_node BKConditional e2.etype e2.epos in
 				add_texpr g bb (wrap_meta ":cond-branch" e1);
 				add_cfg_edge g bb bb_then (CFGCondBranch (mk (TConst (TBool true)) ctx.com.basic.tbool e2.epos));
 				let bb_then_next = block bb_then e2 in
 				scope();
-				let bb_next = create_node BKNormal bb bb.bb_type bb.bb_pos in
+				let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in
 				set_syntax_edge g bb (SEIfThen(bb_then,bb_next));
 				add_cfg_edge g bb bb_next CFGCondElse;
 				close_node g bb;
@@ -1387,8 +1385,8 @@ module TexprTransformer = struct
 			| TIf(e1,e2,Some e3) ->
 				let bb,e1 = bind_to_temp bb false e1 in
 				let scope = increase_scope() in
-				let bb_then = create_node BKConditional bb e2.etype e2.epos in
-				let bb_else = create_node BKConditional bb e3.etype e3.epos in
+				let bb_then = create_node BKConditional e2.etype e2.epos in
+				let bb_else = create_node BKConditional e3.etype e3.epos in
 				add_texpr g bb (wrap_meta ":cond-branch" e1);
 				add_cfg_edge g bb bb_then (CFGCondBranch (mk (TConst (TBool true)) ctx.com.basic.tbool e2.epos));
 				add_cfg_edge g bb bb_else CFGCondElse;
@@ -1396,25 +1394,17 @@ module TexprTransformer = struct
 				let bb_then_next = block bb_then e2 in
 				let bb_else_next = block bb_else e3 in
 				scope();
-				let dead_then = bb_then_next == g.g_unreachable in
-				let dead_else = bb_else_next == g.g_unreachable in
-				begin try
-					let dom = match dead_then,dead_else with
-						| false,false -> bb
-						| true,true -> raise Exit
-						| true,false -> bb_else_next
-						| false,true -> bb_then_next
-					in
-					let bb_next = create_node BKNormal dom bb.bb_type bb.bb_pos in
+				if bb_then_next == g.g_unreachable && bb_else_next == g.g_unreachable then begin
+					set_syntax_edge g bb (SEIfThenElse(bb_then,bb_else,g.g_unreachable,e.etype));
+					g.g_unreachable
+				end else begin
+					let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in
 					set_syntax_edge g bb (SEIfThenElse(bb_then,bb_else,bb_next,e.etype));
 					add_cfg_edge g bb_then_next bb_next CFGGoto;
 					add_cfg_edge g bb_else_next bb_next CFGGoto;
 					close_node g bb_then_next;
 					close_node g bb_else_next;
 					bb_next
-				with Exit ->
-					set_syntax_edge g bb (SEIfThenElse(bb_then,bb_else,g.g_unreachable,e.etype));
-					g.g_unreachable
 				end
 			| TSwitch(e1,cases,edef) ->
 				let is_exhaustive = edef <> None || Optimizer.is_exhaustive e1 in
@@ -1423,7 +1413,7 @@ module TexprTransformer = struct
 				let reachable = ref [] in
 				let make_case e =
 					let scope = increase_scope() in
-					let bb_case = create_node BKConditional bb e.etype e.epos in
+					let bb_case = create_node BKConditional e.etype e.epos in
 					let bb_case_next = block bb_case e in
 					scope();
 					if bb_case_next != g.g_unreachable then
@@ -1444,35 +1434,28 @@ module TexprTransformer = struct
 						add_cfg_edge g bb bb_case (CFGCondElse);
 						Some (bb_case)
 				in
-				begin try
-					let dom = if not is_exhaustive then begin
-						bb
-					end else match !reachable with
-						| [] -> raise Exit
-						| [bb_case] -> bb_case
-						| _ -> bb
-					in
-					let bb_next = create_node BKNormal dom bb.bb_type bb.bb_pos in
+				if is_exhaustive && !reachable = [] then begin
+					set_syntax_edge g bb (SESwitch(cases,def,g.g_unreachable));
+					close_node g bb;
+					g.g_unreachable;
+				end else begin
+					let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in
 					if not is_exhaustive then add_cfg_edge g bb bb_next CFGGoto;
 					List.iter (fun bb -> add_cfg_edge g bb bb_next CFGGoto) !reachable;
 					set_syntax_edge g bb (SESwitch(cases,def,bb_next));
 					close_node g bb;
 					bb_next
-				with Exit ->
-					set_syntax_edge g bb (SESwitch(cases,def,g.g_unreachable));
-					close_node g bb;
-					g.g_unreachable;
 				end
 			| TWhile(e1,e2,NormalWhile) ->
-				let bb_loop_pre = create_node BKNormal bb e1.etype e1.epos in
+				let bb_loop_pre = create_node BKNormal e1.etype e1.epos in
 				add_cfg_edge g bb bb_loop_pre CFGGoto;
 				set_syntax_edge g bb (SEMerge bb_loop_pre);
 				close_node g bb;
-				let bb_loop_head = create_node BKLoopHead bb_loop_pre e1.etype e1.epos in
+				let bb_loop_head = create_node BKLoopHead e1.etype e1.epos in
 				add_cfg_edge g bb_loop_pre bb_loop_head CFGGoto;
 				let scope = increase_scope() in
 				let close = begin_loop bb bb_loop_head in
-				let bb_loop_body = create_node BKNormal bb_loop_head e2.etype e2.epos in
+				let bb_loop_body = create_node BKNormal e2.etype e2.epos in
 				let bb_loop_body_next = block bb_loop_body e2 in
 				let bb_breaks = close() in
 				scope();
@@ -1483,7 +1466,7 @@ module TexprTransformer = struct
 					| [bb_break] -> bb_break
 					| _ -> bb_loop_body (* TODO: this is not accurate for while(true) loops *)
 				in
-				let bb_next = if dom == g.g_unreachable then g.g_unreachable else create_node BKNormal dom bb.bb_type bb.bb_pos in
+				let bb_next = if dom == g.g_unreachable then g.g_unreachable else create_node BKNormal bb.bb_type bb.bb_pos in
 				List.iter (fun bb -> add_cfg_edge g bb bb_next CFGGoto) bb_breaks;
 				set_syntax_edge g bb_loop_pre (SEWhile(bb_loop_body,bb_next));
 				close_node g bb_loop_pre;
@@ -1495,8 +1478,8 @@ module TexprTransformer = struct
 				bb_next;
 			| TTry(e1,catches) ->
 				let scope = increase_scope() in
-				let bb_try = create_node BKNormal bb e1.etype e1.epos in
-				let bb_exc = create_node BKException bb_try t_dynamic e.epos in
+				let bb_try = create_node BKNormal e1.etype e1.epos in
+				let bb_exc = create_node BKException t_dynamic e.epos in
 				add_cfg_edge g bb bb_try CFGGoto;
 				let close = begin_try bb_exc in
 				let bb_try_next = block bb_try e1 in
@@ -1506,7 +1489,7 @@ module TexprTransformer = struct
 					let bb_next = if bb_try_next == g.g_unreachable then
 						g.g_unreachable
 					else begin
-						let bb_next = create_node BKNormal bb_try bb.bb_type bb.bb_pos in
+						let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in
 						add_cfg_edge g bb_try_next bb_next CFGGoto;
 						close_node g bb_try_next;
 						bb_next
@@ -1517,7 +1500,7 @@ module TexprTransformer = struct
 					let is_reachable = ref (not (bb_try_next == g.g_unreachable)) in
 					let catches = List.map (fun (v,e) ->
 						let scope = increase_scope() in
-						let bb_catch = create_node BKNormal bb_exc e.etype e.epos in
+						let bb_catch = create_node BKNormal e.etype e.epos in
 						declare_var ctx.graph v bb_catch;
 						add_var_def g bb_catch v;
 						add_cfg_edge g bb_exc bb_catch CFGGoto;
@@ -1526,7 +1509,7 @@ module TexprTransformer = struct
 						is_reachable := !is_reachable || (not (bb_catch_next == g.g_unreachable));
 						v,bb_catch,bb_catch_next
 					) catches in
-					let bb_next = if !is_reachable then create_node BKNormal bb_try bb.bb_type bb.bb_pos else g.g_unreachable in
+					let bb_next = if !is_reachable then create_node BKNormal bb.bb_type bb.bb_pos else g.g_unreachable in
 					let catches = List.map (fun (v,bb_catch,bb_catch_next) ->
 						if bb_catch_next != g.g_unreachable then add_cfg_edge g bb_catch_next bb_next CFGGoto;
 						close_node g bb_catch_next;
@@ -1642,7 +1625,7 @@ module TexprTransformer = struct
 						let bb = if not (can_throw e) then
 							block_element bb e
 						else begin
-							let bb' = create_node BKNormal bb e.etype e.epos in
+							let bb' = create_node BKNormal e.etype e.epos in
 							add_cfg_edge g bb bb' CFGGoto;
 							List.iter (fun bb_exc -> add_cfg_edge g bb bb_exc CFGMaybeThrow) bbl;
 							set_syntax_edge g bb (SEMerge bb');