[Cost] Use OneInstrPerNode CFG

Summary:
We want instr-granular invariant maps so let's use the OneInstrPerNode CFG in the AI analyzers.
This requires specializing the TransferFunctions.
Keep using the normal CFG where we only need node-granular informations.

Depends on D7587241
Depends on D7608526

Reviewed By: sblackshear

Differential Revision: D7618320

fbshipit-source-id: 73918f0
master
Mehdi Bouaziz 7 years ago committed by Facebook Github Bot
parent 00d79ec839
commit 094eb9dcc7

@ -156,8 +156,8 @@ module Pair (Domain1 : S) (Domain2 : S) = struct
let pp fmt (astate1, astate2) = F.fprintf fmt "(%a, %a)" Domain1.pp astate1 Domain2.pp astate2 let pp fmt (astate1, astate2) = F.fprintf fmt "(%a, %a)" Domain1.pp astate1 Domain2.pp astate2
end end
module FiniteSet (Element : PrettyPrintable.PrintableOrderedType) = struct module FiniteSetOfPPSet (S : PrettyPrintable.PPSet) = struct
include PrettyPrintable.MakePPSet (Element) include S
type astate = t type astate = t
@ -168,6 +168,9 @@ module FiniteSet (Element : PrettyPrintable.PrintableOrderedType) = struct
let widen ~prev ~next ~num_iters:_ = join prev next let widen ~prev ~next ~num_iters:_ = join prev next
end end
module FiniteSet (Element : PrettyPrintable.PrintableOrderedType) =
FiniteSetOfPPSet (PrettyPrintable.MakePPSet (Element))
module InvertedSet (Element : PrettyPrintable.PrintableOrderedType) = struct module InvertedSet (Element : PrettyPrintable.PrintableOrderedType) = struct
include PrettyPrintable.MakePPSet (Element) include PrettyPrintable.MakePPSet (Element)

@ -70,6 +70,14 @@ end
(** Cartesian product of two domains. *) (** Cartesian product of two domains. *)
module Pair (Domain1 : S) (Domain2 : S) : S with type astate = Domain1.astate * Domain2.astate module Pair (Domain1 : S) (Domain2 : S) : S with type astate = Domain1.astate * Domain2.astate
(** Lift a PPSet to a powerset domain ordered by subset. The elements of the set should be drawn from
a *finite* collection of possible values, since the widening operator here is just union. *)
module FiniteSetOfPPSet (PPSet : PrettyPrintable.PPSet) : sig
include module type of PPSet with type elt = PPSet.elt
include WithBottom with type astate = t
end
(** Lift a set to a powerset domain ordered by subset. The elements of the set should be drawn from (** Lift a set to a powerset domain ordered by subset. The elements of the set should be drawn from
a *finite* collection of possible values, since the widening operator here is just union. *) a *finite* collection of possible values, since the widening operator here is just union. *)
module FiniteSet (Element : PrettyPrintable.PrintableOrderedType) : sig module FiniteSet (Element : PrettyPrintable.PrintableOrderedType) : sig

