[m-rev.] deep profiler server enhancements
Zoltan Somogyi
zs at cs.mu.OZ.AU
Mon Jun 4 20:04:03 AEST 2001
These have built up in the queue while the original code was supposed to be
reviewed. Since the code in the deep_profiler directory had only a superficial
review, unless Tom has an objection, I will commit this tomorrow evening or
on wednesday. It has been tested, and Tom agrees on the parts I have discussed
with him.
Zoltan.
deep_profiler/read_profile.m:
Delete the ptr_info structure; it is not needed anymore.
deep_profiler/read_profile.m:
deep_profiler/io_combinator.m:
Separate out the I/O combinator part of read_profile.m into a new file.
deep_profiler/startup.m:
deep_profiler/canonical.m:
Separate out the part of startup.m that attempts to canonicalize call
graphs, and add code for merging call graphs from separate profiling
runs. This code is not yet complete.
deep_profiler/startup.m:
deep_profiler/callgraph.m:
Separate out the part of startup.m that generates the call graph
(whose cliques we compute), for use by the new file canonical.m,
and clean it up.
deep_profiler/array_util.m:
Make the names of the predicates more expressive.
Add a new utility predicate.
deep_profiler/interface.m:
deep_profiler/server.m:
Make the number of ancestor call sites displayed configurable.
deep_profiler/measurements.m:
Use a more compact representation for profiling information. This
change reduced the resident set size of the server in one case from
130 Mb to 110 Mb.
deep_profiler/profile.m:
Remove the redirection field, since that info is now stored in
separate, temporary arrays by canonical.m.
Clarify the documentation of the fields giving the sizes of arrays.
deep_profiler/server.m:
Output more structured HTML.
Make the format for times prettier.
deep_profiler/notes/deep_profilint.html:
Document the new modules.
cvs diff: Diffing .
Index: array_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/array_util.m,v
retrieving revision 1.1
diff -u -b -r1.1 array_util.m
--- array_util.m 2001/05/31 05:59:57 1.1
+++ array_util.m 2001/06/01 11:31:11
@@ -14,36 +14,53 @@
:- import_module array, list.
+ % Perform a mode cast on the given array, making the compiler believe
+ % that the ground array is unique. Should be used only if the only use
+ % of the old value is as input to the upcoming destructive operation
+ % that needs the array to be unique. Otherwise, calling this function
+ % is dangerous.
:- func u(T) = T.
:- mode (u(in) = array_uo) is det.
-:- pred array_foldl(pred(int, T, U, U), array(T), U, U).
-:- mode array_foldl(pred(in, in, di, uo) is det, in, di, uo) is det.
-:- mode array_foldl(pred(in, in, array_di, array_uo) is det, in,
+ % Performs a foldl on all the elements of the given array,
+ % starting at index 1.
+:- pred array_foldl_from_1(pred(int, T, U, U), array(T), U, U).
+:- mode array_foldl_from_1(pred(in, in, di, uo) is det, in, di, uo) is det.
+:- mode array_foldl_from_1(pred(in, in, array_di, array_uo) is det, in,
array_di, array_uo) is det.
-:- mode array_foldl(pred(in, in, in, out) is det, in, in, out) is det.
+:- mode array_foldl_from_1(pred(in, in, in, out) is det, in, in, out) is det.
-:- pred array_foldl0(pred(int, T, U, U), array(T), U, U).
-:- mode array_foldl0(pred(in, in, di, uo) is det, in, di, uo) is det.
-:- mode array_foldl0(pred(in, in, array_di, array_uo) is det, in,
+ % Performs a foldl on all the elements of the given array,
+ % starting at index 0.
+:- pred array_foldl_from_0(pred(int, T, U, U), array(T), U, U).
+:- mode array_foldl_from_0(pred(in, in, di, uo) is det, in, di, uo) is det.
+:- mode array_foldl_from_0(pred(in, in, array_di, array_uo) is det, in,
array_di, array_uo) is det.
-:- mode array_foldl0(pred(in, in, in, out) is det, in, in, out) is det.
+:- mode array_foldl_from_0(pred(in, in, in, out) is det, in, in, out) is det.
+ % Performs a foldl on all the elements of the given array
+ % between the two index values given by the first two arguments,
+ % both inclusive.
:- pred array_foldl(int, int, pred(int, T, U, U), array(T), U, U).
:- mode array_foldl(in, in, pred(in, in, di, uo) is det, in, di, uo) is det.
:- mode array_foldl(in, in, pred(in, in, array_di, array_uo) is det, in,
array_di, array_uo) is det.
:- mode array_foldl(in, in, pred(in, in, in, out) is det, in, in, out) is det.
-:- pred array_foldl2(pred(int, T, U, U, V, V), array(T), U, U, V, V).
-:- mode array_foldl2(pred(in, in, di, uo, di, uo) is det, in, di, uo, di, uo)
- is det.
-:- mode array_foldl2(pred(in, in, array_di, array_uo, array_di, array_uo)
- is det, in, array_di, array_uo, array_di, array_uo)
- is det.
-:- mode array_foldl2(pred(in, in, in, out, di, uo) is det, in, in, out, di, uo)
- is det.
-
+ % Performs a foldl2 on all the elements of the given array,
+ % starting at index 1.
+:- pred array_foldl2_from_1(pred(int, T, U, U, V, V), array(T), U, U, V, V).
+:- mode array_foldl2_from_1(pred(in, in, di, uo, di, uo) is det,
+ in, di, uo, di, uo) is det.
+:- mode array_foldl2_from_1(pred(in, in, array_di, array_uo,
+ array_di, array_uo) is det,
+ in, array_di, array_uo, array_di, array_uo) is det.
+:- mode array_foldl2_from_1(pred(in, in, in, out, di, uo) is det,
+ in, in, out, di, uo) is det.
+
+ % Performs a foldl2 on all the elements of the given array
+ % between the two index values given by the first two arguments,
+ % both inclusive.
:- pred array_foldl2(int, int, pred(int, T, U, U, V, V), array(T), U, U, V, V).
:- mode array_foldl2(in, in, pred(in, in, di, uo, di, uo) is det, in,
di, uo, di, uo) is det.
@@ -53,16 +70,30 @@
:- mode array_foldl2(in, in, pred(in, in, in, out, di, uo) is det, in,
in, out, di, uo) is det.
+ % Performs the same computation as list__foldl; the only difference
+ % is that the accumulator is an array and has an array mode.
:- pred array_list_foldl(pred(T, array(U), array(U)), list(T),
array(U), array(U)).
:- mode array_list_foldl(pred(in, array_di, array_uo) is det, in,
array_di, array_uo) is det.
+ % Performs the same computation as list__foldl2; the only difference
+ % is that the accumulators are arrays and have array modes.
:- pred array_list_foldl2(pred(T, array(U), array(U), array(V), array(V)),
list(T), array(U), array(U), array(V), array(V)).
:- mode array_list_foldl2(pred(in, array_di, array_uo, array_di, array_uo)
is det, in, array_di, array_uo, array_di, array_uo) is det.
+ % Performs a map on all the elements of the given array,
+ % starting at index 0.
+:- pred array_map_from_0(pred(T, T), array(T), array(T)).
+:- mode array_map_from_0(pred(in, out) is det, array_di, array_uo) is det.
+
+ % Performs a map on all the elements of the given array,
+ % starting at index 1.
+:- pred array_map_from_1(pred(T, T), array(T), array(T)).
+:- mode array_map_from_1(pred(in, out) is det, array_di, array_uo) is det.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -74,11 +105,11 @@
"B = A;"
).
-array_foldl(P, A, U0, U) :-
+array_foldl_from_1(P, A, U0, U) :-
array__max(A, Max),
array_foldl(1, Max, P, A, U0, U).
-array_foldl0(P, A, U0, U) :-
+array_foldl_from_0(P, A, U0, U) :-
array__max(A, Max),
array_foldl(0, Max, P, A, U0, U).
@@ -91,7 +122,7 @@
U = U0
).
-array_foldl2(P, A, U0, U, V0, V) :-
+array_foldl2_from_1(P, A, U0, U, V0, V) :-
array__max(A, Max),
array_foldl2(1, Max, P, A, U0, U, V0, V).
@@ -114,3 +145,24 @@
array_list_foldl2(P, [X | Xs], AccU0, AccU, AccV0, AccV) :-
call(P, X, AccU0, AccU1, AccV0, AccV1),
array_list_foldl2(P, Xs, AccU1, AccU, AccV1, AccV).
+
+array_map_from_0(P, U0, U) :-
+ array__max(U0, Max),
+ array_map(0, Max, P, U0, U).
+
+array_map_from_1(P, U0, U) :-
+ array__max(U0, Max),
+ array_map(1, Max, P, U0, U).
+
+:- pred array_map(int, int, pred(T, T), array(T), array(T)).
+:- mode array_map(in, in, pred(in, out) is det, array_di, array_uo) is det.
+
+array_map(N, Size, Closure, Array0, Array) :-
+ ( N >= Size ->
+ Array = Array0
+ ;
+ array__lookup(Array0, N, OldElem),
+ Closure(OldElem, NewElem),
+ array__set(Array0, N, NewElem, Array1),
+ array_map(N + 1, Size, Closure, Array1, Array)
+ ).
Index: canonical.m
===================================================================
RCS file: canonical.m
diff -N canonical.m
--- /dev/null Fri Dec 1 02:25:58 2000
+++ canonical.m Mon Jun 4 19:42:03 2001
@@ -0,0 +1,980 @@
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2001 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 module contains code for recursively merging sets of ProcDynamic and
+% CallSiteDynamic nodes.
+
+:- module merge.
+
+:- interface.
+
+:- import_module profile.
+
+:- pred canonicalize_cliques(initial_deep::in, initial_deep::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module measurements, callgraph, array_util.
+:- import_module unsafe, io.
+:- import_module std_util, bool, int, array, list, map, set, require.
+
+:- type merge_info
+ ---> merge_info(
+ merge_clique_members :: array(list(proc_dynamic_ptr)),
+ merge_clique_index :: array(clique_ptr)
+ ).
+
+:- type redirect
+ ---> redirect(
+ csd_redirect :: array(call_site_dynamic_ptr),
+ % index: call_site_dynamic_ptr
+ pd_redirect :: array(proc_dynamic_ptr)
+ % index: proc_dynamic_ptr
+ ).
+
+canonicalize_cliques(InitDeep0, InitDeep) :-
+ MaxCSDs = array__max(InitDeep0 ^ init_call_site_dynamics),
+ MaxPDs = array__max(InitDeep0 ^ init_proc_dynamics),
+ NumCSDs = MaxCSDs + 1,
+ NumPDs = MaxPDs + 1,
+
+ find_cliques(InitDeep0, CliqueList),
+ make_clique_indexes(NumPDs, CliqueList, Cliques, CliqueIndex),
+ MergeInfo = merge_info(Cliques, CliqueIndex),
+
+ CSDRedirect0 = array__init(NumCSDs, call_site_dynamic_ptr(0)),
+ PDRedirect0 = array__init(NumPDs, proc_dynamic_ptr(0)),
+ Redirect0 = redirect(CSDRedirect0, PDRedirect0),
+ merge_cliques(CliqueList, MergeInfo, InitDeep0, Redirect0,
+ InitDeep1, Redirect1),
+ compact_dynamics(InitDeep1, Redirect1, NumCSDs, NumPDs, InitDeep).
+
+:- pred merge_cliques(list(list(proc_dynamic_ptr))::in,
+ merge_info::in, initial_deep::in, redirect::in,
+ initial_deep::out, redirect::out) is det.
+
+merge_cliques([], _, InitDeep, Redirect, InitDeep, Redirect).
+merge_cliques([Clique | Cliques], MergeInfo, InitDeep0, Redirect0,
+ InitDeep, Redirect) :-
+ merge_clique(Clique, MergeInfo, InitDeep0, Redirect0,
+ InitDeep1, Redirect1),
+ merge_cliques(Cliques, MergeInfo, InitDeep1, Redirect1,
+ InitDeep, Redirect).
+
+:- pred merge_clique(list(proc_dynamic_ptr)::in,
+ merge_info::in, initial_deep::in, redirect::in,
+ initial_deep::out, redirect::out) is det.
+
+merge_clique(CliquePDs, MergeInfo, InitDeep0, Redirect0, InitDeep, Redirect) :-
+ % find set of proc_statics in the CliquePDs
+ % for all (first order) calls in CliquePDs, if call is to a procedure
+ % that CliquePDs contains a call to, add its PD to the set
+
+ map__init(ProcMap0),
+ set__list_to_set(CliquePDs, Clique),
+ list__foldl(cluster_pds_by_ps(InitDeep0), CliquePDs,
+ ProcMap0, ProcMap),
+ map__values(ProcMap, PDsList),
+ list__filter(two_or_more, PDsList, ToMergePDsList),
+ list__foldl2(merge_proc_dynamics(MergeInfo, Clique),
+ ToMergePDsList, InitDeep0, InitDeep, Redirect0, Redirect).
+
+:- pred merge_proc_dynamics(merge_info::in, set(proc_dynamic_ptr)::in,
+ list(proc_dynamic_ptr)::in, proc_dynamic_ptr::out,
+ initial_deep::in, initial_deep::out, redirect::in, redirect::out)
+ is det.
+
+merge_proc_dynamics(MergeInfo, Clique, CandidatePDPtrs, ChosenPDPtr,
+ InitDeep0, InitDeep, Redirect0, Redirect) :-
+ ProcDynamics0 = InitDeep0 ^ init_proc_dynamics,
+ list__filter(valid_proc_dynamic_ptr_raw(ProcDynamics0),
+ CandidatePDPtrs, ValidPDPtrs),
+ ( ValidPDPtrs = [PrimePDPtr | RestPDPtrs] ->
+ record_pd_redirect(RestPDPtrs, PrimePDPtr,
+ Redirect0, Redirect1),
+ lookup_proc_dynamics(ProcDynamics0, PrimePDPtr, PrimePD0),
+ list__map(lookup_proc_dynamics(ProcDynamics0),
+ RestPDPtrs, RestPDs),
+ list__map(extract_pd_sites, RestPDs, RestSites),
+ PrimeSites0 = PrimePD0 ^ pd_sites,
+ array__max(PrimeSites0, MaxSiteNum),
+ merge_proc_dynamic_slots(MergeInfo, MaxSiteNum, Clique,
+ PrimePDPtr, u(PrimeSites0), RestSites, PrimeSites,
+ InitDeep0, InitDeep1, Redirect1, Redirect),
+ PrimePD = PrimePD0 ^ pd_sites := PrimeSites,
+ ProcDynamics1 = InitDeep1 ^ init_proc_dynamics,
+ update_proc_dynamics(u(ProcDynamics1), PrimePDPtr, PrimePD,
+ ProcDynamics),
+ InitDeep = InitDeep1 ^ init_proc_dynamics := ProcDynamics,
+ ChosenPDPtr = PrimePDPtr
+ ;
+ % This can happen when merging the callees of CSDs
+ % representing special calls.
+ ChosenPDPtr = proc_dynamic_ptr(0),
+ InitDeep = InitDeep0,
+ Redirect = Redirect0
+ ).
+
+:- pred merge_proc_dynamic_slots(merge_info::in, int::in,
+ set(proc_dynamic_ptr)::in, proc_dynamic_ptr::in,
+ array(call_site_array_slot)::array_di,
+ list(array(call_site_array_slot))::in,
+ array(call_site_array_slot)::array_uo,
+ initial_deep::in, initial_deep::out, redirect::in, redirect::out)
+ is det.
+
+merge_proc_dynamic_slots(MergeInfo, SlotNum, Clique, PrimePDPtr,
+ PrimeSiteArray0, RestSiteArrays, PrimeSiteArray,
+ InitDeep0, InitDeep, Redirect0, Redirect) :-
+ ( SlotNum >= 0 ->
+ array__lookup(PrimeSiteArray0, SlotNum, PrimeSite0),
+ (
+ PrimeSite0 = normal(PrimeCSDPtr0),
+ merge_proc_dynamic_normal_slot(MergeInfo, SlotNum,
+ Clique, PrimePDPtr, PrimeCSDPtr0,
+ RestSiteArrays, PrimeCSDPtr,
+ InitDeep0, InitDeep1, Redirect0, Redirect1),
+ array__set(PrimeSiteArray0, SlotNum,
+ normal(PrimeCSDPtr), PrimeSiteArray1)
+ ;
+ PrimeSite0 = multi(PrimeCSDPtrArray0),
+ array__to_list(PrimeCSDPtrArray0, PrimeCSDPtrList0),
+ merge_proc_dynamic_multi_slot(MergeInfo, SlotNum,
+ Clique, PrimePDPtr, PrimeCSDPtrList0,
+ RestSiteArrays, PrimeCSDPtrList,
+ InitDeep0, InitDeep1, Redirect0, Redirect1),
+ PrimeCSDPtrArray = array(PrimeCSDPtrList),
+ array__set(PrimeSiteArray0, SlotNum,
+ multi(PrimeCSDPtrArray), PrimeSiteArray1)
+ ),
+ merge_proc_dynamic_slots(MergeInfo, SlotNum - 1, Clique,
+ PrimePDPtr, PrimeSiteArray1, RestSiteArrays,
+ PrimeSiteArray, InitDeep1, InitDeep,
+ Redirect1, Redirect)
+ ;
+ PrimeSiteArray = PrimeSiteArray0,
+ InitDeep = InitDeep0,
+ Redirect = Redirect0
+ ).
+
+:- pred merge_proc_dynamic_normal_slot(merge_info::in, int::in,
+ set(proc_dynamic_ptr)::in, proc_dynamic_ptr::in,
+ call_site_dynamic_ptr::in, list(array(call_site_array_slot))::in,
+ call_site_dynamic_ptr::out, initial_deep::in, initial_deep::out,
+ redirect::in, redirect::out) is det.
+
+merge_proc_dynamic_normal_slot(MergeInfo, SlotNum, Clique,
+ PrimePDPtr, PrimeCSDPtr0, RestSiteArrays, PrimeCSDPtr,
+ InitDeep0, InitDeep, Redirect0, Redirect) :-
+ lookup_normal_sites(RestSiteArrays, SlotNum, RestCSDPtrs),
+ merge_call_site_dynamics(MergeInfo, Clique, PrimePDPtr,
+ [PrimeCSDPtr0 | RestCSDPtrs], PrimeCSDPtr,
+ InitDeep0, InitDeep, Redirect0, Redirect).
+
+:- pred accumulate_csd_owns(call_site_dynamic::in,
+ own_prof_info::in, own_prof_info::out) is det.
+
+accumulate_csd_owns(CSD, Own0, Own) :-
+ Own = add_own_to_own(Own0, CSD ^ csd_own_prof).
+
+:- pred callee_in_clique(initial_deep::in, set(proc_dynamic_ptr)::in,
+ call_site_dynamic_ptr::in) is semidet.
+
+callee_in_clique(InitDeep, Clique, CSDPtr) :-
+ lookup_call_site_dynamics(InitDeep ^ init_call_site_dynamics,
+ CSDPtr, CSD),
+ CalleePDPtr = CSD ^ csd_callee,
+ set__member(CalleePDPtr, Clique).
+
+:- pred merge_proc_dynamic_multi_slot(merge_info::in, int::in,
+ set(proc_dynamic_ptr)::in, proc_dynamic_ptr::in,
+ list(call_site_dynamic_ptr)::in, list(array(call_site_array_slot))::in,
+ list(call_site_dynamic_ptr)::out, initial_deep::in, initial_deep::out,
+ redirect::in, redirect::out) is det.
+
+merge_proc_dynamic_multi_slot(MergeInfo, SlotNum, Clique,
+ ParentPDPtr, PrimeCSDPtrs0, RestSiteArrays, PrimeCSDPtrs,
+ InitDeep0, InitDeep, Redirect0, Redirect) :-
+ lookup_multi_sites(RestSiteArrays, SlotNum, RestCSDPtrLists),
+ list__condense([PrimeCSDPtrs0 | RestCSDPtrLists], AllCSDPtrs),
+ map__init(ProcMap0),
+ list__foldl(cluster_csds_by_ps(InitDeep0), AllCSDPtrs,
+ ProcMap0, ProcMap),
+ map__values(ProcMap, CSDPtrsClusters),
+ list__foldl3(merge_multi_slot_cluster(MergeInfo, ParentPDPtr, Clique),
+ CSDPtrsClusters, [], PrimeCSDPtrs, InitDeep0, InitDeep,
+ Redirect0, Redirect).
+
+:- pred merge_multi_slot_cluster(merge_info::in, proc_dynamic_ptr::in,
+ set(proc_dynamic_ptr)::in, list(call_site_dynamic_ptr)::in,
+ list(call_site_dynamic_ptr)::in, list(call_site_dynamic_ptr)::out,
+ initial_deep::in, initial_deep::out, redirect::in, redirect::out)
+ is det.
+
+merge_multi_slot_cluster(MergeInfo, ParentPDPtr, Clique, ClusterCSDPtrs,
+ PrimeCSDPtrs0, PrimeCSDPtrs, InitDeep0, InitDeep,
+ Redirect0, Redirect) :-
+ merge_call_site_dynamics(MergeInfo, Clique,
+ ParentPDPtr, ClusterCSDPtrs, PrimeCSDPtr,
+ InitDeep0, InitDeep, Redirect0, Redirect),
+ PrimeCSDPtrs = [PrimeCSDPtr | PrimeCSDPtrs0].
+
+:- pred merge_call_site_dynamics(merge_info::in, set(proc_dynamic_ptr)::in,
+ proc_dynamic_ptr::in, list(call_site_dynamic_ptr)::in,
+ call_site_dynamic_ptr::out, initial_deep::in, initial_deep::out,
+ redirect::in, redirect::out) is det.
+
+merge_call_site_dynamics(MergeInfo, Clique, ParentPDPtr, CandidateCSDPtrs,
+ ChosenCSDPtr, InitDeep0, InitDeep, Redirect0, Redirect) :-
+ CallSiteDynamics0 = InitDeep0 ^ init_call_site_dynamics,
+ list__filter(valid_call_site_dynamic_ptr_raw(CallSiteDynamics0),
+ CandidateCSDPtrs, ValidCSDPtrs),
+ (
+ ValidCSDPtrs = [],
+ % This signifies that there is no call here.
+ ChosenCSDPtr = call_site_dynamic_ptr(0),
+ InitDeep = InitDeep0,
+ Redirect = Redirect0
+ ;
+ ValidCSDPtrs = [FirstCSDPtr | LaterCSDPtrs],
+ lookup_call_site_dynamics(CallSiteDynamics0, FirstCSDPtr,
+ FirstCSD0),
+ FirstCSD = FirstCSD0 ^ csd_caller := ParentPDPtr,
+ update_call_site_dynamics(u(CallSiteDynamics0), FirstCSDPtr,
+ FirstCSD, CallSiteDynamics),
+ InitDeep1 = InitDeep0 ^ init_call_site_dynamics
+ := CallSiteDynamics,
+ (
+ LaterCSDPtrs = [],
+ InitDeep = InitDeep1,
+ Redirect = Redirect0
+ ;
+ LaterCSDPtrs = [_ | _],
+ merge_call_site_dynamics_2(MergeInfo, Clique,
+ FirstCSDPtr, LaterCSDPtrs, InitDeep1, InitDeep,
+ Redirect0, Redirect)
+ ),
+ ChosenCSDPtr = FirstCSDPtr
+ ).
+
+:- pred merge_call_site_dynamics_2(merge_info::in, set(proc_dynamic_ptr)::in,
+ call_site_dynamic_ptr::in, list(call_site_dynamic_ptr)::in,
+ initial_deep::in, initial_deep::out, redirect::in, redirect::out)
+ is det.
+
+merge_call_site_dynamics_2(MergeInfo, Clique, PrimeCSDPtr, RestCSDPtrs,
+ InitDeep0, InitDeep, Redirect0, Redirect) :-
+ % We must check whether PrimeCSDPtr and RestCSDPtrs are in Clique
+ % *before* we update the proc_dynamics array in InitDeep0, which is
+ % destructive updated to create InitDeep1.
+ list__filter(callee_in_clique(InitDeep0, Clique), RestCSDPtrs,
+ InClique, NotInClique),
+ % XXX design error: should take union of cliques
+ % i.e. if call is within clique in *any* caller, it should be within
+ % clique in the final configuration
+ ( callee_in_clique(InitDeep0, Clique, PrimeCSDPtr) ->
+ require(unify(NotInClique, []),
+ "merge_proc_dynamic_normal_slot: prime in clique, others not in clique"),
+ MergeChildren = no
+ ;
+ require(unify(InClique, []),
+ "merge_proc_dynamic_normal_slot: prime not in clique, others in clique"),
+ MergeChildren = yes
+ ),
+ record_csd_redirect(RestCSDPtrs, PrimeCSDPtr, Redirect0, Redirect1),
+ CallSiteDynamics0 = InitDeep0 ^ init_call_site_dynamics,
+ lookup_call_site_dynamics(CallSiteDynamics0, PrimeCSDPtr, PrimeCSD0),
+ list__map(lookup_call_site_dynamics(CallSiteDynamics0),
+ RestCSDPtrs, RestCSDs),
+ PrimeOwn0 = PrimeCSD0 ^ csd_own_prof,
+ list__foldl(accumulate_csd_owns, RestCSDs, PrimeOwn0, PrimeOwn1),
+ PrimeCSD1 = PrimeCSD0 ^ csd_own_prof := PrimeOwn1,
+ update_call_site_dynamics(u(CallSiteDynamics0), PrimeCSDPtr, PrimeCSD1,
+ CallSiteDynamics1),
+ InitDeep1 = InitDeep0 ^ init_call_site_dynamics := CallSiteDynamics1,
+ (
+ MergeChildren = no,
+ InitDeep = InitDeep1,
+ Redirect = Redirect1
+ ;
+ MergeChildren = yes,
+ merge_call_site_dynamics_descendants(MergeInfo,
+ PrimeCSDPtr, RestCSDPtrs, ChosenPDPtr,
+ InitDeep1, InitDeep2, Redirect1, Redirect),
+ % We must ensure that PrimeCSDPtr ^ csd_callee
+ % is updated to reflect the chosen merged ProcDynamic.
+ CallSiteDynamics2 = InitDeep2 ^ init_call_site_dynamics,
+ lookup_call_site_dynamics(CallSiteDynamics2, PrimeCSDPtr,
+ PrimeCSD2),
+ PrimeCSD = PrimeCSD2 ^ csd_callee := ChosenPDPtr,
+ update_call_site_dynamics(u(CallSiteDynamics2),
+ PrimeCSDPtr, PrimeCSD, CallSiteDynamics),
+ InitDeep = InitDeep2 ^ init_call_site_dynamics
+ := CallSiteDynamics
+ ).
+
+:- pred merge_call_site_dynamics_descendants(merge_info::in,
+ call_site_dynamic_ptr::in, list(call_site_dynamic_ptr)::in,
+ proc_dynamic_ptr::out, initial_deep::in, initial_deep::out,
+ redirect::in, redirect::out) is det.
+
+merge_call_site_dynamics_descendants(MergeInfo, PrimeCSDPtr, RestCSDPtrs,
+ ChosenPDPtr, InitDeep0, InitDeep, Redirect0, Redirect) :-
+ CallSiteDynamics = InitDeep0 ^ init_call_site_dynamics,
+ lookup_call_site_dynamics(CallSiteDynamics, PrimeCSDPtr, PrimeCSD),
+ extract_csd_callee(PrimeCSD, PrimeCSDCallee),
+ list__map(lookup_call_site_dynamics(CallSiteDynamics),
+ RestCSDPtrs, RestCSDs),
+ list__map(extract_csd_callee, RestCSDs, RestCSDCallees),
+ PDPtrs = [PrimeCSDCallee | RestCSDCallees],
+ list__foldl(union_cliques(MergeInfo), PDPtrs, set__init, CliqueUnion),
+ merge_proc_dynamics(MergeInfo, CliqueUnion, PDPtrs, ChosenPDPtr,
+ InitDeep0, InitDeep, Redirect0, Redirect).
+
+:- pred union_cliques(merge_info::in, proc_dynamic_ptr::in,
+ set(proc_dynamic_ptr)::in, set(proc_dynamic_ptr)::out) is det.
+
+union_cliques(MergeInfo, PDPtr, CliqueUnion0, CliqueUnion) :-
+ ( PDPtr = proc_dynamic_ptr(0) ->
+ % This can happen with calls to the unify/compare preds
+ % of builtin types.
+ CliqueUnion = CliqueUnion0
+ ;
+ lookup_clique_index(MergeInfo ^ merge_clique_index, PDPtr,
+ CliquePtr),
+ lookup_clique_members(MergeInfo ^ merge_clique_members,
+ CliquePtr, Members),
+ set__insert_list(CliqueUnion0, Members, CliqueUnion)
+ ).
+
+:- pred lookup_normal_sites(list(array(call_site_array_slot))::in, int::in,
+ list(call_site_dynamic_ptr)::out) is det.
+
+lookup_normal_sites([], _, []).
+lookup_normal_sites([RestArray | RestArrays], SlotNum, [CSDPtr | CSDPtrs]) :-
+ array__lookup(RestArray, SlotNum, Slot),
+ (
+ Slot = normal(CSDPtr)
+ ;
+ Slot = multi(_),
+ error("lookup_normal_sites: found multi")
+ ),
+ lookup_normal_sites(RestArrays, SlotNum, CSDPtrs).
+
+:- pred lookup_multi_sites(list(array(call_site_array_slot))::in, int::in,
+ list(list(call_site_dynamic_ptr))::out) is det.
+
+lookup_multi_sites([], _, []).
+lookup_multi_sites([RestArray | RestArrays], SlotNum, [CSDList | CSDLists]) :-
+ array__lookup(RestArray, SlotNum, Slot),
+ (
+ Slot = normal(_),
+ error("lookup_multi_sites: found normal")
+ ;
+ Slot = multi(CSDArray),
+ array__to_list(CSDArray, CSDList)
+ ),
+ lookup_multi_sites(RestArrays, SlotNum, CSDLists).
+
+:- pragma promise_pure(record_pd_redirect/4).
+:- pred record_pd_redirect(list(proc_dynamic_ptr)::in, proc_dynamic_ptr::in,
+ redirect::in, redirect::out) is det.
+
+record_pd_redirect(RestPDPtrs, PrimePDPtr, Redirect0, Redirect) :-
+ impure unsafe_perform_io(io__write_string("pd redirect: ")),
+ impure unsafe_perform_io(io__print(RestPDPtrs)),
+ impure unsafe_perform_io(io__write_string(" -> ")),
+ impure unsafe_perform_io(io__print(PrimePDPtr)),
+ impure unsafe_perform_io(io__nl),
+ lookup_pd_redirect(Redirect0 ^ pd_redirect, PrimePDPtr, OldRedirect),
+ ( OldRedirect = proc_dynamic_ptr(0) ->
+ record_pd_redirect_2(RestPDPtrs, PrimePDPtr,
+ Redirect0, Redirect)
+ ;
+ error("record_pd_redirect: prime is redirected")
+ ).
+
+:- pred record_pd_redirect_2(list(proc_dynamic_ptr)::in, proc_dynamic_ptr::in,
+ redirect::in, redirect::out) is det.
+
+record_pd_redirect_2([], _, Redirect, Redirect).
+record_pd_redirect_2([RestPDPtr | RestPDPtrs], PrimePDPtr,
+ Redirect0, Redirect) :-
+ ProcRedirect0 = Redirect0 ^ pd_redirect,
+ lookup_pd_redirect(ProcRedirect0, RestPDPtr, OldRedirect),
+ ( OldRedirect = proc_dynamic_ptr(0) ->
+ set_pd_redirect(u(ProcRedirect0), RestPDPtr, PrimePDPtr,
+ ProcRedirect)
+ ;
+ error("record_pd_redirect_2: already redirected")
+ ),
+ Redirect1 = Redirect0 ^ pd_redirect := ProcRedirect,
+ record_pd_redirect_2(RestPDPtrs, PrimePDPtr, Redirect1, Redirect).
+
+:- pragma promise_pure(record_csd_redirect/4).
+:- pred record_csd_redirect(list(call_site_dynamic_ptr)::in,
+ call_site_dynamic_ptr::in, redirect::in, redirect::out) is det.
+
+record_csd_redirect(RestCSDPtrs, PrimeCSDPtr, Redirect0, Redirect) :-
+ impure unsafe_perform_io(io__write_string("csd redirect: ")),
+ impure unsafe_perform_io(io__print(RestCSDPtrs)),
+ impure unsafe_perform_io(io__write_string(" -> ")),
+ impure unsafe_perform_io(io__print(PrimeCSDPtr)),
+ impure unsafe_perform_io(io__nl),
+ lookup_csd_redirect(Redirect0 ^ csd_redirect, PrimeCSDPtr, OldRedirect),
+ ( OldRedirect = call_site_dynamic_ptr(0) ->
+ record_csd_redirect_2(RestCSDPtrs, PrimeCSDPtr,
+ Redirect0, Redirect)
+ ;
+ error("record_pd_redirect: prime is redirected")
+ ).
+
+:- pred record_csd_redirect_2(list(call_site_dynamic_ptr)::in,
+ call_site_dynamic_ptr::in, redirect::in, redirect::out) is det.
+
+record_csd_redirect_2([], _, Redirect, Redirect).
+record_csd_redirect_2([RestCSDPtr | RestCSDPtrs], PrimeCSDPtr,
+ Redirect0, Redirect) :-
+ CallSiteRedirect0 = Redirect0 ^ csd_redirect,
+ lookup_csd_redirect(CallSiteRedirect0, RestCSDPtr, OldRedirect),
+ ( OldRedirect = call_site_dynamic_ptr(0) ->
+ set_csd_redirect(u(CallSiteRedirect0), RestCSDPtr, PrimeCSDPtr,
+ CallSiteRedirect)
+ ;
+ error("record_csd_redirect_2: already redirected")
+ ),
+ Redirect1 = Redirect0 ^ csd_redirect := CallSiteRedirect,
+ record_csd_redirect_2(RestCSDPtrs, PrimeCSDPtr, Redirect1, Redirect).
+
+:- pred extract_pd_sites(proc_dynamic::in, array(call_site_array_slot)::out)
+ is det.
+
+extract_pd_sites(PD, PD ^ pd_sites).
+
+:- pred extract_csd_callee(call_site_dynamic::in, proc_dynamic_ptr::out)
+ is det.
+
+extract_csd_callee(CSD, CSD ^ csd_callee).
+
+:- pred two_or_more(list(proc_dynamic_ptr)::in) is semidet.
+
+two_or_more([_, _ | _]).
+
+:- pred cluster_pds_by_ps(initial_deep::in, proc_dynamic_ptr::in,
+ map(proc_static_ptr, list(proc_dynamic_ptr))::in,
+ map(proc_static_ptr, list(proc_dynamic_ptr))::out) is det.
+
+cluster_pds_by_ps(InitDeep, PDPtr, ProcMap0, ProcMap) :-
+ ProcDynamics = InitDeep ^ init_proc_dynamics,
+ ( valid_proc_dynamic_ptr_raw(ProcDynamics, PDPtr) ->
+ lookup_proc_dynamics(ProcDynamics, PDPtr, PD),
+ PSPtr = PD ^ pd_proc_static,
+ ( map__search(ProcMap0, PSPtr, PDPtrs0) ->
+ map__det_update(ProcMap0, PSPtr, [PDPtr | PDPtrs0],
+ ProcMap)
+ ;
+ map__det_insert(ProcMap0, PSPtr, [PDPtr], ProcMap)
+ )
+ ;
+ ProcMap = ProcMap0
+ ).
+
+:- pred cluster_csds_by_ps(initial_deep::in, call_site_dynamic_ptr::in,
+ map(proc_static_ptr, list(call_site_dynamic_ptr))::in,
+ map(proc_static_ptr, list(call_site_dynamic_ptr))::out) is det.
+
+cluster_csds_by_ps(InitDeep, CSDPtr, ProcMap0, ProcMap) :-
+ CallSiteDynamics = InitDeep ^ init_call_site_dynamics,
+ ( valid_call_site_dynamic_ptr_raw(CallSiteDynamics, CSDPtr) ->
+ lookup_call_site_dynamics(CallSiteDynamics, CSDPtr, CSD),
+ PDPtr = CSD ^ csd_callee,
+ ProcDynamics = InitDeep ^ init_proc_dynamics,
+ ( valid_proc_dynamic_ptr_raw(ProcDynamics, PDPtr) ->
+ lookup_proc_dynamics(ProcDynamics, PDPtr, PD),
+ PSPtr = PD ^ pd_proc_static
+ ;
+ PSPtr = proc_static_ptr(0)
+ ),
+ ( map__search(ProcMap0, PSPtr, CSDPtrs0) ->
+ map__det_update(ProcMap0, PSPtr, [CSDPtr | CSDPtrs0],
+ ProcMap)
+ ;
+ map__det_insert(ProcMap0, PSPtr, [CSDPtr], ProcMap)
+ )
+ ;
+ ProcMap = ProcMap0
+ ).
+
+:- pred lookup_pd_redirect(array(proc_dynamic_ptr)::in,
+ proc_dynamic_ptr::in, proc_dynamic_ptr::out) is det.
+
+lookup_pd_redirect(ProcRedirect0, PDPtr, OldRedirect) :-
+ PDPtr = proc_dynamic_ptr(PDI),
+ array__lookup(ProcRedirect0, PDI, OldRedirect).
+
+:- pred set_pd_redirect(array(proc_dynamic_ptr)::array_di,
+ proc_dynamic_ptr::in, proc_dynamic_ptr::in,
+ array(proc_dynamic_ptr)::array_uo) is det.
+
+set_pd_redirect(ProcRedirect0, PDPtr, NewRedirect, ProcRedirect) :-
+ PDPtr = proc_dynamic_ptr(PDI),
+ array__set(ProcRedirect0, PDI, NewRedirect, ProcRedirect).
+
+:- pred lookup_csd_redirect(array(call_site_dynamic_ptr)::in,
+ call_site_dynamic_ptr::in, call_site_dynamic_ptr::out) is det.
+
+lookup_csd_redirect(CallSiteRedirect0, CSDPtr, OldRedirect) :-
+ CSDPtr = call_site_dynamic_ptr(CSDI),
+ array__lookup(CallSiteRedirect0, CSDI, OldRedirect).
+
+:- pred set_csd_redirect(array(call_site_dynamic_ptr)::array_di,
+ call_site_dynamic_ptr::in, call_site_dynamic_ptr::in,
+ array(call_site_dynamic_ptr)::array_uo) is det.
+
+set_csd_redirect(CallSiteRedirect0, CSDPtr, NewRedirect, CallSiteRedirect) :-
+ CSDPtr = call_site_dynamic_ptr(CSDI),
+ array__set(CallSiteRedirect0, CSDI, NewRedirect, CallSiteRedirect).
+
+%-----------------------------------------------------------------------------%
+
+:- pred deref_call_site_dynamic(redirect::in, call_site_dynamic_ptr::in,
+ call_site_dynamic_ptr::out) is det.
+
+deref_call_site_dynamic(Redirect, CSDPtr0, CSDPtr) :-
+ lookup_csd_redirect(Redirect ^ csd_redirect, CSDPtr0, RedirectCSDPtr),
+ RedirectCSDPtr = call_site_dynamic_ptr(RedirectCSDI),
+ ( RedirectCSDI > 0 ->
+ deref_call_site_dynamic(Redirect, RedirectCSDPtr, CSDPtr)
+ ;
+ CSDPtr = CSDPtr0
+ ).
+
+:- pred deref_proc_dynamic(redirect::in, proc_dynamic_ptr::in,
+ proc_dynamic_ptr::out) is det.
+
+deref_proc_dynamic(Redirect, PDPtr0, PDPtr) :-
+ lookup_pd_redirect(Redirect ^ pd_redirect, PDPtr0, RedirectPDPtr),
+ RedirectPDPtr = proc_dynamic_ptr(RedirectPDI),
+ ( RedirectPDI > 0 ->
+ deref_proc_dynamic(Redirect, RedirectPDPtr, PDPtr)
+ ;
+ PDPtr = PDPtr0
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred compact_dynamics(initial_deep::in, redirect::in, int::in, int::in,
+ initial_deep::out) is det.
+
+compact_dynamics(InitDeep0, Redirect0, MaxCSD0, MaxPD0, InitDeep) :-
+ Redirect0 = redirect(CSDredirect0, PDredirect0),
+ InitDeep0 = initial_deep(Stats, Root0, CSDs0, PDs0, CSSs, PSs),
+ compact_csd_redirect(1, 1, MaxCSD0, NumCSD,
+ u(CSDredirect0), CSDredirect),
+ compact_pd_redirect(1, 1, MaxPD0, NumPD,
+ u(PDredirect0), PDredirect),
+ Redirect = redirect(CSDredirect, PDredirect),
+ array_map_from_1(subst_in_call_site_dynamic(Redirect),
+ u(CSDs0), CSDs1),
+ array_map_from_1(subst_in_proc_dynamic(Redirect),
+ u(PDs0), PDs1),
+ array__shrink(CSDs1, NumCSD, CSDs),
+ array__shrink(PDs1, NumPD, PDs),
+ lookup_pd_redirect(PDredirect, Root0, Root),
+ InitDeep = initial_deep(Stats, Root, CSDs, PDs, CSSs, PSs).
+
+:- pred compact_csd_redirect(int::in, int::in, int::in, int::out,
+ array(call_site_dynamic_ptr)::array_di,
+ array(call_site_dynamic_ptr)::array_uo) is det.
+
+compact_csd_redirect(CurOld, CurNew, MaxOld, NumNew,
+ CSDredirect0, CSDredirect) :-
+ ( CurOld > MaxOld ->
+ NumNew = CurNew,
+ CSDredirect = CSDredirect0
+ ;
+ array__lookup(CSDredirect0, CurOld, Redirect0),
+ ( Redirect0 = call_site_dynamic_ptr(0) ->
+ array__set(CSDredirect0, CurOld,
+ call_site_dynamic_ptr(CurNew), CSDredirect1),
+ compact_csd_redirect(CurOld + 1, CurNew + 1,
+ MaxOld, NumNew, CSDredirect1, CSDredirect)
+ ;
+ % Since this CSD is being redirected, its slot is
+ % available for another (non-redirected) CSD.
+ compact_csd_redirect(CurOld + 1, CurNew,
+ MaxOld, NumNew, CSDredirect0, CSDredirect)
+ )
+ ).
+
+:- pred compact_pd_redirect(int::in, int::in, int::in, int::out,
+ array(proc_dynamic_ptr)::array_di,
+ array(proc_dynamic_ptr)::array_uo) is det.
+
+compact_pd_redirect(CurOld, CurNew, MaxOld, NumNew,
+ PDredirect0, PDredirect) :-
+ ( CurOld > MaxOld ->
+ NumNew = CurNew,
+ PDredirect = PDredirect0
+ ;
+ array__lookup(PDredirect0, CurOld, Redirect0),
+ ( Redirect0 = proc_dynamic_ptr(0) ->
+ array__set(PDredirect0, CurOld,
+ proc_dynamic_ptr(CurNew), PDredirect1),
+ compact_pd_redirect(CurOld + 1, CurNew + 1,
+ MaxOld, NumNew, PDredirect1, PDredirect)
+ ;
+ % Since this PD is being redirected, its slot is
+ % available for another (non-redirected) PD.
+ compact_pd_redirect(CurOld + 1, CurNew,
+ MaxOld, NumNew, PDredirect0, PDredirect)
+ )
+ ).
+
+:- pred subst_in_call_site_dynamic(redirect::in, call_site_dynamic::in,
+ call_site_dynamic::out) is det.
+
+subst_in_call_site_dynamic(Redirect, CSD0, CSD) :-
+ CSD0 = call_site_dynamic(Caller0, Callee0, Own),
+ lookup_pd_redirect(Redirect ^ pd_redirect, Caller0, Caller),
+ lookup_pd_redirect(Redirect ^ pd_redirect, Callee0, Callee),
+ CSD = call_site_dynamic(Caller, Callee, Own).
+
+:- pred subst_in_proc_dynamic(redirect::in, proc_dynamic::in,
+ proc_dynamic::out) is det.
+
+subst_in_proc_dynamic(Redirect, PD0, PD) :-
+ PD0 = proc_dynamic(PDPtr, Slots0),
+ array__map(subst_in_slot(Redirect), u(Slots0), Slots),
+ PD = proc_dynamic(PDPtr, Slots).
+
+:- pred subst_in_slot(redirect::in, call_site_array_slot::in,
+ call_site_array_slot::out) is det.
+
+subst_in_slot(Redirect, normal(CSDPtr0), normal(CSDPtr)) :-
+ lookup_csd_redirect(Redirect ^ csd_redirect, CSDPtr0, CSDPtr).
+subst_in_slot(Redirect, multi(CSDPtrs0), multi(CSDPtrs)) :-
+ array__map(lookup_csd_redirect(Redirect ^ csd_redirect),
+ u(CSDPtrs0), CSDPtrs).
+
+%-----------------------------------------------------------------------------%
+
+:- pred merge_profiles(list(initial_deep)::in, maybe_error(initial_deep)::out)
+ is det.
+
+merge_profiles(InitDeeps, MaybeMergedInitDeep) :-
+ ( InitDeeps = [FirstInitDeep | LaterInitDeeps] ->
+ ( all_compatible(FirstInitDeep, LaterInitDeeps) ->
+ do_merge_profiles(FirstInitDeep, LaterInitDeeps,
+ MergedInitDeep),
+ MaybeMergedInitDeep = ok(MergedInitDeep)
+ ;
+ MaybeMergedInitDeep =
+ error("profiles are not from the same executable")
+ )
+ ;
+ MaybeMergedInitDeep =
+ error("merge_profiles: empty list of profiles")
+ ).
+
+:- pred all_compatible(initial_deep::in, list(initial_deep)::in) is semidet.
+
+all_compatible(BaseInitDeep, OtherInitDeeps) :-
+ extract_max_css(BaseInitDeep, BaseMaxCSS),
+ extract_max_ps(BaseInitDeep, BaseMaxPS),
+ extract_ticks_per_sec(BaseInitDeep, BaseTicksPerSec),
+ list__map(extract_max_css, OtherInitDeeps, OtherMaxCSSs),
+ list__map(extract_max_ps, OtherInitDeeps, OtherMaxPSs),
+ list__map(extract_ticks_per_sec, OtherInitDeeps, OtherTicksPerSec),
+ all_true(unify(BaseMaxCSS), OtherMaxCSSs),
+ all_true(unify(BaseMaxPS), OtherMaxPSs),
+ all_true(unify(BaseTicksPerSec), OtherTicksPerSec),
+ extract_init_call_site_statics(BaseInitDeep, BaseCallSiteStatics),
+ extract_init_proc_statics(BaseInitDeep, BaseProcStatics),
+ list__map(extract_init_call_site_statics, OtherInitDeeps,
+ OtherCallSiteStatics),
+ list__map(extract_init_proc_statics, OtherInitDeeps,
+ OtherProcStatics),
+ array_match_elements(1, BaseMaxCSS, BaseCallSiteStatics,
+ OtherCallSiteStatics),
+ array_match_elements(1, BaseMaxPS, BaseProcStatics,
+ OtherProcStatics).
+
+:- pred do_merge_profiles(initial_deep::in, list(initial_deep)::in,
+ initial_deep::out) is det.
+
+do_merge_profiles(BaseInitDeep, OtherInitDeeps, MergedInitDeep) :-
+ extract_max_csd(BaseInitDeep, BaseMaxCSD),
+ extract_max_pd(BaseInitDeep, BaseMaxPD),
+ list__map(extract_max_csd, OtherInitDeeps, OtherMaxCSDs),
+ list__map(extract_max_pd, OtherInitDeeps, OtherMaxPDs),
+ list__foldl(int_add, OtherMaxCSDs, BaseMaxCSD, ConcatMaxCSD),
+ list__foldl(int_add, OtherMaxPDs, BaseMaxPD, ConcatMaxPD),
+ extract_init_call_site_dynamics(BaseInitDeep, BaseCallSiteDynamics),
+ extract_init_proc_dynamics(BaseInitDeep, BaseProcDynamics),
+ array__lookup(BaseCallSiteDynamics, 0, DummyCSD),
+ array__lookup(BaseProcDynamics, 0, DummyPD),
+ array__init(ConcatMaxCSD + 1, DummyCSD, ConcatCallSiteDynamics0),
+ array__init(ConcatMaxPD + 1, DummyPD, ConcatProcDynamics0),
+ AllInitDeeps = [BaseInitDeep | OtherInitDeeps],
+ concatenate_profiles(AllInitDeeps, 0, 0,
+ ConcatCallSiteDynamics0, ConcatCallSiteDynamics,
+ ConcatProcDynamics0, ConcatProcDynamics),
+
+ extract_max_css(BaseInitDeep, BaseMaxCSS),
+ extract_max_ps(BaseInitDeep, BaseMaxPS),
+ extract_ticks_per_sec(BaseInitDeep, BaseTicksPerSec),
+ list__map(extract_instrument_quanta, AllInitDeeps, InstrumentQuantas),
+ list__map(extract_user_quanta, AllInitDeeps, UserQuantas),
+ list__foldl(int_add, InstrumentQuantas, 0, InstrumentQuanta),
+ list__foldl(int_add, UserQuantas, 0, UserQuanta),
+ ConcatProfileStats = profile_stats(
+ ConcatMaxCSD, BaseMaxCSS, ConcatMaxPD, BaseMaxPS,
+ BaseTicksPerSec, InstrumentQuanta, UserQuanta),
+ % The root part is a temporary lie.
+ MergedInitDeep = initial_deep(ConcatProfileStats,
+ BaseInitDeep ^ init_root,
+ ConcatCallSiteDynamics,
+ ConcatProcDynamics,
+ BaseInitDeep ^ init_call_site_statics,
+ BaseInitDeep ^ init_proc_statics).
+ % list__map(extract_init_root, AllInitDeeps, Roots),
+ % merge clique of roots, replacing root with chosen pd
+
+:- pred concatenate_profiles(list(initial_deep)::in, int::in, int::in,
+ call_site_dynamics::array_di, call_site_dynamics::array_uo,
+ proc_dynamics::array_di, proc_dynamics::array_uo) is det.
+
+concatenate_profiles([], _PrevMaxCSD, _PrevMaxPD,
+ ConcatCallSiteDynamics, ConcatCallSiteDynamics,
+ ConcatProcDynamics, ConcatProcDynamics).
+concatenate_profiles([InitDeep | InitDeeps], PrevMaxCSD, PrevMaxPD,
+ ConcatCallSiteDynamics0, ConcatCallSiteDynamics,
+ ConcatProcDynamics0, ConcatProcDynamics) :-
+ concatenate_profile(InitDeep,
+ PrevMaxCSD, PrevMaxPD, NextMaxCSD, NextMaxPD,
+ ConcatCallSiteDynamics0, ConcatCallSiteDynamics,
+ ConcatProcDynamics0, ConcatProcDynamics),
+ concatenate_profiles(InitDeeps, NextMaxCSD, NextMaxPD,
+ ConcatCallSiteDynamics0, ConcatCallSiteDynamics,
+ ConcatProcDynamics0, ConcatProcDynamics).
+
+:- pred concatenate_profile(initial_deep::in,
+ int::in, int::in, int::out, int::out,
+ call_site_dynamics::array_di, call_site_dynamics::array_uo,
+ proc_dynamics::array_di, proc_dynamics::array_uo) is det.
+
+concatenate_profile(InitDeep, PrevMaxCSD, PrevMaxPD, NextMaxCSD, NextMaxPD,
+ ConcatCallSiteDynamics0, ConcatCallSiteDynamics,
+ ConcatProcDynamics0, ConcatProcDynamics) :-
+ extract_max_csd(InitDeep, MaxCSD),
+ extract_max_pd(InitDeep, MaxPD),
+ NextMaxCSD = PrevMaxCSD + MaxCSD,
+ NextMaxPD = PrevMaxPD + MaxPD,
+ concatenate_profile_csds(1, MaxCSD, PrevMaxCSD, PrevMaxPD,
+ InitDeep ^ init_call_site_dynamics,
+ ConcatCallSiteDynamics0, ConcatCallSiteDynamics),
+ concatenate_profile_pds(1, MaxPD, PrevMaxCSD, PrevMaxPD,
+ InitDeep ^ init_proc_dynamics,
+ ConcatProcDynamics0, ConcatProcDynamics).
+
+:- pred concatenate_profile_csds(int::in, int::in, int::in, int::in,
+ call_site_dynamics::in,
+ call_site_dynamics::array_di, call_site_dynamics::array_uo) is det.
+
+concatenate_profile_csds(Cur, Max, PrevMaxCSD, PrevMaxPD, CallSiteDynamics,
+ ConcatCallSiteDynamics0, ConcatCallSiteDynamics) :-
+ ( Cur =< Max ->
+ array__lookup(CallSiteDynamics, Cur, CSD0),
+ CSD0 = call_site_dynamic(CallerPDPtr0, CalleePDPtr0, Own),
+ concat_proc_dynamic_ptr(PrevMaxPD, CallerPDPtr0, CallerPDPtr),
+ concat_proc_dynamic_ptr(PrevMaxPD, CalleePDPtr0, CalleePDPtr),
+ CSD = call_site_dynamic(CallerPDPtr, CalleePDPtr, Own),
+ array__set(ConcatCallSiteDynamics0, PrevMaxCSD + Cur, CSD,
+ ConcatCallSiteDynamics1),
+ concatenate_profile_csds(Cur + 1, Max, PrevMaxCSD, PrevMaxPD,
+ CallSiteDynamics,
+ ConcatCallSiteDynamics1, ConcatCallSiteDynamics)
+ ;
+ ConcatCallSiteDynamics = ConcatCallSiteDynamics0
+ ).
+
+:- pred concatenate_profile_pds(int::in, int::in, int::in, int::in,
+ proc_dynamics::in,
+ proc_dynamics::array_di, proc_dynamics::array_uo) is det.
+
+concatenate_profile_pds(Cur, Max, PrevMaxCSD, PrevMaxPD, ProcDynamics,
+ ConcatProcDynamics0, ConcatProcDynamics) :-
+ ( Cur =< Max ->
+ array__lookup(ProcDynamics, Cur, PD0),
+ PD0 = proc_dynamic(PSPtr, Sites0),
+ array__max(Sites0, MaxSite),
+ concatenate_profile_slots(0, MaxSite, PrevMaxCSD, PrevMaxPD,
+ u(Sites0), Sites),
+ PD = proc_dynamic(PSPtr, Sites),
+ array__set(ConcatProcDynamics0, PrevMaxPD + Cur, PD,
+ ConcatProcDynamics1),
+ concatenate_profile_pds(Cur + 1, Max, PrevMaxCSD, PrevMaxPD,
+ ProcDynamics,
+ ConcatProcDynamics1, ConcatProcDynamics)
+ ;
+ ConcatProcDynamics = ConcatProcDynamics0
+ ).
+
+:- pred concatenate_profile_slots(int::in, int::in, int::in, int::in,
+ array(call_site_array_slot)::array_di,
+ array(call_site_array_slot)::array_uo) is det.
+
+concatenate_profile_slots(Cur, Max, PrevMaxCSD, PrevMaxPD, Sites0, Sites) :-
+ ( Cur =< Max ->
+ array__lookup(Sites0, Cur, Slot0),
+ (
+ Slot0 = normal(CSDPtr0),
+ concat_call_site_dynamic_ptr(PrevMaxCSD,
+ CSDPtr0, CSDPtr),
+ Slot = normal(CSDPtr)
+ ;
+ Slot0 = multi(CSDPtrs0),
+ array_map_from_0(
+ concat_call_site_dynamic_ptr(PrevMaxCSD),
+ CSDPtrs0, CSDPtrs),
+ Slot = multi(CSDPtrs)
+ ),
+ array__set(Sites0, Cur, Slot, Sites1),
+ concatenate_profile_slots(Cur + 1, Max, PrevMaxCSD, PrevMaxPD,
+ Sites1, Sites)
+ ;
+ Sites = Sites0
+ ).
+
+:- pred concat_call_site_dynamic_ptr(int::in, call_site_dynamic_ptr::in,
+ call_site_dynamic_ptr::out) is det.
+
+concat_call_site_dynamic_ptr(PrevMaxCSD, CSDPtr0, CSDPtr) :-
+ CSDPtr0 = call_site_dynamic_ptr(CSDI0),
+ ( CSDI0 = 0 ->
+ CSDPtr = CSDPtr0
+ ;
+ CSDPtr = call_site_dynamic_ptr(CSDI0 + PrevMaxCSD)
+ ).
+
+:- pred concat_proc_dynamic_ptr(int::in, proc_dynamic_ptr::in,
+ proc_dynamic_ptr::out) is det.
+
+concat_proc_dynamic_ptr(PrevMaxPD, PDPtr0, PDPtr) :-
+ PDPtr0 = proc_dynamic_ptr(PDI0),
+ ( PDI0 = 0 ->
+ PDPtr = PDPtr0
+ ;
+ PDPtr = proc_dynamic_ptr(PDI0 + PrevMaxPD)
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred extract_ticks_per_sec(initial_deep::in, int::out) is det.
+
+extract_ticks_per_sec(InitDeep,
+ InitDeep ^ init_profile_stats ^ ticks_per_sec).
+
+:- pred extract_instrument_quanta(initial_deep::in, int::out) is det.
+
+extract_instrument_quanta(InitDeep,
+ InitDeep ^ init_profile_stats ^ instrument_quanta).
+
+:- pred extract_user_quanta(initial_deep::in, int::out) is det.
+
+extract_user_quanta(InitDeep,
+ InitDeep ^ init_profile_stats ^ user_quanta).
+
+:- pred extract_max_css(initial_deep::in, int::out) is det.
+
+extract_max_css(InitDeep, MaxCSS) :-
+ array__max(InitDeep ^ init_call_site_statics, MaxCSS).
+
+:- pred extract_max_ps(initial_deep::in, int::out) is det.
+
+extract_max_ps(InitDeep, MaxPS) :-
+ array__max(InitDeep ^ init_proc_statics, MaxPS).
+
+:- pred extract_max_csd(initial_deep::in, int::out) is det.
+
+extract_max_csd(InitDeep, MaxCSD) :-
+ array__max(InitDeep ^ init_call_site_dynamics, MaxCSD).
+
+:- pred extract_max_pd(initial_deep::in, int::out) is det.
+
+extract_max_pd(InitDeep, MaxPD) :-
+ array__max(InitDeep ^ init_proc_dynamics, MaxPD).
+
+:- pred extract_init_call_site_dynamics(initial_deep::in,
+ call_site_dynamics::out) is det.
+
+extract_init_call_site_dynamics(InitDeep, InitDeep ^ init_call_site_dynamics).
+
+:- pred extract_init_call_site_statics(initial_deep::in,
+ call_site_statics::out) is det.
+
+extract_init_call_site_statics(InitDeep, InitDeep ^ init_call_site_statics).
+
+:- pred extract_init_proc_dynamics(initial_deep::in,
+ proc_dynamics::out) is det.
+
+extract_init_proc_dynamics(InitDeep, InitDeep ^ init_proc_dynamics).
+
+:- pred extract_init_proc_statics(initial_deep::in,
+ proc_statics::out) is det.
+
+extract_init_proc_statics(InitDeep, InitDeep ^ init_proc_statics).
+
+:- pred extract_init_root(initial_deep::in,
+ proc_dynamic_ptr::out) is det.
+
+extract_init_root(InitDeep, InitDeep ^ init_root).
+
+ % list__all_true(P, L) succeeds iff P is true for all elements of the
+ % list L.
+:- pred all_true(pred(X), list(X)).
+:- mode all_true(pred(in) is semidet, in) is semidet.
+
+all_true(_, []).
+all_true(P, [H | T]) :-
+ call(P, H),
+ all_true(P, T).
+
+ % array_match_elements(Min, Max, BaseArray, OtherArrays):
+ % Succeeds iff all the elements of all the OtherArrays are equal to the
+ % corresponding element of BaseArray.
+:- pred array_match_elements(int::in, int::in, array(T)::in,
+ list(array(T))::in) is semidet.
+
+array_match_elements(N, Max, BaseArray, OtherArrays) :-
+ ( N =< Max ->
+ array__lookup(BaseArray, N, BaseElement),
+ match_element(BaseElement, N, OtherArrays),
+ array_match_elements(N + 1, Max, BaseArray, OtherArrays)
+ ;
+ true
+ ).
+
+ % match_element(TestElement, Index, Arrays):
+ % Succeeds iff the elements of all the Arrays at index Index
+ % are equal to TestElement.
+:- pred match_element(T::in, int::in, list(array(T))::in) is semidet.
+
+match_element(_, _, []).
+match_element(TestElement, Index, [Array | Arrays]) :-
+ array__lookup(Array, Index, Element),
+ Element = TestElement,
+ match_element(Element, Index, Arrays).
+
+:- pred int_add(int::in, int::in, int::out) is det.
+
+int_add(A, B, C) :-
+ C = A + B.
Index: cliques.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/cliques.m,v
retrieving revision 1.1
diff -u -b -r1.1 cliques.m
--- cliques.m 2001/05/31 05:59:57 1.1
+++ cliques.m 2001/06/01 11:31:11
@@ -18,17 +18,18 @@
:- import_module list, set.
-% Create a graph with no edges.
+ % Create a graph with no edges.
:- pred init(graph::out) is det.
-% Add an arc from one node to another.
+ % Add an arc from one node to another.
:- pred add_arc(graph::in, int::in, int::in, graph::out) is det.
-% Perform a topological sort on the graph. Each set of integers in the
-% resulting list gives the ids of the nodes in a clique. The list contains
-% the cliques in bottom-up order: if there is an arc from node A to node B
-% and the two nodes are not in the same clique, then the clique containing
-% node A will be before the clique containing node B.
+ % Perform a topological sort on the graph. Each set of integers in the
+ % resulting list gives the ids of the nodes in a clique. The list
+ % contains the cliques in top-down order: if there is an arc from
+ % node A to node B and the two nodes are not in the same clique,
+ % then the clique containing node A will be before the clique
+ % containing node B.
:- pred topological_sort(graph::in, list(set(int))::out) is det.
:- implementation.
@@ -36,8 +37,8 @@
:- import_module array_util, dense_bitset.
:- import_module array, int.
-:- type graph --->
- graph(
+:- type graph
+ ---> graph(
int,
array(set(int))
).
Index: deep_cliques.m
===================================================================
RCS file: deep_cliques.m
diff -N deep_cliques.m
cvs diff: deep_cliques.m: No such file or directory
Index: interface.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/interface.m,v
retrieving revision 1.1
diff -u -b -r1.1 interface.m
--- interface.m 2001/05/31 05:59:57 1.1
+++ interface.m 2001/06/02 10:11:37
@@ -21,7 +21,7 @@
; timeout(int)
; menu
; root(fields)
- ; clique(int, fields)
+ ; clique(int, fields, maybe(int))
; proc(int, fields)
; top_procs(sort_measurement, include_descendants,
display_limit, fields)
@@ -60,6 +60,8 @@
% w: memory words
% The characters must be sorted.
+:- func default_ancestor_limit = maybe(int).
+
:- func default_fields = string.
:- func all_fields = string.
@@ -81,8 +83,9 @@
:- import_module util.
:- import_module char, string, list, set, require.
-default_fields = "pqw".
+default_ancestor_limit = yes(5).
+default_fields = "pqw".
all_fields = "apqtw".
to_server_pipe_name(DataFileName) =
@@ -154,8 +157,16 @@
Cmd = root(Fields),
Query = format("root+%s", [s(Fields)])
;
- Cmd = clique(CliqueNum, Fields),
- Query = format("clique+%s+%d", [s(Fields), i(CliqueNum)])
+ Cmd = clique(CliqueNum, Fields, MaybeAncestorLimit),
+ (
+ MaybeAncestorLimit = yes(AncestorLimit),
+ Query = format("clique+%s+%d+%d",
+ [s(Fields), i(CliqueNum), i(AncestorLimit)])
+ ;
+ MaybeAncestorLimit = no,
+ Query = format("clique+%s+%d+no",
+ [s(Fields), i(CliqueNum)])
+ )
;
Cmd = proc(ProcNum, Fields),
Query = format("proc+%s+%d", [s(Fields), i(ProcNum)])
@@ -199,16 +210,30 @@
split(QueryString, ('+'), Pieces),
(
(
- Pieces = ["clique", NStr],
+ Pieces = ["clique", NStr, AncestorLimitStr],
string__to_int(NStr, N),
+ ( string__to_int(AncestorLimitStr, AncestorLimit) ->
+ MaybeAncestorLimit = yes(AncestorLimit)
+ ; AncestorLimitStr = "no" ->
+ MaybeAncestorLimit = no
+ ;
+ fail
+ ),
Fields = default_fields
;
- Pieces = ["clique", Fields, NStr],
+ Pieces = ["clique", Fields, NStr, AncestorLimitStr],
string__to_int(NStr, N),
+ ( string__to_int(AncestorLimitStr, AncestorLimit) ->
+ MaybeAncestorLimit = yes(AncestorLimit)
+ ; AncestorLimitStr = "no" ->
+ MaybeAncestorLimit = no
+ ;
+ fail
+ ),
validate_fields(Fields)
)
->
- MaybeCmd = yes(clique(N, Fields))
+ MaybeCmd = yes(clique(N, Fields, MaybeAncestorLimit))
;
(
Pieces = ["proc", NStr],
Index: io_combinator.m
===================================================================
RCS file: io_combinator.m
diff -N io_combinator.m
--- /dev/null Fri Dec 1 02:25:58 2000
+++ io_combinator.m Fri Jun 1 21:38:15 2001
@@ -0,0 +1,1636 @@
+%-----------------------------------------------------------------------------%
+% Copyright (C) 1993-2001 The University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: io.m.
+% Authors: conway, zs.
+% Stability: low
+%
+% This file implements I/O "combinators".
+%
+% Each of these predicates takes as its inputs N I/O actions, and a predicate
+% that combines the results of these actions into a single result.
+%
+% The io_combinator__sequence_N forms combine actions that return io__result(T)
+% and return io__result(T) themselves. They return ok if all the actions
+% succeeded. They return error if an action resulted in an error after the
+% previous ones succeeded, and they return eof if one of the actions found eof
+% after the previous ones succeeded. In either case, the inputs of those
+% earlier successful actions have already been consumed, but their results
+% are not returned.
+%
+% The io_combinator__res_sequence_N forms are similar, except they combine
+% actions that return io__res(T) and return io__res(T) themselves. This means
+% that neither the individual actions nor the combinators can ever return a
+% separate eof indication. These forms are for use in situations in which
+% an action finding eof is an error.
+%
+% The io_combinator__maybe_error_sequence_N forms are identical to the
+% io_combinator__res_sequence_N forms, except they return strings, not
+% io__errors, when they find an error.
+%
+%-----------------------------------------------------------------------------%
+
+:- module io_combinator.
+:- interface.
+:- import_module io, std_util.
+
+%-----------------------------------------------------------------------------%
+
+:- pred io_combinator__sequence_2(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(T1, T2, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_2(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__sequence_3(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(io__result(T3), io__state, io__state),
+ pred(T1, T2, T3, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_3(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__sequence_4(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(io__result(T3), io__state, io__state),
+ pred(io__result(T4), io__state, io__state),
+ pred(T1, T2, T3, T4, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_4(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__sequence_5(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(io__result(T3), io__state, io__state),
+ pred(io__result(T4), io__state, io__state),
+ pred(io__result(T5), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_5(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__sequence_6(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(io__result(T3), io__state, io__state),
+ pred(io__result(T4), io__state, io__state),
+ pred(io__result(T5), io__state, io__state),
+ pred(io__result(T6), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_6(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__sequence_7(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(io__result(T3), io__state, io__state),
+ pred(io__result(T4), io__state, io__state),
+ pred(io__result(T5), io__state, io__state),
+ pred(io__result(T6), io__state, io__state),
+ pred(io__result(T7), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_7(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__sequence_8(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(io__result(T3), io__state, io__state),
+ pred(io__result(T4), io__state, io__state),
+ pred(io__result(T5), io__state, io__state),
+ pred(io__result(T6), io__state, io__state),
+ pred(io__result(T7), io__state, io__state),
+ pred(io__result(T8), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, T8, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_8(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__sequence_9(
+ pred(io__result(T1), io__state, io__state),
+ pred(io__result(T2), io__state, io__state),
+ pred(io__result(T3), io__state, io__state),
+ pred(io__result(T4), io__state, io__state),
+ pred(io__result(T5), io__state, io__state),
+ pred(io__result(T6), io__state, io__state),
+ pred(io__result(T7), io__state, io__state),
+ pred(io__result(T8), io__state, io__state),
+ pred(io__result(T9), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, T8, T9, io__result(T)),
+ io__result(T), io__state, io__state).
+:- mode io_combinator__sequence_9(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- pred io_combinator__res_sequence_2(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(T1, T2, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_2(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__res_sequence_3(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(io__res(T3), io__state, io__state),
+ pred(T1, T2, T3, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_3(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__res_sequence_4(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(io__res(T3), io__state, io__state),
+ pred(io__res(T4), io__state, io__state),
+ pred(T1, T2, T3, T4, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_4(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__res_sequence_5(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(io__res(T3), io__state, io__state),
+ pred(io__res(T4), io__state, io__state),
+ pred(io__res(T5), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_5(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__res_sequence_6(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(io__res(T3), io__state, io__state),
+ pred(io__res(T4), io__state, io__state),
+ pred(io__res(T5), io__state, io__state),
+ pred(io__res(T6), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_6(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__res_sequence_7(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(io__res(T3), io__state, io__state),
+ pred(io__res(T4), io__state, io__state),
+ pred(io__res(T5), io__state, io__state),
+ pred(io__res(T6), io__state, io__state),
+ pred(io__res(T7), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_7(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__res_sequence_8(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(io__res(T3), io__state, io__state),
+ pred(io__res(T4), io__state, io__state),
+ pred(io__res(T5), io__state, io__state),
+ pred(io__res(T6), io__state, io__state),
+ pred(io__res(T7), io__state, io__state),
+ pred(io__res(T8), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, T8, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_8(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__res_sequence_9(
+ pred(io__res(T1), io__state, io__state),
+ pred(io__res(T2), io__state, io__state),
+ pred(io__res(T3), io__state, io__state),
+ pred(io__res(T4), io__state, io__state),
+ pred(io__res(T5), io__state, io__state),
+ pred(io__res(T6), io__state, io__state),
+ pred(io__res(T7), io__state, io__state),
+ pred(io__res(T8), io__state, io__state),
+ pred(io__res(T9), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, T8, T9, io__res(T)),
+ io__res(T), io__state, io__state).
+:- mode io_combinator__res_sequence_9(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- pred io_combinator__maybe_error_sequence_2(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(T1, T2, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_2(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__maybe_error_sequence_3(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(maybe_error(T3), io__state, io__state),
+ pred(T1, T2, T3, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_3(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__maybe_error_sequence_4(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(maybe_error(T3), io__state, io__state),
+ pred(maybe_error(T4), io__state, io__state),
+ pred(T1, T2, T3, T4, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_4(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__maybe_error_sequence_5(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(maybe_error(T3), io__state, io__state),
+ pred(maybe_error(T4), io__state, io__state),
+ pred(maybe_error(T5), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_5(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__maybe_error_sequence_6(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(maybe_error(T3), io__state, io__state),
+ pred(maybe_error(T4), io__state, io__state),
+ pred(maybe_error(T5), io__state, io__state),
+ pred(maybe_error(T6), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_6(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__maybe_error_sequence_7(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(maybe_error(T3), io__state, io__state),
+ pred(maybe_error(T4), io__state, io__state),
+ pred(maybe_error(T5), io__state, io__state),
+ pred(maybe_error(T6), io__state, io__state),
+ pred(maybe_error(T7), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_7(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__maybe_error_sequence_8(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(maybe_error(T3), io__state, io__state),
+ pred(maybe_error(T4), io__state, io__state),
+ pred(maybe_error(T5), io__state, io__state),
+ pred(maybe_error(T6), io__state, io__state),
+ pred(maybe_error(T7), io__state, io__state),
+ pred(maybe_error(T8), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, T8, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_8(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+:- pred io_combinator__maybe_error_sequence_9(
+ pred(maybe_error(T1), io__state, io__state),
+ pred(maybe_error(T2), io__state, io__state),
+ pred(maybe_error(T3), io__state, io__state),
+ pred(maybe_error(T4), io__state, io__state),
+ pred(maybe_error(T5), io__state, io__state),
+ pred(maybe_error(T6), io__state, io__state),
+ pred(maybe_error(T7), io__state, io__state),
+ pred(maybe_error(T8), io__state, io__state),
+ pred(maybe_error(T9), io__state, io__state),
+ pred(T1, T2, T3, T4, T5, T6, T7, T8, T9, maybe_error(T)),
+ maybe_error(T), io__state, io__state).
+:- mode io_combinator__maybe_error_sequence_9(
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(out, di, uo) is det,
+ pred(in, in, in, in, in, in, in, in, in, out) is det,
+ out, di, uo) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+io_combinator__sequence_2(P1, P2, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ { call(Combine, T1, T2, Res) }
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__sequence_3(P1, P2, P3, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ { call(Combine, T1, T2, T3, Res) }
+ ;
+ { Res3 = eof },
+ { Res = eof }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__sequence_4(P1, P2, P3, P4, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ { call(Combine, T1, T2, T3, T4, Res) }
+ ;
+ { Res4 = eof },
+ { Res = eof }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = eof },
+ { Res = eof }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__sequence_5(P1, P2, P3, P4, P5, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ { call(Combine, T1, T2, T3, T4,
+ T5, Res) }
+ ;
+ { Res5 = eof },
+ { Res = eof }
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = eof },
+ { Res = eof }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = eof },
+ { Res = eof }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__sequence_6(P1, P2, P3, P4, P5, P6, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ { call(Combine, T1, T2,
+ T3, T4, T5,
+ T6, Res) }
+ ;
+ { Res6 = eof },
+ { Res = eof }
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = eof },
+ { Res = eof }
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = eof },
+ { Res = eof }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = eof },
+ { Res = eof }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__sequence_7(P1, P2, P3, P4, P5, P6, P7, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ { call(Combine, T1, T2, T3, T4, T5, T6, T7,
+ Res) }
+ ;
+ { Res7 = eof },
+ { Res = eof }
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = eof },
+ { Res = eof }
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = eof },
+ { Res = eof }
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = eof },
+ { Res = eof }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = eof },
+ { Res = eof }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__sequence_8(P1, P2, P3, P4, P5, P6, P7, P8, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ call(P8, Res8),
+ (
+ { Res8 = ok(T8) },
+ { call(Combine, T1, T2, T3, T4, T5, T6,
+ T7, T8, Res) }
+ ;
+ { Res8 = eof },
+ { Res = eof }
+ ;
+ { Res8 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res7 = eof },
+ { Res = eof }
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = eof },
+ { Res = eof }
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = eof },
+ { Res = eof }
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = eof },
+ { Res = eof }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = eof },
+ { Res = eof }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__sequence_9(P1, P2, P3, P4, P5, P6, P7, P8, P9, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ call(P8, Res8),
+ (
+ { Res8 = ok(T8) },
+ call(P9, Res9),
+ (
+ { Res9 = ok(T9) },
+ { call(Combine, T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, Res) }
+ ;
+ { Res9 = eof },
+ { Res = eof }
+ ;
+ { Res9 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res8 = eof },
+ { Res = eof }
+ ;
+ { Res8 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res7 = eof },
+ { Res = eof }
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = eof },
+ { Res = eof }
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = eof },
+ { Res = eof }
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = eof },
+ { Res = eof }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = eof },
+ { Res = eof }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = eof },
+ { Res = eof }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = eof },
+ { Res = eof }
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+%-----------------------------------------------------------------------------%
+
+io_combinator__res_sequence_2(P1, P2, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ { call(Combine, T1, T2, Res) }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__res_sequence_3(P1, P2, P3, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ { call(Combine, T1, T2, T3, Res) }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__res_sequence_4(P1, P2, P3, P4, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ { call(Combine, T1, T2, T3, T4, Res) }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__res_sequence_5(P1, P2, P3, P4, P5, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ { call(Combine, T1, T2, T3, T4,
+ T5, Res) }
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__res_sequence_6(P1, P2, P3, P4, P5, P6, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ { call(Combine, T1, T2,
+ T3, T4, T5,
+ T6, Res) }
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__res_sequence_7(P1, P2, P3, P4, P5, P6, P7, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ { call(Combine, T1, T2, T3, T4, T5, T6, T7,
+ Res) }
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__res_sequence_8(P1, P2, P3, P4, P5, P6, P7, P8, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ call(P8, Res8),
+ (
+ { Res8 = ok(T8) },
+ { call(Combine, T1, T2, T3, T4, T5, T6,
+ T7, T8, Res) }
+ ;
+ { Res8 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__res_sequence_9(P1, P2, P3, P4, P5, P6, P7, P8, P9,
+ Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ call(P8, Res8),
+ (
+ { Res8 = ok(T8) },
+ call(P9, Res9),
+ (
+ { Res9 = ok(T9) },
+ { call(Combine, T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, Res) }
+ ;
+ { Res9 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res8 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+%-----------------------------------------------------------------------------%
+
+io_combinator__maybe_error_sequence_2(P1, P2, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ { call(Combine, T1, T2, Res) }
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__maybe_error_sequence_3(P1, P2, P3, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ { call(Combine, T1, T2, T3, Res) }
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__maybe_error_sequence_4(P1, P2, P3, P4, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ { call(Combine, T1, T2, T3, T4, Res) }
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__maybe_error_sequence_5(P1, P2, P3, P4, P5, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ { call(Combine, T1, T2, T3, T4,
+ T5, Res) }
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__maybe_error_sequence_6(P1, P2, P3, P4, P5, P6, Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ { call(Combine, T1, T2,
+ T3, T4, T5,
+ T6, Res) }
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__maybe_error_sequence_7(P1, P2, P3, P4, P5, P6, P7,
+ Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ { call(Combine, T1, T2, T3, T4, T5, T6, T7,
+ Res) }
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__maybe_error_sequence_8(P1, P2, P3, P4, P5, P6, P7, P8,
+ Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ call(P8, Res8),
+ (
+ { Res8 = ok(T8) },
+ { call(Combine, T1, T2, T3, T4, T5, T6,
+ T7, T8, Res) }
+ ;
+ { Res8 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+io_combinator__maybe_error_sequence_9(P1, P2, P3, P4, P5, P6, P7, P8, P9,
+ Combine, Res) -->
+ call(P1, Res1),
+ (
+ { Res1 = ok(T1) },
+ call(P2, Res2),
+ (
+ { Res2 = ok(T2) },
+ call(P3, Res3),
+ (
+ { Res3 = ok(T3) },
+ call(P4, Res4),
+ (
+ { Res4 = ok(T4) },
+ call(P5, Res5),
+ (
+ { Res5 = ok(T5) },
+ call(P6, Res6),
+ (
+ { Res6 = ok(T6) },
+ call(P7, Res7),
+ (
+ { Res7 = ok(T7) },
+ call(P8, Res8),
+ (
+ { Res8 = ok(T8) },
+ call(P9, Res9),
+ (
+ { Res9 = ok(T9) },
+ { call(Combine, T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, Res) }
+ ;
+ { Res9 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res8 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res7 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res6 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res5 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res4 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res3 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res2 = error(Err) },
+ { Res = error(Err) }
+ )
+ ;
+ { Res1 = error(Err) },
+ { Res = error(Err) }
+ ).
+
+%-----------------------------------------------------------------------------%
Index: measurements.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/measurements.m,v
retrieving revision 1.1
diff -u -b -r1.1 measurements.m
--- measurements.m 2001/05/31 05:59:58 1.1
+++ measurements.m 2001/06/01 17:27:01
@@ -23,13 +23,13 @@
:- func fails(own_prof_info) = int.
:- func redos(own_prof_info) = int.
:- func quanta(own_prof_info) = int.
-:- func mallocs(own_prof_info) = int.
+:- func allocs(own_prof_info) = int.
:- func words(own_prof_info) = int.
:- func zero_own_prof_info = own_prof_info.
:- func inherit_quanta(inherit_prof_info) = int.
-:- func inherit_mallocs(inherit_prof_info) = int.
+:- func inherit_allocs(inherit_prof_info) = int.
:- func inherit_words(inherit_prof_info) = int.
:- func zero_inherit_prof_info = inherit_prof_info.
@@ -46,7 +46,7 @@
:- func sum_own_infos(list(own_prof_info)) = own_prof_info.
:- func sum_inherit_infos(list(inherit_prof_info)) = inherit_prof_info.
-:- func compress_profile(int, int, int, int, int, int, int) = own_prof_info.
+:- func compress_profile(int, int, int, int, int, int) = own_prof_info.
:- func compress_profile(own_prof_info) = own_prof_info.
:- func own_to_string(own_prof_info) = string.
@@ -59,95 +59,109 @@
:- import_module string.
:- type own_prof_info
- ---> all(int, int, int, int, int, int, int)
- % calls, exits, fails, redos, quanta,
- % memory_mallocs, memory_words
- ; det(int, int, int, int) % calls, quanta, mallocs, words;
- % implicit exits == calls,
+ ---> all(int, int, int, int, int, int)
+ % exits, fails, redos, quanta, allocs, words
+ % implicit calls = exits + fails - redos
+ ; det(int, int, int, int)
+ % exits, quanta, allocs, words;
% implicit fails == redos == 0
- ; zdet(int, int, int). % calls, mallocs, words;
- % implicit exits == calls,
+ % implicit calls == exits
+ ; fast_det(int, int, int)
+ % exits, allocs, words;
% implicit fails == redos == 0
+ % implicit calls == exits
% implicit quanta == 0
+ ; fast_nomem_semi(int, int).
+ % exits, fails
+ % implicit redos == 0
+ % implicit calls == exits + fails
+ % implicit quanta == 0
+ % implicit allocs == words == 0
:- type inherit_prof_info
---> inherit_prof_info(
int, % quanta
- int, % memory_mallocs
- int % memory_words
+ int, % allocs
+ int % words
).
-calls(zdet(Calls, _, _)) = Calls.
-exits(zdet(Calls, _, _)) = Calls.
-fails(zdet(_, _, _)) = 0.
-redos(zdet(_, _, _)) = 0.
-quanta(zdet(_, _, _)) = 0.
-mallocs(zdet(_, Mallocs, _)) = Mallocs.
-words(zdet(_, _, Words)) = Words.
+calls(fast_nomem_semi(Exits, Fails)) = Exits + Fails.
+exits(fast_nomem_semi(Exits, _)) = Exits.
+fails(fast_nomem_semi(_, Fails)) = Fails.
+redos(fast_nomem_semi(_, _)) = 0.
+quanta(fast_nomem_semi(_, _)) = 0.
+allocs(fast_nomem_semi(_, _)) = 0.
+words(fast_nomem_semi(_, _)) = 0.
+
+calls(fast_det(Exits, _, _)) = Exits.
+exits(fast_det(Exits, _, _)) = Exits.
+fails(fast_det(_, _, _)) = 0.
+redos(fast_det(_, _, _)) = 0.
+quanta(fast_det(_, _, _)) = 0.
+allocs(fast_det(_, Allocs, _)) = Allocs.
+words(fast_det(_, _, Words)) = Words.
-calls(det(Calls, _, _, _)) = Calls.
-exits(det(Calls, _, _, _)) = Calls.
+calls(det(Exits, _, _, _)) = Exits.
+exits(det(Exits, _, _, _)) = Exits.
fails(det(_, _, _, _)) = 0.
redos(det(_, _, _, _)) = 0.
quanta(det(_, Quanta, _, _)) = Quanta.
-mallocs(det(_, _, Mallocs, _)) = Mallocs.
+allocs(det(_, _, Allocs, _)) = Allocs.
words(det(_, _, _, Words)) = Words.
-calls(all(Calls, _, _, _, _, _, _)) = Calls.
-exits(all(_, Exits, _, _, _, _, _)) = Exits.
-fails(all(_, _, Fails, _, _, _, _)) = Fails.
-redos(all(_, _, _, Redos, _, _, _)) = Redos.
-quanta(all(_, _, _, _, Quanta, _, _)) = Quanta.
-mallocs(all(_, _, _, _, _, Mallocs, _)) = Mallocs.
-words(all(_, _, _, _, _, _, Words)) = Words.
+calls(all(Exits, Fails, Redos, _, _, _)) = Exits + Fails - Redos.
+exits(all(Exits, _, _, _, _, _)) = Exits.
+fails(all(_, Fails, _, _, _, _)) = Fails.
+redos(all(_, _, Redos, _, _, _)) = Redos.
+quanta(all(_, _, _, Quanta, _, _)) = Quanta.
+allocs(all(_, _, _, _, Allocs, _)) = Allocs.
+words(all(_, _, _, _, _, Words)) = Words.
-zero_own_prof_info = zdet(0, 0, 0).
+zero_own_prof_info = fast_nomem_semi(0, 0).
inherit_quanta(inherit_prof_info(Quanta, _, _)) = Quanta.
-inherit_mallocs(inherit_prof_info(_, Mallocs, _)) = Mallocs.
+inherit_allocs(inherit_prof_info(_, Allocs, _)) = Allocs.
inherit_words(inherit_prof_info(_, _, Words)) = Words.
zero_inherit_prof_info = inherit_prof_info(0, 0, 0).
add_inherit_to_inherit(PI1, PI2) = SumPI :-
Quanta = inherit_quanta(PI1) + inherit_quanta(PI2),
- Mallocs = inherit_mallocs(PI1) + inherit_mallocs(PI2),
+ Allocs = inherit_allocs(PI1) + inherit_allocs(PI2),
Words = inherit_words(PI1) + inherit_words(PI2),
- SumPI = inherit_prof_info(Quanta, Mallocs, Words).
+ SumPI = inherit_prof_info(Quanta, Allocs, Words).
add_own_to_inherit(PI1, PI2) = SumPI :-
Quanta = quanta(PI1) + inherit_quanta(PI2),
- Mallocs = mallocs(PI1) + inherit_mallocs(PI2),
+ Allocs = allocs(PI1) + inherit_allocs(PI2),
Words = words(PI1) + inherit_words(PI2),
- SumPI = inherit_prof_info(Quanta, Mallocs, Words).
+ SumPI = inherit_prof_info(Quanta, Allocs, Words).
subtract_own_from_inherit(PI1, PI2) = SumPI :-
Quanta = inherit_quanta(PI2) - quanta(PI1),
- Mallocs = inherit_mallocs(PI2) - mallocs(PI1),
+ Allocs = inherit_allocs(PI2) - allocs(PI1),
Words = inherit_words(PI2) - words(PI1),
- SumPI = inherit_prof_info(Quanta, Mallocs, Words).
+ SumPI = inherit_prof_info(Quanta, Allocs, Words).
add_inherit_to_own(PI1, PI2) = SumPI :-
- Calls = calls(PI2),
Exits = exits(PI2),
Fails = fails(PI2),
Redos = redos(PI2),
Quanta = inherit_quanta(PI1) + quanta(PI2),
- Mallocs = inherit_mallocs(PI1) + mallocs(PI2),
+ Allocs = inherit_allocs(PI1) + allocs(PI2),
Words = inherit_words(PI1) + words(PI2),
- SumPI = compress_profile(Calls, Exits, Fails, Redos,
- Quanta, Mallocs, Words).
+ SumPI = compress_profile(Exits, Fails, Redos,
+ Quanta, Allocs, Words).
add_own_to_own(PI1, PI2) = SumPI :-
- Calls = calls(PI1) + calls(PI2),
Exits = exits(PI1) + exits(PI2),
Fails = fails(PI1) + fails(PI2),
Redos = redos(PI1) + redos(PI2),
Quanta = quanta(PI1) + quanta(PI2),
- Mallocs = mallocs(PI1) + mallocs(PI2),
+ Allocs = allocs(PI1) + allocs(PI2),
Words = words(PI1) + words(PI2),
- SumPI = compress_profile(Calls, Exits, Fails, Redos,
- Quanta, Mallocs, Words).
+ SumPI = compress_profile(Exits, Fails, Redos,
+ Quanta, Allocs, Words).
sum_own_infos(Owns) =
list__foldl(add_own_to_own, Owns, zero_own_prof_info).
@@ -155,60 +169,74 @@
sum_inherit_infos(Inherits) =
list__foldl(add_inherit_to_inherit, Inherits, zero_inherit_prof_info).
-compress_profile(Calls, Exits, Fails, Redos, Quanta, Mallocs, Words) = PI :-
+compress_profile(Exits, Fails, Redos, Quanta, Allocs, Words) = PI :-
(
- Calls = Exits,
+ Redos = 0,
+ Quanta = 0,
+ Allocs = 0,
+ Words = 0
+ ->
+ PI = fast_nomem_semi(Exits, Fails)
+ ;
Fails = 0,
Redos = 0
- ->
- (
- Quanta = 0
->
- PI = zdet(Calls, Mallocs, Words)
+ ( Quanta = 0 ->
+ PI = fast_det(Exits, Allocs, Words)
;
- PI = det(Calls, Quanta, Mallocs, Words)
+ PI = det(Exits, Quanta, Allocs, Words)
)
;
- PI = all(Calls, Exits, Fails, Redos, Quanta, Mallocs, Words)
+ PI = all(Exits, Fails, Redos, Quanta, Allocs, Words)
).
compress_profile(PI0) = PI :-
(
- PI0 = all(Calls, Exits, Fails, Redos, Quanta, Mallocs, Words),
+ PI0 = all(Exits, Fails, Redos, Quanta, Allocs, Words),
(
- Calls = Exits,
+ Redos = 0,
+ Quanta = 0,
+ Allocs = 0,
+ Words = 0
+ ->
+ PI = fast_nomem_semi(Exits, Fails)
+ ;
Fails = 0,
Redos = 0
->
- (
- Quanta = 0
- ->
- PI = zdet(Calls, Mallocs, Words)
+ ( Quanta = 0 ->
+ PI = fast_det(Exits, Allocs, Words)
;
- PI = det(Calls, Quanta, Mallocs, Words)
+ PI = det(Exits, Quanta, Allocs, Words)
)
;
PI = PI0
)
;
- PI0 = det(Calls, Quanta, Mallocs, Words),
- (
- Quanta = 0
- ->
- PI = zdet(Calls, Mallocs, Words)
+ PI0 = det(Exits, Quanta, Allocs, Words),
+ ( Allocs = 0, Words = 0 ->
+ PI = fast_nomem_semi(Exits, 0)
+ ; Quanta = 0 ->
+ PI = fast_det(Exits, Allocs, Words)
+ ;
+ PI = PI0
+ )
+ ;
+ PI0 = fast_det(Exits, Allocs, Words),
+ ( Allocs = 0, Words = 0 ->
+ PI = fast_nomem_semi(Exits, 0)
;
PI = PI0
)
;
- PI0 = zdet(_, _, _),
+ PI0 = fast_nomem_semi(_, _),
PI = PI0
).
%-----------------------------------------------------------------------------%
-own_to_string(all(Calls, Exits, Fails, Redos, Quanta, Allocs, Words)) =
+own_to_string(all(Exits, Fails, Redos, Quanta, Allocs, Words)) =
"all(" ++
- string__int_to_string(Calls) ++ ", " ++
string__int_to_string(Exits) ++ ", " ++
string__int_to_string(Fails) ++ ", " ++
string__int_to_string(Redos) ++ ", " ++
@@ -216,16 +244,21 @@
string__int_to_string(Allocs) ++ ", " ++
string__int_to_string(Words) ++
")".
-own_to_string(det(Calls, Quanta, Allocs, Words)) =
+own_to_string(det(Exits, Quanta, Allocs, Words)) =
"det(" ++
- string__int_to_string(Calls) ++ ", " ++
+ string__int_to_string(Exits) ++ ", " ++
string__int_to_string(Quanta) ++ ", " ++
string__int_to_string(Allocs) ++ ", " ++
string__int_to_string(Words) ++
")".
-own_to_string(zdet(Calls, Allocs, Words)) =
- "det(" ++
- string__int_to_string(Calls) ++ ", " ++
+own_to_string(fast_det(Exits, Allocs, Words)) =
+ "fast_det(" ++
+ string__int_to_string(Exits) ++ ", " ++
string__int_to_string(Allocs) ++ ", " ++
string__int_to_string(Words) ++
+ ")".
+own_to_string(fast_nomem_semi(Exits, Fails)) =
+ "fast_det(" ++
+ string__int_to_string(Exits) ++ ", " ++
+ string__int_to_string(Fails) ++
")".
Index: profile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/profile.m,v
retrieving revision 1.1
diff -u -b -r1.1 profile.m
--- profile.m 2001/05/31 05:59:58 1.1
+++ profile.m 2001/06/01 11:38:41
@@ -7,7 +7,7 @@
% Authors: conway, zs.
%
% This file defines the main data structures of the Mercury deep profiler,
-% and predicates for accessing it. The main concern of the access predicates
+% 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
@@ -25,13 +25,13 @@
:- type profile_stats --->
profile_stats(
+ max_csd :: int,
+ max_css :: int,
+ max_pd :: int,
+ max_ps :: int,
+ ticks_per_sec :: int,
instrument_quanta :: int,
- user_quanta :: int,
- num_csds :: int,
- num_pds :: int,
- num_csss :: int,
- num_pss :: int,
- ticks_per_sec :: int
+ user_quanta :: int
).
:- type initial_deep --->
@@ -112,8 +112,7 @@
:- type proc_dynamic
---> proc_dynamic(
pd_proc_static :: proc_static_ptr,
- pd_sites :: array(call_site_array_slot),
- pd_redirect :: maybe(proc_dynamic_ptr)
+ pd_sites :: array(call_site_array_slot)
).
:- type proc_static
@@ -129,8 +128,7 @@
---> call_site_dynamic(
csd_caller :: proc_dynamic_ptr,
csd_callee :: proc_dynamic_ptr,
- csd_own_prof :: own_prof_info,
- csd_redirect :: maybe(call_site_dynamic_ptr)
+ csd_own_prof :: own_prof_info
).
:- type call_site_static
Index: read_profile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/read_profile.m,v
retrieving revision 1.1
diff -u -b -r1.1 read_profile.m
--- read_profile.m 2001/05/31 05:59:58 1.1
+++ read_profile.m 2001/06/01 17:26:24
@@ -21,24 +21,13 @@
:- implementation.
:- import_module measurements, array_util.
-:- import_module array, char, string, int, float, std_util, list, require.
+:- import_module array, char, string, int, float, list, require.
+:- import_module io_combinator.
-:- type deep_result(T)
- ---> ok(T)
- ; error(string).
-
-:- type deep_result2(T1, T2)
+:- type maybe_error2(T1, T2)
---> ok2(T1, T2)
; error2(string).
-:- type ptr_info --->
- ptr_info(
- ps :: int,
- css :: int,
- pd :: int,
- csd :: int
- ).
-
:- type ptr_kind
---> ps
; pd
@@ -52,7 +41,7 @@
read_id_string(Res1),
(
{ Res1 = ok(_) },
- read_sequence7(
+ io_combinator__maybe_error_sequence_7(
read_fixed_size_int,
read_fixed_size_int,
read_fixed_size_int,
@@ -60,14 +49,13 @@
read_num,
read_num,
read_num,
- (pred(NumCSDs::in, NumCSSs::in,
- NumPDs::in, NumPSs::in,
+ (pred(MaxCSD::in, MaxCSS::in,
+ MaxPD::in, MaxPS::in,
TicksPerSec::in,
InstrumentQuanta::in,
UserQuanta::in,
ResInitDeep::out) is det :-
- init_deep(NumCSDs, NumCSSs,
- NumPDs, NumPSs,
+ init_deep(MaxCSD, MaxCSS, MaxPD, MaxPS,
TicksPerSec,
InstrumentQuanta, UserQuanta,
InitDeep0),
@@ -76,10 +64,8 @@
Res2),
(
{ Res2 = ok(InitDeep) },
- { PtrInfo0 = ptr_info(0, 0, 0, 0) },
- read_nodes(InitDeep, PtrInfo0, Res3),
- io__seen_binary,
- { resize_arrays(Res3, Res) }
+ read_nodes(InitDeep, Res),
+ io__seen_binary
;
{ Res2 = error(Err) },
{ Res = error(Err) }
@@ -94,7 +80,7 @@
{ Res = error(Msg) }
).
-:- pred read_id_string(deep_result(string)::out,
+:- pred read_id_string(maybe_error(string)::out,
io__state::di, io__state::uo) is det.
read_id_string(Res) -->
@@ -117,131 +103,119 @@
:- pred init_deep(int::in, int::in, int::in, int::in, int::in, int::in,
int::in, initial_deep::out) is det.
+
+init_deep(MaxCSD, MaxCSS, MaxPD, MaxPS, TicksPerSec,
+ InstrumentQuanta, UserQuanta, InitDeep) :-
+ InitStats = profile_stats(MaxCSD, MaxCSS, MaxPD, MaxPS,
+ TicksPerSec, InstrumentQuanta, UserQuanta),
-init_deep(NumCSDs, NumCSSs, NumPDs, NumPSs, InstrumentQuanta, UserQuanta,
- TicksPerSec, InitDeep) :-
- InitStats = profile_stats(
- InstrumentQuanta,
- UserQuanta,
- -1, -1, -1, -1,
- TicksPerSec),
InitDeep = initial_deep(
InitStats,
proc_dynamic_ptr(-1),
- array__init(NumCSDs + 1,
+ array__init(MaxCSD + 1,
call_site_dynamic(
proc_dynamic_ptr(-1),
proc_dynamic_ptr(-1),
- zero_own_prof_info,
- no
+ zero_own_prof_info
)),
- array__init(NumPDs + 1,
- proc_dynamic(proc_static_ptr(-1), array([]), no)),
- array__init(NumCSSs + 1,
+ array__init(MaxPD + 1,
+ proc_dynamic(proc_static_ptr(-1), array([]))),
+ array__init(MaxCSS + 1,
call_site_static(
proc_static_ptr(-1), -1,
normal_call(proc_static_ptr(-1), ""), -1, ""
)),
- array__init(NumPSs + 1,
+ array__init(MaxPS + 1,
proc_static(dummy_proc_id, "", "", "", array([])))
).
-:- pred read_nodes(initial_deep::in, ptr_info::in,
- deep_result2(initial_deep, ptr_info)::out,
+:- pred read_nodes(initial_deep::in, maybe_error(initial_deep)::out,
io__state::di, io__state::uo) is det.
-read_nodes(InitDeep0, PtrInfo0, Res) -->
+read_nodes(InitDeep0, Res) -->
read_byte(Res0),
(
{ Res0 = ok(Byte) },
- ( { Byte = token_call_site_static } ->
- read_call_site_static(Res1),
+ ( { Byte = token_call_site_dynamic } ->
+ read_call_site_dynamic(Res1),
(
- { Res1 = ok2(CallSiteStatic, CSSI) },
+ { Res1 = ok2(CallSiteDynamic, CSDI) },
{ deep_insert(
- InitDeep0 ^ init_call_site_statics,
- CSSI, CallSiteStatic, CSSs) },
+ InitDeep0 ^ init_call_site_dynamics,
+ CSDI, CallSiteDynamic, CSDs) },
{ InitDeep1 = InitDeep0
- ^ init_call_site_statics := CSSs },
- { PtrInfo1 = PtrInfo0 ^ css
- := max(PtrInfo0 ^ css, CSSI) },
- read_nodes(InitDeep1, PtrInfo1, Res)
+ ^ init_call_site_dynamics := CSDs },
+ read_nodes(InitDeep1, Res)
;
{ Res1 = error2(Err) },
- { Res = error2(Err) }
+ { Res = error(Err) }
)
- ; { Byte = token_proc_static } ->
- read_proc_static(Res1),
+ ; { Byte = token_proc_dynamic } ->
+ read_proc_dynamic(Res1),
(
- { Res1 = ok2(ProcStatic, PSI) },
+ { Res1 = ok2(ProcDynamic, PDI) },
{ deep_insert(
- InitDeep0 ^ init_proc_statics,
- PSI, ProcStatic, PSs) },
+ InitDeep0 ^ init_proc_dynamics,
+ PDI, ProcDynamic, PDs) },
{ InitDeep1 = InitDeep0
- ^ init_proc_statics := PSs },
- { PtrInfo1 = PtrInfo0 ^ ps
- := max(PtrInfo0 ^ ps, PSI) },
- read_nodes(InitDeep1, PtrInfo1, Res)
+ ^ init_proc_dynamics := PDs },
+ read_nodes(InitDeep1, Res)
;
{ Res1 = error2(Err) },
- { Res = error2(Err) }
+ { Res = error(Err) }
)
- ; { Byte = token_call_site_dynamic } ->
- read_call_site_dynamic(Res1),
+ ; { Byte = token_call_site_static } ->
+ read_call_site_static(Res1),
(
- { Res1 = ok2(CallSiteDynamic, CSDI) },
+ { Res1 = ok2(CallSiteStatic, CSSI) },
{ deep_insert(
- InitDeep0 ^ init_call_site_dynamics,
- CSDI, CallSiteDynamic, CSDs) },
+ InitDeep0 ^ init_call_site_statics,
+ CSSI, CallSiteStatic, CSSs) },
{ InitDeep1 = InitDeep0
- ^ init_call_site_dynamics := CSDs },
- { PtrInfo1 = PtrInfo0 ^ csd
- := max(PtrInfo0 ^ csd, CSDI) },
- read_nodes(InitDeep1, PtrInfo1, Res)
+ ^ init_call_site_statics := CSSs },
+ read_nodes(InitDeep1, Res)
;
{ Res1 = error2(Err) },
- { Res = error2(Err) }
+ { Res = error(Err) }
)
- ; { Byte = token_proc_dynamic } ->
- read_proc_dynamic(Res1),
+ ; { Byte = token_proc_static } ->
+ read_proc_static(Res1),
(
- { Res1 = ok2(ProcDynamic, PDI) },
+ { Res1 = ok2(ProcStatic, PSI) },
{ deep_insert(
- InitDeep0 ^ init_proc_dynamics,
- PDI, ProcDynamic, PDs) },
+ InitDeep0 ^ init_proc_statics,
+ PSI, ProcStatic, PSs) },
{ InitDeep1 = InitDeep0
- ^ init_proc_dynamics := PDs },
- { PtrInfo1 = PtrInfo0 ^ pd
- := max(PtrInfo0 ^ pd, PDI) },
- read_nodes(InitDeep1, PtrInfo1, Res)
+ ^ init_proc_statics := PSs },
+ read_nodes(InitDeep1, Res)
;
{ Res1 = error2(Err) },
- { Res = error2(Err) }
+ { Res = error(Err) }
)
; { Byte = token_root } ->
read_root(Res1),
(
{ Res1 = ok(PDPtr) },
{ InitDeep1 = InitDeep0 ^ init_root := PDPtr },
- read_nodes(InitDeep1, PtrInfo0, Res)
+ read_nodes(InitDeep1, Res)
;
{ Res1 = error(Err) },
- { Res = error2(Err) }
+ { Res = error(Err) }
)
;
{ format("unexpected token %d", [i(Byte)], Msg) },
- { Res = error2(Msg) }
+ { Res = error(Msg) }
)
;
{ Res0 = eof },
- { Res = ok2(InitDeep0, PtrInfo0) }
+ { Res = ok(InitDeep0) }
;
{ Res0 = error(Err) },
{ io__error_message(Err, Msg) },
- { Res = error2(Msg) }
+ { Res = error(Msg) }
).
-:- pred read_root(deep_result(proc_dynamic_ptr)::out,
+:- pred read_root(maybe_error(proc_dynamic_ptr)::out,
io__state::di, io__state::uo) is det.
read_root(Res) -->
@@ -256,12 +230,12 @@
{ Res = error(Err) }
).
-:- pred read_call_site_static(deep_result2(call_site_static, int)::out,
+:- pred read_call_site_static(maybe_error2(call_site_static, int)::out,
io__state::di, io__state::uo) is det.
read_call_site_static(Res) -->
% format("reading call_site_static.\n", []),
- read_sequence4(
+ io_combinator__maybe_error_sequence_4(
read_ptr(css),
read_call_site_kind_and_callee,
read_num,
@@ -284,12 +258,12 @@
).
-:- pred read_proc_static(deep_result2(proc_static, int)::out,
+:- pred read_proc_static(maybe_error2(proc_static, int)::out,
io__state::di, io__state::uo) is det.
read_proc_static(Res) -->
% format("reading proc_static.\n", []),
- read_sequence4(
+ io_combinator__maybe_error_sequence_4(
read_ptr(ps),
read_proc_id,
read_string,
@@ -321,7 +295,7 @@
{ Res = error2(Err) }
).
-:- pred read_proc_id(deep_result(proc_id)::out,
+:- pred read_proc_id(maybe_error(proc_id)::out,
io__state::di, io__state::uo) is det.
read_proc_id(Res) -->
@@ -344,11 +318,11 @@
{ Res = error(Err) }
).
-:- pred read_proc_id_compiler_generated(deep_result(proc_id)::out,
+:- pred read_proc_id_compiler_generated(maybe_error(proc_id)::out,
io__state::di, io__state::uo) is det.
read_proc_id_compiler_generated(Res) -->
- read_sequence6(
+ io_combinator__maybe_error_sequence_6(
read_string,
read_string,
read_string,
@@ -363,11 +337,11 @@
),
Res).
-:- pred read_proc_id_user_defined(pred_or_func::in, deep_result(proc_id)::out,
+:- pred read_proc_id_user_defined(pred_or_func::in, maybe_error(proc_id)::out,
io__state::di, io__state::uo) is det.
read_proc_id_user_defined(PredOrFunc, Res) -->
- read_sequence5(
+ io_combinator__maybe_error_sequence_5(
read_string,
read_string,
read_string,
@@ -525,12 +499,12 @@
fail
).
-:- pred read_proc_dynamic(deep_result2(proc_dynamic, int)::out,
+:- pred read_proc_dynamic(maybe_error2(proc_dynamic, int)::out,
io__state::di, io__state::uo) is det.
read_proc_dynamic(Res) -->
% format("reading proc_dynamic.\n", []),
- read_sequence3(
+ io_combinator__maybe_error_sequence_3(
read_ptr(pd),
read_ptr(ps),
read_num,
@@ -544,7 +518,7 @@
(
{ Res2 = ok(Refs) },
{ PSPtr = proc_static_ptr(PSI) },
- { ProcDynamic = proc_dynamic(PSPtr, array(Refs), no) },
+ { ProcDynamic = proc_dynamic(PSPtr, array(Refs)) },
{ Res = ok2(ProcDynamic, PDI) }
;
{ Res2 = error(Err) },
@@ -555,7 +529,7 @@
{ Res = error2(Err) }
).
-:- pred read_call_site_dynamic(deep_result2(call_site_dynamic, int)::out,
+:- pred read_call_site_dynamic(maybe_error2(call_site_dynamic, int)::out,
io__state::di, io__state::uo) is det.
read_call_site_dynamic(Res) -->
@@ -572,7 +546,7 @@
{ PDPtr = proc_dynamic_ptr(PDI) },
{ DummyPDPtr = proc_dynamic_ptr(-1) },
{ CallSiteDynamic = call_site_dynamic(
- DummyPDPtr, PDPtr, Profile, no) },
+ DummyPDPtr, PDPtr, Profile) },
{ Res = ok2(CallSiteDynamic, CSDI) }
;
{ Res3 = error(Err) },
@@ -587,7 +561,7 @@
{ Res = error2(Err) }
).
-:- pred read_profile(deep_result(own_prof_info)::out,
+:- pred read_profile(maybe_error(own_prof_info)::out,
io__state::di, io__state::uo) is det.
read_profile(Res) -->
@@ -651,8 +625,7 @@
{ Res = error(Error) }
;
{ MaybeError7 = no },
- { Calls = Exits + Fails - Redos },
- { Res = ok(compress_profile(Calls, Exits, Fails, Redos,
+ { Res = ok(compress_profile(Exits, Fails, Redos,
Quanta, Mallocs, Words)) }
)
;
@@ -675,7 +648,7 @@
{ MaybeError = yes(Error) }
).
-:- pred read_call_site_ref(deep_result(call_site_array_slot)::out,
+:- pred read_call_site_ref(maybe_error(call_site_array_slot)::out,
io__state::di, io__state::uo) is det.
read_call_site_ref(Res) -->
@@ -711,7 +684,7 @@
{ Res = error(Err) }
).
-:- pred read_call_site_kind(deep_result(call_site_kind)::out,
+:- pred read_call_site_kind(maybe_error(call_site_kind)::out,
io__state::di, io__state::uo) is det.
read_call_site_kind(Res) -->
@@ -742,7 +715,7 @@
).
:- pred read_call_site_kind_and_callee(
- deep_result(call_site_kind_and_callee)::out,
+ maybe_error(call_site_kind_and_callee)::out,
io__state::di, io__state::uo) is det.
read_call_site_kind_and_callee(Res) -->
@@ -791,8 +764,8 @@
%-----------------------------------------------------------------------------%
-:- pred read_n_things(int, pred(deep_result(T), io__state, io__state),
- deep_result(list(T)), io__state, io__state).
+:- pred read_n_things(int, pred(maybe_error(T), io__state, io__state),
+ maybe_error(list(T)), io__state, io__state).
:- mode read_n_things(in, pred(out, di, uo) is det, out, di, uo) is det.
read_n_things(N, ThingReader, Res) -->
@@ -806,8 +779,8 @@
{ Res = error(Err) }
).
-:- pred read_n_things(int, pred(deep_result(T), io__state, io__state),
- list(T), deep_result(list(T)), io__state, io__state).
+:- pred read_n_things(int, pred(maybe_error(T), io__state, io__state),
+ list(T), maybe_error(list(T)), io__state, io__state).
:- mode read_n_things(in, pred(out, di, uo) is det, in, out, di, uo) is det.
read_n_things(N, ThingReader, Things0, Res) -->
@@ -824,15 +797,15 @@
)
).
-:- pred read_things(pred(deep_result(T), io__state, io__state),
- deep_result(list(T)), io__state, io__state).
+:- pred read_things(pred(maybe_error(T), io__state, io__state),
+ maybe_error(list(T)), io__state, io__state).
:- mode read_things(pred(out, di, uo) is det, out, di, uo) is det.
read_things(ThingReader, Res) -->
read_things(ThingReader, [], Res).
-:- pred read_things(pred(deep_result(T), io__state, io__state),
- list(T), deep_result(list(T)), io__state, io__state).
+:- pred read_things(pred(maybe_error(T), io__state, io__state),
+ list(T), maybe_error(list(T)), io__state, io__state).
:- mode read_things(pred(out, di, uo) is det, in, out, di, uo) is det.
read_things(ThingReader, Things0, Res) -->
@@ -858,317 +831,8 @@
).
%-----------------------------------------------------------------------------%
-
-:- pred read_sequence2(
- pred(deep_result(T1), io__state, io__state),
- pred(deep_result(T2), io__state, io__state),
- pred(T1, T2, deep_result(T3)),
- deep_result(T3), io__state, io__state).
-:- mode read_sequence2(
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(in, in, out) is det,
- out, di, uo) is det.
-
-read_sequence2(P1, P2, Combine, Res) -->
- call(P1, Res1),
- (
- { Res1 = ok(T1) },
- call(P2, Res2),
- (
- { Res2 = ok(T2) },
- { call(Combine, T1, T2, Res) }
- ;
- { Res2 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res1 = error(Err) },
- { Res = error(Err) }
- ).
-
-:- pred read_sequence3(
- pred(deep_result(T1), io__state, io__state),
- pred(deep_result(T2), io__state, io__state),
- pred(deep_result(T3), io__state, io__state),
- pred(T1, T2, T3, deep_result(T4)),
- deep_result(T4), io__state, io__state).
-:- mode read_sequence3(
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(in, in, in, out) is det,
- out, di, uo) is det.
-
-read_sequence3(P1, P2, P3, Combine, Res) -->
- call(P1, Res1),
- (
- { Res1 = ok(T1) },
- call(P2, Res2),
- (
- { Res2 = ok(T2) },
- call(P3, Res3),
- (
- { Res3 = ok(T3) },
- { call(Combine, T1, T2, T3, Res) }
- ;
- { Res3 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res2 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res1 = error(Err) },
- { Res = error(Err) }
- ).
-:- pred read_sequence4(
- pred(deep_result(T1), io__state, io__state),
- pred(deep_result(T2), io__state, io__state),
- pred(deep_result(T3), io__state, io__state),
- pred(deep_result(T4), io__state, io__state),
- pred(T1, T2, T3, T4, deep_result(T5)),
- deep_result(T5), io__state, io__state).
-:- mode read_sequence4(
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(in, in, in, in, out) is det,
- out, di, uo) is det.
-
-read_sequence4(P1, P2, P3, P4, Combine, Res) -->
- call(P1, Res1),
- (
- { Res1 = ok(T1) },
- call(P2, Res2),
- (
- { Res2 = ok(T2) },
- call(P3, Res3),
- (
- { Res3 = ok(T3) },
- call(P4, Res4),
- (
- { Res4 = ok(T4) },
- { call(Combine, T1, T2, T3, T4, Res) }
- ;
- { Res4 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res3 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res2 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res1 = error(Err) },
- { Res = error(Err) }
- ).
-
-:- pred read_sequence5(
- pred(deep_result(T1), io__state, io__state),
- pred(deep_result(T2), io__state, io__state),
- pred(deep_result(T3), io__state, io__state),
- pred(deep_result(T4), io__state, io__state),
- pred(deep_result(T5), io__state, io__state),
- pred(T1, T2, T3, T4, T5, deep_result(T6)),
- deep_result(T6), io__state, io__state).
-:- mode read_sequence5(
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(in, in, in, in, in, out) is det,
- out, di, uo) is det.
-
-read_sequence5(P1, P2, P3, P4, P5, Combine, Res) -->
- call(P1, Res1),
- (
- { Res1 = ok(T1) },
- call(P2, Res2),
- (
- { Res2 = ok(T2) },
- call(P3, Res3),
- (
- { Res3 = ok(T3) },
- call(P4, Res4),
- (
- { Res4 = ok(T4) },
- call(P5, Res5),
- (
- { Res5 = ok(T5) },
- { call(Combine, T1, T2, T3, T4,
- T5, Res) }
- ;
- { Res5 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res4 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res3 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res2 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res1 = error(Err) },
- { Res = error(Err) }
- ).
-
-:- pred read_sequence6(
- pred(deep_result(T1), io__state, io__state),
- pred(deep_result(T2), io__state, io__state),
- pred(deep_result(T3), io__state, io__state),
- pred(deep_result(T4), io__state, io__state),
- pred(deep_result(T5), io__state, io__state),
- pred(deep_result(T6), io__state, io__state),
- pred(T1, T2, T3, T4, T5, T6, deep_result(T7)),
- deep_result(T7), io__state, io__state).
-:- mode read_sequence6(
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(in, in, in, in, in, in, out) is det,
- out, di, uo) is det.
-
-read_sequence6(P1, P2, P3, P4, P5, P6, Combine, Res) -->
- call(P1, Res1),
- (
- { Res1 = ok(T1) },
- call(P2, Res2),
- (
- { Res2 = ok(T2) },
- call(P3, Res3),
- (
- { Res3 = ok(T3) },
- call(P4, Res4),
- (
- { Res4 = ok(T4) },
- call(P5, Res5),
- (
- { Res5 = ok(T5) },
- call(P6, Res6),
- (
- { Res6 = ok(T6) },
- { call(Combine, T1, T2,
- T3, T4, T5,
- T6, Res) }
- ;
- { Res6 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res5 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res4 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res3 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res2 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res1 = error(Err) },
- { Res = error(Err) }
- ).
-
-:- pred read_sequence7(
- pred(deep_result(T1), io__state, io__state),
- pred(deep_result(T2), io__state, io__state),
- pred(deep_result(T3), io__state, io__state),
- pred(deep_result(T4), io__state, io__state),
- pred(deep_result(T5), io__state, io__state),
- pred(deep_result(T6), io__state, io__state),
- pred(deep_result(T7), io__state, io__state),
- pred(T1, T2, T3, T4, T5, T6, T7, deep_result(T8)),
- deep_result(T8), io__state, io__state).
-:- mode read_sequence7(
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(out, di, uo) is det,
- pred(in, in, in, in, in, in, in, out) is det,
- out, di, uo) is det.
-
-read_sequence7(P1, P2, P3, P4, P5, P6, P7, Combine, Res) -->
- call(P1, Res1),
- (
- { Res1 = ok(T1) },
- call(P2, Res2),
- (
- { Res2 = ok(T2) },
- call(P3, Res3),
- (
- { Res3 = ok(T3) },
- call(P4, Res4),
- (
- { Res4 = ok(T4) },
- call(P5, Res5),
- (
- { Res5 = ok(T5) },
- call(P6, Res6),
- (
- { Res6 = ok(T6) },
- call(P7, Res7),
- (
- { Res7 = ok(T7) },
- { call(Combine, T1, T2, T3, T4, T5, T6, T7,
- Res) }
- ;
- { Res7 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res6 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res5 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res4 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res3 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res2 = error(Err) },
- { Res = error(Err) }
- )
- ;
- { Res1 = error(Err) },
- { Res = error(Err) }
- ).
-
-%-----------------------------------------------------------------------------%
-
-:- pred read_string(deep_result(string)::out,
+:- pred read_string(maybe_error(string)::out,
io__state::di, io__state::uo) is det.
read_string(Res) -->
@@ -1185,7 +849,7 @@
{ Res = error(Err) }
).
-:- pred read_n_byte_string(int::in, deep_result(string)::out,
+:- pred read_n_byte_string(int::in, maybe_error(string)::out,
io__state::di, io__state::uo) is det.
read_n_byte_string(Length, Res) -->
@@ -1210,7 +874,7 @@
% io__write(Res),
% io__write_string("\n")
-:- pred read_ptr(ptr_kind::in, deep_result(int)::out,
+:- pred read_ptr(ptr_kind::in, maybe_error(int)::out,
io__state::di, io__state::uo) is det.
read_ptr(_Kind, Res) -->
@@ -1219,7 +883,7 @@
% io__write(Res),
% io__write_string("\n").
-:- pred read_num(deep_result(int)::out, io__state::di, io__state::uo) is det.
+:- pred read_num(maybe_error(int)::out, io__state::di, io__state::uo) is det.
read_num(Res) -->
read_num1(0, Res).
@@ -1227,7 +891,7 @@
% io__write(Res),
% io__write_string("\n").
-:- pred read_num1(int::in, deep_result(int)::out,
+:- pred read_num1(int::in, maybe_error(int)::out,
io__state::di, io__state::uo) is det.
read_num1(Num0, Res) -->
@@ -1256,13 +920,13 @@
fixed_size_int_bytes = 4.
-:- pred read_fixed_size_int(deep_result(int)::out,
+:- pred read_fixed_size_int(maybe_error(int)::out,
io__state::di, io__state::uo) is det.
read_fixed_size_int(Res) -->
read_fixed_size_int1(fixed_size_int_bytes, 0, 0, Res).
-:- pred read_fixed_size_int1(int::in, int::in, int::in, deep_result(int)::out,
+:- pred read_fixed_size_int1(int::in, int::in, int::in, maybe_error(int)::out,
io__state::di, io__state::uo) is det.
read_fixed_size_int1(BytesLeft, Num0, ShiftBy, Res) -->
@@ -1281,7 +945,7 @@
)
).
-:- pred read_n_bytes(int::in, deep_result(list(int))::out,
+:- pred read_n_bytes(int::in, maybe_error(list(int))::out,
io__state::di, io__state::uo) is det.
read_n_bytes(N, Res) -->
@@ -1295,7 +959,7 @@
{ Res = error(Err) }
).
-:- pred read_n_bytes(int::in, list(int)::in, deep_result(list(int))::out,
+:- pred read_n_bytes(int::in, list(int)::in, maybe_error(list(int))::out,
io__state::di, io__state::uo) is det.
read_n_bytes(N, Bytes0, Res) -->
@@ -1312,7 +976,7 @@
)
).
-:- pred read_deep_byte(deep_result(int)::out,
+:- pred read_deep_byte(maybe_error(int)::out,
io__state::di, io__state::uo) is det.
read_deep_byte(Res) -->
@@ -1419,41 +1083,3 @@
%------------------------------------------------------------------------------%
%------------------------------------------------------------------------------%
-
-:- pred resize_arrays(deep_result2(initial_deep, ptr_info)::in,
- maybe_error(initial_deep)::out) is det.
-
-resize_arrays(error2(Err), error(Err)).
-resize_arrays(ok2(InitDeep0, PI), ok(InitDeep)) :-
- PI ^ csd = CSDMax,
- CSDs0 = InitDeep0 ^ init_call_site_dynamics,
- array__lookup(CSDs0, 0, CSDx),
- array__resize(u(CSDs0), CSDMax + 1, CSDx, CSDs),
- InitDeep1 = InitDeep0 ^ init_call_site_dynamics := CSDs,
-
- PI ^ pd = PDMax,
- PDs0 = InitDeep1 ^ init_proc_dynamics,
- array__lookup(PDs0, 0, PDx),
- array__resize(u(PDs0), PDMax + 1, PDx, PDs),
- InitDeep2 = InitDeep1 ^ init_proc_dynamics := PDs,
-
- PI ^ css = CSSMax,
- CSSs0 = InitDeep2 ^ init_call_site_statics,
- array__lookup(CSSs0, 0, CSSx),
- array__resize(u(CSSs0), CSSMax + 1, CSSx, CSSs),
- InitDeep3 = InitDeep2 ^ init_call_site_statics := CSSs,
-
- PI ^ ps = PSMax,
- PSs0 = InitDeep3 ^ init_proc_statics,
- array__lookup(PSs0, 0, PSx),
- array__resize(u(PSs0), PSMax + 1, PSx, PSs),
- InitDeep4 = InitDeep3 ^ init_proc_statics := PSs,
-
- ProfileStats0 = InitDeep4 ^ init_profile_stats,
- ProfileStats0 = profile_stats(InstrumentQuanta, UserQuanta,
- _, _, _, _, TicksPerSec),
- ProfileStats = profile_stats(InstrumentQuanta, UserQuanta,
- CSDMax, PDMax, CSSMax, PSMax, TicksPerSec),
- InitDeep = InitDeep4 ^ init_profile_stats := ProfileStats.
-
-%-----------------------------------------------------------------------------%
Index: server.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/server.m,v
retrieving revision 1.1
diff -u -b -r1.1 server.m
--- server.m 2001/05/31 05:59:58 1.1
+++ server.m 2001/06/04 09:54:43
@@ -52,7 +52,8 @@
test_cliques(Cur, Max, DirName, Deep, Fields) -->
( { Cur =< Max } ->
- { try_exec(clique(Cur, Fields), Deep, HTML) },
+ { try_exec(clique(Cur, Fields, default_ancestor_limit),
+ Deep, HTML) },
write_html(DirName, "clique", Cur, HTML),
test_cliques(Cur + 1, Max, DirName, Deep, Fields)
;
@@ -176,7 +177,7 @@
{ ReadRes = error(Msg, Line) },
(
{ Debug = yes },
- format(StdErr,
+ io__format(StdErr,
"error reading input line %d: %s\n",
[i(Line), s(Msg)])
;
@@ -189,7 +190,7 @@
{ try_exec(Cmd, Deep, HTML) },
(
{ Debug = yes },
- format(StdErr, "query %d output:\n%s\n",
+ io__format(StdErr, "query %d output:\n%s\n",
[i(QueryNum), s(HTML)])
;
{ Debug = no }
@@ -237,7 +238,8 @@
Msg = "unknown exception"
),
HTML =
- format("<H1>AN EXCEPTION HAS OCCURRED: %s.</H1>\n",
+ string__format(
+ "<H1>AN EXCEPTION HAS OCCURRED: %s.</H1>\n",
[s(Msg)])
).
@@ -246,12 +248,14 @@
exec(Cmd, Deep, HTML) :-
Cmd = quit,
HTML =
- format("<H1>Shutting down deep profile server for %s.</H1>\n",
+ string__format(
+ "<H1>Shutting down deep profile server for %s.</H1>\n",
[s(Deep ^ data_file_name)]).
exec(Cmd, _Deep, HTML) :-
Cmd = timeout(TimeOut),
- HTML = format("<H1>Timeout set to %d minutes</H1>\n", [i(TimeOut)]).
+ HTML = string__format("<H1>Timeout set to %d minutes</H1>\n",
+ [i(TimeOut)]).
exec(Cmd, Deep, HTML) :-
Cmd = menu,
@@ -308,16 +312,17 @@
Cmd = root(Fields),
deep_lookup_clique_index(Deep, Deep ^ root, RootCliquePtr),
RootCliquePtr = clique_ptr(RootCliqueNum),
- exec(clique(RootCliqueNum, Fields), Deep, HTML).
+ exec(clique(RootCliqueNum, Fields, default_ancestor_limit),
+ Deep, HTML).
exec(Cmd, Deep, HTML) :-
- Cmd = clique(CliqueNum, Fields),
+ Cmd = clique(CliqueNum, Fields, MaybeAncestorLimit),
( valid_clique_ptr(Deep, clique_ptr(CliqueNum)) ->
HTML =
banner ++
- "<TABLE>\n" ++
+ "<TABLE border=1 rules=cols frame=void>\n" ++
fields_header(Fields) ++
- clique_to_html(Deep, Fields,
+ clique_to_html(Deep, Fields, MaybeAncestorLimit,
clique_ptr(CliqueNum)) ++
"</TABLE>\n" ++
footer(Cmd, Deep)
@@ -398,7 +403,7 @@
PSPtr = proc_static_ptr(PSI),
HTML =
"<HTML>\n" ++
- format("proc_static %d, ", [i(PSI)]) ++
+ string__format("proc_static %d, ", [i(PSI)]) ++
array_slots_to_html(PD ^ pd_sites) ++
"</HTML>\n"
;
@@ -456,7 +461,7 @@
( valid_clique_ptr(Deep, CliquePtr) ->
deep_lookup_clique_parents(Deep, CliquePtr, Parent),
Parent = call_site_dynamic_ptr(ParentPDI),
- ParentStr = format("%d ->", [i(ParentPDI)]),
+ ParentStr = string__format("%d ->", [i(ParentPDI)]),
deep_lookup_clique_members(Deep, CliquePtr, Members),
HTML =
"<HTML>\n" ++
@@ -474,28 +479,28 @@
Cmd = num_proc_dynamics,
HTML =
"<HTML>\n" ++
- string__int_to_string(Deep ^ profile_stats ^ num_pds) ++
+ string__int_to_string(Deep ^ profile_stats ^ max_pd) ++
"</HTML>\n".
exec(Cmd, Deep, HTML) :-
Cmd = num_call_site_dynamics,
HTML =
"<HTML>\n" ++
- string__int_to_string(Deep ^ profile_stats ^ num_csds) ++
+ string__int_to_string(Deep ^ profile_stats ^ max_csd) ++
"</HTML>\n".
exec(Cmd, Deep, HTML) :-
Cmd = num_proc_statics,
HTML =
"<HTML>\n" ++
- string__int_to_string(Deep ^ profile_stats ^ num_pss) ++
+ string__int_to_string(Deep ^ profile_stats ^ max_ps) ++
"</HTML>\n".
exec(Cmd, Deep, HTML) :-
Cmd = num_call_site_statics,
HTML =
"<HTML>\n" ++
- string__int_to_string(Deep ^ profile_stats ^ num_csss) ++
+ string__int_to_string(Deep ^ profile_stats ^ max_css) ++
"</HTML>\n".
%-----------------------------------------------------------------------------%
@@ -521,7 +526,8 @@
array__to_list(CSDPtrArray, CSDPtrs),
list__foldl(append_csdi_to_string, CSDPtrs, "", CSDI_HTML),
list__length(CSDPtrs, CSDPtrCount),
- HTML = format("multi(%d): [", [i(CSDPtrCount)]) ++ CSDI_HTML ++ "]".
+ HTML = string__format("multi(%d): [", [i(CSDPtrCount)])
+ ++ CSDI_HTML ++ "]".
:- pred append_csdi_to_string(call_site_dynamic_ptr::in,
string::in, string::out) is det.
@@ -549,37 +555,57 @@
present_stats(Deep) = HTML :-
Stats = Deep ^ profile_stats,
+ lookup_ticks_per_sec(Stats, TicksPerSec, Assumed),
+ (
+ Assumed = yes,
+ AssumedStr = " (assumed)"
+ ;
+ Assumed = no,
+ AssumedStr = ""
+ ),
HTML =
"<TABLE>\n" ++
+ "<TR><TD ALIGN=left>Quanta per second:</TD>\n" ++
+ string__format("<TD ALIGN=right>%d%s</TD></TR>\n",
+ [i(TicksPerSec), s(AssumedStr)]) ++
"<TR><TD ALIGN=left>Quanta in user code:</TD>\n" ++
- format("<TD ALIGN=right>%d</TD></TR>\n",
+ string__format("<TD ALIGN=right>%d</TD></TR>\n",
[i(Stats ^ user_quanta)]) ++
"<TR><TD ALIGN=left>Quanta in instrumentation:</TD>\n" ++
- format("<TD ALIGN=right>%d</TD></TR>\n",
+ string__format("<TD ALIGN=right>%d</TD></TR>\n",
[i(Stats ^ instrument_quanta)]) ++
"<TR><TD ALIGN=left>CallSiteDynamic structures:</TD>\n" ++
- format("<TD ALIGN=right>%d</TD></TR>\n",
- [i(Stats ^ num_csds)]) ++
+ string__format("<TD ALIGN=right>%d</TD></TR>\n",
+ [i(Stats ^ max_csd)]) ++
"<TR><TD ALIGN=left>ProcDynamic structures:</TD>\n" ++
- format("<TD ALIGN=right>%d</TD></TR>\n",
- [i(Stats ^ num_pds)]) ++
+ string__format("<TD ALIGN=right>%d</TD></TR>\n",
+ [i(Stats ^ max_pd)]) ++
"<TR><TD ALIGN=left>CallSiteStatic structures:</TD>\n" ++
- format("<TD ALIGN=right>%d</TD></TR>\n",
- [i(Stats ^ num_csss)]) ++
+ string__format("<TD ALIGN=right>%d</TD></TR>\n",
+ [i(Stats ^ max_css)]) ++
"<TR><TD ALIGN=left>ProcStatic structures:</TD>\n" ++
- format("<TD ALIGN=right>%d</TD></TR>\n",
- [i(Stats ^ num_pss)]) ++
+ string__format("<TD ALIGN=right>%d</TD></TR>\n",
+ [i(Stats ^ max_ps)]) ++
"<TR><TD ALIGN=left>Cliques:</TD>\n" ++
- format("<TD ALIGN=right>%d</TD></TR>\n",
+ string__format("<TD ALIGN=right>%d</TD></TR>\n",
[i(array__max(Deep ^ clique_members))]) ++
"</TABLE>\n".
%-----------------------------------------------------------------------------%
-:- func clique_to_html(deep, fields, clique_ptr) = string.
+:- func clique_to_html(deep, fields, maybe(int), clique_ptr) = string.
-clique_to_html(Deep, Fields, CliquePtr) = HTML :-
- Ancestors = clique_ancestors_to_html(Deep, Fields, CliquePtr),
+clique_to_html(Deep, Fields, MaybeAncestorLimit, CliquePtr) = HTML :-
+ (
+ MaybeAncestorLimit = yes(AncestorLimit),
+ RespectLimit = yes
+ ;
+ MaybeAncestorLimit = no,
+ AncestorLimit = 0, % the value doesn't matter
+ RespectLimit = no
+ ),
+ Ancestors = clique_ancestors_to_html(Deep, Fields, MaybeAncestorLimit,
+ AncestorLimit, RespectLimit, CliquePtr),
deep_lookup_clique_members(Deep, CliquePtr, PDPtrs),
list__foldl(group_proc_dynamics_by_proc_static(Deep), PDPtrs,
map__init, PStoPDsMap),
@@ -596,8 +622,8 @@
PStoPDsList = PStoPDsList0
),
- PDsStrs = list__map(procs_in_clique_to_html(Deep, Fields, CliquePtr),
- PStoPDsList),
+ PDsStrs = list__map(procs_in_clique_to_html(Deep, Fields,
+ MaybeAncestorLimit, CliquePtr), PStoPDsList),
string__append_list(PDsStrs, ProcGroups),
HTML =
Ancestors ++
@@ -611,23 +637,29 @@
proc_group_contains(EntryPDPtr, _ - PDPtrs) :-
list__member(EntryPDPtr, PDPtrs).
-:- func clique_ancestors_to_html(deep, fields, clique_ptr) = string.
+:- func clique_ancestors_to_html(deep, fields, maybe(int), int, bool,
+ clique_ptr) = string.
-clique_ancestors_to_html(Deep, Fields, CliquePtr) = HTML :-
+clique_ancestors_to_html(Deep, Fields, OrigMaybeAncestorLimit,
+ AncestorLimit, RespectLimit, CliquePtr) = HTML :-
deep_lookup_clique_index(Deep, Deep ^ root, RootCliquePtr),
( CliquePtr = RootCliquePtr ->
HTML = ""
+ ; RespectLimit = yes, AncestorLimit =< 0 ->
+ HTML = "<TR><TD>..."
;
deep_lookup_clique_parents(Deep, CliquePtr, EntryCSDPtr),
ThisHTML = call_site_dynamic_to_html(Deep, Fields,
- call_site_line_number, no, EntryCSDPtr),
+ OrigMaybeAncestorLimit, call_site_line_number,
+ no, EntryCSDPtr),
deep_lookup_call_site_dynamics(Deep, EntryCSDPtr, EntryCSD),
EntryPDPtr = EntryCSD ^ csd_caller,
require(valid_proc_dynamic_ptr(Deep, EntryPDPtr),
"clique_ancestors_to_html: invalid proc_dynamic"),
deep_lookup_clique_index(Deep, EntryPDPtr, EntryCliquePtr),
AncestorHTML = clique_ancestors_to_html(Deep, Fields,
- EntryCliquePtr),
+ OrigMaybeAncestorLimit,
+ AncestorLimit - 1, RespectLimit, EntryCliquePtr),
HTML =
AncestorHTML ++
ThisHTML
@@ -649,14 +681,16 @@
map__det_insert(PStoPDsMap0, PSPtr, [PDPtr], PStoPDsMap)
).
-:- func procs_in_clique_to_html(deep, fields, clique_ptr,
+:- func procs_in_clique_to_html(deep, fields, maybe(int), clique_ptr,
pair(proc_static_ptr, list(proc_dynamic_ptr))) = string.
-procs_in_clique_to_html(Deep, Fields, CliquePtr, PSPtr - PDPtrs) = HTML :-
+procs_in_clique_to_html(Deep, Fields, OrigMaybeAncestorLimit, CliquePtr,
+ PSPtr - PDPtrs) = HTML :-
( PDPtrs = [] ->
HTML = ""
; PDPtrs = [PDPtr] ->
- HTML = proc_in_clique_to_html(Deep, Fields, CliquePtr, PDPtr)
+ HTML = proc_in_clique_to_html(Deep, Fields,
+ OrigMaybeAncestorLimit, CliquePtr, PDPtr)
;
Separator = separator_row(Fields),
list__map(deep_lookup_pd_own(Deep), PDPtrs, ProcOwns),
@@ -666,7 +700,7 @@
ProcTotal = proc_total_in_clique(Deep, Fields,
PSPtr, no, ProcOwn, ProcDesc),
ComponentHTMLs = list__map(proc_in_clique_to_html(Deep, Fields,
- CliquePtr), PDPtrs),
+ OrigMaybeAncestorLimit, CliquePtr), PDPtrs),
string__append_list(ComponentHTMLs, ComponentHTML),
HTML =
Separator ++
@@ -675,10 +709,11 @@
ComponentHTML
).
-:- func proc_in_clique_to_html(deep, fields, clique_ptr, proc_dynamic_ptr)
- = string.
+:- func proc_in_clique_to_html(deep, fields, maybe(int), clique_ptr,
+ proc_dynamic_ptr) = string.
-proc_in_clique_to_html(Deep, Fields, CliquePtr, PDPtr) = HTML :-
+proc_in_clique_to_html(Deep, Fields, OrigMaybeAncestorLimit, CliquePtr, PDPtr)
+ = HTML :-
( valid_proc_dynamic_ptr(Deep, PDPtr) ->
InitialSeparator = separator_row(Fields),
deep_lookup_pd_own(Deep, PDPtr, ProcOwn),
@@ -689,7 +724,8 @@
PSPtr, yes, ProcOwn, ProcDesc),
child_call_sites(Deep ^ proc_dynamics, Deep ^ proc_statics,
PDPtr, GroupPairs),
- list__foldl(call_site_group_to_html(Deep, Fields, CliquePtr),
+ list__foldl(call_site_group_to_html(Deep, Fields,
+ OrigMaybeAncestorLimit, CliquePtr),
GroupPairs, map__init, GroupMap),
map__to_assoc_list(GroupMap, GroupPairLists),
assoc_list__values(GroupPairLists, GroupLists),
@@ -736,18 +772,18 @@
),
HTML =
"<TR>\n" ++
- format("<TD COLSPAN=2><B>%s%s</B></TD>\n",
+ string__format("<TD COLSPAN=2><B>%s%s</B></TD>\n",
[s(OnlyStr), s(ProcName)]) ++
own_and_desc_to_html(Own, Desc, Deep, Fields) ++
"</TR>\n".
-:- pred call_site_group_to_html(deep::in, fields::in,
+:- pred call_site_group_to_html(deep::in, fields::in, maybe(int)::in,
clique_ptr::in, pair(call_site_static_ptr, call_site_array_slot)::in,
map(pair(string, int), list(string))::in,
map(pair(string, int), list(string))::out) is det.
-call_site_group_to_html(Deep, Fields, ThisCliquePtr, Pair,
- GroupMap0, GroupMap) :-
+call_site_group_to_html(Deep, Fields, OrigMaybeAncestorLimit, ThisCliquePtr,
+ Pair, GroupMap0, GroupMap) :-
Pair = CSSPtr - CallSiteArray,
deep_lookup_call_site_statics(Deep, CSSPtr, CSS),
CSS = call_site_static(PSPtr, _SlotNum, Kind, LineNumber, _GoalPath),
@@ -760,7 +796,8 @@
error("call_site_group_to_html: normal_call error")
),
HTML = maybe_call_site_dynamic_to_html(Deep, Fields,
- call_site_line_number, ThisCliquePtr, CSDPtr)
+ OrigMaybeAncestorLimit, call_site_line_number,
+ ThisCliquePtr, CSDPtr)
;
( CallSiteArray = multi(CSDPtrs0) ->
array__to_list(CSDPtrs0, CSDPtrs)
@@ -769,8 +806,8 @@
),
Tuple0 = { "", zero_own_prof_info, zero_inherit_prof_info },
Tuple = list__foldl(call_site_array_to_html(Deep, Fields,
- no_call_site_line_number, ThisCliquePtr),
- CSDPtrs, Tuple0),
+ OrigMaybeAncestorLimit, no_call_site_line_number,
+ ThisCliquePtr), CSDPtrs, Tuple0),
Tuple = { GroupHTML, SumOwn, SumDesc },
CallSiteName0 = call_site_kind_and_callee_to_html(Kind),
( GroupHTML = "" ->
@@ -780,9 +817,9 @@
),
HTML =
"<TR>\n" ++
- format("<TD>%s:%d</TD>\n",
+ string__format("<TD>%s:%d</TD>\n",
[s(FileName), i(LineNumber)]) ++
- format("<TD>%s</TD>\n", [s(CallSiteName)]) ++
+ string__format("<TD>%s</TD>\n", [s(CallSiteName)]) ++
own_and_desc_to_html(SumOwn, SumDesc, Deep, Fields) ++
"</TR>\n" ++
GroupHTML
@@ -794,17 +831,19 @@
map__det_insert(GroupMap0, Key, [HTML], GroupMap)
).
-:- func call_site_array_to_html(deep, fields, call_site_line_number,
- clique_ptr, call_site_dynamic_ptr,
+:- func call_site_array_to_html(deep, fields, maybe(int),
+ call_site_line_number, clique_ptr, call_site_dynamic_ptr,
{string, own_prof_info, inherit_prof_info}) =
{string, own_prof_info, inherit_prof_info}.
-call_site_array_to_html(Deep, Fields, PrintCallSiteLineNmber,
- ThisCliquePtr, CSDPtr, Tuple0) = Tuple :-
+call_site_array_to_html(Deep, Fields, OrigMaybeAncestorLimit,
+ PrintCallSiteLineNmber, ThisCliquePtr, CSDPtr, Tuple0)
+ = Tuple :-
( valid_call_site_dynamic_ptr(Deep, CSDPtr) ->
Tuple0 = { HTML0, Own0, Desc0 },
HTML1 = call_site_dynamic_to_html(Deep, Fields,
- PrintCallSiteLineNmber, yes(ThisCliquePtr), CSDPtr),
+ OrigMaybeAncestorLimit, PrintCallSiteLineNmber,
+ yes(ThisCliquePtr), CSDPtr),
string__append(HTML0, HTML1, HTML),
deep_lookup_csd_own(Deep, CSDPtr, CallSiteOwn),
deep_lookup_csd_desc(Deep, CSDPtr, CallSiteDesc),
@@ -848,12 +887,13 @@
process_call_site_dynamics_group(CSDPtrs, Deep, CalleePSPtr,
MaybeToCliquePtr1, MaybeToCliquePtr, Own1, Own, Desc1, Desc).
-:- func call_site_dynamics_to_html(deep, fields, maybe(pair(string, int)),
- clique_ptr, clique_ptr, proc_static_ptr,
+:- func call_site_dynamics_to_html(deep, fields, maybe(int),
+ maybe(pair(string, int)), clique_ptr, clique_ptr, proc_static_ptr,
own_prof_info, inherit_prof_info) = string.
-call_site_dynamics_to_html(Deep, Fields, MaybeFileNameLineNumber,
- ThisCliquePtr, ToCliquePtr, PSPtr, Own, Desc) = HTML :-
+call_site_dynamics_to_html(Deep, Fields, OrigMaybeAncestorLimit,
+ MaybeFileNameLineNumber, ThisCliquePtr, ToCliquePtr,
+ PSPtr, Own, Desc) = HTML :-
deep_lookup_proc_statics(Deep, PSPtr, PS),
CalleeName = PS ^ ps_refined_id,
( ThisCliquePtr = ToCliquePtr ->
@@ -862,14 +902,14 @@
;
ToCliquePtr = clique_ptr(ToCliqueNum),
ToCliqueURL = deep_cmd_to_url(Deep,
- clique(ToCliqueNum, Fields)),
+ clique(ToCliqueNum, Fields, OrigMaybeAncestorLimit)),
ProcName =
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(ToCliqueURL), s(CalleeName)])
),
( MaybeFileNameLineNumber = yes(FileName - LineNumber) ->
SourceField =
- format("<TD>%s:%d</TD>\n",
+ string__format("<TD>%s:%d</TD>\n",
[s(FileName), i(LineNumber)])
;
SourceField = "<TD> </TD>\n"
@@ -877,27 +917,29 @@
HTML =
"<TR>\n" ++
SourceField ++
- format("<TD>%s</TD>\n", [s(ProcName)]) ++
+ string__format("<TD>%s</TD>\n", [s(ProcName)]) ++
own_and_desc_to_html(Own, Desc, Deep, Fields) ++
"</TR>\n".
-:- func maybe_call_site_dynamic_to_html(deep, fields, call_site_line_number,
- clique_ptr, call_site_dynamic_ptr) = string.
+:- func maybe_call_site_dynamic_to_html(deep, fields, maybe(int),
+ call_site_line_number, clique_ptr, call_site_dynamic_ptr) = string.
-maybe_call_site_dynamic_to_html(Deep, Fields, PrintCallSiteLineNmber,
- ThisCliquePtr, CSDPtr) = HTML :-
+maybe_call_site_dynamic_to_html(Deep, Fields, OrigMaybeAncestorLimit,
+ PrintCallSiteLineNmber, ThisCliquePtr, CSDPtr) = HTML :-
( valid_call_site_dynamic_ptr(Deep, CSDPtr) ->
HTML = call_site_dynamic_to_html(Deep, Fields,
- PrintCallSiteLineNmber, yes(ThisCliquePtr), CSDPtr)
+ OrigMaybeAncestorLimit, PrintCallSiteLineNmber,
+ yes(ThisCliquePtr), CSDPtr)
;
HTML = ""
).
-:- func call_site_dynamic_to_html(deep, fields, call_site_line_number,
- maybe(clique_ptr), call_site_dynamic_ptr) = string.
+:- func call_site_dynamic_to_html(deep, fields, maybe(int),
+ call_site_line_number, maybe(clique_ptr), call_site_dynamic_ptr)
+ = string.
-call_site_dynamic_to_html(Deep, Fields, PrintCallSiteLineNmber,
- MaybeThisCliquePtr, CSDPtr) = HTML :-
+call_site_dynamic_to_html(Deep, Fields, OrigMaybeAncestorLimit,
+ PrintCallSiteLineNmber, MaybeThisCliquePtr, CSDPtr) = HTML :-
require(valid_call_site_dynamic_ptr(Deep, CSDPtr),
"call_site_dynamic_to_html: invalid call_site_dynamic_ptr"),
deep_lookup_call_site_dynamics(Deep, CSDPtr, CSD),
@@ -916,9 +958,10 @@
;
ToCliquePtr = clique_ptr(ToCliqueNum),
ToCliqueURL = deep_cmd_to_url(Deep,
- clique(ToCliqueNum, Fields)),
+ clique(ToCliqueNum, Fields,
+ OrigMaybeAncestorLimit)),
ProcName =
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(ToCliqueURL), s(CalleeName)])
)
;
@@ -930,7 +973,7 @@
CSS = call_site_static(PSPtr, _, _, LineNumber, _),
deep_lookup_proc_statics(Deep, PSPtr, PS),
SourceField =
- format("<TD>%s:%d</TD>\n",
+ string__format("<TD>%s:%d</TD>\n",
[s(PS ^ ps_filename), i(LineNumber)])
;
SourceField = "<TD> </TD>\n"
@@ -938,7 +981,7 @@
HTML =
"<TR>\n" ++
SourceField ++
- format("<TD>%s</TD>\n", [s(ProcName)]) ++
+ string__format("<TD>%s</TD>\n", [s(ProcName)]) ++
own_and_desc_to_html(CallSiteOwn, CallSiteDesc,
Deep, Fields) ++
"</TR>\n".
@@ -966,7 +1009,7 @@
deep_lookup_ps_desc(Deep, PSPtr, Desc),
HTML =
"<TR>\n" ++
- format("<TD COLSPAN=2>%s</TD>\n",
+ string__format("<TD COLSPAN=2>%s</TD>\n",
[s(proc_static_to_html_ref(Deep, Fields,
proc_static_ptr(PSI)))]) ++
own_and_desc_to_html(Own, Desc, Deep, Fields) ++
@@ -997,7 +1040,7 @@
error("normal call site calls more than one procedure")
),
MainLineRest =
- format("<TD>%s</TD>\n",
+ string__format("<TD>%s</TD>\n",
[s(CalleePS ^ ps_refined_id)]) ++
own_and_desc_to_html(Own, Desc, Deep, Fields),
AdditionalLines = ""
@@ -1010,7 +1053,7 @@
CallSiteName = CallSiteName0
),
MainLineRest =
- format("<TD>%s</TD>\n",
+ string__format("<TD>%s</TD>\n",
[s(CallSiteName)]) ++
own_and_desc_to_html(Own, Desc, Deep, Fields),
CallSiteCallLines = list__map(
@@ -1020,7 +1063,8 @@
),
HTML =
"<TR>\n" ++
- format("<TD>%s:%d</TD>\n", [s(FileName), i(LineNumber)]) ++
+ string__format("<TD>%s:%d</TD>\n",
+ [s(FileName), i(LineNumber)]) ++
MainLineRest ++
"</TR>\n" ++
AdditionalLines.
@@ -1041,7 +1085,7 @@
zero_own_prof_info, Own, zero_inherit_prof_info, Desc),
HTML =
"<TR>\n" ++
- format("<TD></TD><TD>%s</TD>\n",
+ string__format("<TD></TD><TD>%s</TD>\n",
[s(proc_static_to_html_ref(Deep, Fields, PSPtr))]) ++
own_and_desc_to_html(Own, Desc, Deep, Fields) ++
"</TR>\n".
@@ -1084,7 +1128,7 @@
deep_lookup_proc_statics(Deep, PSPtr, PS),
PSPtr = proc_static_ptr(PSI),
PSURL = deep_cmd_to_url(Deep, proc(PSI, Fields)),
- HTML = format("<A HREF=""%s"">%s</A>\n",
+ HTML = string__format("<A HREF=""%s"">%s</A>\n",
[s(PSURL), s(PS ^ ps_refined_id)])
;
HTML =
@@ -1093,33 +1137,51 @@
%-----------------------------------------------------------------------------%
+ % The number of ticks per sec to assume if the profiling data file
+ % does not record the actual tick rate.
+:- func default_ticks_per_sec = int.
+
+default_ticks_per_sec = 100.
+
+:- pred lookup_ticks_per_sec(profile_stats::in, int::out, bool::out) is det.
+
+lookup_ticks_per_sec(Stats, TicksPerSec, Assumed) :-
+ TicksPerSec0 = Stats ^ ticks_per_sec,
+ ( TicksPerSec0 = 0 ->
+ TicksPerSec = default_ticks_per_sec,
+ Assumed = yes
+ ;
+ TicksPerSec = TicksPerSec0,
+ Assumed = no
+ ).
+
:- func quantum_time(deep, int) = string.
quantum_time(Deep, Quanta) = TimeStr :-
- % Time is in units of milliseconds.
- TicksPerSec = Deep ^ profile_stats ^ ticks_per_sec,
- Time = float(Quanta) * 1000.0 / float(TicksPerSec),
- format("%5.2f", [f(Time)], Str0),
+ lookup_ticks_per_sec(Deep ^ profile_stats, TicksPerSec, _Assumed),
+ % We display Time as seconds, with two digits after the decimal point.
+ % This is the most we can do, given clock granularity.
+ Time = 100.0 * float(Quanta) / float(TicksPerSec),
+ string__format("%d", [i(floor_to_int(Time))], Str0),
string__to_char_list(Str0, Chars0),
reverse(Chars0, RevChars0),
string__from_char_list(reverse(
- milliseconds_to_seconds(RevChars0)), TimeStr).
+ centiseconds_to_seconds(RevChars0)), TimeStr).
:- func commas(int) = string.
commas(Num) = Str :-
- format("%d", [i(Num)], Str0),
+ string__format("%d", [i(Num)], Str0),
string__to_char_list(Str0, Chars0),
reverse(Chars0, RevChars0),
string__from_char_list(reverse(add_commas(RevChars0)), Str).
-:- func milliseconds_to_seconds(list(char)) = list(char).
+:- func centiseconds_to_seconds(list(char)) = list(char).
-milliseconds_to_seconds([]) = ['0', '0', '.', '0'].
-milliseconds_to_seconds([_C]) = ['0', '0', '.', '0'].
-milliseconds_to_seconds([_C, D]) = [D, '0', '.', '0'].
-milliseconds_to_seconds([_C, D, E]) = [D, E, '.', '0'].
-milliseconds_to_seconds([_C, D, E, F | R]) = [D, E, '.' | add_commas([F | R])].
+centiseconds_to_seconds([]) = ['0', '0', '.', '0'].
+centiseconds_to_seconds([D]) = [D, '0', '.', '0'].
+centiseconds_to_seconds([D, E]) = [D, E, '.', '0'].
+centiseconds_to_seconds([D, E, F | R]) = [D, E, '.' | add_commas([F | R])].
:- func add_commas(list(char)) = list(char).
@@ -1294,8 +1356,8 @@
PSOwn = Deep ^ ps_own,
array__lookup(PSOwn, PSI1, Own1),
array__lookup(PSOwn, PSI2, Own2),
- OwnAllocs1 = mallocs(Own1),
- OwnAllocs2 = mallocs(Own2),
+ OwnAllocs1 = allocs(Own1),
+ OwnAllocs2 = allocs(Own2),
compare(Result, OwnAllocs1, OwnAllocs2).
:- pred compare_ps_allocs_both(deep::in, int::in, int::in,
@@ -1308,10 +1370,10 @@
array__lookup(PSOwn, PSI2, Own2),
array__lookup(PSDesc, PSI1, Desc1),
array__lookup(PSDesc, PSI2, Desc2),
- OwnAllocs1 = mallocs(Own1),
- OwnAllocs2 = mallocs(Own2),
- DescAllocs1 = inherit_mallocs(Desc1),
- DescAllocs2 = inherit_mallocs(Desc2),
+ OwnAllocs1 = allocs(Own1),
+ OwnAllocs2 = allocs(Own2),
+ DescAllocs1 = inherit_allocs(Desc1),
+ DescAllocs2 = inherit_allocs(Desc2),
TotalAllocs1 = OwnAllocs1 + DescAllocs1,
TotalAllocs2 = OwnAllocs2 + DescAllocs2,
compare(Result, TotalAllocs1, TotalAllocs2).
@@ -1382,9 +1444,9 @@
array__lookup(PSOwn, PSI, Own),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
- OwnAllocs = mallocs(Own),
- RootOwnAllocs = mallocs(RootOwn),
- RootDescAllocs = inherit_mallocs(RootDesc),
+ OwnAllocs = allocs(Own),
+ RootOwnAllocs = allocs(RootOwn),
+ RootDescAllocs = inherit_allocs(RootDesc),
RootTotalAllocs = RootOwnAllocs + RootDescAllocs,
100.0 * float(OwnAllocs) > Threshold * float(RootTotalAllocs).
@@ -1397,10 +1459,10 @@
array__lookup(PSDesc, PSI, Desc),
RootOwn = root_own_info(Deep),
RootDesc = root_desc_info(Deep),
- OwnAllocs = mallocs(Own),
- RootOwnAllocs = mallocs(RootOwn),
- DescAllocs = inherit_mallocs(Desc),
- RootDescAllocs = inherit_mallocs(RootDesc),
+ OwnAllocs = allocs(Own),
+ RootOwnAllocs = allocs(RootOwn),
+ DescAllocs = inherit_allocs(Desc),
+ RootDescAllocs = inherit_allocs(RootDesc),
TotalAllocs = OwnAllocs + DescAllocs,
RootTotalAllocs = RootOwnAllocs + RootDescAllocs,
100.0 * float(TotalAllocs) > Threshold * float(RootTotalAllocs).
@@ -1440,8 +1502,13 @@
:- func banner = string.
banner =
+ "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01//EN""\n" ++
+ """http://www.w3.org/TR/html4/strict.dtd"">\n" ++
"<HTML>\n" ++
- "<TITLE>The University of Melbourne Mercury Deep Profiler.</TITLE>\n".
+ "<HEAD>\n" ++
+ "<TITLE>Page created by the Mercury Deep Profiler.</TITLE>\n" ++
+ "</HEAD>\n" ++
+ "<BODY>\n".
:- func footer(cmd, deep) = string.
@@ -1449,42 +1516,123 @@
% Link back to root,
% Search, etc, etc.
HTML =
- footer_field_select(Cmd, Deep) ++
+ footer_cmd_toggles(Cmd, Deep) ++
"<p>\n" ++
- format("<A HREF=""%s"">Menu</A>\n",
+ string__format("<A HREF=""%s"">Menu</A>\n",
[s(deep_cmd_to_url(Deep, menu))]) ++
- format("<A HREF=""%s"">Quit</A>\n",
+ string__format("<A HREF=""%s"">Quit</A>\n",
[s(deep_cmd_to_url(Deep, quit))]) ++
+ "</BODY>\n" ++
"</HTML>\n".
-:- func footer_field_select(cmd, deep) = string.
+:- func footer_cmd_toggles(cmd, deep) = string.
-footer_field_select(quit, _) = "".
-footer_field_select(timeout(_), _) = "".
-footer_field_select(menu, _) = "".
-footer_field_select(root(Fields), Deep) =
+footer_cmd_toggles(quit, _) = "".
+footer_cmd_toggles(timeout(_), _) = "".
+footer_cmd_toggles(menu, _) = "".
+footer_cmd_toggles(root(Fields), Deep) =
footer_field_toggle(Deep, Fields,
func(ArgFields) = root(ArgFields) :- true).
-footer_field_select(clique(CI, Fields), Deep) =
+footer_cmd_toggles(clique(CI, Fields, MaybeAncestorLimit), Deep) =
footer_field_toggle(Deep, Fields,
- func(ArgFields) = clique(CI, ArgFields) :- true).
-footer_field_select(proc(PSI, Fields), Deep) =
+ func(ArgFields) = clique(CI, ArgFields, MaybeAncestorLimit)
+ :- true) ++
+ "<p>\n" ++
+ footer_ancestor_toggle(Deep, MaybeAncestorLimit,
+ func(ArgMaybeAncestorLimit) =
+ clique(CI, Fields, ArgMaybeAncestorLimit) :- true).
+footer_cmd_toggles(proc(PSI, Fields), Deep) =
footer_field_toggle(Deep, Fields,
func(ArgFields) = proc(PSI, ArgFields) :- true).
-footer_field_select(top_procs(Sort, InclDesc, Limit, Fields), Deep) =
+footer_cmd_toggles(top_procs(Sort, InclDesc, Limit, Fields), Deep) =
footer_field_toggle(Deep, Fields,
func(ArgFields) = top_procs(Sort, InclDesc, Limit, ArgFields)
:- true).
-footer_field_select(proc_static(_), _) = "".
-footer_field_select(proc_dynamic(_), _) = "".
-footer_field_select(call_site_static(_), _) = "".
-footer_field_select(call_site_dynamic(_), _) = "".
-footer_field_select(raw_clique(_), _) = "".
-footer_field_select(num_proc_statics, _) = "".
-footer_field_select(num_call_site_statics, _) = "".
-footer_field_select(num_proc_dynamics, _) = "".
-footer_field_select(num_call_site_dynamics, _) = "".
+footer_cmd_toggles(proc_static(_), _) = "".
+footer_cmd_toggles(proc_dynamic(_), _) = "".
+footer_cmd_toggles(call_site_static(_), _) = "".
+footer_cmd_toggles(call_site_dynamic(_), _) = "".
+footer_cmd_toggles(raw_clique(_), _) = "".
+footer_cmd_toggles(num_proc_statics, _) = "".
+footer_cmd_toggles(num_call_site_statics, _) = "".
+footer_cmd_toggles(num_proc_dynamics, _) = "".
+footer_cmd_toggles(num_call_site_dynamics, _) = "".
+
+:- func footer_ancestor_toggle(deep, maybe(int), func(maybe(int)) = cmd)
+ = string.
+footer_ancestor_toggle(Deep, MaybeAncestorLimit, MakeCmd) = HTML :-
+ (
+ MaybeAncestorLimit = no,
+ Display1 = yes,
+ Display2 = yes,
+ Msg1 = "One ancestor",
+ MaybeAncestorLimit1 = yes(1),
+ Msg2 = "Two ancestors",
+ MaybeAncestorLimit2 = yes(2),
+ Msg3 = "Three ancestors",
+ MaybeAncestorLimit3 = yes(3),
+ Msg4 = "Five ancestors",
+ MaybeAncestorLimit4 = yes(5),
+ Msg5 = "Ten ancestors",
+ MaybeAncestorLimit5 = yes(10)
+ ;
+ MaybeAncestorLimit = yes(OldAncestorLimit),
+ ( OldAncestorLimit > 2 ->
+ Display1 = yes
+ ;
+ Display1 = no
+ ),
+ ( OldAncestorLimit > 1 ->
+ Display2 = yes
+ ;
+ Display2 = no
+ ),
+ Msg1 = "Halve ancestors",
+ MaybeAncestorLimit1 = yes(OldAncestorLimit // 2),
+ Msg2 = "Remove an ancestor",
+ MaybeAncestorLimit2 = yes(OldAncestorLimit - 1),
+ Msg3 = "Add an ancestor",
+ MaybeAncestorLimit3 = yes(OldAncestorLimit + 1),
+ Msg4 = "Double ancestors",
+ MaybeAncestorLimit4 = yes(OldAncestorLimit * 2),
+ Msg5 = "Unlimited ancestors",
+ MaybeAncestorLimit5 = no
+ ),
+ Cmd1 = MakeCmd(MaybeAncestorLimit1),
+ Cmd2 = MakeCmd(MaybeAncestorLimit2),
+ Cmd3 = MakeCmd(MaybeAncestorLimit3),
+ Cmd4 = MakeCmd(MaybeAncestorLimit4),
+ Cmd5 = MakeCmd(MaybeAncestorLimit5),
+ Toggle1 = string__format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_to_url(Deep, Cmd1)), s(Msg1)]),
+ Toggle2 = string__format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_to_url(Deep, Cmd2)), s(Msg2)]),
+ Toggle3 = string__format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_to_url(Deep, Cmd3)), s(Msg3)]),
+ Toggle4 = string__format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_to_url(Deep, Cmd4)), s(Msg4)]),
+ Toggle5 = string__format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_to_url(Deep, Cmd5)), s(Msg5)]),
+ (
+ Display1 = yes,
+ MaybeToggle1 = Toggle1
+ ;
+ Display1 = no,
+ MaybeToggle1 = ""
+ ),
+ (
+ Display2 = yes,
+ MaybeToggle2 = Toggle2
+ ;
+ Display2 = no,
+ MaybeToggle2 = ""
+ ),
+ HTML =
+ "<p>\n" ++
+ "Toggle ancestors: " ++
+ MaybeToggle1 ++ MaybeToggle2 ++ Toggle3 ++ Toggle4 ++ Toggle5.
+
:- func footer_field_toggle(deep, string, func(string) = cmd) = string.
footer_field_toggle(Deep, Fields, MakeCmd) = HTML :-
@@ -1532,15 +1680,15 @@
HTML =
"<p>\n" ++
"Toggle fields: " ++
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_to_url(Deep, CmdPort)), s(PortMsg)]) ++
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_to_url(Deep, CmdQuanta)), s(QuantaMsg)]) ++
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_to_url(Deep, CmdTimes)), s(TimesMsg)]) ++
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_to_url(Deep, CmdAllocs)), s(AllocsMsg)]) ++
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_to_url(Deep, CmdWords)), s(WordsMsg)]).
:- func menu_text = string.
@@ -1551,7 +1699,7 @@
:- func menu_item(deep, cmd, string) = string.
menu_item(Deep, Cmd, Text) =
- format("<A HREF=""%s"">%s</A>\n",
+ string__format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_to_url(Deep, Cmd)), s(Text)]).
%-----------------------------------------------------------------------------%
@@ -1577,65 +1725,122 @@
:- func fields_header(fields) = string.
-fields_header(Fields) =
- "<TR>\n" ++
- "<TD>Source</TD>\n" ++
- "<TD>Procedure</TD>\n" ++
+fields_header(Fields) = HTML :-
+ Groups0 = "<COLGROUP>\n" ++
+ "<COL ALIGN=LEFT>\n" ++
+ "<COL ALIGN=LEFT>\n",
+ FirstRow0 = "<TR>\n" ++
+ "<TH ALIGN=LEFT ROWSPAN=2>Source\n" ++
+ "<TH ALIGN=LEFT ROWSPAN=2>Procedure\n",
+ SecondRow0 = "<TR>\n",
( show_port_counts(Fields) ->
- "<TD ALIGN=RIGHT>Calls</TD>\n" ++
- "<TD ALIGN=RIGHT>Exits</TD>\n" ++
- "<TD ALIGN=RIGHT>Fails</TD>\n" ++
- "<TD ALIGN=RIGHT>Redos</TD>\n"
- ;
- ""
- ) ++
- ( show_quanta(Fields) ->
- "<TD ALIGN=RIGHT>Self quanta</TD>\n"
- ;
- ""
- ) ++
- ( show_times(Fields) ->
- "<TD ALIGN=RIGHT>Self time</TD>\n"
- ;
- ""
- ) ++
- ( (show_quanta(Fields) ; show_times(Fields)) ->
- "<TD ALIGN=RIGHT>% of root</TD>\n"
- ;
- ""
- ) ++
- ( show_quanta(Fields) ->
- "<TD ALIGN=RIGHT>Total quanta</TD>\n"
- ;
- ""
- ) ++
- ( show_times(Fields) ->
- "<TD ALIGN=RIGHT>Total time</TD>\n"
- ;
- ""
- ) ++
- ( (show_quanta(Fields) ; show_times(Fields)) ->
- "<TD ALIGN=RIGHT>% of root</TD>\n"
- ;
- ""
- ) ++
+ Groups1 = Groups0 ++
+ "<COLGROUP>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n",
+ FirstRow1 = FirstRow0 ++
+ "<TH COLSPAN=4>Port counts\n",
+ SecondRow1 = SecondRow0 ++
+ "<TH ALIGN=RIGHT>Calls\n" ++
+ "<TH ALIGN=RIGHT>Exits\n" ++
+ "<TH ALIGN=RIGHT>Fails\n" ++
+ "<TH ALIGN=RIGHT>Redos\n"
+ ;
+ Groups1 = Groups0,
+ FirstRow1 = FirstRow0,
+ SecondRow1 = SecondRow0
+ ),
+ ( show_quanta(Fields), show_times(Fields) ->
+ Groups2 = Groups1 ++
+ "<COLGROUP>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n",
+ FirstRow2 = FirstRow1 ++
+ "<TH COLSPAN=6>Clock ticks and times\n",
+ SecondRow2 = SecondRow1 ++
+ "<TH ALIGN=RIGHT ROWSPAN=2>Self\n" ++
+ "<TH ALIGN=RIGHT>%\n" ++
+ "<TH ALIGN=RIGHT ROWSPAN=2>Total\n" ++
+ "<TH ALIGN=RIGHT>%\n"
+ ; show_quanta(Fields) ->
+ Groups2 = Groups1 ++
+ "<COLGROUP>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n",
+ FirstRow2 = FirstRow1 ++
+ "<TH COLSPAN=4>Clock ticks\n",
+ SecondRow2 = SecondRow1 ++
+ "<TH ALIGN=RIGHT>Self\n" ++
+ "<TH ALIGN=RIGHT>%\n" ++
+ "<TH ALIGN=RIGHT>Total\n" ++
+ "<TH ALIGN=RIGHT>%\n"
+ ; show_times(Fields) ->
+ Groups2 = Groups1 ++
+ "<COLGROUP>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n",
+ FirstRow2 = FirstRow1 ++
+ "<TH COLSPAN=4>Time\n",
+ SecondRow2 = SecondRow1 ++
+ "<TH ALIGN=RIGHT>Self\n" ++
+ "<TH ALIGN=RIGHT>%\n" ++
+ "<TH ALIGN=RIGHT>Total\n" ++
+ "<TH ALIGN=RIGHT>%\n"
+ ;
+ Groups2 = Groups1,
+ FirstRow2 = FirstRow1,
+ SecondRow2 = SecondRow1
+ ),
( show_allocs(Fields) ->
- "<TD ALIGN=RIGHT>Self allocs</TD>\n" ++
- "<TD ALIGN=RIGHT>% of root</TD>\n" ++
- "<TD ALIGN=RIGHT>Total allocs</TD>\n" ++
- "<TD ALIGN=RIGHT>% of root</TD>\n"
- ;
- ""
- ) ++
+ Groups3 = Groups2 ++
+ "<COLGROUP>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n",
+ FirstRow3 = FirstRow2 ++
+ "<TH COLSPAN=4>Memory allocations\n",
+ SecondRow3 = SecondRow2 ++
+ "<TH ALIGN=RIGHT>Self\n" ++
+ "<TH ALIGN=RIGHT>%\n" ++
+ "<TH ALIGN=RIGHT>Total\n" ++
+ "<TH ALIGN=RIGHT>%\n"
+ ;
+ Groups3 = Groups2,
+ FirstRow3 = FirstRow2,
+ SecondRow3 = SecondRow2
+ ),
( show_words(Fields) ->
- "<TD ALIGN=RIGHT>Self words</TD>\n" ++
- "<TD ALIGN=RIGHT>% of root</TD>\n" ++
- "<TD ALIGN=RIGHT>Total words</TD>\n" ++
- "<TD ALIGN=RIGHT>% of root</TD>\n"
- ;
- ""
- ) ++
- "</TR>\n".
+ Groups4 = Groups3 ++
+ "<COLGROUP>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n" ++
+ "<COL ALIGN=RIGHT>\n",
+ FirstRow4 = FirstRow3 ++
+ "<TH COLSPAN=4>Memory words\n",
+ SecondRow4 = SecondRow3 ++
+ "<TH ALIGN=RIGHT>Self\n" ++
+ "<TH ALIGN=RIGHT>%\n" ++
+ "<TH ALIGN=RIGHT>Total\n" ++
+ "<TH ALIGN=RIGHT>%\n"
+ ;
+ Groups4 = Groups3,
+ FirstRow4 = FirstRow3,
+ SecondRow4 = SecondRow3
+ ),
+ HTML = Groups4 ++ "<THEAD>\n" ++
+ FirstRow4 ++ SecondRow4 ++ "<TBODY>\n".
:- func separator_row(fields) = string.
@@ -1692,9 +1897,9 @@
OwnQuantaProp = percentage(OwnQuanta, RootQuanta),
TotalQuantaProp = percentage(TotalQuanta, RootQuanta),
- OwnAllocs = mallocs(Own),
- TotalAllocs = inherit_mallocs(OwnPlusDesc),
- RootAllocs = inherit_mallocs(Root),
+ OwnAllocs = allocs(Own),
+ TotalAllocs = inherit_allocs(OwnPlusDesc),
+ RootAllocs = inherit_allocs(Root),
OwnAllocProp = percentage(OwnAllocs, RootAllocs),
TotalAllocProp = percentage(TotalAllocs, RootAllocs),
@@ -1706,73 +1911,73 @@
HTML =
( show_port_counts(Fields) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(Calls))]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(Exits))]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(Fails))]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(Redos))])
;
""
) ++
( show_quanta(Fields) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(OwnQuanta))])
;
""
) ++
( show_times(Fields) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(quantum_time(Deep, OwnQuanta))])
;
""
) ++
( (show_quanta(Fields) ; show_times(Fields)) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(OwnQuantaProp)])
;
""
) ++
( show_quanta(Fields) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(TotalQuanta))])
;
""
) ++
( show_times(Fields) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(quantum_time(Deep, TotalQuanta))])
;
""
) ++
( (show_quanta(Fields) ; show_times(Fields)) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(TotalQuantaProp)])
;
""
) ++
( show_allocs(Fields) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(OwnAllocs))]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(OwnAllocProp)]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(TotalAllocs))]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(TotalAllocProp)])
;
""
) ++
( show_words(Fields) ->
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(OwnWords))]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(OwnWordProp)]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(commas(TotalWords))]) ++
- format("<TD ALIGN=RIGHT>%s</TD>\n",
+ string__format("<TD ALIGN=RIGHT>%s</TD>\n",
[s(TotalWordProp)])
;
""
@@ -1785,7 +1990,7 @@
PercentageStr = "N/A"
;
Percentage = 100.0 * float(Fraction) / float(Whole),
- PercentageStr = string__format("%4.2f", [f(Percentage)])
+ PercentageStr = string__format("%5.2f", [f(Percentage)])
).
:- func deep_cmd_to_url(deep, cmd) = string.
Index: startup.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/startup.m,v
retrieving revision 1.1
diff -u -b -r1.1 startup.m
--- startup.m 2001/05/31 05:59:59 1.1
+++ startup.m 2001/06/04 09:42:06
@@ -26,8 +26,9 @@
:- implementation.
:- import_module unsafe.
-:- import_module profile, read_profile, cliques, measurements, array_util.
-:- import_module std_util, int, array, assoc_list, set, map, require.
+:- import_module profile, read_profile, callgraph.
+:- import_module measurements, array_util.
+:- import_module std_util, int, string, array, assoc_list, set, map, require.
read_and_startup(Machine, DataFileNames, CanonicalClique, Res) -->
(
@@ -43,9 +44,9 @@
io__write_string(StdErr, " Done.\n"),
io__report_stats,
(
- { Res0 = ok(InitialDeep) },
+ { Res0 = ok(InitDeep) },
startup(Machine, DataFileName, CanonicalClique,
- InitialDeep, Deep),
+ InitDeep, Deep),
{ Res = ok(Deep) }
;
{ Res0 = error(Error) },
@@ -59,78 +60,67 @@
:- pred startup(string::in, string::in, bool::in, initial_deep::in, deep::out,
io__state::di, io__state::uo) is det.
-startup(Machine, DataFileName, CanonicalClique, InitialDeep0, Deep) -->
+startup(Machine, DataFileName, _CanonicalClique, InitDeep0, Deep) -->
stderr_stream(StdErr),
- { InitialDeep0 = initial_deep(InitStats, Root,
+ { InitDeep0 = initial_deep(InitStats, Root,
CallSiteDynamics0, ProcDynamics,
CallSiteStatics0, ProcStatics) },
- format(StdErr,
+ io__format(StdErr,
" Mapping static call sites to containing procedures...\n",
[]),
- { array_foldl(record_css_containers, ProcStatics,
+ { array_foldl_from_1(record_css_containers, ProcStatics,
u(CallSiteStatics0), CallSiteStatics) },
- format(StdErr, " Done.\n", []),
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- format(StdErr,
+ io__format(StdErr,
" Mapping dynamic call sites to containing procedures...\n",
[]),
- { array_foldl(record_csd_containers, ProcDynamics,
+ { array_foldl_from_1(record_csd_containers, ProcDynamics,
u(CallSiteDynamics0), CallSiteDynamics) },
- format(StdErr, " Done.\n", []),
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- { InitialDeep1 = initial_deep(InitStats, Root,
+ { InitDeep1 = initial_deep(InitStats, Root,
CallSiteDynamics, ProcDynamics,
CallSiteStatics, ProcStatics) },
- find_cliques(InitialDeep1, CliqueList0),
- (
- { CanonicalClique = no },
- { InitialDeep = InitialDeep1 },
- { CliqueList = CliqueList0 }
- ;
- { CanonicalClique = yes },
- format(StdErr, " Canonicalizing cliques...\n", []),
- { merge_cliques(CliqueList0, InitialDeep1, InitialDeep) },
- io__report_stats,
-
- find_cliques(InitialDeep, CliqueList)
- ),
-
- format(StdErr, " Constructing clique indexes...\n", []),
- flush_output(StdErr),
+ { InitDeep = InitDeep1 },
+% (
+% { CanonicalClique = no },
+% { InitDeep = InitDeep1 }
+% ;
+% { CanonicalClique = yes },
+% io__format(StdErr, " Canonicalizing cliques...\n", []),
+% { canonicalize_cliques(InitDeep1, InitDeep) },
+% io__format(StdErr, " Done.\n", []),
+% io__report_stats
+% ),
- { Cliques = array(CliqueList) },
-
- { array__max(ProcDynamics, PDMax) },
+ { array__max(InitDeep ^ init_proc_dynamics, PDMax) },
{ NPDs = PDMax + 1 },
- { array__max(CallSiteDynamics, CSDMax) },
+ { array__max(InitDeep ^ init_call_site_dynamics, CSDMax) },
{ NCSDs = CSDMax + 1 },
- { array__max(ProcStatics, PSMax) },
+ { array__max(InitDeep ^ init_proc_statics, PSMax) },
{ NPSs = PSMax + 1 },
- { array__max(CallSiteStatics, CSSMax) },
+ { array__max(InitDeep ^ init_call_site_statics, CSSMax) },
{ NCSSs = CSSMax + 1 },
- { array__init(NPDs, clique_ptr(-1), CliqueIndex0) },
+ io__format(StdErr, " Finding cliques...\n", []),
+ flush_output(StdErr),
+ { find_cliques(InitDeep, CliqueList) },
+ io__format(StdErr, " Done.\n", []),
+ io__report_stats,
- % For each clique, add entries in an array
- % that maps from each clique member (ProcDynamic)
- % back to the clique to which it belongs.
- { array_foldl((pred(CliqueN::in, CliqueMembers::in,
- I0::array_di, I::array_uo) is det :-
- array_list_foldl((pred(X::in, I1::array_di, I2::array_uo)
- is det :-
- X = proc_dynamic_ptr(Y),
- array__set(I1, Y, clique_ptr(CliqueN), I2)
- ), CliqueMembers, I0, I)
- ), Cliques, CliqueIndex0, CliqueIndex) },
- format(StdErr, " Done.\n", []),
+ io__format(StdErr, " Constructing clique indexes...\n", []),
+ flush_output(StdErr),
+ { make_clique_indexes(NPDs, CliqueList, Cliques, CliqueIndex) },
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- format(StdErr, " Constructing clique parent map...\n", []),
+ io__format(StdErr, " Constructing clique parent map...\n", []),
% For each CallSiteDynamic pointer, if it points to
% a ProcDynamic which is in a different clique to
@@ -143,40 +133,40 @@
{ NCliques = CliqueMax + 1 },
{ array__init(NCliques, call_site_dynamic_ptr(-1), CliqueParents0) },
{ array__init(NCSDs, no, CliqueMaybeChildren0) },
- { array_foldl2(construct_clique_parents(InitialDeep, CliqueIndex),
+ { array_foldl2_from_1(construct_clique_parents(InitDeep, CliqueIndex),
CliqueIndex,
CliqueParents0, CliqueParents,
CliqueMaybeChildren0, CliqueMaybeChildren) },
- format(StdErr, " Done.\n", []),
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- format(StdErr, " Finding procedure callers...\n", []),
+ io__format(StdErr, " Finding procedure callers...\n", []),
{ array__init(NPSs, [], ProcCallers0) },
- { array_foldl(construct_proc_callers(InitialDeep), CallSiteDynamics,
- ProcCallers0, ProcCallers) },
- format(StdErr, " Done.\n", []),
+ { array_foldl_from_1(construct_proc_callers(InitDeep),
+ CallSiteDynamics, ProcCallers0, ProcCallers) },
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- format(StdErr, " Constructing call site static map...\n", []),
+ io__format(StdErr, " Constructing call site static map...\n", []),
{ array__init(NCSDs, call_site_static_ptr(-1), CallSiteStaticMap0) },
- { array_foldl(construct_call_site_caller(InitialDeep), ProcDynamics,
- CallSiteStaticMap0, CallSiteStaticMap) },
- format(StdErr, " Done.\n", []),
+ { array_foldl_from_1(construct_call_site_caller(InitDeep),
+ ProcDynamics, CallSiteStaticMap0, CallSiteStaticMap) },
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- format(StdErr, " Finding call site calls...\n", []),
+ io__format(StdErr, " Finding call site calls...\n", []),
{ array__init(NCSSs, map__init, CallSiteCalls0) },
- { array_foldl(construct_call_site_calls(InitialDeep), ProcDynamics,
- CallSiteCalls0, CallSiteCalls) },
- format(StdErr, " Done.\n", []),
+ { array_foldl_from_1(construct_call_site_calls(InitDeep),
+ ProcDynamics, CallSiteCalls0, CallSiteCalls) },
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- format(StdErr, " Propagating time up call graph...\n", []),
+ io__format(StdErr, " Propagating time up call graph...\n", []),
{ array__init(NCSDs, zero_inherit_prof_info, CSDDesc0) },
{ array__init(NPDs, zero_own_prof_info, PDOwn0) },
- { array_foldl(sum_call_sites_in_proc_dynamic,
+ { array_foldl_from_1(sum_call_sites_in_proc_dynamic,
CallSiteDynamics, PDOwn0, PDOwn) },
{ array__init(NPDs, zero_inherit_prof_info, PDDesc0) },
{ array__init(NPSs, zero_own_prof_info, PSOwn0) },
@@ -191,94 +181,23 @@
PDOwn, PDDesc0, CSDDesc0,
PSOwn0, PSDesc0, CSSOwn0, CSSDesc0) },
- { array_foldl(propagate_to_clique, Cliques, Deep0, Deep1) },
- format(StdErr, " Done.\n", []),
+ { array_foldl_from_1(propagate_to_clique, Cliques, Deep0, Deep1) },
+ io__format(StdErr, " Done.\n", []),
io__report_stats,
- format(StdErr, " Summarizing information...\n", []),
+ io__format(StdErr, " Summarizing information...\n", []),
{ summarize_proc_dynamics(Deep1, Deep2) },
{ summarize_call_site_dynamics(Deep2, Deep) },
- format(StdErr, " Done.\n", []),
+ io__format(StdErr, " Done.\n", []),
io__report_stats.
-
-:- pred find_cliques(initial_deep::in, list(list(proc_dynamic_ptr))::out,
- io__state::di, io__state::uo) is det.
-find_cliques(InitialDeep, CliqueList) -->
- stderr_stream(StdErr),
- format(StdErr, " Constructing graph...\n", []),
- make_graph(InitialDeep, Graph),
- format(StdErr, " Done.\n", []),
- io__report_stats,
-
- format(StdErr, " Constructing cliques...\n", []),
- { topological_sort(Graph, CliqueList0) },
+:- pred count_quanta(int::in, call_site_dynamic::in, int::in, int::out) is det.
- % Turn each of the sets into a list.
- % (We use foldl here because the list may be very
- % long and map runs out of stack space, and we
- % want the final list in reverse order anyway.)
- { list__foldl((pred(Set::in, L0::in, L::out) is det :-
- set__to_sorted_list(Set, List0),
- map((pred(PDI::in, PDPtr::out) is det :-
- PDPtr = proc_dynamic_ptr(PDI)
- ), List0, List),
- L = [List | L0]
- ), CliqueList0, [], CliqueList) },
- % It's actually more convenient to have the list in
- % reverse order so that foldl works from the bottom
- % of the tsort to the top, so that we can use it to
- % do the propagation simply.
- format(StdErr, " Done.\n", []),
- io__report_stats.
+count_quanta(_N, CSD, Quanta0, Quanta) :-
+ Quanta = Quanta0 + quanta(CSD ^ csd_own_prof).
%-----------------------------------------------------------------------------%
-:- pred make_graph(initial_deep::in, graph::out,
- io__state::di, io__state::uo) is det.
-
-make_graph(InitialDeep, Graph) -->
- { init(Graph0) },
- array_foldl2((pred(PDI::in, PD::in, G1::in, G2::out, di, uo) is det -->
- { From = PDI },
- { CallSiteRefArray = PD ^ pd_sites },
- { array__to_list(CallSiteRefArray, CallSiteRefList) },
- list__foldl2((pred(CSR::in, G5::in, G6::out, di, uo) is det -->
- (
- { CSR = normal(call_site_dynamic_ptr(CSDI)) },
- ( { CSDI > 0 } ->
- { array__lookup(
- InitialDeep ^ init_call_site_dynamics,
- CSDI, CSD) },
- { CPDPtr = CSD ^ csd_callee },
- { CPDPtr = proc_dynamic_ptr(To) },
- { add_arc(G5, From, To, G6) }
- ;
- { G6 = G5 }
- )
- ;
- { CSR = multi(CallSiteArray) },
- { array__to_list(CallSiteArray, CallSites) },
- list__foldl2((pred(CSDPtr1::in, G7::in, G8::out,
- di, uo) is det -->
- { CSDPtr1 = call_site_dynamic_ptr(CSDI) },
- ( { CSDI > 0 } ->
- { array__lookup(
- InitialDeep ^ init_call_site_dynamics,
- CSDI, CSD) },
- { CPDPtr = CSD ^ csd_callee },
- { CPDPtr = proc_dynamic_ptr(To) },
- { add_arc(G7, From, To, G8) }
- ;
- { G8 = G7 }
- )
- ), CallSites, G5, G6)
- )
- ), CallSiteRefList, G1, G2)
- ), InitialDeep ^ init_proc_dynamics, Graph0, Graph).
-
-%-----------------------------------------------------------------------------%
-
:- pred record_css_containers(int::in, proc_static::in,
array(call_site_static)::array_di,
array(call_site_static)::array_uo) is det.
@@ -338,11 +257,10 @@
record_csd_containers_2(PDPtr, [CSDPtr | CSDPtrs],
CallSiteDynamics0, CallSiteDynamics) :-
lookup_call_site_dynamics(CallSiteDynamics0, CSDPtr, CSD0),
- CSD0 = call_site_dynamic(CallerPDPtr0, CalleePDPtr, Own,
- MaybeRedirect),
+ CSD0 = call_site_dynamic(CallerPDPtr0, CalleePDPtr, Own),
require(unify(CallerPDPtr0, proc_dynamic_ptr(-1)),
"record_csd_containers_2: real proc_dynamic_ptr"),
- CSD = call_site_dynamic(PDPtr, CalleePDPtr, Own, MaybeRedirect),
+ CSD = call_site_dynamic(PDPtr, CalleePDPtr, Own),
update_call_site_dynamics(CallSiteDynamics0, CSDPtr, CSD,
CallSiteDynamics1),
record_csd_containers_2(PDPtr, CSDPtrs,
@@ -357,14 +275,14 @@
array(maybe(clique_ptr))::array_di,
array(maybe(clique_ptr))::array_uo) is det.
-construct_clique_parents(InitialDeep, CliqueIndex, PDI, CliquePtr,
+construct_clique_parents(InitDeep, CliqueIndex, PDI, CliquePtr,
CliqueParents0, CliqueParents,
CliqueMaybeChildren0, CliqueMaybeChildren) :-
( PDI > 0 ->
- flat_call_sites(InitialDeep ^ init_proc_dynamics,
+ flat_call_sites(InitDeep ^ init_proc_dynamics,
proc_dynamic_ptr(PDI), CSDPtrs),
array_list_foldl2(
- construct_clique_parents_2(InitialDeep,
+ construct_clique_parents_2(InitDeep,
CliqueIndex, CliquePtr),
CSDPtrs, CliqueParents0, CliqueParents,
CliqueMaybeChildren0, CliqueMaybeChildren)
@@ -379,13 +297,12 @@
array(maybe(clique_ptr))::array_di,
array(maybe(clique_ptr))::array_uo) is det.
-construct_clique_parents_2(InitialDeep, CliqueIndex, ParentCliquePtr, CSDPtr,
+construct_clique_parents_2(InitDeep, CliqueIndex, ParentCliquePtr, CSDPtr,
CliqueParents0, CliqueParents,
CliqueMaybeChildren0, CliqueMaybeChildren) :-
CSDPtr = call_site_dynamic_ptr(CSDI),
( CSDI > 0 ->
- array__lookup(InitialDeep ^ init_call_site_dynamics, CSDI,
- CSD),
+ array__lookup(InitDeep ^ init_call_site_dynamics, CSDI, CSD),
ChildPDPtr = CSD ^ csd_callee,
ChildPDPtr = proc_dynamic_ptr(ChildPDI),
( ChildPDI > 0 ->
@@ -454,11 +371,11 @@
array(list(call_site_dynamic_ptr))::array_di,
array(list(call_site_dynamic_ptr))::array_uo) is det.
-construct_proc_callers(InitialDeep, CSDI, CSD, ProcCallers0, ProcCallers) :-
+construct_proc_callers(InitDeep, CSDI, CSD, ProcCallers0, ProcCallers) :-
PDPtr = CSD ^ csd_callee,
PDPtr = proc_dynamic_ptr(PDI),
- ( PDI > 0, array__in_bounds(InitialDeep ^ init_proc_dynamics, PDI) ->
- array__lookup(InitialDeep ^ init_proc_dynamics, PDI, PD),
+ ( PDI > 0, array__in_bounds(InitDeep ^ init_proc_dynamics, PDI) ->
+ array__lookup(InitDeep ^ init_proc_dynamics, PDI, PD),
PSPtr = PD ^ pd_proc_static,
PSPtr = proc_static_ptr(PSI),
array__lookup(ProcCallers0, PSI, Callers0),
@@ -472,16 +389,16 @@
array(call_site_static_ptr)::array_di,
array(call_site_static_ptr)::array_uo) is det.
-construct_call_site_caller(InitialDeep, _PDI, PD,
+construct_call_site_caller(InitDeep, _PDI, PD,
CallSiteStaticMap0, CallSiteStaticMap) :-
PSPtr = PD ^ pd_proc_static,
CSDArraySlots = PD ^ pd_sites,
PSPtr = proc_static_ptr(PSI),
- array__lookup(InitialDeep ^ init_proc_statics, PSI, PS),
+ array__lookup(InitDeep ^ init_proc_statics, PSI, PS),
PS = proc_static(_, _, _, _, CSSPtrs),
array__max(CSDArraySlots, MaxCS),
construct_call_site_caller_2(MaxCS,
- InitialDeep ^ init_call_site_dynamics, CSSPtrs, CSDArraySlots,
+ InitDeep ^ init_call_site_dynamics, CSSPtrs, CSDArraySlots,
CallSiteStaticMap0, CallSiteStaticMap).
:- pred construct_call_site_caller_2(int::in, call_site_dynamics::in,
@@ -502,7 +419,7 @@
;
CSDArraySlot = multi(CSDPtrs),
- array_foldl0(
+ array_foldl_from_0(
construct_call_site_caller_3(Deep, CSSPtr),
CSDPtrs,
CallSiteStaticMap0, CallSiteStaticMap1)
@@ -532,16 +449,15 @@
array(map(proc_static_ptr, list(call_site_dynamic_ptr)))::array_uo)
is det.
-construct_call_site_calls(InitialDeep, _PDI, PD,
- CallSiteCalls0, CallSiteCalls) :-
+construct_call_site_calls(InitDeep, _PDI, PD, CallSiteCalls0, CallSiteCalls) :-
PSPtr = PD ^ pd_proc_static,
CSDArraySlots = PD ^ pd_sites,
array__max(CSDArraySlots, MaxCS),
PSPtr = proc_static_ptr(PSI),
- array__lookup(InitialDeep ^ init_proc_statics, PSI, PS),
+ array__lookup(InitDeep ^ init_proc_statics, PSI, PS),
CSSPtrs = PS ^ ps_sites,
- CallSiteDynamics = InitialDeep ^ init_call_site_dynamics,
- ProcDynamics = InitialDeep ^ init_proc_dynamics,
+ CallSiteDynamics = InitDeep ^ init_call_site_dynamics,
+ ProcDynamics = InitDeep ^ init_proc_dynamics,
construct_call_site_calls_2(CallSiteDynamics, ProcDynamics, MaxCS,
CSSPtrs, CSDArraySlots, CallSiteCalls0, CallSiteCalls).
@@ -564,7 +480,7 @@
CSDPtr, CallSiteCalls0, CallSiteCalls1)
;
CSDArraySlot = multi(CSDPtrs),
- array_foldl0(
+ array_foldl_from_0(
construct_call_site_calls_3(CallSiteDynamics,
ProcDynamics, CSSPtr),
CSDPtrs, CallSiteCalls0, CallSiteCalls1)
@@ -626,7 +542,8 @@
summarize_proc_dynamics(Deep0, Deep) :-
PSOwn0 = Deep0 ^ ps_own,
PSDesc0 = Deep0 ^ ps_desc,
- array_foldl2(summarize_proc_dynamic(Deep0 ^ pd_own, Deep0 ^ pd_desc),
+ array_foldl2_from_1(
+ summarize_proc_dynamic(Deep0 ^ pd_own, Deep0 ^ pd_desc),
Deep0 ^ proc_dynamics,
copy(PSOwn0), PSOwn, copy(PSDesc0), PSDesc),
Deep = ((Deep0
@@ -663,7 +580,8 @@
summarize_call_site_dynamics(Deep0, Deep) :-
CSSOwn0 = Deep0 ^ css_own,
CSSDesc0 = Deep0 ^ css_desc,
- array_foldl2(summarize_call_site_dynamic(Deep0 ^ call_site_static_map,
+ array_foldl2_from_1(
+ summarize_call_site_dynamic(Deep0 ^ call_site_static_map,
Deep0 ^ csd_desc),
Deep0 ^ call_site_dynamics,
copy(CSSOwn0), CSSOwn, copy(CSSDesc0), CSSDesc),
@@ -777,373 +695,3 @@
).
%-----------------------------------------------------------------------------%
-
-:- pred merge_cliques(list(list(proc_dynamic_ptr))::in,
- initial_deep::in, initial_deep::out) is det.
-
-merge_cliques([], InitDeep, InitDeep).
-merge_cliques([Clique | Cliques], InitDeep0, InitDeep) :-
- merge_clique(Clique, InitDeep0, InitDeep1),
- merge_cliques(Cliques, InitDeep1, InitDeep).
-
-:- pred merge_clique(list(proc_dynamic_ptr)::in,
- initial_deep::in, initial_deep::out) is det.
-
-merge_clique(CliquePDs, InitDeep0, InitDeep) :-
- map__init(ProcMap0),
- set__list_to_set(CliquePDs, Clique),
- list__foldl(cluster_pds_by_ps(InitDeep0), CliquePDs,
- ProcMap0, ProcMap),
- map__values(ProcMap, PDsList),
- list__filter(two_or_more, PDsList, ToMergePDsList),
- list__foldl(merge_proc_dynamics(Clique), ToMergePDsList,
- InitDeep0, InitDeep).
-
-:- pred merge_proc_dynamics(set(proc_dynamic_ptr)::in,
- list(proc_dynamic_ptr)::in,
- initial_deep::in, initial_deep::out) is det.
-
-merge_proc_dynamics(Clique, CandidatePDPtrs, InitDeep0, InitDeep) :-
- ProcDynamics0 = InitDeep0 ^ init_proc_dynamics,
- list__filter(valid_proc_dynamic_ptr_raw(ProcDynamics0),
- CandidatePDPtrs, ValidPDPtrs),
- ( ValidPDPtrs = [PrimePDPtr | RestPDPtrs] ->
- record_pd_redirect(RestPDPtrs, PrimePDPtr,
- InitDeep0, InitDeep1),
- ProcDynamics1 = InitDeep1 ^ init_proc_dynamics,
- lookup_proc_dynamics(ProcDynamics1, PrimePDPtr, PrimePD0),
- list__map(lookup_proc_dynamics(ProcDynamics1),
- RestPDPtrs, RestPDs),
- list__map(extract_pd_sites, RestPDs, RestSites),
- require(unify(PrimePD0 ^ pd_redirect, no),
- "merge_proc_dynamics: pd already redirected"),
- PrimeSites0 = PrimePD0 ^ pd_sites,
- array__max(PrimeSites0, MaxSiteNum),
- merge_proc_dynamic_slots(MaxSiteNum, Clique, PrimePDPtr,
- u(PrimeSites0), RestSites, PrimeSites,
- InitDeep1, InitDeep2),
- PrimePD = PrimePD0 ^ pd_sites := PrimeSites,
- ProcDynamics2 = InitDeep2 ^ init_proc_dynamics,
- update_proc_dynamics(u(ProcDynamics2), PrimePDPtr, PrimePD,
- ProcDynamics),
- InitDeep = InitDeep2 ^ init_proc_dynamics := ProcDynamics
- ;
- % This can happen when merging the callees of CSDs
- % representing special calls.
- InitDeep = InitDeep0
- ).
-
-:- pred merge_proc_dynamic_slots(int::in, set(proc_dynamic_ptr)::in,
- proc_dynamic_ptr::in, array(call_site_array_slot)::array_di,
- list(array(call_site_array_slot))::in,
- array(call_site_array_slot)::array_uo,
- initial_deep::in, initial_deep::out) is det.
-
-merge_proc_dynamic_slots(SlotNum, Clique, PrimePDPtr, PrimeSiteArray0,
- RestSiteArrays, PrimeSiteArray, InitDeep0, InitDeep) :-
- ( SlotNum >= 0 ->
- array__lookup(PrimeSiteArray0, SlotNum, PrimeSite0),
- (
- PrimeSite0 = normal(PrimeCSDPtr0),
- merge_proc_dynamic_normal_slot(SlotNum, Clique,
- PrimePDPtr, PrimeCSDPtr0, RestSiteArrays,
- PrimeCSDPtr, InitDeep0, InitDeep1),
- array__set(PrimeSiteArray0, SlotNum,
- normal(PrimeCSDPtr), PrimeSiteArray1)
- ;
- PrimeSite0 = multi(PrimeCSDPtrArray0),
- array__to_list(PrimeCSDPtrArray0, PrimeCSDPtrList0),
- merge_proc_dynamic_multi_slot(SlotNum, Clique,
- PrimePDPtr, PrimeCSDPtrList0, RestSiteArrays,
- PrimeCSDPtrList, InitDeep0, InitDeep1),
- PrimeCSDPtrArray = array(PrimeCSDPtrList),
- array__set(PrimeSiteArray0, SlotNum,
- multi(PrimeCSDPtrArray), PrimeSiteArray1)
- ),
- merge_proc_dynamic_slots(SlotNum - 1, Clique, PrimePDPtr,
- PrimeSiteArray1, RestSiteArrays, PrimeSiteArray,
- InitDeep1, InitDeep)
- ;
- PrimeSiteArray = PrimeSiteArray0,
- InitDeep = InitDeep0
- ).
-
-:- pred merge_proc_dynamic_normal_slot(int::in, set(proc_dynamic_ptr)::in,
- proc_dynamic_ptr::in, call_site_dynamic_ptr::in,
- list(array(call_site_array_slot))::in, call_site_dynamic_ptr::out,
- initial_deep::in, initial_deep::out) is det.
-
-merge_proc_dynamic_normal_slot(SlotNum, Clique, PrimePDPtr, PrimeCSDPtr0,
- RestSiteArrays, PrimeCSDPtr, InitDeep0, InitDeep) :-
- lookup_normal_sites(RestSiteArrays, SlotNum, RestCSDPtrs),
- merge_call_site_dynamics(Clique, PrimePDPtr,
- [PrimeCSDPtr0 | RestCSDPtrs], PrimeCSDPtr,
- InitDeep0, InitDeep).
-
-:- pred accumulate_csd_owns(call_site_dynamic::in,
- own_prof_info::in, own_prof_info::out) is det.
-
-accumulate_csd_owns(CSD, Own0, Own) :-
- Own = add_own_to_own(Own0, CSD ^ csd_own_prof).
-
-:- pred callee_in_clique(initial_deep::in, set(proc_dynamic_ptr)::in,
- call_site_dynamic_ptr::in) is semidet.
-
-callee_in_clique(InitDeep, Clique, CSDPtr) :-
- lookup_call_site_dynamics(InitDeep ^ init_call_site_dynamics,
- CSDPtr, CSD),
- CalleePDPtr = CSD ^ csd_callee,
- set__member(CalleePDPtr, Clique).
-
-:- pred merge_proc_dynamic_multi_slot(int::in, set(proc_dynamic_ptr)::in,
- proc_dynamic_ptr::in, list(call_site_dynamic_ptr)::in,
- list(array(call_site_array_slot))::in,
- list(call_site_dynamic_ptr)::out, initial_deep::in, initial_deep::out)
- is det.
-
-merge_proc_dynamic_multi_slot(SlotNum, Clique, ParentPDPtr, PrimeCSDPtrs0,
- RestSiteArrays, PrimeCSDPtrs, InitDeep0, InitDeep) :-
- lookup_multi_sites(RestSiteArrays, SlotNum, RestCSDPtrLists),
- list__condense([PrimeCSDPtrs0 | RestCSDPtrLists], AllCSDPtrs),
- map__init(ProcMap0),
- list__foldl(cluster_csds_by_ps(InitDeep0), AllCSDPtrs,
- ProcMap0, ProcMap),
- map__values(ProcMap, CSDPtrsClusters),
- list__foldl2(merge_multi_slot_cluster(ParentPDPtr, Clique),
- CSDPtrsClusters, [], PrimeCSDPtrs, InitDeep0, InitDeep).
-
-:- pred merge_multi_slot_cluster(proc_dynamic_ptr::in,
- set(proc_dynamic_ptr)::in, list(call_site_dynamic_ptr)::in,
- list(call_site_dynamic_ptr)::in, list(call_site_dynamic_ptr)::out,
- initial_deep::in, initial_deep::out) is det.
-
-merge_multi_slot_cluster(ParentPDPtr, Clique, ClusterCSDPtrs,
- PrimeCSDPtrs0, PrimeCSDPtrs, InitDeep0, InitDeep) :-
- merge_call_site_dynamics(Clique, ParentPDPtr, ClusterCSDPtrs,
- PrimeCSDPtr, InitDeep0, InitDeep),
- PrimeCSDPtrs = [PrimeCSDPtr | PrimeCSDPtrs0].
-
-:- pred merge_call_site_dynamics(set(proc_dynamic_ptr)::in,
- proc_dynamic_ptr::in, list(call_site_dynamic_ptr)::in,
- call_site_dynamic_ptr::out,
- initial_deep::in, initial_deep::out) is det.
-
-merge_call_site_dynamics(Clique, ParentPDPtr, CandidateCSDPtrs,
- FirstCSDPtr, InitDeep0, InitDeep) :-
- CallSiteDynamics0 = InitDeep0 ^ init_call_site_dynamics,
- list__filter(valid_call_site_dynamic_ptr_raw(CallSiteDynamics0),
- CandidateCSDPtrs, ValidCSDPtrs),
- (
- ValidCSDPtrs = [],
- % This signifies that there is no call here.
- FirstCSDPtr = call_site_dynamic_ptr(0),
- InitDeep = InitDeep0
- ;
- ValidCSDPtrs = [FirstCSDPtr | LaterCSDPtrs],
- lookup_call_site_dynamics(CallSiteDynamics0, FirstCSDPtr,
- FirstCSD0),
- FirstCSD = FirstCSD0 ^ csd_caller := ParentPDPtr,
- update_call_site_dynamics(u(CallSiteDynamics0), FirstCSDPtr,
- FirstCSD, CallSiteDynamics),
- InitDeep1 = InitDeep0 ^ init_call_site_dynamics
- := CallSiteDynamics,
- (
- LaterCSDPtrs = [],
- InitDeep = InitDeep1
- ;
- LaterCSDPtrs = [_ | _],
- merge_call_site_dynamics_2(Clique,
- FirstCSDPtr, LaterCSDPtrs, InitDeep1, InitDeep)
- )
- ).
-
-:- pred merge_call_site_dynamics_2(set(proc_dynamic_ptr)::in,
- call_site_dynamic_ptr::in, list(call_site_dynamic_ptr)::in,
- initial_deep::in, initial_deep::out) is det.
-
-merge_call_site_dynamics_2(Clique, PrimeCSDPtr, RestCSDPtrs,
- InitDeep0, InitDeep) :-
- record_csd_redirect(RestCSDPtrs, PrimeCSDPtr, InitDeep0, InitDeep1),
- CallSiteDynamics1 = InitDeep1 ^ init_call_site_dynamics,
- lookup_call_site_dynamics(CallSiteDynamics1, PrimeCSDPtr, PrimeCSD1),
- list__map(lookup_call_site_dynamics(CallSiteDynamics1),
- RestCSDPtrs, RestCSDs),
- PrimeOwn1 = PrimeCSD1 ^ csd_own_prof,
- list__foldl(accumulate_csd_owns, RestCSDs, PrimeOwn1, PrimeOwn2),
- PrimeCSD2 = PrimeCSD1 ^ csd_own_prof := PrimeOwn2,
- update_call_site_dynamics(u(CallSiteDynamics1), PrimeCSDPtr, PrimeCSD2,
- CallSiteDynamics2),
- InitDeep2 = InitDeep1 ^ init_call_site_dynamics := CallSiteDynamics2,
- list__filter(callee_in_clique(InitDeep2, Clique), RestCSDPtrs,
- InClique, NotInClique),
- ( callee_in_clique(InitDeep2, Clique, PrimeCSDPtr) ->
- require(unify(NotInClique, []),
- "merge_proc_dynamic_normal_slot: prime in clique, others not in clique"),
- InitDeep = InitDeep2
- ;
- require(unify(InClique, []),
- "merge_proc_dynamic_normal_slot: prime not in clique, others in clique"),
- merge_call_site_dynamics_descendants(PrimeCSDPtr, RestCSDPtrs,
- InitDeep2, InitDeep)
- % XXX must ensure that PrimeCSDPtr ^ csd_callee is the chosen
- % ProcDynamic
- ).
-
-:- pred merge_call_site_dynamics_descendants(call_site_dynamic_ptr::in,
- list(call_site_dynamic_ptr)::in, initial_deep::in, initial_deep::out)
- is det.
-
-merge_call_site_dynamics_descendants(PrimeCSDPtr, RestCSDPtrs,
- InitDeep0, InitDeep) :-
- CallSiteDynamics = InitDeep0 ^ init_call_site_dynamics,
- lookup_call_site_dynamics(CallSiteDynamics, PrimeCSDPtr, PrimeCSD),
- extract_csd_callee(PrimeCSD, PrimeCSDCallee),
- list__map(lookup_call_site_dynamics(CallSiteDynamics),
- RestCSDPtrs, RestCSDs),
- list__map(extract_csd_callee, RestCSDs, RestCSDCallees),
- merge_proc_dynamics(set__init, [PrimeCSDCallee | RestCSDCallees],
- InitDeep0, InitDeep).
-
-:- pred lookup_normal_sites(list(array(call_site_array_slot))::in, int::in,
- list(call_site_dynamic_ptr)::out) is det.
-
-lookup_normal_sites([], _, []).
-lookup_normal_sites([RestArray | RestArrays], SlotNum, [CSDPtr | CSDPtrs]) :-
- array__lookup(RestArray, SlotNum, Slot),
- (
- Slot = normal(CSDPtr)
- ;
- Slot = multi(_),
- error("lookup_normal_sites: found multi")
- ),
- lookup_normal_sites(RestArrays, SlotNum, CSDPtrs).
-
-:- pred lookup_multi_sites(list(array(call_site_array_slot))::in, int::in,
- list(list(call_site_dynamic_ptr))::out) is det.
-
-lookup_multi_sites([], _, []).
-lookup_multi_sites([RestArray | RestArrays], SlotNum, [CSDList | CSDLists]) :-
- array__lookup(RestArray, SlotNum, Slot),
- (
- Slot = normal(_),
- error("lookup_multi_sites: found normal")
- ;
- Slot = multi(CSDArray),
- array__to_list(CSDArray, CSDList)
- ),
- lookup_multi_sites(RestArrays, SlotNum, CSDLists).
-
-:- pragma promise_pure(record_pd_redirect/4).
-:- pred record_pd_redirect(list(proc_dynamic_ptr)::in, proc_dynamic_ptr::in,
- initial_deep::in, initial_deep::out) is det.
-
-record_pd_redirect(RestPDPtrs, PrimePDPtr, InitDeep0, InitDeep) :-
- impure unsafe_perform_io(io__write_string("pd redirect: ")),
- impure unsafe_perform_io(io__print(RestPDPtrs)),
- impure unsafe_perform_io(io__write_string(" -> ")),
- impure unsafe_perform_io(io__print(PrimePDPtr)),
- impure unsafe_perform_io(io__nl),
- record_pd_redirect_2(RestPDPtrs, PrimePDPtr, InitDeep0, InitDeep).
-
-:- pred record_pd_redirect_2(list(proc_dynamic_ptr)::in, proc_dynamic_ptr::in,
- initial_deep::in, initial_deep::out) is det.
-
-record_pd_redirect_2([], _, InitDeep, InitDeep).
-record_pd_redirect_2([RestPDPtr | RestPDPtrs], PrimePDPtr,
- InitDeep0, InitDeep) :-
- ProcDynamics0 = InitDeep0 ^ init_proc_dynamics,
- lookup_proc_dynamics(ProcDynamics0, RestPDPtr, RestPD0),
- require(unify(RestPD0 ^ pd_redirect, no),
- "record_pd_redirect: already redirected"),
- RestPD = RestPD0 ^ pd_redirect := yes(PrimePDPtr),
- update_proc_dynamics(u(ProcDynamics0), RestPDPtr, RestPD,
- ProcDynamics),
- InitDeep1 = InitDeep0 ^ init_proc_dynamics := ProcDynamics,
- record_pd_redirect_2(RestPDPtrs, PrimePDPtr, InitDeep1, InitDeep).
-
-:- pragma promise_pure(record_csd_redirect/4).
-:- pred record_csd_redirect(list(call_site_dynamic_ptr)::in,
- call_site_dynamic_ptr::in, initial_deep::in, initial_deep::out) is det.
-
-record_csd_redirect(RestCSDPtrs, PrimeCSDPtr, InitDeep0, InitDeep) :-
- impure unsafe_perform_io(io__write_string("csd redirect: ")),
- impure unsafe_perform_io(io__print(RestCSDPtrs)),
- impure unsafe_perform_io(io__write_string(" -> ")),
- impure unsafe_perform_io(io__print(PrimeCSDPtr)),
- impure unsafe_perform_io(io__nl),
- record_csd_redirect_2(RestCSDPtrs, PrimeCSDPtr, InitDeep0, InitDeep).
-
-:- pred record_csd_redirect_2(list(call_site_dynamic_ptr)::in,
- call_site_dynamic_ptr::in, initial_deep::in, initial_deep::out) is det.
-
-record_csd_redirect_2([], _, InitDeep, InitDeep).
-record_csd_redirect_2([RestCSDPtr | RestCSDPtrs], PrimeCSDPtr,
- InitDeep0, InitDeep) :-
- CallSiteDynamics0 = InitDeep0 ^ init_call_site_dynamics,
- lookup_call_site_dynamics(CallSiteDynamics0, RestCSDPtr, RestCSD0),
- require(unify(RestCSD0 ^ csd_redirect, no),
- "record_csd_redirect: already redirected"),
- RestCSD = RestCSD0 ^ csd_redirect := yes(PrimeCSDPtr),
- update_call_site_dynamics(u(CallSiteDynamics0), RestCSDPtr, RestCSD,
- CallSiteDynamics),
- InitDeep1 = InitDeep0 ^ init_call_site_dynamics := CallSiteDynamics,
- record_csd_redirect_2(RestCSDPtrs, PrimeCSDPtr, InitDeep1, InitDeep).
-
-:- pred extract_pd_sites(proc_dynamic::in, array(call_site_array_slot)::out)
- is det.
-
-extract_pd_sites(PD, PD ^ pd_sites).
-
-:- pred extract_csd_callee(call_site_dynamic::in, proc_dynamic_ptr::out)
- is det.
-
-extract_csd_callee(CSD, CSD ^ csd_callee).
-
-:- pred two_or_more(list(proc_dynamic_ptr)::in) is semidet.
-
-two_or_more([_, _ | _]).
-
-:- pred cluster_pds_by_ps(initial_deep::in, proc_dynamic_ptr::in,
- map(proc_static_ptr, list(proc_dynamic_ptr))::in,
- map(proc_static_ptr, list(proc_dynamic_ptr))::out) is det.
-
-cluster_pds_by_ps(InitDeep, PDPtr, ProcMap0, ProcMap) :-
- ProcDynamics = InitDeep ^ init_proc_dynamics,
- ( valid_proc_dynamic_ptr_raw(ProcDynamics, PDPtr) ->
- lookup_proc_dynamics(ProcDynamics, PDPtr, PD),
- PSPtr = PD ^ pd_proc_static,
- ( map__search(ProcMap0, PSPtr, PDPtrs0) ->
- map__det_update(ProcMap0, PSPtr, [PDPtr | PDPtrs0],
- ProcMap)
- ;
- map__det_insert(ProcMap0, PSPtr, [PDPtr], ProcMap)
- )
- ;
- ProcMap = ProcMap0
- ).
-
-:- pred cluster_csds_by_ps(initial_deep::in, call_site_dynamic_ptr::in,
- map(proc_static_ptr, list(call_site_dynamic_ptr))::in,
- map(proc_static_ptr, list(call_site_dynamic_ptr))::out) is det.
-
-cluster_csds_by_ps(InitDeep, CSDPtr, ProcMap0, ProcMap) :-
- CallSiteDynamics = InitDeep ^ init_call_site_dynamics,
- ( valid_call_site_dynamic_ptr_raw(CallSiteDynamics, CSDPtr) ->
- lookup_call_site_dynamics(CallSiteDynamics, CSDPtr, CSD),
- PDPtr = CSD ^ csd_callee,
- ProcDynamics = InitDeep ^ init_proc_dynamics,
- ( valid_proc_dynamic_ptr_raw(ProcDynamics, PDPtr) ->
- lookup_proc_dynamics(ProcDynamics, PDPtr, PD),
- PSPtr = PD ^ pd_proc_static
- ;
- PSPtr = proc_static_ptr(0)
- ),
- ( map__search(ProcMap0, PSPtr, CSDPtrs0) ->
- map__det_update(ProcMap0, PSPtr, [CSDPtr | CSDPtrs0],
- ProcMap)
- ;
- map__det_insert(ProcMap0, PSPtr, [CSDPtr], ProcMap)
- )
- ;
- ProcMap = ProcMap0
- ).
cvs diff: Diffing notes
Index: notes/deep_profiling.html
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/notes/deep_profiling.html,v
retrieving revision 1.1
diff -u -b -r1.1 deep_profiling.html
--- notes/deep_profiling.html 2001/05/31 06:00:00 1.1
+++ notes/deep_profiling.html 2001/06/04 09:45:22
@@ -293,6 +293,17 @@
<dt> array_util.m
<dd>
This module contains utility predicates for handling arrays.
+<dt> callgraph.m
+<dd>
+This module constructs an explicit representation of the call graph,
+so we can find its cliques.
+<dt> canonical.m
+<dd>
+This module has code to canonicalize call graphs
+(i.e. ensure that no clique contains
+more than one ProcDynamic from a given procedure).
+It also has code that uses canonicalization to merge two call graphs.
+This module is not complete yet.
<dt> cliques.m
<dd>
This module allows you build a description of a directed graph (represented
@@ -313,6 +324,9 @@
This module defines the type of the commands
that mdprof_cgi passes to mdprof_server,
as well as utility predicates for manipulating commands and responses.
+<dt> io_combinator.m
+<dd>
+This module a set of I/O combinators for use by read_profile.m.
<dt> mdprof_cgi.m
<dd>
This file contains the program that is executed by the web server
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list