From 2d0e69c191405135d29f0ada2d0d14d00f05acf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr>
Date: Tue, 11 Jul 2023 10:04:10 +0200
Subject: [PATCH] [Eva] Uses new callstack type in Eva_perf.

---
 .../abstract_interp/eva_types.ml              | 11 +++---
 .../abstract_interp/eva_types.mli             |  1 +
 src/plugins/eva/Eva.mli                       |  2 +
 src/plugins/eva/types/callstack.mli           |  2 +
 src/plugins/eva/utils/eva_perf.ml             | 37 +++++++++----------
 src/plugins/eva/utils/eva_perf.mli            |  4 +-
 src/plugins/eva/utils/eva_utils.ml            |  8 ++--
 7 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/src/kernel_services/abstract_interp/eva_types.ml b/src/kernel_services/abstract_interp/eva_types.ml
index aa8a24814b9..6d07a666499 100644
--- a/src/kernel_services/abstract_interp/eva_types.ml
+++ b/src/kernel_services/abstract_interp/eva_types.ml
@@ -126,13 +126,14 @@ struct
 
   (* Conversion *)
 
-  let to_legacy cs =
+  let to_kf_list cs = cs.entry_point :: List.rev_map fst cs.stack
+  let to_stmt_list cs = List.rev_map snd cs.stack
+
+  let to_call_list cs =
     let l =
       List.rev_map (fun (kf, stmt) -> (kf, Cil_types.Kstmt stmt)) cs.stack
     in
-    List.rev ((cs.entry_point, Cil_types.Kglobal) :: l)
+    (cs.entry_point, Cil_types.Kglobal) :: l
 
-  let to_kf_list cs = cs.entry_point :: List.rev_map fst cs.stack
-
-  let to_stmt_list cs = List.rev_map snd cs.stack
+  let to_legacy cs = List.rev (to_call_list cs)
 end
diff --git a/src/kernel_services/abstract_interp/eva_types.mli b/src/kernel_services/abstract_interp/eva_types.mli
index bffc1c71b20..57944aea8df 100644
--- a/src/kernel_services/abstract_interp/eva_types.mli
+++ b/src/kernel_services/abstract_interp/eva_types.mli
@@ -54,6 +54,7 @@ sig
   val to_legacy : t -> Value_types.callstack
   val to_kf_list : t -> Cil_types.kernel_function list
   val to_stmt_list : t -> Cil_types.stmt list
