[cost] Support closure symbols in operation/allocation cost kinds

Summary: This diff adds closure symbols to operation/allocation costs, when function pointer is called.

Reviewed By: ezgicicek

Differential Revision: D24308550

fbshipit-source-id: 6c5889d41
master
Sungkeun Cho 4 years ago committed by Facebook GitHub Bot
parent 075581ec8d
commit 0f44f39b41

@ -106,19 +106,22 @@ module InstrBasicCostWithReason = struct
|> Option.value ~default:(Option.value callee_cost_opt ~default:BasicCostWithReason.zero) |> Option.value ~default:(Option.value callee_cost_opt ~default:BasicCostWithReason.zero)
let dispatch_autoreleasepool_func_ptr_call {inferbo_invariant_map; integer_type_widths} instr_node let dispatch_func_ptr_call {inferbo_invariant_map; integer_type_widths} instr_node fun_exp =
fun_exp =
BufferOverrunAnalysis.extract_pre (InstrCFG.Node.id instr_node) inferbo_invariant_map BufferOverrunAnalysis.extract_pre (InstrCFG.Node.id instr_node) inferbo_invariant_map
|> Option.value_map ~default:BasicCostWithReason.zero ~f:(fun inferbo_mem -> |> Option.bind ~f:(fun inferbo_mem ->
let func_ptrs = let func_ptrs =
BufferOverrunSemantics.eval integer_type_widths fun_exp inferbo_mem BufferOverrunSemantics.eval integer_type_widths fun_exp inferbo_mem
|> BufferOverrunDomain.Val.get_func_ptrs |> BufferOverrunDomain.Val.get_func_ptrs
in in
match FuncPtr.Set.is_singleton_or_more func_ptrs with match FuncPtr.Set.is_singleton_or_more func_ptrs with
| Singleton (Path path) -> | Singleton (Path path) ->
BasicCost.of_func_ptr path |> BasicCostWithReason.of_basic_cost let symbolic_cost =
BasicCost.of_func_ptr path |> BasicCostWithReason.of_basic_cost
in
Some (CostDomain.construct ~f:(fun _ -> symbolic_cost))
| _ -> | _ ->
BasicCostWithReason.zero ) None )
|> Option.value ~default:CostDomain.unit_cost_atomic_operation
let get_instr_cost_record tenv extras cfg instr_node instr = let get_instr_cost_record tenv extras cfg instr_node instr =
@ -186,14 +189,7 @@ module InstrBasicCostWithReason = struct
| Sil.Call (_, Exp.Const (Const.Cfun _), _, _, _) -> | Sil.Call (_, Exp.Const (Const.Cfun _), _, _, _) ->
CostDomain.zero_record CostDomain.zero_record
| Sil.Call (_, fun_exp, _, _location, _) -> | Sil.Call (_, fun_exp, _, _location, _) ->
CostDomain.construct ~f:(fun kind -> dispatch_func_ptr_call extras instr_node fun_exp
match kind with
| OperationCost ->
BasicCostWithReason.one ()
| AllocationCost ->
BasicCostWithReason.zero
| AutoreleasepoolSize ->
dispatch_autoreleasepool_func_ptr_call extras instr_node fun_exp )
| Sil.Load {id= lhs_id} when Ident.is_none lhs_id -> | Sil.Load {id= lhs_id} when Ident.is_none lhs_id ->
(* dummy deref inserted by frontend--don't count as a step. In (* dummy deref inserted by frontend--don't count as a step. In
JDK 11, dummy deref disappears and causes cost differences JDK 11, dummy deref disappears and causes cost differences

@ -64,7 +64,7 @@ codetoanalyze/c/performance/loops.c, if_out_loop, 515, OnUIThread:false, []
codetoanalyze/c/performance/loops.c, larger_state_FN, 1005, OnUIThread:false, [] codetoanalyze/c/performance/loops.c, larger_state_FN, 1005, OnUIThread:false, []
codetoanalyze/c/performance/loops.c, loop_use_global_vars, 4 + 4 ⋅ x + 2 ⋅ (1+max(0, x)), OnUIThread:false, [{1+max(0, x)},Loop,{x},Loop] codetoanalyze/c/performance/loops.c, loop_use_global_vars, 4 + 4 ⋅ x + 2 ⋅ (1+max(0, x)), OnUIThread:false, [{1+max(0, x)},Loop,{x},Loop]
codetoanalyze/c/performance/loops.c, ptr_cmp, 5 + 5 ⋅ size + 2 ⋅ (2+max(-1, size)), OnUIThread:false, [{2+max(-1, size)},Loop,{size},Loop] codetoanalyze/c/performance/loops.c, ptr_cmp, 5 + 5 ⋅ size + 2 ⋅ (2+max(-1, size)), OnUIThread:false, [{2+max(-1, size)},Loop,{size},Loop]
codetoanalyze/c/performance/purity.c, loop, 7007, OnUIThread:false, [] codetoanalyze/c/performance/purity.c, loop, 6007 + 1000 ⋅ |fun_ptr|, OnUIThread:false, []
codetoanalyze/c/performance/switch_continue.c, test_switch_FN, 601, OnUIThread:false, [] codetoanalyze/c/performance/switch_continue.c, test_switch_FN, 601, OnUIThread:false, []
codetoanalyze/c/performance/switch_continue.c, unroll_loop, 16 + (n - 1) + 11 ⋅ (max(1, n)), OnUIThread:false, [{max(1, n)},Loop,{n - 1},Loop] codetoanalyze/c/performance/switch_continue.c, unroll_loop, 16 + (n - 1) + 11 ⋅ (max(1, n)), OnUIThread:false, [{max(1, n)},Loop,{n - 1},Loop]
codetoanalyze/c/performance/two_loops_symbolic.c, nop, 2, OnUIThread:false, [] codetoanalyze/c/performance/two_loops_symbolic.c, nop, 2, OnUIThread:false, []

@ -38,3 +38,11 @@ void doBlockA_direct_block_linear(int a) {
loop_linear(a); loop_linear(a);
}); });
} }
void wrapper_runBlockA(BlockA block) { runBlockA(block); }
void call_wrapper_runBlockA_linear(int a) {
wrapper_runBlockA(^{
loop_linear(a);
});
}

