From b0e6ed8b35c199bdb1fd69a5b2f9596a89a741c5 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Mon, 9 Jan 2017 07:34:22 -0800 Subject: [PATCH] [clang frontend] Eliminate use of expensive list append Reviewed By: jberdine Differential Revision: D4387084 fbshipit-source-id: fcc113e --- infer/src/clang/cFrontend_utils.ml | 5 ---- infer/src/clang/cFrontend_utils.mli | 3 -- infer/src/clang/cVar_decl.ml | 46 ++++++++++++++++------------- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index 25d1ca6f2..abeba5c23 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -537,11 +537,6 @@ struct let eq (m1, t1) (m2, t2) = (Mangled.equal m1 m2) && (Typ.equal t1 t2) in append_no_duplicates eq list1 list2 - let append_no_duplicateds list1 list2 = - let eq (e1, t1) (e2, t2) = (Exp.equal e1 e2) && (Typ.equal t1 t2) in - append_no_duplicates eq list1 list2 - - let append_no_duplicates_annotations list1 list2 = let eq (annot1, _) (annot2, _) = annot1.Annot.class_name = annot2.Annot.class_name in append_no_duplicates eq list1 list2 diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index a71a16ba3..404d0000c 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -193,9 +193,6 @@ sig val append_no_duplicated_vars : (Mangled.t * Typ.t) list -> (Mangled.t * Typ.t) list -> (Mangled.t * Typ.t) list - val append_no_duplicateds : - (Exp.t * Typ.t) list -> (Exp.t * Typ.t) list -> (Exp.t * Typ.t) list - val sort_fields : (Ident.fieldname * Typ.t * Annot.Item.t) list -> (Ident.fieldname * Typ.t * Annot.Item.t) list diff --git a/infer/src/clang/cVar_decl.ml b/infer/src/clang/cVar_decl.ml index c07e959ac..2ca584d9e 100644 --- a/infer/src/clang/cVar_decl.ml +++ b/infer/src/clang/cVar_decl.ml @@ -62,27 +62,31 @@ let add_var_to_locals procdesc var_decl sil_typ pvar = Procdesc.append_locals procdesc [(Pvar.get_name pvar, sil_typ)] | _ -> assert false -let rec compute_autorelease_pool_vars context stmts = - let procname = Procdesc.get_proc_name context.CContext.procdesc in - match stmts with - | [] -> [] - | Clang_ast_t.DeclRefExpr (_, _, _, drei):: stmts' -> - (let res = compute_autorelease_pool_vars context stmts' in - match drei.Clang_ast_t.drti_decl_ref with - | Some decl_ref -> - (match decl_ref.Clang_ast_t.dr_type_ptr with - | Some type_ptr when decl_ref.Clang_ast_t.dr_kind = `Var -> - let typ = CType_decl.type_ptr_to_sil_type context.CContext.tenv type_ptr in - let pvar = sil_var_of_decl_ref context decl_ref procname in - if Pvar.is_local pvar then - General_utils.append_no_duplicateds [(Exp.Lvar pvar, typ)] res - else res - | _ -> res) - | _ -> res) - | s :: stmts' -> - let sl = snd (Clang_ast_proj.get_stmt_tuple s) in - compute_autorelease_pool_vars context (sl @ stmts') - +let compute_autorelease_pool_vars context stmts = + let rec do_stmts map = function + | [] -> + map + | Clang_ast_t.DeclRefExpr (_, _, _, drei):: stmts' -> + let map1 = match drei.Clang_ast_t.drti_decl_ref with + | Some decl_ref -> + (match decl_ref.Clang_ast_t.dr_type_ptr with + | Some type_ptr when decl_ref.Clang_ast_t.dr_kind = `Var -> + let typ = CType_decl.type_ptr_to_sil_type context.CContext.tenv type_ptr in + let procname = Procdesc.get_proc_name context.CContext.procdesc in + let pvar = sil_var_of_decl_ref context decl_ref procname in + if Pvar.is_local pvar then + Exp.Map.add (Exp.Lvar pvar) typ map + else map + | _ -> + map) + | None -> + map in + do_stmts map1 stmts' + | s :: stmts' -> + let sl = snd (Clang_ast_proj.get_stmt_tuple s) in + let map1 = do_stmts map sl in + do_stmts map1 stmts' in + Exp.Map.bindings (do_stmts Exp.Map.empty stmts) (* Returns a list of captured variables as sil variables. *) let captured_vars_from_block_info context cvl =