[sledge] Move analysis config options from Domain_intf to Control_intf

Summary:
The configuration options for the analysis are used only/principally
in Control, they do not belong in the interface of domains. Also, the
definition of the used_globals type for the results of the used
globals pre-analysis belongs to the Domain_used_globals module.

Reviewed By: jvillard

Differential Revision: D27828752

fbshipit-source-id: e42de74e0
master
Josh Berdine 4 years ago committed by Facebook GitHub Bot
parent 0cd75f8551
commit 716c207095

@ -74,22 +74,22 @@ let unmarshal file () =
let entry_points = Config.find_list "entry-points" let entry_points = Config.find_list "entry-points"
let used_globals pgm entry_points preanalyze : Domain_intf.used_globals = let used_globals pgm entry_points preanalyze =
let module UG = Domain_used_globals in
if preanalyze then if preanalyze then
let module Opts = struct let module Config = struct
let bound = 1 let bound = 1
let function_summaries = true let function_summaries = true
let entry_points = entry_points let entry_points = entry_points
let globals = Domain_intf.Declared Llair.Global.Set.empty let globals = UG.Declared Llair.Global.Set.empty
end in end in
let module Analysis = let module Analysis = Control.Make (Config) (UG) (Control.PriorityQueue)
Control.Make (Opts) (Domain_used_globals) (Control.PriorityQueue)
in in
let summary_table = Analysis.compute_summaries pgm in let summary_table = Analysis.compute_summaries pgm in
Per_function UG.Per_function
(Llair.Function.Map.map summary_table ~f:Llair.Global.Set.union_list) (Llair.Function.Map.map summary_table ~f:Llair.Global.Set.union_list)
else else
Declared UG.Declared
(Llair.Global.Set.of_iter (Llair.Global.Set.of_iter
(Iter.map ~f:(fun g -> g.name) (IArray.to_iter pgm.globals))) (Iter.map ~f:(fun g -> g.name) (IArray.to_iter pgm.globals)))
@ -129,7 +129,7 @@ let analyze =
Timer.enabled := stats ; Timer.enabled := stats ;
let pgm = program () in let pgm = program () in
let globals = used_globals pgm entry_points preanalyze_globals in let globals = used_globals pgm entry_points preanalyze_globals in
let module Opts = struct let module Config = struct
let bound = bound let bound = bound
let function_summaries = function_summaries let function_summaries = function_summaries
let entry_points = entry_points let entry_points = entry_points
@ -143,7 +143,8 @@ let analyze =
| `unit -> (module Domain_unit) | `unit -> (module Domain_unit)
in in
let module Dom = (val dom) in let module Dom = (val dom) in
let module Analysis = Control.Make (Opts) (Dom) (Control.PriorityQueue) let module Analysis =
Control.Make (Config) (Dom) (Control.PriorityQueue)
in in
Domain_sh.simplify_states := not no_simplify_states ; Domain_sh.simplify_states := not no_simplify_states ;
Option.iter dump_query ~f:(fun n -> Solver.dump_query := n) ; Option.iter dump_query ~f:(fun n -> Solver.dump_query := n) ;