@ -95,15 +95,19 @@ codetoanalyze/objc/performance/araii.m, Araii.initWithBuffer, 15, OnUIThread:fa
codetoanalyze/objc/performance/araii.m, Araii.setBuffer:, 4, OnUIThread:false, [] codetoanalyze/objc/performance/araii.m, Araii.setBuffer:, 4, OnUIThread:false, []
codetoanalyze/objc/performance/araii.m, memory_leak_raii_main, 18, OnUIThread:false, [] codetoanalyze/objc/performance/araii.m, memory_leak_raii_main, 18, OnUIThread:false, []
codetoanalyze/objc/performance/block.m, block_multiply_array_linear, 13 + 5 ⋅ array->elements.length.ub + 4 ⋅ (array->elements.length.ub + 1), OnUIThread:false, [{array->elements.length.ub + 1},Call to objc_blockblock_multiply_array_linear_1,Loop,{array->elements.length.ub},Call to objc_blockblock_multiply_array_linear_1,Loop] codetoanalyze/objc/performance/block.m, block_multiply_array_linear, 13 + 5 ⋅ array->elements.length.ub + 4 ⋅ (array->elements.length.ub + 1), OnUIThread:false, [{array->elements.length.ub + 1},Call to objc_blockblock_multiply_array_linear_1,Loop,{array->elements.length.ub},Call to objc_blockblock_multiply_array_linear_1,Loop]
codetoanalyze/objc/performance/block.m, call_wrapper_runBlockA_linear, 11 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to loop_linear,Loop,{a},Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, doBlockA_direct_block_linear, 10 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to runBlockA[objc_blockdoBlockA_direct_block_linear_3],Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop,{a},Call to runBlockA[objc_blockdoBlockA_direct_block_linear_3],Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop] codetoanalyze/objc/performance/block.m, doBlockA_direct_block_linear, 10 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to runBlockA[objc_blockdoBlockA_direct_block_linear_3],Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop,{a},Call to runBlockA[objc_blockdoBlockA_direct_block_linear_3],Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, doBlockA_linear, 12 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to runBlockA[objc_blockdoBlockA_linear_2],Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop,{a},Call to runBlockA[objc_blockdoBlockA_linear_2],Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop] codetoanalyze/objc/performance/block.m, doBlockA_linear, 12 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to runBlockA[objc_blockdoBlockA_linear_2],Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop,{a},Call to runBlockA[objc_blockdoBlockA_linear_2],Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, loop_linear, 3 + 3 ⋅ x + 2 ⋅ (1+max(0, x)), OnUIThread:false, [{1+max(0, x)},Loop,{x},Loop] codetoanalyze/objc/performance/block.m, loop_linear, 3 + 3 ⋅ x + 2 ⋅ (1+max(0, x)), OnUIThread:false, [{1+max(0, x)},Loop,{x},Loop]
codetoanalyze/objc/performance/block.m, objc_blockblock_multiply_array_linear_1, 8 + 5 ⋅ array->elements.length.ub + 4 ⋅ (array->elements.length.ub + 1), OnUIThread:false, [{array->elements.length.ub + 1},Loop,{array->elements.length.ub},Loop] codetoanalyze/objc/performance/block.m, objc_blockblock_multiply_array_linear_1, 8 + 5 ⋅ array->elements.length.ub + 4 ⋅ (array->elements.length.ub + 1), OnUIThread:false, [{array->elements.length.ub + 1},Loop,{array->elements.length.ub},Loop]
codetoanalyze/objc/performance/block.m, objc_blockcall_wrapper_runBlockA_linear_4, 5 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to loop_linear,Loop,{a},Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, objc_blockdoBlockA_direct_block_linear_3, 5 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to loop_linear,Loop,{a},Call to loop_linear,Loop] codetoanalyze/objc/performance/block.m, objc_blockdoBlockA_direct_block_linear_3, 5 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to loop_linear,Loop,{a},Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, objc_blockdoBlockA_linear_2, 5 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to loop_linear,Loop,{a},Call to loop_linear,Loop] codetoanalyze/objc/performance/block.m, objc_blockdoBlockA_linear_2, 5 + 3 ⋅ a + 2 ⋅ (1+max(0, a)), OnUIThread:false, [{1+max(0, a)},Call to loop_linear,Loop,{a},Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, runBlockA, 3, OnUIThread:false, [] codetoanalyze/objc/performance/block.m, runBlockA, 2 + |block|, OnUIThread:false, []
codetoanalyze/objc/performance/block.m, runBlockA[objc_blockdoBlockA_direct_block_linear_3], 8 + 3 ⋅ a[doBlockA_direct_block_linear()] + 2 ⋅ (1+max(0, a[doBlockA_direct_block_linear()])), OnUIThread:false, [{1+max(0, a[doBlockA_direct_block_linear()])},Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop,{a[doBlockA_direct_block_linear()]},Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop] codetoanalyze/objc/performance/block.m, runBlockA[objc_blockdoBlockA_direct_block_linear_3], 8 + 3 ⋅ a[doBlockA_direct_block_linear()] + 2 ⋅ (1+max(0, a[doBlockA_direct_block_linear()])), OnUIThread:false, [{1+max(0, a[doBlockA_direct_block_linear()])},Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop,{a[doBlockA_direct_block_linear()]},Call to objc_blockdoBlockA_direct_block_linear_3,Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, runBlockA[objc_blockdoBlockA_linear_2], 8 + 3 ⋅ a[doBlockA_linear()] + 2 ⋅ (1+max(0, a[doBlockA_linear()])), OnUIThread:false, [{1+max(0, a[doBlockA_linear()])},Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop,{a[doBlockA_linear()]},Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop] codetoanalyze/objc/performance/block.m, runBlockA[objc_blockdoBlockA_linear_2], 8 + 3 ⋅ a[doBlockA_linear()] + 2 ⋅ (1+max(0, a[doBlockA_linear()])), OnUIThread:false, [{1+max(0, a[doBlockA_linear()])},Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop,{a[doBlockA_linear()]},Call to objc_blockdoBlockA_linear_2,Call to loop_linear,Loop]
codetoanalyze/objc/performance/block.m, wrapper_runBlockA, 4 + |block|, OnUIThread:false, []
codetoanalyze/objc/performance/block.m, wrapper_runBlockA[objc_blockcall_wrapper_runBlockA_linear_4], 4 + |block|, OnUIThread:false, []
codetoanalyze/objc/performance/break.m, break_constant_FP, 8 + 5 ⋅ p + 2 ⋅ (1+max(0, p)), OnUIThread:false, [{1+max(0, p)},Call to break_loop,Loop,{p},Call to break_loop,Loop] codetoanalyze/objc/performance/break.m, break_constant_FP, 8 + 5 ⋅ p + 2 ⋅ (1+max(0, p)), OnUIThread:false, [{1+max(0, p)},Call to break_loop,Loop,{p},Call to break_loop,Loop]
codetoanalyze/objc/performance/break.m, break_loop, 5 + 5 ⋅ p + 2 ⋅ (1+max(0, p)), OnUIThread:false, [{1+max(0, p)},Loop,{p},Loop] codetoanalyze/objc/performance/break.m, break_loop, 5 + 5 ⋅ p + 2 ⋅ (1+max(0, p)), OnUIThread:false, [{1+max(0, p)},Loop,{p},Loop]
codetoanalyze/objc/performance/break.m, break_loop_with_t, 7 + 5 ⋅ p + 2 ⋅ (1+max(0, p)), OnUIThread:false, [{1+max(0, p)},Loop,{p},Loop] codetoanalyze/objc/performance/break.m, break_loop_with_t, 7 + 5 ⋅ p + 2 ⋅ (1+max(0, p)), OnUIThread:false, [{1+max(0, p)},Loop,{p},Loop]
@ -202,7 +206,7 @@ codetoanalyze/objc/performance/mutable_copy_test.m, MyMutableObj.mutableCopyWith
codetoanalyze/objc/performance/mutable_copy_test.m, MyMutableObj.objects, 7, OnUIThread:false, [] codetoanalyze/objc/performance/mutable_copy_test.m, MyMutableObj.objects, 7, OnUIThread:false, []
codetoanalyze/objc/performance/mutable_copy_test.m, MyMutableObj.setMObjects:, 4, OnUIThread:false, [] codetoanalyze/objc/performance/mutable_copy_test.m, MyMutableObj.setMObjects:, 4, OnUIThread:false, []
codetoanalyze/objc/performance/mutable_copy_test.m, loop_over_mutable_copy_linear, 36 + 3 ⋅ b->_mObjects->elements.length.ub + 3 ⋅ (b->_mObjects->elements.length.ub + 1), OnUIThread:false, [{b->_mObjects->elements.length.ub + 1},Loop,{b->_mObjects->elements.length.ub},Loop] codetoanalyze/objc/performance/mutable_copy_test.m, loop_over_mutable_copy_linear, 36 + 3 ⋅ b->_mObjects->elements.length.ub + 3 ⋅ (b->_mObjects->elements.length.ub + 1), OnUIThread:false, [{b->_mObjects->elements.length.ub + 1},Loop,{b->_mObjects->elements.length.ub},Loop]
codetoanalyze/objc/performance/purity.m, loop, 7007, OnUIThread:false, [] codetoanalyze/objc/performance/purity.m, loop, 6007 + 1000 ⋅ |fun_ptr|, OnUIThread:false, []
codetoanalyze/objc/performance/switch_continue.m, test_switch_FN, 601, OnUIThread:false, [] codetoanalyze/objc/performance/switch_continue.m, test_switch_FN, 601, OnUIThread:false, []
codetoanalyze/objc/performance/switch_continue.m, unroll_loop, 16 + (n - 1) + 11 ⋅ (max(1, n)), OnUIThread:false, [{max(1, n)},Loop,{n - 1},Loop] codetoanalyze/objc/performance/switch_continue.m, unroll_loop, 16 + (n - 1) + 11 ⋅ (max(1, n)), OnUIThread:false, [{max(1, n)},Loop,{n - 1},Loop]
codetoanalyze/objc/performance/two_loops_symbolic.m, nop, 2, OnUIThread:false, [] codetoanalyze/objc/performance/two_loops_symbolic.m, nop, 2, OnUIThread:false, []

Loading…
Cancel
Save