From 349f34a24f987c0abf133d9a269d997e54c459e1 Mon Sep 17 00:00:00 2001
From: Valentin Perrelle <valentin.perrelle@cea.fr>
Date: Sat, 25 Jul 2020 18:41:36 +0200
Subject: [PATCH] [dive] send information about roots in the graph

---
 headers/header_spec.txt                       |   2 +
 ivette/api/plugins/dive/index.ts              |   9 +-
 ivette/src/frama-c/dive/Dive.tsx              |  13 +-
 ivette/src/frama-c/dive/style.json            |  29 ++-
 src/plugins/dive/Makefile.in                  |   4 +-
 src/plugins/dive/build.ml                     | 204 ++++-------------
 src/plugins/dive/build.mli                    |  19 +-
 src/plugins/dive/context.ml                   | 205 ++++++++++++++++++
 src/plugins/dive/context.mli                  |  61 ++++++
 src/plugins/dive/dive_graph.ml                |  82 ++++---
 src/plugins/dive/dive_graph.mli               |   2 +-
 src/plugins/dive/dive_types.mli               |   5 +-
 src/plugins/dive/main.ml                      |   8 +-
 src/plugins/dive/server_interface.ml          |  20 +-
 .../dive/tests/dive/oracle/assigned_param.dot |  22 +-
 .../tests/dive/oracle/callstack_global.dot    |  48 ++--
 .../tests/dive/oracle/callstack_strategy.dot  |  50 ++---
 src/plugins/dive/tests/dive/oracle/const.dot  |  32 +--
 .../dive/tests/dive/oracle/exceptional.dot    |  28 +--
 src/plugins/dive/tests/dive/oracle/global.dot |  20 +-
 .../dive/tests/dive/oracle/manydeps.dot       |  76 +++----
 .../dive/tests/dive/oracle/per_callstack.dot  |  58 ++---
 .../dive/tests/dive/oracle/pointed_param.dot  |  34 +--
 .../tests/dive/oracle/pointers_to_local.dot   |  20 +-
 src/plugins/dive/tests/dive/oracle/ranges.dot |  76 +++----
 .../tests/dive/oracle/unfocused_callers.dot   |  32 +--
 .../dive/tests/dive/oracle/various.dot        |  90 ++++----
 27 files changed, 711 insertions(+), 538 deletions(-)
 create mode 100644 src/plugins/dive/context.ml
 create mode 100644 src/plugins/dive/context.mli

diff --git a/headers/header_spec.txt b/headers/header_spec.txt
index 55a3289cd5e..59e9fb34c5d 100644
--- a/headers/header_spec.txt
+++ b/headers/header_spec.txt
@@ -768,6 +768,8 @@ src/plugins/dive/build.mli: CEA_LGPL_OR_PROPRIETARY
 src/plugins/dive/callstack.ml: CEA_LGPL_OR_PROPRIETARY
 src/plugins/dive/callstack.mli: CEA_LGPL_OR_PROPRIETARY
 src/plugins/dive/configure.ac: CEA_LGPL_OR_PROPRIETARY
+src/plugins/dive/context.ml: CEA_LGPL_OR_PROPRIETARY
+src/plugins/dive/context.mli: CEA_LGPL_OR_PROPRIETARY
 src/plugins/dive/dive_graph.ml: CEA_LGPL_OR_PROPRIETARY
 src/plugins/dive/dive_graph.mli: CEA_LGPL_OR_PROPRIETARY
 src/plugins/dive/dive_types.mli: CEA_LGPL_OR_PROPRIETARY
diff --git a/ivette/api/plugins/dive/index.ts b/ivette/api/plugins/dive/index.ts
index 8223fb299d7..a63a701b04e 100644
--- a/ivette/api/plugins/dive/index.ts
+++ b/ivette/api/plugins/dive/index.ts
@@ -142,8 +142,9 @@ export const byNodeLocality: Compare.Order<nodeLocality> =
 /** A graph node */
 export type node =
   { id: nodeId, label: string, kind: string, locality: nodeLocality,
-    backward_explored: string, forward_explored: string, writes: location[],
-    values?: string, range: number | string, type?: string };
+    is_root: boolean, backward_explored: string, forward_explored: string,
+    writes: location[], values?: string, range: number | string,
+    type?: string };
 
 /** Loose decoder for `node` */
 export const jNode: Json.Loose<node> =
@@ -152,6 +153,7 @@ export const jNode: Json.Loose<node> =
     label: Json.jFail(Json.jString,'String expected'),
     kind: Json.jFail(Json.jString,'String expected'),
     locality: jNodeLocalitySafe,
+    is_root: Json.jFail(Json.jBoolean,'Boolean expected'),
     backward_explored: Json.jFail(Json.jString,'String expected'),
     forward_explored: Json.jFail(Json.jString,'String expected'),
     writes: Json.jArray(jLocationSafe),
@@ -169,13 +171,14 @@ export const jNodeSafe: Json.Safe<node> = Json.jFail(jNode,'Node expected');
 export const byNode: Compare.Order<node> =
   Compare.byFields
     <{ id: nodeId, label: string, kind: string, locality: nodeLocality,
-       backward_explored: string, forward_explored: string,
+       is_root: boolean, backward_explored: string, forward_explored: string,
        writes: location[], values?: string, range: number | string,
        type?: string }>({
     id: byNodeId,
     label: Compare.string,
     kind: Compare.string,
     locality: byNodeLocality,
+    is_root: Compare.boolean,
     backward_explored: Compare.string,
     forward_explored: Compare.string,
     writes: Compare.array(byLocation),
diff --git a/ivette/src/frama-c/dive/Dive.tsx b/ivette/src/frama-c/dive/Dive.tsx
index 3f8c31dd406..2a17080fe4a 100644
--- a/ivette/src/frama-c/dive/Dive.tsx
+++ b/ivette/src/frama-c/dive/Dive.tsx
@@ -273,12 +273,13 @@ class Dive {
 
     for (const dep of data.deps)
     {
+      const src = this.cy.$id(dep.src);
+      const dst = this.cy.$id(dep.dst);
+      const isRoot = dst?.data('is_root');
       this.cy.add({
-        data: { ...dep, source: dep.src, target: dep.dst },
+        data: { ...dep, source: dep.src, target: dep.dst, is_root: isRoot },
         group: 'edges',
-        classes:
-          this.cy.$id(dep.src).hasClass('new') ||
-          this.cy.$id(dep.dst).hasClass('new') ? 'new' : ''
+        classes: src?.hasClass('new') || dst?.hasClass('new') ? 'new' : '',
       });
     }
 
@@ -327,8 +328,8 @@ class Dive {
         /* Do not move new nodes */
         animateFilter: (node: Cytoscape.Singular) => !newNodes.contains(node),
         stop: () => {
-            this.cy.$(".new").addClass('old').removeClass('new');
-          },
+          this.cy.$('.new').addClass('old').removeClass('new');
+        },
         ...this.layoutOptions,
       } as unknown as Cytoscape.LayoutOptions).run();
     }
diff --git a/ivette/src/frama-c/dive/style.json b/ivette/src/frama-c/dive/style.json
index 31cf4157725..38374dab223 100644
--- a/ivette/src/frama-c/dive/style.json
+++ b/ivette/src/frama-c/dive/style.json
@@ -24,21 +24,19 @@
     }
   },
   {
-    "selector": "edge:selected",
+    "selector": "node[label]",
     "style": {
-      "color": "#48f",
-      "overlay-color": "#8bf",
-      "overlay-padding": "10px",
-      "overlay-opacity": 0.4
+      "label": "data(label)"
+
     }
   },
   {
-    "selector": "node[label]",
+    "selector": "node[?is_root]",
     "style": {
-      "label": "data(label)"
-
+      "border-width": "2px"
     }
   },
+
   {
     "selector": "node.more",
     "style": {
@@ -59,6 +57,21 @@
       "arrow-scale": 2.0
     }
   },
