Decrease number of allocations in Prop.typ_normalize

Summary:
I ran perf on rocksdb analysis and found out that ~40% of time is spent inside ocaml GC originating
from Prop.typ_normalize.
After this change, profile shows that GC is ~2% and Prop.typ_normalize takes 50% of the time.

Reviewed By: jberdine

Differential Revision: D3219113

fb-gh-sync-id: 27c34d9
fbshipit-source-id: 27c34d9
master
Andrzej Kotulski 9 years ago committed by Facebook Github Bot 0
parent 77791b7e8e
commit 2989105318

@ -845,6 +845,28 @@ let rec texp_normalize sub exp = match exp with
| Sil.Sizeof (typ, st) -> Sil.Sizeof (typ_normalize sub typ, st) | Sil.Sizeof (typ, st) -> Sil.Sizeof (typ_normalize sub typ, st)
| _ -> exp_normalize sub exp | _ -> exp_normalize sub exp
(* NOTE: usage of == operator in flds_norm and typ_normalize is intended*)
(* to decrease pressure on ocaml's GC and not allocate new objects if typ_normalize*)
(* doesn't change anything in structure of the type *)
and flds_norm sub fields =
let fld_norm ((f, t, a) as field) =
let t' = typ_normalize sub t in
if t' == t then
field
else
(f, t', a) in
let rec flds_norm_aux fields = match fields with
| [] -> fields
| field :: rest ->
let rest' = flds_norm_aux rest in
let field' = fld_norm field in
if field == field' && rest == rest' then
fields
else
field' :: rest' in
flds_norm_aux fields
and typ_normalize sub typ = match typ with and typ_normalize sub typ = match typ with
| Sil.Tvar _ | Sil.Tvar _
| Sil.Tint _ | Sil.Tint _
@ -852,18 +874,29 @@ and typ_normalize sub typ = match typ with
| Sil.Tvoid | Sil.Tvoid
| Sil.Tfun _ -> | Sil.Tfun _ ->
typ typ
| Sil.Tptr (t', pk) -> | Sil.Tptr (t, pk) ->
Sil.Tptr (typ_normalize sub t', pk) let t' = typ_normalize sub t in
if t == t' then
typ
else
Sil.Tptr (t', pk)
| Sil.Tstruct struct_typ -> | Sil.Tstruct struct_typ ->
let fld_norm = IList.map (fun (f, t, a) -> (f, typ_normalize sub t, a)) in let instance_fields = struct_typ.Sil.instance_fields in
let instance_fields = fld_norm struct_typ.Sil.instance_fields in let instance_fields' = flds_norm sub instance_fields in
let static_fields = fld_norm struct_typ.Sil.static_fields in let static_fields = struct_typ.Sil.static_fields in
let static_fields' = flds_norm sub static_fields in
if instance_fields == instance_fields' && static_fields == static_fields' then
typ
else
Sil.Tstruct Sil.Tstruct
{ struct_typ with { struct_typ with
Sil.instance_fields; Sil.instance_fields = instance_fields';
static_fields; static_fields = static_fields';
} }
| Sil.Tarray (t, e) -> | Sil.Tarray (t, e) ->
(* this case is not optimized for less GC allocations since it requires*)
(* to make exp_normalize GC-friendly as well. Profiling showed that it's fine*)
(* to keep this code not optimized *)
Sil.Tarray (typ_normalize sub t, exp_normalize sub e) Sil.Tarray (typ_normalize sub t, exp_normalize sub e)
let run_with_abs_val_eq_zero f = let run_with_abs_val_eq_zero f =

Loading…
Cancel
Save