From 41f129a2a66fc09c1e0b7bb8056231aa6310a565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 9 Oct 2024 10:55:16 +0200 Subject: [PATCH] [Eva] In offsetmaps, rewrites some functions to share more code. Uses [fold_between] and [Base.range_validity]; removes [clip_by_validity]. --- .../abstract_interp/offsetmap.ml | 94 ++++++++----------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/src/kernel_services/abstract_interp/offsetmap.ml b/src/kernel_services/abstract_interp/offsetmap.ml index 2c3099a0fe..a04bb8fabe 100644 --- a/src/kernel_services/abstract_interp/offsetmap.ml +++ b/src/kernel_services/abstract_interp/offsetmap.ml @@ -510,11 +510,11 @@ module Make / \ iter f t = f n1; fn0; f n2; n1 n2 *) - let fold_offset f o t acc = + let fold_offset f ~offset t acc = if t = Empty then acc else - let o, n, z = leftmost_child o End t in + let o, n, z = leftmost_child offset End t in let rec aux_fold o t z pre = match t with | Empty -> pre @@ -528,7 +528,7 @@ module Make aux_fold o n z acc ;; - let fold f t = fold_offset f Integer.zero t + let fold = fold_offset ~offset:Integer.zero ;; let iter_offset f o t = @@ -1722,47 +1722,6 @@ module Make let update_itv = update_itv_with_rem ~rem:Rel.zero ~once:false - (* This should be in Int_Intervals, but is currently needed here. - Returns an interval with reversed bounds when the intersection is empty. *) - let clip_by_validity = function - | Base.Empty | Base.Invalid -> - (fun _-> Int.one, Int.zero (* reversed interval -> no intersection*)) - | Base.Known (min, max) - | Base.Unknown (min, _, max) -> - (fun (min', max') -> Integer.max min min', Integer.min max max') - | Base.Variable variable_v -> - (fun (min', max') -> Integer.max Int.zero min', - Integer.min variable_v.Base.max_alloc max') - - (** This function does a weak update of the entire [offsm], by adding the - topification of [v]. The parameter [validity] is respected, and so is the - current size of [offsm]: each interval already present in [offsm] and valid - is overwritten. Interval already present but not valid are bound to - [V.bottom]. - This function used to write bottom on non-valid locations, but this was - unnecessary as values on non-valid locations should never be accessed - anyway. *) - (* TODO: this function should also be written as a call to fold_between *) - let update_imprecise_everywhere ~validity o v offsm = - let v = V.topify_with_origin o v in - if Base.Validity.equal validity Base.Invalid then - `Bottom - else - let clip = clip_by_validity validity in - let r = fold - (fun itv (bound_v, _, _) acc -> - let new_v = V.topify_with_origin o (V.join bound_v v) in - let new_min, new_max = clip itv in - if new_min <=~ new_max then (* [min..max] and validity intersect *) - append_basic_itv ~min:new_min ~max:new_max ~v:new_v acc - else - acc - ) offsm m_empty - in - `Value r - ;; - - (** Update a set of intervals in a given rangemap all offsets starting from mn ending in mx must be updated with value v, every period *) let update_itvs ~exact ~mn ~mx ~period ~size v curr_off tree = @@ -1961,7 +1920,7 @@ module Make | Node(_, _, Empty, _, Empty, _, _, v', _) -> V.equal v v' | _ -> false - let fold_between ?(direction=`LTR) ~entire (imin, imax) f t acc = + let fold_between_offset ?(direction=`LTR) ~entire (imin, imax) f ~offset t acc = let rec aux curr_off t acc = match t with | Empty -> acc | Node (max, offl, subl, offr, subr, rem, modu, v, _) -> @@ -1998,8 +1957,10 @@ module Make | `LTR -> acc_right (acc_middle (acc_left acc)) | `RTL -> acc_left (acc_middle (acc_right acc)) in - aux Integer.zero t acc - ;; + aux offset t acc + + let fold_between = fold_between_offset ~offset:Integer.zero + (* weak validity should be handled caller *) let paste_slice_itv ~exact from stop start_dest to_ = @@ -2189,6 +2150,26 @@ module Make let bounds = bounds_offset Int.zero m in find_imprecise_between bounds m + (** This function does a weak update of the entire [offsm], by adding the + topification of [v]. The parameter [validity] is respected, and so is the + current size of [offsm]: each interval already present in [offsm] and valid + is overwritten. Interval already present but not valid are bound to + [V.bottom]. + This function used to write bottom on non-valid locations, but this was + unnecessary as values on non-valid locations should never be accessed + anyway. *) + let update_imprecise_everywhere ~validity o v offsm = + match Base.valid_range validity with + | Invalid_range -> `Bottom + | Valid_range None -> `Value offsm + | Valid_range (Some itv) -> + let v = V.topify_with_origin o v in + let topify (min, max) (bound_v, _, _) acc = + let new_v = V.topify_with_origin o (V.join bound_v v) in + append_basic_itv ~min ~max ~v:new_v acc + in + `Value (fold_between ~entire:false itv topify offsm m_empty) + let clear_caches () = List.iter (fun f -> f ()) !clear_caches_ref end @@ -2624,7 +2605,7 @@ module Int_Intervals = struct let co, i = Int_Intervals_Map.diff (co1, i1) coi2' in normalize_itv co i - let fold f m acc = + let generic_fold ~fold_offset f m acc = match m with | Bottom -> acc | Top -> raise Error_Top @@ -2632,7 +2613,14 @@ module Int_Intervals = struct let aux_itv itv (v, _, _) acc = if v then f itv acc else acc in - Int_Intervals_Map.fold_offset aux_itv curr_off i acc + fold_offset aux_itv ~offset:curr_off i acc + + let fold f m acc = + generic_fold ~fold_offset:Int_Intervals_Map.fold_offset f m acc + + let fold_between ~entire itv f m acc = + let fold_offset = Int_Intervals_Map.fold_between_offset ~entire itv in + generic_fold ~fold_offset f m acc (* Could be slightly improved *) let inject l = @@ -2810,16 +2798,14 @@ module Make_bitwise(V: sig try match Base.valid_range validity with | Base.Invalid_range -> `Bottom - | Base.Valid_range None -> (* empty validity *) `Value m - | Base.Valid_range (Some _) -> - let clip = clip_by_validity validity in + | Base.Valid_range None -> `Value m (* empty validity *) + | Base.Valid_range (Some itv) -> let aux_itv itv m = - let itv = clip itv in if Int.le (fst itv) (snd itv) then add ~exact itv (v_size_mod v) m else m in - `Value (Int_Intervals.fold aux_itv itvs m) + `Value (Int_Intervals.fold_between ~entire:false itv aux_itv itvs m) with Error_Top -> update_imprecise_everywhere ~validity Origin.(current Misalign_write) v m -- GitLab