summaryrefslogtreecommitdiff
path: root/src/bytecode_util.ml
diff options
context:
space:
mode:
authorAlasdair Armstrong2019-03-06 14:11:24 +0000
committerAlasdair Armstrong2019-03-06 14:14:19 +0000
commit2b4018a07e9eead8bfe147611b24a4d5856b4d56 (patch)
tree456ce19e0ad0b413a3c4597008222425aba0e4f3 /src/bytecode_util.ml
parent2cd88a225adf5f382df85a046cd59c43e1436965 (diff)
Add option to slice out printing and tracing functions when generating C
Make instruction dependency graph use graph.ml Expose incremental graph building functions for performance in graph.mli
Diffstat (limited to 'src/bytecode_util.ml')
-rw-r--r--src/bytecode_util.ml103
1 files changed, 46 insertions, 57 deletions
diff --git a/src/bytecode_util.ml b/src/bytecode_util.ml
index 489bcc64..ee407289 100644
--- a/src/bytecode_util.ml
+++ b/src/bytecode_util.ml
@@ -540,6 +540,7 @@ module Node = struct
| G_id id1, G_id id2 -> Id.compare id1 id2
| G_label str1, G_label str2 -> String.compare str1 str2
| G_instr (n1, _), G_instr (n2, _) -> compare n1 n2
+ | G_start , G_start -> 0
| G_start , _ -> 1
| _ , G_start -> -1
| G_instr _, _ -> 1
@@ -548,10 +549,12 @@ module Node = struct
| _ , G_id _ -> -1
end
+module NodeGraph = Graph.Make(Node)
+
module NM = Map.Make(Node)
module NS = Set.Make(Node)
-type dep_graph = NS.t NM.t
+type dep_graph = NodeGraph.graph
let rec fragment_deps = function
| F_id id | F_ref id -> NS.singleton (G_id id)
@@ -593,78 +596,74 @@ let instr_deps = function
| I_undefined _ -> NS.empty, NS.empty
| I_match_failure -> NS.empty, NS.empty
-let add_link from_node to_node graph =
- try
- NM.add from_node (NS.add to_node (NM.find from_node graph)) graph
- with
- | Not_found -> NM.add from_node (NS.singleton to_node) graph
-
-let leaves graph =
- List.fold_left (fun acc (from_node, to_nodes) -> NS.filter (fun to_node -> Node.compare to_node from_node != 0) (NS.union acc to_nodes))
- NS.empty
- (NM.bindings graph)
-
-(* Ensure that all leaves exist in the graph *)
-let fix_leaves graph =
- NS.fold (fun leaf graph -> if NM.mem leaf graph then graph else NM.add leaf NS.empty graph) (leaves graph) graph
-
let instrs_graph instrs =
let icounter = ref 0 in
- let graph = ref NM.empty in
+ let graph = ref NodeGraph.empty in
- let rec add_instr last_instr (I_aux (instr, _) as iaux) =
+ let rec add_instr last_instrs (I_aux (instr, _) as iaux) =
incr icounter;
let node = G_instr (!icounter, iaux) in
match instr with
| I_block instrs | I_try_block instrs ->
- List.fold_left add_instr last_instr instrs
+ List.fold_left add_instr last_instrs instrs
| I_if (_, then_instrs, else_instrs, _) ->
begin
let inputs, _ = instr_deps instr in (* if has no outputs *)
- graph := add_link last_instr node !graph;
- NS.iter (fun input -> graph := add_link input node !graph) inputs;
- let n1 = List.fold_left add_instr node then_instrs in
- let n2 = List.fold_left add_instr node else_instrs in
+ List.iter (fun i -> graph := NodeGraph.add_edge' i node !graph) last_instrs;
+ NS.iter (fun input -> graph := NodeGraph.add_edge' input node !graph) inputs;
+ let n1 = List.fold_left add_instr [node] then_instrs in
+ let n2 = List.fold_left add_instr [node] else_instrs in
incr icounter;
let join = G_instr (!icounter, icomment "join") in
- graph := add_link n1 join !graph;
- graph := add_link n2 join !graph;
- join
+ List.iter (fun i -> graph := NodeGraph.add_edge' i join !graph) n1;
+ List.iter (fun i -> graph := NodeGraph.add_edge' i join !graph) n2;
+ [join]
+ end
+ | I_return _ ->
+ begin
+ let inputs, outputs = instr_deps instr in
+ List.iter (fun i -> graph := NodeGraph.add_edge' i node !graph) last_instrs;
+ NS.iter (fun input -> graph := NodeGraph.add_edge' input node !graph) inputs;
+ NS.iter (fun output -> graph := NodeGraph.add_edge' node output !graph) outputs;
+ []
end
+ | I_label _ ->
+ node :: last_instrs
| I_goto label ->
begin
let _, outputs = instr_deps instr in
- graph := add_link last_instr node !graph;
- NS.iter (fun output -> graph := add_link node output !graph) outputs;
- incr icounter;
- G_instr (!icounter, icomment "after goto")
+ List.iter (fun i -> graph := NodeGraph.add_edge' i node !graph) last_instrs;
+ NS.iter (fun output -> graph := NodeGraph.add_edge' node output !graph) outputs;
+ []
end
| _ ->
begin
let inputs, outputs = instr_deps instr in
- graph := add_link last_instr node !graph;
- NS.iter (fun input -> graph := add_link input node !graph) inputs;
- NS.iter (fun output -> graph := add_link node output !graph) outputs;
- node
+ List.iter (fun i -> graph := NodeGraph.add_edge' i node !graph) last_instrs;
+ NS.iter (fun input -> graph := NodeGraph.add_edge' input node !graph) inputs;
+ NS.iter (fun output -> graph := NodeGraph.add_edge' node output !graph) outputs;
+ [node]
end
in
- ignore (List.fold_left add_instr G_start instrs);
- fix_leaves !graph
+ ignore (List.fold_left add_instr [G_start] instrs);
+ let graph = NodeGraph.fix_leaves !graph in
+ graph
let make_dot id graph =
Util.opt_colors := false;
let to_string node = String.escaped (string_of_node node) in
let node_color = function
- | G_start -> "lightpink"
- | G_id _ -> "yellow"
- | G_instr (_, I_aux (I_decl _, _)) -> "olivedrab1"
- | G_instr (_, I_aux (I_init _, _)) -> "springgreen"
- | G_instr (_, I_aux (I_clear _, _)) -> "peachpuff"
- | G_instr (_, I_aux (I_goto _, _)) -> "orange1"
- | G_instr (_, I_aux (I_label _, _)) -> "white"
- | G_instr (_, I_aux (I_raw _, _)) -> "khaki"
- | G_instr _ -> "azure"
- | G_label _ -> "lightpink"
+ | G_start -> "lightpink"
+ | G_id _ -> "yellow"
+ | G_instr (_, I_aux (I_decl _, _)) -> "olivedrab1"
+ | G_instr (_, I_aux (I_init _, _)) -> "springgreen"
+ | G_instr (_, I_aux (I_clear _, _)) -> "peachpuff"
+ | G_instr (_, I_aux (I_goto _, _)) -> "orange1"
+ | G_instr (_, I_aux (I_label _, _)) -> "white"
+ | G_instr (_, I_aux (I_raw _, _)) -> "khaki"
+ | G_instr (_, I_aux (I_return _, _)) -> "deeppink"
+ | G_instr _ -> "azure"
+ | G_label _ -> "lightpink"
in
let edge_color from_node to_node =
match from_node, to_node with
@@ -677,17 +676,7 @@ let make_dot id graph =
| _ , _ -> "coral3"
in
let out_chan = open_out (Util.zencode_string (string_of_id id) ^ ".gv") in
- output_string out_chan "digraph DEPS {\n";
- let make_node from_node =
- output_string out_chan (Printf.sprintf " \"%s\" [fillcolor=%s;style=filled];\n" (to_string from_node) (node_color from_node))
- in
- let make_line from_node to_node =
- output_string out_chan (Printf.sprintf " \"%s\" -> \"%s\" [color=%s];\n" (to_string from_node) (to_string to_node) (edge_color from_node to_node))
- in
- NM.bindings graph |> List.iter (fun (from_node, _) -> make_node from_node);
- NM.bindings graph |> List.iter (fun (from_node, to_nodes) -> NS.iter (make_line from_node) to_nodes);
- output_string out_chan "}\n";
- Util.opt_colors := true;
+ NodeGraph.make_dot node_color edge_color to_string out_chan graph;
close_out out_chan
let rec map_clexp_ctyp f = function