proc_inline_synthetic_methods: got rid of refs

Reviewed By: jeremydubreil

Differential Revision: D8150793

fbshipit-source-id: 2a63f95
master
Mehdi Bouaziz 7 years ago committed by Facebook Github Bot
parent fbc13cf952
commit 256b74b289

@ -84,15 +84,14 @@ let save_attributes source_file cfg =
(** Inline a synthetic (access or bridge) method. *) (** Inline a synthetic (access or bridge) method. *)
let inline_synthetic_method ((ret_id, _) as ret) etl pdesc loc_call : Sil.instr option = let inline_synthetic_method ((ret_id, _) as ret) etl pdesc loc_call : Sil.instr option =
let modified = ref None in
let found instr instr' = let found instr instr' =
modified := Some instr' ;
L.(debug Analysis Verbose) L.(debug Analysis Verbose)
"XX inline_synthetic_method found instr: %a@." (Sil.pp_instr Pp.text) instr ; "XX inline_synthetic_method found instr: %a@." (Sil.pp_instr Pp.text) instr ;
L.(debug Analysis Verbose) L.(debug Analysis Verbose)
"XX inline_synthetic_method instr': %a@." (Sil.pp_instr Pp.text) instr' "XX inline_synthetic_method instr': %a@." (Sil.pp_instr Pp.text) instr' ;
Some instr'
in in
let do_instr _ instr = let do_instr instr =
match (instr, etl) with match (instr, etl) with
| Sil.Load (_, Exp.Lfield (Exp.Var _, fn, ft), bt, _), [(* getter for fields *) (e1, _)] -> | Sil.Load (_, Exp.Lfield (Exp.Var _, fn, ft), bt, _), [(* getter for fields *) (e1, _)] ->
let instr' = Sil.Load (ret_id, Exp.Lfield (e1, fn, ft), bt, loc_call) in let instr' = Sil.Load (ret_id, Exp.Lfield (e1, fn, ft), bt, loc_call) in
@ -125,15 +124,15 @@ let inline_synthetic_method ((ret_id, _) as ret) etl pdesc loc_call : Sil.instr
let instr' = Sil.Call (ret, Exp.Const (Const.Cfun pn), etl1, loc_call, cf) in let instr' = Sil.Call (ret, Exp.Const (Const.Cfun pn), etl1, loc_call, cf) in
found instr instr' found instr instr'
| _ -> | _ ->
() None
in in
Procdesc.iter_instrs do_instr pdesc ; Procdesc.find_map_instrs ~f:do_instr pdesc
!modified
(** Find synthetic (access or bridge) Java methods in the procedure and inline them in the cfg. *) (** Find synthetic (access or bridge) Java methods in the procedure and inline them in the cfg. *)
let proc_inline_synthetic_methods cfg pdesc : unit = let proc_inline_synthetic_methods cfg pdesc : unit =
let instr_inline_synthetic_method = function let instr_inline_synthetic_method instr =
match instr with
| Sil.Call (ret_id_typ, Exp.Const (Const.Cfun (Typ.Procname.Java java_pn as pn)), etl, loc, _) | Sil.Call (ret_id_typ, Exp.Const (Const.Cfun (Typ.Procname.Java java_pn as pn)), etl, loc, _)
-> ( -> (
match Typ.Procname.Hash.find cfg pn with match Typ.Procname.Hash.find cfg pn with
@ -143,28 +142,14 @@ let proc_inline_synthetic_methods cfg pdesc : unit =
let is_synthetic = attributes.is_synthetic_method in let is_synthetic = attributes.is_synthetic_method in
let is_bridge = attributes.is_bridge_method in let is_bridge = attributes.is_bridge_method in
if is_access || is_bridge || is_synthetic then if is_access || is_bridge || is_synthetic then
inline_synthetic_method ret_id_typ etl pd loc inline_synthetic_method ret_id_typ etl pd loc |> Option.value ~default:instr
else None else instr
| exception Caml.Not_found -> | exception Caml.Not_found ->
None ) instr )
| _ -> | _ ->
None instr
in
let node_inline_synthetic_methods node =
let modified = ref false in
let do_instr instr =
match instr_inline_synthetic_method instr with
| None ->
instr
| Some instr' ->
modified := true ;
instr'
in
let instrs = Procdesc.Node.get_instrs node in
let instrs' = List.map ~f:do_instr instrs in
if !modified then Procdesc.Node.replace_instrs node instrs'
in in
Procdesc.iter_nodes node_inline_synthetic_methods pdesc Procdesc.replace_instrs pdesc ~f:instr_inline_synthetic_method
let inline_java_synthetic_methods cfg = let inline_java_synthetic_methods cfg =

