Skip to content

Commit 16ab1ee

Browse files
committed
CHB: add rewriting with loop counters
1 parent 985e20d commit 16ab1ee

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

CodeHawk/CHB/bchlib/bCHLocationInvariant.ml

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -231,38 +231,34 @@ let get_variable_equality_variables (lineq: linear_equality_t) =
231231
[]
232232

233233

234-
let linear_equality_get_expr e v =
234+
(* Note: the signature of this function should be changed into a result
235+
type; the function should not raise an exception.
236+
*)
237+
let linear_equality_get_expr (lineq: linear_equality_t) (v: variable_t): xpr_t option =
235238
let make_factor c f =
236239
if c#equal numerical_one then
237240
XVar f
238241
else
239242
XOp (XMult, [num_constant_expr c; XVar f]) in
240243
try
241-
let (c, _f) = List.find (fun (_, f) -> f#equal v) e.leq_factors in
242-
let xfactors = List.filter (fun (_, f) -> not (f#equal v)) e.leq_factors in
244+
let (c, _f) = List.find (fun (_, f) -> f#equal v) lineq.leq_factors in
245+
let xfactors = List.filter (fun (_, f) -> not (f#equal v)) lineq.leq_factors in
243246
let x =
244247
if c#equal numerical_one then
245248
List.fold_left (fun a (c,f) -> XOp (XPlus, [a; make_factor c#neg f]))
246-
(num_constant_expr e.leq_constant) xfactors
249+
(num_constant_expr lineq.leq_constant) xfactors
247250
else if c#equal numerical_one#neg then
248251
List.fold_left (fun a (c,f) -> XOp (XPlus, [a; make_factor c f]))
249-
(num_constant_expr e.leq_constant#neg) xfactors
252+
(num_constant_expr lineq.leq_constant#neg) xfactors
250253
else
251-
raise
254+
raise
252255
(BCH_failure
253-
(LBLOCK [
254-
STR "Case with higher coefficients not yet handled: ";
255-
linear_equality_to_pretty e])) in
256-
simplify_xpr x
256+
(LBLOCK [STR "Case with higher coefficients not yet handled: ";
257+
linear_equality_to_pretty lineq])) in
258+
Some (simplify_xpr x)
257259
with
258-
Not_found ->
259-
raise
260-
(BCH_failure
261-
(LBLOCK [
262-
STR "Variable ";
263-
v#toPretty;
264-
STR " not found in linear equality ";
265-
linear_equality_to_pretty e]))
260+
| Not_found ->
261+
None
266262

267263

268264
let linear_equality_compare e1 e2 =
@@ -416,6 +412,13 @@ object (self:'a)
416412
is_variable_equality lineq
417413
| _ -> false
418414

415+
method is_loopcounter_equality =
416+
match fact with
417+
| RelationalFact lineq ->
418+
List.exists (fun (_, f) -> List.mem "lc" f#getName#getAttributes)
419+
lineq.leq_factors
420+
| _ -> false
421+
419422
method get_variable_equality_variables =
420423
match fact with
421424
| RelationalFact lineq when is_variable_equality lineq ->
@@ -425,6 +428,14 @@ object (self:'a)
425428
(BCH_failure
426429
(LBLOCK [STR "Not a variable-equality: "; self#toPretty]))
427430

431+
method get_var_loopcounter_expr (v: variable_t): xpr_t option =
432+
if self#is_loopcounter_equality then
433+
match fact with
434+
| RelationalFact lineq -> linear_equality_get_expr lineq v
435+
| _ -> None
436+
else
437+
None
438+
428439
method is_smaller (other:'a) =
429440
match (fact, other#get_fact) with
430441
| (NonRelationalFact (_, i1), NonRelationalFact (_, i2)) -> is_smaller_nrv i1 i2
@@ -643,7 +654,13 @@ object (self)
643654
| NonRelationalFact (w, FSymbolicExpr x) when w#equal v -> Some x
644655
| _ -> None) None (self#get_var_facts v)
645656

646-
method rewrite_expr (x:xpr_t) =
657+
method private get_var_loopcounter_expr (v: variable_t): xpr_t option =
658+
List.fold_left (fun acc inv ->
659+
match acc with
660+
| Some _ -> acc
661+
| _ -> inv#get_var_loopcounter_expr v) None self#get_facts
662+
663+
method rewrite_expr ?(loopcounter=false) (x:xpr_t) =
647664
let subst1 v =
648665
if self#is_constant v then
649666
XConst (IntConst (self#get_constant v))
@@ -662,7 +679,19 @@ object (self)
662679
match self#get_external_exprs v with
663680
| [] -> XVar v
664681
| x :: _tl -> x in
665-
let x1 = simplify_xpr (substitute_expr subst1 x) in
682+
let subst_lc v =
683+
(* For now only user-designated loop counter variables are annotated
684+
with the lc attribute. Loop counter does not refer to the engine
685+
loop-counter variable. *)
686+
if loopcounter && (not (List.mem "lc" v#getName#getAttributes)) then
687+
let eq = self#get_var_loopcounter_expr v in
688+
match eq with
689+
| Some x -> x
690+
| _ -> XVar v
691+
else
692+
XVar v in
693+
let x0 = simplify_xpr (substitute_expr subst_lc x) in
694+
let x1 = simplify_xpr (substitute_expr subst1 x0) in
666695
let x2 = simplify_xpr (substitute_expr subst2 x1) in
667696
let x3 = simplify_xpr (substitute_expr subst3 x2) in
668697
let x4 = simplify_xpr (substitute_expr subst4 x3) in
@@ -920,6 +949,9 @@ object (self)
920949
| NonRelationalFact (w, FSymbolicExpr _) when v#equal w -> true
921950
| _ -> false) false (self#get_var_facts v)
922951

952+
method has_loop_counter_equality: bool =
953+
List.exists (fun inv -> inv#is_loopcounter_equality) self#get_facts
954+
923955
method write_xml (node:xml_element_int) =
924956
let invs = List.sort Stdlib.compare (H.fold (fun k _ a -> k::a) facts []) in
925957
if (List.length invs) > 0 then
@@ -1134,7 +1166,9 @@ object (self)
11341166
self#add iaddr (TestVarEquality (tvar,tval,taddr,jaddr))
11351167

11361168
method add_lineq (iaddr:string) (nc:numerical_constraint_t) =
1137-
self#add iaddr (RelationalFact (numerical_constraint_to_linear_equality nc))
1169+
let lineq = numerical_constraint_to_linear_equality nc in
1170+
let fact = RelationalFact lineq in
1171+
self#add iaddr fact
11381172

11391173
method get_location_invariant (iaddr:string) =
11401174
match invariants#get iaddr with

CodeHawk/CHB/bchlib/bCHLocationInvariant.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ val numerical_constraint_to_linear_equality:
4646

4747
val linear_equality_get_vars: linear_equality_t -> variable_t list
4848

49-
val linear_equality_get_expr: linear_equality_t -> variable_t -> xpr_t
49+
val linear_equality_get_expr: linear_equality_t -> variable_t -> xpr_t option
5050

5151
val mk_invariant_io:
5252
xml_element_int option -> vardictionary_int -> string -> invariant_io_int

0 commit comments

Comments
 (0)