mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
library/*.m:
mdbcomp/*.m:
ssdb/*.m:
Specify the type constructor for every inst definition that lists
the functors that values of that type may be bound to.
In library/maybe.m, delete the inst maybe_errors/1, because
(a) its name is misleading, since it is for the maybe_error/1 type (no s),
and (b) there is already an inst with the non-misleading name maybe_error
which had an identical definition.
In compiler/dep_par_conj.m, delete two insts that were duplicates
of insts defined in hlds_goal.m, and replace references to them
accordingly.
737 lines
29 KiB
Mathematica
737 lines
29 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2008-2011 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: report.m.
|
|
% Author: pbone.
|
|
%
|
|
% This module defines deep profiling reports. Each report is the result of
|
|
% querying a Deep.data file. Different queries result in different types
|
|
% of reports. Reports can be converted into HTML by display_report.m and
|
|
% html_format.m, but some tools may use the data structures constructed here
|
|
% directly.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module report.
|
|
:- interface.
|
|
|
|
:- import_module coverage.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.goal_path.
|
|
:- import_module mdbcomp.program_representation.
|
|
:- import_module measurement_units.
|
|
:- import_module profile.
|
|
% TODO: The data structures in query should be moved into a different module,
|
|
% then this module may depend on those data structures but not the rest of
|
|
% query.
|
|
:- import_module query.
|
|
:- import_module var_use_analysis.
|
|
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module set.
|
|
:- import_module unit.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type deep_report
|
|
---> report_message(
|
|
message_report
|
|
)
|
|
; report_menu(
|
|
maybe_error(menu_report)
|
|
)
|
|
; report_clique(
|
|
maybe_error(clique_report)
|
|
)
|
|
; report_clique_recursion_costs(
|
|
maybe_error(clique_recursion_report)
|
|
)
|
|
; report_recursion_types_frequency(
|
|
maybe_error(recursion_types_frequency_report)
|
|
)
|
|
; report_program_modules(
|
|
maybe_error(program_modules_report)
|
|
)
|
|
; report_module(
|
|
maybe_error(module_report)
|
|
)
|
|
; report_module_getter_setters(
|
|
maybe_error(module_getter_setters_report)
|
|
)
|
|
; report_module_rep(
|
|
maybe_error(module_rep_report)
|
|
)
|
|
; report_top_procs(
|
|
maybe_error(top_procs_report)
|
|
)
|
|
; report_proc(
|
|
maybe_error(proc_report)
|
|
)
|
|
; report_procrep_coverage(
|
|
maybe_error(procrep_coverage_info)
|
|
)
|
|
; report_proc_callers(
|
|
maybe_error(proc_callers_report)
|
|
)
|
|
; report_proc_static_dump(
|
|
maybe_error(proc_static_dump_info)
|
|
)
|
|
; report_proc_dynamic_dump(
|
|
maybe_error(proc_dynamic_dump_info)
|
|
)
|
|
; report_call_site_static_dump(
|
|
maybe_error(call_site_static_dump_info)
|
|
)
|
|
; report_call_site_dynamic_dump(
|
|
maybe_error(call_site_dynamic_dump_info)
|
|
)
|
|
; report_clique_dump(
|
|
maybe_error(clique_dump_info)
|
|
)
|
|
; report_call_site_dynamic_var_use(
|
|
maybe_error(call_site_dynamic_var_use_info)
|
|
).
|
|
|
|
:- type message_report
|
|
---> message_report(
|
|
% A simple message, this may be used in response to the
|
|
% 'shutdown' and similar queries.
|
|
|
|
string
|
|
).
|
|
|
|
:- type menu_report
|
|
---> menu_report(
|
|
% Statistics about the deep profiling data. Gives simple
|
|
% information about the size of the program and its runtime.
|
|
% These statistics are displayed on the menu of the mdprof_cgi
|
|
% program.
|
|
|
|
menu_program_name :: string,
|
|
menu_quanta_per_sec :: int,
|
|
menu_user_quanta :: int,
|
|
menu_inst_quanta :: int,
|
|
menu_num_callseqs :: int,
|
|
menu_num_csd :: int,
|
|
menu_num_css :: int,
|
|
menu_num_pd :: int,
|
|
menu_num_ps :: int,
|
|
menu_num_clique :: int
|
|
).
|
|
|
|
:- type clique_report
|
|
---> clique_report(
|
|
% The clique the report is for.
|
|
cr_clique_ptr :: clique_ptr,
|
|
|
|
% The ancestor call sites of the clique,
|
|
% - from the innermost ancestor call site (in the parent)
|
|
% - to the outermost ancestor call site (in main/2).
|
|
cr_ancestor_call_sites :: list(
|
|
perf_row_data(ancestor_desc)),
|
|
|
|
% Reports for every procedure in the clique. The first
|
|
% procedure in the list is the entry procedure (if the parent
|
|
% clique had a valid CSD.) and that CSD was found in the
|
|
% clique. TODO: we might want to express this within this
|
|
% type.
|
|
cr_clique_procs :: list(clique_proc_report)
|
|
).
|
|
|
|
:- type clique_proc_report
|
|
---> clique_proc_report(
|
|
% Summary information for the cost of this procedure in this
|
|
% clique.
|
|
cpr_proc_summary :: perf_row_data(proc_desc),
|
|
|
|
% A clique may contain more than one proc_dynamic for the same
|
|
% procedure in one rare circumstance. Consider a clique of
|
|
% two procedures, let's call them p and q. The entry procedure
|
|
% is p. When p calls q and q then calls p, the runtime
|
|
% discovers they are in the same clique. However, after all
|
|
% those mutually recursive calls unwind and we get back to the
|
|
% original call to p, p can call q again. If it does so through
|
|
% a call site through which it has not called q before, then
|
|
% the call port code in q will allocate a new proc_dynamic,
|
|
% since it will not find an existing one it can reuse;
|
|
% q's proc_static won't point to an active proc_dynamic, and
|
|
% the call site will not supply one either.
|
|
%
|
|
% We could modify the code we invoke at call ports to keep a
|
|
% list of the proc_dynamics of the procedures known to be in
|
|
% the current clique, and to reuse the proc_dynamic of the
|
|
% callee in these cases, but that would significantly increase
|
|
% the call port overhead. Instead, we let the callee allocate a
|
|
% second (and maybe third etc) proc_dynamic for a procedure,
|
|
% and let the deep profiler sort it out.
|
|
%
|
|
% Note that the entry procedure of a clique will always have
|
|
% exactly one proc_dynamic.
|
|
cpr_first_proc_dynamic :: clique_proc_dynamic_report,
|
|
cpr_other_proc_dynamics :: list(clique_proc_dynamic_report)
|
|
).
|
|
|
|
:- type clique_proc_dynamic_report
|
|
---> clique_proc_dynamic_report(
|
|
% Summary information for the cost of this proc _dynamic
|
|
% in this clique.
|
|
cpdr_proc_summary :: perf_row_data(proc_desc),
|
|
|
|
% Information about the costs of the call sites in this
|
|
% procedure in this clique.
|
|
cpdr_call_sites :: list(clique_call_site_report)
|
|
).
|
|
|
|
:- type clique_call_site_report
|
|
---> clique_call_site_report(
|
|
% The id of the call site, and the summary performance for
|
|
% that call site.
|
|
ccsr_call_site_summary :: perf_row_data(call_site_desc),
|
|
|
|
ccsr_kind_and_callee :: call_site_kind_and_callee(
|
|
proc_desc),
|
|
|
|
% All the callees and their associated performance information.
|
|
% If ccsr_kind_and_callee indicates a normal call, the list
|
|
% will have either zero entries (no calls through this site)
|
|
% or one entry (some calls through this site). If this is
|
|
% some other kind of call site, the list may have any number
|
|
% of entries.
|
|
ccsr_callee_perfs :: list(perf_row_data(clique_desc))
|
|
).
|
|
|
|
:- type clique_recursion_report
|
|
---> clique_recursion_report(
|
|
% The clique the report is for.
|
|
crr_clique_ptr :: clique_ptr,
|
|
|
|
% The type of recursion in this clique.
|
|
crr_recursion_type :: recursion_type,
|
|
|
|
% The number of procedures in the clique.
|
|
crr_num_procs :: int
|
|
).
|
|
|
|
:- type recursion_type
|
|
---> rt_not_recursive
|
|
; rt_single(
|
|
rts_base :: recursion_level_report,
|
|
rts_recursive :: recursion_level_report,
|
|
rts_avg_max_depth :: float,
|
|
|
|
% These costs are per-call.
|
|
rts_avg_rec_cost :: float,
|
|
|
|
% The cost at any level is Cost = func(Level).
|
|
rts_any_rec_cost :: (func(int) = float)
|
|
)
|
|
; rt_divide_and_conquer(
|
|
rtdsc_base :: recursion_level_report,
|
|
rtdsc_recursive :: recursion_level_report
|
|
)
|
|
; rt_mutual_recursion(
|
|
rtml_num_procs :: int
|
|
)
|
|
; rt_other(
|
|
rto_all_levels :: list(recursion_level_report)
|
|
)
|
|
; rt_errors(
|
|
rte_errors :: list(string)
|
|
).
|
|
|
|
% Recursion types for which call costs at any level can be calculated.
|
|
%
|
|
:- inst recursion_type_known_costs for recursion_type/0
|
|
---> rt_not_recursive
|
|
; rt_single(ground, ground, ground, ground, ground).
|
|
|
|
% Recursion types for which call costs at any level can not be calculated.
|
|
%
|
|
:- inst recursion_type_unknown_costs for recursion_type/0
|
|
---> rt_divide_and_conquer(ground, ground)
|
|
; rt_mutual_recursion(ground)
|
|
; rt_other(ground)
|
|
; rt_errors(ground).
|
|
|
|
:- type recursion_level_report
|
|
---> recursion_level_report(
|
|
rlr_level :: int,
|
|
rlr_calls :: int,
|
|
rlr_prob :: probability,
|
|
rlr_non_rec_calls_cost :: float,
|
|
rlr_rec_calls_ex_chld_cost :: float
|
|
).
|
|
|
|
:- type recursion_types_frequency_report
|
|
---> recursion_types_frequency_report(
|
|
rtfr_histogram :: recursion_type_histogram
|
|
).
|
|
|
|
:- type recursion_type_histogram ==
|
|
map(recursion_type_simple, recursion_type_freq_data).
|
|
|
|
:- type recursion_type_simple
|
|
---> rts_not_recursive
|
|
; rts_single
|
|
; rts_divide_and_conquer
|
|
; rts_mutual_recursion(
|
|
rtsmr_num_procs :: int
|
|
)
|
|
; rts_other(
|
|
rtso_levels :: set(int)
|
|
)
|
|
; rts_error(
|
|
rtse_error :: string
|
|
)
|
|
; rts_total_error_instances.
|
|
|
|
:- type recursion_type_freq_data
|
|
---> recursion_type_freq_data(
|
|
rtfd_freq :: int,
|
|
rtfd_percent :: percent,
|
|
rtfd_maybe_summary :: maybe(perf_row_data(unit)),
|
|
rtfd_entry_procs :: recursion_type_proc_map
|
|
).
|
|
|
|
:- type recursion_type_proc_map ==
|
|
map(proc_static_ptr, recursion_type_proc_freq_data).
|
|
|
|
:- type recursion_type_proc_freq_data
|
|
---> recursion_type_proc_freq_data(
|
|
rtpfd_freq :: int,
|
|
rtpfd_percent :: percent,
|
|
rtpfd_summary :: perf_row_data(proc_desc)
|
|
).
|
|
|
|
:- type program_modules_report
|
|
---> program_modules_report(
|
|
% Summary information about all the modules of the program.
|
|
program_modules :: list(
|
|
perf_row_data(module_active))
|
|
).
|
|
|
|
:- type module_report
|
|
---> module_report(
|
|
% Summary information about all the procedures in one module
|
|
% of the program.
|
|
mr_module_name :: string,
|
|
mr_have_module_rep :: maybe_have_module_rep,
|
|
mr_procs :: list(perf_row_data(proc_active))
|
|
).
|
|
|
|
:- type maybe_have_module_rep
|
|
---> do_not_have_module_rep
|
|
; have_module_rep.
|
|
|
|
:- type data_struct_name
|
|
---> data_struct_name(string).
|
|
|
|
:- type field_name
|
|
---> field_name(string).
|
|
|
|
:- type getter_or_setter
|
|
---> getter
|
|
; setter.
|
|
|
|
:- type gs_field_info(I, S)
|
|
---> gs_field_both(
|
|
gsf_both_getter :: I,
|
|
gsf_both_setter :: I,
|
|
gsf_both_summary :: S
|
|
)
|
|
; gs_field_getter(
|
|
gsf_getter :: I
|
|
)
|
|
; gs_field_setter(
|
|
gsf_setter :: I
|
|
).
|
|
|
|
:- type gs_field_map(T) == map(field_name, T).
|
|
:- type gs_ds_map(T) == map(data_struct_name, gs_field_map(T)).
|
|
|
|
:- type gs_field_info == gs_field_info(
|
|
perf_row_data(proc_desc),
|
|
perf_row_data(unit)
|
|
).
|
|
:- type gs_field_map == gs_field_map(gs_field_info).
|
|
:- type gs_ds_map == gs_ds_map(gs_field_info).
|
|
|
|
:- type module_getter_setters_report
|
|
---> module_getter_setters_report(
|
|
% Summary information about all the getter/setter procedures
|
|
% in one module of the program.
|
|
mgsr_module_name :: string,
|
|
mgsr_procs :: gs_ds_map
|
|
).
|
|
|
|
:- type module_rep_report
|
|
---> module_rep_report(
|
|
% A representation of one module of the program.
|
|
mrr_module_name :: string,
|
|
mrr_report :: string
|
|
).
|
|
|
|
:- type top_procs_report
|
|
---> top_procs_report(
|
|
% Information about the most expensive procedures. The ordering
|
|
% field defines what measurements are used to select and order
|
|
% the procedures in this report.
|
|
|
|
tp_ordering :: report_ordering,
|
|
tp_top_procs :: list(perf_row_data(proc_desc))
|
|
).
|
|
|
|
:- type proc_report
|
|
---> proc_report(
|
|
% The integer is a count of the number of cliques this
|
|
% procedure appears in.
|
|
proc_callers_summary :: perf_row_data(callers_counts),
|
|
|
|
% The proc description is inside the proc_summary field.
|
|
proc_summary :: perf_row_data(proc_desc),
|
|
proc_call_site_summaries :: list(call_site_perf)
|
|
).
|
|
|
|
% A count of the number of callers.
|
|
%
|
|
:- type callers_counts
|
|
---> callers_counts(
|
|
cc_static :: int,
|
|
cc_dynamic :: int
|
|
).
|
|
|
|
:- type call_site_perf
|
|
---> call_site_perf(
|
|
% The csf_summary_perf field contains the description of this
|
|
% call site and the summary of its performance.
|
|
%
|
|
% If the call site can call only one procedure, the csf_kind
|
|
% field tell you the id and the name of that procedure, and
|
|
% the type substitution made in the call to it, if there is one
|
|
% and it is known.
|
|
%
|
|
% Otherwise, if the call site can call more than one procedure,
|
|
% the csf_sub_callees field will have one performance row
|
|
% giving the contribution of each of the called procedures.
|
|
%
|
|
% If csf_kind = normal_call_and_info(_), then csf_sub_callees
|
|
% should be the empty list.
|
|
%
|
|
% The call site description is inside the csf_summary field.
|
|
|
|
csf_kind :: call_site_kind_and_info(
|
|
normal_callee_id),
|
|
csf_summary_perf :: perf_row_data(call_site_desc),
|
|
csf_sub_callees :: list(perf_row_data(proc_desc))
|
|
).
|
|
|
|
:- type normal_callee_id
|
|
---> normal_callee_id(
|
|
nci_callee_desc :: proc_desc,
|
|
nci_type_subst :: string
|
|
).
|
|
|
|
:- type procrep_coverage_info
|
|
---> procrep_coverage_info(
|
|
prci_proc :: proc_static_ptr,
|
|
prci_proc_rep :: proc_rep(goal_id),
|
|
prci_coverage_array :: goal_attr_array(coverage_info)
|
|
).
|
|
|
|
:- type proc_callers_report
|
|
---> proc_callers_report(
|
|
% The id of the procedure.
|
|
pc_proc_desc :: proc_desc,
|
|
|
|
% The call sites that call this procedure.
|
|
pc_callers :: proc_callers,
|
|
|
|
% Which batch of rows to show; transmitted without processing
|
|
% from the request.
|
|
pc_batch_number :: int,
|
|
|
|
% How many callers per batch, also transmitted without
|
|
% processing from the request.
|
|
pc_callers_per_batch :: int,
|
|
|
|
% Whether contour exclusion was applied in computing the
|
|
% pc_callers field.
|
|
pc_contour_exclusion :: contour_exclusion,
|
|
|
|
% If contour exclusion was asked for, this field may contain
|
|
% a warning message about nonfatal problems with the exclusion
|
|
% specification file.
|
|
pc_contour_warn_message :: maybe(string)
|
|
).
|
|
|
|
:- type proc_callers
|
|
---> proc_caller_call_sites(
|
|
pc_caller_call_sites :: list(
|
|
perf_row_data(call_site_desc))
|
|
)
|
|
; proc_caller_procedures(
|
|
pc_caller_procedures :: list(
|
|
perf_row_data(proc_desc))
|
|
)
|
|
; proc_caller_modules(
|
|
pc_caller_modules :: list(
|
|
perf_row_data(string))
|
|
)
|
|
; proc_caller_cliques(
|
|
pc_caller_cliques :: list(
|
|
perf_row_data(clique_desc))
|
|
).
|
|
|
|
:- type proc_static_dump_info
|
|
---> proc_static_dump_info(
|
|
psdi_psptr :: proc_static_ptr,
|
|
psdi_raw_name :: string,
|
|
psdi_uq_refined_name :: string,
|
|
psdi_q_refined_name :: string,
|
|
psdi_filename :: string,
|
|
psdi_linenumber :: int,
|
|
% Should we list the call_site_statics and coverage points
|
|
% themselves?
|
|
psdi_num_call_sites :: int,
|
|
psdi_num_coverage_points :: int
|
|
).
|
|
|
|
:- type proc_dynamic_dump_info
|
|
---> proc_dynamic_dump_info(
|
|
pddi_pdptr :: proc_dynamic_ptr,
|
|
pddi_psptr :: proc_static_ptr,
|
|
pddi_ps_raw_name :: string,
|
|
pddi_ps_module_name :: string,
|
|
pddi_ps_uq_refined_name :: string,
|
|
pddi_ps_q_refined_name :: string,
|
|
pddi_call_sites :: list(call_site_array_slot),
|
|
pddi_coverage_points :: maybe(list(coverage_point))
|
|
).
|
|
|
|
:- type call_site_static_dump_info
|
|
---> call_site_static_dump_info(
|
|
cssdi_cssptr :: call_site_static_ptr,
|
|
cssdi_containing_psptr :: proc_static_ptr,
|
|
cssdi_slot_number :: int,
|
|
cssdi_line_number :: int,
|
|
cssdi_goal_path :: reverse_goal_path,
|
|
cssdi_callee :: call_site_kind_and_callee
|
|
).
|
|
|
|
:- type call_site_dynamic_dump_info
|
|
---> call_site_dynamic_dump_info(
|
|
csddi_csdptr :: call_site_dynamic_ptr,
|
|
csddi_caller_pdptr :: proc_dynamic_ptr,
|
|
csddi_callee_pdptr :: proc_dynamic_ptr,
|
|
csddi_own_perf :: perf_row_data(call_site_desc)
|
|
).
|
|
|
|
:- type clique_dump_info
|
|
---> clique_dump_info(
|
|
cdi_clique_desc :: clique_desc,
|
|
cdi_caller_csd_ptr :: call_site_dynamic_ptr,
|
|
cdi_member_pdptrs :: list(proc_dynamic_ptr)
|
|
).
|
|
|
|
:- type call_site_dynamic_var_use_info
|
|
---> call_site_dynamic_var_use_info(
|
|
csdvui_total_cost :: float,
|
|
csdvui_var_uses :: list(var_use_and_name)
|
|
).
|
|
|
|
:- type var_use_and_name
|
|
---> var_use_and_name(
|
|
vun_var_name :: string,
|
|
vun_use :: var_use_info
|
|
).
|
|
|
|
% This type represents information about the performance of the subject.
|
|
% It is intended to be displayed on a browser page or used by a tool as is.
|
|
% It is NOT intended to be subject to further processing, such as adding
|
|
% two perf_row_datas together. Any such arithmetic is much better done
|
|
% on the data structures from which perf_row_datas are derived
|
|
% (own_prof_info and inherit_prof_info in the measurements module).
|
|
%
|
|
:- type perf_row_data(T)
|
|
---> perf_row_data(
|
|
% The item represented by this data row.
|
|
perf_row_subject :: T,
|
|
|
|
% Port counts.
|
|
perf_row_calls :: int,
|
|
perf_row_exits :: int,
|
|
perf_row_fails :: int,
|
|
perf_row_redos :: int,
|
|
perf_row_excps :: int,
|
|
|
|
perf_row_bytes_per_word :: int,
|
|
perf_row_self :: inheritable_perf,
|
|
perf_row_maybe_total :: maybe(inheritable_perf)
|
|
).
|
|
|
|
:- type inheritable_perf
|
|
---> inheritable_perf(
|
|
% Clock ticks and times. We always use simple integers to
|
|
% represent clock ticks, whereas for time, we use more
|
|
% user-friendly units. When the total time for the program
|
|
% is close to zero, i.e. the number of ticks or quanta is zero
|
|
% for the whole program, then the percentage may be zero
|
|
% for everything (it used to be a NaN for 0/0, but we now
|
|
% check explicitly for division by zero).
|
|
perf_row_ticks :: int,
|
|
perf_row_time :: time,
|
|
perf_row_time_percent :: percent,
|
|
perf_row_time_percall :: time,
|
|
|
|
% Call sequence counts.
|
|
perf_row_callseqs :: int,
|
|
perf_row_callseqs_percent :: percent,
|
|
perf_row_callseqs_percall :: float,
|
|
|
|
% Memory allocations.
|
|
perf_row_allocs :: int,
|
|
perf_row_allocs_percent :: percent,
|
|
perf_row_allocs_percall :: float,
|
|
|
|
% Memory used. We try to use the most appropriate units
|
|
% for representing each given amount of memory.
|
|
% XXX Memory per call might not be an integer, so we should
|
|
% make sure that the memory type can represent fractions.
|
|
perf_row_mem :: memory,
|
|
perf_row_mem_percent :: percent,
|
|
perf_row_mem_percall :: memory
|
|
).
|
|
|
|
% This type is used to define 'most expensive procedures'. It contains all
|
|
% the parameters that the query is given to select and order the procedures
|
|
% shown in the report. See also the function symbol deep_cmd_top_procs of
|
|
% the cmd type.
|
|
%
|
|
:- type report_ordering
|
|
---> report_ordering(
|
|
display_limit :: display_limit,
|
|
cost_kind :: cost_kind,
|
|
incl_desc :: include_descendants,
|
|
scope :: measurement_scope
|
|
).
|
|
|
|
% The representation of a module in a report structure.
|
|
%
|
|
:- type module_active
|
|
---> module_active(
|
|
ma_module_name :: string,
|
|
ma_is_active :: module_is_active
|
|
).
|
|
|
|
:- type module_is_active
|
|
---> module_is_active
|
|
; module_is_not_active.
|
|
|
|
:- type proc_active
|
|
---> proc_active(
|
|
pa_proc_desc :: proc_desc,
|
|
pa_is_active :: proc_is_active
|
|
).
|
|
|
|
:- type proc_is_active
|
|
---> proc_is_active
|
|
; proc_is_not_active.
|
|
|
|
% The representation of a procedure in a report structure, including
|
|
% information about its location in Mercury source code.
|
|
%
|
|
:- type proc_desc
|
|
---> proc_desc(
|
|
pdesc_ps_ptr :: proc_static_ptr,
|
|
pdesc_file_name :: string,
|
|
pdesc_line_number :: int,
|
|
pdesc_module_name :: string,
|
|
pdesc_uq_refined_name :: string,
|
|
pdesc_q_refined_name :: string
|
|
).
|
|
|
|
% The representation of a call site in a report structure, including
|
|
% information about its location in Mercury source code.
|
|
%
|
|
:- type call_site_desc
|
|
---> call_site_desc(
|
|
csdesc_css_ptr :: call_site_static_ptr,
|
|
csdesc_container :: proc_static_ptr,
|
|
csdesc_file_name :: string,
|
|
csdesc_line_number :: int,
|
|
csdesc_caller_module_name :: string,
|
|
csdesc_caller_uq_refined_name :: string,
|
|
csdesc_caller_q_refined_name :: string,
|
|
csdesc_slot_number :: int,
|
|
csdesc_goal_path :: reverse_goal_path,
|
|
csdesc_maybe_callee :: maybe(proc_desc)
|
|
).
|
|
|
|
:- type ancestor_desc
|
|
---> ancestor_desc(
|
|
% The caller and callee cliques.
|
|
ad_caller_clique_ptr :: clique_ptr,
|
|
ad_callee_clique_ptr :: clique_ptr,
|
|
|
|
% The callee procedure.
|
|
ad_callee_pdesc :: proc_desc,
|
|
|
|
% The description of the call site. This includes a description
|
|
% of the caller procedure.
|
|
ad_call_site_desc :: call_site_desc
|
|
).
|
|
|
|
% The description of a clique in a report structure.
|
|
%
|
|
:- type clique_desc
|
|
---> clique_desc(
|
|
cdesc_clique_ptr :: clique_ptr,
|
|
cdesc_entry_member :: proc_desc,
|
|
cdesc_other_members :: list(proc_desc)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Predicates to make common actions on these types easier.
|
|
%
|
|
|
|
:- pred proc_label_from_proc_desc(deep::in, proc_desc::in,
|
|
string_proc_label::out) is det.
|
|
|
|
% foldl(add_call_site_report_to_map(CallSiteReports, map.init,
|
|
% CallSitesMap).
|
|
%
|
|
% Build a map from goal paths to call site reports.
|
|
%
|
|
:- pred add_call_site_report_to_map(clique_call_site_report::in,
|
|
map(reverse_goal_path, clique_call_site_report)::in,
|
|
map(reverse_goal_path, clique_call_site_report)::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
proc_label_from_proc_desc(Deep, ProcDesc, ProcLabel) :-
|
|
PSPtr = ProcDesc ^ pdesc_ps_ptr,
|
|
deep_lookup_proc_statics(Deep, PSPtr, ProcStatic),
|
|
ProcLabel = ProcStatic ^ ps_id.
|
|
|
|
add_call_site_report_to_map(CallSite, !Map) :-
|
|
GoalPath = CallSite ^ ccsr_call_site_summary ^ perf_row_subject
|
|
^ csdesc_goal_path,
|
|
map.det_insert(GoalPath, CallSite, !Map).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module report.
|
|
%---------------------------------------------------------------------------%
|