From bf21b4410770d96e349db359ac13f02c42c58597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 2 Aug 2019 10:40:08 +0200 Subject: [PATCH] [Eva] Auto loop unroll: new strategy to reduce an expression from a condition. Relies on the computation of the mathematical complement of ival. --- .../value/partitioning/auto_loop_unroll.ml | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/src/plugins/value/partitioning/auto_loop_unroll.ml b/src/plugins/value/partitioning/auto_loop_unroll.ml index 384533297e5..37e2b81bbcb 100644 --- a/src/plugins/value/partitioning/auto_loop_unroll.ml +++ b/src/plugins/value/partitioning/auto_loop_unroll.ml @@ -233,6 +233,17 @@ module Make (Abstract: Abstractions.Eva) = struct let (>>) v f = match v with `Value v -> f v | _ -> None let (>>=) v f = match v with Some v -> f v | None -> None + let cvalue_complement typ cvalue = + let open Eval_typ in + match Eval_typ.classify_as_scalar typ with + | Some (TSFloat _ | TSPtr _) | None -> None + | Some (TSInt ik) -> + try + let ival = Cvalue.V.project_ival cvalue in + Ival.complement_int_under ~size:ik.i_bits ~signed:ik.i_signed ival + >> fun ival -> Some (Cvalue.V.inject_ival ival) + with Cvalue.V.Not_based_on_null -> None + (* Reduces the condition "[condition] = [positive]" to a sufficient hypothesis on the value of the expression [expr]: computes a value [v] such that if the expression [expr] evaluates to [v], then [condition] = [positive]. @@ -241,18 +252,33 @@ module Make (Abstract: Abstractions.Eva) = struct and in the given valuation. *) let reduce_to_expr valuation ~expr ~condition ~positive = let state = Abstract.Dom.top in - (* Assumes that the [condition] is [positive]. *) - fst (Eval.reduce ~valuation state condition positive) - >> fun resulting_valuation -> - (* Finds the value of [expr] in the resulting valuation. *) - Valuation.find resulting_valuation expr >> fun record -> - record.value.v >> fun value -> - (* If the value of [expr] is top, no reduction has been performed. *) - if Val.(equal top value) then None - else - (* Otherwise, re-evaluate the condition with the hypothesis that [expr] - evaluates to [value]. If the condition is satisfied, then - [expr] ∈ [value] ⇒ [condition] = [positive]. *) + (* Reduces [expr] by assuming that [condition] is [positive]. *) + let reduce positive = + (* Assumes that [condition] is [positive]. *) + fst (Eval.reduce ~valuation state condition positive) >> fun valuation -> + (* Finds the value of [expr] in the resulting valuation. *) + Valuation.find valuation expr >> fun record -> + record.value.v >> fun value -> + (* If the new value of [expr] is top, no reduction has been performed. *) + if Val.(equal top value) then None else Some (value, record) + in + (* Different strategies whether cvalue is present. *) + match Val.get Main_values.CVal.key with + | Some get_cvalue -> + (* Assumes that [condition] is NOT [positive]. *) + reduce (not positive) >>= fun (value, _record) -> + (* [value] is an over-approximation of the values of [expr] for which + [condition] is NOT positive; its complement is an under-approximation + of the values for which [condition] is positive. *) + let cvalue = get_cvalue value in + cvalue_complement (Cil.typeOf expr) cvalue >>= fun cvalue -> + Some (Val.set Main_values.CVal.key cvalue Val.top) + | None -> + (* Assumes that [condition] is [positive]. Returns an over-approximation + of the values for which [condition] is [positive]. *) + reduce positive >>= fun (value, record) -> + (* Evaluates [condition] with the hypothesis [expr] ∈ [value], to check + whether [expr] ∈ [value] ⇒ [condition] = [positive]. *) let valuation = Valuation.add valuation expr record in fst (Eval.evaluate ~valuation ~reduction:false state condition) >> fun (_valuation, v) -> -- GitLab