@ -126,8 +126,11 @@ module Node = struct
(** Add the instructions at the beginning of the list of instructions to execute *) (** Add the instructions at the beginning of the list of instructions to execute *)
let prepend_instrs node instrs = node.instrs <- instrs @ node.instrs let prepend_instrs node instrs = node.instrs <- instrs @ node.instrs
(** Replace the instructions to be executed. *) (** Map and replace the instructions to be executed *)
let replace_instrs node instrs = node.instrs <- instrs let replace_instrs node ~f =
let instrs' = IList.map_changed node.instrs ~equal:phys_equal ~f in
if not (phys_equal instrs' node.instrs) then node.instrs <- instrs'
(** Add declarations for local variables and return variable to the node *) (** Add declarations for local variables and return variable to the node *)
let add_locals_ret_declaration node (proc_attributes: ProcAttributes.t) locals = let add_locals_ret_declaration node (proc_attributes: ProcAttributes.t) locals =
@ -306,6 +309,18 @@ let fold_instrs pdesc ~init ~f =
fold_nodes ~f:fold_node ~init pdesc fold_nodes ~f:fold_node ~init pdesc
let find_map_nodes pdesc ~f = List.find_map ~f (get_nodes pdesc)
let find_map_instrs pdesc ~f =
let find_map_node node = List.find_map ~f (Node.get_instrs node) in
find_map_nodes ~f:find_map_node pdesc
let replace_instrs pdesc ~f =
let do_node node = Node.replace_instrs ~f node in
iter_nodes do_node pdesc
(** fold between two nodes or until we reach a branching structure *) (** fold between two nodes or until we reach a branching structure *)
let fold_slope_range = let fold_slope_range =
let rec aux node visited acc ~f = let rec aux node visited acc ~f =

@ -101,9 +101,6 @@ module Node : sig
val pp_instrs : Pp.env -> sub_instrs:bool -> Sil.instr option -> Format.formatter -> t -> unit val pp_instrs : Pp.env -> sub_instrs:bool -> Sil.instr option -> Format.formatter -> t -> unit
(** Print extended instructions for the node, (** Print extended instructions for the node,
highlighting the given subinstruction if present *) highlighting the given subinstruction if present *)
val replace_instrs : t -> Sil.instr list -> unit
(** Replace the instructions to be executed. *)
end end
(** Map with node id keys. *) (** Map with node id keys. *)
@ -139,6 +136,8 @@ val did_preanalysis : t -> bool
val fold_instrs : t -> init:'accum -> f:('accum -> Node.t -> Sil.instr -> 'accum) -> 'accum val fold_instrs : t -> init:'accum -> f:('accum -> Node.t -> Sil.instr -> 'accum) -> 'accum
(** fold over all nodes and their instructions *) (** fold over all nodes and their instructions *)
val find_map_instrs : t -> f:(Sil.instr -> 'a option) -> 'a option
val from_proc_attributes : ProcAttributes.t -> t val from_proc_attributes : ProcAttributes.t -> t
(** Use [Cfg.create_proc_desc] if you are adding a proc desc to a cfg *) (** Use [Cfg.create_proc_desc] if you are adding a proc desc to a cfg *)
@ -184,6 +183,9 @@ val is_java_synchronized : t -> bool
val iter_instrs : (Node.t -> Sil.instr -> unit) -> t -> unit val iter_instrs : (Node.t -> Sil.instr -> unit) -> t -> unit
(** iterate over all nodes and their instructions *) (** iterate over all nodes and their instructions *)
val replace_instrs : t -> f:(Sil.instr -> Sil.instr) -> unit
(** Map and replace the instructions to be executed *)
val iter_nodes : (Node.t -> unit) -> t -> unit val iter_nodes : (Node.t -> unit) -> t -> unit
(** iterate over all the nodes of a procedure *) (** iterate over all the nodes of a procedure *)

Loading…
Cancel
Save