diff --git a/src/plugins/region/analysis.ml b/src/plugins/region/analysis.ml index 0a1ca081d49cba614a5ed3aee4a1c57db6dbde3e..58d131f5b4f2d79901a37ef4612c0e8ab02492a9 100644 --- a/src/plugins/region/analysis.ml +++ b/src/plugins/region/analysis.ml @@ -53,9 +53,19 @@ let find = STATE.find let get kf = try STATE.find kf with Not_found -> - Options.feedback ~ontty:`Transient "Function %a" Kernel_function.pretty kf ; + Options.feedback ~ontty:`Transient "Function %a…" Kernel_function.pretty kf ; let domain = Code.domain kf in - STATE.add kf domain ; domain + STATE.add kf domain ; + Options.result "@[<v 2>Function %a:%t@]@." + Kernel_function.pretty kf + begin fun fmt -> + Memory.iter domain.map + begin fun r m -> + Format.pp_print_newline fmt () ; + Memory.pp_region fmt r m ; + end + end ; + domain let compute kf = ignore @@ get kf diff --git a/src/plugins/region/code.ml b/src/plugins/region/code.ml index 1a39ee97ab0857dece35d86e4b1924d4be573a00..2c1b468afd101a66f150be267897c44babe6bad4 100644 --- a/src/plugins/region/code.ml +++ b/src/plugins/region/code.ml @@ -83,7 +83,7 @@ and exp (m: map) (s:stmt) (e:exp) : node option = | BinOp((PlusPI|MinusPI),p,k,_) -> value m s k ; let r = pointer m s p in - Memory.shift m r (Exp(s,e)) ; + Memory.shift m r (Exp(s,p)) ; Some r | BinOp(_,a,b,_) -> diff --git a/src/plugins/region/memory.ml b/src/plugins/region/memory.ml index f430fea663068a37f81b4d34f7bcbfeee8ff3b3e..4ecd531ad6626c6026ba22f696656e824b105c57 100644 --- a/src/plugins/region/memory.ml +++ b/src/plugins/region/memory.ml @@ -54,6 +54,26 @@ type map = { mutable index: node Vmap.t ; } +(* -------------------------------------------------------------------------- *) +(* --- Accessors --- *) +(* -------------------------------------------------------------------------- *) + +let sizeof = function Blob -> 0 | Cell(s,_) | Compound(s,_) -> s +let points_to = function Blob | Compound _ -> None | Cell(_,p) -> p +let ranges = function Blob | Cell _ -> [] | Compound(_,R rs) -> rs + +let types (m : region) : typ list = + let pool = ref Typ.Set.empty in + let add acs = + pool := Typ.Set.add (Cil.unrollType @@ Access.typeof acs) !pool in + Access.Set.iter add m.reads ; + Access.Set.iter add m.writes ; + Typ.Set.elements !pool + +(* -------------------------------------------------------------------------- *) +(* --- Printers --- *) +(* -------------------------------------------------------------------------- *) + let pp_node fmt (n : node) = Format.fprintf fmt "R%04x" @@ Store.id n let pp_layout fmt = function @@ -61,12 +81,28 @@ let pp_layout fmt = function | Cell(s,None) -> Format.fprintf fmt "<%04d>" s | Cell(s,Some n) -> Format.fprintf fmt "<%04d>(*%a)" s pp_node n | Compound(s,rg) -> - Format.fprintf fmt "@[<hov 2>{%04d" s ; + Format.fprintf fmt "@[<hv 0>{%04d" s ; Ranges.iteri (fun (rg : range) -> Format.fprintf fmt "@ | %a: %a" Ranges.pp_range rg pp_node rg.data ) rg ; - Format.fprintf fmt " }@]" + Format.fprintf fmt "@ }@]" + +let pp_region fmt (n: node) (m: region) = + begin + let acs r s = if Access.Set.is_empty s then '-' else r in + Format.fprintf fmt "@[<hov 2>%a: %c%c%c" pp_node n + (acs 'R' m.reads) (acs 'W' m.writes) (acs 'A' m.shifts) ; + List.iter (Format.fprintf fmt "@ (%a)" Typ.pretty) (types m) ; + List.iter (Format.fprintf fmt "@ %a" Varinfo.pretty) m.roots ; + if Options.debug_atleast 1 then + begin + Access.Set.iter (Format.fprintf fmt "@ R:%a" Access.pretty) m.reads ; + Access.Set.iter (Format.fprintf fmt "@ W:%a" Access.pretty) m.writes ; + Access.Set.iter (Format.fprintf fmt "@ A:%a" Access.pretty) m.shifts ; + end ; + Format.fprintf fmt "@ %a ;@]" pp_layout m.layout ; + end (* -------------------------------------------------------------------------- *) (* --- Constructors --- *) @@ -82,10 +118,6 @@ let copy m = { index = m.index ; } -let sizeof = function Blob -> 0 | Cell(s,_) | Compound(s,_) -> s -let points_to = function Blob | Compound _ -> None | Cell(_,p) -> p -let ranges = function Blob | Cell _ -> [] | Compound(_,R rs) -> rs - let empty = { parents = [] ; roots = [] ; @@ -242,8 +274,8 @@ let merge_region (m: map) (q: queue) (a : region) (b : region) : region = { parents = nodes m (Store.bag a.parents b.parents) ; roots = Store.bag a.roots b.roots ; reads = Access.Set.union a.reads b.reads ; - writes = Access.Set.union a.reads b.writes ; - shifts = Access.Set.union a.reads b.shifts ; + writes = Access.Set.union a.writes b.writes ; + shifts = Access.Set.union a.shifts b.shifts ; layout = merge_layout m q a.layout b.layout ; } diff --git a/src/plugins/region/memory.mli b/src/plugins/region/memory.mli index 01d1f63e3afabc47c8966098304922db95b8c093..f3a03a5417c23ff000d783fe8ad3ac7a3693ed00 100644 --- a/src/plugins/region/memory.mli +++ b/src/plugins/region/memory.mli @@ -41,9 +41,11 @@ type region = private { val sizeof : layout -> int val points_to : layout -> node option val ranges : layout -> node Ranges.range list +val types : region -> typ list val pp_node : Format.formatter -> node -> unit val pp_layout : Format.formatter -> layout -> unit +val pp_region : Format.formatter -> node -> region -> unit type map diff --git a/src/plugins/region/services.ml b/src/plugins/region/services.ml index 8f1e8f634a993ceea1815defa6c9c5507ab2747e..b14918e442d92eb98bbdd10c74016f16e8f07f73 100644 --- a/src/plugins/region/services.ml +++ b/src/plugins/region/services.ml @@ -71,12 +71,19 @@ struct "sizeof", Jnumber ; "ranges", Ranges.jtype ; "pointsTo", NodeOpt.jtype ; + "reads", Jboolean ; + "writes", Jboolean ; + "shifts", Jboolean ; + "types", Jarray Kernel_ast.Marker.jtype ; ] let roots_to_json vs = let open Cil_types in Json.of_list @@ List.map (fun v -> Json.of_string v.vname) vs + let typ_to_json typ = + Kernel_ast.Marker.to_json @@ Printer_tag.PType typ + let to_json (m: Memory.region) = Json.of_fields [ "roots", roots_to_json m.roots ; @@ -84,6 +91,10 @@ struct "sizeof", Json.of_int @@ Memory.sizeof m.layout ; "ranges", Ranges.to_json @@ Memory.ranges m.layout ; "pointsTo", NodeOpt.to_json @@ Memory.points_to m.layout ; + "reads", Json.of_bool @@ not @@ Access.Set.is_empty m.reads ; + "writes", Json.of_bool @@ not @@ Access.Set.is_empty m.writes ; + "shifts", Json.of_bool @@ not @@ Access.Set.is_empty m.shifts ; + "types", Json.of_list @@ List.map typ_to_json @@ Memory.types m ; ] let of_json _ = failwith "Region.Layout.of_json" end