@ -9,6 +9,8 @@
The analysis' semantics of control flow. *) The analysis' semantics of control flow. *)
open Control_intf
module type Elt = sig module type Elt = sig
type t [@@deriving compare, equal, sexp_of] type t [@@deriving compare, equal, sexp_of]
@ -74,10 +76,7 @@ module PriorityQueue (Elt : Elt) : QueueS with type elt = Elt.t = struct
Some (top, elts, {queue; removed}) Some (top, elts, {queue; removed})
end end
module Make module Make (Config : Config) (Dom : Domain_intf.Dom) (Queue : Queue) =
(Opts : Domain_intf.Opts)
(Dom : Domain_intf.Dom)
(Queue : Queue) =
struct struct
module Stack : sig module Stack : sig
type t type t
@ -265,7 +264,7 @@ struct
let prune depth edge queue = let prune depth edge queue =
[%Trace.info " %i: %a" depth Edge.pp edge] ; [%Trace.info " %i: %a" depth Edge.pp edge] ;
Report.hit_bound Opts.bound ; Report.hit_bound Config.bound ;
queue queue
let dequeue queue = let dequeue queue =
@ -289,7 +288,7 @@ struct
let edge = {Edge.dst= curr; src= prev; stk} in let edge = {Edge.dst= curr; src= prev; stk} in
let depth = Option.value (Depths.find edge depths) ~default:0 in let depth = Option.value (Depths.find edge depths) ~default:0 in
let depth = if retreating then depth + 1 else depth in let depth = if retreating then depth + 1 else depth in
if depth <= Opts.bound then enqueue depth edge state depths queue if depth <= Config.bound then enqueue depth edge state depths queue
else prune depth edge queue else prune depth edge queue
let init state curr = let init state curr =
@ -336,14 +335,14 @@ struct
Llair.Function.pp return.dst.parent.name Dom.pp state] Llair.Function.pp return.dst.parent.name Dom.pp state]
; ;
let dnf_states = let dnf_states =
if Opts.function_summaries then Dom.dnf state else [state] if Config.function_summaries then Dom.dnf state else [state]
in in
let domain_call = let domain_call =
Dom.call ~globals ~actuals ~areturn ~formals ~freturn ~locals Dom.call ~globals ~actuals ~areturn ~formals ~freturn ~locals
in in
List.fold dnf_states Work.skip ~f:(fun state acc -> List.fold dnf_states Work.skip ~f:(fun state acc ->
match match
if not Opts.function_summaries then None if not Config.function_summaries then None
else else
let state = fst (domain_call ~summaries:false state) in let state = fst (domain_call ~summaries:false state) in
let* summary = Llair.Function.Tbl.find summary_table name in let* summary = Llair.Function.Tbl.find summary_table name in
@ -351,7 +350,7 @@ struct
with with
| None -> | None ->
let state, from_call = let state, from_call =
domain_call ~summaries:Opts.function_summaries state domain_call ~summaries:Config.function_summaries state
in in
let stk = Stack.push_call call from_call stk in let stk = Stack.push_call call from_call stk in
Work.seq acc Work.seq acc
@ -371,7 +370,7 @@ struct
[%Trace.call fun {pf} -> pf "@ from: %a" Llair.Function.pp name] [%Trace.call fun {pf} -> pf "@ from: %a" Llair.Function.pp name]
; ;
let summarize post_state = let summarize post_state =
if not Opts.function_summaries then post_state if not Config.function_summaries then post_state
else else
let function_summary, post_state = let function_summary, post_state =
Dom.create_summary ~locals ~formals post_state Dom.create_summary ~locals ~formals post_state
@ -394,7 +393,7 @@ struct
let retn_state = Dom.retn formals freturn from_call post_state in let retn_state = Dom.retn formals freturn from_call post_state in
exec_jump stk retn_state block retn_site exec_jump stk retn_state block retn_site
| None -> | None ->
if Opts.function_summaries then if Config.function_summaries then
summarize exit_state |> (ignore : Dom.t -> unit) ; summarize exit_state |> (ignore : Dom.t -> unit) ;
Work.skip ) Work.skip )
|> |>
@ -457,7 +456,7 @@ struct
|> Work.seq x ) |> Work.seq x )
| Call ({callee} as call) -> | Call ({callee} as call) ->
exec_call stk state block call exec_call stk state block call
(Domain_used_globals.by_function Opts.globals callee.name) (Domain_used_globals.by_function Config.globals callee.name)
| ICall ({callee; areturn; return} as call) -> ( | ICall ({callee; areturn; return} as call) -> (
let lookup name = Llair.Func.find name pgm.functions in let lookup name = Llair.Func.find name pgm.functions in
match Dom.resolve_callee lookup callee state with match Dom.resolve_callee lookup callee state with
@ -465,7 +464,8 @@ struct
| callees -> | callees ->
List.fold callees Work.skip ~f:(fun callee x -> List.fold callees Work.skip ~f:(fun callee x ->
exec_call stk state block {call with callee} exec_call stk state block {call with callee}
(Domain_used_globals.by_function Opts.globals callee.name) (Domain_used_globals.by_function Config.globals
callee.name)
|> Work.seq x ) ) |> Work.seq x ) )
| Return {exp} -> exec_return stk state block exp | Return {exp} -> exec_return stk state block exp
| Throw {exc} -> exec_throw stk state block exc | Throw {exc} -> exec_throw stk state block exc
@ -501,12 +501,12 @@ struct
let call_entry_point : Llair.program -> Work.t option = let call_entry_point : Llair.program -> Work.t option =
fun pgm -> fun pgm ->
let+ {name; formals; freturn; locals; entry} = let+ {name; formals; freturn; locals; entry} =
List.find_map Opts.entry_points ~f:(fun entry_point -> List.find_map Config.entry_points ~f:(fun entry_point ->
let* func = Llair.Func.find entry_point pgm.functions in let* func = Llair.Func.find entry_point pgm.functions in
if IArray.is_empty func.formals then Some func else None ) if IArray.is_empty func.formals then Some func else None )
in in
let summaries = Opts.function_summaries in let summaries = Config.function_summaries in
let globals = Domain_used_globals.by_function Opts.globals name in let globals = Domain_used_globals.by_function Config.globals name in
let actuals = IArray.empty in let actuals = IArray.empty in
let areturn = None in let areturn = None in
let state, _ = let state, _ =
@ -522,7 +522,7 @@ struct
| None -> fail "no entry point found" () | None -> fail "no entry point found" ()
let compute_summaries pgm : Dom.summary list Llair.Function.Map.t = let compute_summaries pgm : Dom.summary list Llair.Function.Map.t =
assert Opts.function_summaries ; assert Config.function_summaries ;
exec_pgm pgm ; exec_pgm pgm ;
Llair.Function.Tbl.fold summary_table Llair.Function.Map.empty Llair.Function.Tbl.fold summary_table Llair.Function.Map.empty
~f:(fun ~key ~data map -> ~f:(fun ~key ~data map ->

@ -7,11 +7,13 @@
(** The analysis' semantics of control flow. *) (** The analysis' semantics of control flow. *)
open Control_intf
module type Queue module type Queue
module PriorityQueue : Queue module PriorityQueue : Queue
module Make (_ : Domain_intf.Opts) (Dom : Domain_intf.Dom) (_ : Queue) : sig module Make (_ : Config) (Dom : Domain_intf.Dom) (_ : Queue) : sig
val exec_pgm : Llair.program -> unit val exec_pgm : Llair.program -> unit
val compute_summaries : val compute_summaries :

@ -0,0 +1,20 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
module type Config = sig
val bound : int
(** Loop/recursion unrolling bound *)
val function_summaries : bool
(** Use function summarization *)
val entry_points : string list
(** C linkage names of entry points *)
val globals : Domain_used_globals.used_globals
(** results of used globals pre-analysis *)
end

@ -48,21 +48,3 @@ module type Dom = sig
val apply_summary : t -> summary -> t option val apply_summary : t -> summary -> t option
end end
type used_globals =
| Per_function of Llair.Global.Set.t Llair.Function.Map.t
(** per-function used-globals map *)
| Declared of Llair.Global.Set.t (** program-wide set *)
module type Opts = sig
val bound : int
(** Loop/recursion unrolling bound *)
val function_summaries : bool
(** Use function summarization *)
val entry_points : string list
(** C linkage names of entry points *)
val globals : used_globals
end

@ -62,7 +62,11 @@ let apply_summary st summ = Some (Llair.Global.Set.union st summ)
(** Query *) (** Query *)
let by_function : Domain_intf.used_globals -> Llair.Function.t -> t = type used_globals =
| Per_function of summary Llair.Function.Map.t
| Declared of summary
let by_function : used_globals -> Llair.Function.t -> t =
fun s fn -> fun s fn ->
[%Trace.call fun {pf} -> pf "@ %a" Llair.Function.pp fn] [%Trace.call fun {pf} -> pf "@ %a" Llair.Function.pp fn]
; ;

@ -9,4 +9,10 @@
include Domain_intf.Dom with type summary = Llair.Global.Set.t include Domain_intf.Dom with type summary = Llair.Global.Set.t
val by_function : Domain_intf.used_globals -> Llair.Function.t -> summary type used_globals =
| Per_function of Llair.Global.Set.t Llair.Function.Map.t
(** map of functions to globals they or their callees use *)
| Declared of Llair.Global.Set.t
(** set of declared globals used in the program *)
val by_function : used_globals -> Llair.Function.t -> summary

Loading…
Cancel
Save