Permalink
Switch branches/tags
version-14_01_1 version-14_01 version-13_05_2 version-13_05_1 version-13_05 version-12_08-branchpoint version-12_08-GIT version-11_07_2 version-11_07_1 version-11_07 version-11_07-branchpoint version-11_01 version-11_01-branchpoint version-10_04_2 version-10_04_1 version-10_04 version-10_04-branchpoint version-0_13_1 version-0_13-branchpoint version-0_12_2 version-0_12_1 version-0_12-branchpoint version-0_11_0 version-0_11-branchpoint version-0_10 version-0_9_1 version-0_9 version-0_9_x-snapshot version-0_9_x-snapshot-19991220 unstable-version-0_13_1-x86_64-unknown-linux-gnu-libc2_3 unstable-version-0_13_1-i686-pc-linux-libc2_3-gnu-O5-intermod unstable-version-0_13-branch-x86_64-unknown-linux-gnu-libc2_3 unstable-version-0_13-branch-i686-pc-linux-libc2_3-gnu-O5-intermod unstable-version-0_12_2-i686-pc-linux-libc2_2-gnu-O5-intermod unstable-version-0_12_2-i386-pc-solaris2_8 unstable-version-0_12_1-i686-pc-linux-libc2_3-gnu-O4-intermod unstable-version-0_12_1-i686-pc-linux-libc2_3-gnu-O2 unstable-version-0_12_1-i686-pc-linux-libc2_2-gnu-O5-intermod unstable-version-0_12_1-i386-pc-solaris2_8 unstable-version-0_12-branch-i686-pc-linux-libc2_3-gnu-O5 unstable-version-0_12-branch-i686-pc-linux-libc2_3-gnu-O4-intermod unstable-version-0_12-branch-i686-pc-linux-libc2_3-gnu-O4-hlc unstable-version-0_12-branch-i686-pc-linux-libc2_3-gnu-O2 unstable-version-0_12-branch-i686-pc-linux-libc2_2-gnu-O5 unstable-version-0_12-branch-i686-pc-linux-libc2_2-gnu-O5-intermod unstable-version-0_12-branch-i686-pc-linux-libc2_2-gnu-O3 unstable-version-0_12-branch-i386-pc-solaris2_8 unstable-version-0_11_0-sparc-sun-solaris2_7 unstable-version-0_11_0-i686-pc-linux-libc2_3-gnu-O5-intermod unstable-version-0_11_0-i686-pc-linux-libc2_2-gnu-O5 unstable-version-0_11_0-i686-pc-linux-libc2_2-gnu-O5-lcc unstable-version-0_11_0-i686-pc-linux-libc2_2-gnu-O5-hlc unstable-version-0_11_0-i686-pc-linux-libc2_1-gnu-O4 unstable-version-0_11_0-i686-pc-linux-libc2_1-gnu-O4-asm unstable-version-0_11_0-i686-pc-linux-libc2_1-gnu-O3 unstable-version-0_11_0-i386-pc-solaris2_8 unstable-version-0_11-branch-i686-pc-linux-libc2_3-gnu-O5-intermod unstable-version-0_11-branch-i686-pc-linux-libc2_2-gnu-O5-intermod unstable-version-0_11-branch-i686-pc-linux-libc2_2-gnu-O5-hlc unstable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5 unstable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5-lcc unstable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5-intermod unstable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5-hlc unstable-version-0_11-branch-alpha-dec-osf5_1 unstable-version-0_10_y-sparc-sun-solaris2_7 unstable-version-0_10_y-i686-pc-linux-libc2_1-gnu-O5 unstable-version-0_10_y-i686-pc-linux-libc2_1-gnu-O5-lcc unstable-version-0_10_y-i686-pc-linux-libc2_1-gnu-O5-intermod unstable-version-0_10_y-i686-pc-linux-libc2_1-gnu-O5-hlc unstable-version-0_10_y-i686-pc-linux-libc2_1-gnu-O4 unstable-version-0_10_y-i686-pc-linux-libc2_1-gnu-O4-hlc unstable-version-0_10_y-i686-pc-linux-libc2_1-gnu-O2 unstable-version-0_10_y-i586-pc-linux-libc2_1-gnu-O0 unstable-version-0_10_y-alpha-dec-osf5_1 unstable-version-0_10_y-alpha-dec-osf3_2 unstable-version-0_10_x-sparc-sun-solaris2_7 unstable-version-0_10_x-i686-pc-linux-libc2_1-gnu-O5 unstable-version-0_10_x-i686-pc-linux-libc2_1-gnu-O5-lcc unstable-version-0_10_x-i686-pc-linux-libc2_1-gnu-O4 unstable-version-0_10_x-i686-pc-linux-libc2_1-gnu-O4-hlc unstable-version-0_10_x-i686-pc-linux-libc2_1-gnu-O3 unstable-version-0_10_x-i686-pc-linux-libc2_1-gnu-O2 unstable-version-0_10_x-i586-pc-linux-libc2_1-gnu-O0 unstable-version-0_10_x-alpha-dec-osf3_2 termination2_trunk stable-version-0_11_0-i686-pc-linux-libc2_3-gnu-O5-intermod stable-version-0_11_0-i686-pc-linux-libc2_2-gnu-O5 stable-version-0_11_0-i686-pc-linux-libc2_2-gnu-O5-lcc stable-version-0_11_0-i686-pc-linux-libc2_2-gnu-O5-hlc stable-version-0_11_0-i686-pc-linux-libc2_1-gnu-O4 stable-version-0_11_0-i686-pc-linux-libc2_1-gnu-O4-asm stable-version-0_11_0-i686-pc-linux-libc2_1-gnu-O3 stable-version-0_11-branch-i686-pc-linux-libc2_3-gnu-O5-intermod stable-version-0_11-branch-i686-pc-linux-libc2_2-gnu-O5-lcc stable-version-0_11-branch-i686-pc-linux-libc2_2-gnu-O5-intermod stable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5 stable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5-lcc stable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5-intermod stable-version-0_11-branch-i686-pc-linux-libc2_1-gnu-O5-hlc stable-version-0_11-branch-alpha-dec-osf5_1
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1294 lines (1109 sloc) 46.5 KB
%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2001, 2005-2008, 2010 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: top_procs.m.
% Author: zs.
%
% This module contains code to find the top procedures by several criteria.
%
% For comparisons on costs, we sort highest first. For comparisons on names and
% contexts, we sort lowest first. This is consistently what users want.
%
%---------------------------------------------------------------------------%
:- module top_procs.
:- interface.
:- import_module measurements.
:- import_module profile.
:- import_module query.
:- import_module list.
:- import_module maybe.
%---------------------------------------------------------------------------%
:- func find_top_procs(cost_kind, include_descendants, measurement_scope,
display_limit, deep) = maybe_error(list(int)).
% A line group consists of a first line, and optionally a group of later
% lines. The first line is structured as a sequence of fields, which may
% have one or two id fields but must have all the measurement fields
% demanded by the current preferences. The later lines must all be full
% rows.
%
:- type line_group(FL, LL)
---> line_group(
group_filename :: string,
group_linenumber :: int,
group_name :: string,
group_own :: own_prof_info,
group_desc :: inherit_prof_info,
group_first_line_id :: string,
group_later_lines :: LL
).
:- func sort_line_groups(order_criteria, list(line_group(FL, LL)))
= list(line_group(FL, LL)).
:- pred sum_line_group_measurements(list(line_group(FL, LL))::in,
own_prof_info::out, inherit_prof_info::out) is det.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module array.
:- import_module bool.
:- import_module float.
:- import_module int.
%---------------------------------------------------------------------------%
find_top_procs(Sort, InclDesc, Scope, Limit, Deep) = MaybeTopPSIs :-
find_top_sort_predicate(Sort, InclDesc, Scope, SortCompatible,
RawSortFunc, FilterPred),
(
SortCompatible = no,
MaybeTopPSIs = error("bad sort specification")
;
SortCompatible = yes,
ProcStatics = Deep ^ proc_statics,
array.max(ProcStatics, MaxProcStatic),
PSIs0 = 1 .. MaxProcStatic,
deep_lookup_proc_dynamics(Deep, Deep ^ root, RootPD),
RootPD ^ pd_proc_static = proc_static_ptr(RootPSI),
list.filter(filter_top_procs(Deep, RootPSI, FilterPred), PSIs0, PSIs),
SortPred = (pred(PSI1::in, PSI2::in, ComparisonResult::out) is det :-
ComparisonResult =
compare_procs_fallback(RawSortFunc, Deep, PSI1, PSI2)
),
list.sort(SortPred, PSIs, DescendingPSIs),
(
Limit = rank_range(First, Last),
( if list.drop(First - 1, DescendingPSIs, RemainingPSIs) then
list.take_upto(Last - First + 1, RemainingPSIs, TopPSIs),
MaybeTopPSIs = ok(TopPSIs)
else
MaybeTopPSIs = ok([])
)
;
Limit = threshold_percent(Threshold),
find_threshold_percent_predicate(Sort, InclDesc,
ThresholdCompatible, RawThresholdPred),
(
ThresholdCompatible = no,
MaybeTopPSIs = error("bad threshold specification")
;
ThresholdCompatible = yes,
ThresholdPred = (pred(PSI::in) is semidet :-
RawThresholdPred(Deep, Threshold, PSI)
),
list.take_while(ThresholdPred, DescendingPSIs, TopPSIs),
MaybeTopPSIs = ok(TopPSIs)
)
;
Limit = threshold_value(Threshold),
find_threshold_value_predicate(Sort, InclDesc,
ThresholdCompatible, RawThresholdPred),
(
ThresholdCompatible = no,
MaybeTopPSIs = error("bad threshold specification")
;
ThresholdCompatible = yes,
ThresholdPred = (pred(PSI::in) is semidet :-
RawThresholdPred(Deep, Threshold, PSI)
),
list.take_while(ThresholdPred, DescendingPSIs, TopPSIs),
MaybeTopPSIs = ok(TopPSIs)
)
)
).
%---------------------------------------------------------------------------%
:- type compare_proc_statics == (func(deep, int, int) = comparison_result).
:- func compare_procs_fallback(compare_proc_statics, deep, int, int)
= comparison_result.
compare_procs_fallback(MainFunc, Deep, PSI1, PSI2) = Result :-
Result0 = MainFunc(Deep, PSI1, PSI2),
(
Result0 = (=),
Result1 = compare_ps_time_both_overall(Deep, PSI1, PSI2),
(
Result1 = (=),
Result = compare_ps_words_both_overall(Deep, PSI1, PSI2)
;
( Result1 = (<)
; Result1 = (>)
),
Result = Result1
)
;
( Result0 = (<)
; Result0 = (>)
),
Result = Result0
).
%---------------------------------------------------------------------------%
:- pred filter_top_procs(deep::in, int::in,
pred(deep, int)::in(pred(in, in) is semidet), int::in) is semidet.
filter_top_procs(Deep, RootPSI, FilterPred, PSI) :-
PSI \= RootPSI,
FilterPred(Deep, PSI).
:- pred find_top_sort_predicate(cost_kind::in, include_descendants::in,
measurement_scope::in, bool::out,
compare_proc_statics::out(func(in, in, in) = out is det),
pred(deep, int)::out(pred(in, in) is semidet)) is det.
find_top_sort_predicate(cost_calls, self, overall, yes,
compare_ps_calls_self_overall, filter_ps_calls_self).
find_top_sort_predicate(cost_calls, self, per_call, no,
compare_ps_calls_self_overall, filter_ps_calls_self).
find_top_sort_predicate(cost_calls, self_and_desc, overall, no,
compare_ps_calls_self_overall, filter_ps_calls_self).
find_top_sort_predicate(cost_calls, self_and_desc, per_call, no,
compare_ps_calls_self_overall, filter_ps_calls_self).
find_top_sort_predicate(cost_redos, self, overall, yes,
compare_ps_redos_self_overall, filter_ps_redos_self).
find_top_sort_predicate(cost_redos, self, per_call, no,
compare_ps_redos_self_overall, filter_ps_redos_self).
find_top_sort_predicate(cost_redos, self_and_desc, overall, no,
compare_ps_redos_self_overall, filter_ps_redos_self).
find_top_sort_predicate(cost_redos, self_and_desc, per_call, no,
compare_ps_redos_self_overall, filter_ps_redos_self).
find_top_sort_predicate(cost_time, self, overall, yes,
compare_ps_time_self_overall, filter_ps_time_self).
find_top_sort_predicate(cost_time, self, per_call, yes,
compare_ps_time_self_percall, filter_ps_time_self).
find_top_sort_predicate(cost_time, self_and_desc, overall, yes,
compare_ps_time_both_overall, filter_ps_time_both).
find_top_sort_predicate(cost_time, self_and_desc, per_call, yes,
compare_ps_time_both_percall, filter_ps_time_both).
find_top_sort_predicate(cost_callseqs, self, overall, yes,
compare_ps_callseqs_self_overall, filter_ps_callseqs_self).
find_top_sort_predicate(cost_callseqs, self, per_call, yes,
compare_ps_callseqs_self_percall, filter_ps_callseqs_self).
find_top_sort_predicate(cost_callseqs, self_and_desc, overall, yes,
compare_ps_callseqs_both_overall, filter_ps_callseqs_both).
find_top_sort_predicate(cost_callseqs, self_and_desc, per_call, yes,
compare_ps_callseqs_both_percall, filter_ps_callseqs_both).
find_top_sort_predicate(cost_allocs, self, overall, yes,
compare_ps_allocs_self_overall, filter_ps_allocs_self).
find_top_sort_predicate(cost_allocs, self, per_call, yes,
compare_ps_allocs_self_percall, filter_ps_allocs_self).
find_top_sort_predicate(cost_allocs, self_and_desc, overall, yes,
compare_ps_allocs_both_overall, filter_ps_allocs_both).
find_top_sort_predicate(cost_allocs, self_and_desc, per_call, yes,
compare_ps_allocs_both_percall, filter_ps_allocs_both).
find_top_sort_predicate(cost_words, self, overall, yes,
compare_ps_words_self_overall, filter_ps_words_self).
find_top_sort_predicate(cost_words, self, per_call, yes,
compare_ps_words_self_percall, filter_ps_words_self).
find_top_sort_predicate(cost_words, self_and_desc, overall, yes,
compare_ps_words_both_overall, filter_ps_words_both).
find_top_sort_predicate(cost_words, self_and_desc, per_call, yes,
compare_ps_words_both_percall, filter_ps_words_both).
:- pred find_threshold_percent_predicate(cost_kind::in,
include_descendants::in, bool::out,
pred(deep, float, int)::out(pred(in, in, in) is semidet)) is det.
find_threshold_percent_predicate(cost_calls, self, no,
threshold_percent_ps_time_self).
find_threshold_percent_predicate(cost_calls, self_and_desc, no,
threshold_percent_ps_time_self).
find_threshold_percent_predicate(cost_redos, self, no,
threshold_percent_ps_time_self).
find_threshold_percent_predicate(cost_redos, self_and_desc, no,
threshold_percent_ps_time_self).
find_threshold_percent_predicate(cost_time, self, yes,
threshold_percent_ps_time_self).
find_threshold_percent_predicate(cost_time, self_and_desc, yes,
threshold_percent_ps_time_both).
find_threshold_percent_predicate(cost_callseqs, self, yes,
threshold_percent_ps_callseqs_self).
find_threshold_percent_predicate(cost_callseqs, self_and_desc, yes,
threshold_percent_ps_callseqs_both).
find_threshold_percent_predicate(cost_allocs, self, yes,
threshold_percent_ps_allocs_self).
find_threshold_percent_predicate(cost_allocs, self_and_desc, yes,
threshold_percent_ps_allocs_both).
find_threshold_percent_predicate(cost_words, self, yes,
threshold_percent_ps_words_self).
find_threshold_percent_predicate(cost_words, self_and_desc, yes,
threshold_percent_ps_words_both).
:- pred find_threshold_value_predicate(cost_kind::in, include_descendants::in,
bool::out, pred(deep, float, int)::out(pred(in, in, in) is semidet))
is det.
find_threshold_value_predicate(cost_calls, self, no,
threshold_value_ps_time_self).
find_threshold_value_predicate(cost_calls, self_and_desc, no,
threshold_value_ps_time_self).
find_threshold_value_predicate(cost_redos, self, no,
threshold_value_ps_time_self).
find_threshold_value_predicate(cost_redos, self_and_desc, no,
threshold_value_ps_time_self).
find_threshold_value_predicate(cost_time, self, yes,
threshold_value_ps_time_self).
find_threshold_value_predicate(cost_time, self_and_desc, yes,
threshold_value_ps_time_both).
find_threshold_value_predicate(cost_callseqs, self, yes,
threshold_value_ps_callseqs_self).
find_threshold_value_predicate(cost_callseqs, self_and_desc, yes,
threshold_value_ps_callseqs_both).
find_threshold_value_predicate(cost_allocs, self, yes,
threshold_value_ps_allocs_self).
find_threshold_value_predicate(cost_allocs, self_and_desc, yes,
threshold_value_ps_allocs_both).
find_threshold_value_predicate(cost_words, self, yes,
threshold_value_ps_words_self).
find_threshold_value_predicate(cost_words, self_and_desc, yes,
threshold_value_ps_words_both).
%---------------------------------------------------------------------------%
:- func compare_ps_calls_self_overall(deep, int, int) = comparison_result.
compare_ps_calls_self_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
OwnCalls1 = calls(Own1),
OwnCalls2 = calls(Own2),
compare(Result, OwnCalls2, OwnCalls1).
:- func compare_ps_redos_self_overall(deep, int, int) = comparison_result.
compare_ps_redos_self_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
OwnRedos1 = redos(Own1),
OwnRedos2 = redos(Own2),
compare(Result, OwnRedos2, OwnRedos1).
:- func compare_ps_time_self_overall(deep, int, int) = comparison_result.
compare_ps_time_self_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
OwnQuanta1 = quanta(Own1),
OwnQuanta2 = quanta(Own2),
compare(Result, OwnQuanta2, OwnQuanta1).
:- func compare_ps_time_self_percall(deep, int, int) = comparison_result.
compare_ps_time_self_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnQuanta1 = quanta(Own1),
OwnQuanta2 = quanta(Own2),
OwnQuantaPerCall1 = float(OwnQuanta1) / float(Calls1),
OwnQuantaPerCall2 = float(OwnQuanta2) / float(Calls2),
compare(Result, OwnQuantaPerCall2, OwnQuantaPerCall1).
:- func compare_ps_time_both_overall(deep, int, int) = comparison_result.
compare_ps_time_both_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
OwnQuanta1 = quanta(Own1),
OwnQuanta2 = quanta(Own2),
DescQuanta1 = inherit_quanta(Desc1),
DescQuanta2 = inherit_quanta(Desc2),
TotalQuanta1 = OwnQuanta1 + DescQuanta1,
TotalQuanta2 = OwnQuanta2 + DescQuanta2,
compare(Result, TotalQuanta2, TotalQuanta1).
:- func compare_ps_time_both_percall(deep, int, int) = comparison_result.
compare_ps_time_both_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnQuanta1 = quanta(Own1),
OwnQuanta2 = quanta(Own2),
DescQuanta1 = inherit_quanta(Desc1),
DescQuanta2 = inherit_quanta(Desc2),
TotalQuanta1 = OwnQuanta1 + DescQuanta1,
TotalQuanta2 = OwnQuanta2 + DescQuanta2,
TotalQuantaPerCall1 = float(TotalQuanta1) / float(Calls1),
TotalQuantaPerCall2 = float(TotalQuanta2) / float(Calls2),
compare(Result, TotalQuantaPerCall2, TotalQuantaPerCall1).
:- func compare_ps_callseqs_self_overall(deep, int, int) = comparison_result.
compare_ps_callseqs_self_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
OwnCallSeqs1 = callseqs(Own1),
OwnCallSeqs2 = callseqs(Own2),
compare(Result, OwnCallSeqs2, OwnCallSeqs1).
:- func compare_ps_callseqs_self_percall(deep, int, int) = comparison_result.
compare_ps_callseqs_self_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnCallSeqs1 = callseqs(Own1),
OwnCallSeqs2 = callseqs(Own2),
OwnCallSeqsPerCall1 = float(OwnCallSeqs1) / float(Calls1),
OwnCallSeqsPerCall2 = float(OwnCallSeqs2) / float(Calls2),
compare(Result, OwnCallSeqsPerCall2, OwnCallSeqsPerCall1).
:- func compare_ps_callseqs_both_overall(deep, int, int) = comparison_result.
compare_ps_callseqs_both_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
OwnCallSeqs1 = callseqs(Own1),
OwnCallSeqs2 = callseqs(Own2),
DescCallSeqs1 = inherit_callseqs(Desc1),
DescCallSeqs2 = inherit_callseqs(Desc2),
TotalCallSeqs1 = OwnCallSeqs1 + DescCallSeqs1,
TotalCallSeqs2 = OwnCallSeqs2 + DescCallSeqs2,
compare(Result, TotalCallSeqs2, TotalCallSeqs1).
:- func compare_ps_callseqs_both_percall(deep, int, int) = comparison_result.
compare_ps_callseqs_both_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnCallSeqs1 = callseqs(Own1),
OwnCallSeqs2 = callseqs(Own2),
DescCallSeqs1 = inherit_callseqs(Desc1),
DescCallSeqs2 = inherit_callseqs(Desc2),
TotalCallSeqs1 = OwnCallSeqs1 + DescCallSeqs1,
TotalCallSeqs2 = OwnCallSeqs2 + DescCallSeqs2,
TotalCallSeqsPerCall1 = float(TotalCallSeqs1) / float(Calls1),
TotalCallSeqsPerCall2 = float(TotalCallSeqs2) / float(Calls2),
compare(Result, TotalCallSeqsPerCall2, TotalCallSeqsPerCall1).
:- func compare_ps_allocs_self_overall(deep, int, int) = comparison_result.
compare_ps_allocs_self_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
OwnAlloc1 = allocs(Own1),
OwnAlloc2 = allocs(Own2),
compare(Result, OwnAlloc2, OwnAlloc1).
:- func compare_ps_allocs_self_percall(deep, int, int) = comparison_result.
compare_ps_allocs_self_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnAlloc1 = allocs(Own1),
OwnAlloc2 = allocs(Own2),
OwnAllocPerCall1 = float(OwnAlloc1) / float(Calls1),
OwnAllocPerCall2 = float(OwnAlloc2) / float(Calls2),
compare(Result, OwnAllocPerCall2, OwnAllocPerCall1).
:- func compare_ps_allocs_both_overall(deep, int, int) = comparison_result.
compare_ps_allocs_both_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
OwnAlloc1 = allocs(Own1),
OwnAlloc2 = allocs(Own2),
DescAlloc1 = inherit_allocs(Desc1),
DescAlloc2 = inherit_allocs(Desc2),
TotalAlloc1 = OwnAlloc1 + DescAlloc1,
TotalAlloc2 = OwnAlloc2 + DescAlloc2,
compare(Result, TotalAlloc2, TotalAlloc1).
:- func compare_ps_allocs_both_percall(deep, int, int) = comparison_result.
compare_ps_allocs_both_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnAlloc1 = allocs(Own1),
OwnAlloc2 = allocs(Own2),
DescAlloc1 = inherit_allocs(Desc1),
DescAlloc2 = inherit_allocs(Desc2),
TotalAlloc1 = OwnAlloc1 + DescAlloc1,
TotalAlloc2 = OwnAlloc2 + DescAlloc2,
TotalAllocPerCall1 = float(TotalAlloc1) / float(Calls1),
TotalAllocPerCall2 = float(TotalAlloc2) / float(Calls2),
compare(Result, TotalAllocPerCall2, TotalAllocPerCall1).
:- func compare_ps_words_self_overall(deep, int, int) = comparison_result.
compare_ps_words_self_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
OwnWords1 = words(Own1),
OwnWords2 = words(Own2),
compare(Result, OwnWords2, OwnWords1).
:- func compare_ps_words_self_percall(deep, int, int) = comparison_result.
compare_ps_words_self_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnWords1 = words(Own1),
OwnWords2 = words(Own2),
OwnWordsPerCall1 = float(OwnWords1) / float(Calls1),
OwnWordsPerCall2 = float(OwnWords2) / float(Calls2),
compare(Result, OwnWordsPerCall2, OwnWordsPerCall1).
:- func compare_ps_words_both_overall(deep, int, int) = comparison_result.
compare_ps_words_both_overall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
OwnWords1 = words(Own1),
OwnWords2 = words(Own2),
DescWords1 = inherit_words(Desc1),
DescWords2 = inherit_words(Desc2),
TotalWords1 = OwnWords1 + DescWords1,
TotalWords2 = OwnWords2 + DescWords2,
compare(Result, TotalWords2, TotalWords1).
:- func compare_ps_words_both_percall(deep, int, int) = comparison_result.
compare_ps_words_both_percall(Deep, PSI1, PSI2) = Result :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSOwn, PSI2, Own2),
array.lookup(PSDesc, PSI1, Desc1),
array.lookup(PSDesc, PSI2, Desc2),
Calls1 = calls(Own1),
Calls2 = calls(Own2),
OwnWords1 = words(Own1),
OwnWords2 = words(Own2),
DescWords1 = inherit_words(Desc1),
DescWords2 = inherit_words(Desc2),
TotalWords1 = OwnWords1 + DescWords1,
TotalWords2 = OwnWords2 + DescWords2,
TotalWordsPerCall1 = float(TotalWords1) / float(Calls1),
TotalWordsPerCall2 = float(TotalWords2) / float(Calls2),
compare(Result, TotalWordsPerCall2, TotalWordsPerCall1).
%---------------------------------------------------------------------------%
:- pred filter_ps_calls_self(deep::in, int::in) is semidet.
filter_ps_calls_self(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
OwnCalls1 = calls(Own1),
OwnCalls1 > 0.
:- pred filter_ps_redos_self(deep::in, int::in) is semidet.
filter_ps_redos_self(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
OwnCalls1 = redos(Own1),
OwnCalls1 > 0.
:- pred filter_ps_time_self(deep::in, int::in) is semidet.
filter_ps_time_self(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
OwnQuanta1 = quanta(Own1),
OwnQuanta1 > 0.
:- pred filter_ps_time_both(deep::in, int::in) is semidet.
filter_ps_time_both(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSDesc, PSI1, Desc1),
OwnQuanta1 = quanta(Own1),
DescQuanta1 = inherit_quanta(Desc1),
TotalQuanta1 = OwnQuanta1 + DescQuanta1,
TotalQuanta1 > 0.
:- pred filter_ps_callseqs_self(deep::in, int::in) is semidet.
filter_ps_callseqs_self(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
OwnCallSeqs1 = callseqs(Own1),
OwnCallSeqs1 > 0.
:- pred filter_ps_callseqs_both(deep::in, int::in) is semidet.
filter_ps_callseqs_both(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSDesc, PSI1, Desc1),
OwnCallSeqs1 = callseqs(Own1),
DescCallSeqs1 = inherit_callseqs(Desc1),
TotalCallSeqs1 = OwnCallSeqs1 + DescCallSeqs1,
TotalCallSeqs1 > 0.
:- pred filter_ps_allocs_self(deep::in, int::in) is semidet.
filter_ps_allocs_self(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
OwnAlloc1 = allocs(Own1),
OwnAlloc1 > 0.
:- pred filter_ps_allocs_both(deep::in, int::in) is semidet.
filter_ps_allocs_both(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSDesc, PSI1, Desc1),
OwnAlloc1 = allocs(Own1),
DescAlloc1 = inherit_allocs(Desc1),
TotalAlloc1 = OwnAlloc1 + DescAlloc1,
TotalAlloc1 > 0.
:- pred filter_ps_words_self(deep::in, int::in) is semidet.
filter_ps_words_self(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI1, Own1),
OwnWords1 = words(Own1),
OwnWords1 > 0.
:- pred filter_ps_words_both(deep::in, int::in) is semidet.
filter_ps_words_both(Deep, PSI1) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI1, Own1),
array.lookup(PSDesc, PSI1, Desc1),
OwnWords1 = words(Own1),
DescWords1 = inherit_words(Desc1),
TotalWords1 = OwnWords1 + DescWords1,
TotalWords1 > 0.
%---------------------------------------------------------------------------%
:- pred threshold_value_ps_time_self(deep::in, float::in, int::in) is semidet.
threshold_value_ps_time_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
OwnQuanta = quanta(Own),
float(OwnQuanta) > Threshold.
:- pred threshold_value_ps_time_both(deep::in, float::in, int::in) is semidet.
threshold_value_ps_time_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
OwnQuanta = quanta(Own),
DescQuanta = inherit_quanta(Desc),
TotalQuanta = OwnQuanta + DescQuanta,
float(TotalQuanta) > Threshold.
:- pred threshold_value_ps_callseqs_self(deep::in, float::in, int::in)
is semidet.
threshold_value_ps_callseqs_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
OwnCallSeqs = callseqs(Own),
float(OwnCallSeqs) > Threshold.
:- pred threshold_value_ps_callseqs_both(deep::in, float::in, int::in)
is semidet.
threshold_value_ps_callseqs_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
OwnCallSeqs = callseqs(Own),
DescCallSeqs = inherit_callseqs(Desc),
TotalCallSeqs = OwnCallSeqs + DescCallSeqs,
float(TotalCallSeqs) > Threshold.
:- pred threshold_value_ps_allocs_self(deep::in, float::in, int::in)
is semidet.
threshold_value_ps_allocs_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
OwnAlloc = allocs(Own),
float(OwnAlloc) > Threshold.
:- pred threshold_value_ps_allocs_both(deep::in, float::in, int::in)
is semidet.
threshold_value_ps_allocs_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
OwnAlloc = allocs(Own),
DescAlloc = inherit_allocs(Desc),
TotalAlloc = OwnAlloc + DescAlloc,
float(TotalAlloc) > Threshold.
:- pred threshold_value_ps_words_self(deep::in, float::in, int::in)
is semidet.
threshold_value_ps_words_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
OwnWords = words(Own),
float(OwnWords) > Threshold.
:- pred threshold_value_ps_words_both(deep::in, float::in, int::in) is semidet.
threshold_value_ps_words_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
OwnWords = words(Own),
DescWords = inherit_words(Desc),
TotalWords = OwnWords + DescWords,
float(TotalWords) > Threshold.
%---------------------------------------------------------------------------%
:- pred threshold_percent_ps_time_self(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_time_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnQuanta = quanta(Own),
RootOwnQuanta = quanta(RootOwn),
RootDescQuanta = inherit_quanta(RootDesc),
RootTotalQuanta = RootOwnQuanta + RootDescQuanta,
100.0 * float(OwnQuanta) > Threshold * float(RootTotalQuanta).
:- pred threshold_percent_ps_time_both(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_time_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnQuanta = quanta(Own),
RootOwnQuanta = quanta(RootOwn),
DescQuanta = inherit_quanta(Desc),
RootDescQuanta = inherit_quanta(RootDesc),
TotalQuanta = OwnQuanta + DescQuanta,
RootTotalQuanta = RootOwnQuanta + RootDescQuanta,
100.0 * float(TotalQuanta) > Threshold * float(RootTotalQuanta).
:- pred threshold_percent_ps_callseqs_self(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_callseqs_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnCallSeqs = callseqs(Own),
RootOwnCallSeqs = callseqs(RootOwn),
RootDescCallSeqs = inherit_callseqs(RootDesc),
RootTotalCallSeqs = RootOwnCallSeqs + RootDescCallSeqs,
100.0 * float(OwnCallSeqs) > Threshold * float(RootTotalCallSeqs).
:- pred threshold_percent_ps_callseqs_both(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_callseqs_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnCallSeqs = callseqs(Own),
RootOwnCallSeqs = callseqs(RootOwn),
DescCallSeqs = inherit_callseqs(Desc),
RootDescCallSeqs = inherit_callseqs(RootDesc),
TotalCallSeqs = OwnCallSeqs + DescCallSeqs,
RootTotalCallSeqs = RootOwnCallSeqs + RootDescCallSeqs,
100.0 * float(TotalCallSeqs) > Threshold * float(RootTotalCallSeqs).
:- pred threshold_percent_ps_allocs_self(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_allocs_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnAlloc = allocs(Own),
RootOwnAlloc = allocs(RootOwn),
RootDescAlloc = inherit_allocs(RootDesc),
RootTotalAlloc = RootOwnAlloc + RootDescAlloc,
100.0 * float(OwnAlloc) > Threshold * float(RootTotalAlloc).
:- pred threshold_percent_ps_allocs_both(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_allocs_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnAlloc = allocs(Own),
RootOwnAlloc = allocs(RootOwn),
DescAlloc = inherit_allocs(Desc),
RootDescAlloc = inherit_allocs(RootDesc),
TotalAlloc = OwnAlloc + DescAlloc,
RootTotalAlloc = RootOwnAlloc + RootDescAlloc,
100.0 * float(TotalAlloc) > Threshold * float(RootTotalAlloc).
:- pred threshold_percent_ps_words_self(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_words_self(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
array.lookup(PSOwn, PSI, Own),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnWords = words(Own),
RootOwnWords = words(RootOwn),
RootDescWords = inherit_words(RootDesc),
RootTotalWords = RootOwnWords + RootDescWords,
100.0 * float(OwnWords) > Threshold * float(RootTotalWords).
:- pred threshold_percent_ps_words_both(deep::in, float::in, int::in)
is semidet.
threshold_percent_ps_words_both(Deep, Threshold, PSI) :-
PSOwn = Deep ^ ps_own,
PSDesc = Deep ^ ps_desc,
array.lookup(PSOwn, PSI, Own),
array.lookup(PSDesc, PSI, Desc),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
OwnWords = words(Own),
RootOwnWords = words(RootOwn),
DescWords = inherit_words(Desc),
RootDescWords = inherit_words(RootDesc),
TotalWords = OwnWords + DescWords,
RootTotalWords = RootOwnWords + RootDescWords,
100.0 * float(TotalWords) > Threshold * float(RootTotalWords).
%---------------------------------------------------------------------------%
sort_line_groups(Criteria, Groups) = SortedGroups :-
(
Criteria = by_context,
CompFunc = compare_line_groups_by_context
;
Criteria = by_name,
CompFunc = compare_line_groups_by_name
;
Criteria = by_cost(Measurement, InclDesc, Scope),
(
Measurement = cost_calls,
% We ignore the setting of InclDesc because calls are not
% inherited from descendants, and we ignore the setting of Scope
% because sorting on "calls per call" is not useful.
CompFunc = compare_line_groups_by_calls
;
Measurement = cost_redos,
CompFunc = compare_line_groups_by_redos
;
Measurement = cost_time,
InclDesc = self,
Scope = overall,
CompFunc = compare_line_groups_by_time_self_overall
;
Measurement = cost_time,
InclDesc = self,
Scope = per_call,
CompFunc = compare_line_groups_by_time_self_percall
;
Measurement = cost_time,
InclDesc = self_and_desc,
Scope = overall,
CompFunc = compare_line_groups_by_time_total_overall
;
Measurement = cost_time,
InclDesc = self_and_desc,
Scope = per_call,
CompFunc = compare_line_groups_by_time_total_percall
;
Measurement = cost_callseqs,
InclDesc = self,
Scope = overall,
CompFunc = compare_line_groups_by_callseqs_self_overall
;
Measurement = cost_callseqs,
InclDesc = self,
Scope = per_call,
CompFunc = compare_line_groups_by_callseqs_self_percall
;
Measurement = cost_callseqs,
InclDesc = self_and_desc,
Scope = overall,
CompFunc = compare_line_groups_by_callseqs_total_overall
;
Measurement = cost_callseqs,
InclDesc = self_and_desc,
Scope = per_call,
CompFunc = compare_line_groups_by_callseqs_total_percall
;
Measurement = cost_allocs,
InclDesc = self,
Scope = overall,
CompFunc = compare_line_groups_by_allocs_self_overall
;
Measurement = cost_allocs,
InclDesc = self,
Scope = per_call,
CompFunc = compare_line_groups_by_allocs_self_percall
;
Measurement = cost_allocs,
InclDesc = self_and_desc,
Scope = overall,
CompFunc = compare_line_groups_by_allocs_total_overall
;
Measurement = cost_allocs,
InclDesc = self_and_desc,
Scope = per_call,
CompFunc = compare_line_groups_by_allocs_total_percall
;
Measurement = cost_words,
InclDesc = self,
Scope = overall,
CompFunc = compare_line_groups_by_words_self_overall
;
Measurement = cost_words,
InclDesc = self,
Scope = per_call,
CompFunc = compare_line_groups_by_words_self_percall
;
Measurement = cost_words,
InclDesc = self_and_desc,
Scope = overall,
CompFunc = compare_line_groups_by_words_total_overall
;
Measurement = cost_words,
InclDesc = self_and_desc,
Scope = per_call,
CompFunc = compare_line_groups_by_words_total_percall
)
),
SortedGroups = list.sort(compare_groups_fallback(CompFunc), Groups).
:- type compare_line_groups_func(FL, LL) ==
(func(line_group(FL, LL), line_group(FL, LL)) = comparison_result).
:- func compare_groups_fallback(compare_line_groups_func(FL, LL),
line_group(FL, LL), line_group(FL, LL)) = comparison_result.
compare_groups_fallback(MainFunc, Group1, Group2) = Result :-
Result0 = MainFunc(Group1, Group2),
(
Result0 = (=),
Result1 = compare_line_groups_by_context(Group1, Group2),
(
Result1 = (=),
Result = compare_line_groups_by_name(Group1, Group2)
;
( Result1 = (<)
; Result1 = (>)
),
Result = Result1
)
;
( Result0 = (<)
; Result0 = (>)
),
Result = Result0
).
%---------------------------------------------------------------------------%
:- func compare_line_groups_by_context(line_group(FL, LL), line_group(FL, LL))
= comparison_result.
compare_line_groups_by_context(Group1, Group2) = Result :-
compare(ResultFilenames,
Group1 ^ group_filename, Group2 ^ group_filename),
(
ResultFilenames = (=),
compare(Result, Group1 ^ group_linenumber, Group2 ^ group_linenumber)
;
( ResultFilenames = (<)
; ResultFilenames = (>)
),
Result = ResultFilenames
).
:- func compare_line_groups_by_name(line_group(FL, LL), line_group(FL, LL))
= comparison_result.
compare_line_groups_by_name(Group1, Group2) = Result :-
compare(Result, Group1 ^ group_name, Group2 ^ group_name).
:- func compare_line_groups_by_calls(line_group(FL, LL), line_group(FL, LL))
= comparison_result.
compare_line_groups_by_calls(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
compare(Result, Calls2, Calls1).
:- func compare_line_groups_by_redos(line_group(FL, LL), line_group(FL, LL))
= comparison_result.
compare_line_groups_by_redos(Group1, Group2) = Result :-
Redos1 = redos(Group1 ^ group_own),
Redos2 = redos(Group2 ^ group_own),
compare(Result, Redos2, Redos1).
:- func compare_line_groups_by_time_self_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_time_self_overall(Group1, Group2) = Result :-
Quanta1 = quanta(Group1 ^ group_own),
Quanta2 = quanta(Group2 ^ group_own),
compare(Result, Quanta2, Quanta1).
:- func compare_line_groups_by_time_self_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_time_self_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
Quanta1 = quanta(Group1 ^ group_own),
Quanta2 = quanta(Group2 ^ group_own),
( if Calls1 = 0 then
QuantaPerCall1 = 0.0
else
QuantaPerCall1 = float(Quanta1) / float(Calls1)
),
( if Calls2 = 0 then
QuantaPerCall2 = 0.0
else
QuantaPerCall2 = float(Quanta2) / float(Calls2)
),
compare(Result, QuantaPerCall2, QuantaPerCall1).
:- func compare_line_groups_by_time_total_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_time_total_overall(Group1, Group2) = Result :-
Quanta1 = quanta(Group1 ^ group_own) + inherit_quanta(Group1 ^ group_desc),
Quanta2 = quanta(Group2 ^ group_own) + inherit_quanta(Group2 ^ group_desc),
compare(Result, Quanta2, Quanta1).
:- func compare_line_groups_by_time_total_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_time_total_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
Quanta1 = quanta(Group1 ^ group_own) + inherit_quanta(Group1 ^ group_desc),
Quanta2 = quanta(Group2 ^ group_own) + inherit_quanta(Group2 ^ group_desc),
( if Calls1 = 0 then
QuantaPerCall1 = 0.0
else
QuantaPerCall1 = float(Quanta1) / float(Calls1)
),
( if Calls2 = 0 then
QuantaPerCall2 = 0.0
else
QuantaPerCall2 = float(Quanta2) / float(Calls2)
),
compare(Result, QuantaPerCall2, QuantaPerCall1).
:- func compare_line_groups_by_callseqs_self_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_callseqs_self_overall(Group1, Group2) = Result :-
CallSeqs1 = callseqs(Group1 ^ group_own),
CallSeqs2 = callseqs(Group2 ^ group_own),
compare(Result, CallSeqs2, CallSeqs1).
:- func compare_line_groups_by_callseqs_self_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_callseqs_self_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
CallSeqs1 = callseqs(Group1 ^ group_own),
CallSeqs2 = callseqs(Group2 ^ group_own),
( if Calls1 = 0 then
CallSeqsPerCall1 = 0.0
else
CallSeqsPerCall1 = float(CallSeqs1) / float(Calls1)
),
( if Calls2 = 0 then
CallSeqsPerCall2 = 0.0
else
CallSeqsPerCall2 = float(CallSeqs2) / float(Calls2)
),
compare(Result, CallSeqsPerCall2, CallSeqsPerCall1).
:- func compare_line_groups_by_callseqs_total_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_callseqs_total_overall(Group1, Group2) = Result :-
CallSeqs1 = callseqs(Group1 ^ group_own) +
inherit_callseqs(Group1 ^ group_desc),
CallSeqs2 = callseqs(Group2 ^ group_own) +
inherit_callseqs(Group2 ^ group_desc),
compare(Result, CallSeqs2, CallSeqs1).
:- func compare_line_groups_by_callseqs_total_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_callseqs_total_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
CallSeqs1 = callseqs(Group1 ^ group_own) +
inherit_callseqs(Group1 ^ group_desc),
CallSeqs2 = callseqs(Group2 ^ group_own) +
inherit_callseqs(Group2 ^ group_desc),
( if Calls1 = 0 then
CallSeqsPerCall1 = 0.0
else
CallSeqsPerCall1 = float(CallSeqs1) / float(Calls1)
),
( if Calls2 = 0 then
CallSeqsPerCall2 = 0.0
else
CallSeqsPerCall2 = float(CallSeqs2) / float(Calls2)
),
compare(Result, CallSeqsPerCall2, CallSeqsPerCall1).
:- func compare_line_groups_by_allocs_self_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_allocs_self_overall(Group1, Group2) = Result :-
Alloc1 = allocs(Group1 ^ group_own),
Alloc2 = allocs(Group2 ^ group_own),
compare(Result, Alloc2, Alloc1).
:- func compare_line_groups_by_allocs_self_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_allocs_self_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
Alloc1 = allocs(Group1 ^ group_own),
Alloc2 = allocs(Group2 ^ group_own),
( if Calls1 = 0 then
AllocPerCall1 = 0.0
else
AllocPerCall1 = float(Alloc1) / float(Calls1)
),
( if Calls2 = 0 then
AllocPerCall2 = 0.0
else
AllocPerCall2 = float(Alloc2) / float(Calls2)
),
compare(Result, AllocPerCall2, AllocPerCall1).
:- func compare_line_groups_by_allocs_total_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_allocs_total_overall(Group1, Group2) = Result :-
Alloc1 = allocs(Group1 ^ group_own) + inherit_allocs(Group1 ^ group_desc),
Alloc2 = allocs(Group2 ^ group_own) + inherit_allocs(Group2 ^ group_desc),
compare(Result, Alloc2, Alloc1).
:- func compare_line_groups_by_allocs_total_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_allocs_total_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
Alloc1 = allocs(Group1 ^ group_own) + inherit_allocs(Group1 ^ group_desc),
Alloc2 = allocs(Group2 ^ group_own) + inherit_allocs(Group2 ^ group_desc),
( if Calls1 = 0 then
AllocPerCall1 = 0.0
else
AllocPerCall1 = float(Alloc1) / float(Calls1)
),
( if Calls2 = 0 then
AllocPerCall2 = 0.0
else
AllocPerCall2 = float(Alloc2) / float(Calls2)
),
compare(Result, AllocPerCall2, AllocPerCall1).
:- func compare_line_groups_by_words_self_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_words_self_overall(Group1, Group2) = Result :-
Words1 = words(Group1 ^ group_own),
Words2 = words(Group2 ^ group_own),
compare(Result, Words2, Words1).
:- func compare_line_groups_by_words_self_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_words_self_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
Words1 = words(Group1 ^ group_own),
Words2 = words(Group2 ^ group_own),
( if Calls1 = 0 then
WordsPerCall1 = 0.0
else
WordsPerCall1 = float(Words1) / float(Calls1)
),
( if Calls2 = 0 then
WordsPerCall2 = 0.0
else
WordsPerCall2 = float(Words2) / float(Calls2)
),
compare(Result, WordsPerCall2, WordsPerCall1).
:- func compare_line_groups_by_words_total_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_words_total_overall(Group1, Group2) = Result :-
Words1 = words(Group1 ^ group_own) + inherit_words(Group1 ^ group_desc),
Words2 = words(Group2 ^ group_own) + inherit_words(Group2 ^ group_desc),
compare(Result, Words2, Words1).
:- func compare_line_groups_by_words_total_percall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_words_total_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
Words1 = words(Group1 ^ group_own) + inherit_words(Group1 ^ group_desc),
Words2 = words(Group2 ^ group_own) + inherit_words(Group2 ^ group_desc),
( if Calls1 = 0 then
WordsPerCall1 = 0.0
else
WordsPerCall1 = float(Words1) / float(Calls1)
),
( if Calls2 = 0 then
WordsPerCall2 = 0.0
else
WordsPerCall2 = float(Words2) / float(Calls2)
),
compare(Result, WordsPerCall2, WordsPerCall1).
%---------------------------------------------------------------------------%
sum_line_group_measurements(LineGroups, Own, Desc) :-
list.foldl2(accumulate_line_group_measurements, LineGroups,
zero_own_prof_info, Own, zero_inherit_prof_info, Desc).
:- pred accumulate_line_group_measurements(line_group(FL, LL)::in,
own_prof_info::in, own_prof_info::out,
inherit_prof_info::in, inherit_prof_info::out) is det.
accumulate_line_group_measurements(LineGroup, Own0, Own, Desc0, Desc) :-
Own = add_own_to_own(Own0, LineGroup ^ group_own),
Desc = add_inherit_to_inherit(Desc0, LineGroup ^ group_desc).
%---------------------------------------------------------------------------%
:- end_module top_procs.
%---------------------------------------------------------------------------%