mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 20:34:19 +00:00
Fix a bunch of deviations from our coding standards.
Estimated hours taken: 1 Branches: main profiler/*.m: Fix a bunch of deviations from our coding standards. Rename some predicates to make them better reflect the predicates' semantics.
This commit is contained in:
@@ -6,12 +6,11 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% atsort_callgraph.m
|
||||
%
|
||||
% File: atsort_callgraph.m.
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Takes a list of files which contains the callgraph of a Mercury module
|
||||
% and approximately topologically sorts them to std out.
|
||||
% and approximately topologically sorts them to standard output.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% call_graph.m
|
||||
%
|
||||
% File: call_graph.m
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Responsible for building the static call graph. The dynamic call graph is
|
||||
@@ -27,7 +26,7 @@
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
|
||||
:- pred call_graph.main(list(string)::in,
|
||||
:- pred build_call_graph(list(string)::in,
|
||||
relation(string)::in, relation(string)::out, io::di, io::uo) is det.
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
@@ -42,10 +41,11 @@
|
||||
:- import_module bool.
|
||||
:- import_module maybe.
|
||||
:- import_module require.
|
||||
:- import_module svrelation.
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
call_graph.main(Args, !StaticCallGraph, !IO) :-
|
||||
build_call_graph(Args, !StaticCallGraph, !IO) :-
|
||||
globals.io_lookup_bool_option(dynamic_cg, Dynamic, !IO),
|
||||
globals.io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
|
||||
%
|
||||
@@ -61,6 +61,7 @@ call_graph.main(Args, !StaticCallGraph, !IO) :-
|
||||
).
|
||||
|
||||
% build_static_call_graph:
|
||||
%
|
||||
% Builds the static call graph located in the *.prof files.
|
||||
%
|
||||
:- pred build_static_call_graph(list(string)::in, bool::in,
|
||||
@@ -70,6 +71,7 @@ build_static_call_graph(Files, VeryVerbose, !StaticCallGraph, !IO) :-
|
||||
list.foldl2(process_prof_file(VeryVerbose), Files, !StaticCallGraph, !IO).
|
||||
|
||||
% process_prof_file:
|
||||
%
|
||||
% Puts all the Caller and Callee label pairs from File into the
|
||||
% static call graph relation.
|
||||
%
|
||||
@@ -103,8 +105,7 @@ process_prof_file_2(!StaticCallGraph, !IO) :-
|
||||
read_label_name(CalleeLabel, !IO),
|
||||
relation.lookup_element(!.StaticCallGraph, CallerLabel, CallerKey),
|
||||
relation.lookup_element(!.StaticCallGraph, CalleeLabel, CalleeKey),
|
||||
relation.add(!.StaticCallGraph, CallerKey, CalleeKey,
|
||||
!:StaticCallGraph),
|
||||
svrelation.add(CallerKey, CalleeKey, !StaticCallGraph),
|
||||
process_prof_file_2(!StaticCallGraph, !IO)
|
||||
;
|
||||
true
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
% File: demangle.m
|
||||
% Author: fjh
|
||||
%
|
||||
% A mercury symbol demangler.
|
||||
% This is used to convert symbol names back
|
||||
% A Mercury symbol demangler. This is used to convert symbol names back
|
||||
% into a form that users can understand.
|
||||
%
|
||||
% BEWARE: the code here is duplicated in util/mdemangle.c,
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
%-----------------------------------------------------------------------------%
|
||||
% vim: ft=mercury ts=4 sw=4 et
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% Copyright (C) 1997, 2005-2006 The University of Melbourne.
|
||||
% This file may only be copied under the terms of the GNU General
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% File: demangle_test.m
|
||||
% Author: fjh
|
||||
%
|
||||
% Front-end to a mercury symbol demangler.
|
||||
% This is used to convert error messages from the linker back
|
||||
% into a form that users can understand.
|
||||
% Front-end to a Mercury symbol demangler. This is used to convert error
|
||||
% messages from the linker back into a form that users can understand.
|
||||
%
|
||||
% BEWARE:
|
||||
% The code here duplicates the functionality of util/mdemangle.c.
|
||||
@@ -41,18 +38,16 @@ main(!IO) :-
|
||||
io.command_line_arguments(Args, !IO),
|
||||
(
|
||||
Args = [_ | _],
|
||||
%
|
||||
% invoke demangle/2 on each command line argument
|
||||
%
|
||||
|
||||
% Invoke demangle/2 on each command line argument.
|
||||
list.map(demangle, Args, DemangledArgs),
|
||||
io.write_list(DemangledArgs, "\n", io.write_string, !IO),
|
||||
io.nl(!IO)
|
||||
;
|
||||
Args = [],
|
||||
%
|
||||
% copy stdin to stdout, calling demangle/2 for
|
||||
% every valid C identifier in the input
|
||||
%
|
||||
|
||||
% Copy stdin to stdout, calling demangle/2 for every valid C identifier
|
||||
% in the input.
|
||||
demangle_stdin([], !IO)
|
||||
).
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% generate_output.m
|
||||
%
|
||||
% File: generate_output.m
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Takes the prof structure and generates the output.
|
||||
@@ -30,7 +29,7 @@
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
:- pred generate_output.main(prof::in, map(string, int)::out, output::out,
|
||||
:- pred generate_prof_output(prof::in, map(string, int)::out, output::out,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
:- func checked_float_divide(float, float) = float.
|
||||
@@ -47,10 +46,11 @@
|
||||
:- import_module list.
|
||||
:- import_module rbtree.
|
||||
:- import_module relation.
|
||||
:- import_module svmap.
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% rbtrees are used because they allow duplicate values to be stored.
|
||||
% We use rbtrees because they allow duplicate values to be stored.
|
||||
% This means that we can then convert to a sorted list of names which
|
||||
% can be used to lookup the output_prof map when we actually output.
|
||||
:- type profiling
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
generate_output.main(Prof, IndexMap, Output, !IO) :-
|
||||
generate_prof_output(Prof, IndexMap, Output, !IO) :-
|
||||
globals.io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
|
||||
|
||||
% Get intitial values of use.
|
||||
@@ -104,9 +104,10 @@ process_prof_node_list([PN | PNs], Prof, VeryVerbose, !OutputProf, !IO) :-
|
||||
process_prof_node(PN, Prof, !OutputProf),
|
||||
process_prof_node_list(PNs, Prof, VeryVerbose, !OutputProf, !IO).
|
||||
|
||||
% process_prof_node:
|
||||
% This is the main function. It converts the prof_node
|
||||
% structure to the output_prof structure.
|
||||
% process_prof_node(ProfNode, Prof, !OutputProf):
|
||||
%
|
||||
% This is the main function. It converts the prof_node structure
|
||||
% to the output_prof structure.
|
||||
%
|
||||
:- pred process_prof_node(prof_node::in, prof::in,
|
||||
profiling::in, profiling::out) is det.
|
||||
@@ -114,20 +115,20 @@ process_prof_node_list([PN | PNs], Prof, VeryVerbose, !OutputProf, !IO) :-
|
||||
process_prof_node(ProfNode, Prof, !OutputProf) :-
|
||||
prof_node_type(ProfNode, ProfNodeType),
|
||||
( ProfNodeType = predicate ->
|
||||
generate_output.single_predicate(ProfNode, Prof, !OutputProf)
|
||||
generate_output_for_single_predicate(ProfNode, Prof, !OutputProf)
|
||||
;
|
||||
true
|
||||
% generate_output.cycle(ProfNode, Prof, OutputProf0,
|
||||
% OutputProf)
|
||||
% generate_output.cycle(ProfNode, Prof, OutputProf0, OutputProf)
|
||||
).
|
||||
|
||||
% generate_output.cycle
|
||||
% generate_output_for_cycle(ProfNode, Prof, !OutputProf):
|
||||
%
|
||||
% XXX
|
||||
%
|
||||
:- pred generate_output.cycle(prof_node::in, prof::in,
|
||||
:- pred generate_output_for_cycle(prof_node::in, prof::in,
|
||||
profiling::in, profiling::out) is det.
|
||||
|
||||
generate_output.cycle(ProfNode, Prof, !OutputProf) :-
|
||||
generate_output_for_cycle(ProfNode, Prof, !OutputProf) :-
|
||||
prof_get_entire(Prof, Scale, _Units, IntTotalCounts, _, _, _CycleMap),
|
||||
TotalCounts = float.float(IntTotalCounts),
|
||||
|
||||
@@ -136,9 +137,8 @@ generate_output.cycle(ProfNode, Prof, !OutputProf) :-
|
||||
|
||||
!.OutputProf = profiling(InfoMap0, CallTree0, FreeTree),
|
||||
|
||||
% Calculate proportion of time in current predicate and its
|
||||
% descendents as a percentage.
|
||||
%
|
||||
% Calculate proportion of time in current predicate and its descendants
|
||||
% as a percentage.
|
||||
InitialFloat = float.float(Initial),
|
||||
( TotalCounts = 0.0 ->
|
||||
DescPercentage = 0.0
|
||||
@@ -148,7 +148,7 @@ generate_output.cycle(ProfNode, Prof, !OutputProf) :-
|
||||
|
||||
% Calculate the self time spent in the current predicate.
|
||||
% Calculate the descendant time, which is the time spent in the
|
||||
% current predicate and its descendants
|
||||
% current predicate and its descendants.
|
||||
SelfTime = InitialFloat * Scale,
|
||||
DescTime = (InitialFloat + Prop) * Scale,
|
||||
|
||||
@@ -160,13 +160,14 @@ generate_output.cycle(ProfNode, Prof, !OutputProf) :-
|
||||
|
||||
!:OutputProf = profiling(InfoMap, CallTree, FreeTree).
|
||||
|
||||
% generate_output.single_predicate:
|
||||
% generate_output_for_single_predicate(ProfNode, Prof, !OutputProf):
|
||||
%
|
||||
% Fills out the output_prof structure when pred is a single predicate.
|
||||
%
|
||||
:- pred generate_output.single_predicate(prof_node::in, prof::in,
|
||||
:- pred generate_output_for_single_predicate(prof_node::in, prof::in,
|
||||
profiling::in, profiling::out) is det.
|
||||
|
||||
generate_output.single_predicate(ProfNode, Prof, !OutputProf) :-
|
||||
generate_output_for_single_predicate(ProfNode, Prof, !OutputProf) :-
|
||||
prof_get_entire(Prof, Scale, _Units, IntTotalCounts, _, _, CycleMap),
|
||||
TotalCounts = float.float(IntTotalCounts),
|
||||
|
||||
@@ -185,7 +186,7 @@ generate_output.single_predicate(ProfNode, Prof, !OutputProf) :-
|
||||
Name = LabelName ++ construct_name(NameList),
|
||||
|
||||
% Calculate proportion of time in current predicate and its
|
||||
% descendents as a percentage.
|
||||
% descendants as a percentage.
|
||||
% Calculate proportion of time in current predicate
|
||||
% as a percentage.
|
||||
InitialFloat = float.float(Initial),
|
||||
@@ -193,8 +194,7 @@ generate_output.single_predicate(ProfNode, Prof, !OutputProf) :-
|
||||
DescPercentage = 0.0,
|
||||
FlatPercentage = 0.0
|
||||
;
|
||||
DescPercentage = (InitialFloat + Prop) / TotalCounts
|
||||
* 100.0,
|
||||
DescPercentage = (InitialFloat + Prop) / TotalCounts * 100.0,
|
||||
FlatPercentage = InitialFloat / TotalCounts * 100.0
|
||||
),
|
||||
|
||||
@@ -210,16 +210,11 @@ generate_output.single_predicate(ProfNode, Prof, !OutputProf) :-
|
||||
process_prof_node_children(ChildList, CycleNum, CycleMap,
|
||||
Prof, OutputChildList, OutputCycleChildList),
|
||||
|
||||
OutputProfNode = output_prof(
|
||||
Name, CycleNum,
|
||||
DescPercentage,
|
||||
FlatPercentage, SelfTime,
|
||||
DescTime, TotalCalls,
|
||||
SelfCalls,
|
||||
OutputParentList,
|
||||
OutputChildList,
|
||||
OutputCycleParentList,
|
||||
OutputCycleChildList
|
||||
OutputProfNode = output_prof(Name, CycleNum,
|
||||
DescPercentage, FlatPercentage, SelfTime, DescTime,
|
||||
TotalCalls, SelfCalls,
|
||||
OutputParentList, OutputChildList,
|
||||
OutputCycleParentList, OutputCycleChildList
|
||||
),
|
||||
|
||||
map.det_insert(InfoMap0, LabelName, OutputProfNode, InfoMap),
|
||||
@@ -233,8 +228,9 @@ generate_output.single_predicate(ProfNode, Prof, !OutputProf) :-
|
||||
).
|
||||
|
||||
% construct_name:
|
||||
% When more then one predicate maps to the same address. This predicate
|
||||
% When more then one predicate maps to the same address, this predicate
|
||||
% will build a string of all the different names separated by 'or's.
|
||||
%
|
||||
:- func construct_name(list(string)) = string.
|
||||
|
||||
construct_name([]) = "".
|
||||
@@ -244,7 +240,8 @@ construct_name([Name | Names]) = NameStr :-
|
||||
string.append(NameStr1, NameStr0, NameStr).
|
||||
|
||||
% process_prof_node_parents:
|
||||
% generate the parents output structure.
|
||||
%
|
||||
% Generate the parents output structure.
|
||||
%
|
||||
:- pred process_prof_node_parents(list(pred_info)::in, float::in, float::in,
|
||||
int::in, int::in, cycle_map::in, list(parent)::out, list(parent)::out)
|
||||
@@ -258,10 +255,12 @@ process_prof_node_parents(Parents0, SelfTime, DescTime, TotalCalls0, CycleNum,
|
||||
process_prof_node_parents_2(Parents, SelfTime, DescTime, FltTotalCalls,
|
||||
CycleMap, OutputParentList).
|
||||
|
||||
% remove_cycle_members
|
||||
% removes any members of the same cycle from the parent listing
|
||||
% of a predicate. Then adjusts the total calls so as not to include
|
||||
% that predicate.
|
||||
% remove_cycle_members(PredInfos, CycleNum, CycleMap, !TotalCalls, List,
|
||||
% OutputCycleParentList):
|
||||
%
|
||||
% Removes any members of the same cycle from the parent listing
|
||||
% of a predicate. Then adjusts the total calls so as not to include
|
||||
% that predicate.
|
||||
%
|
||||
:- pred remove_cycle_members(list(pred_info)::in, int::in, cycle_map::in,
|
||||
int::in, int::out, list(pred_info)::out, list(parent)::out) is det.
|
||||
@@ -309,10 +308,8 @@ process_prof_node_parents_3([PN | PNs], SelfTime, DescTime, TotalCalls,
|
||||
CycleMap, !Output) :-
|
||||
pred_info_get_entire(PN, LabelName, Calls),
|
||||
|
||||
(
|
||||
% if parent member of cycle
|
||||
map.search(CycleMap, LabelName, ParentCycleNum0)
|
||||
->
|
||||
% Check if the parent is a member of a cycle.
|
||||
( map.search(CycleMap, LabelName, ParentCycleNum0) ->
|
||||
ParentCycleNum = ParentCycleNum0
|
||||
;
|
||||
ParentCycleNum = 0
|
||||
@@ -414,15 +411,16 @@ process_prof_node_children_2([PN | PNs], Prof, !Output) :-
|
||||
rbtree.insert_duplicate(!.Output, Calls, Child, !:Output),
|
||||
process_prof_node_children_2(PNs, Prof, !Output).
|
||||
|
||||
% assign_index_numbers:
|
||||
% assign_index_numbers(IndexMap, RevList, List):
|
||||
%
|
||||
% Reverses the output list so that the predicates which account for
|
||||
% most of the time come first, and then assigns index numbers.
|
||||
%
|
||||
:- pred assign_index_numbers(map(string, int)::out,
|
||||
list(string)::in, list(string)::out) is det.
|
||||
|
||||
assign_index_numbers(IndexMap, List0, List) :-
|
||||
list.reverse(List0, List),
|
||||
assign_index_numbers(IndexMap, RevList, List) :-
|
||||
list.reverse(RevList, List),
|
||||
assign_index_numbers_2(List, 1, map.init, IndexMap).
|
||||
|
||||
:- pred assign_index_numbers_2(list(string)::in, int::in,
|
||||
@@ -430,7 +428,7 @@ assign_index_numbers(IndexMap, List0, List) :-
|
||||
|
||||
assign_index_numbers_2([], _, !IndexMap).
|
||||
assign_index_numbers_2([X0 | Xs0], N, !IndexMap) :-
|
||||
map.det_insert(!.IndexMap, X0, N, !:IndexMap),
|
||||
svmap.det_insert(X0, N, !IndexMap),
|
||||
assign_index_numbers_2(Xs0, N + 1, !IndexMap).
|
||||
|
||||
:- func profiling_init = profiling.
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
% This file may only be copied under the terms of the GNU General
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
%
|
||||
% File: globals.m.
|
||||
% Main author: fjh.
|
||||
|
||||
%
|
||||
% This module exports the `globals' type and associated access predicates.
|
||||
% The globals type is used to collect together all the various data
|
||||
% that would be global variables in an imperative language.
|
||||
% This global data is stored in the io.
|
||||
|
||||
% This global data is stored in the io state.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
:- module globals.
|
||||
@@ -113,9 +113,9 @@ what_to_profile("real-time", real_time).
|
||||
|
||||
:- type globals
|
||||
---> globals(
|
||||
what_to_profile :: what_to_profile,
|
||||
option_table :: option_table
|
||||
).
|
||||
what_to_profile :: what_to_profile,
|
||||
option_table :: option_table
|
||||
).
|
||||
|
||||
globals.init(Options, globals(user_plus_system_time, Options)).
|
||||
|
||||
|
||||
@@ -9,15 +9,12 @@
|
||||
% Mercury profiler
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Notes:
|
||||
% Processes the Prof.* and the *.prof files to produce an output very
|
||||
% similar to `gprof'
|
||||
% Processes the Prof.* and the *.prof files to produce an output very similar
|
||||
% to `gprof'
|
||||
%
|
||||
% Based on the profiling scheme described in [1].
|
||||
%
|
||||
% [1] Graham, Kessler and McKusick "Gprof: a call graph execution
|
||||
% profiler". In Proceedings of the 1982 SIGPLAN Symposium
|
||||
% on Compiler Construction, pages 120-126.
|
||||
% Based on the profiling scheme described in the paper: Graham, Kessler and
|
||||
% McKusick "Gprof: a call graph execution profiler", Proceedings of the 1982
|
||||
% SIGPLAN Symposium on Compiler Construction, pages 120-126.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
%-----------------------------------------------------------------------------%
|
||||
@@ -161,17 +158,17 @@ main_2(no, Args, !IO) :-
|
||||
globals.io_lookup_bool_option(verbose, Verbose, !IO),
|
||||
|
||||
maybe_write_string(Verbose, "% Processing input files...", !IO),
|
||||
process_file.main(Prof0, CallGraph0, !IO),
|
||||
process_profiling_data_files(Prof0, CallGraph0, !IO),
|
||||
maybe_write_string(Verbose, " done\n", !IO),
|
||||
|
||||
(
|
||||
CallGraphOpt = yes,
|
||||
maybe_write_string(Verbose, "% Building call graph...", !IO),
|
||||
call_graph.main(Args, CallGraph0, CallGraph, !IO),
|
||||
build_call_graph(Args, CallGraph0, CallGraph, !IO),
|
||||
maybe_write_string(Verbose, " done\n", !IO),
|
||||
|
||||
maybe_write_string(Verbose, "% Propagating counts...", !IO),
|
||||
propagate.counts(CallGraph, Prof0, Prof, !IO),
|
||||
propagate_counts(CallGraph, Prof0, Prof, !IO),
|
||||
maybe_write_string(Verbose, " done\n", !IO)
|
||||
;
|
||||
CallGraphOpt = no,
|
||||
@@ -179,11 +176,11 @@ main_2(no, Args, !IO) :-
|
||||
),
|
||||
|
||||
maybe_write_string(Verbose, "% Generating output...", !IO),
|
||||
generate_output.main(Prof, IndexMap, OutputProf, !IO),
|
||||
generate_prof_output(Prof, IndexMap, OutputProf, !IO),
|
||||
maybe_write_string(Verbose, " done\n", !IO),
|
||||
|
||||
io.set_output_stream(StdOut, _, !IO),
|
||||
output.main(OutputProf, IndexMap, !IO),
|
||||
output_profile(OutputProf, IndexMap, !IO),
|
||||
io.nl(!IO)
|
||||
).
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
% This file may only be copied under the terms of the GNU General
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
%
|
||||
% File: options.m.
|
||||
% Main author: fjh.
|
||||
|
||||
% This defines the stuff necessary so that getopt.m
|
||||
% can parse the command-line options.
|
||||
|
||||
%
|
||||
% This defines the stuff necessary so that getopt.m can parse the command line
|
||||
% options.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% output.m
|
||||
%
|
||||
% File: output.m
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Prints out the output.
|
||||
% Prints out the output of the profiler.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
%-----------------------------------------------------------------------------%
|
||||
@@ -27,7 +26,8 @@
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
:- pred output.main(output::in, map(string, int)::in, io::di, io::uo) is det.
|
||||
:- pred output_profile(output::in, map(string, int)::in,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
%-----------------------------------------------------------------------------%
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
output.main(Output, IndexMap, !IO) :-
|
||||
output_profile(Output, IndexMap, !IO) :-
|
||||
globals.io_get_globals(Globals, !IO),
|
||||
globals.get_what_to_profile(Globals, WhatToProfile),
|
||||
what_to_profile(WhatToProfileString, WhatToProfile),
|
||||
@@ -243,11 +243,11 @@ output_formatted_prof_node(ProfNode, Index, IndexMap, !IO) :-
|
||||
io.format("%67s", [s("<spontaneous>\n")], !IO)
|
||||
;
|
||||
list.sort(CycleParentList, SortedCycleParentList),
|
||||
output_formatted_cycle_parent_list(SortedCycleParentList,
|
||||
IndexMap, !IO),
|
||||
output_formatted_cycle_parent_list(SortedCycleParentList, IndexMap,
|
||||
!IO),
|
||||
list.sort(ParentList, SortedParentList),
|
||||
output_formatted_parent_list(SortedParentList, IndexMap,
|
||||
TotalCalls, !IO)
|
||||
output_formatted_parent_list(SortedParentList, IndexMap, TotalCalls,
|
||||
!IO)
|
||||
),
|
||||
|
||||
|
||||
@@ -297,12 +297,13 @@ output_formatted_parent_list([Parent | Parents], IndexMap, TotalCalls, !IO) :-
|
||||
Parent = parent(LabelName, CycleNum, Self, Descendant, Calls),
|
||||
Name = construct_name(LabelName, CycleNum),
|
||||
Index = IndexMap ^ det_elem(LabelName),
|
||||
io.format("%20.2f %11.2f %7d/%-11d %s [%d]\n", [f(Self),
|
||||
f(Descendant), i(Calls), i(TotalCalls),
|
||||
s(Name), i(Index)], !IO),
|
||||
io.format("%20.2f %11.2f %7d/%-11d %s [%d]\n",
|
||||
[f(Self), f(Descendant), i(Calls), i(TotalCalls), s(Name), i(Index)],
|
||||
!IO),
|
||||
output_formatted_parent_list(Parents, IndexMap, TotalCalls, !IO).
|
||||
|
||||
% output_formatted_cycle_child_list
|
||||
% output_formatted_cycle_child_list:
|
||||
%
|
||||
% Outputs the children of a procedure that are in the same cycle.
|
||||
%
|
||||
:- pred output_formatted_cycle_child_list(list(child)::in,
|
||||
@@ -318,6 +319,7 @@ output_formatted_cycle_child_list([Child | Childs], IndexMap, !IO) :-
|
||||
output_formatted_cycle_child_list(Childs, IndexMap, !IO).
|
||||
|
||||
% output_formatted_child_list:
|
||||
%
|
||||
% outputs the child list of the current procedure.
|
||||
%
|
||||
:- pred output_formatted_child_list(list(child)::in, map(string, int)::in,
|
||||
@@ -419,11 +421,8 @@ output.flat_profile([LabelName | LNs], CumTime0, InfoMap, IndexMap, !IO) :-
|
||||
string.int_to_string(Index, IndexStr0),
|
||||
string.append_list(["[", IndexStr0, "] "], IndexStr),
|
||||
io.format("%5.1f %10.2f %8.2f %8d %8.2f %8.2f %s %s\n",
|
||||
[ f(Percentage), f(CumTime),
|
||||
f(Self), i(Calls),
|
||||
f(SelfMs), f(DescMs),
|
||||
s(FullName), s(IndexStr)
|
||||
],
|
||||
[f(Percentage), f(CumTime), f(Self), i(Calls),
|
||||
f(SelfMs), f(DescMs), s(FullName), s(IndexStr)],
|
||||
!IO),
|
||||
|
||||
output.flat_profile(LNs, CumTime, InfoMap, IndexMap, !IO).
|
||||
@@ -448,7 +447,8 @@ output_alphabet_listing_2([Name - Index | T], !IO) :-
|
||||
io.format("[%d]\t%-30s\n", [i(Index), s(Name)], !IO),
|
||||
output_alphabet_listing_2(T, !IO).
|
||||
|
||||
% output.construct_name
|
||||
% output.construct_name:
|
||||
%
|
||||
% Constructs an output name with an optional cycle number if required.
|
||||
%
|
||||
:- func construct_name(string, int) = string.
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% output_prof_info.m
|
||||
%
|
||||
% File: output_prof_info.m
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Declare the main data structures for mercury.profile and their access
|
||||
% Declare the main data structures for the Mercury profiler and their access
|
||||
% predicates, the actual types are exported as well. This is because some
|
||||
% predicates need to access entire data structure.
|
||||
% XXX Should maybe changed at a later date.
|
||||
@@ -33,70 +32,72 @@
|
||||
% XXX Needs to be explained more clearly.
|
||||
:- type output
|
||||
---> output(
|
||||
map(string, output_prof), % Map which contains all
|
||||
% the info which is
|
||||
% required to generate
|
||||
% the output.
|
||||
list(string), % list of label names
|
||||
% used to lookup map.
|
||||
% list sorted so that
|
||||
% it is in the correct
|
||||
% order for call.
|
||||
list(string) % same except for flat
|
||||
).
|
||||
% The map that contains all the info which is required
|
||||
% to generate the output.
|
||||
|
||||
map(string, output_prof),
|
||||
|
||||
% List of label names used to lookup map. list sorted so that
|
||||
% it is in the correct order for call.
|
||||
list(string),
|
||||
|
||||
% Same, except flat.
|
||||
list(string)
|
||||
).
|
||||
|
||||
:- type output_prof
|
||||
---> output_prof(
|
||||
string, % predicate name
|
||||
int, % cycle number
|
||||
float, % %time in current predicate and descendants
|
||||
float, % %time in current predicate
|
||||
float, % self: time spent in current predicate
|
||||
float, % descendants: time spent in current predicate and
|
||||
% descendants
|
||||
int, % called: number of times predicate is called
|
||||
% excluding self recursive calls
|
||||
int, % number of times predicate calls itself.
|
||||
list(parent), % parents of predicate
|
||||
list(child), % children of predicate
|
||||
list(parent), % parents and children who are
|
||||
list(child) % members of the same cycle.
|
||||
)
|
||||
;
|
||||
output_cycle_prof(
|
||||
string, % predicate name
|
||||
int, % cycle number
|
||||
float, % %time in current predicate and descendants
|
||||
float, % self: time spent in current predicate
|
||||
float, % descendants: time spent in current predicate
|
||||
% and descendants
|
||||
int, % called: number of times predicate is called
|
||||
% excluding self recursive calls
|
||||
int, % number of times predicate calls itself.
|
||||
list(parent), % parents of predicate
|
||||
list(child) % children of predicate
|
||||
).
|
||||
string, % predicate name
|
||||
int, % cycle number
|
||||
float, % %time in current predicate and descendants
|
||||
float, % %time in current predicate
|
||||
float, % self: time spent in current predicate
|
||||
float, % descendants: time spent in current predicate
|
||||
% and descendants
|
||||
int, % called: number of times predicate is called
|
||||
% excluding self recursive calls
|
||||
int, % number of times predicate calls itself.
|
||||
list(parent), % parents of predicate
|
||||
list(child), % children of predicate
|
||||
list(parent), % parents and children who are
|
||||
list(child) % members of the same cycle.
|
||||
)
|
||||
; output_cycle_prof(
|
||||
string, % predicate name
|
||||
int, % cycle number
|
||||
float, % %time in current predicate and descendants
|
||||
float, % self: time spent in current predicate
|
||||
float, % descendants: time spent in current predicate
|
||||
% and descendants
|
||||
int, % called: number of times predicate is called
|
||||
% excluding self recursive calls
|
||||
int, % number of times predicate calls itself.
|
||||
list(parent), % parents of predicate
|
||||
list(child) % children of predicate
|
||||
).
|
||||
|
||||
:- type parent
|
||||
---> parent(
|
||||
string, % parent name
|
||||
int, % cycle number
|
||||
float, % the number of seconds of current predicate's
|
||||
% self time which is due to calls from this parent.
|
||||
float, % same as above for descendants
|
||||
int % calls to current predicate
|
||||
).
|
||||
string, % parent name
|
||||
int, % cycle number
|
||||
float, % the number of seconds of current predicate's
|
||||
% self time which is due to calls from this
|
||||
% parent.
|
||||
float, % same as above for descendants
|
||||
int % calls to current predicate
|
||||
).
|
||||
|
||||
:- type child
|
||||
---> child(
|
||||
string, % child name
|
||||
int, % cycle number
|
||||
float, % the number of seconds of child's self time
|
||||
% which is due to calls from the current predicate.
|
||||
float, % same as above for descendants
|
||||
int, % number of times child called
|
||||
int % total calls of child
|
||||
).
|
||||
string, % child name
|
||||
int, % cycle number
|
||||
float, % the number of seconds of child's self time
|
||||
% which is due to calls from the current
|
||||
% predicate.
|
||||
float, % same as above for descendants
|
||||
int, % number of times child called
|
||||
int % total calls of child
|
||||
).
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
:- end_module output_prof_info.
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% process_file.m
|
||||
%
|
||||
% File: process_file.m
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Processs the files that contain the label declarations, label counts and
|
||||
@@ -27,8 +26,8 @@
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
:- pred process_file.main(prof::out, relation(string)::out, io::di, io::uo)
|
||||
is det.
|
||||
:- pred process_profiling_data_files(prof::out, relation(string)::out,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
%-----------------------------------------------------------------------------%
|
||||
@@ -52,7 +51,7 @@
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
process_file.main(Prof, DynamicCallGraph, !IO) :-
|
||||
process_profiling_data_files(Prof, DynamicCallGraph, !IO) :-
|
||||
globals.io_lookup_bool_option(very_verbose, VVerbose, !IO),
|
||||
globals.io_lookup_string_option(declfile, DeclFile, !IO),
|
||||
globals.io_lookup_string_option(countfile, CountFile, !IO),
|
||||
@@ -103,13 +102,14 @@ process_file.main(Prof, DynamicCallGraph, !IO) :-
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% process_addr_decl:
|
||||
% process_addr_decl(AddrDeclMap, ProfNodeMap, !IO):
|
||||
%
|
||||
% Reads in the Prof.Decl file.
|
||||
% Builds the addrdecl map which associates label names(key)
|
||||
% with label addresses.
|
||||
% Also builds the prof_node_map which associates label addresses
|
||||
% with the prof_node structure. Initialises and inserts the
|
||||
% label name into the structure at the same time.
|
||||
% with the prof_node structure. Initialises and inserts the label name
|
||||
% into the structure at the same time.
|
||||
%
|
||||
:- pred process_addr_decl(addrdecl::out, prof_node_map::out,
|
||||
io::di, io::uo) is det.
|
||||
@@ -154,9 +154,11 @@ process_addr_decl_2(!AddrDecl, !ProfNodeMap, !IO) :-
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% process_addr:
|
||||
% Reads in the Prof.Counts file and stores all the counts in the
|
||||
% prof_node structure. Also sums the total counts at the same time.
|
||||
% process_addr(!ProfNodeMap, WhatToProfile, Scale, Units, TotalCounts,
|
||||
% !IO):
|
||||
%
|
||||
% Reads in the Prof.Counts file and stores all the counts in the prof_node
|
||||
% structure. Also sums the total counts at the same time.
|
||||
%
|
||||
:- pred process_addr(prof_node_map::in, prof_node_map::out,
|
||||
what_to_profile::out, float::out, string::out, int::out,
|
||||
@@ -209,9 +211,8 @@ process_addr_2(!TotalCounts, !ProfNodeMap, !IO) :-
|
||||
svmap.set(LabelAddr, ProfNode, !ProfNodeMap),
|
||||
!:TotalCounts = !.TotalCounts + Count
|
||||
;
|
||||
io.format("\nWarning address " ++
|
||||
"%d not found! Ignoring address and " ++
|
||||
"continuing computation.\n",
|
||||
io.format("\nWarning address %d not found! " ++
|
||||
"Ignoring address and continuing computation.\n",
|
||||
[i(LabelAddr)], !IO)
|
||||
),
|
||||
process_addr_2(!TotalCounts, !ProfNodeMap, !IO)
|
||||
@@ -221,7 +222,8 @@ process_addr_2(!TotalCounts, !ProfNodeMap, !IO) :-
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% process_addr_pair:
|
||||
% process_addr_pair(!ProfNodeMap, !AddrDecl, DynamicCallGraph, !IO):
|
||||
%
|
||||
% Reads in the Prof.CallPair file and stores the data in the relevant
|
||||
% lists of the prof_node structure. Also calculates the number of
|
||||
% times a predicate is called.
|
||||
@@ -259,19 +261,18 @@ process_addr_pair_2(Dynamic, !DynamicCallGraph, !ProfNodeMap, !AddrDecl,
|
||||
read_label_addr(CalleeAddr, !IO),
|
||||
read_int(Count, !IO),
|
||||
|
||||
% Get child and parent information
|
||||
% Get child and parent information.
|
||||
lookup_addr(CallerAddr, CallerProfNode0, !AddrDecl, !ProfNodeMap),
|
||||
lookup_addr(CalleeAddr, CalleeProfNode0, !AddrDecl, !ProfNodeMap),
|
||||
prof_node_get_pred_name(CallerProfNode0, CallerName),
|
||||
prof_node_get_pred_name(CalleeProfNode0, CalleeName),
|
||||
|
||||
% Insert child information
|
||||
|
||||
% Insert child information.
|
||||
prof_node_concat_to_child(CalleeName, Count, CallerProfNode0,
|
||||
CallerProfNode),
|
||||
svmap.set(CallerAddr, CallerProfNode, !ProfNodeMap),
|
||||
|
||||
% Update the total calls field if not self recursive
|
||||
% Update the total calls field if not self recursive.
|
||||
( CalleeAddr \= CallerAddr ->
|
||||
prof_node_get_total_calls(CalleeProfNode0, TotalCalls0),
|
||||
TotalCalls = TotalCalls0 + Count,
|
||||
@@ -283,7 +284,7 @@ process_addr_pair_2(Dynamic, !DynamicCallGraph, !ProfNodeMap, !AddrDecl,
|
||||
prof_node_set_self_calls(Count, CalleeProfNode0, CalleeProfNode)
|
||||
),
|
||||
|
||||
% Insert parent information
|
||||
% Insert parent information.
|
||||
svmap.set(CalleeAddr, CalleeProfNode, !ProfNodeMap),
|
||||
|
||||
% Add edge to call graph if generating dynamic call graph.
|
||||
@@ -303,8 +304,9 @@ process_addr_pair_2(Dynamic, !DynamicCallGraph, !ProfNodeMap, !AddrDecl,
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% process_library_callgraph:
|
||||
% XXX
|
||||
% process_library_callgraph(LibraryATSort, LibPredMap, !IO):
|
||||
%
|
||||
% XXX
|
||||
%
|
||||
:- pred process_library_callgraph(list(string)::out, map(string, unit)::out,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% prof_debug.m: Debuging predicates for the mercury profiler
|
||||
%
|
||||
% File: prof_debug.m.
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Debugging predicates for the Mercury profiler.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
@@ -23,6 +24,7 @@
|
||||
:- import_module string.
|
||||
|
||||
% output_cliques:
|
||||
%
|
||||
% Used to check that the topological ordering is being done correctly.
|
||||
%
|
||||
:- pred output_cliques(list(set(string))::in, io::di, io::uo) is det.
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% prof_info.m
|
||||
|
||||
% File: prof_info.m
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Declare the main data structures for mercury.profile and their access
|
||||
@@ -28,16 +27,16 @@
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% prof: Data structure which contains ALL the relevant info for use
|
||||
% in generating the output.
|
||||
% in generating the output.
|
||||
:- type prof.
|
||||
|
||||
% addrdecl = map(label_name, label_address)
|
||||
% Maps label names to label addresses.
|
||||
:- type addrdecl == map(string, int).
|
||||
|
||||
% prof_node_map = map(label_address, prof_node)
|
||||
% Maps label addresses to prof nodes.
|
||||
:- type prof_node_map == map(int, prof_node).
|
||||
|
||||
% cycle_map == map(predicate_name, cycle it is in).
|
||||
% Maps predicate names to the cycle the predicate is in.
|
||||
:- type cycle_map == map(string, int).
|
||||
|
||||
% prof_node: Contains all the info used for output, for a single pred.
|
||||
@@ -230,7 +229,7 @@
|
||||
% address.
|
||||
)
|
||||
; cycle_node(
|
||||
% A node which is built up with more then one predicate
|
||||
% A node which is built up with more than one predicate
|
||||
% and is a cycle.
|
||||
|
||||
cycle_name :: string,
|
||||
@@ -262,7 +261,8 @@
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% get_prof_node:
|
||||
% Gets the prof_node given a label name.
|
||||
%
|
||||
% Gets the prof_node given a label name.
|
||||
%
|
||||
get_prof_node(Pred, AddrMap, ProfNodeMap, ProfNode) :-
|
||||
map.lookup(AddrMap, Pred, Key),
|
||||
@@ -392,7 +392,7 @@ prof_node_concat_to_name_list(_, cycle_node(_, _, _, _, _, _, _), _) :-
|
||||
prof_node_concat_to_member(Name, Count, cycle_node(A, B, C, D, CList, F, G),
|
||||
cycle_node(A, B, C, D, [pred_info(Name,Count) | CList], F, G)).
|
||||
prof_node_concat_to_member(_, _, pred_node(_, _, _, _, _, _, _, _, _), _) :-
|
||||
error("prof_node_concat_to_member: pred_node has no members\n").
|
||||
error("prof_node_concat_to_member: pred_node has no members\n").
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% propagate.m
|
||||
%
|
||||
% File: propagate.m
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Propagates the counts around the call_graph.
|
||||
% To do this it first identifies all the cycles in the call graph.
|
||||
% Each cycle is treated as a new super-predicate. ie All time propagated into
|
||||
% a cycle is shared between all it's members.
|
||||
%
|
||||
% To do this, it first identifies all the cycles in the call graph.
|
||||
% Each cycle is treated as a new super-predicate, i.e. all time propagated
|
||||
% into a cycle is shared between all its members.
|
||||
% Then using a topological sorting of the call graph, the time is propagated
|
||||
% from the leaves of all the call graph to the head.
|
||||
%
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
:- pred propagate.counts(relation(string)::in, prof::in, prof::out,
|
||||
:- pred propagate_counts(relation(string)::in, prof::in, prof::out,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
@@ -49,155 +49,148 @@
|
||||
:- import_module sparse_bitset.
|
||||
:- import_module string.
|
||||
:- import_module svmap.
|
||||
:- import_module svmulti_map.
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
:- type cycle_info ==
|
||||
pair(
|
||||
map(string, int), % predicate - cycle
|
||||
multi_map(int, string) % cycle - list preds
|
||||
).
|
||||
:- type pred_to_cycle_map == map(string, int).
|
||||
:- type cycle_to_preds_map == multi_map(int, string).
|
||||
|
||||
propagate.counts(CallGraph, !Prof, !IO) :-
|
||||
:- type cycle_info
|
||||
---> cycle_info(
|
||||
pred_to_cycle_map :: pred_to_cycle_map,
|
||||
cycle_to_preds_map :: cycle_to_preds_map
|
||||
).
|
||||
|
||||
propagate_counts(CallGraph, !Prof, !IO) :-
|
||||
prof_get_addrdeclmap(!.Prof, AddrDeclMap),
|
||||
prof_get_profnodemap(!.Prof, ProfNodeMap0),
|
||||
|
||||
propagate.identify_cycles(CallGraph, ATSort, CycleInfo),
|
||||
propagate.update_cycles(CycleInfo, AddrDeclMap, ProfNodeMap0,
|
||||
ProfNodeMap1),
|
||||
identify_cycles(CallGraph, ATSort, CycleInfo),
|
||||
update_cycles(CycleInfo, AddrDeclMap, ProfNodeMap0, ProfNodeMap1),
|
||||
|
||||
propagate.counts_2(ATSort, CycleInfo, AddrDeclMap, ProfNodeMap1,
|
||||
ProfNodeMap),
|
||||
propagate_counts_2(ATSort, CycleInfo, AddrDeclMap,
|
||||
ProfNodeMap1, ProfNodeMap),
|
||||
|
||||
prof_set_cyclemap(fst(CycleInfo), !Prof),
|
||||
prof_set_cyclemap(CycleInfo ^ pred_to_cycle_map, !Prof),
|
||||
prof_set_profnodemap(ProfNodeMap, !Prof).
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% propagate.identify_cycles:
|
||||
% identify_cycles(Rel, ATSort, CycleInfo):
|
||||
%
|
||||
% Identifies the cycles in the callgraph and places the members of each
|
||||
% cycle into a map which associates a unique int with each cycle and a
|
||||
% multimap which associates with each cycle number a list of preds.
|
||||
% Also approximate topologically sorts the call graph.
|
||||
%
|
||||
:- pred propagate.identify_cycles(relation(string)::in, list(string)::out,
|
||||
:- pred identify_cycles(relation(string)::in, list(string)::out,
|
||||
cycle_info::out) is det.
|
||||
|
||||
propagate.identify_cycles(Rel, ATSort, CycleInfo) :-
|
||||
identify_cycles(Rel, ATSort, cycle_info(PredToCycleMap, CycleToPredsMap)) :-
|
||||
relation.dfsrev(Rel, DfsRev),
|
||||
relation.inverse(Rel, RelInv),
|
||||
propagate.identify_cycles_2(DfsRev, 1, RelInv, sparse_bitset.init,
|
||||
[], ATSort, cycle_info_init, CycleInfo).
|
||||
identify_cycles_2(DfsRev, 1, RelInv, sparse_bitset.init,
|
||||
[], ATSort, map.init, PredToCycleMap, multi_map.init, CycleToPredsMap).
|
||||
|
||||
:- pred propagate.identify_cycles_2(list(relation_key)::in, int::in,
|
||||
:- pred identify_cycles_2(list(relation_key)::in, int::in,
|
||||
relation(string)::in, relation_key_set::in,
|
||||
list(string)::in, list(string)::out, cycle_info::in, cycle_info::out)
|
||||
is det.
|
||||
list(string)::in, list(string)::out,
|
||||
pred_to_cycle_map::in, pred_to_cycle_map::out,
|
||||
cycle_to_preds_map::in, cycle_to_preds_map::out) is det.
|
||||
|
||||
propagate.identify_cycles_2([], _, _, _, !ATSort, !CycleInfo).
|
||||
propagate.identify_cycles_2([X | Xs0], CycleNum0, RelInv, Visit0, !ATSort,
|
||||
!CycleInfo) :-
|
||||
%
|
||||
% Do a DFS on R'. The nodes we can get to and have not
|
||||
identify_cycles_2([], _, _, _, !ATSort, !PredToCycleMap, !CycleToPredsMap).
|
||||
identify_cycles_2([Key | Keys0], CycleNum0, RelInv, Visit0, !ATSort,
|
||||
!PredToCycleMap, !CycleToPredsMap) :-
|
||||
% Do a depth-first search on R'. The nodes we can get to and have not
|
||||
% already visited before are one cycle in the call graph.
|
||||
%
|
||||
relation.dfsrev(RelInv, X, Visit0, Visit, DfsRev0),
|
||||
|
||||
relation.dfsrev(RelInv, Key, Visit0, Visit, DfsRev0),
|
||||
list.map(relation.lookup_key(RelInv), DfsRev0, DfsRev),
|
||||
|
||||
(
|
||||
(
|
||||
DfsRev = [_]
|
||||
;
|
||||
DfsRev = [], % This case should never happen
|
||||
error("propagate.identify_cycles_2: empty list\n")
|
||||
)
|
||||
->
|
||||
DfsRev = [],
|
||||
error("identify_cycles_2: empty list\n")
|
||||
;
|
||||
DfsRev = [_],
|
||||
CycleNum = CycleNum0
|
||||
;
|
||||
DfsRev = [_, _ | _],
|
||||
CycleNum = CycleNum0 + 1,
|
||||
propagate.add_to_cycle_map(DfsRev, CycleNum, !CycleInfo)
|
||||
add_to_cycle_map(DfsRev, CycleNum, !PredToCycleMap, !CycleToPredsMap)
|
||||
),
|
||||
|
||||
list.append(DfsRev, !ATSort),
|
||||
%
|
||||
% Delete all visited elements from Xs0 as they have already
|
||||
% been identified as part of a cycle.
|
||||
%
|
||||
list.delete_elems(Xs0, DfsRev0, Xs),
|
||||
propagate.identify_cycles_2(Xs, CycleNum, RelInv, Visit, !ATSort,
|
||||
!CycleInfo).
|
||||
|
||||
% cycle_info_init:
|
||||
% Initialise the cycle_info structure.
|
||||
% Delete all visited elements from Keys0 as they have already been
|
||||
% identified as part of a cycle.
|
||||
list.delete_elems(Keys0, DfsRev0, Keys),
|
||||
identify_cycles_2(Keys, CycleNum, RelInv, Visit, !ATSort,
|
||||
!PredToCycleMap, !CycleToPredsMap).
|
||||
|
||||
% add_to_cycle_map(Preds, CycleNum, !PredToCycleMap, !CycleToPredsMap):
|
||||
%
|
||||
:- func cycle_info_init = cycle_info.
|
||||
|
||||
cycle_info_init = map.init - multi_map.init.
|
||||
|
||||
% propagate.add_to_cycle_map:
|
||||
% Add all the predicates in a cycle into the cycle map.
|
||||
%
|
||||
:- pred propagate.add_to_cycle_map(list(string)::in, int::in,
|
||||
cycle_info::in, cycle_info::out) is det.
|
||||
:- pred add_to_cycle_map(list(string)::in, int::in,
|
||||
pred_to_cycle_map::in, pred_to_cycle_map::out,
|
||||
cycle_to_preds_map::in, cycle_to_preds_map::out) is det.
|
||||
|
||||
propagate.add_to_cycle_map([], _, !CycleInfo).
|
||||
propagate.add_to_cycle_map([X | Xs], V, M0 - MM0, M - MM) :-
|
||||
map.det_insert(M0, X, V, M1),
|
||||
multi_map.set(MM0, V, X, MM1),
|
||||
propagate.add_to_cycle_map(Xs, V, M1 - MM1, M - MM).
|
||||
add_to_cycle_map([], _, !PredToCycleMap, !CycleToPredsMap).
|
||||
add_to_cycle_map([Pred | Preds], Cycle, !PredToCycleMap, !CycleToPredsMap) :-
|
||||
svmap.det_insert(Pred, Cycle, !PredToCycleMap),
|
||||
svmulti_map.set(Cycle, Pred, !CycleToPredsMap),
|
||||
add_to_cycle_map(Preds, Cycle, !PredToCycleMap, !CycleToPredsMap).
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
:- pred propagate.update_cycles(cycle_info::in, addrdecl::in,
|
||||
:- pred update_cycles(cycle_info::in, addrdecl::in,
|
||||
prof_node_map::in, prof_node_map::out) is det.
|
||||
|
||||
propagate.update_cycles(_M - MM, AddrDecl, !ProfNodeMap) :-
|
||||
AssocList = multi_map.to_assoc_list(MM),
|
||||
propagate.update_cycles_2(AssocList, AddrDecl, !ProfNodeMap).
|
||||
update_cycles(CycleInfo, AddrDecl, !ProfNodeMap) :-
|
||||
AssocList = multi_map.to_assoc_list(CycleInfo ^ cycle_to_preds_map),
|
||||
update_cycles_2(AssocList, AddrDecl, !ProfNodeMap).
|
||||
|
||||
:- pred propagate.update_cycles_2(assoc_list(int, list(string))::in,
|
||||
:- pred update_cycles_2(assoc_list(int, list(string))::in,
|
||||
addrdecl::in, prof_node_map::in, prof_node_map::out) is det.
|
||||
|
||||
propagate.update_cycles_2([], _, !ProfNodeMap).
|
||||
propagate.update_cycles_2([ Num - Preds | Rest], AddrDecl, !ProfNodeMap) :-
|
||||
propagate.update_cycles_3(Preds, Num, AddrDecl, !ProfNodeMap),
|
||||
propagate.update_cycles_2(Rest, AddrDecl, !ProfNodeMap).
|
||||
update_cycles_2([], _, !ProfNodeMap).
|
||||
update_cycles_2([ Num - Preds | Rest], AddrDecl, !ProfNodeMap) :-
|
||||
update_cycles_3(Preds, Num, AddrDecl, !ProfNodeMap),
|
||||
update_cycles_2(Rest, AddrDecl, !ProfNodeMap).
|
||||
|
||||
:- pred propagate.update_cycles_3(list(string)::in, int::in, addrdecl::in,
|
||||
:- pred update_cycles_3(list(string)::in, int::in, addrdecl::in,
|
||||
prof_node_map::in, prof_node_map::out) is det.
|
||||
|
||||
propagate.update_cycles_3([], _, _, !ProfNodeMap).
|
||||
propagate.update_cycles_3([P | Ps], CycleNum, AddrDecl, !ProfNodeMap) :-
|
||||
update_cycles_3([], _, _, !ProfNodeMap).
|
||||
update_cycles_3([P | Ps], CycleNum, AddrDecl, !ProfNodeMap) :-
|
||||
get_prof_node(P, AddrDecl, !.ProfNodeMap, ProfNode0),
|
||||
prof_node_set_cycle_num(CycleNum, ProfNode0, ProfNode),
|
||||
update_prof_node(P, ProfNode, AddrDecl, !ProfNodeMap),
|
||||
propagate.update_cycles_3(Ps, CycleNum, AddrDecl, !ProfNodeMap).
|
||||
update_cycles_3(Ps, CycleNum, AddrDecl, !ProfNodeMap).
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
% propagate.counts_2
|
||||
% XXX
|
||||
% propagate_counts_2
|
||||
%
|
||||
:- pred propagate.counts_2(list(string)::in, cycle_info::in, addrdecl::in,
|
||||
% XXX
|
||||
%
|
||||
:- pred propagate_counts_2(list(string)::in, cycle_info::in, addrdecl::in,
|
||||
prof_node_map::in, prof_node_map::out) is det.
|
||||
|
||||
propagate.counts_2([], _, _, !ProfNodeMap).
|
||||
propagate.counts_2([Pred | Preds], M - MM, AddrDeclMap, !ProfNodeMap) :-
|
||||
( map.search(M, Pred, Cycle) ->
|
||||
multi_map.lookup(MM, Cycle, CyclePreds),
|
||||
propagate_counts_2([], _, _, !ProfNodeMap).
|
||||
propagate_counts_2([Pred | Preds], CycleInfo, AddrDeclMap, !ProfNodeMap) :-
|
||||
( map.search(CycleInfo ^ pred_to_cycle_map, Pred, Cycle) ->
|
||||
multi_map.lookup(CycleInfo ^ cycle_to_preds_map, Cycle, CyclePreds),
|
||||
list.length(CyclePreds, Length),
|
||||
|
||||
(
|
||||
% Throw away the rest of the predicates to
|
||||
% be processed by the profiler as we are about
|
||||
% to make them into one cycle.
|
||||
list.drop((Length - 1), Preds, NewPreds)
|
||||
->
|
||||
propagate.process_cycle(CyclePreds, Cycle, AddrDeclMap,
|
||||
!ProfNodeMap),
|
||||
propagate.counts_2(NewPreds, M-MM, AddrDeclMap, !ProfNodeMap)
|
||||
% Throw away the rest of the predicates to be processed by the profiler
|
||||
% as we are about to make them into one cycle.
|
||||
( list.drop((Length - 1), Preds, NewPreds) ->
|
||||
process_cycle(CyclePreds, Cycle, AddrDeclMap, !ProfNodeMap),
|
||||
propagate_counts_2(NewPreds, CycleInfo, AddrDeclMap, !ProfNodeMap)
|
||||
;
|
||||
error("propagate.counts_2: list_drop failed\n")
|
||||
error("propagate_counts_2: list_drop failed\n")
|
||||
)
|
||||
;
|
||||
get_prof_node(Pred, AddrDeclMap, !.ProfNodeMap, ProfNode),
|
||||
@@ -208,148 +201,155 @@ propagate.counts_2([Pred | Preds], M - MM, AddrDeclMap, !ProfNodeMap) :-
|
||||
|
||||
TotalCounts = float(InitCounts) + PropCounts,
|
||||
|
||||
propagate.counts_3(ParentList, TotalCounts, float(TotalCalls),
|
||||
propagate_counts_3(ParentList, TotalCounts, float(TotalCalls),
|
||||
AddrDeclMap, !ProfNodeMap),
|
||||
propagate.counts_2(Preds, M-MM, AddrDeclMap, !ProfNodeMap)
|
||||
propagate_counts_2(Preds, CycleInfo, AddrDeclMap, !ProfNodeMap)
|
||||
).
|
||||
|
||||
% propagate.process_cycle:
|
||||
% process_cycle(Preds, Cycle, AddrMap, !ProfNodeMap):
|
||||
%
|
||||
% Takes the list of cycle preds and treats them as one single unit
|
||||
% called <cycle X>.
|
||||
%
|
||||
:- pred propagate.process_cycle(list(string)::in, int::in, addrdecl::in,
|
||||
:- pred process_cycle(list(string)::in, int::in, addrdecl::in,
|
||||
prof_node_map::in, prof_node_map::out) is det.
|
||||
|
||||
propagate.process_cycle(Preds, Cycle, AddrMap, !ProfNodeMap) :-
|
||||
%
|
||||
% Determine the parents of a cycle
|
||||
%
|
||||
propagate.cycle_parents(Preds, AddrMap, !.ProfNodeMap, Total,
|
||||
Recursive, ParentList),
|
||||
%
|
||||
% Build the cycle name.
|
||||
%
|
||||
NameStr = string.format("< cycle %d as a whole >", [i(Cycle)]),
|
||||
%
|
||||
% Work out number of selfcounts.
|
||||
%
|
||||
SelfCounts = propagate.sum_self_counts(Preds, AddrMap, !.ProfNodeMap),
|
||||
%
|
||||
% Work out number of propagated counts.
|
||||
%
|
||||
PropCounts = propagate.sum_propagated_counts(Preds, AddrMap,
|
||||
!.ProfNodeMap),
|
||||
process_cycle(Preds, Cycle, AddrMap, !ProfNodeMap) :-
|
||||
% Determine the parents of a cycle.
|
||||
cycle_parents(Preds, AddrMap, !.ProfNodeMap, Total, Recursive, ParentList),
|
||||
|
||||
propagate.build_cycle_list(Preds, AddrMap, !.ProfNodeMap, CycleList),
|
||||
% Build the cycle name.
|
||||
NameStr = string.format("< cycle %d as a whole >", [i(Cycle)]),
|
||||
|
||||
% Work out number of selfcounts.
|
||||
SelfCounts = sum_self_counts(Preds, AddrMap, !.ProfNodeMap),
|
||||
|
||||
% Work out number of propagated counts.
|
||||
PropCounts = sum_propagated_counts(Preds, AddrMap, !.ProfNodeMap),
|
||||
|
||||
build_cycle_list(Preds, AddrMap, !.ProfNodeMap, CycleList),
|
||||
|
||||
ProfNode = prof_node_init_cycle(NameStr, 0, SelfCounts, PropCounts,
|
||||
CycleList, Total, Recursive),
|
||||
%
|
||||
% NB we give the address of a cycle as being the negative of
|
||||
% the cycle number as this will be unique.
|
||||
%
|
||||
|
||||
% NB We give the address of a cycle as being the negative of the cycle
|
||||
% number as this will be unique.
|
||||
Address = -Cycle,
|
||||
map.det_insert(!.ProfNodeMap, Address, ProfNode, !:ProfNodeMap),
|
||||
%
|
||||
|
||||
% Propagate the counts XXX
|
||||
%
|
||||
TotalCalls = float.float(Total),
|
||||
TotalCounts = float(SelfCounts) + PropCounts,
|
||||
propagate.counts_3(ParentList, TotalCounts, TotalCalls, AddrMap,
|
||||
propagate_counts_3(ParentList, TotalCounts, TotalCalls, AddrMap,
|
||||
!ProfNodeMap).
|
||||
|
||||
% propagate.sum_self_counts:
|
||||
% sum_self_counts(Preds, ADMap, PNMap):
|
||||
%
|
||||
% Sums the self counts fields for all the predicates.
|
||||
%
|
||||
:- func propagate.sum_self_counts(list(string), addrdecl, prof_node_map) = int.
|
||||
:- func sum_self_counts(list(string), addrdecl, prof_node_map) = int.
|
||||
|
||||
propagate.sum_self_counts(Preds, ADMap, PNMap) =
|
||||
list.foldl((func(Pred, Sum0) = Sum :-
|
||||
get_prof_node(Pred, ADMap, PNMap, ProfNode),
|
||||
prof_node_get_initial_counts(ProfNode, InitCount),
|
||||
Sum = Sum0 + InitCount
|
||||
), Preds, 0).
|
||||
sum_self_counts(Preds, ADMap, PNMap) = Sum :-
|
||||
list.foldl(accumulate_self_counts(ADMap, PNMap), Preds, 0, Sum).
|
||||
|
||||
% propagate.sum_propagated_counts:
|
||||
:- pred accumulate_self_counts(addrdecl::in, prof_node_map::in, string::in,
|
||||
int::in, int::out) is det.
|
||||
|
||||
accumulate_self_counts(ADMap, PNMap, Pred, !Sum) :-
|
||||
get_prof_node(Pred, ADMap, PNMap, ProfNode),
|
||||
prof_node_get_initial_counts(ProfNode, InitCount),
|
||||
!:Sum = !.Sum + InitCount.
|
||||
|
||||
% sum_propagated_counts:
|
||||
%
|
||||
% Sums the propagated counts fields for all the predicates.
|
||||
%
|
||||
:- func propagate.sum_propagated_counts(list(string), addrdecl, prof_node_map)
|
||||
= float.
|
||||
:- func sum_propagated_counts(list(string), addrdecl, prof_node_map) = float.
|
||||
|
||||
propagate.sum_propagated_counts(Preds, ADMap, PNMap) =
|
||||
list.foldl((func(Pred, Sum0) = Sum :-
|
||||
get_prof_node(Pred, ADMap, PNMap, ProfNode),
|
||||
prof_node_get_propagated_counts(ProfNode, PropCount),
|
||||
Sum = Sum0 + PropCount
|
||||
), Preds, 0.0).
|
||||
sum_propagated_counts(Preds, ADMap, PNMap) = Sum :-
|
||||
list.foldl(accumulate_propagated_counts(ADMap, PNMap), Preds, 0.0, Sum).
|
||||
|
||||
% propagate.build_cycle_list
|
||||
:- pred accumulate_propagated_counts(addrdecl::in, prof_node_map::in,
|
||||
string::in, float::in, float::out) is det.
|
||||
|
||||
accumulate_propagated_counts(ADMap, PNMap, Pred, !Sum) :-
|
||||
get_prof_node(Pred, ADMap, PNMap, ProfNode),
|
||||
prof_node_get_propagated_counts(ProfNode, PropCount),
|
||||
!:Sum = !.Sum + PropCount.
|
||||
|
||||
% build_cycle_list
|
||||
%
|
||||
% Takes the list of predicates and works out how many times each
|
||||
% predicate is called by a fellow predicate
|
||||
% predicate is called by a fellow predicate.
|
||||
% XXX Not fully implemented yet.
|
||||
%
|
||||
:- pred propagate.build_cycle_list(list(string)::in, addrdecl::in,
|
||||
prof_node_map::in, list(pred_info)::out) is det.
|
||||
:- pred build_cycle_list(list(string)::in, addrdecl::in, prof_node_map::in,
|
||||
list(pred_info)::out) is det.
|
||||
|
||||
propagate.build_cycle_list([], _, _, []).
|
||||
propagate.build_cycle_list([P | Ps], ADM, PNM, CycleList) :-
|
||||
propagate.build_cycle_list(Ps, ADM, PNM, CycleList0),
|
||||
build_cycle_list([], _, _, []).
|
||||
build_cycle_list([P | Ps], ADM, PNM, CycleList) :-
|
||||
build_cycle_list(Ps, ADM, PNM, CycleList0),
|
||||
pred_info_init(P, 0, PredInfo),
|
||||
CycleList = [ PredInfo | CycleList0].
|
||||
CycleList = [PredInfo | CycleList0].
|
||||
|
||||
:- pred propagate.counts_3(list(pred_info)::in, float::in, float::in,
|
||||
:- pred propagate_counts_3(list(pred_info)::in, float::in, float::in,
|
||||
addrdecl::in, prof_node_map::in, prof_node_map::out) is det.
|
||||
|
||||
propagate.counts_3([], _, _, _, !ProfNodeMap).
|
||||
propagate.counts_3([ P | Ps], TotalCounts, TotalCalls, AddrMap,
|
||||
!ProfNodeMap) :-
|
||||
propagate_counts_3([], _, _, _, !ProfNodeMap).
|
||||
propagate_counts_3([ P | Ps], TotalCounts, TotalCalls, AddrMap, !ProfNodeMap) :-
|
||||
pred_info_get_entire(P, Pred, Calls),
|
||||
%
|
||||
|
||||
% Work out the number of counts to propagate.
|
||||
% XXX Probably need to do a 0.0 check
|
||||
%
|
||||
% XXX Probably need to do a 0.0 check.
|
||||
ToPropagateCounts = float(Calls) / TotalCalls * TotalCounts,
|
||||
%
|
||||
|
||||
% Add new counts to current propagated counts.
|
||||
%
|
||||
get_prof_node(Pred, AddrMap, !.ProfNodeMap, ProfNode0),
|
||||
prof_node_get_propagated_counts(ProfNode0, PropCount0),
|
||||
PropCount = PropCount0 + ToPropagateCounts,
|
||||
prof_node_set_propagated_counts(PropCount, ProfNode0, ProfNode),
|
||||
update_prof_node(Pred, ProfNode, AddrMap, !ProfNodeMap),
|
||||
propagate.counts_3(Ps, TotalCounts, TotalCalls, AddrMap, !ProfNodeMap).
|
||||
propagate_counts_3(Ps, TotalCounts, TotalCalls, AddrMap, !ProfNodeMap).
|
||||
|
||||
% propagate.cycle_parents
|
||||
% cycle_parents(Preds, AddrMap, ProfNodeMap, TotalCalls, SelfCalls,
|
||||
% ParentList):
|
||||
%
|
||||
% Returns a list(pred_info) which is the list of parents of the cycle
|
||||
% Also returns how may times the cycle is called and how may times
|
||||
% predicates in a cycle call each other.
|
||||
%
|
||||
:- pred propagate.cycle_parents(list(string)::in, addrdecl::in,
|
||||
prof_node_map::in, int::out, int::out, list(pred_info)::out) is det.
|
||||
:- pred cycle_parents(list(string)::in, addrdecl::in, prof_node_map::in,
|
||||
int::out, int::out, list(pred_info)::out) is det.
|
||||
|
||||
propagate.cycle_parents(Preds, AddrMap, ProfNodeMap, TotalCalls, SelfCalls,
|
||||
cycle_parents(Preds, AddrMap, ProfNodeMap, TotalCalls, SelfCalls,
|
||||
ParentList) :-
|
||||
propagate.build_parent_map(Preds, AddrMap, ProfNodeMap, TotalCalls,
|
||||
build_parent_map(Preds, AddrMap, ProfNodeMap, TotalCalls,
|
||||
SelfCalls, ParentMap),
|
||||
map.to_assoc_list(ParentMap, ParentAssocList),
|
||||
ParentList = assoc_list_to_pred_info_list(ParentAssocList).
|
||||
|
||||
% propagate.build_parent_map:
|
||||
% build_parent_map(CliqueList, AddrMap, ProfNodeMap, TotalCalls, SelfCalls,
|
||||
% ParentMap):
|
||||
%
|
||||
% Builds a map which contains all the parents of a cycle, and the
|
||||
% total number of times that parent is called. Doesn't include the
|
||||
% cycle members, and callers which never call any of the members of
|
||||
% the cycle. At the same time also sums the total calls into the
|
||||
% cycle and the calls internal to the cycle.
|
||||
%
|
||||
:- pred propagate.build_parent_map(list(string)::in, addrdecl::in,
|
||||
:- pred build_parent_map(list(string)::in, addrdecl::in,
|
||||
prof_node_map::in, int::out, int::out, map(string, int)::out) is det.
|
||||
|
||||
propagate.build_parent_map([], _AddrMap, _ProfNodeMap, _, _, _ParentMap) :-
|
||||
error("build_parent_map: empty cycle list\n").
|
||||
propagate.build_parent_map([C | Cs], AddrMap, ProfNodeMap, TotalCalls,
|
||||
SelfCalls, ParentMap) :-
|
||||
build_parent_map_2([C | Cs], [C | Cs], AddrMap, ProfNodeMap,
|
||||
0, TotalCalls, 0, SelfCalls, map.init, ParentMap).
|
||||
build_parent_map(CliqueList, AddrMap, ProfNodeMap, TotalCalls, SelfCalls,
|
||||
ParentMap) :-
|
||||
(
|
||||
CliqueList = [],
|
||||
error("build_parent_map: empty cycle list\n")
|
||||
;
|
||||
CliqueList = [_ | _],
|
||||
build_parent_map_2(CliqueList, CliqueList, AddrMap, ProfNodeMap,
|
||||
0, TotalCalls, 0, SelfCalls, map.init, ParentMap)
|
||||
).
|
||||
|
||||
:- pred build_parent_map_2(list(string)::in, list(string)::in, addrdecl::in,
|
||||
prof_node_map::in, int::in, int::out, int::in, int::out,
|
||||
@@ -360,27 +360,30 @@ build_parent_map_2([C | Cs], CliqueList, AddrMap, ProfNodeMap,
|
||||
!TotalCalls, !SelfCalls, !ParentMap) :-
|
||||
get_prof_node(C, AddrMap, ProfNodeMap, ProfNode),
|
||||
prof_node_get_parent_list(ProfNode, ParentList),
|
||||
add_to_parent_map(ParentList, CliqueList, 0, TotalCalls1,
|
||||
0, SelfCalls1, !ParentMap),
|
||||
add_to_parent_map(ParentList, CliqueList, 0, TotalCalls1, 0, SelfCalls1,
|
||||
!ParentMap),
|
||||
|
||||
!:TotalCalls = !.TotalCalls + TotalCalls1,
|
||||
!:SelfCalls = !.SelfCalls + SelfCalls1,
|
||||
build_parent_map_2(Cs, CliqueList, AddrMap, ProfNodeMap, !TotalCalls,
|
||||
!SelfCalls, !ParentMap).
|
||||
build_parent_map_2(Cs, CliqueList, AddrMap, ProfNodeMap,
|
||||
!TotalCalls, !SelfCalls, !ParentMap).
|
||||
|
||||
% add_to_parent_map:
|
||||
% Adds list of parents to parent map. Ignores clique members and
|
||||
% repeats and callers which never call current predicate.
|
||||
% Also returns the total number of times predicate is called.
|
||||
% add_to_parent_map(Preds, CliqueList, !TotalCalls, !SelfCalls,
|
||||
% !ParentMap):
|
||||
%
|
||||
% Adds list of parents to parent map. Ignores clique members and repeats
|
||||
% and callers which never call current predicate. Also returns the total
|
||||
% number of times predicate is called.
|
||||
%
|
||||
:- pred add_to_parent_map(list(pred_info)::in, list(string)::in,
|
||||
int::in, int::out, int::in, int::out,
|
||||
map(string, int)::in, map(string, int)::out) is det.
|
||||
|
||||
add_to_parent_map([], _, !TotalCalls, !SelfCalls, !ParentMap).
|
||||
add_to_parent_map([P | Ps], CliqueList, !TotalCalls, !SelfCalls, !ParentMap) :-
|
||||
pred_info_get_pred_name(P, PredName),
|
||||
pred_info_get_counts(P, Counts),
|
||||
add_to_parent_map([Pred | Preds], CliqueList, !TotalCalls, !SelfCalls,
|
||||
!ParentMap) :-
|
||||
pred_info_get_pred_name(Pred, PredName),
|
||||
pred_info_get_counts(Pred, Counts),
|
||||
(
|
||||
(
|
||||
list.member(PredName, CliqueList)
|
||||
@@ -389,18 +392,18 @@ add_to_parent_map([P | Ps], CliqueList, !TotalCalls, !SelfCalls, !ParentMap) :-
|
||||
)
|
||||
->
|
||||
!:SelfCalls = !.SelfCalls + Counts,
|
||||
add_to_parent_map(Ps, CliqueList, !TotalCalls, !SelfCalls, !ParentMap)
|
||||
add_to_parent_map(Preds, CliqueList, !TotalCalls, !SelfCalls,
|
||||
!ParentMap)
|
||||
;
|
||||
(
|
||||
map.search(!.ParentMap, PredName, CurrCount0)
|
||||
->
|
||||
( map.search(!.ParentMap, PredName, CurrCount0) ->
|
||||
CurrCount = CurrCount0 + Counts,
|
||||
svmap.det_update(PredName, CurrCount, !ParentMap)
|
||||
;
|
||||
svmap.det_insert(PredName, Counts, !ParentMap)
|
||||
),
|
||||
!:TotalCalls = !.TotalCalls + Counts,
|
||||
add_to_parent_map(Ps, CliqueList, !TotalCalls, !SelfCalls, !ParentMap)
|
||||
add_to_parent_map(Preds, CliqueList, !TotalCalls, !SelfCalls,
|
||||
!ParentMap)
|
||||
).
|
||||
|
||||
:- func assoc_list_to_pred_info_list(assoc_list(string, int))
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
% Public License - see the file COPYING in the Mercury distribution.
|
||||
%-----------------------------------------------------------------------------%
|
||||
%
|
||||
% read.m: Input predicates for use with mercury_profile
|
||||
%
|
||||
% File: read.m.
|
||||
% Main author: petdr.
|
||||
%
|
||||
% Input predicates for use with mercury_profile.
|
||||
%
|
||||
%-----------------------------------------------------------------------------%
|
||||
%-----------------------------------------------------------------------------%
|
||||
|
||||
@@ -67,8 +68,8 @@ maybe_read_label_addr(MaybeLabelAddr, !IO) :-
|
||||
( string.base_string_to_int(16, LabelAddrStr, LabelAddrHex) ->
|
||||
MaybeLabelAddr = yes(LabelAddrHex)
|
||||
;
|
||||
error("maybe_read_label_addr: Label " ++
|
||||
"address not hexadecimal or integer\n")
|
||||
error("maybe_read_label_addr: " ++
|
||||
"Label address not hexadecimal or integer\n")
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user