+  val to_call_list : t -> (Cil_types.kernel_function * Cil_types.kinstr) list
 end
 [@@alert db_deprecated
     "Eva_types is only provided for compatibility reason and will be removed \
diff --git a/src/plugins/eva/Eva.mli b/src/plugins/eva/Eva.mli
index 45bcd42e26f..7cf6b0097b1 100644
--- a/src/plugins/eva/Eva.mli
+++ b/src/plugins/eva/Eva.mli
@@ -168,6 +168,8 @@ module Callstack: sig
   (** Gives the list of call statements from the bottom to the top of the callstack (i.e. reverse order of the call stack). *)
   val to_stmt_list : t -> Cil_types.stmt list
 
+  val to_call_list : t -> (Cil_types.kernel_function * Cil_types.kinstr) list
+
 end
 
 module Results: sig
diff --git a/src/plugins/eva/types/callstack.mli b/src/plugins/eva/types/callstack.mli
index 9476b2a7386..6460b8d5bc2 100644
--- a/src/plugins/eva/types/callstack.mli
+++ b/src/plugins/eva/types/callstack.mli
@@ -73,6 +73,8 @@ val to_kf_list : t -> Cil_types.kernel_function list
 (** Gives the list of call statements from the bottom to the top of the callstack (i.e. reverse order of the call stack). *)
 val to_stmt_list : t -> Cil_types.stmt list
 
+val to_call_list : t -> (Cil_types.kernel_function * Cil_types.kinstr) list
+
 [@@@ api_end]
 
 val pretty_debug : Format.formatter -> t -> unit
diff --git a/src/plugins/eva/utils/eva_perf.ml b/src/plugins/eva/utils/eva_perf.ml
index 1efc3d7c32a..e8bd382190e 100644
--- a/src/plugins/eva/utils/eva_perf.ml
+++ b/src/plugins/eva/utils/eva_perf.ml
@@ -218,7 +218,8 @@ module Imperative_callstack_trie(M:sig type t val default:unit -> t end) = struc
           n
       in find_subtree subnode.subtree b (Some subnode)
 
-  let find_subtree t callstack = find_subtree t (List.rev callstack) None
+  let find_subtree t callstack =
+    find_subtree t (Callstack.to_call_list callstack) None
 
   let find t callstack = (find_subtree t callstack).self
 
@@ -285,25 +286,25 @@ let display fmt =
   end
 ;;
 
-let caller_callee_callinfo = function
-  | (callee_kf,_)::(caller_kf,_)::_ ->
-    (let caller_flat = Kernel_function.Hashtbl.find flat caller_kf in
-     try
+let caller_callee_callinfo callstack =
+  match Callstack.last_caller callstack with
+  | Some caller_kf ->
+    let callee_kf = Callstack.top_kf callstack in
+    let caller_flat = Kernel_function.Hashtbl.find flat caller_kf in
+    (try
        Kernel_function.Hashtbl.find caller_flat.called_functions callee_kf
      with Not_found ->
        let call_info = Call_info.create() in
        Kernel_function.Hashtbl.add caller_flat.called_functions callee_kf call_info;
        call_info)
-  | [_] -> Call_info.main
-  | [] -> assert false
+  | None -> Call_info.main
 ;;
 
 let start_doing_perf callstack =
   if Parameters.ValShowPerf.get()
   then begin
     let time = Sys.time() in
-    assert (callstack != []);
-    let kf = fst (List.hd callstack) in
+    let kf = Callstack.top_kf callstack in
     let flat_info =
       try Kernel_function.Hashtbl.find flat kf
       with Not_found ->
@@ -325,7 +326,7 @@ let stop_doing_perf callstack =
   if Parameters.ValShowPerf.get()
   then begin
     let time = Sys.time() in
-    let kf = fst (List.hd callstack) in
+    let kf = Callstack.top_kf callstack in
     let flat_info = Kernel_function.Hashtbl.find flat kf in
     Call_info.after_call flat_info.call_info time;
     let node = Perf_by_callstack.find perf callstack in
@@ -365,14 +366,13 @@ let stack_flamegraph = ref []
 
 (* pretty-prints the functions in a Value callstack, starting by main (i.e.
    in reverse order). *)
-let pretty_callstack oc l =
+let pretty_callstack oc callstack =
   let rec aux oc = function
     | [] -> () (* does not happen in theory *)
-    | [main, _] -> Printf.fprintf oc "%s" (Kernel_function.get_name main)
-    | (f, _) :: q ->
-      Printf.fprintf oc "%a;%s" aux q (Kernel_function.get_name f)
+    | [main] -> Printf.fprintf oc "%s" (Kernel_function.get_name main)
+    | kf :: q -> Printf.fprintf oc "%s;%a" (Kernel_function.get_name kf) aux q
   in
-  aux oc l
+  aux oc (Callstack.to_kf_list callstack)
 
 (* update the [self_total_time] information for the function being analyzed,
    assuming that the current time is [time] *)
@@ -385,9 +385,8 @@ let update_self_total_time time =
 
 (* called when a new function is being analyzed *)
 let start_doing_flamegraph callstack =
-  match callstack with
-  | [] -> assert false
-  | [_] ->
+  match callstack.Callstack.stack with
+  | [] ->
     (* Analysis of main *)
     if not (Parameters.ValPerfFlamegraphs.is_empty ()) then begin
       let file = Parameters.ValPerfFlamegraphs.get () in
@@ -401,7 +400,7 @@ let start_doing_flamegraph callstack =
           (Printexc.to_string e);
         oc_flamegraph := None (* to be on the safe side  *)
     end
-  | _ :: _ :: _ ->
+  | _ :: _ ->
     if !oc_flamegraph <> None then
       (* Flamegraphs are being computed. Update time spent in current function
          so far, then push a slot for the analysis of the new function *)
diff --git a/src/plugins/eva/utils/eva_perf.mli b/src/plugins/eva/utils/eva_perf.mli
index 2c0a2edd183..cb4a2af9a1e 100644
--- a/src/plugins/eva/utils/eva_perf.mli
+++ b/src/plugins/eva/utils/eva_perf.mli
@@ -22,11 +22,11 @@
 
 (** Call [start_doing] when starting analyzing a new function. The new
     function is on the top of the call stack.*)
-val start_doing: Value_types.callstack -> unit
+val start_doing: Callstack.t -> unit
 
 (** Call [start_doing] when finishing analyzing a function. The
     function must still be on the top of the call stack. *)
-val stop_doing: Value_types.callstack -> unit
+val stop_doing: Callstack.t -> unit
 
 (** Display a complete summary of performance informations. Can be
     called during the analysis. *)
diff --git a/src/plugins/eva/utils/eva_utils.ml b/src/plugins/eva/utils/eva_utils.ml
index c6b504fd2f4..5982ade6c13 100644
--- a/src/plugins/eva/utils/eva_utils.ml
+++ b/src/plugins/eva/utils/eva_utils.ml
@@ -30,13 +30,13 @@ let clear_call_stack () =
   match !current_callstack with
   | None -> ()
   | Some cs ->
-    Eva_perf.stop_doing (Callstack.to_legacy cs);
+    Eva_perf.stop_doing cs;
     current_callstack := None
 
 let set_call_stack cs =
   assert (!current_callstack = None);
   current_callstack := Some cs;
-  Eva_perf.start_doing (Callstack.to_legacy cs)
+  Eva_perf.start_doing cs
 
 let current_call_stack_opt () = !current_callstack
 
@@ -57,11 +57,11 @@ let legacy_call_stack () =
 let push_call_stack kf stmt =
   let cs = current_call_stack () in
   current_callstack := Some (Callstack.push kf stmt cs);
-  Eva_perf.start_doing (Callstack.to_legacy cs)
+  Eva_perf.start_doing cs
 
 let pop_call_stack () =
   let cs = current_call_stack () in
-  Eva_perf.stop_doing (Callstack.to_legacy cs);
+  Eva_perf.stop_doing cs;
   current_callstack := Callstack.pop cs
 
 let pp_callstack fmt =
-- 
GitLab