From c841bf262a8dae2df672ef4eb413d7aa346bc64e Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 May 2018 01:08:17 -0700 Subject: [PATCH] Preanal: append_instrs once per node Summary: Append can be costly, let's do it once only. Depends on D8185619 Reviewed By: jeremydubreil Differential Revision: D8185634 fbshipit-source-id: 67f84a9 --- infer/src/IR/Procdesc.ml | 2 +- infer/src/backend/preanal.ml | 26 ++++++++++++-------------- infer/src/istd/IList.ml | 2 ++ infer/src/istd/IList.mli | 3 +++ 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index c29609dbf..1fe23ce89 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -121,7 +121,7 @@ module Node = struct let get_distance_to_exit node = node.dist_exit (** Append the instructions to the list of instructions to execute *) - let append_instrs node instrs = node.instrs <- node.instrs @ instrs + let append_instrs node instrs = if instrs <> [] then node.instrs <- node.instrs @ instrs (** Add the instructions at the beginning of the list of instructions to execute *) let prepend_instrs node instrs = node.instrs <- instrs @ node.instrs diff --git a/infer/src/backend/preanal.ml b/infer/src/backend/preanal.ml index f986dc0db..de54a1525 100644 --- a/infer/src/backend/preanal.ml +++ b/infer/src/backend/preanal.ml @@ -132,18 +132,12 @@ let add_nullify_instrs pdesc tenv liveness_inv_map = in (* only nullify pvars that are local; don't nullify those that can escape *) let is_local pvar = not (Pvar.is_return pvar || Pvar.is_global pvar) in - let node_add_nullify_instructions node pvars = - let loc = Procdesc.Node.get_last_loc node in - let nullify_instrs = - List.rev_filter_map pvars ~f:(fun pvar -> - if is_local pvar then Some (Sil.Nullify (pvar, loc)) else None ) - in - if nullify_instrs <> [] then Procdesc.Node.append_instrs node nullify_instrs + let node_nullify_instructions loc pvars = + List.rev_filter_map pvars ~f:(fun pvar -> + if is_local pvar then Some (Sil.Nullify (pvar, loc)) else None ) in - let node_add_removetmps_instructions node ids = - if ids <> [] then - let loc = Procdesc.Node.get_last_loc node in - Procdesc.Node.append_instrs node [Sil.Remove_temps (List.rev ids, loc)] + let node_removetmps_instruction loc ids = + if ids <> [] then Some (Sil.Remove_temps (List.rev ids, loc)) else None in List.iter ~f:(fun node -> @@ -163,15 +157,19 @@ let add_nullify_instrs pdesc tenv liveness_inv_map = (pvars_acc, ids_acc) ) to_nullify ([], []) in - node_add_removetmps_instructions node ids_to_remove ; - node_add_nullify_instructions node pvars_to_nullify + let loc = Procdesc.Node.get_last_loc node in + node_nullify_instructions loc pvars_to_nullify + |> IList.opt_cons (node_removetmps_instruction loc ids_to_remove) + |> Procdesc.Node.append_instrs node | None -> () ) (ProcCfg.Exceptional.nodes nullify_proc_cfg) ; (* nullify all address taken variables *) if not (AddressTaken.Domain.is_empty address_taken_vars) then let exit_node = ProcCfg.Exceptional.exit_node nullify_proc_cfg in - node_add_nullify_instructions exit_node (AddressTaken.Domain.elements address_taken_vars) + let exit_loc = Procdesc.Node.get_last_loc exit_node in + node_nullify_instructions exit_loc (AddressTaken.Domain.elements address_taken_vars) + |> Procdesc.Node.append_instrs exit_node (** perform liveness analysis and insert Nullify/Remove_temps instructions into the IR to make it diff --git a/infer/src/istd/IList.ml b/infer/src/istd/IList.ml index 9d3656a18..a68023e4c 100644 --- a/infer/src/istd/IList.ml +++ b/infer/src/istd/IList.ml @@ -145,3 +145,5 @@ let rec drop list index = let mem_nth list index = drop list index |> List.is_empty |> not + +let opt_cons opt list = match opt with Some x -> x :: list | None -> list diff --git a/infer/src/istd/IList.mli b/infer/src/istd/IList.mli index fd340920d..fcd6bb16b 100644 --- a/infer/src/istd/IList.mli +++ b/infer/src/istd/IList.mli @@ -41,3 +41,6 @@ val drop : 'a list -> int -> 'a list val mem_nth : 'a list -> int -> bool (** [mem_nth l n] returns whether the list [l] contains a [n]th element. *) + +val opt_cons : 'a option -> 'a list -> 'a list +(** [opt_cons None l] returns [l]. [opt_cons (Some x) l] returns [x :: l]*)