+  {
+    "selector": "edge:selected",
+    "style": {
+      "color": "#48f",
+      "overlay-color": "#8bf",
+      "overlay-padding": "10px",
+      "overlay-opacity": 0.4
+    }
+  },
+  {
+    "selector": "edge[?is_root]",
+    "style": {
+      "width": 4
+    }
+  },
   {
     "selector": ".function",
     "style": {
diff --git a/src/plugins/dive/Makefile.in b/src/plugins/dive/Makefile.in
index 3847f07858b..10125171ad2 100644
--- a/src/plugins/dive/Makefile.in
+++ b/src/plugins/dive/Makefile.in
@@ -39,8 +39,8 @@ endif
 PLUGIN_DIR ?=.
 PLUGIN_ENABLE:=@ENABLE_DIVE@
 PLUGIN_NAME := Dive
-PLUGIN_CMO := self callstack node_kind node_range dive_graph build main \
-  server_interface
+PLUGIN_CMO := self callstack node_kind node_range dive_graph context build \
+  main server_interface
 PLUGIN_CMI := dive_types
 PLUGIN_DEPENDENCIES:= Eva Studia Server
 PLUGIN_HAS_MLI:= yes
diff --git a/src/plugins/dive/build.ml b/src/plugins/dive/build.ml
index b621e26021a..b737adb26e8 100644
--- a/src/plugins/dive/build.ml
+++ b/src/plugins/dive/build.ml
@@ -251,87 +251,19 @@ let find_compatible_callstacks stmt callstack =
     Callstack.filter_truncate callstacks callstack
 
 
-(* --- Context object --- *)
-
-module NodeRef = Datatype.Pair_with_collections
-    (Node_kind) (Callstack)
-    (struct let module_name = "Build.NodeRef" end)
-
-module Index = Datatype.Int.Hashtbl
-module NodeTable = FCHashtbl.Make (NodeRef)
-module BaseSet = Cil_datatype.Varinfo.Set
-module FunctionMap = Kernel_function.Map
-
-type t = {
-  mutable graph: Graph.t;
-  mutable vertex_table: node Index.t; (* node_key -> node *)
-  mutable node_table: node NodeTable.t; (* node_kind * callstack -> node *)
-  mutable unfolded_bases: BaseSet.t;
-  mutable hidden_bases: BaseSet.t;
-  mutable focus: bool FunctionMap.t;
-  mutable max_dep_fetch_count: int;
-  mutable roots: node list;
-  mutable graph_diff: graph_diff;
-}
-
-let is_folded context vi =
-  not (BaseSet.mem vi context.unfolded_bases)
-
-let is_hidden context node_kind =
-  match Node_kind.get_base node_kind with
-  | Some vi when BaseSet.mem vi context.hidden_bases -> true
-  | _ -> false
-
-let find_node context node_key =
-  Index.find context.vertex_table node_key
-
-let update_node context node =
-  if
-    not (List.exists (Graph.Node.equal node) context.graph_diff.added_nodes)
-  then
-    context.graph_diff <- {
-      context.graph_diff with
-      added_nodes = node :: context.graph_diff.added_nodes
-    }
-
-let add_node context ~node_kind ~node_locality =
-  let node_ref = (node_kind, node_locality.loc_callstack) in
-  let add_new _ =
-    let node = Graph.create_node context.graph ~node_kind ~node_locality in
-    node.node_hidden <- is_hidden context node.node_kind;
-    Index.add context.vertex_table node.node_key node;
-    update_node context node;
-    node
-  in
-  NodeTable.memo context.node_table node_ref add_new
-
-let remove_node context node =
-  let node_ref = (node.node_kind, node.node_locality.loc_callstack) in
-  let graph = context.graph in
-  Graph.iter_succ (fun n -> n.node_writes_computation <- NotDone) graph node;
-  Graph.iter_pred (fun n -> n.node_reads_computation <- NotDone) graph node;
-  Graph.remove_node context.graph node;
-  Index.remove context.vertex_table node.node_key;
-  NodeTable.remove context.node_table node_ref;
-  context.graph_diff <- {
-    context.graph_diff with
-    removed_nodes = node :: context.graph_diff.removed_nodes
-  }
-
-
 (* --- Graph building --- *)
 
 let add_or_update_node context callstack node_kind =
   let node_locality = build_node_locality callstack node_kind in
-  add_node context ~node_kind ~node_locality
+  Context.add_node context ~node_kind ~node_locality
 
 let build_node context callstack lval kinstr =
-  let is_folded_base = is_folded context in
+  let is_folded_base = Context.is_folded context in
   let node_kind = build_node_kind ~is_folded_base lval kinstr in
   add_or_update_node context callstack node_kind
 
 let build_all_scattered_node ~limit context callstack kinstr lval =
-  let is_folded_base = is_folded context in
+  let is_folded_base = Context.is_folded context in
   let cells, complete =
     try
       enumerate_cells ~is_folded_base ~limit lval kinstr, true
@@ -359,10 +291,14 @@ let build_lval context callstack kinstr lval =
 let build_alarm context callstack stmt alarm =
   let node_kind = Alarm (stmt,alarm) in
   let node_locality = build_node_locality callstack node_kind in
-  add_node context ~node_kind ~node_locality
+  Context.add_node context ~node_kind ~node_locality
+
 
+(* --- Writes --- *)
 
 let build_node_writes context node =
+  let graph = Context.get_graph context
+  and max_dep_fetch_count = Context.get_max_dep_fetch_count context in
 
   let rec build_write_deps callstack kinstr lval =
     let writes = match node.node_writes_computation with
@@ -378,7 +314,7 @@ let build_node_writes context node =
         List.iter (fun cs -> build_instr_deps cs stmt instr) callstacks
       | _ -> assert false (* Studia invariant *)
     in
-    let sub,rest = list_break context.max_dep_fetch_count writes in
+    let sub,rest = list_break max_dep_fetch_count writes in
     List.iter add_deps sub;
     if rest = [] then Done else Partial rest
 
@@ -455,17 +391,17 @@ let build_node_writes context node =
   and build_lval_deps callstack stmt kind lval =
     let kinstr = Kstmt stmt in
     let dst = build_lval context callstack kinstr lval in
-    Graph.create_dependency context.graph kinstr dst kind node
+    Graph.create_dependency graph kinstr dst kind node
 
   and build_scattered_deps callstack kinstr lval =
-    let succ_count = List.length (Graph.pred context.graph node) in
-    let limit = succ_count + context.max_dep_fetch_count in
+    let succ_count = List.length (Graph.pred graph node) in
+    let limit = succ_count + max_dep_fetch_count in
     let nodes, complete =
       build_all_scattered_node ~limit context callstack kinstr lval
     in
     let kind = Composition in
     let add_dep dst =
-      Graph.create_dependency context.graph kinstr dst kind node
+      Graph.create_dependency graph kinstr dst kind node
     in
     List.iter add_dep nodes;
     if complete then Done else Partial []
@@ -489,10 +425,15 @@ let build_node_writes context node =
   node.node_writes_computation <- writes_computation;
   let compare_stmt = Cil_datatype.Stmt_Id.compare in
   node.node_writes_stmts <- List.sort compare_stmt node.node_writes_stmts;
-  update_node context node
+  Context.update_diff context node
 
 
+(* --- Reads --- *)
+
 let build_node_reads context node =
+  let graph = Context.get_graph context
+  and max_dep_fetch_count = Context.get_max_dep_fetch_count context in
+
   let rec build_reads_deps callstack kinstr lval =
     let reads = match node.node_reads_computation with
       | Done -> []
@@ -503,7 +444,7 @@ let build_node_reads context node =
       let callstacks = find_compatible_callstacks stmt callstack in
       List.iter (fun cs -> build_stmt_deps cs zone stmt) callstacks
     in
-    let sub,rest = list_break context.max_dep_fetch_count reads in
+    let sub,rest = list_break max_dep_fetch_count reads in
     List.iter add_deps sub;
     if rest = [] then Done else Partial rest
 
@@ -585,7 +526,7 @@ let build_node_reads context node =
   and build_lval_deps callstack stmt lval =
     let kinstr = Kstmt stmt in
     let src = build_lval context callstack kinstr lval in
-    Graph.create_dependency context.graph kinstr node Data src
+    Graph.create_dependency graph kinstr node Data src
 
   and build_var_deps callstack stmt vi =
     build_lval_deps callstack stmt (Cil.var vi)
@@ -605,57 +546,10 @@ let build_node_reads context node =
       Done
   in
   node.node_reads_computation <- reads_computation;
-  update_node context node
-
-
-(* --- Graph initialization --- *)
-
-let create () =
-  !Db.Value.compute ();
-  {
-    graph = Graph.create ();
-    vertex_table = Index.create 13;
-    node_table = NodeTable.create 13;
-    unfolded_bases = BaseSet.empty;
-    hidden_bases = BaseSet.empty;
-    focus = FunctionMap.empty;
-    max_dep_fetch_count = 10;
-    roots = [];
-    graph_diff = { last_root = None ; added_nodes=[] ; removed_nodes=[] };
-  }
+  Context.update_diff context node
 
-let clear context =
-  context.graph <- Graph.create ();
-  context.vertex_table <- Index.create 13;
-  context.node_table <- NodeTable.create 13;
-  context.focus <- FunctionMap.empty;
-  context.max_dep_fetch_count <- 10;
-  context.roots <- [];
-  context.graph_diff <- { last_root = None ; added_nodes=[] ; removed_nodes=[] }
 
-
-(* --- Accessors --- *)
-
-let get_graph context =
-  context.graph
-
-let get_roots context =
-  context.roots
-
-
-(* --- Mutators --- *)
-
-let unfold_base context vi =
-  context.unfolded_bases <- BaseSet.add vi context.unfolded_bases
-
-let fold_base context vi =
-  context.unfolded_bases <- BaseSet.remove vi context.unfolded_bases
-
-let hide_base context vi =
-  context.hidden_bases <- BaseSet.add vi context.hidden_bases
-
-let unhide_base context vi =
-  context.hidden_bases <- BaseSet.add vi context.hidden_bases
+(* --- Exploration --- *)
 
 let should_explore node =
   match node.node_kind with
@@ -674,8 +568,7 @@ let bfs ~depth ~iter_succ f root =
   done
 
 let explore_backward ~depth context root =
-  context.graph_diff <- { context.graph_diff with last_root = Some root };
-  let iter_succ f n = Graph.iter_pred f context.graph n
+  let iter_succ f n = Graph.iter_pred f (Context.get_graph context) n
   and explore_node n =
     if n.node_writes_computation <> Done && should_explore n then
       build_node_writes context n
@@ -683,15 +576,18 @@ let explore_backward ~depth context root =
   bfs ~depth ~iter_succ explore_node root
 
 let explore_forward ~depth context root =
-  let iter_succ f n = Graph.iter_succ f context.graph n
+  let iter_succ f n = Graph.iter_succ f (Context.get_graph context) n
   and explore_node n =
     if n.node_reads_computation <> Done && should_explore n then
       build_node_reads context n;
   in
   bfs ~depth ~iter_succ explore_node root
 
+
+(* --- Adding new roots --- *)
+
 let complete context root =
-  context.roots <- root :: context.roots;
+  Context.add_root context root;
   root
 
 let add_var context varinfo =
@@ -741,28 +637,32 @@ let add_localizable context = function
   | _ -> None (* Do nothing for any other localizable *)
 
 
+(* --- Visibility handling --- *)
+
 let remove_dependencies context node =
   (* Remove incomming edges *)
-  Graph.remove_dependencies (context.graph) node;
+  Graph.remove_dependencies (Context.get_graph context) node;
   (* Dependencies are not there anymore *)
   node.node_writes_computation <- NotDone;
   node.node_writes_stmts <- [];
   (* Notify node update *)
-  update_node context node
+  Context.update_diff context node
 
 let remove_disconnected context =
-  let l = Graph.find_independant_nodes context.graph context.roots in
-  List.iter (remove_node context) l
-
+  let roots = Context.get_roots context in
+  let l = Graph.find_independant_nodes (Context.get_graph context) roots in
+  List.iter (Context.remove_node context) l
 
-let reduce_to_horizon ({ graph } as context) range new_root =
+let reduce_to_horizon context range new_root =
   (* Reduce to one root *)
-  context.roots <- [ new_root ];
+  Context.set_unique_root context new_root ;
   (* List visible nodes *)
-  let backward_bfs = Graph.bfs ~iter_succ:Graph.iter_pred ?limit:range.backward
+  let graph = Context.get_graph context
+  and roots = Context.get_roots context
+  and backward_bfs = Graph.bfs ~iter_succ:Graph.iter_pred ?limit:range.backward
   and forward_bfs = Graph.bfs ~iter_succ:Graph.iter_succ ?limit:range.forward in
-  let bacward_nodes = backward_bfs graph context.roots
-  and forward_nodes = forward_bfs graph context.roots in
+  let bacward_nodes = backward_bfs graph roots
+  and forward_nodes = forward_bfs graph roots in
   (* Table of visible nodes *)
   let module Table = Hashtbl.Make (Graph.Node) in
   let visible = Table.create 13 in
@@ -774,7 +674,7 @@ let reduce_to_horizon ({ graph } as context) range new_root =
       if List.exists is_visible (Graph.succ graph node) then
         remove_dependencies context node
       else
-        remove_node context node
+        Context.remove_node context node
   in
   Graph.iter_vertex update graph
 
@@ -784,21 +684,7 @@ let show _context node =
 let hide context node =
   if not node.node_hidden then begin
     node.node_hidden <- true;
+    Context.remove_root context node;
     remove_dependencies context node;
     remove_disconnected context
   end
-
-let take_last_differences context =
-  let pp_node fmt n = Format.pp_print_int fmt n.node_key in
-  let pp_node_list = Pretty_utils.pp_list ~sep:",@, " pp_node in
-  let diff = context.graph_diff in
-  Self.debug ~dkey "root: %a,@, added: %a,@, subbed: %a"
-    (Pretty_utils.pp_opt pp_node) diff.last_root
-    pp_node_list diff.added_nodes
-    pp_node_list diff.removed_nodes;
-  context.graph_diff <- {
-    last_root = None ;
-    added_nodes=[] ;
-    removed_nodes=[]
-  };
-  diff
diff --git a/src/plugins/dive/build.mli b/src/plugins/dive/build.mli
index 48e725ec93c..913ee78fd5a 100644
--- a/src/plugins/dive/build.mli
+++ b/src/plugins/dive/build.mli
@@ -22,22 +22,7 @@
 
 open Cil_types
 open Dive_types
-
-type t
-
-val create : unit -> t
-val clear : t -> unit (* reset to almost an empty context,
-                         but keeps folded and hidden bases *)
-
-val get_graph : t -> Dive_graph.t
-val get_roots : t -> node list
-
-val unfold_base : t -> varinfo -> unit
-val fold_base : t -> varinfo -> unit
-val hide_base : t -> varinfo -> unit
-val unhide_base : t -> varinfo -> unit
-
-val find_node : t -> int -> node
+open Context
 
 val add_lval : t -> kinstr -> lval -> node
 val add_var : t -> varinfo -> node
@@ -54,5 +39,3 @@ val show : t -> node -> unit
 val hide : t -> node -> unit
 
 val reduce_to_horizon : t -> int option range -> node -> unit
-
-val take_last_differences : t -> graph_diff
diff --git a/src/plugins/dive/context.ml b/src/plugins/dive/context.ml
new file mode 100644
index 00000000000..df14fe7c723
--- /dev/null
+++ b/src/plugins/dive/context.ml
@@ -0,0 +1,205 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2020                                               *)
+(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
+(*         alternatives)                                                  *)
+(*                                                                        *)
+(*  you can redistribute it and/or modify it under the terms of the GNU   *)
+(*  Lesser General Public License as published by the Free Software       *)
+(*  Foundation, version 2.1.                                              *)
+(*                                                                        *)
+(*  It is distributed in the hope that it will be useful,                 *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
+(*  GNU Lesser General Public License for more details.                   *)
+(*                                                                        *)
+(*  See the GNU Lesser General Public License version 2.1                 *)
+(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+open Dive_types
+
+module Graph = Dive_graph
+
+let dkey = Self.register_category "context"
+
+
+module NodeRef = Datatype.Pair_with_collections
+    (Node_kind) (Callstack)
+    (struct let module_name = "Build.NodeRef" end)
+
+module Index = Datatype.Int.Hashtbl
+module NodeTable = FCHashtbl.Make (NodeRef)
+module NodeSet = Graph.Node.Set
+module BaseSet = Cil_datatype.Varinfo.Set
+module FunctionMap = Kernel_function.Map
+
+type t = {
+  mutable graph: Graph.t;
+  mutable vertex_table: node Index.t; (* node_key -> node *)
+  mutable node_table: node NodeTable.t; (* node_kind * callstack -> node *)
+  mutable unfolded_bases: BaseSet.t;
+  mutable hidden_bases: BaseSet.t;
+  mutable focus: bool FunctionMap.t;
+  mutable max_dep_fetch_count: int;
+  mutable roots: NodeSet.t;
+  mutable graph_diff: graph_diff;
+}
+
+
+(* --- initialization --- *)
+
+let create () =
+  !Db.Value.compute ();
+  {
+    graph = Graph.create ();
+    vertex_table = Index.create 13;
+    node_table = NodeTable.create 13;
+    unfolded_bases = BaseSet.empty;
+    hidden_bases = BaseSet.empty;
+    focus = FunctionMap.empty;
+    max_dep_fetch_count = 10;
+    roots = NodeSet.empty;
+    graph_diff = { last_root = None ; added_nodes=[] ; removed_nodes=[] };
+  }
+
+let clear context =
+  context.graph <- Graph.create ();
+  context.vertex_table <- Index.create 13;
+  context.node_table <- NodeTable.create 13;
+  context.focus <- FunctionMap.empty;
+  context.max_dep_fetch_count <- 10;
+  context.roots <- NodeSet.empty;
+  context.graph_diff <- { last_root = None ; added_nodes=[] ; removed_nodes=[] }
+
+
+(* --- Accessors --- *)
+
+let get_graph context =
+  context.graph
+
+let find_node context node_key =
+  Index.find context.vertex_table node_key
+
+let get_max_dep_fetch_count context =
+  context.max_dep_fetch_count
+
+
+(* --- State --- *)
+
+let is_node_updated context node =
+  let is_node n = Graph.Node.equal node n in
+  List.exists is_node context.graph_diff.removed_nodes ||
+  List.exists is_node context.graph_diff.added_nodes
+
+let update_diff context node =
+  if not (is_node_updated context node) then
+    context.graph_diff <- {
+      context.graph_diff with
+      added_nodes = node :: context.graph_diff.added_nodes;
+    }
+
+let take_last_diff context =
+  let pp_node fmt n = Format.pp_print_int fmt n.node_key in
+  let pp_node_list = Pretty_utils.pp_list ~sep:",@, " pp_node in
+  let diff = context.graph_diff in
+  Self.debug ~dkey "root: %a,@, added: %a,@, subbed: %a"
+    (Pretty_utils.pp_opt pp_node) diff.last_root
+    pp_node_list diff.added_nodes
+    pp_node_list diff.removed_nodes;
+  context.graph_diff <- {
+    last_root = None ;
+    added_nodes=[] ;
+    removed_nodes=[]
+  };
+  diff
+
+
+(* --- Roots --- *)
+
+let get_roots context =
+  NodeSet.elements context.roots
+
+let update_roots context new_roots =
+  let old_roots = context.roots in
+  context.roots <- new_roots;
+  let unset n =
+    if not (NodeSet.mem n new_roots) then begin
+      n.node_is_root <- false;
+      update_diff context n
+    end
+  and set n =
+    if not (NodeSet.mem n old_roots) then begin
+      n.node_is_root <- true;
+      update_diff context n
+    end
+  in
+  NodeSet.iter unset old_roots;
+  NodeSet.iter set new_roots
+
+let set_unique_root context root =
+  update_roots context (NodeSet.singleton root)
+
+let add_root context root =
+  update_roots context (NodeSet.add root context.roots)
+
+let remove_root context root =
+  update_roots context (NodeSet.remove root context.roots)
+
+
+(* --- Folding --- *)
+
+let is_folded context vi =
+  not (BaseSet.mem vi context.unfolded_bases)
+
+let fold context vi =
+  context.unfolded_bases <- BaseSet.remove vi context.unfolded_bases
+
+let unfold context vi =
+  context.unfolded_bases <- BaseSet.add vi context.unfolded_bases
+
+
+(* --- Base hiding --- *)
+
+let is_hidden context node_kind =
+  match Node_kind.get_base node_kind with
+  | Some vi when BaseSet.mem vi context.hidden_bases -> true
+  | _ -> false
+
+let show context vi =
+  context.hidden_bases <- BaseSet.add vi context.hidden_bases
+
+let hide context vi =
+  context.hidden_bases <- BaseSet.add vi context.hidden_bases
+
+
+(* --- Building --- *)
+
+let add_node context ~node_kind ~node_locality =
+  let node_ref = (node_kind, node_locality.loc_callstack) in
+  let add_new _ =
+    let node = Graph.create_node context.graph ~node_kind ~node_locality in
+    node.node_hidden <- is_hidden context node.node_kind;
+    Index.add context.vertex_table node.node_key node;
+    update_diff context node;
+    node
+  in
+  NodeTable.memo context.node_table node_ref add_new
+
+let remove_node context node =
+  let node_ref = (node.node_kind, node.node_locality.loc_callstack) in
+  let graph = context.graph in
+  Graph.iter_succ (fun n -> n.node_writes_computation <- NotDone) graph node;
+  Graph.iter_pred (fun n -> n.node_reads_computation <- NotDone) graph node;
+  Graph.remove_node context.graph node;
+  Index.remove context.vertex_table node.node_key;
+  NodeTable.remove context.node_table node_ref;
+  let is_not_node n = not (Graph.Node.equal node n) in
+  context.graph_diff <- {
+    context.graph_diff with
+    added_nodes = List.filter is_not_node context.graph_diff.added_nodes;
+    removed_nodes = node :: context.graph_diff.removed_nodes;
+  }
diff --git a/src/plugins/dive/context.mli b/src/plugins/dive/context.mli
new file mode 100644
index 00000000000..953fcf72a9a
--- /dev/null
+++ b/src/plugins/dive/context.mli
@@ -0,0 +1,61 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2020                                               *)
+(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
+(*         alternatives)                                                  *)
+(*                                                                        *)
+(*  you can redistribute it and/or modify it under the terms of the GNU   *)
+(*  Lesser General Public License as published by the Free Software       *)
+(*  Foundation, version 2.1.                                              *)
+(*                                                                        *)
+(*  It is distributed in the hope that it will be useful,                 *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
+(*  GNU Lesser General Public License for more details.                   *)
+(*                                                                        *)
+(*  See the GNU Lesser General Public License version 2.1                 *)
+(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+open Dive_types
+
+(*
+module NodeRef : Datatype.S with type t = node_kind * callstack
+module Index : Datatype.Hashtbl with type key = int
+module NodeTable : Datatype.Hashtbl with type key = NodeRef.t
+module NodeSet : Datatype.Set with type elt = node
+module BaseSet : Datatype.Set with type elt = Cil_types.varinfo
+module FunctionMap : Datatype.Map with type key = Cil_types.kernel_function
+*)
+
+type t
+
+val create : unit -> t
+val clear : t -> unit (* reset to almost an empty context,
+                         but keeps folded and hidden bases *)
+
+val get_graph : t -> Dive_graph.t
+val find_node : t -> int -> node
+val get_max_dep_fetch_count : t -> int
+
+val get_roots : t -> node list
+val set_unique_root : t -> node -> unit
+val add_root : t -> node -> unit
+val remove_root : t -> node -> unit
+
+val is_folded : t -> Cil_types.varinfo -> bool
+val unfold : t -> Cil_types.varinfo -> unit
+val fold : t -> Cil_types.varinfo -> unit
+
+val is_hidden : t -> node_kind -> bool
+val hide : t -> Cil_types.varinfo -> unit
+val show : t -> Cil_types.varinfo -> unit
+
+val add_node : t -> node_kind:node_kind -> node_locality:node_locality -> node
+val remove_node : t -> node -> unit
+
+val update_diff : t -> node -> unit
+val take_last_diff : t -> graph_diff
diff --git a/src/plugins/dive/dive_graph.ml b/src/plugins/dive/dive_graph.ml
index 562203b59ea..32aff4d9971 100644
--- a/src/plugins/dive/dive_graph.ml
+++ b/src/plugins/dive/dive_graph.ml
@@ -22,13 +22,37 @@
 
 open Dive_types
 
-module Node =
-struct
-  type t = node
-  let compare v1 v2 = v1.node_key - v2.node_key
-  let hash v = v.node_key
-  let equal v1 v2 = v1.node_key = v2.node_key
-end
+let fresh_key =
+  let next_key = ref 0 in
+  fun () -> incr next_key; !next_key
+
+let new_node
+    ?(node_kind=Error "no kind")
+    ?(node_locality={loc_file=""; loc_callstack=[]})
+    () = {
+  node_key = fresh_key ();
+  node_kind;
+  node_locality;
+  node_is_root = false;
+  node_hidden = false;
+  node_values = None;
+  node_range = Empty;
+  node_writes_computation = NotDone;
+  node_reads_computation = NotDone;
+  node_writes_stmts = [];
+}
+
+module Node = Datatype.Make_with_collections
+    (struct
+      type t = node
+      include Datatype.Serializable_undefined
+      let name = "Dive.Node"
+      let reprs = [ new_node () ]
+      let compare n1 n2 = Datatype.Int.compare n1.node_key n2.node_key
+      let hash n = n.node_key
+      let equal n1 n2 = n1.node_key = n2.node_key
+      let pretty fmt n = Format.pp_print_int fmt n.node_key
+    end)
 
 module Dependency =
 struct
@@ -47,40 +71,14 @@ module G =
   Graph.Imperative.Digraph.ConcreteBidirectionalLabeled (Node) (Dependency)
 include G
 
-let vertices g =
-  fold_vertex (fun n acc -> n ::acc) g []
-
-let edges g =
-  fold_edges_e (fun d acc -> d ::acc) g []
-
-let fresh_key =
-  let next_key = ref 0 in
-  fun () -> incr next_key; !next_key
 
 let create_node ~node_kind ~node_locality g =
-  let node = {
-    node_key = fresh_key ();
-    node_kind;
-    node_locality;
-    node_hidden = false;
-    node_values = None;
-    node_range = Empty;
-    node_writes_computation = NotDone;
-    node_reads_computation = NotDone;
-    node_writes_stmts = [];
-  }
-  in
+  let node = new_node ~node_kind ~node_locality () in
   add_vertex g node;
   node
 
 let remove_node = remove_vertex
 
-let update_node_values node new_values typ =
-  node.node_values <-
-    Some (Extlib.opt_fold Cvalue.V.join node.node_values new_values);
-  node.node_range <-
-    Node_range.(upper_bound node.node_range (evaluate new_values typ))
-
 let create_dependency g kinstr v1 dependency_kind v2 =
   let same_kind (_,e,_) =
     e.dependency_kind = dependency_kind
@@ -118,6 +116,19 @@ let remove_dependency g edge =
 let remove_dependencies g node =
   iter_pred_e (remove_dependency g) g node
 
+let vertices g =
+  fold_vertex (fun n acc -> n ::acc) g []
+
+let edges g =
+  fold_edges_e (fun d acc -> d ::acc) g []
+
+
+let update_node_values node new_values typ =
+  node.node_values <-
+    Some (Extlib.opt_fold Cvalue.V.join node.node_values new_values);
+  node.node_range <-
+    Node_range.(upper_bound node.node_range (evaluate new_values typ))
+
 let find_independant_nodes g roots =
   let module Dfs = Graph.Traverse.Dfs (struct
       include G
@@ -224,6 +235,8 @@ let ouptput_to_dot out_channel g =
         l := range @ kind @ !l;
         if v.node_writes_computation <> Done then
           l := [ `Style `Dotted ] @ !l;
+        if v.node_is_root then
+          l := [ `Style `Bold ] @ !l;
         !l
       let get_subgraph v =
         let {loc_file ; loc_callstack} = v.node_locality in
@@ -318,6 +331,7 @@ struct
         ("label", `String label) ;
         ("kind", output_node_kind node.node_kind) ;
         ("locality", output_node_locality node.node_locality) ;
+        ("is_root", `Bool node.node_is_root) ;
         ("backward_explored", output_computation node.node_writes_computation) ;
         ("forward_explored", output_computation node.node_reads_computation) ;
         ("writes", `List (List.map output_stmt node.node_writes_stmts)) ;
diff --git a/src/plugins/dive/dive_graph.mli b/src/plugins/dive/dive_graph.mli
index 63e7b40e029..1f4f6d43cb6 100644
--- a/src/plugins/dive/dive_graph.mli
+++ b/src/plugins/dive/dive_graph.mli
@@ -26,7 +26,7 @@ include Graph.Sig.G
   with type V.t = node
    and type E.t = node * dependency * node
 
-module Node : Graph.Sig.COMPARABLE with type t = node
+module Node : Datatype.S_with_collections with type t = node
 
 module Dependency : Graph.Sig.COMPARABLE with type t = dependency
 
diff --git a/src/plugins/dive/dive_types.mli b/src/plugins/dive/dive_types.mli
index 5555e11f1c3..599612a8647 100644
--- a/src/plugins/dive/dive_types.mli
+++ b/src/plugins/dive/dive_types.mli
@@ -30,9 +30,11 @@ type node_kind =
   | String of int * Base.cstring
   | Error of string
 
+type callstack = Callstack.t
+
 type node_locality = {
   loc_file : string;
-  loc_callstack : Callstack.t;
+  loc_callstack : callstack;
 }
 
 type node_range =
@@ -47,6 +49,7 @@ type node = {
   node_key : int;
   node_kind : node_kind;
   node_locality : node_locality;
+  mutable node_is_root : bool;
   mutable node_hidden : bool;
   mutable node_values : Cvalue.V.t option;
   mutable node_range : node_range;
diff --git a/src/plugins/dive/main.ml b/src/plugins/dive/main.ml
index acc8011ba63..5f728b624ad 100644
--- a/src/plugins/dive/main.ml
+++ b/src/plugins/dive/main.ml
@@ -29,17 +29,17 @@ let output format context basename =
   in
   Self.result "output to %s" filename;
   let out_channel = open_out filename in
-  output_function out_channel (Build.get_graph context);
+  output_function out_channel (Context.get_graph context);
   close_out out_channel
 
 let main () =
   if not (Self.FromBases.is_empty () &&
           Self.FromFunctionAlarms.is_empty ()) then begin
     (* Create the initial graph  *)
-    let context = Build.create () in
+    let context = Context.create () in
     (* Handle parameters *)
-    Self.UnfoldedBases.iter (Build.unfold_base context);
-    Self.HiddenBases.iter (Build.hide_base context);
+    Self.UnfoldedBases.iter (Context.unfold context);
+    Self.HiddenBases.iter (Context.hide context);
     let depth = Self.DepthLimit.get () in
     (* Add targeted vars to it *)
     let add_var vi =
diff --git a/src/plugins/dive/server_interface.ml b/src/plugins/dive/server_interface.ml
index b17d0b267f3..71a309b3c1e 100644
--- a/src/plugins/dive/server_interface.ml
+++ b/src/plugins/dive/server_interface.ml
@@ -38,7 +38,7 @@ let get_context =
     match !context with
     | Some c -> c
     | None ->
-      let c = Build.create () in
+      let c = Context.create () in
       context := Some c;
       c
 
@@ -146,7 +146,7 @@ struct
   let of_json json =
     let node_key = Data.Jint.of_json json in
     try
-      Build.find_node (get_context ()) node_key
+      Context.find_node (get_context ()) node_key
     with Not_found ->
       Data.failure "no node '%d' in the current graph" node_key
 end
@@ -180,6 +180,7 @@ struct
       "label", Jstring;
       "kind", Jstring;
       "locality", NodeLocality.jtype;
+      "is_root", Jboolean;
       "backward_explored", Jstring;
       "forward_explored", Jstring;
       "writes", Jarray Kernel_ast.KfMarker.jtype;
@@ -238,8 +239,9 @@ end
 (* --- Actions                                                            --- *)
 (* -------------------------------------------------------------------------- *)
 
-let result context =
-  Build.get_graph context, Build.take_last_differences context
+let result context last_root =
+  let diff = Context.take_last_diff context in
+  Context.get_graph context, { diff with last_root }
 
 let finalize' context node_opt =
   begin match node_opt with
@@ -256,7 +258,7 @@ let finalize' context node_opt =
       then
         Build.reduce_to_horizon context horizon node
   end;
-  result context
+  result context node_opt
 
 let finalize context node =
   finalize' context (Some node)
@@ -271,13 +273,13 @@ let () = Request.register ~package
     ~kind:`GET ~name:"graph"
     ~descr:(Markdown.plain "Retrieve the whole graph")
     ~input:(module Data.Junit) ~output:(module Graph)
-    (fun () -> Build.get_graph (get_context ()))
+    (fun () -> Context.get_graph (get_context ()))
 
 let () = Request.register ~package
     ~kind:`EXEC ~name:"clear"
     ~descr:(Markdown.plain "Erase the graph and start over with an empty one")
     ~input:(module Data.Junit) ~output:(module Data.Junit)
-    (fun () -> Build.clear (get_context ()))
+    (fun () -> Context.clear (get_context ()))
 
 let () = Request.register ~package
     ~kind:`EXEC ~name:"add"
@@ -306,7 +308,7 @@ let () = Request.register ~package
       let context = get_context () in
       Build.show context node;
       Build.explore_backward ~depth:1 context node;
-      result context
+      finalize' context None
     end
 
 let () = Request.register ~package
@@ -316,5 +318,5 @@ let () = Request.register ~package
     begin fun node ->
       let context = get_context () in
       Build.hide context node;
-      result context
+      finalize' context None
     end
diff --git a/src/plugins/dive/tests/dive/oracle/assigned_param.dot b/src/plugins/dive/tests/dive/oracle/assigned_param.dot
index a7eacc650c1..198c8cfc1b7 100644
--- a/src/plugins/dive/tests/dive/oracle/assigned_param.dot
+++ b/src/plugins/dive/tests/dive/oracle/assigned_param.dot
@@ -1,22 +1,22 @@
 digraph G {
-  cp1 [label=<w>, shape=box, ];
-  cp2 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<w>, shape=box, style="bold", ];
+  cp3 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp7 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp8 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp9 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp8;cp4;cp1;
-    subgraph cluster_cs_2 { label=<f>; cp6;cp2;
+  subgraph cluster_cs_1 { label=<main>; cp9;cp5;cp2;
+    subgraph cluster_cs_2 { label=<f>; cp7;cp3;
        };
      };
   
-  cp2 -> cp1;
-  cp4 -> cp2;
-  cp6 -> cp2;
-  cp8 -> cp6;
+  cp3 -> cp2;
+  cp5 -> cp3;
+  cp7 -> cp3;
+  cp9 -> cp7;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/callstack_global.dot b/src/plugins/dive/tests/dive/oracle/callstack_global.dot
index f0d3527ffca..82c7a0b0fc6 100644
--- a/src/plugins/dive/tests/dive/oracle/callstack_global.dot
+++ b/src/plugins/dive/tests/dive/oracle/callstack_global.dot
@@ -1,42 +1,42 @@
 digraph G {
-  cp1 [label=<r>, shape=box, ];
-  cp2 [label=<tmp>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp2 [label=<r>, shape=box, style="bold", ];
+  cp3 [label=<tmp>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp4 [label=<tmp_0>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp5 [label=<tmp_0>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp6 [label=<__retres>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp7 [label=<__retres>, shape=box, fillcolor="#EEFFEE", color="#004400",
        style="filled", ];
-  cp8 [label=<__retres>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp9 [label=<__retres>, shape=box, fillcolor="#EEFFEE", color="#004400",
        style="filled", ];
-  cp10 [label=<g>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp11 [label=<g>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp14 [label=<x>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp15 [label=<x>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp16 [label=<x2>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp17 [label=<x2>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp18 [label=<x1>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp19 [label=<x1>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp18;cp16;cp4;cp2;cp1;
-    subgraph cluster_cs_2 { label=<f>; cp6;
+  subgraph cluster_cs_1 { label=<main>; cp19;cp17;cp5;cp3;cp2;
+    subgraph cluster_cs_2 { label=<f>; cp7;
        };
-    subgraph cluster_cs_3 { label=<f>; cp8;
+    subgraph cluster_cs_3 { label=<f>; cp9;
        };
      };
-  subgraph cluster_cs_4 { label=<f>; cp14;
+  subgraph cluster_cs_4 { label=<f>; cp15;
      };
-  subgraph cluster_file_1 { label=<tests/dive/callstack_global.i>; cp10;
+  subgraph cluster_file_1 { label=<tests/dive/callstack_global.i>; cp11;
      };
   
-  cp2 -> cp1;
-  cp4 -> cp1;
-  cp6 -> cp2;
-  cp8 -> cp4;
-  cp10 -> cp6;
-  cp10 -> cp8;
-  cp10 -> cp10;
-  cp14 -> cp10;
-  cp16 -> cp14;
-  cp18 -> cp14;
+  cp3 -> cp2;
+  cp5 -> cp2;
+  cp7 -> cp3;
+  cp9 -> cp5;
+  cp11 -> cp7;
+  cp11 -> cp9;
+  cp11 -> cp11;
+  cp15 -> cp11;
+  cp17 -> cp15;
+  cp19 -> cp15;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/callstack_strategy.dot b/src/plugins/dive/tests/dive/oracle/callstack_strategy.dot
index 2b2f3df4ca3..0ef329150cf 100644
--- a/src/plugins/dive/tests/dive/oracle/callstack_strategy.dot
+++ b/src/plugins/dive/tests/dive/oracle/callstack_strategy.dot
@@ -1,44 +1,44 @@
 digraph G {
-  cp1 [label=<r>, shape=box, ];
-  cp2 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<r>, shape=box, style="bold", ];
+  cp3 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp7 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp8 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp9 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp10 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp11 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp12 [label=<a>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp13 [label=<a>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp14 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp15 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp17 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp18 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
   
-  subgraph cluster_cs_1 { label=<g>; cp4;cp2;cp1;
-    subgraph cluster_cs_4 { label=<f>; cp10;
+  subgraph cluster_cs_1 { label=<g>; cp5;cp3;cp2;
+    subgraph cluster_cs_4 { label=<f>; cp11;
        };
      };
-  subgraph cluster_cs_2 { label=<i>; cp6;
+  subgraph cluster_cs_2 { label=<i>; cp7;
      };
-  subgraph cluster_cs_3 { label=<h>; cp17;cp8;
-    subgraph cluster_cs_6 { label=<f>; cp14;
+  subgraph cluster_cs_3 { label=<h>; cp18;cp9;
+    subgraph cluster_cs_6 { label=<f>; cp15;
        };
      };
-  subgraph cluster_cs_5 { label=<main>; cp12;
+  subgraph cluster_cs_5 { label=<main>; cp13;
      };
   
-  cp2 -> cp1;
-  cp2 -> cp10;
-  cp4 -> cp1;
-  cp6 -> cp2;
-  cp8 -> cp2;
-  cp10 -> cp4;
-  cp12 -> cp6;
-  cp12 -> cp17;
-  cp14 -> cp8;
-  cp17 -> cp14;
+  cp3 -> cp2;
+  cp3 -> cp11;
+  cp5 -> cp2;
+  cp7 -> cp3;
+  cp9 -> cp3;
+  cp11 -> cp5;
+  cp13 -> cp7;
+  cp13 -> cp18;
+  cp15 -> cp9;
+  cp18 -> cp15;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/const.dot b/src/plugins/dive/tests/dive/oracle/const.dot
index 12f16cf13e8..6ea580760fe 100644
--- a/src/plugins/dive/tests/dive/oracle/const.dot
+++ b/src/plugins/dive/tests/dive/oracle/const.dot
@@ -1,29 +1,29 @@
 digraph G {
-  cp1 [label=<res>, shape=box, ];
-  cp2 [label=<__retres>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<res>, shape=box, style="bold", ];
+  cp3 [label=<__retres>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<c>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<c>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<w>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp7 [label=<w>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp8 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp9 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp10 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp11 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp12 [label=<i>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp13 [label=<i>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp12;cp1;
-    subgraph cluster_cs_2 { label=<f>; cp10;cp8;cp6;cp4;cp2;
+  subgraph cluster_cs_1 { label=<main>; cp13;cp2;
+    subgraph cluster_cs_2 { label=<f>; cp11;cp9;cp7;cp5;cp3;
        };
      };
   
-  cp2 -> cp1;
-  cp4 -> cp2;
-  cp6 -> cp2;
-  cp8 -> cp4;
-  cp10 -> cp6;
-  cp12 -> cp8;
-  cp12 -> cp10;
+  cp3 -> cp2;
+  cp5 -> cp3;
+  cp7 -> cp3;
+  cp9 -> cp5;
+  cp11 -> cp7;
+  cp13 -> cp9;
+  cp13 -> cp11;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/exceptional.dot b/src/plugins/dive/tests/dive/oracle/exceptional.dot
index 821e4f9d1ad..a512210f1c4 100644
--- a/src/plugins/dive/tests/dive/oracle/exceptional.dot
+++ b/src/plugins/dive/tests/dive/oracle/exceptional.dot
@@ -1,26 +1,26 @@
 digraph G {
-  cp1 [label=<__retres>, shape=box, ];
-  cp2 [label=<a>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<__retres>, shape=box, style="bold", ];
+  cp3 [label=<a>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<c>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp7 [label=<c>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp8 [label=<0x10000000-0x1fffffff>, shape=box3d, fillcolor="#FFBBBB",
+  cp9 [label=<0x10000000-0x1fffffff>, shape=box3d, fillcolor="#FFBBBB",
        color="#FF0000", style="filled", ];
-  cp10 [label=<*p>, shape=parallelogram, fillcolor="#FFBBBB",
+  cp11 [label=<*p>, shape=parallelogram, fillcolor="#FFBBBB",
         color="#FF0000", style="filled,dotted", ];
-  cp12 [label=<"lorem ipsum">, shape=box3d, fillcolor="#AACCFF",
+  cp13 [label=<"lorem ipsum">, shape=box3d, fillcolor="#AACCFF",
         color="#88AAFF", style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp12;cp10;cp8;cp6;cp4;cp2;cp1;
+  subgraph cluster_cs_1 { label=<main>; cp13;cp11;cp9;cp7;cp5;cp3;cp2;
      };
   
-  cp2 -> cp1;
-  cp4 -> cp1;
-  cp6 -> cp1;
-  cp8 -> cp2;
-  cp10 -> cp4;
-  cp12 -> cp6;
+  cp3 -> cp2;
+  cp5 -> cp2;
+  cp7 -> cp2;
+  cp9 -> cp3;
+  cp11 -> cp5;
+  cp13 -> cp7;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/global.dot b/src/plugins/dive/tests/dive/oracle/global.dot
index 44bf4463e4f..262b981a163 100644
--- a/src/plugins/dive/tests/dive/oracle/global.dot
+++ b/src/plugins/dive/tests/dive/oracle/global.dot
@@ -1,20 +1,20 @@
 digraph G {
-  cp1 [label=<z>, shape=box, ];
-  cp2 [label=<g>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<z>, shape=box, style="bold", ];
+  cp3 [label=<g>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp7 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp6;cp4;cp1;
+  subgraph cluster_cs_1 { label=<main>; cp7;cp5;cp2;
      };
-  subgraph cluster_file_1 { label=<tests/dive/global.i>; cp2;
+  subgraph cluster_file_1 { label=<tests/dive/global.i>; cp3;
      };
   
-  cp2 -> cp1;
-  cp4 -> cp1;
-  cp4 -> cp6;
-  cp6 -> cp2;
+  cp3 -> cp2;
+  cp5 -> cp2;
+  cp5 -> cp7;
+  cp7 -> cp3;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/manydeps.dot b/src/plugins/dive/tests/dive/oracle/manydeps.dot
index fb65b05ce76..7a7b73389b9 100644
--- a/src/plugins/dive/tests/dive/oracle/manydeps.dot
+++ b/src/plugins/dive/tests/dive/oracle/manydeps.dot
@@ -1,60 +1,60 @@
 digraph G {
-  cp1 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp2 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+       style="filled,bold", ];
+  cp4 [label=<t14>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp3 [label=<t14>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp6 [label=<t13>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp5 [label=<t13>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp8 [label=<t12>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp7 [label=<t12>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
-       style="filled", ];
-  cp9 [label=<t11>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
-       style="filled", ];
-  cp11 [label=<t10>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp10 [label=<t11>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+        style="filled", ];
+  cp12 [label=<t10>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp13 [label=<t1>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp14 [label=<t1>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp15 [label=<t9>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp16 [label=<t9>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp17 [label=<t8>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp18 [label=<t8>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp19 [label=<t7>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp20 [label=<t7>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp21 [label=<t6>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp22 [label=<t6>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp23 [label=<t5>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp24 [label=<t5>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp25 [label=<t4>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp26 [label=<t4>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp27 [label=<t3>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp28 [label=<t3>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp29 [label=<t2>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp30 [label=<t2>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp31 [label=<__retres>, shape=box, ];
-  cp32 [label=<*(pt[x])>, shape=parallelogram, fillcolor="#AACCFF",
+  cp32 [label=<__retres>, shape=box, style="bold", ];
+  cp33 [label=<*(pt[x])>, shape=parallelogram, fillcolor="#AACCFF",
         color="#88AAFF", style="filled,dotted", ];
   
-  subgraph cluster_cs_1 { label=<many_writes>; cp1;
+  subgraph cluster_cs_1 { label=<many_writes>; cp2;
      };
-  subgraph cluster_cs_2 { label=<many_values>; cp32;cp31;
+  subgraph cluster_cs_2 { label=<many_values>; cp33;cp32;
      };
-  subgraph cluster_file_1 { label=<tests/dive/manydeps.i>; cp29;cp27;cp25;cp23;cp21;cp19;cp17;cp15;cp13;cp11;cp9;cp7;cp5;cp3;
+  subgraph cluster_file_1 { label=<tests/dive/manydeps.i>; cp30;cp28;cp26;cp24;cp22;cp20;cp18;cp16;cp14;cp12;cp10;cp8;cp6;cp4;
      };
   
-  cp1 -> cp1 [style="bold", ];
-  cp3 -> cp1;
-  cp5 -> cp1;
-  cp7 -> cp1;
-  cp9 -> cp1;
-  cp11 -> cp1;
-  cp13 -> cp1 [style="bold", ];
-  cp15 -> cp1;
-  cp17 -> cp1;
-  cp19 -> cp1;
-  cp21 -> cp1;
-  cp23 -> cp1;
-  cp25 -> cp1;
-  cp27 -> cp1;
-  cp29 -> cp1;
-  cp32 -> cp31;
+  cp2 -> cp2 [style="bold", ];
+  cp4 -> cp2;
+  cp6 -> cp2;
+  cp8 -> cp2;
+  cp10 -> cp2;
+  cp12 -> cp2;
+  cp14 -> cp2 [style="bold", ];
+  cp16 -> cp2;
+  cp18 -> cp2;
+  cp20 -> cp2;
+  cp22 -> cp2;
+  cp24 -> cp2;
+  cp26 -> cp2;
+  cp28 -> cp2;
+  cp30 -> cp2;
+  cp33 -> cp32;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/per_callstack.dot b/src/plugins/dive/tests/dive/oracle/per_callstack.dot
index 28a8c4762d4..22fa39f4a0b 100644
--- a/src/plugins/dive/tests/dive/oracle/per_callstack.dot
+++ b/src/plugins/dive/tests/dive/oracle/per_callstack.dot
@@ -1,50 +1,50 @@
 digraph G {
-  cp1 [label=<w>, shape=box, ];
-  cp2 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<w>, shape=box, style="bold", ];
+  cp3 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp7 [label=<z>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp8 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp9 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp10 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp11 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp12 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp13 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp14 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp15 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp16 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp17 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp18 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp19 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp20 [label=<a>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp21 [label=<a>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp22 [label=<b>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp23 [label=<b>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp24 [label=<c>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp25 [label=<c>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp24;cp22;cp20;cp6;cp4;cp2;cp1;
-    subgraph cluster_cs_2 { label=<f>; cp14;cp8;
+  subgraph cluster_cs_1 { label=<main>; cp25;cp23;cp21;cp7;cp5;cp3;cp2;
+    subgraph cluster_cs_2 { label=<f>; cp15;cp9;
        };
-    subgraph cluster_cs_3 { label=<f>; cp16;cp10;
+    subgraph cluster_cs_3 { label=<f>; cp17;cp11;
        };
-    subgraph cluster_cs_4 { label=<f>; cp18;cp12;
+    subgraph cluster_cs_4 { label=<f>; cp19;cp13;
        };
      };
   
-  cp2 -> cp1;
-  cp4 -> cp1;
-  cp6 -> cp1;
-  cp8 -> cp2;
-  cp10 -> cp4;
-  cp12 -> cp6;
-  cp14 -> cp8;
-  cp16 -> cp10;
-  cp18 -> cp12;
-  cp20 -> cp14;
-  cp22 -> cp16;
-  cp24 -> cp18;
+  cp3 -> cp2;
+  cp5 -> cp2;
+  cp7 -> cp2;
+  cp9 -> cp3;
+  cp11 -> cp5;
+  cp13 -> cp7;
+  cp15 -> cp9;
+  cp17 -> cp11;
+  cp19 -> cp13;
+  cp21 -> cp15;
+  cp23 -> cp17;
+  cp25 -> cp19;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/pointed_param.dot b/src/plugins/dive/tests/dive/oracle/pointed_param.dot
index e146c4a060d..f2713a435f6 100644
--- a/src/plugins/dive/tests/dive/oracle/pointed_param.dot
+++ b/src/plugins/dive/tests/dive/oracle/pointed_param.dot
@@ -1,32 +1,32 @@
 digraph G {
-  cp1 [label=<y>, shape=box, ];
-  cp2 [label=<tmp>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<y>, shape=box, style="bold", ];
+  cp3 [label=<tmp>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<tmp>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<tmp>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<tmp>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp7 [label=<tmp>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp8 [label=<__retres>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp9 [label=<__retres>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp10 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp11 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp12 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp13 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled,dotted", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp12;cp2;cp1;
-    subgraph cluster_cs_2 { label=<f>; cp10;cp4;
-      subgraph cluster_cs_3 { label=<g>; cp6;
-        subgraph cluster_cs_4 { label=<h>; cp8;
+  subgraph cluster_cs_1 { label=<main>; cp13;cp3;cp2;
+    subgraph cluster_cs_2 { label=<f>; cp11;cp5;
+      subgraph cluster_cs_3 { label=<g>; cp7;
+        subgraph cluster_cs_4 { label=<h>; cp9;
            };
          };
        };
      };
   
-  cp2 -> cp1;
-  cp4 -> cp2;
-  cp6 -> cp4;
-  cp8 -> cp6;
-  cp10 -> cp8;
-  cp12 -> cp10;
+  cp3 -> cp2;
+  cp5 -> cp3;
+  cp7 -> cp5;
+  cp9 -> cp7;
+  cp11 -> cp9;
+  cp13 -> cp11;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/pointers_to_local.dot b/src/plugins/dive/tests/dive/oracle/pointers_to_local.dot
index 70a81cb9a48..243f81deb0c 100644
--- a/src/plugins/dive/tests/dive/oracle/pointers_to_local.dot
+++ b/src/plugins/dive/tests/dive/oracle/pointers_to_local.dot
@@ -1,20 +1,20 @@
 digraph G {
-  cp1 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
-       style="filled", ];
   cp2 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+       style="filled,bold", ];
+  cp3 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp5 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp6 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp1;
-    subgraph cluster_cs_4 { label=<f2>; cp5;
+  subgraph cluster_cs_1 { label=<main>; cp2;
+    subgraph cluster_cs_4 { label=<f2>; cp6;
        };
      };
   
-  cp1 -> cp1;
-  cp1 -> cp2;
-  cp1 -> cp5;
-  cp2 -> cp1;
-  cp5 -> cp1;
+  cp2 -> cp2;
+  cp2 -> cp3;
+  cp2 -> cp6;
+  cp3 -> cp2;
+  cp6 -> cp2;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/ranges.dot b/src/plugins/dive/tests/dive/oracle/ranges.dot
index 93374387479..c6e74f511d0 100644
--- a/src/plugins/dive/tests/dive/oracle/ranges.dot
+++ b/src/plugins/dive/tests/dive/oracle/ranges.dot
@@ -1,62 +1,62 @@
 digraph G {
-  cp1 [label=<res>, shape=box, ];
-  cp2 [label=<i>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<res>, shape=box, style="bold", ];
+  cp3 [label=<i>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<f>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<f>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<i0>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp7 [label=<i0>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp8 [label=<i1>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp9 [label=<i1>, shape=box, fillcolor="#EEFFEE", color="#004400",
        style="filled", ];
-  cp10 [label=<i2>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp11 [label=<i2>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp12 [label=<i3>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp13 [label=<i3>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp14 [label=<i4>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp15 [label=<i4>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp16 [label=<i5>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp17 [label=<i5>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp18 [label=<i6>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp19 [label=<i6>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp20 [label=<i7>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp21 [label=<i7>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp22 [label=<f0>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp23 [label=<f0>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp24 [label=<f1>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp25 [label=<f1>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp26 [label=<f2>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp27 [label=<f2>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp28 [label=<f3>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp29 [label=<f3>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp30 [label=<f4>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp31 [label=<f4>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp32 [label=<f5>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp33 [label=<f5>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp34 [label=<f6>, shape=box, fillcolor="#EEFFEE", color="#004400",
+  cp35 [label=<f6>, shape=box, fillcolor="#EEFFEE", color="#004400",
         style="filled", ];
-  cp36 [label=<f7>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp37 [label=<f7>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
   
-  subgraph cluster_cs_1 { label=<main>; cp36;cp34;cp32;cp30;cp28;cp26;cp24;cp22;cp20;cp18;cp16;cp14;cp12;cp10;cp8;cp6;cp4;cp2;cp1;
+  subgraph cluster_cs_1 { label=<main>; cp37;cp35;cp33;cp31;cp29;cp27;cp25;cp23;cp21;cp19;cp17;cp15;cp13;cp11;cp9;cp7;cp5;cp3;cp2;
      };
   
-  cp2 -> cp1;
-  cp4 -> cp1;
-  cp6 -> cp2;
-  cp8 -> cp2;
-  cp10 -> cp2;
-  cp12 -> cp2;
-  cp14 -> cp2;
-  cp16 -> cp2;
-  cp18 -> cp2;
-  cp20 -> cp2;
-  cp22 -> cp4;
-  cp24 -> cp4;
-  cp26 -> cp4;
-  cp28 -> cp4;
-  cp30 -> cp4;
-  cp32 -> cp4;
-  cp34 -> cp4;
-  cp36 -> cp4;
+  cp3 -> cp2;
+  cp5 -> cp2;
+  cp7 -> cp3;
+  cp9 -> cp3;
+  cp11 -> cp3;
+  cp13 -> cp3;
+  cp15 -> cp3;
+  cp17 -> cp3;
+  cp19 -> cp3;
+  cp21 -> cp3;
+  cp23 -> cp5;
+  cp25 -> cp5;
+  cp27 -> cp5;
+  cp29 -> cp5;
+  cp31 -> cp5;
+  cp33 -> cp5;
+  cp35 -> cp5;
+  cp37 -> cp5;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/unfocused_callers.dot b/src/plugins/dive/tests/dive/oracle/unfocused_callers.dot
index ad32ab6c9f1..a76ec08dcb6 100644
--- a/src/plugins/dive/tests/dive/oracle/unfocused_callers.dot
+++ b/src/plugins/dive/tests/dive/oracle/unfocused_callers.dot
@@ -1,30 +1,30 @@
 digraph G {
-  cp1 [label=<x>, shape=box, ];
-  cp2 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<x>, shape=box, style="bold", ];
+  cp3 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp5 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp6 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp7 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp8 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp9 [label=<x>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
   
-  subgraph cluster_cs_1 { label=<g>; cp1;
+  subgraph cluster_cs_1 { label=<g>; cp2;
      };
-  subgraph cluster_cs_2 { label=<f3>; cp2;
+  subgraph cluster_cs_2 { label=<f3>; cp3;
      };
-  subgraph cluster_cs_3 { label=<f2>; cp4;
+  subgraph cluster_cs_3 { label=<f2>; cp5;
      };
-  subgraph cluster_cs_4 { label=<f1>; cp6;
+  subgraph cluster_cs_4 { label=<f1>; cp7;
      };
-  subgraph cluster_cs_5 { label=<main>; cp8;
+  subgraph cluster_cs_5 { label=<main>; cp9;
      };
   
-  cp2 -> cp1;
-  cp4 -> cp1;
-  cp6 -> cp1;
-  cp8 -> cp2;
-  cp8 -> cp4;
-  cp8 -> cp6;
+  cp3 -> cp2;
+  cp5 -> cp2;
+  cp7 -> cp2;
+  cp9 -> cp3;
+  cp9 -> cp5;
+  cp9 -> cp7;
   
   }
\ No newline at end of file
diff --git a/src/plugins/dive/tests/dive/oracle/various.dot b/src/plugins/dive/tests/dive/oracle/various.dot
index 18dee99f035..201055d7fc3 100644
--- a/src/plugins/dive/tests/dive/oracle/various.dot
+++ b/src/plugins/dive/tests/dive/oracle/various.dot
@@ -1,68 +1,68 @@
 digraph G {
-  cp1 [label=<x2>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp2 [label=<x2>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+       style="filled,bold", ];
+  cp3 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp2 [label=<x>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp5 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
        style="filled", ];
-  cp4 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp8 [label=<g>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
        style="filled", ];
-  cp7 [label=<g>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
-       style="filled", ];
-  cp10 [label=<z>, shape=box, ];
-  cp11 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp11 [label=<z>, shape=box, style="bold", ];
+  cp12 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp13 [label=<w>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp14 [label=<w>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp15 [label=<x2>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp16 [label=<x2>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp17 [label=<tmp_0>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp18 [label=<tmp_0>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp20 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp21 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp22 [label=<pf>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
+  cp23 [label=<pf>, shape=box, fillcolor="#AACCFF", color="#88AAFF",
         style="filled", ];
-  cp24 [label=<x2>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp25 [label=<x2>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp27 [label=<f>, shape=box, ];
-  cp30 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
+  cp28 [label=<f>, shape=box, ];
+  cp31 [label=<y>, shape=box, fillcolor="#FFBBBB", color="#FF0000",
         style="filled", ];
-  cp33 [label=<is_nan_or_infinite: \is_finite((float)\mul_double((double)y, (double)2.0))>,
+  cp34 [label=<is_nan_or_infinite: \is_finite((float)\mul_double((double)y, (double)2.0))>,
         fillcolor="#FF0000", color="#FF0000", shape=doubleoctagon,
-        style="filled,bold", ];
-  cp35 [label=<is_nan_or_infinite: \is_finite(\add_float(y, w))>,
+        style="filled,bold,bold", ];
+  cp36 [label=<is_nan_or_infinite: \is_finite(\add_float(y, w))>,
         fillcolor="#FF0000", color="#FF0000", shape=doubleoctagon,
-        style="filled,bold", ];
+        style="filled,bold,bold", ];
   
-  subgraph cluster_cs_1 { label=<f>; cp33;cp4;cp1;
+  subgraph cluster_cs_1 { label=<f>; cp34;cp5;cp2;
      };
-  subgraph cluster_cs_2 { label=<main>; cp35;cp22;cp17;cp13;cp11;cp10;cp2;
-    subgraph cluster_cs_3 { label=<f>; cp20;cp15;
+  subgraph cluster_cs_2 { label=<main>; cp36;cp23;cp18;cp14;cp12;cp11;cp3;
+    subgraph cluster_cs_3 { label=<f>; cp21;cp16;
        };
-    subgraph cluster_cs_4 { label=<f>; cp30;cp24;
+    subgraph cluster_cs_4 { label=<f>; cp31;cp25;
        };
      };
-  subgraph cluster_file_1 { label=<tests/dive/various.i>; cp27;cp7;
+  subgraph cluster_file_1 { label=<tests/dive/various.i>; cp28;cp8;
      };
   
-  cp1 -> cp4;
-  cp2 -> cp1;
-  cp2 -> cp2;
-  cp2 -> cp15;
-  cp2 -> cp24;
-  cp4 -> cp1;
-  cp4 -> cp33;
-  cp7 -> cp2;
-  cp11 -> cp10;
-  cp11 -> cp35;
-  cp13 -> cp10;
-  cp13 -> cp35;
-  cp15 -> cp11;
-  cp15 -> cp20;
-  cp17 -> cp13;
-  cp20 -> cp15;
-  cp22 -> cp17 [color="#00FF00", ];
-  cp24 -> cp17;
-  cp24 -> cp30;
-  cp27 -> cp22;
-  cp30 -> cp24;
+  cp2 -> cp5;
+  cp3 -> cp2;
+  cp3 -> cp3;
+  cp3 -> cp16;
+  cp3 -> cp25;
+  cp5 -> cp2;
+  cp5 -> cp34;
+  cp8 -> cp3;
+  cp12 -> cp11;
+  cp12 -> cp36;
+  cp14 -> cp11;
+  cp14 -> cp36;
+  cp16 -> cp12;
+  cp16 -> cp21;
+  cp18 -> cp14;
+  cp21 -> cp16;
+  cp23 -> cp18 [color="#00FF00", ];
+  cp25 -> cp18;
+  cp25 -> cp31;
+  cp28 -> cp23;
+  cp31 -> cp25;
   
   }
\ No newline at end of file
-- 
GitLab