Skip to content

Commit f878d05

Browse files
committed
CHB: incorporate loop counters in result rewriting
1 parent 0816cd8 commit f878d05

File tree

4 files changed

+100
-9
lines changed

4 files changed

+100
-9
lines changed

CodeHawk/CHB/bchlib/bCHFloc.ml

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,32 @@ object (self)
16091609
TR.tfold_default BCHBCTypeUtil.is_pointer false (self#get_xpr_type y) in
16101610
let default () = self#convert_xpr_offsets ~xtype ~size x in
16111611
match x with
1612+
| XOp (XPlus, [y; XOp (XMult, [XConst (IntConst n); XVar v])]) ->
1613+
let _ =
1614+
log_diagnostics_result
1615+
~msg:(p2s self#l#toPretty)
1616+
~tag:"xpr_to_cxpr:scaled expr"
1617+
__FILE__ __LINE__
1618+
["y: " ^ (x2s y);
1619+
"var: " ^ (p2s v#toPretty);
1620+
"n: " ^ n#toString] in
1621+
let gloc_o = memmap#xpr_containing_location x in
1622+
(match gloc_o with
1623+
| Some gloc ->
1624+
let memoff_o = TR.to_option (gloc#address_memory_offset self#l x) in
1625+
(match memoff_o with
1626+
| Some memoff ->
1627+
let _ =
1628+
log_diagnostics_result
1629+
~msg:(p2s self#l#toPretty)
1630+
~tag:"xpr_to_cxpr:scaled gloc expr"
1631+
__FILE__ __LINE__
1632+
[(x2s x); gloc#name; memory_offset_to_string memoff] in
1633+
Ok (XOp ((Xf "addressofvar"),
1634+
[XVar (self#f#env#mk_gloc_variable gloc memoff)]))
1635+
| _ -> default ())
1636+
| _ -> default ())
1637+
16121638
| XOp (XPlus, [y; XConst (IntConst n)]) when is_pointer y && arithm ->
16131639
let derefty = BCHBCTypeUtil.ptr_deref (TR.tget_ok (self#get_xpr_type y)) in
16141640
let _ =
@@ -2374,8 +2400,20 @@ object (self)
23742400
match rhs with
23752401
| XConst (IntConst n) when n#gt CHNumerical.numerical_zero ->
23762402
let dw = numerical_mod_to_doubleword n in
2377-
if memmap#has_location dw then
2378-
TR.tvalue (self#f#env#mk_global_variable_address dw) ~default:rhs
2403+
(* do not rewrite to global addresses in the presence of loop counter
2404+
equalities, because the presence of symbolic constants derails the
2405+
generation of loop invariants. *)
2406+
if (memmap#has_location dw)
2407+
&& (not (self#inv#has_loop_counter_equality)) then
2408+
let newrhs =
2409+
TR.tvalue (self#f#env#mk_global_variable_address dw) ~default:rhs in
2410+
let _ =
2411+
ch_diagnostics_log#add
2412+
"rewrite constant to global address"
2413+
(LBLOCK [
2414+
self#l#toPretty; STR ": ";
2415+
dw#toPretty; STR " ==> "; (x2p newrhs)]) in
2416+
newrhs
23792417
else
23802418
rhs
23812419
| _ -> rhs in
@@ -2426,6 +2464,7 @@ object (self)
24262464
let reqC = self#env#request_num_constant in
24272465
let (rhscmds, rhs_c) = xpr_to_numexpr reqN reqC rhs in
24282466
let cmds = rhscmds @ [ASSIGN_NUM (lhs, rhs_c)] in
2467+
24292468
let fndata = self#f#get_function_data in
24302469
match fndata#get_regvar_intro self#ia with
24312470
| Some rvi when rvi.rvi_cast && Option.is_some rvi.rvi_vartype ->
@@ -3216,7 +3255,16 @@ object (self)
32163255
let bridgeVars = self#env#get_bridge_values_at self#cia in
32173256
let abstractglobals =
32183257
let globals =
3219-
List.filter self#env#is_global_variable self#env#get_variables in
3258+
List.filter self#f#env#is_mutable_global_variable self#env#get_variables in
3259+
let _ =
3260+
ch_diagnostics_log#add
3261+
"call: abstract globals"
3262+
(LBLOCK [
3263+
self#l#toPretty; STR ": ";
3264+
pretty_print_list
3265+
globals
3266+
(fun v -> STR (self#f#env#variable_name_to_string v))
3267+
"[" ", " "]"]) in
32203268
[ABSTRACT_VARS globals] in
32213269
let sideeffect_assigns =
32223270
self#get_sideeffect_assigns termev self#get_call_target#get_semantics in

CodeHawk/CHB/bchlib/bCHFunctionStackframe.ml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ object (self)
107107
| Ok t -> is_scalar t
108108
| _ -> false
109109

110+
method is_loopcounter: bool = sslot.sslot_loopcounter
111+
110112
method size: int option = sslot.sslot_size
111113

112114
method desc = sslot.sslot_desc
@@ -365,6 +367,7 @@ object (self)
365367
sslot_name = svintro.svi_name;
366368
sslot_btype = ty;
367369
sslot_spill = None;
370+
sslot_loopcounter = svintro.svi_loopcounter;
368371
sslot_desc = Some ("svintro");
369372
sslot_size = size} in
370373
let stackslot = new stackslot_t sslot in
@@ -449,6 +452,7 @@ object (self)
449452
sslot_btype = btype;
450453
sslot_spill = spill;
451454
sslot_size = size;
455+
sslot_loopcounter = false;
452456
sslot_desc = desc
453457
} in
454458
let sslot = new stackslot_t ssrec in
@@ -495,6 +499,7 @@ object (self)
495499
sslot_btype = t_unknown;
496500
sslot_spill = Some reg;
497501
sslot_size = Some 4;
502+
sslot_loopcounter = false;
498503
sslot_desc = Some "register spill"
499504
} in
500505
let sslot = new stackslot_t ssrec in
@@ -534,6 +539,7 @@ object (self)
534539
sslot_btype = t_unknown;
535540
sslot_spill = Some reg;
536541
sslot_size = Some 4;
542+
sslot_loopcounter = false;
537543
sslot_desc = Some "register_spill"
538544
} in
539545
let sslot = new stackslot_t ssrec in
@@ -571,7 +577,20 @@ object (self)
571577
(iaddr:ctxt_iaddress_t) =
572578
let ty = match typ with Some t -> t | _ -> t_unknown in
573579
let blread = StackBlockRead (offset, size, ty) in
574-
self#add_access offset iaddr blread
580+
let ssrec = {
581+
sslot_name = "blockread";
582+
sslot_offset = offset;
583+
sslot_btype = ty;
584+
sslot_size = size;
585+
sslot_spill = None;
586+
sslot_loopcounter = false;
587+
sslot_desc = None
588+
} in
589+
let sslot = new stackslot_t ssrec in
590+
begin
591+
self#add_access offset iaddr blread;
592+
H.add stackslots offset sslot
593+
end
575594

576595
method add_block_write
577596
~(offset:int)

CodeHawk/CHB/bchlib/bCHLibTypes.mli

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,7 +1511,8 @@ type stackvar_intro_t = {
15111511
svi_offset: int;
15121512
svi_name: string;
15131513
svi_vartype: btype_t option;
1514-
svi_cast: bool
1514+
svi_cast: bool;
1515+
svi_loopcounter: bool
15151516
}
15161517

15171518
type typing_rule_t = {
@@ -1531,7 +1532,8 @@ type function_annotation_t = {
15311532
regvarintros: regvar_intro_t list;
15321533
stackvarintros: stackvar_intro_t list;
15331534
typingrules: typing_rule_t list;
1534-
reachingdefspecs: reachingdef_spec_t list
1535+
reachingdefspecs: reachingdef_spec_t list;
1536+
constglobalvars: string list
15351537
}
15361538

15371539
class type function_data_int =
@@ -1592,6 +1594,7 @@ class type function_data_int =
15921594
method has_regvar_type_cast: doubleword_int -> bool
15931595
method has_stackvar_type_annotation: int -> bool
15941596
method has_stackvar_type_cast: int -> bool
1597+
method is_const_global_variable: string -> bool
15951598
method filter_deflocs: string -> variable_t -> symbol_t list -> symbol_t list
15961599
method is_typing_rule_enabled: ?rdef:string option -> string -> string -> bool
15971600
method has_class_info: bool
@@ -1858,11 +1861,13 @@ object ('a)
18581861
method get_fact: invariant_fact_t
18591862
method get_variables: variable_t list
18601863
method get_variable_equality_variables: variable_t list
1864+
method get_var_loopcounter_expr: variable_t -> xpr_t option
18611865
method is_constant: bool
18621866
method is_interval: bool
18631867
method is_base_offset_value: bool
18641868
method is_symbolic_expr: bool
18651869
method is_linear_equality: bool
1870+
method is_loopcounter_equality: bool
18661871
method is_variable_equality: bool
18671872
method is_smaller: 'a -> bool
18681873
method write_xml: xml_element_int -> unit
@@ -1893,7 +1898,7 @@ object
18931898
method get_known_initial_values: variable_t list
18941899
method get_init_disequalities: variable_t list (* initial values *)
18951900
method get_init_equalities: variable_t list (* initial values *)
1896-
method rewrite_expr: xpr_t -> xpr_t
1901+
method rewrite_expr: ?loopcounter:bool -> xpr_t -> xpr_t
18971902

18981903
(* predicates *)
18991904
method is_unreachable: bool
@@ -1907,6 +1912,7 @@ object
19071912
variable_t -> ctxt_iaddress_t -> ctxt_iaddress_t -> bool
19081913
method var_has_initial_value: variable_t -> bool
19091914
method var_has_symbolic_expr: variable_t -> bool
1915+
method has_loop_counter_equality: bool
19101916

19111917
(* xml *)
19121918
method write_xml: xml_element_int -> unit
@@ -3780,6 +3786,10 @@ class type vardictionary_int =
37803786
method xd: xprdictionary_int
37813787
method faddr: doubleword_int
37823788
method reset: unit
3789+
3790+
method set_av_attributes: int -> string list -> unit
3791+
method get_av_attributes: int -> string list
3792+
37833793
method get_indexed_variables: (int * assembly_variable_denotation_t) list
37843794
method get_indexed_bases: (int * memory_base_t) list
37853795

@@ -3840,6 +3850,9 @@ object
38403850
(** Returns the memory reference manager for this function.*)
38413851
method memrefmgr: memory_reference_manager_int
38423852

3853+
method set_av_attributes: int -> string list -> unit
3854+
method get_av_attributes: int -> string list
3855+
38433856
(** {1 Creating variables}*)
38443857

38453858
(** {2 Registers and flags}*)
@@ -4580,6 +4593,7 @@ end
45804593
sslot_btype: btype_t;
45814594
sslot_size: int option;
45824595
sslot_spill: register_t option;
4596+
sslot_loopcounter: bool;
45834597
sslot_desc: string option
45844598
}
45854599

@@ -4612,6 +4626,7 @@ class type stackslot_int =
46124626
method is_struct: bool
46134627
method is_array: bool
46144628
method is_spill: bool
4629+
method is_loopcounter: bool
46154630

46164631
method write_xml: xml_element_int -> unit
46174632
end
@@ -5018,6 +5033,15 @@ class type function_environment_int =
50185033
or if [var] is the initial value of a global variable. *)
50195034
method is_global_variable: variable_t -> bool
50205035

5036+
(** [is_mutable_global_variable var] returns [true] if [var] is a global
5037+
variable, but not an initial memory value and not a const global variable
5038+
(as annotated in the function annotations).
5039+
5040+
Note: non-mutability is asserted only in the context of a given function
5041+
(as derived from the function annotations).
5042+
*)
5043+
method is_mutable_global_variable: variable_t -> bool
5044+
50215045
(** Returns true if [var] is a global variable with a constant offset
50225046
(i.e., a numerical value). *)
50235047
method has_global_variable_address: variable_t -> bool

CodeHawk/CHB/bchlib/bCHVersion.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ end
9595

9696

9797
let version = new version_info_t
98-
~version:"0.6.0_20251012"
99-
~date:"2025-10-12"
98+
~version:"0.6.0_20251021"
99+
~date:"2025-10-21"
100100
~licensee: None
101101
~maxfilesize: None
102102
()

0 commit comments

Comments
 (0)