[cost] The first cost model is a log

Reviewed By: ezgicicek

Differential Revision: D13175881

fbshipit-source-id: 7718bdf0d
master
Mehdi Bouaziz 6 years ago committed by Facebook Github Bot
parent 2ebbf554e5
commit 85bab87d16

@ -13,8 +13,6 @@ open Ints
module DegreeKind = struct module DegreeKind = struct
type t = Linear | Log [@@deriving compare] type t = Linear | Log [@@deriving compare]
let[@warning "-32"] _i_know_log_isn't_used_for_now = Log
let compute d i = let compute d i =
match d with match d with
| Linear -> | Linear ->
@ -421,9 +419,9 @@ module NonNegativePolynomial = struct
let of_int_exn i = NonTop (NonNegativeNonTopPolynomial.of_int_exn i) let of_int_exn i = NonTop (NonNegativeNonTopPolynomial.of_int_exn i)
let of_non_negative_bound b = let of_non_negative_bound ?(degree_kind = DegreeKind.Linear) b =
b b
|> NonNegativeBoundWithDegreeKind.make DegreeKind.Linear |> NonNegativeBoundWithDegreeKind.make degree_kind
|> NonNegativeBoundWithDegreeKind.classify |> NonNegativeNonTopPolynomial.of_valclass |> NonNegativeBoundWithDegreeKind.classify |> NonNegativeNonTopPolynomial.of_valclass

@ -8,6 +8,10 @@
open! IStd open! IStd
module Bound = Bounds.Bound module Bound = Bounds.Bound
module DegreeKind : sig
type t = Linear | Log
end
module Degree : sig module Degree : sig
type t [@@deriving compare] type t [@@deriving compare]
@ -36,7 +40,7 @@ module NonNegativePolynomial : sig
val is_one : t -> bool val is_one : t -> bool
val of_non_negative_bound : Bounds.NonNegativeBound.t -> t val of_non_negative_bound : ?degree_kind:DegreeKind.t -> Bounds.NonNegativeBound.t -> t
val plus : t -> t -> t val plus : t -> t -> t

@ -66,14 +66,18 @@ module TransferFunctionsNodesBasicCost = struct
match instr with match instr with
| Sil.Call (_, Exp.Const (Const.Cfun callee_pname), params, _, _) -> | Sil.Call (_, Exp.Const (Const.Cfun callee_pname), params, _, _) ->
let callee_cost = let callee_cost =
match Payload.read pdesc callee_pname with match CostModels.Call.dispatch () callee_pname params with
| Some {post= callee_cost} -> | Some model ->
if BasicCost.is_symbolic callee_cost then model inferbo_mem
instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem | None -> (
~callee_pname ~params ~callee_cost match Payload.read pdesc callee_pname with
else callee_cost | Some {post= callee_cost} ->
| None -> if BasicCost.is_symbolic callee_cost then
cost_atomic_instruction instantiate_cost integer_type_widths ~inferbo_caller_mem:inferbo_mem
~callee_pname ~params ~callee_cost
else callee_cost
| None ->
cost_atomic_instruction )
in in
CostDomain.NodeInstructionToCostMap.add key callee_cost astate CostDomain.NodeInstructionToCostMap.add key callee_cost astate
| Sil.Load _ | Sil.Store _ | Sil.Call _ | Sil.Prune _ -> | Sil.Load _ | Sil.Store _ | Sil.Call _ | Sil.Prune _ ->

