aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialyzer/src')
-rw-r--r--lib/dialyzer/src/Makefile1
-rw-r--r--lib/dialyzer/src/dialyzer.hrl9
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl3
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl2
-rw-r--r--lib/dialyzer/src/dialyzer_cl_parse.erl9
-rw-r--r--lib/dialyzer/src/dialyzer_options.erl2
-rw-r--r--lib/dialyzer/src/dialyzer_succ_typings.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_timing.erl88
8 files changed, 116 insertions, 5 deletions
diff --git a/lib/dialyzer/src/Makefile b/lib/dialyzer/src/Makefile
index 39b1b3eb3e..09fb02bda2 100644
--- a/lib/dialyzer/src/Makefile
+++ b/lib/dialyzer/src/Makefile
@@ -63,6 +63,7 @@ MODULES = \
dialyzer_plt \
dialyzer_races \
dialyzer_succ_typings \
+ dialyzer_timing \
dialyzer_typesig \
dialyzer_coordinator \
dialyzer_worker \
diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl
index 44b1ebeabd..e2edd3f0af 100644
--- a/lib/dialyzer/src/dialyzer.hrl
+++ b/lib/dialyzer/src/dialyzer.hrl
@@ -132,6 +132,7 @@
-record(options, {files = [] :: [file:filename()],
files_rec = [] :: [file:filename()],
analysis_type = succ_typings :: anal_type1(),
+ timing = false :: boolean(),
defines = [] :: [dial_define()],
from = byte_code :: start_from(),
get_warnings = maybe :: boolean() | 'maybe',
@@ -153,3 +154,11 @@
forms = [] :: [{_, _}]}).
%%--------------------------------------------------------------------
+
+-define(timing(Msg,Expr),
+ begin
+ dialyzer_timing:start_stamp(Msg),
+ __T = Expr,
+ dialyzer_timing:end_stamp(),
+ __T
+ end).
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index febaf56e40..30eb087fcf 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -134,7 +134,8 @@ analysis_start(Parent, Analysis) ->
use_contracts = Analysis#analysis.use_contracts
},
Files = ordsets:from_list(Analysis#analysis.files),
- {Callgraph, NoWarn, TmpCServer0} = compile_and_store(Files, State),
+ {Callgraph, NoWarn, TmpCServer0} =
+ ?timing("compile",compile_and_store(Files, State)),
%% Remote type postprocessing
NewCServer =
try
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index 6d3b1f0531..482f428e02 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -400,8 +400,10 @@ do_analysis(Files, Options, Plt, PltInfo) ->
callgraph_file = Options#options.callgraph_file},
State3 = start_analysis(State2, InitAnalysis),
{T1, _} = statistics(wall_clock),
+ ok = dialyzer_timing:init(Options#options.timing),
Return = cl_loop(State3),
{T2, _} = statistics(wall_clock),
+ ok = dialyzer_timing:stop(),
report_elapsed_time(T1, T2, Options),
Return.
diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl
index ff8fc39a5e..5baba7d11b 100644
--- a/lib/dialyzer/src/dialyzer_cl_parse.erl
+++ b/lib/dialyzer/src/dialyzer_cl_parse.erl
@@ -164,6 +164,9 @@ cl(["--src"|T]) ->
cl(["--no_spec"|T]) ->
put(dialyzer_options_use_contracts, false),
cl(T);
+cl(["--time"|T]) ->
+ put(dialyzer_timing, true),
+ cl(T);
cl(["-v"|_]) ->
io:format("Dialyzer version "++?VSN++"\n"),
erlang:halt(?RET_NOTHING_SUSPICIOUS);
@@ -250,6 +253,7 @@ init() ->
put(dialyzer_output_format, formatted),
put(dialyzer_filename_opt, basename),
put(dialyzer_options_check_plt, DefaultOpts#options.check_plt),
+ put(dialyzer_timing, DefaultOpts#options.timing),
ok.
append_defines([Def, Val]) ->
@@ -290,6 +294,7 @@ cl_options() ->
{filename_opt, get(dialyzer_filename_opt)},
{analysis_type, get(dialyzer_options_analysis_type)},
{get_warnings, get(dialyzer_options_get_warnings)},
+ {timing, get(dialyzer_timing)},
{callgraph_file, get(dialyzer_callgraph_file)}
|common_options()].
@@ -351,7 +356,7 @@ help_message() ->
[--apps applications] [-o outfile]
[--build_plt] [--add_to_plt] [--remove_from_plt]
[--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
- [--no_native] [--fullpath]
+ [--no_native] [--fullpath] [--time]
Options:
files_or_dirs (for backwards compatibility also as: -c files_or_dirs)
Use Dialyzer from the command line to detect defects in the
@@ -418,6 +423,8 @@ Options:
Make Dialyzer a bit more quiet.
--verbose
Make Dialyzer a bit more verbose.
+ --time
+ Print time information
--build_plt
The analysis starts from an empty plt and creates a new one from the
files specified with -c and -r. Only works for beam files.
diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl
index 866650a0b2..a1e316d6cc 100644
--- a/lib/dialyzer/src/dialyzer_options.erl
+++ b/lib/dialyzer/src/dialyzer_options.erl
@@ -194,6 +194,8 @@ build_options([{OptionName, Value} = Term|Rest], Options) ->
callgraph_file ->
assert_filename(Value),
build_options(Rest, Options#options{callgraph_file = Value});
+ timing ->
+ build_options(Rest, Options#options{timing = Value});
_ ->
bad_option("Unknown dialyzer command line option", Term)
end;
diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl
index 4d813e06bb..e901677ce2 100644
--- a/lib/dialyzer/src/dialyzer_succ_typings.erl
+++ b/lib/dialyzer/src/dialyzer_succ_typings.erl
@@ -132,7 +132,8 @@ get_warnings(Callgraph, Plt, DocPlt, Codeserver, NoWarnUnused, Parent) ->
NewState#st.plt),
MiniDocPlt = dialyzer_plt:get_mini_plt(DocPlt),
{Warnings, FinalPlt, FinalDocPlt} =
- get_warnings_from_modules(Mods, NewState, MiniDocPlt, CWarns),
+ ?timing("warning",
+ get_warnings_from_modules(Mods, NewState, MiniDocPlt, CWarns)),
{postprocess_warnings(Warnings, Codeserver),
dialyzer_plt:restore_full_plt(FinalPlt, Plt),
dialyzer_plt:restore_full_plt(FinalDocPlt, DocPlt)}.
@@ -201,7 +202,7 @@ refine_succ_typings(ModulePostorder, #st{codeserver = Codeserver,
?debug("Module postorder: ~p\n", [ModulePostorder]),
Servers = {Codeserver, Callgraph, Plt},
Coordinator = dialyzer_coordinator:start(dataflow, Servers),
- refine_succ_typings(ModulePostorder, State, Coordinator).
+ ?timing("refine",refine_succ_typings(ModulePostorder, State, Coordinator)).
refine_succ_typings([M|Rest], State, Coordinator) ->
Msg = io_lib:format("Dataflow of module: ~w\n", [M]),
@@ -315,7 +316,7 @@ find_succ_typings(SCCs, #st{codeserver = Codeserver, callgraph = Callgraph,
plt = Plt} = State) ->
Servers = {Codeserver, dialyzer_callgraph:mini_callgraph(Callgraph), Plt},
Coordinator = dialyzer_coordinator:start(typesig, Servers),
- find_succ_typings(SCCs, State, Coordinator).
+ ?timing("typesig", find_succ_typings(SCCs, State, Coordinator)).
find_succ_typings([SCC|Rest], #st{parent = Parent} = State, Coordinator) ->
Msg = io_lib:format("Typesig analysis for SCC: ~w\n", [format_scc(SCC)]),
diff --git a/lib/dialyzer/src/dialyzer_timing.erl b/lib/dialyzer/src/dialyzer_timing.erl
new file mode 100644
index 0000000000..73dbbf5a34
--- /dev/null
+++ b/lib/dialyzer/src/dialyzer_timing.erl
@@ -0,0 +1,88 @@
+%% -*- erlang-indent-level: 2 -*-
+%%-------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : dialyzer_timing.erl
+%%% Authors : Stavros Aronis <[email protected]>
+%%% Description : Timing reports for Dialyzer
+%%%-------------------------------------------------------------------
+
+-module(dialyzer_timing).
+
+-export([init/1, start_stamp/1, end_stamp/0, stop/0]).
+
+-spec init(boolean()) -> ok.
+
+init(Active) ->
+ Pid = spawn(fun() -> loop_init(Active) end),
+ case whereis(?MODULE) of
+ undefined -> ok;
+ _ -> unregister(?MODULE)
+ end,
+ register(?MODULE, Pid),
+ ok.
+
+loop_init(Active) ->
+ case Active of
+ true ->
+ io:format("\n"),
+ loop(now());
+ false -> dummy_loop()
+ end.
+
+dummy_loop() ->
+ receive
+ {Pid, stop, _Now} -> Pid ! ok;
+ _ -> dummy_loop()
+ end.
+
+loop(LastNow) ->
+ receive
+ {stamp, Msg, Now} ->
+ io:format("~s\t(+~6.2fs): ", [Msg, diff(Now, LastNow)]),
+ loop(Now);
+ {stamp, Now} ->
+ io:format("~6.2fs\n", [diff(Now, LastNow)]),
+ loop(Now);
+ {Pid, stop, Now} ->
+ io:format("\t(+~6.2fs)\n", [diff(Now, LastNow)]),
+ Pid ! ok
+ end.
+
+-spec start_stamp(string()) -> ok.
+
+start_stamp(Msg) ->
+ ?MODULE ! {stamp, Msg, now()},
+ ok.
+
+-spec end_stamp() -> ok.
+
+end_stamp() ->
+ ?MODULE ! {stamp, now()},
+ ok.
+
+-spec stop() -> ok.
+
+stop() ->
+ ?MODULE ! {self(), stop, now()},
+ receive ok -> ok end.
+
+diff(T2, T1) ->
+ timer:now_diff(T2,T1) / 1000000.