[cost] Instantiate costs using formals not pname

Summary:
Simplifies `instantiate_cost`, call `Ondemand` once per call site.

Depends on D14028249

Reviewed By: ddino

Differential Revision: D14028281

fbshipit-source-id: 865151fee
master
Mehdi Bouaziz 6 years ago committed by Facebook Github Bot
parent ba5ad82128
commit 3139ee5d46

@ -518,19 +518,11 @@ type extras_WCET =
; integer_type_widths: Typ.IntegerWidths.t ; integer_type_widths: Typ.IntegerWidths.t
; get_node_nb_exec: Node.id -> BasicCost.t } ; get_node_nb_exec: Node.id -> BasicCost.t }
let instantiate_cost integer_type_widths ~inferbo_caller_mem ~callee_pname ~params ~callee_cost = let instantiate_cost integer_type_widths ~inferbo_caller_mem ~callee_formals ~params ~callee_cost =
match Ondemand.get_proc_desc callee_pname with let eval_sym =
| None -> BufferOverrunSemantics.mk_eval_sym integer_type_widths callee_formals params inferbo_caller_mem
L.(die InternalError) in
"Can't instantiate symbolic cost %a from call to %a (can't get procdesc)" BasicCost.pp BasicCost.subst callee_cost eval_sym
callee_cost Typ.Procname.pp callee_pname
| Some callee_pdesc ->
let callee_formals = Procdesc.get_pvar_formals callee_pdesc in
let eval_sym =
BufferOverrunSemantics.mk_eval_sym integer_type_widths callee_formals params
inferbo_caller_mem
in
BasicCost.subst callee_cost eval_sym
module InstrBasicCost = struct module InstrBasicCost = struct
@ -539,10 +531,11 @@ module InstrBasicCost = struct
For example for basic operation we set it to 1 and for function call we take it from the spec of the function. For example for basic operation we set it to 1 and for function call we take it from the spec of the function.
*) *)
let callee_OperationCost callee_cost_record integer_type_widths inferbo_mem callee_pname params = let callee_OperationCost callee_cost_record integer_type_widths inferbo_mem callee_formals params
=
let callee_cost = CostDomain.get_operation_cost callee_cost_record in let callee_cost = CostDomain.get_operation_cost callee_cost_record in
if BasicCost.is_symbolic callee_cost then if BasicCost.is_symbolic callee_cost then
instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem ~callee_pname ~params instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem ~callee_formals ~params
~callee_cost ~callee_cost
else callee_cost else callee_cost
@ -551,6 +544,14 @@ module InstrBasicCost = struct
let callee_IOCost cost_record = CostDomain.get_IO_cost cost_record let callee_IOCost cost_record = CostDomain.get_IO_cost cost_record
let get_callee_summary caller_pdesc callee_pname =
Ondemand.analyze_proc_name ~caller_pdesc callee_pname
|> Option.bind ~f:(fun summary ->
Payload.of_summary summary
|> Option.map ~f:(fun payload ->
(payload, Summary.get_proc_desc summary |> Procdesc.get_pvar_formals) ) )
let get_instr_cost_record pdata instr_node instr = let get_instr_cost_record pdata instr_node instr =
match instr with match instr with
| Sil.Call (_, Exp.Const (Const.Cfun callee_pname), params, _, _) -> ( | Sil.Call (_, Exp.Const (Const.Cfun callee_pname), params, _, _) -> (
@ -565,11 +566,11 @@ module InstrBasicCost = struct
| Some model -> | Some model ->
CostDomain.set_operation_cost (model inferbo_mem) CostDomain.zero_record CostDomain.set_operation_cost (model inferbo_mem) CostDomain.zero_record
| None -> ( | None -> (
match Payload.read pdesc callee_pname with match get_callee_summary pdesc callee_pname with
| Some {post= callee_cost_record} -> | Some ({CostDomain.post= callee_cost_record}, callee_formals) ->
let callee_operation_cost = let callee_operation_cost =
callee_OperationCost callee_cost_record integer_type_widths inferbo_mem callee_OperationCost callee_cost_record integer_type_widths inferbo_mem
callee_pname params callee_formals params
in in
let callee_allocation_cost = callee_AllocationCost callee_cost_record in let callee_allocation_cost = callee_AllocationCost callee_cost_record in
let callee_IO_cost = callee_IOCost callee_cost_record in let callee_IO_cost = callee_IOCost callee_cost_record in

@ -12,7 +12,7 @@ val checker : Callbacks.proc_callback_t
val instantiate_cost : val instantiate_cost :
Typ.IntegerWidths.t Typ.IntegerWidths.t
-> inferbo_caller_mem:BufferOverrunDomain.Mem.t -> inferbo_caller_mem:BufferOverrunDomain.Mem.t
-> callee_pname:Typ.Procname.t -> callee_formals:(Pvar.t * Typ.t) list
-> params:(Exp.t * 'a) list -> params:(Exp.t * 'a) list
-> callee_cost:CostDomain.BasicCost.t -> callee_cost:CostDomain.BasicCost.t
-> CostDomain.BasicCost.t -> CostDomain.BasicCost.t

@ -91,16 +91,17 @@ let get_issue_to_report tenv Call.({pname; node; params}) integer_type_widths in
|| ||
(* only report if function call has expensive/symbolic cost *) (* only report if function call has expensive/symbolic cost *)
match Ondemand.analyze_proc_name pname with match Ondemand.analyze_proc_name pname with
| Some {Summary.payloads= {Payloads.cost= Some {CostDomain.post= cost_record}}} | Some ({Summary.payloads= {Payloads.cost= Some {CostDomain.post= cost_record}}} as summary)
when CostDomain.BasicCost.is_symbolic (CostDomain.get_operation_cost cost_record) -> when CostDomain.BasicCost.is_symbolic (CostDomain.get_operation_cost cost_record) ->
let instr_node_id = InstrCFG.last_of_underlying_node node |> InstrCFG.Node.id in let instr_node_id = InstrCFG.last_of_underlying_node node |> InstrCFG.Node.id in
let inferbo_invariant_map = Lazy.force inferbo_invariant_map in let inferbo_invariant_map = Lazy.force inferbo_invariant_map in
let inferbo_mem = let inferbo_mem =
Option.value_exn (BufferOverrunAnalysis.extract_pre instr_node_id inferbo_invariant_map) Option.value_exn (BufferOverrunAnalysis.extract_pre instr_node_id inferbo_invariant_map)
in in
let callee_formals = Summary.get_proc_desc summary |> Procdesc.get_pvar_formals in
(* get the cost of the function call *) (* get the cost of the function call *)
Cost.instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem Cost.instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem ~callee_formals
~callee_pname:pname ~params ~params
~callee_cost:(CostDomain.get_operation_cost cost_record) ~callee_cost:(CostDomain.get_operation_cost cost_record)
|> CostDomain.BasicCost.is_symbolic |> CostDomain.BasicCost.is_symbolic
| _ -> | _ ->

Loading…
Cancel
Save