Files
mercury/deep_profiler/profile.m
Zoltan Somogyi 3c07fc2121 Use explicit streams in deep_profiler/*.m.
deep_profiler/analysis_utils.m:
deep_profiler/autopar_find_best_par.m:
deep_profiler/autopar_reports.m:
deep_profiler/autopar_search_callgraph.m:
deep_profiler/autopar_search_goals.m:
deep_profiler/callgraph.m:
deep_profiler/canonical.m:
deep_profiler/cliques.m:
deep_profiler/coverage.m:
deep_profiler/dump.m:
deep_profiler/mdprof_cgi.m:
deep_profiler/mdprof_create_feedback.m:
deep_profiler/mdprof_dump.m:
deep_profiler/mdprof_procrep.m:
deep_profiler/mdprof_report_feedback.m:
deep_profiler/mdprof_test.m:
deep_profiler/profile.m:
deep_profiler/read_profile.m:
deep_profiler/recursion_patterns.m:
deep_profiler/startup.m:
deep_profiler/var_use_analysis.m:
    Replace implicit streams with explicit streams.

    In some places, simplify some code, often using constructs such as
    string.format that either did not exist or were too expensive to use
    when the original code was written.

    Consistenly use the spelling StdErr over Stderr.

    In mdbprof_dump.m, put filename and reason-for-failing-to-open-that-file
    in the right order in an error message.

deep_profiler/DEEP_FLAGS.in:
    Turn on --warn-implicit-stream-calls for the entire deep_profiler
    directory.

mdbcomp/program_representation.m:
mdbcomp/trace_counts.m:
    Replace implicit streams with explicit streams. These are the two mdbcomp
    modules that (a) used to use implicit streams, and (2) are used by the
    deep profiler.

mdbcomp/Mercury.options:
    Turn on --warn-implicit-stream-calls for these two modules.

slice/mcov.m:
slice/mtc_union.m:
    Conform to the changes in mdbcomp.
2021-03-06 18:30:50 +11:00

1092 lines
40 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2001, 2004-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.
%---------------------------------------------------------------------------%
%
% Authors: conway, zs.
%
% This file defines the main data structures of the Mercury deep profiler,
% and predicates for accessing them. The main concern of the access predicates
% is ensuring the safety of array accesses.
%
% For historical reasons, all the top-level arrays (i.e. those directly
% contained in initial_deep and deep structures) have a dummy element
% at index 0; their first real element is at index 1. The arrays in
% proc_static and proc_dynamic structures, being reflections of arrays created
% in C code, start at index 0.
%
%---------------------------------------------------------------------------%
:- module profile.
:- interface.
:- import_module exclude.
:- import_module measurements.
:- import_module mdbcomp.
:- import_module mdbcomp.goal_path.
:- import_module mdbcomp.program_representation.
:- import_module array.
:- import_module bool.
:- import_module io.
:- import_module list.
:- import_module map.
:- import_module maybe.
%---------------------------------------------------------------------------%
:- type deep_compression_flag
---> no_compression.
:- type canonical_flag
---> is_canonical
; maybe_not_canonical.
:- type deep_flags
---> deep_flags(
df_bytes_per_int :: int,
df_canonical_flag :: canonical_flag,
df_compression_flag :: deep_compression_flag,
df_coverage_data_type :: coverage_data_type
).
:- type profile_stats
---> profile_stats(
prs_program_name :: string,
prs_num_csd :: int,
prs_num_css :: int,
prs_num_pd :: int,
prs_num_ps :: int,
prs_ticks_per_sec :: int,
prs_instrument_quanta :: int,
prs_user_quanta :: int,
prs_num_callseqs :: int,
prs_deep_flags :: deep_flags
).
:- type initial_deep
---> initial_deep(
init_profile_stats :: profile_stats,
init_root :: proc_dynamic_ptr,
% The following fields are the main arrays.
% Each is indexed by its own xxx_ptr int.
init_call_site_dynamics :: call_site_dynamics,
init_proc_dynamics :: proc_dynamics,
init_call_site_statics :: call_site_statics,
init_proc_statics :: proc_statics
).
:- type deep
---> deep(
profile_stats :: profile_stats,
server_name_port :: string,
script_name :: string,
data_file_name :: string,
root :: proc_dynamic_ptr,
% The following fields are the main arrays.
% Each is indexed by its own xxx_ptr int.
call_site_dynamics :: call_site_dynamics,
proc_dynamics :: proc_dynamics,
call_site_statics :: call_site_statics,
proc_statics :: proc_statics,
% The following fields give information about cliques.
clique_index :: array(clique_ptr),
% index: proc_dynamic_ptr int
clique_members :: array(list(proc_dynamic_ptr)),
% index: clique_ptr int
clique_parents :: array(call_site_dynamic_ptr),
% index: clique_ptr int
clique_maybe_child :: array(maybe(clique_ptr)),
% index: call_site_dynamic_ptr int
% Reverse links.
proc_callers :: array(list(call_site_dynamic_ptr)),
% index: proc_static_ptr int
call_site_static_map :: call_site_static_map,
% index: call_site_dynamic_ptr int
call_site_calls :: array(map(proc_static_ptr,
list(call_site_dynamic_ptr))),
% index: call_site_static_ptr int
% Propagated measurements.
pd_own :: array(own_prof_info),
pd_desc :: array(inherit_prof_info),
csd_desc :: array(inherit_prof_info),
ps_own :: array(own_prof_info),
ps_desc :: array(inherit_prof_info),
css_own :: array(own_prof_info),
css_desc :: array(inherit_prof_info),
% Additional propagated timing info to solve the problem
% of undetected recursion through higher order calls,
% which is caused by our use of zeroing.
pd_comp_table :: array(compensation_table),
csd_comp_table :: array(compensation_table),
% Information about modules.
module_data :: map(string, module_data),
% Static coverage information.
maybe_static_coverage :: maybe(array(static_coverage_info)),
% If this field is `no', then there is no (readable) contour
% exclusion file. If this field is yes(MaybeExcludeFile),
% then there are again two possibilities. The normal case is
% MaybeExcludeFile = ok(ExcludeFile). The other case is
% MaybeExcludeFile = error(ErrorMsg), which shows that the
% contour exclusion file was malformed.
exclude_contour_file :: exclude_file,
% If this field is `no', then there is no (readable) proc
% representation file. If this field is yes(MaybeProcRepFile),
% then there are again two possibilities. The normal case is
% MaybeProcRepFile = ok(ProcRepFile). The other case is
% MaybeProcRepFile = error(ErrorMsg), which shows that the
% proc representation file was malformed.
procrep_file :: maybe(maybe_error(prog_rep)),
% Contains a stream for progress messages, if desired.
progress_stream :: maybe(io.text_output_stream)
).
:- type compensation_table == map(proc_static_ptr, inherit_prof_info).
:- type module_data
---> module_data(
% The total cost of the module.
module_own :: own_prof_info,
module_desc :: inherit_prof_info,
% The procedures defined in the module.
module_procs :: list(proc_static_ptr)
).
%---------------------------------------------------------------------------%
:- type proc_dynamics == array(proc_dynamic).
:- type proc_statics == array(proc_static).
:- type call_site_dynamics == array(call_site_dynamic).
:- type call_site_statics == array(call_site_static).
:- type call_site_static_map == array(call_site_static_ptr).
:- type proc_dynamic_ptr
---> proc_dynamic_ptr(int).
:- type proc_static_ptr
---> proc_static_ptr(int).
:- type call_site_dynamic_ptr
---> call_site_dynamic_ptr(int).
:- type call_site_static_ptr
---> call_site_static_ptr(int).
:- type clique_ptr
---> clique_ptr(int).
%---------------------------------------------------------------------------%
:- type proc_dynamic
---> proc_dynamic(
pd_proc_static :: proc_static_ptr,
pd_sites :: array(call_site_array_slot),
% An array of coverage points. If present then coverage points
% for this procedure are dynamic and the corresponding static
% info can be found in the proc_static. If no, then coverage
% points aren't available or are stored in the proc static.
pd_maybe_coverage_points :: maybe(array(int))
).
:- type proc_static
---> proc_static(
% procedure ID
ps_id :: string_proc_label,
% declaring module
ps_decl_module :: string,
% unqualified refined id
ps_uq_refined_id :: string,
% qualified refined id
ps_q_refined_id :: string,
% raw procedure id
ps_raw_id :: string,
% file name of proc
ps_file_name :: string,
% line number of proc
ps_line_number :: int,
% is in interface?
ps_in_interface :: bool,
ps_sites :: array(call_site_static_ptr),
ps_coverage_point_infos :: array(coverage_point_info),
ps_maybe_coverage_points :: maybe(array(int)),
ps_is_zeroed :: is_zeroed
).
:- type call_site_dynamic
---> call_site_dynamic(
csd_caller :: proc_dynamic_ptr,
csd_callee :: proc_dynamic_ptr,
csd_own_prof :: own_prof_info
).
:- type call_site_static
---> call_site_static(
css_container :: proc_static_ptr,
% The containing procedure.
css_slot_num :: int,
% Slot number in the containing procedure.
css_kind :: call_site_kind_and_callee,
css_line_num :: int,
css_goal_path :: reverse_goal_path
).
%---------------------------------------------------------------------------%
:- type call_site_array_slot
---> slot_normal(call_site_dynamic_ptr)
; slot_multi(is_zeroed, array(call_site_dynamic_ptr)).
:- type is_zeroed
---> zeroed
; not_zeroed.
:- type call_site_kind
---> normal_call
; special_call
; higher_order_call
; method_call
; callback.
:- type call_site_kind_and_callee
== call_site_kind_and_callee(proc_static_ptr).
:- type call_site_kind_and_callee(T)
---> normal_call_and_callee(
% The identity of the callee.
T,
% A description of the type substitution, if any and if known.
string
)
; special_call_and_no_callee
; higher_order_call_and_no_callee
; method_call_and_no_callee
; callback_and_no_callee.
:- type call_site_kind_and_info(T)
---> normal_call_and_info(T)
; special_call_and_no_info
; higher_order_call_and_no_info
; method_call_and_no_info
; callback_and_no_info.
:- type call_site_callees
---> call_site_callees(
list(proc_dynamic_ptr)
).
:- type call_site_caller
---> call_site_caller(
call_site_static_ptr
).
% The type of coverage data available in a profile.
%
:- type coverage_data_type
---> no_coverage_data
; static_coverage_data
; dynamic_coverage_data.
:- pred is_call_site_kind(int::in, call_site_kind::out) is semidet.
%---------------------------------------------------------------------------%
:- func decl_module(string_proc_label) = string.
:- func dummy_proc_id = string_proc_label.
:- func main_parent_proc_id = string_proc_label.
:- func dummy_clique_ptr = clique_ptr.
:- func dummy_proc_static_ptr = proc_static_ptr.
:- func dummy_proc_dynamic_ptr = proc_dynamic_ptr.
:- func dummy_call_site_static_ptr = call_site_static_ptr.
:- func dummy_call_site_dynamic_ptr = call_site_dynamic_ptr.
:- pred valid_clique_ptr(deep::in, clique_ptr::in) is semidet.
:- pred valid_proc_dynamic_ptr(deep::in, proc_dynamic_ptr::in) is semidet.
:- pred valid_proc_static_ptr(deep::in, proc_static_ptr::in) is semidet.
:- pred valid_call_site_dynamic_ptr(deep::in, call_site_dynamic_ptr::in)
is semidet.
:- pred valid_call_site_static_ptr(deep::in, call_site_static_ptr::in)
is semidet.
:- pred valid_proc_dynamic_ptr_raw(proc_dynamics::in, proc_dynamic_ptr::in)
is semidet.
:- pred valid_proc_static_ptr_raw(proc_statics::in, proc_static_ptr::in)
is semidet.
:- pred valid_call_site_dynamic_ptr_raw(call_site_dynamics::in,
call_site_dynamic_ptr::in) is semidet.
:- pred valid_call_site_static_ptr_raw(call_site_statics::in,
call_site_static_ptr::in) is semidet.
:- pred lookup_call_site_dynamics(call_site_dynamics::in,
call_site_dynamic_ptr::in, call_site_dynamic::out) is det.
:- pred lookup_call_site_statics(call_site_statics::in,
call_site_static_ptr::in, call_site_static::out) is det.
:- pred lookup_proc_dynamics(proc_dynamics::in,
proc_dynamic_ptr::in, proc_dynamic::out) is det.
:- pred lookup_proc_statics(proc_statics::in,
proc_static_ptr::in, proc_static::out) is det.
:- pred lookup_clique_index(array(clique_ptr)::in,
proc_dynamic_ptr::in, clique_ptr::out) is det.
:- pred lookup_clique_members(array(list(proc_dynamic_ptr))::in,
clique_ptr::in, list(proc_dynamic_ptr)::out) is det.
:- pred lookup_clique_parents(array(call_site_dynamic_ptr)::in,
clique_ptr::in, call_site_dynamic_ptr::out) is det.
:- pred lookup_clique_maybe_child(array(maybe(clique_ptr))::in,
call_site_dynamic_ptr::in, maybe(clique_ptr)::out) is det.
:- pred lookup_proc_callers(array(list(call_site_dynamic_ptr))::in,
proc_static_ptr::in, list(call_site_dynamic_ptr)::out) is det.
:- pred lookup_call_site_static_map(call_site_static_map::in,
call_site_dynamic_ptr::in, call_site_static_ptr::out) is det.
:- pred lookup_call_site_calls(array(map(proc_static_ptr,
list(call_site_dynamic_ptr)))::in, call_site_static_ptr::in,
map(proc_static_ptr, list(call_site_dynamic_ptr))::out) is det.
:- pred lookup_pd_own(array(own_prof_info)::in,
proc_dynamic_ptr::in, own_prof_info::out) is det.
:- pred lookup_pd_desc(array(inherit_prof_info)::in,
proc_dynamic_ptr::in, inherit_prof_info::out) is det.
:- pred lookup_csd_own(array(own_prof_info)::in,
call_site_dynamic_ptr::in, own_prof_info::out) is det.
:- pred lookup_csd_desc(array(inherit_prof_info)::in,
call_site_dynamic_ptr::in, inherit_prof_info::out) is det.
:- pred lookup_ps_own(array(own_prof_info)::in,
proc_static_ptr::in, own_prof_info::out) is det.
:- pred lookup_ps_desc(array(inherit_prof_info)::in,
proc_static_ptr::in, inherit_prof_info::out) is det.
:- pred lookup_css_own(array(own_prof_info)::in,
call_site_static_ptr::in, own_prof_info::out) is det.
:- pred lookup_css_desc(array(inherit_prof_info)::in,
call_site_static_ptr::in, inherit_prof_info::out) is det.
:- pred lookup_pd_comp_table(array(compensation_table)::in,
proc_dynamic_ptr::in, compensation_table::out) is det.
:- pred lookup_csd_comp_table(array(compensation_table)::in,
call_site_dynamic_ptr::in, compensation_table::out) is det.
:- pred lookup_ps_coverage(array(static_coverage_info)::in,
proc_static_ptr::in, static_coverage_info::out) is det.
:- pred deep_lookup_call_site_dynamics(deep::in, call_site_dynamic_ptr::in,
call_site_dynamic::out) is det.
:- pred deep_lookup_call_site_statics(deep::in, call_site_static_ptr::in,
call_site_static::out) is det.
:- pred deep_lookup_proc_dynamics(deep::in, proc_dynamic_ptr::in,
proc_dynamic::out) is det.
:- pred deep_lookup_proc_statics(deep::in, proc_static_ptr::in,
proc_static::out) is det.
:- pred deep_lookup_clique_index(deep::in, proc_dynamic_ptr::in,
clique_ptr::out) is det.
:- pred deep_lookup_clique_members(deep::in, clique_ptr::in,
list(proc_dynamic_ptr)::out) is det.
:- pred deep_lookup_clique_parents(deep::in, clique_ptr::in,
call_site_dynamic_ptr::out) is det.
:- pred deep_lookup_clique_maybe_child(deep::in, call_site_dynamic_ptr::in,
maybe(clique_ptr)::out) is det.
:- pred deep_lookup_proc_callers(deep::in, proc_static_ptr::in,
list(call_site_dynamic_ptr)::out) is det.
:- pred deep_lookup_call_site_static_map(deep::in, call_site_dynamic_ptr::in,
call_site_static_ptr::out) is det.
:- pred deep_lookup_call_site_calls(deep::in, call_site_static_ptr::in,
map(proc_static_ptr, list(call_site_dynamic_ptr))::out) is det.
:- pred deep_lookup_proc_dynamic_sites(deep::in, proc_dynamic_ptr::in,
array(call_site_array_slot)::out) is det.
:- pred deep_lookup_pd_comp_table(deep::in, proc_dynamic_ptr::in,
compensation_table::out) is det.
:- pred deep_lookup_csd_comp_table(deep::in, call_site_dynamic_ptr::in,
compensation_table::out) is det.
:- pred deep_lookup_pd_own(deep::in, proc_dynamic_ptr::in,
own_prof_info::out) is det.
:- pred deep_lookup_pd_desc(deep::in, proc_dynamic_ptr::in,
inherit_prof_info::out) is det.
:- pred deep_lookup_csd_own(deep::in, call_site_dynamic_ptr::in,
own_prof_info::out) is det.
:- pred deep_lookup_csd_desc(deep::in, call_site_dynamic_ptr::in,
inherit_prof_info::out) is det.
:- pred deep_lookup_ps_own(deep::in, proc_static_ptr::in,
own_prof_info::out) is det.
:- pred deep_lookup_ps_desc(deep::in, proc_static_ptr::in,
inherit_prof_info::out) is det.
:- pred deep_lookup_css_own(deep::in, call_site_static_ptr::in,
own_prof_info::out) is det.
:- pred deep_lookup_css_desc(deep::in, call_site_static_ptr::in,
inherit_prof_info::out) is det.
:- pred deep_lookup_ps_coverage(deep::in, proc_static_ptr::in,
static_coverage_info::out) is det.
:- pred update_call_site_dynamics(call_site_dynamic_ptr::in,
call_site_dynamic::in,
call_site_dynamics::array_di, call_site_dynamics::array_uo) is det.
:- pred update_call_site_statics(call_site_static_ptr::in,
call_site_static::in,
call_site_statics::array_di, call_site_statics::array_uo) is det.
:- pred update_proc_dynamics(proc_dynamic_ptr::in, proc_dynamic::in,
proc_dynamics::array_di, proc_dynamics::array_uo) is det.
:- pred update_proc_statics(proc_static_ptr::in, proc_static::in,
proc_statics::array_di, proc_statics::array_uo) is det.
:- pred update_call_site_static_map(call_site_dynamic_ptr::in,
call_site_static_ptr::in,
call_site_static_map::array_di, call_site_static_map::array_uo) is det.
:- pred update_proc_callers(proc_static_ptr::in,
list(call_site_dynamic_ptr)::in,
array(list(call_site_dynamic_ptr))::array_di,
array(list(call_site_dynamic_ptr))::array_uo) is det.
:- pred update_ps_own(proc_static_ptr::in, own_prof_info::in,
array(own_prof_info)::array_di, array(own_prof_info)::array_uo) is det.
:- pred update_ps_desc(proc_static_ptr::in, inherit_prof_info::in,
array(inherit_prof_info)::array_di, array(inherit_prof_info)::array_uo)
is det.
:- pred update_css_own(call_site_static_ptr::in, own_prof_info::in,
array(own_prof_info)::array_di, array(own_prof_info)::array_uo) is det.
:- pred update_css_desc(call_site_static_ptr::in, inherit_prof_info::in,
array(inherit_prof_info)::array_di, array(inherit_prof_info)::array_uo)
is det.
:- pred update_ps_coverage(proc_static_ptr::in, static_coverage_info::in,
array(static_coverage_info)::array_di,
array(static_coverage_info)::array_uo) is det.
:- pred deep_update_csd_desc(call_site_dynamic_ptr::in, inherit_prof_info::in,
deep::in, deep::out) is det.
:- pred deep_update_pd_desc(proc_dynamic_ptr::in, inherit_prof_info::in,
deep::in, deep::out) is det.
:- pred deep_update_pd_own(proc_dynamic_ptr::in, own_prof_info::in,
deep::in, deep::out) is det.
:- pred deep_update_pd_comp_table(proc_dynamic_ptr::in, compensation_table::in,
deep::in, deep::out) is det.
:- pred deep_update_csd_comp_table(call_site_dynamic_ptr::in,
compensation_table::in, deep::in, deep::out) is det.
:- pred extract_pd_sites(proc_dynamic::in, array(call_site_array_slot)::out)
is det.
:- pred extract_csd_caller(call_site_dynamic::in, proc_dynamic_ptr::out)
is det.
:- pred extract_csd_callee(call_site_dynamic::in, proc_dynamic_ptr::out)
is det.
:- pred extract_csdptr_caller(initial_deep::in, call_site_dynamic_ptr::in,
proc_dynamic_ptr::out) is det.
:- pred extract_csdptr_callee(initial_deep::in, call_site_dynamic_ptr::in,
proc_dynamic_ptr::out) is det.
:- pred extract_ticks_per_sec(initial_deep::in, int::out) is det.
:- pred extract_instrument_quanta(initial_deep::in, int::out) is det.
:- pred extract_user_quanta(initial_deep::in, int::out) is det.
:- pred extract_num_callseqs(initial_deep::in, int::out) is det.
:- pred extract_max_css(initial_deep::in, int::out) is det.
:- pred extract_max_ps(initial_deep::in, int::out) is det.
:- pred extract_max_csd(initial_deep::in, int::out) is det.
:- pred extract_max_pd(initial_deep::in, int::out) is det.
:- pred extract_init_call_site_dynamics(initial_deep::in,
call_site_dynamics::out) is det.
:- pred extract_init_call_site_statics(initial_deep::in,
call_site_statics::out) is det.
:- pred extract_init_proc_dynamics(initial_deep::in,
proc_dynamics::out) is det.
:- pred extract_init_proc_statics(initial_deep::in,
proc_statics::out) is det.
:- pred extract_init_root(initial_deep::in,
proc_dynamic_ptr::out) is det.
:- pred deep_extract_csdptr_caller(deep::in, call_site_dynamic_ptr::in,
proc_dynamic_ptr::out) is det.
:- pred deep_extract_csdptr_callee(deep::in, call_site_dynamic_ptr::in,
proc_dynamic_ptr::out) is det.
:- func wrap_proc_static_ptr(int) = proc_static_ptr.
:- func root_total_info(deep) = inherit_prof_info.
:- func root_desc_info(deep) = inherit_prof_info.
:- func root_own_info(deep) = own_prof_info.
%---------------------------------------------------------------------------%
% Lookup the program representation data.
%
:- pred deep_get_progrep_det(deep::in, prog_rep::out) is det.
:- pred deep_get_maybe_progrep(deep::in, maybe_error(prog_rep)::out) is det.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module mdbcomp.prim_data.
:- import_module array_util.
:- import_module int.
:- import_module require.
:- import_module string.
%---------------------------------------------------------------------------%
:- pragma foreign_decl("C", "#include ""mercury_deep_profiling.h""").
:- pragma foreign_enum("C", call_site_kind/0, [
normal_call - "MR_callsite_normal_call",
special_call - "MR_callsite_special_call",
higher_order_call - "MR_callsite_higher_order_call",
method_call - "MR_callsite_method_call",
callback - "MR_callsite_callback"
]).
:- pragma foreign_proc("C",
is_call_site_kind(Int::in, CallSite::out),
[promise_pure, will_not_call_mercury, thread_safe],
"
CallSite = (MR_CallSiteKind) Int;
switch (CallSite) {
case MR_callsite_normal_call:
case MR_callsite_special_call:
case MR_callsite_higher_order_call:
case MR_callsite_method_call:
case MR_callsite_callback:
SUCCESS_INDICATOR = MR_TRUE;
break;
default:
SUCCESS_INDICATOR = MR_FALSE;
break;
}
").
%---------------------------------------------------------------------------%
decl_module(ProcId) = DeclModule :-
(
ProcId = str_ordinary_proc_label(_, DeclModule, _, _, _, _)
;
ProcId = str_special_proc_label(_, DeclModule, _, _, _, _)
).
dummy_proc_id = str_ordinary_proc_label(pf_predicate, "unknown",
"unknown", "unknown", -1, -1).
main_parent_proc_id = str_ordinary_proc_label(pf_predicate, "mercury_runtime",
"mercury_runtime", "main_parent", 0, 0).
%---------------------------------------------------------------------------%
dummy_clique_ptr = clique_ptr(-1).
dummy_proc_static_ptr = proc_static_ptr(-1).
dummy_proc_dynamic_ptr = proc_dynamic_ptr(-1).
dummy_call_site_static_ptr = call_site_static_ptr(-1).
dummy_call_site_dynamic_ptr = call_site_dynamic_ptr(-1).
%---------------------------------------------------------------------------%
valid_clique_ptr(Deep, clique_ptr(CliqueNum)) :-
CliqueNum > 0,
array.in_bounds(Deep ^ clique_members, CliqueNum).
valid_proc_dynamic_ptr(Deep, proc_dynamic_ptr(PDI)) :-
PDI > 0,
array.in_bounds(Deep ^ proc_dynamics, PDI).
valid_proc_static_ptr(Deep, proc_static_ptr(PSI)) :-
PSI > 0,
array.in_bounds(Deep ^ proc_statics, PSI).
valid_call_site_dynamic_ptr(Deep, call_site_dynamic_ptr(CSDI)) :-
CSDI > 0,
array.in_bounds(Deep ^ call_site_dynamics, CSDI).
valid_call_site_static_ptr(Deep, call_site_static_ptr(CSSI)) :-
CSSI > 0,
array.in_bounds(Deep ^ call_site_statics, CSSI).
%---------------------------------------------------------------------------%
valid_proc_dynamic_ptr_raw(ProcDynamics, proc_dynamic_ptr(PDI)) :-
PDI > 0,
array.in_bounds(ProcDynamics, PDI).
valid_proc_static_ptr_raw(ProcStatics, proc_static_ptr(PSI)) :-
PSI > 0,
array.in_bounds(ProcStatics, PSI).
valid_call_site_dynamic_ptr_raw(CallSiteDynamics,
call_site_dynamic_ptr(CSDI)) :-
CSDI > 0,
array.in_bounds(CallSiteDynamics, CSDI).
valid_call_site_static_ptr_raw(CallSiteStatics, call_site_static_ptr(CSSI)) :-
CSSI > 0,
array.in_bounds(CallSiteStatics, CSSI).
%---------------------------------------------------------------------------%
lookup_call_site_dynamics(CallSiteDynamics, CSDPtr, CSD) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
( if CSDI > 0, array.in_bounds(CallSiteDynamics, CSDI) then
array.lookup(CallSiteDynamics, CSDI, CSD)
else
unexpected($pred, "bounds error")
).
lookup_call_site_statics(CallSiteStatics, CSSPtr, CSS) :-
CSSPtr = call_site_static_ptr(CSSI),
( if CSSI > 0, array.in_bounds(CallSiteStatics, CSSI) then
array.lookup(CallSiteStatics, CSSI, CSS)
else
unexpected($pred, "bounds error")
).
lookup_proc_dynamics(ProcDynamics, PDPtr, PD) :-
PDPtr = proc_dynamic_ptr(PDI),
( if PDI > 0, array.in_bounds(ProcDynamics, PDI) then
array.lookup(ProcDynamics, PDI, PD)
else
unexpected($pred, "bounds error")
).
lookup_proc_statics(ProcStatics, PSPtr, PS) :-
PSPtr = proc_static_ptr(PSI),
( if PSI > 0, array.in_bounds(ProcStatics, PSI) then
array.lookup(ProcStatics, PSI, PS)
else
unexpected($pred, "bounds error")
).
lookup_clique_index(CliqueIndex, PDPtr, CliquePtr) :-
PDPtr = proc_dynamic_ptr(PDI),
( if PDI > 0, array.in_bounds(CliqueIndex, PDI) then
array.lookup(CliqueIndex, PDI, CliquePtr)
else
unexpected($pred, "bounds error")
).
lookup_clique_members(CliqueMembers, CliquePtr, PDPtrs) :-
CliquePtr = clique_ptr(CI),
( if array.in_bounds(CliqueMembers, CI) then
array.lookup(CliqueMembers, CI, PDPtrs)
else
unexpected($pred, "bounds error")
).
lookup_clique_parents(CliqueParents, CliquePtr, CSDPtr) :-
CliquePtr = clique_ptr(CI),
( if array.in_bounds(CliqueParents, CI) then
array.lookup(CliqueParents, CI, CSDPtr)
else
unexpected($pred, "bounds error")
).
lookup_clique_maybe_child(CliqueMaybeChild, CSDPtr, MaybeCliquePtr) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
( if CSDI > 0, array.in_bounds(CliqueMaybeChild, CSDI) then
array.lookup(CliqueMaybeChild, CSDI, MaybeCliquePtr)
else
unexpected($pred, "bounds error")
).
lookup_proc_callers(ProcCallers, PSPtr, Callers) :-
PSPtr = proc_static_ptr(PSI),
( if PSI > 0, array.in_bounds(ProcCallers, PSI) then
array.lookup(ProcCallers, PSI, Callers)
else
unexpected($pred, "bounds error")
).
lookup_call_site_static_map(CallSiteStaticMap, CSDPtr, CSSPtr) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
( if CSDI > 0, array.in_bounds(CallSiteStaticMap, CSDI) then
array.lookup(CallSiteStaticMap, CSDI, CSSPtr)
else
unexpected($pred, "bounds error")
).
lookup_call_site_calls(CallSiteCalls, CSSPtr, Calls) :-
CSSPtr = call_site_static_ptr(CSSI),
( if CSSI > 0, array.in_bounds(CallSiteCalls, CSSI) then
array.lookup(CallSiteCalls, CSSI, Calls)
else
unexpected($pred, "bounds error")
).
lookup_pd_own(PDOwns, PDPtr, PDOwn) :-
PDPtr = proc_dynamic_ptr(PDI),
( if PDI > 0, array.in_bounds(PDOwns, PDI) then
array.lookup(PDOwns, PDI, PDOwn)
else
unexpected($pred, "bounds error")
).
lookup_pd_desc(PDDescs, PDPtr, PDDesc) :-
PDPtr = proc_dynamic_ptr(PDI),
( if PDI > 0, array.in_bounds(PDDescs, PDI) then
array.lookup(PDDescs, PDI, PDDesc)
else
unexpected($pred, "bounds error")
).
lookup_csd_own(CSDOwns, CSDPtr, CSDOwn) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
( if CSDI > 0, array.in_bounds(CSDOwns, CSDI) then
array.lookup(CSDOwns, CSDI, CSDOwn)
else
unexpected($pred, "bounds error")
).
lookup_csd_desc(CSDDescs, CSDPtr, CSDDesc) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
( if CSDI > 0, array.in_bounds(CSDDescs, CSDI) then
array.lookup(CSDDescs, CSDI, CSDDesc)
else
unexpected($pred, "bounds error")
).
lookup_ps_own(PSOwns, PSPtr, PSOwn) :-
PSPtr = proc_static_ptr(PSI),
( if PSI > 0, array.in_bounds(PSOwns, PSI) then
array.lookup(PSOwns, PSI, PSOwn)
else
unexpected($pred, "bounds error")
).
lookup_ps_desc(PSDescs, PSPtr, PSDesc) :-
PSPtr = proc_static_ptr(PSI),
( if PSI > 0, array.in_bounds(PSDescs, PSI) then
array.lookup(PSDescs, PSI, PSDesc)
else
unexpected($pred, "bounds error")
).
lookup_css_own(CSSOwns, CSSPtr, CSSOwn) :-
CSSPtr = call_site_static_ptr(CSSI),
( if CSSI > 0, array.in_bounds(CSSOwns, CSSI) then
array.lookup(CSSOwns, CSSI, CSSOwn)
else
unexpected($pred, "bounds error")
).
lookup_css_desc(CSSDescs, CSSPtr, CSSDesc) :-
CSSPtr = call_site_static_ptr(CSSI),
( if CSSI > 0, array.in_bounds(CSSDescs, CSSI) then
array.lookup(CSSDescs, CSSI, CSSDesc)
else
unexpected($pred, "bounds error")
).
lookup_pd_comp_table(PDCompTables, PDPtr, CompTable) :-
PDPtr = proc_dynamic_ptr(PDI),
( if PDI > 0, array.in_bounds(PDCompTables, PDI) then
array.lookup(PDCompTables, PDI, CompTable)
else
unexpected($pred, "bounds error")
).
lookup_csd_comp_table(CSDCompTables, CSDPtr, CompTable) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
( if CSDI > 0, array.in_bounds(CSDCompTables, CSDI) then
array.lookup(CSDCompTables, CSDI, CompTable)
else
unexpected($pred, "bounds error")
).
lookup_ps_coverage(PSCoverageArrays, PSPtr, PSCoverageArray) :-
PSPtr = proc_static_ptr(PSI),
( if PSI > 0, array.in_bounds(PSCoverageArrays, PSI) then
array.lookup(PSCoverageArrays, PSI, PSCoverageArray)
else
unexpected($pred, "bounds error")
).
%---------------------------------------------------------------------------%
deep_lookup_call_site_dynamics(Deep, CSDPtr, CSD) :-
lookup_call_site_dynamics(Deep ^ call_site_dynamics, CSDPtr, CSD).
deep_lookup_call_site_statics(Deep, CSSPtr, CSS) :-
lookup_call_site_statics(Deep ^ call_site_statics, CSSPtr, CSS).
deep_lookup_proc_dynamics(Deep, PDPtr, PD) :-
lookup_proc_dynamics(Deep ^ proc_dynamics, PDPtr, PD).
deep_lookup_proc_statics(Deep, PSPtr, PS) :-
lookup_proc_statics(Deep ^ proc_statics, PSPtr, PS).
deep_lookup_clique_index(Deep, PDPtr, CliquePtr) :-
lookup_clique_index(Deep ^ clique_index, PDPtr, CliquePtr).
deep_lookup_clique_members(Deep, CliquePtr, PDPtrs) :-
lookup_clique_members(Deep ^ clique_members, CliquePtr, PDPtrs).
deep_lookup_clique_parents(Deep, CliquePtr, CSDPtr) :-
lookup_clique_parents(Deep ^ clique_parents, CliquePtr, CSDPtr).
deep_lookup_clique_maybe_child(Deep, CSDPtr, MaybeCliquePtr) :-
lookup_clique_maybe_child(Deep ^ clique_maybe_child, CSDPtr,
MaybeCliquePtr).
deep_lookup_proc_callers(Deep, PSPtr, CallerCSDPtrs) :-
lookup_proc_callers(Deep ^ proc_callers, PSPtr, CallerCSDPtrs).
deep_lookup_call_site_static_map(Deep, CSDPtr, CSSPtr) :-
lookup_call_site_static_map(Deep ^ call_site_static_map, CSDPtr,
CSSPtr).
deep_lookup_call_site_calls(Deep, CSSPtr, Calls) :-
lookup_call_site_calls(Deep ^ call_site_calls, CSSPtr, Calls).
deep_lookup_proc_dynamic_sites(Deep, PDPtr, PDSites) :-
deep_lookup_proc_dynamics(Deep, PDPtr, PD),
PDSites = PD ^ pd_sites.
deep_lookup_pd_comp_table(Deep, PDPtr, CompTable) :-
lookup_pd_comp_table(Deep ^ pd_comp_table, PDPtr, CompTable).
deep_lookup_csd_comp_table(Deep, CSDPtr, CompTable) :-
lookup_csd_comp_table(Deep ^ csd_comp_table, CSDPtr, CompTable).
%---------------------------------------------------------------------------%
deep_lookup_pd_own(Deep, PDPtr, Own) :-
PDPtr = proc_dynamic_ptr(PDI),
array.lookup(Deep ^ pd_own, PDI, Own).
deep_lookup_pd_desc(Deep, PDPtr, Desc) :-
PDPtr = proc_dynamic_ptr(PDI),
array.lookup(Deep ^ pd_desc, PDI, Desc).
deep_lookup_csd_own(Deep, CSDPtr, Own) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
array.lookup(Deep ^ call_site_dynamics, CSDI, CSD),
Own = CSD ^ csd_own_prof.
deep_lookup_csd_desc(Deep, CSDPtr, Desc) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
array.lookup(Deep ^ csd_desc, CSDI, Desc).
deep_lookup_ps_own(Deep, PSPtr, Own) :-
PSPtr = proc_static_ptr(PSI),
array.lookup(Deep ^ ps_own, PSI, Own).
deep_lookup_ps_desc(Deep, PSPtr, Desc) :-
PSPtr = proc_static_ptr(PSI),
array.lookup(Deep ^ ps_desc, PSI, Desc).
deep_lookup_css_own(Deep, CSSPtr, Own) :-
CSSPtr = call_site_static_ptr(CSSI),
array.lookup(Deep ^ css_own, CSSI, Own).
deep_lookup_css_desc(Deep, CSSPtr, Desc) :-
CSSPtr = call_site_static_ptr(CSSI),
array.lookup(Deep ^ css_desc, CSSI, Desc).
deep_lookup_ps_coverage(Deep, PSPtr, Coverage) :-
MaybeCoverageTables = Deep ^ maybe_static_coverage,
(
MaybeCoverageTables = yes(CoverageTables),
lookup_ps_coverage(CoverageTables, PSPtr, Coverage)
;
MaybeCoverageTables = no,
Coverage = zero_static_coverage
).
%---------------------------------------------------------------------------%
update_call_site_dynamics(CSDPtr, CSD, !CallSiteDynamics) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
array.set(CSDI, CSD, !CallSiteDynamics).
update_call_site_statics(CSSPtr, CSS, !CallSiteStatics) :-
CSSPtr = call_site_static_ptr(CSSI),
array.set(CSSI, CSS, !CallSiteStatics).
update_proc_dynamics(PDPtr, PD, !ProcDynamics) :-
PDPtr = proc_dynamic_ptr(PDI),
array.set(PDI, PD, !ProcDynamics).
update_proc_statics(PSPtr, PS, !ProcStatics) :-
PSPtr = proc_static_ptr(PSI),
array.set(PSI, PS, !ProcStatics).
update_call_site_static_map(CSDPtr, CSSPtr, !CallSiteStaticMap) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
array.set(CSDI, CSSPtr, !CallSiteStaticMap).
update_proc_callers(PSPtr, CSDPtrs, !ProcCallers) :-
PSPtr = proc_static_ptr(PSI),
array.set(PSI, CSDPtrs, !ProcCallers).
update_ps_own(PSPtr, Own, !PSOwns) :-
PSPtr = proc_static_ptr(PSI),
array.set(PSI, Own, !PSOwns).
update_ps_desc(PSPtr, Desc, !PSDescs) :-
PSPtr = proc_static_ptr(PSI),
array.set(PSI, Desc, !PSDescs).
update_css_own(CSSPtr, Own, !CSSOwns) :-
CSSPtr = call_site_static_ptr(CSSI),
array.set(CSSI, Own, !CSSOwns).
update_css_desc(CSSPtr, Desc, !CSSDescs) :-
CSSPtr = call_site_static_ptr(CSSI),
array.set(CSSI, Desc, !CSSDescs).
update_ps_coverage(PSPtr, Coverage, !Coverages) :-
PSPtr = proc_static_ptr(PSI),
array.set(PSI, Coverage, !Coverages).
%---------------------------------------------------------------------------%
deep_update_csd_desc(CSDPtr, CSDDesc, !Deep) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
array.set(CSDI, CSDDesc, u(!.Deep ^ csd_desc), CSDDescs),
!Deep ^ csd_desc := CSDDescs.
deep_update_pd_desc(PDPtr, PDDesc, !Deep) :-
PDPtr = proc_dynamic_ptr(PDI),
array.set(PDI, PDDesc, u(!.Deep ^ pd_desc), PDDescs),
!Deep ^ pd_desc := PDDescs.
deep_update_pd_own(PDPtr, PDOwn, !Deep) :-
PDPtr = proc_dynamic_ptr(PDI),
array.set(PDI, PDOwn, u(!.Deep ^ pd_own), PDOwns),
!Deep ^ pd_own := PDOwns.
deep_update_pd_comp_table(PDPtr, CompTable, !Deep) :-
PDPtr = proc_dynamic_ptr(PDI),
array.set(PDI, CompTable, u(!.Deep ^ pd_comp_table), PDCompTables),
!Deep ^ pd_comp_table := PDCompTables.
deep_update_csd_comp_table(CSDPtr, CompTable, !Deep) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
array.set(CSDI, CompTable, u(!.Deep ^ csd_comp_table), CSDCompTables),
!Deep ^ csd_comp_table := CSDCompTables.
%---------------------------------------------------------------------------%
extract_pd_sites(PD, PD ^ pd_sites).
extract_csd_caller(CSD, CSD ^ csd_caller).
extract_csd_callee(CSD, CSD ^ csd_callee).
extract_csdptr_caller(InitDeep, CSDPtr, CallerPDPtr) :-
lookup_call_site_dynamics(InitDeep ^ init_call_site_dynamics,
CSDPtr, CSD),
CallerPDPtr = CSD ^ csd_caller.
extract_csdptr_callee(InitDeep, CSDPtr, CalleePDPtr) :-
lookup_call_site_dynamics(InitDeep ^ init_call_site_dynamics,
CSDPtr, CSD),
CalleePDPtr = CSD ^ csd_callee.
extract_ticks_per_sec(InitDeep,
InitDeep ^ init_profile_stats ^ prs_ticks_per_sec).
extract_instrument_quanta(InitDeep,
InitDeep ^ init_profile_stats ^ prs_instrument_quanta).
extract_user_quanta(InitDeep,
InitDeep ^ init_profile_stats ^ prs_user_quanta).
extract_num_callseqs(InitDeep,
InitDeep ^ init_profile_stats ^ prs_num_callseqs).
extract_max_css(InitDeep, MaxCSS) :-
array.max(InitDeep ^ init_call_site_statics, MaxCSS).
extract_max_ps(InitDeep, MaxPS) :-
array.max(InitDeep ^ init_proc_statics, MaxPS).
extract_max_csd(InitDeep, MaxCSD) :-
array.max(InitDeep ^ init_call_site_dynamics, MaxCSD).
extract_max_pd(InitDeep, MaxPD) :-
array.max(InitDeep ^ init_proc_dynamics, MaxPD).
extract_init_call_site_dynamics(InitDeep, InitDeep ^ init_call_site_dynamics).
extract_init_call_site_statics(InitDeep, InitDeep ^ init_call_site_statics).
extract_init_proc_dynamics(InitDeep, InitDeep ^ init_proc_dynamics).
extract_init_proc_statics(InitDeep, InitDeep ^ init_proc_statics).
extract_init_root(InitDeep, InitDeep ^ init_root).
%---------------------------------------------------------------------------%
deep_extract_csdptr_caller(Deep, CSDPtr, CallerPDPtr) :-
lookup_call_site_dynamics(Deep ^ call_site_dynamics, CSDPtr, CSD),
CallerPDPtr = CSD ^ csd_caller.
deep_extract_csdptr_callee(Deep, CSDPtr, CalleePDPtr) :-
lookup_call_site_dynamics(Deep ^ call_site_dynamics, CSDPtr, CSD),
CalleePDPtr = CSD ^ csd_callee.
%---------------------------------------------------------------------------%
wrap_proc_static_ptr(PSI) = proc_static_ptr(PSI).
%---------------------------------------------------------------------------%
root_total_info(Deep) = RootTotal :-
deep_lookup_pd_own(Deep, Deep ^ root, RootOwn),
deep_lookup_pd_desc(Deep, Deep ^ root, RootDesc),
add_own_to_inherit(RootOwn, RootDesc) = RootTotal.
root_desc_info(Deep) = RootDesc :-
deep_lookup_pd_desc(Deep, Deep ^ root, RootDesc).
root_own_info(Deep) = RootOwn :-
deep_lookup_pd_own(Deep, Deep ^ root, RootOwn).
%---------------------------------------------------------------------------%
deep_get_progrep_det(Deep, ProgRep) :-
deep_get_maybe_progrep(Deep, MaybeProgRep),
(
MaybeProgRep = ok(ProgRep)
;
MaybeProgRep = error(Error),
unexpected($pred, Error)
).
deep_get_maybe_progrep(Deep, MaybeProgRep) :-
MaybeProgRep0 = Deep ^ procrep_file,
(
MaybeProgRep0 = no,
MaybeProgRep = error("There is no readable " ++
"procedure representation information file.")
;
MaybeProgRep0 = yes(error(Error)),
MaybeProgRep = error("Error reading procedure representation " ++
"information file: " ++ Error)
;
MaybeProgRep0 = yes(ok(ProgRep)),
MaybeProgRep = ok(ProgRep)
).
%---------------------------------------------------------------------------%
:- end_module profile.
%---------------------------------------------------------------------------%