diff --git a/src/plugins/value/api/values_request.ml b/src/plugins/value/api/values_request.ml
index 986e4339faf65d14376ebf79b6294ca1d3274a4a..1a6c222f453e37b83ba79221374ae50fb8c55b6d 100644
--- a/src/plugins/value/api/values_request.ml
+++ b/src/plugins/value/api/values_request.ml
@@ -24,6 +24,11 @@ open Server
 open Data
 open Cil_types
 
+module Kmap = Kernel_function.Hashtbl
+module Smap = Cil_datatype.Stmt.Hashtbl
+module CS = Value_types.Callstack
+module CSmap = CS.Hashtbl
+
 module Md = Markdown
 module Jkf = Kernel_ast.Kf
 module Jki = Kernel_ast.Ki
@@ -87,15 +92,119 @@ let probe marker =
   | _ -> Pnone
 
 (* -------------------------------------------------------------------------- *)
-(* --- Domain Utilities                                                   --- *)
+(* --- Stmt Ranking                                                       --- *)
 (* -------------------------------------------------------------------------- *)
 
-module CS = Value_types.Callstack
-module CSmap = CS.Hashtbl
+module Ranking :
+sig
+  val stmt : stmt -> int
+  val kinstr : kinstr -> int
+  val sort : callstack list -> callstack list
+end =
+struct
+
+  class ranker =
+    object(self)
+      inherit Visitor.frama_c_inplace
+
+      val mutable rank = (-1)
+      val rmap = Smap.create 0
+      val fmark = Kmap.create 0
+      val fqueue = Queue.create ()
+
+      method private call kf =
+        if not (Kmap.mem fmark kf) then
+          begin
+            Kmap.add fmark kf () ;
+            Queue.push kf fqueue ;
+          end
+
+      method private newrank s =
+        let r = succ rank in
+        Smap.add rmap s r ;
+        rank <- r ; r
+
+      method! vlval lv =
+        begin
+          try match fst lv with
+            | Var vi -> self#call (Globals.Functions.get vi)
+            | _ -> ()
+          with Not_found -> ()
+        end ; Cil.DoChildren
+
+      method! vstmt_aux s =
+        ignore (self#newrank s) ;
+        Cil.DoChildren
+
+      method compute =
+        match Globals.entry_point () with
+        | kf , _ ->
+          let job kf =
+            ignore (Visitor.(visitFramacKf (self :> frama_c_visitor) kf))
+          in begin
+            job kf ;
+            while not (Queue.is_empty fqueue) do
+              job (Queue.pop fqueue)
+            done
+          end
+        | exception Globals.No_such_entry_point _ -> ()
+
+      method rank s =
+        if rank < 0 then (rank <- 0 ; self#compute) ;
+        try Smap.find rmap s
+        with Not_found -> self#newrank s
+
+    end
+
+  let stmt = let rk = new ranker in rk#rank
+
+  let kinstr = function
+    | Kglobal -> 0
+    | Kstmt s -> stmt s
+
+  let rec ranks (rks : int list) (cs : callstack) : int list =
+    match cs with
+    | [] -> rks
+    | (_,Kglobal)::wcs -> ranks rks wcs
+    | (_,Kstmt s)::wcs -> ranks (stmt s :: rks) wcs
+
+  let order : int list -> int list -> int = Stdlib.compare
+
+  let sort (wcs : callstack list) : callstack list =
+    List.map fst @@
+    List.sort (fun (_,rp) (_,rq) -> order rp rq) @@
+    List.map (fun cs -> cs , ranks [] cs) wcs
+
+end
+
+(* -------------------------------------------------------------------------- *)
+(* --- Domain Utilities                                                   --- *)
+(* -------------------------------------------------------------------------- *)
 
 module Jcallstack = Data.Index(Value_types.Callstack.Map)
     (struct let name = "eva-callstack-id" end)
 
+module Jcallsite : Data.S with type t = Value_types.call_site =
+struct
+  type t = kernel_function * kinstr
+  let jtype = Package.(Jrecord [
+      "fct" , Jkf.jtype ;
+      "stmt" , Jki.jtype ;
+      "rank" , Jnumber ;
+    ])
+  let to_json (kf,ki) = `Assoc [
+      "fct" , Jkf.to_json kf ;
+      "stmt" , Jki.to_json ki ;
+      "rank" , Jint.to_json (Ranking.kinstr ki) ;
+    ]
+  let of_json = function
+    | `Assoc fds ->
+      let kf = Jkf.of_json (List.assoc "fct" fds) in
+      let ki = Jki.of_json (List.assoc "stmt" fds) in
+      (kf,ki)
+    | _ -> failwith "Not a call-site"
+end
+
 module Jtruth : Data.S with type t = truth =
 struct
   type t = truth
@@ -238,7 +347,10 @@ let () = Request.register ~package
     ~descr:(Md.plain "Callstacks for markers")
     ~input:(module Jstmt)
     ~output:(module Jlist(Jcallstack))
-    (fun stmt -> let module A = (val !proxy) in A.callstacks stmt)
+    begin fun stmt ->
+      let module A = (val !proxy) in
+      Ranking.sort (A.callstacks stmt)
+    end
 
 (* -------------------------------------------------------------------------- *)
 (* --- Request getCallstackInfo                                           --- *)
@@ -260,7 +372,7 @@ let () =
       (module Jstring) in
   let set_calls = Request.result getCallstackInfo ~name:"calls"
       ~descr:(Md.plain "Callers site, from last to first")
-      (module Jlist(Jpair(Jkf)(Jki))) in
+      (module Jlist(Jcallsite)) in
   Request.register_sig ~package getCallstackInfo
       ~kind:`GET ~name:"getCallstackInfo"
       ~descr:(Md.plain "Callstack Description")
@@ -269,6 +381,26 @@ let () =
         set_descr rq (Pretty_utils.to_string pretty cs) ;
       end
 
+(* -------------------------------------------------------------------------- *)
+(* --- Request getStmtInfo                                                --- *)
+(* -------------------------------------------------------------------------- *)
+
+let () =
+  let getStmtInfo = Request.signature ~input:(module Jstmt) () in
+  let set_fct = Request.result getStmtInfo ~name:"fct"
+      ~descr:(Md.plain "Englobing function")
+      (module Jkf) in
+  let set_rank = Request.result getStmtInfo ~name:"rank"
+      ~descr:(Md.plain "Global stmt order")
+      (module Jint) in
+  Request.register_sig ~package getStmtInfo
+    ~kind:`GET ~name:"getStmtInfo"
+    ~descr:(Md.plain "Stmt Information")
+    begin fun rq s ->
+      set_fct rq (Kernel_function.find_englobing_kf s) ;
+      set_rank rq (Ranking.stmt s) ;
+    end
+
 (* -------------------------------------------------------------------------- *)
 (* --- Request getProbeInfo                                               --- *)
 (* -------------------------------------------------------------------------- *)
diff --git a/src/plugins/value_types/value_types.mli b/src/plugins/value_types/value_types.mli
index 99589861241eeb1e280acc5f5abee60270ee4f0e..cdd8f86c51b15e072ea718a42cf62740ba5e5143 100644
--- a/src/plugins/value_types/value_types.mli
+++ b/src/plugins/value_types/value_types.mli
@@ -27,8 +27,23 @@ open Cil_types
 
 (* TODO: These types are already defined in Value_util. *)
 type call_site = kernel_function * kinstr
+(** Value call-site.
+    A callsite [(f,p)] represents a call at function [f] invoked
+    {i from} program point [p].
+*)
+
 type callstack = call_site list
-(** Value callstacks, as used e.g. in Db.Value hooks *)
+(** Value callstacks, as used e.g. in Db.Value hooks.
+
+    The head call site [(f,p)] is the most recent one,
+    where current function [f] has been called from program point [p].
+
+    Therefore, the tail call site is expected to be [(main,Kglobal)]
+    where [main] is the global entry point.
+
+    Moreover, given two consecutive call-sites […(_,p);(g,_)…] in a callstack,
+    program point [p] is then expected to live in function [g].
+ *)
 
 module Callsite: Datatype.S_with_collections with type t = call_site
 module Callstack: sig