Invalidate summaries for changed procedures

Summary: This implements incremental diff analysis by deleting only the summaries that need to be re-analyzed, keeping all summaries corresponding to procedures that have not been changed (or had a callee change).

Reviewed By: jvillard

Differential Revision: D16358474

fbshipit-source-id: 660a704a0
master
Phoebe Nichols 5 years ago committed by Facebook Github Bot
parent f91ddef3fc
commit ee5abef97c

@ -158,3 +158,11 @@ let get_unflagged_leaves g =
(fun _id (n : Node.t) acc -> (fun _id (n : Node.t) acc ->
if n.flag || List.exists n.successors ~f:(mem g) then acc else n :: acc ) if n.flag || List.exists n.successors ~f:(mem g) then acc else n :: acc )
g.node_map [] g.node_map []
let iter_flagged graph ~f =
NodeMap.iter (fun _id node -> if node.Node.flag then f node else ()) graph.node_map
(** choose some reasonable minimum capacity that also is a prime number *)
let default_initial_capacity = 1009

@ -56,11 +56,15 @@ val trim_id_map : t -> unit
val remove_unflagged_and_unflag_all : t -> unit val remove_unflagged_and_unflag_all : t -> unit
(** remove all nodes with flag set to false, and set flag to false on all remaining nodes *) (** remove all nodes with flag set to false, and set flag to false on all remaining nodes *)
(* suppress unused value warning until this is used for T47276251 *)
val add_edge : t -> pname:Typ.Procname.t -> successor_pname:Typ.Procname.t -> unit val add_edge : t -> pname:Typ.Procname.t -> successor_pname:Typ.Procname.t -> unit
[@@warning "-32"]
(** add an edge from [pname] to [successor_pname] in the graph, creating a node for [pname] if there (** add an edge from [pname] to [successor_pname] in the graph, creating a node for [pname] if there
isn't one already *) isn't one already *)
val create_node : t -> Typ.Procname.t -> Typ.Procname.t sexp_list -> unit val create_node : t -> Typ.Procname.t -> Typ.Procname.t sexp_list -> unit
(** create a new node with edges from [pname] to [successor_pnames] in the graph *) (** create a new node with edges from [pname] to [successor_pnames] in the graph *)
val iter_flagged : t -> f:(Node.t -> unit) -> unit
(** iterate over the nodes in the graph with flag set to true *)
val default_initial_capacity : int
(** reasonable minimum capacity for the graph that is prime *)

@ -141,12 +141,28 @@ let analyze source_files_to_analyze =
collected_stats ) collected_stats )
let invalidate_changed_procedures changed_files =
L.progress "Incremental analysis: invalidating procedures that have been changed@." ;
let reverse_callgraph = CallGraph.create CallGraph.default_initial_capacity in
ReverseAnalysisCallGraph.build reverse_callgraph ;
SourceFile.Set.iter
(fun sf ->
SourceFiles.proc_names_of_source sf
|> List.iter ~f:(CallGraph.flag_reachable reverse_callgraph) )
changed_files ;
CallGraph.iter_flagged reverse_callgraph ~f:(fun node -> SpecsFiles.delete node.pname) ;
(* save some memory *)
CallGraph.reset reverse_callgraph
let main ~changed_files = let main ~changed_files =
register_active_checkers () ; register_active_checkers () ;
if Config.reanalyze then ( if Config.reanalyze then (
L.progress "Invalidating procedures to be reanalyzed@." ; L.progress "Invalidating procedures to be reanalyzed@." ;
Summary.OnDisk.reset_all ~filter:(Lazy.force Filtering.procedures_filter) () ; Summary.OnDisk.reset_all ~filter:(Lazy.force Filtering.procedures_filter) () ;
L.progress "Done@." ) L.progress "Done@." )
else if Config.incremental_analysis then
Option.iter ~f:invalidate_changed_procedures changed_files
else DB.Results_dir.clean_specs_dir () ; else DB.Results_dir.clean_specs_dir () ;
let source_files = get_source_files_to_analyze ~changed_files in let source_files = get_source_files_to_analyze ~changed_files in
(* empty all caches to minimize the process heap to have less work to do when forking *) (* empty all caches to minimize the process heap to have less work to do when forking *)

@ -6,7 +6,5 @@
*) *)
open! IStd open! IStd
(* Suppress unused value warning until this is used for incremental diff analysis *)
val build : CallGraph.t -> unit val build : CallGraph.t -> unit
[@@warning "-32"]
(** Build the graph from the summaries in the .specs files *) (** Build the graph from the summaries in the .specs files *)

@ -7,17 +7,13 @@
open! IStd open! IStd
(* Suppress unused value warning until this is used for incremental diff analysis *)
val iter : f:(Summary.t -> unit) -> unit val iter : f:(Summary.t -> unit) -> unit
[@@warning "-32"]
(** Iterates over all summaries from the .specs files *) (** Iterates over all summaries from the .specs files *)
val iter_from_config : f:(Summary.t -> unit) -> unit val iter_from_config : f:(Summary.t -> unit) -> unit
(** Iterates over all sumaries from the .specs files unless a list of specs files has been passed on (** Iterates over all sumaries from the .specs files unless a list of specs files has been passed on
the command line *) the command line *)
(* Suppress unused value warning until this is used for incremental diff analysis *)
val delete : Typ.Procname.t -> unit val delete : Typ.Procname.t -> unit
[@@warning "-32"]
(** Delete the .specs file associated with a summary and remove the summary from the caches in (** Delete the .specs file associated with a summary and remove the summary from the caches in
Summary.ml and ondemand.ml *) Summary.ml and ondemand.ml *)

@ -38,14 +38,11 @@ let count_procedures () =
count count
(** choose some reasonable minimum capacity that also is a prime number *)
let initial_call_graph_capacity = 1009
let bottom_up sources : target task_generator = let bottom_up sources : target task_generator =
(* this will potentially grossly overapproximate the tasks *) (* this will potentially grossly overapproximate the tasks *)
let remaining = ref (count_procedures ()) in let remaining = ref (count_procedures ()) in
let remaining_tasks () = !remaining in let remaining_tasks () = !remaining in
let syntactic_call_graph = CallGraph.create initial_call_graph_capacity in let syntactic_call_graph = CallGraph.create CallGraph.default_initial_capacity in
let initialized = ref false in let initialized = ref false in
let pending : CallGraph.Node.t list ref = ref [] in let pending : CallGraph.Node.t list ref = ref [] in
let scheduled = ref Typ.Procname.Set.empty in let scheduled = ref Typ.Procname.Set.empty in

@ -191,8 +191,7 @@ val unsafe_unret : string
val use_cost_threshold : bool val use_cost_threshold : bool
(* Suppress unused value warning because the incremental analysis feature is not yet complete *) val incremental_analysis : bool
val incremental_analysis : bool [@@warning "-32"]
val weak : string val weak : string

Loading…
Cancel
Save