You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
4.0 KiB
121 lines
4.0 KiB
/*
|
|
* Copyright (c) 2009 - 2013 Monoidics ltd.
|
|
* Copyright (c) 2013 - present Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
open! IStd;
|
|
|
|
|
|
/** Main module for the analysis after the capture phase */
|
|
let module L = Logging;
|
|
|
|
let module F = Format;
|
|
|
|
let analyze_exe_env exe_env => {
|
|
let init_time = Unix.gettimeofday ();
|
|
L.log_progress_file ();
|
|
Specs.clear_spec_tbl ();
|
|
Random.self_init ();
|
|
if Config.checkers {
|
|
/* run the checkers only */
|
|
let call_graph = Exe_env.get_cg exe_env;
|
|
Callbacks.iterate_callbacks Checkers.ST.store_summary call_graph exe_env
|
|
} else {
|
|
/* run the full analysis */
|
|
Interproc.do_analysis exe_env;
|
|
Printer.write_all_html_files exe_env;
|
|
Interproc.print_stats exe_env;
|
|
let elapsed = Unix.gettimeofday () -. init_time;
|
|
L.out "Interprocedural footprint analysis terminated in %f sec@." elapsed
|
|
}
|
|
};
|
|
|
|
|
|
/** Create an exe_env from a cluster. */
|
|
let exe_env_from_cluster cluster => {
|
|
let _exe_env = Exe_env.create ();
|
|
Exe_env.add_cg _exe_env cluster;
|
|
Exe_env.freeze _exe_env
|
|
};
|
|
|
|
|
|
/** Analyze a cluster of files */
|
|
let analyze_cluster cluster_num (cluster: Cluster.t) => {
|
|
let exe_env = exe_env_from_cluster cluster;
|
|
let defined_procs = Cg.get_defined_nodes (Exe_env.get_cg exe_env);
|
|
let num_procs = IList.length defined_procs;
|
|
L.err "@.Processing cluster #%d with %d procedures@." (cluster_num + 1) num_procs;
|
|
analyze_exe_env exe_env
|
|
};
|
|
|
|
let output_json_makefile_stats clusters => {
|
|
let clusters_to_analyze = IList.filter ClusterMakefile.cluster_should_be_analyzed clusters;
|
|
let num_files = IList.length clusters_to_analyze;
|
|
let num_procs = 0;
|
|
/* can't compute it at this stage */
|
|
let num_lines = 0;
|
|
let file_stats =
|
|
`Assoc [("files", `Int num_files), ("procedures", `Int num_procs), ("lines", `Int num_lines)];
|
|
/* write stats file to disk, intentionally overwriting old file if it already exists */
|
|
let f = open_out (Filename.concat Config.results_dir Config.proc_stats_filename);
|
|
Yojson.Basic.pretty_to_channel f file_stats
|
|
};
|
|
|
|
let process_cluster_cmdline fname =>
|
|
switch (Cluster.load_from_file (DB.filename_from_string fname)) {
|
|
| None => L.err "Cannot find cluster file %s@." fname
|
|
| Some (nr, cluster) => analyze_cluster (nr - 1) cluster
|
|
};
|
|
|
|
let print_stdout_legend () => {
|
|
L.stdout "Starting analysis...@\n";
|
|
L.stdout "@\n";
|
|
L.stdout "legend:@\n";
|
|
L.stdout " \"%s\" analyzing a file@\n" Config.log_analysis_file;
|
|
L.stdout " \"%s\" analyzing a procedure@\n" Config.log_analysis_procedure;
|
|
if Config.stats_mode {
|
|
L.stdout " \"%s\" analyzer crashed@\n" Config.log_analysis_crash;
|
|
L.stdout
|
|
" \"%s\" timeout: procedure analysis took too much time@\n"
|
|
Config.log_analysis_wallclock_timeout;
|
|
L.stdout
|
|
" \"%s\" timeout: procedure analysis took too many symbolic execution steps@\n"
|
|
Config.log_analysis_symops_timeout;
|
|
L.stdout
|
|
" \"%s\" timeout: procedure analysis took too many recursive iterations@\n"
|
|
Config.log_analysis_recursion_timeout
|
|
};
|
|
L.stdout "@\n@?"
|
|
};
|
|
|
|
let main makefile => {
|
|
BuiltinDefn.init ();
|
|
switch Config.modified_targets {
|
|
| Some file => MergeCapture.modified_file file
|
|
| None => ()
|
|
};
|
|
switch Config.cluster_cmdline {
|
|
| Some fname => process_cluster_cmdline fname
|
|
| None =>
|
|
if Config.allow_specs_cleanup {
|
|
DB.Results_dir.clean_specs_dir ()
|
|
};
|
|
if Config.merge {
|
|
MergeCapture.merge_captured_targets ()
|
|
};
|
|
let clusters = DB.find_source_dirs ();
|
|
L.stdout "Found %d source files in %s@." (IList.length clusters) Config.results_dir;
|
|
if (makefile != "") {
|
|
ClusterMakefile.create_cluster_makefile clusters makefile
|
|
} else {
|
|
IList.iteri (fun i cluster => analyze_cluster i cluster) clusters;
|
|
L.stdout "@\nAnalysis finished in %as@." Pp.elapsed_time ()
|
|
};
|
|
output_json_makefile_stats clusters
|
|
}
|
|
};
|