@ -25,8 +25,10 @@ end)
Currently it's set randomly to 200. *) Currently it's set randomly to 200. *)
let expensive_threshold = Itv.Bound.of_int 200 let expensive_threshold = Itv.Bound.of_int 200
(* CFG module used in several other modules *) (* CFG modules used in several other modules *)
module CFG = ProcCfg.Normal module InstrCFG = ProcCfg.NormalOneInstrPerNode
module NodeCFG = ProcCfg.Normal
module InstrCFGScheduler = Scheduler.ReversePostorder (InstrCFG)
module Node = struct module Node = struct
include ProcCfg.DefaultNode include ProcCfg.DefaultNode
@ -45,8 +47,8 @@ end
set it to 1 and for function call we take it from the spec of the function. set it to 1 and for function call we take it from the spec of the function.
The nodes in the domain of the map are those in the path reaching the current node. The nodes in the domain of the map are those in the path reaching the current node.
*) *)
module TransferFunctionsNodesBasicCost (CFG : ProcCfg.S) = struct module TransferFunctionsNodesBasicCost = struct
module CFG = CFG module CFG = InstrCFG
module InferboTransferFunctions = BufferOverrunChecker.TransferFunctions (CFG) module InferboTransferFunctions = BufferOverrunChecker.TransferFunctions (CFG)
module Domain = NodesBasicCostDomain module Domain = NodesBasicCostDomain
@ -54,21 +56,9 @@ module TransferFunctionsNodesBasicCost (CFG : ProcCfg.S) = struct
let cost_atomic_instruction = Itv.Bound.one let cost_atomic_instruction = Itv.Bound.one
let instr_idx (node: CFG.node) instr =
match CFG.instrs node with
| [] ->
0
| instrs ->
List.find_mapi_exn
~f:(fun idx i -> if Sil.equal_instr i instr then Some idx else None)
instrs
let exec_instr_cost _inferbo_mem (astate: CostDomain.NodeInstructionToCostMap.astate) let exec_instr_cost _inferbo_mem (astate: CostDomain.NodeInstructionToCostMap.astate)
{ProcData.pdesc} (node: CFG.node) instr : CostDomain.NodeInstructionToCostMap.astate = {ProcData.pdesc} (node: CFG.node) instr : CostDomain.NodeInstructionToCostMap.astate =
let nid_int = Procdesc.Node.get_id (CFG.underlying_node node) in let key = CFG.id node in
let instr_idx = instr_idx node instr in
let key = (nid_int, instr_idx) in
let astate' = let astate' =
match instr with match instr with
| Sil.Call (_, Exp.Const (Const.Cfun callee_pname), _, _, _) -> ( | Sil.Call (_, Exp.Const (Const.Cfun callee_pname), _, _, _) -> (
@ -94,10 +84,11 @@ module TransferFunctionsNodesBasicCost (CFG : ProcCfg.S) = struct
(inferbo_mem, costmap) (inferbo_mem, costmap)
let pp_session_name _node fmt = F.pp_print_string fmt "cost(basic)" let pp_session_name node fmt = F.fprintf fmt "cost(basic) %a" CFG.pp_id (CFG.id node)
end end
module AnalyzerNodesBasicCost = AbstractInterpreter.Make (CFG) (TransferFunctionsNodesBasicCost) module AnalyzerNodesBasicCost =
AbstractInterpreter.MakeNoCFG (InstrCFGScheduler) (TransferFunctionsNodesBasicCost)
(* Map associating to each node a bound on the number of times it can be executed. (* Map associating to each node a bound on the number of times it can be executed.
This bound is computed using environments (map: val -> values), using the following This bound is computed using environments (map: val -> values), using the following
@ -150,19 +141,20 @@ module BoundMap = struct
NonBottom env NonBottom env
let compute_upperbound_map pdesc invariant_map_NodesBasicCost data_invariant_map let compute_upperbound_map node_cfg invariant_map_NodesBasicCost data_invariant_map
control_invariant_map = control_invariant_map =
let fparam = Procdesc.get_formals pdesc in let fparam = Procdesc.get_formals node_cfg in
let pname = Procdesc.get_proc_name pdesc in let pname = Procdesc.get_proc_name node_cfg in
let fparam' = List.map ~f:(fun (m, _) -> Exp.Lvar (Pvar.mk m pname)) fparam in let fparam' = List.map ~f:(fun (m, _) -> Exp.Lvar (Pvar.mk m pname)) fparam in
let compute_node_upper_bound bound_map node = let compute_node_upper_bound bound_map node =
let node_id = Procdesc.Node.get_id node in let node_id = NodeCFG.id node in
match Procdesc.Node.get_kind node with match Procdesc.Node.get_kind node with
| Procdesc.Node.Exit_node _ -> | Procdesc.Node.Exit_node _ ->
Node.IdMap.add node_id Itv.Bound.one bound_map Node.IdMap.add node_id Itv.Bound.one bound_map
| _ -> | _ ->
let entry_state_opt = let entry_state_opt =
AnalyzerNodesBasicCost.extract_post node_id invariant_map_NodesBasicCost let instr_node_id = InstrCFG.of_underlying_node node |> InstrCFG.id in
AnalyzerNodesBasicCost.extract_pre instr_node_id invariant_map_NodesBasicCost
in in
match entry_state_opt with match entry_state_opt with
| Some (entry_mem, _) -> | Some (entry_mem, _) ->
@ -204,22 +196,20 @@ module BoundMap = struct
in in
let range = Itv.range itv' in let range = Itv.range itv' in
L.(debug Analysis Medium) L.(debug Analysis Medium)
"@\n>>>For node = %i : exp=%a itv=%a range =%a @\n\n" "@\n>>>For node = %a : exp=%a itv=%a range =%a @\n\n" Node.pp_id
(node_id :> int) node_id Exp.pp exp Itv.pp itv' Itv.Bound.pp range ;
Exp.pp exp Itv.pp itv' Itv.Bound.pp range ;
Itv.Bound.mult acc range ) Itv.Bound.mult acc range )
env Itv.Bound.one env Itv.Bound.one
in in
L.(debug Analysis Medium) L.(debug Analysis Medium)
"@\n>>>Setting bound for node = %i to %a@\n\n" "@\n>>>Setting bound for node = %a to %a@\n\n" Node.pp_id node_id Itv.Bound.pp
(node_id :> int) bound ;
Itv.Bound.pp bound ;
Node.IdMap.add node_id bound bound_map Node.IdMap.add node_id bound bound_map
| _ -> | _ ->
Node.IdMap.add node_id Itv.Bound.zero bound_map Node.IdMap.add node_id Itv.Bound.zero bound_map
in in
let bound_map = let bound_map =
List.fold (CFG.nodes pdesc) ~f:compute_node_upper_bound ~init:Node.IdMap.empty List.fold (NodeCFG.nodes node_cfg) ~f:compute_node_upper_bound ~init:Node.IdMap.empty
in in
print_upper_bound_map bound_map ; bound_map print_upper_bound_map bound_map ; bound_map
@ -279,25 +269,25 @@ module StructuralConstraints = struct
i<=Sum_{j \in Predecessors(i) } j i<=Sum_{j \in Predecessors(i) } j
i<=Sum_{j \in Successors(i)} j i<=Sum_{j \in Successors(i)} j
*) *)
let compute_structural_constraints cfg = let compute_structural_constraints node_cfg =
let compute_node_constraints acc node = let compute_node_constraints acc node =
let constraints_append node get_nodes tail = let constraints_append node get_nodes tail =
match get_nodes node with match get_nodes node with
| [] -> | [] ->
tail tail
| [single] -> | [single] ->
{lhs= CFG.id node; rhs= Single (CFG.id single)} :: tail {lhs= NodeCFG.id node; rhs= Single (NodeCFG.id single)} :: tail
| nodes -> | nodes ->
let sum = let sum =
List.fold nodes ~init:Node.IdSet.empty ~f:(fun idset node -> List.fold nodes ~init:Node.IdSet.empty ~f:(fun idset node ->
Node.IdSet.add (CFG.id node) idset ) Node.IdSet.add (NodeCFG.id node) idset )
in in
{lhs= CFG.id node; rhs= Sum sum} :: tail {lhs= NodeCFG.id node; rhs= Sum sum} :: tail
in in
acc |> constraints_append node Procdesc.Node.get_preds acc |> constraints_append node Procdesc.Node.get_preds
|> constraints_append node Procdesc.Node.get_succs |> constraints_append node Procdesc.Node.get_succs
in in
let constraints = List.fold (CFG.nodes cfg) ~f:compute_node_constraints ~init:[] in let constraints = List.fold (NodeCFG.nodes node_cfg) ~f:compute_node_constraints ~init:[] in
print_constraint_list constraints ; constraints print_constraint_list constraints ; constraints
end end
@ -436,7 +426,7 @@ return the addends of the sum x_j1+x_j2+..+x_j_n*)
branch node branch node
let compute_trees_from_contraints bound_map cfg constraints = let compute_trees_from_contraints bound_map node_cfg constraints =
(* a map used for bookkeeping of the min trees that we have already built *) (* a map used for bookkeeping of the min trees that we have already built *)
let global_built_tree_map : mt_node BuiltTreeMap.t ref = ref BuiltTreeMap.empty in let global_built_tree_map : mt_node BuiltTreeMap.t ref = ref BuiltTreeMap.empty in
let min_trees = let min_trees =
@ -447,7 +437,7 @@ return the addends of the sum x_j1+x_j2+..+x_j_n*)
minimum_propagation bound_map nid Node.IdSet.empty constraints global_built_tree_map minimum_propagation bound_map nid Node.IdSet.empty constraints global_built_tree_map
in in
(nid, tree) :: acc ) (nid, tree) :: acc )
~init:[] (CFG.nodes cfg) ~init:[] (NodeCFG.nodes node_cfg)
in in
List.iter List.iter
~f:(fun (nid, t) -> L.(debug Analysis Medium) "@\n node %a = %a @\n" Node.pp_id nid pp t) ~f:(fun (nid, t) -> L.(debug Analysis Medium) "@\n node %a = %a @\n" Node.pp_id nid pp t)
@ -455,7 +445,7 @@ return the addends of the sum x_j1+x_j2+..+x_j_n*)
min_trees min_trees
end end
module ReportedOnNodes = AbstractDomain.FiniteSet (Int) module ReportedOnNodes = AbstractDomain.FiniteSetOfPPSet (Node.IdSet)
type extras_TransferFunctionsWCET = type extras_TransferFunctionsWCET =
{ basic_cost_map: AnalyzerNodesBasicCost.invariant_map { basic_cost_map: AnalyzerNodesBasicCost.invariant_map
@ -466,15 +456,15 @@ type extras_TransferFunctionsWCET =
It uses the basic cost of the nodes (computed previously by AnalyzerNodesBasicCost) It uses the basic cost of the nodes (computed previously by AnalyzerNodesBasicCost)
and MinTrees which give an upperbound on the number of times a node can be executed and MinTrees which give an upperbound on the number of times a node can be executed
*) *)
module TransferFunctionsWCET (CFG : ProcCfg.S) = struct module TransferFunctionsWCET = struct
module CFG = CFG module CFG = InstrCFG
module Domain = AbstractDomain.Pair (Itv.Bound) (ReportedOnNodes) module Domain = AbstractDomain.Pair (Itv.Bound) (ReportedOnNodes)
type extras = extras_TransferFunctionsWCET type extras = extras_TransferFunctionsWCET
(* We don't report when the cost is Top as it corresponds to subsequent 'don't know's. (* We don't report when the cost is Top as it corresponds to subsequent 'don't know's.
Instead, we report Top cost only at the top level per function when `report_infinity` is set to true *) Instead, we report Top cost only at the top level per function when `report_infinity` is set to true *)
let report_cost summary instr (cost: Itv.Bound.t) nid reported_so_far = let report_cost summary instr (cost: Itv.Bound.t) instr_node reported_so_far =
let mk_message () = let mk_message () =
F.asprintf F.asprintf
"The execution time from the beginning of the function up to this program point is likely \ "The execution time from the beginning of the function up to this program point is likely \
@ -494,6 +484,7 @@ module TransferFunctionsWCET (CFG : ProcCfg.S) = struct
(IssueType.expensive_execution_time_call, Localise.verbatim_desc (mk_message ())) (IssueType.expensive_execution_time_call, Localise.verbatim_desc (mk_message ()))
in in
Reporting.log_error summary ~loc ~ltr exn ; Reporting.log_error summary ~loc ~ltr exn ;
let nid = instr_node |> CFG.underlying_node |> Procdesc.Node.get_id in
(cost, ReportedOnNodes.add nid reported_so_far) (cost, ReportedOnNodes.add nid reported_so_far)
| Sil.Load (_, _, _, loc) | Sil.Load (_, _, _, loc)
| Sil.Store (_, _, _, loc) | Sil.Store (_, _, _, loc)
@ -506,6 +497,7 @@ module TransferFunctionsWCET (CFG : ProcCfg.S) = struct
(IssueType.expensive_execution_time_call, Localise.verbatim_desc (mk_message ())) (IssueType.expensive_execution_time_call, Localise.verbatim_desc (mk_message ()))
in in
Reporting.log_error summary ~loc ~ltr exn ; Reporting.log_error summary ~loc ~ltr exn ;
let nid = instr_node |> CFG.underlying_node |> Procdesc.Node.get_id in
(cost, ReportedOnNodes.add nid reported_so_far) (cost, ReportedOnNodes.add nid reported_so_far)
| _ -> | _ ->
(cost, reported_so_far) ) (cost, reported_so_far) )
@ -517,48 +509,49 @@ module TransferFunctionsWCET (CFG : ProcCfg.S) = struct
least one of them. In that case no need to report again. *) least one of them. In that case no need to report again. *)
let should_report preds reported_so_far = let should_report preds reported_so_far =
List.for_all List.for_all
~f:(fun n -> ~f:(fun node ->
let n_id = (Procdesc.Node.get_id n :> int) in let nid = Procdesc.Node.get_id node in
not (ReportedOnNodes.mem n_id reported_so_far) ) not (ReportedOnNodes.mem nid reported_so_far) )
preds preds
let exec_instr (astate: Domain.astate) {ProcData.extras} (node: CFG.node) instr : Domain.astate = let map_cost trees m : Itv.Bound.t =
CostDomain.NodeInstructionToCostMap.fold
(fun ((node_id, _) as instr_node_id) c acc ->
let t = Node.IdMap.find node_id trees in
let c_node = Itv.Bound.mult c t in
let c_node' = Itv.Bound.plus_u acc c_node in
L.(debug Analysis Medium)
"@\n [AnalyzerWCET] Adding cost: (%a) --> c =%a t = %a @\n" InstrCFG.pp_id
instr_node_id Itv.Bound.pp c Itv.Bound.pp t ;
L.(debug Analysis Medium)
"@\n [AnalyzerWCET] Adding cost: (%a) --> c_node=%a cost = %a @\n" InstrCFG.pp_id
instr_node_id Itv.Bound.pp c_node Itv.Bound.pp c_node' ;
c_node' )
m Itv.Bound.zero
let exec_instr ((_, reported_so_far): Domain.astate) {ProcData.extras} (node: CFG.node) instr
: Domain.astate =
let {basic_cost_map= invariant_map_cost; min_trees_map= trees; summary} = extras in let {basic_cost_map= invariant_map_cost; min_trees_map= trees; summary} = extras in
let map_cost m : Itv.Bound.t =
CostDomain.NodeInstructionToCostMap.fold
(fun ((node_id, _) as instr_node_id) c acc ->
let t = Node.IdMap.find node_id trees in
let c_node = Itv.Bound.mult c t in
L.(debug Analysis Medium)
"@\n [AnalyzerWCET] Adding cost: (%a) --> c =%a t = %a @\n" ProcCfg.InstrNode.pp_id
instr_node_id Itv.Bound.pp c Itv.Bound.pp t ;
let c_node' = Itv.Bound.plus_u acc c_node in
L.(debug Analysis Medium)
"@\n [AnalyzerWCET] Adding cost: (%a) --> c_node=%a cost = %a @\n"
ProcCfg.InstrNode.pp_id instr_node_id Itv.Bound.pp c_node Itv.Bound.pp c_node' ;
c_node' )
m Itv.Bound.zero
in
let und_node = CFG.underlying_node node in
let node_id = Procdesc.Node.get_id und_node in
let cost_node = let cost_node =
match AnalyzerNodesBasicCost.extract_post node_id invariant_map_cost with let instr_node_id = CFG.id node in
match AnalyzerNodesBasicCost.extract_post instr_node_id invariant_map_cost with
| Some (_, node_map) -> | Some (_, node_map) ->
L.(debug Analysis Medium) L.(debug Analysis Medium)
"@\n AnalyzerWCET] Final map for node: %a @\n" Procdesc.Node.pp_id node_id ; "@\n AnalyzerWCET] Final map for node: %a @\n" CFG.pp_id instr_node_id ;
map_cost node_map map_cost trees node_map
| _ -> | _ ->
assert false assert false
in in
L.(debug Analysis Medium) L.(debug Analysis Medium)
"@\n>>>AnalyzerWCET] Instr: %a Cost: %a@\n" (Sil.pp_instr Pp.text) instr Itv.Bound.pp "@\n>>>AnalyzerWCET] Instr: %a Cost: %a@\n" (Sil.pp_instr Pp.text) instr Itv.Bound.pp
cost_node ; cost_node ;
let reported_so_far = snd astate in
let astate' = let astate' =
let und_node = CFG.underlying_node node in
let preds = Procdesc.Node.get_preds und_node in let preds = Procdesc.Node.get_preds und_node in
if should_report (und_node :: preds) reported_so_far then if should_report (und_node :: preds) reported_so_far then
report_cost summary instr cost_node (node_id :> int) reported_so_far report_cost summary instr cost_node node reported_so_far
else (cost_node, reported_so_far) else (cost_node, reported_so_far)
in in
astate' astate'
@ -567,7 +560,7 @@ module TransferFunctionsWCET (CFG : ProcCfg.S) = struct
let pp_session_name _node fmt = F.pp_print_string fmt "cost(wcet)" let pp_session_name _node fmt = F.pp_print_string fmt "cost(wcet)"
end end
module AnalyzerWCET = AbstractInterpreter.Make (CFG) (TransferFunctionsWCET) module AnalyzerWCET = AbstractInterpreter.MakeNoCFG (InstrCFGScheduler) (TransferFunctionsWCET)
let check_and_report_infinity cost proc_desc summary = let check_and_report_infinity cost proc_desc summary =
if not (Itv.Bound.is_not_infty cost) then if not (Itv.Bound.is_not_infty cost) then
@ -585,31 +578,34 @@ let check_and_report_infinity cost proc_desc summary =
let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary =
Preanal.do_preanalysis proc_desc tenv ; Preanal.do_preanalysis proc_desc tenv ;
let proc_data = ProcData.make_default proc_desc tenv in let proc_data = ProcData.make_default proc_desc tenv in
let cfg = CFG.from_pdesc proc_desc in let node_cfg = NodeCFG.from_pdesc proc_desc in
(* computes the data dependencies: node -> (var -> var set) *) (* computes the data dependencies: node -> (var -> var set) *)
let data_dep_invariant_map = let data_dep_invariant_map =
Control.DataDepAnalyzer.exec_cfg cfg proc_data ~initial:Control.DataDepMap.empty ~debug:true Control.DataDepAnalyzer.exec_cfg node_cfg proc_data ~initial:Control.DataDepMap.empty
~debug:true
in in
(* computes the control dependencies: node -> var set *) (* computes the control dependencies: node -> var set *)
let control_dep_invariant_map = let control_dep_invariant_map =
Control.ControlDepAnalyzer.exec_cfg cfg proc_data ~initial:Control.ControlDepSet.empty Control.ControlDepAnalyzer.exec_cfg node_cfg proc_data ~initial:Control.ControlDepSet.empty
~debug:true ~debug:true
in in
let instr_cfg = InstrCFG.from_pdesc proc_desc in
let invariant_map_NodesBasicCost = let invariant_map_NodesBasicCost =
(*compute_WCET cfg invariant_map min_trees in *) (*compute_WCET cfg invariant_map min_trees in *)
AnalyzerNodesBasicCost.exec_cfg cfg proc_data ~initial:NodesBasicCostDomain.init ~debug:true AnalyzerNodesBasicCost.exec_cfg instr_cfg proc_data ~initial:NodesBasicCostDomain.init
~debug:true
in in
(* given the semantics computes the upper bound on the number of times a node could be executed *) (* given the semantics computes the upper bound on the number of times a node could be executed *)
let bound_map = let bound_map =
BoundMap.compute_upperbound_map cfg invariant_map_NodesBasicCost data_dep_invariant_map BoundMap.compute_upperbound_map node_cfg invariant_map_NodesBasicCost data_dep_invariant_map
control_dep_invariant_map control_dep_invariant_map
in in
let constraints = StructuralConstraints.compute_structural_constraints cfg in let constraints = StructuralConstraints.compute_structural_constraints node_cfg in
L.internal_error "@\n[COST ANALYSIS] PROCESSING MIN_TREE for PROCEDURE '%a' |CFG| = %i " L.internal_error "@\n[COST ANALYSIS] PROCESSING MIN_TREE for PROCEDURE '%a' |CFG| = %i "
Typ.Procname.pp Typ.Procname.pp
(Procdesc.get_proc_name proc_desc) (Procdesc.get_proc_name proc_desc)
(List.length (CFG.nodes cfg)) ; (List.length (NodeCFG.nodes node_cfg)) ;
let min_trees = MinTree.compute_trees_from_contraints bound_map cfg constraints in let min_trees = MinTree.compute_trees_from_contraints bound_map node_cfg constraints in
let trees_valuation = let trees_valuation =
List.fold List.fold
~f:(fun acc (nid, t) -> ~f:(fun acc (nid, t) ->
@ -621,12 +617,14 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary =
let initWCET = (Itv.Bound.zero, ReportedOnNodes.empty) in let initWCET = (Itv.Bound.zero, ReportedOnNodes.empty) in
let invariant_map_WCETFinal = let invariant_map_WCETFinal =
(* Final map with nodes cost *) (* Final map with nodes cost *)
AnalyzerWCET.exec_cfg cfg AnalyzerWCET.exec_cfg instr_cfg
(ProcData.make proc_desc tenv (ProcData.make proc_desc tenv
{basic_cost_map= invariant_map_NodesBasicCost; min_trees_map= trees_valuation; summary}) {basic_cost_map= invariant_map_NodesBasicCost; min_trees_map= trees_valuation; summary})
~initial:initWCET ~debug:true ~initial:initWCET ~debug:true
in in
match AnalyzerWCET.extract_post (CFG.id (CFG.exit_node cfg)) invariant_map_WCETFinal with match
AnalyzerWCET.extract_post (InstrCFG.id (InstrCFG.exit_node instr_cfg)) invariant_map_WCETFinal
with
| Some (exit_cost, _) -> | Some (exit_cost, _) ->
L.internal_error " PROCEDURE COST = %a @\n" Itv.Bound.pp exit_cost ; L.internal_error " PROCEDURE COST = %a @\n" Itv.Bound.pp exit_cost ;
check_and_report_infinity exit_cost proc_desc summary ; check_and_report_infinity exit_cost proc_desc summary ;

@ -6,22 +6,22 @@ codetoanalyze/c/performance/cost_test.c, loop0_bad, 5, EXPENSIVE_EXECUTION_TIME_
codetoanalyze/c/performance/cost_test.c, loop1_bad, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1104] codetoanalyze/c/performance/cost_test.c, loop1_bad, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1104]
codetoanalyze/c/performance/cost_test.c, loop1_bad, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1104] codetoanalyze/c/performance/cost_test.c, loop1_bad, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1104]
codetoanalyze/c/performance/cost_test.c, loop1_bad, 6, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1106] codetoanalyze/c/performance/cost_test.c, loop1_bad, 6, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1106]
codetoanalyze/c/performance/cost_test.c, main_bad, 8, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 212] codetoanalyze/c/performance/cost_test.c, main_bad, 8, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 211]
codetoanalyze/c/performance/cost_test_deps.c, if_bad_loop, 12, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 202] codetoanalyze/c/performance/cost_test_deps.c, if_bad_loop, 12, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 201]
codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204] codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204]
codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204] codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204]
codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204] codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204]
codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 5, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204] codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 5, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1204]
codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 9, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1207] codetoanalyze/c/performance/cost_test_deps.c, loop_despite_inferbo, 9, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 1206]
codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep1, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 605] codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep1, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 605]
codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep1, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 605] codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep1, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 605]
codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep1, 6, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 608] codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep1, 6, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 607]
codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep2, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 609] codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep2, 3, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 609]
codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep2, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 609] codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep2, 4, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 609]
codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep2, 6, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 612] codetoanalyze/c/performance/cost_test_deps.c, loop_no_dep2, 6, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 611]
codetoanalyze/c/performance/cost_test_deps.c, nested_loop, 0, INFINITE_EXECUTION_TIME_CALL, ERROR, [] codetoanalyze/c/performance/cost_test_deps.c, nested_loop, 0, INFINITE_EXECUTION_TIME_CALL, ERROR, []
codetoanalyze/c/performance/cost_test_deps.c, simulated_nested_loop, 0, INFINITE_EXECUTION_TIME_CALL, ERROR, [] codetoanalyze/c/performance/cost_test_deps.c, simulated_nested_loop, 0, INFINITE_EXECUTION_TIME_CALL, ERROR, []
codetoanalyze/c/performance/cost_test_deps.c, simulated_nested_loop_more_expensive, 0, INFINITE_EXECUTION_TIME_CALL, ERROR, [] codetoanalyze/c/performance/cost_test_deps.c, simulated_nested_loop_more_expensive, 0, INFINITE_EXECUTION_TIME_CALL, ERROR, []
codetoanalyze/c/performance/cost_test_deps.c, two_loops, 7, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 545] codetoanalyze/c/performance/cost_test_deps.c, two_loops, 7, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 545]
codetoanalyze/c/performance/cost_test_deps.c, two_loops, 8, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 545] codetoanalyze/c/performance/cost_test_deps.c, two_loops, 8, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 545]
codetoanalyze/c/performance/cost_test_deps.c, two_loops, 10, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 548] codetoanalyze/c/performance/cost_test_deps.c, two_loops, 10, EXPENSIVE_EXECUTION_TIME_CALL, ERROR, [with estimated cost 547]

Loading…
Cancel
Save