@ -0,0 +1,40 @@
(*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module BasicCost = CostDomain.BasicCost
type model = BufferOverrunDomain.Mem.t -> BasicCost.t
module Collections = struct
let eval_collection_length coll_exp inferbo_mem =
let upper_bound =
let itv =
BufferOverrunModels.Collection.eval_collection_length coll_exp inferbo_mem
|> BufferOverrunDomain.Val.get_itv
in
match itv with Bottom -> Bounds.Bound.PInf | NonBottom itv_pure -> Itv.ItvPure.ub itv_pure
in
Bounds.NonNegativeBound.of_bound upper_bound
let n_log_n b =
let n = BasicCost.of_non_negative_bound b in
let log_n = BasicCost.of_non_negative_bound ~degree_kind:Polynomials.DegreeKind.Log b in
BasicCost.mult n log_n
let sort coll_exp inferbo_mem =
let length = eval_collection_length coll_exp inferbo_mem in
n_log_n length
end
module Call = struct
let dispatch : (unit, model) ProcnameDispatcher.Call.dispatcher =
let open ProcnameDispatcher.Call in
make_dispatcher [-"java.util.Collections" &:: "sort" $ capt_exp $--> Collections.sort]
end

@ -1 +1 @@
{"top":{"current":1,"previous":0},"zero":{"current":0,"previous":0},"degrees":[{"degree":0,"current":3,"previous":2},{"degree":100,"current":1,"previous":1},{"degree":200,"current":0,"previous":1}]} {"top":{"current":1,"previous":0},"zero":{"current":0,"previous":0},"degrees":[{"degree":0,"current":3,"previous":2},{"degree":100,"current":1,"previous":2},{"degree":101,"current":2,"previous":0},{"degree":200,"current":0,"previous":2}]}

@ -0,0 +1 @@
PERFORMANCE_VARIATION, no_bucket, src/DiffExample.java, DiffExample.f6(java.util.ArrayList):void, 0

@ -1,2 +1,3 @@
INFINITE_EXECUTION_TIME_CALL, no_bucket, src/DiffExample.java, DiffExample.f1(int):void, 0 INFINITE_EXECUTION_TIME_CALL, no_bucket, src/DiffExample.java, DiffExample.f1(int):void, 0
PERFORMANCE_VARIATION, no_bucket, src/DiffExample.java, DiffExample.f4(int):int, 0 PERFORMANCE_VARIATION, no_bucket, src/DiffExample.java, DiffExample.f4(int):int, 0
PERFORMANCE_VARIATION, no_bucket, src/DiffExample.java, DiffExample.f5(java.util.ArrayList):void, 0

@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import java.util.ArrayList;
// This class has the following costs: // This class has the following costs:
// 1 bottom (zero), 2 constant, 1 linear, 1 top // 1 bottom (zero), 2 constant, 1 linear, 1 top
// constructor: constant // constructor: constant
@ -12,6 +14,8 @@
// f2: bottom (zero) // f2: bottom (zero)
// f3: constant // f3: constant
// f4: linear // f4: linear
// f5: n log n
// f6: n log n
public class DiffExample { public class DiffExample {
@ -41,4 +45,14 @@ public class DiffExample {
} }
return 0; return 0;
} }
// cost: n log n
private void f5(ArrayList<Integer> list) {
java.util.Collections.sort(list);
}
// cost: n log n
private void f6(ArrayList<Integer> list) {
f5(list);
}
} }

@ -11,6 +11,8 @@
// f1: linear // f1: linear
// f2: quadratic // f2: quadratic
// f4: constant // f4: constant
// f5: linear
// f6: quadratic
public class DiffExample { public class DiffExample {
// cost: linear // cost: linear
@ -32,4 +34,14 @@ public class DiffExample {
int i = 1; int i = 1;
return i + k; return i + k;
} }
// cost: linear
private static void f5(int n) {
f1(n);
}
// cost: quadratic
private static void f6(int n) {
f2(n);
}
} }

@ -197,4 +197,12 @@ public class ArrayListTest {
} }
return true; return true;
} }
public static void sortArrayList(ArrayList<Integer> list) {
java.util.Collections.sort(list);
}
private static void call_sortArrayList(ArrayList<Integer> list) {
sortArrayList(list);
}
} }

@ -25,6 +25,7 @@ codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remov
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_overrun_bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Through,Array access: Offset: 1 Size: 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_remove_overrun_bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Through,Array access: Offset: 1 Size: 1]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_set_overrun_bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Through,Array access: Offset: 1 Size: 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_set_overrun_bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Through,Array access: Offset: 1 Size: 1]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_set_underrun_bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 0 Size: 0] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.arraylist_set_underrun_bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 0 Size: 0]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.call_sortArrayList(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 4 + list.length.ub × log(list.length.ub), degree = 1 + 1⋅log]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 7 + 5 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 7 + 5 ⋅ list.length.ub, degree = 1]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ list.length.ub, degree = 1]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist_shortcut_FP(java.util.ArrayList):boolean, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 13 ⋅ (list.length.ub - 1) + 2 ⋅ (list.length.ub - 1) × (-Integer.intValue().lb + 11) + 4 ⋅ list.length.ub × (-Integer.intValue().lb + 11), degree = 2] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist_shortcut_FP(java.util.ArrayList):boolean, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 13 ⋅ (list.length.ub - 1) + 2 ⋅ (list.length.ub - 1) × (-Integer.intValue().lb + 11) + 4 ⋅ list.length.ub × (-Integer.intValue().lb + 11), degree = 2]
@ -41,6 +42,7 @@ codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_h
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 4, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 12 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 4, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 12 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 9 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 9 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 9 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 9 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1]
codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.sortArrayList(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 2 + list.length.ub × log(list.length.ub), degree = 1 + 1⋅log]
codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_constant(int):int, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 10 + 7 ⋅ p.ub, degree = 1] codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_constant(int):int, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 10 + 7 ⋅ p.ub, degree = 1]
codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_loop(int,int):int, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 3 + 7 ⋅ p.ub, degree = 1] codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_loop(int,int):int, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 3 + 7 ⋅ p.ub, degree = 1]
codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_loop(int,int):int, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 2 + 7 ⋅ p.ub, degree = 1] codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_loop(int,int):int, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 2 + 7 ⋅ p.ub, degree = 1]

Loading…
Cancel
Save