[m-dev.] [reuse] diff: write out call graph
Peter Ross
peter.ross at miscrit.be
Tue Oct 24 01:41:08 AEDT 2000
Hi,
===================================================================
Estimated hours taken: 4
Output the call graph of the module in the .profile file.
Nodes which are red squares are those which have structure reuse.
dependency_graph.m:
Add dependency_graph__build_dependency_graph with an option of
whether or not we consider imported procedures.
Add some higher order code to write out a dependency graph.
sr_profile.m:
Write out the dependency graph, coloring any procedures which have
reuse.
sr_profile_run.m:
Pass the HLDS to sr_profile__write_profiling.
Index: dependency_graph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.48.2.1
diff -u -r1.48.2.1 dependency_graph.m
--- dependency_graph.m 2000/09/27 14:59:12 1.48.2.1
+++ dependency_graph.m 2000/10/23 14:33:48
@@ -21,11 +21,18 @@
:- interface.
:- import_module hlds_module, hlds_pred.
-:- import_module list, io.
+:- import_module bool, list, io.
:- pred module_info_ensure_dependency_info(module_info, module_info).
:- mode module_info_ensure_dependency_info(in, out) is det.
+ % Give me the dependency graph. If the bool is yes then
+ % imported_procedures aren't included in the dependency graph,
+ % otherwise they are.
+:- pred dependency_graph__build_dependency_graph(module_info, bool,
+ dependency_info).
+:- mode dependency_graph__build_dependency_graph(in, in, out) is det.
+
:- pred dependency_graph__write_dependency_graph(module_info, module_info,
io__state, io__state).
:- mode dependency_graph__write_dependency_graph(in, out, di, uo) is det.
@@ -56,6 +63,28 @@
:- pred module_info_ensure_aditi_dependency_info(module_info, module_info).
:- mode module_info_ensure_aditi_dependency_info(in, out) is det.
+ % write_graph(Graph, WriteNode, WriteEdge)
+ %
+ % Write out the dependency graph using two higher predicates to
+ % decide output a node and any edges.
+ %
+:- pred write_graph(dependency_info::in,
+ pred(pred_proc_id, io__state, io__state)::pred(in, di, uo) is det,
+ pred(pred_proc_id, pred_proc_id, io__state, io__state)::
+ pred(in, in, di, uo) is det,
+ io__state::di, io__state::uo) is det.
+
+ % write_graph_nodes(Nodes, Graph, WriteNode, WriteEdge)
+ %
+ % Write out each of the Nodes in the Graph and any edges
+ % origination in Nodes.
+ %
+:- pred write_graph_nodes(list(pred_proc_id)::in, dependency_graph::in,
+ pred(pred_proc_id, io__state, io__state)::pred(in, di, uo) is det,
+ pred(pred_proc_id, pred_proc_id, io__state, io__state)::
+ pred(in, in, di, uo) is det,
+ io__state::di, io__state::uo) is det.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -85,21 +114,19 @@
( MaybeDepInfo = yes(_) ->
ModuleInfo = ModuleInfo0
;
- dependency_graph__build_dependency_graph(ModuleInfo0, ModuleInfo)
+ dependency_graph__build_dependency_graph(ModuleInfo0, yes, DepInfo),
+ module_info_set_dependency_info(ModuleInfo0, DepInfo, ModuleInfo)
).
% Traverse the module structure, calling `dependency_graph__add_arcs'
% for each procedure body.
-:- pred dependency_graph__build_dependency_graph(module_info, module_info).
-:- mode dependency_graph__build_dependency_graph(in, out) is det.
-
-dependency_graph__build_dependency_graph(ModuleInfo0, ModuleInfo) :-
+dependency_graph__build_dependency_graph(ModuleInfo0, LocalOnly, DepInfo) :-
module_info_predids(ModuleInfo0, PredIds),
relation__init(DepGraph0),
- dependency_graph__add_pred_nodes(PredIds, ModuleInfo0,
+ dependency_graph__add_pred_nodes(PredIds, ModuleInfo0, LocalOnly,
DepGraph0, DepGraph1),
- dependency_graph__add_pred_arcs(PredIds, ModuleInfo0,
+ dependency_graph__add_pred_arcs(PredIds, ModuleInfo0, LocalOnly,
DepGraph1, DepGraph),
hlds_dependency_info_init(DepInfo0),
hlds_dependency_info_set_dependency_graph(DepInfo0, DepGraph,
@@ -107,8 +134,7 @@
relation__atsort(DepGraph, DepOrd0),
dependency_graph__sets_to_lists(DepOrd0, [], DepOrd),
hlds_dependency_info_set_dependency_ordering(DepInfo1, DepOrd,
- DepInfo),
- module_info_set_dependency_info(ModuleInfo0, DepInfo, ModuleInfo).
+ DepInfo).
:- pred dependency_graph__sets_to_lists( list(set(pred_proc_id)),
list(list(pred_proc_id)), list(list(pred_proc_id))).
@@ -123,21 +149,28 @@
%-----------------------------------------------------------------------------%
:- pred dependency_graph__add_pred_nodes(list(pred_id), module_info,
- dependency_graph, dependency_graph).
-:- mode dependency_graph__add_pred_nodes(in, in, in, out) is det.
+ bool, dependency_graph, dependency_graph).
+:- mode dependency_graph__add_pred_nodes(in, in, in, in, out) is det.
-dependency_graph__add_pred_nodes([], _ModuleInfo, DepGraph, DepGraph).
-dependency_graph__add_pred_nodes([PredId | PredIds], ModuleInfo,
+dependency_graph__add_pred_nodes([], _ModuleInfo, _, DepGraph, DepGraph).
+dependency_graph__add_pred_nodes([PredId | PredIds], ModuleInfo, LocalOnly,
DepGraph0, DepGraph) :-
module_info_preds(ModuleInfo, PredTable),
map__lookup(PredTable, PredId, PredInfo),
- % Don't bother adding nodes (or arcs) for procedures
- % which which are imported (ie we don't have any `clauses'
- % for).
- pred_info_non_imported_procids(PredInfo, ProcIds),
+ (
+ % Don't bother adding nodes (or arcs) for procedures
+ % which which are imported (ie we don't have any
+ % `clauses' for).
+ LocalOnly = yes,
+ pred_info_non_imported_procids(PredInfo, ProcIds)
+ ;
+ LocalOnly = no,
+ pred_info_procids(PredInfo, ProcIds)
+ ),
+
dependency_graph__add_proc_nodes(ProcIds, PredId, ModuleInfo,
DepGraph0, DepGraph1),
- dependency_graph__add_pred_nodes(PredIds, ModuleInfo,
+ dependency_graph__add_pred_nodes(PredIds, ModuleInfo, LocalOnly,
DepGraph1, DepGraph).
:- pred dependency_graph__add_proc_nodes(list(proc_id), pred_id, module_info,
@@ -154,39 +187,70 @@
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
-:- pred dependency_graph__add_pred_arcs(list(pred_id), module_info,
+:- pred dependency_graph__add_pred_arcs(list(pred_id), module_info, bool,
dependency_graph, dependency_graph).
-:- mode dependency_graph__add_pred_arcs(in, in, in, out) is det.
+:- mode dependency_graph__add_pred_arcs(in, in, in, in, out) is det.
-dependency_graph__add_pred_arcs([], _ModuleInfo, DepGraph, DepGraph).
-dependency_graph__add_pred_arcs([PredId | PredIds], ModuleInfo,
+dependency_graph__add_pred_arcs([], _ModuleInfo, _, DepGraph, DepGraph).
+dependency_graph__add_pred_arcs([PredId | PredIds], ModuleInfo, LocalOnly,
DepGraph0, DepGraph) :-
module_info_preds(ModuleInfo, PredTable),
map__lookup(PredTable, PredId, PredInfo),
- pred_info_non_imported_procids(PredInfo, ProcIds),
- dependency_graph__add_proc_arcs(ProcIds, PredId, ModuleInfo,
+ (
+ % Don't bother adding nodes (or arcs) for procedures
+ % which which are imported (ie we don't have any
+ % `clauses' for).
+ LocalOnly = yes,
+ pred_info_non_imported_procids(PredInfo, ProcIds)
+ ;
+ LocalOnly = no,
+ pred_info_procids(PredInfo, ProcIds)
+ ),
+ dependency_graph__add_proc_arcs(ProcIds, PredId, ModuleInfo, LocalOnly,
DepGraph0, DepGraph1),
- dependency_graph__add_pred_arcs(PredIds, ModuleInfo,
+ dependency_graph__add_pred_arcs(PredIds, ModuleInfo, LocalOnly,
DepGraph1, DepGraph).
:- pred dependency_graph__add_proc_arcs(list(proc_id), pred_id, module_info,
- dependency_graph, dependency_graph).
-:- mode dependency_graph__add_proc_arcs(in, in, in, in, out) is det.
+ bool, dependency_graph, dependency_graph).
+:- mode dependency_graph__add_proc_arcs(in, in, in, in, in, out) is det.
-dependency_graph__add_proc_arcs([], _PredId, _ModuleInfo, DepGraph, DepGraph).
+dependency_graph__add_proc_arcs([], _PredId, _ModuleInfo, _,
+ DepGraph, DepGraph).
dependency_graph__add_proc_arcs([ProcId | ProcIds], PredId, ModuleInfo,
- DepGraph0, DepGraph) :-
+ LocalOnly, DepGraph0, DepGraph) :-
+
module_info_preds(ModuleInfo, PredTable0),
map__lookup(PredTable0, PredId, PredInfo0),
pred_info_procedures(PredInfo0, ProcTable0),
map__lookup(ProcTable0, ProcId, ProcInfo0),
- proc_info_goal(ProcInfo0, Goal),
+ (
+ LocalOnly = yes,
+ proc_info_goal(ProcInfo0, Goal),
- relation__lookup_element(DepGraph0, proc(PredId, ProcId), Caller),
- dependency_graph__add_arcs_in_goal(Goal, Caller, DepGraph0, DepGraph1),
+ relation__lookup_element(DepGraph0,
+ proc(PredId, ProcId), Caller),
+ dependency_graph__add_arcs_in_goal(Goal, Caller,
+ DepGraph0, DepGraph1)
+ ;
+ LocalOnly = no,
+ pred_info_import_status(PredInfo0, ImportStatus),
+ status_is_imported(ImportStatus, Imported),
+ (
+ Imported = yes,
+ DepGraph1 = DepGraph0
+ ;
+ Imported = no,
+ proc_info_goal(ProcInfo0, Goal),
- dependency_graph__add_proc_arcs(ProcIds, PredId, ModuleInfo,
+ relation__lookup_element(DepGraph0,
+ proc(PredId, ProcId), Caller),
+ dependency_graph__add_arcs_in_goal(Goal, Caller,
+ DepGraph0, DepGraph1)
+ )
+ ),
+ dependency_graph__add_proc_arcs(ProcIds, PredId, ModuleInfo, LocalOnly,
DepGraph1, DepGraph).
%-----------------------------------------------------------------------------%
@@ -514,6 +578,38 @@
io__write_string("\n"),
dependency_graph__write_prof_dependency_graph_3(Ss, Node, DepGraph,
ModuleInfo).
+
+%-----------------------------------------------------------------------------%
+
+write_graph(DepInfo, WriteNode, WriteLink) -->
+ { hlds_dependency_info_get_dependency_graph(DepInfo, DepGraph) },
+ { relation__domain(DepGraph, DomSet) },
+ { set__to_sorted_list(DomSet, DomList) },
+ write_graph_nodes(DomList, DepGraph, WriteNode, WriteLink).
+
+write_graph_nodes([], _Graph, _WriteNode, _WriteLink) --> [].
+write_graph_nodes([Node | Nodes], Graph, WriteNode, WriteLink) -->
+ WriteNode(Node),
+
+ { relation__lookup_element(Graph, Node, NodeKey) },
+ { relation__lookup_from(Graph, NodeKey, ChildrenSet) },
+ { set__to_sorted_list(ChildrenSet, Children) },
+
+ write_graph_children(Children, Node, Graph, WriteLink),
+
+ write_graph_nodes(Nodes, Graph, WriteNode, WriteLink).
+
+:- pred write_graph_children(list(relation_key)::in, pred_proc_id::in,
+ dependency_graph::in,
+ pred(pred_proc_id, pred_proc_id, io__state, io__state)::
+ pred(in, in, di, uo) is det,
+ io__state::di, io__state::uo) is det.
+
+write_graph_children([], _Parent, _Graph, _WriteLink) --> [].
+write_graph_children([ChildKey | Children], Parent, Graph, WriteLink) -->
+ { relation__lookup_key(Graph, ChildKey, Child) },
+ WriteLink(Parent, Child),
+ write_graph_children(Children, Parent, Graph, WriteLink).
%-----------------------------------------------------------------------------%
Index: sr_profile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_profile.m,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 sr_profile.m
--- sr_profile.m 2000/10/18 22:38:09 1.1.2.1
+++ sr_profile.m 2000/10/23 14:33:48
@@ -12,6 +12,7 @@
:- interface.
:- import_module io, int, string.
+:- import_module hlds_module.
:- type profiling_info --->
prof(
@@ -66,14 +67,15 @@
:- pred inc_no_reuse_calls( profiling_info::in, profiling_info::out ) is det.
-:- pred write_profiling( string::in, profiling_info::in,
+:- pred write_profiling( string::in, profiling_info::in, module_info::in,
io__state::di, io__state::uo ) is det.
%-----------------------------------------------------------------------------%
:- implementation.
-:- import_module require, time, list.
+:- import_module bool, relation, require, set, time, list, std_util.
+:- import_module dependency_graph, hlds_out, hlds_pred.
init( P ) :-
P = prof( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).
@@ -134,13 +136,13 @@
reuse_calls( P0, P0 ^ reuse_calls ).
no_reuse_calls( P0, P0 ^ no_reuse_calls ).
-write_profiling( String, Prof ) -->
+write_profiling( String, Prof, HLDS ) -->
{ string__append(String, ".profile", String2) },
io__open_output( String2, IOResult),
(
{ IOResult = ok(Stream) },
% top
- io__write_string(Stream, "Profiling output for module: "),
+ io__write_string(Stream, "/*\nProfiling output for module: "),
io__write_string(Stream, String),
io__nl(Stream),
% date
@@ -187,12 +189,88 @@
"# calls to procedures with reuse"),
write_prof_item( Stream, no_reuse_calls, Prof,
"# failed calls to procedures with reuse"),
+
+ io__write_string( Stream, "*/\ndigraph "),
+ io__write_string(Stream, String),
+ io__write_string(Stream, " {\n"),
+ { dependency_graph__build_dependency_graph(HLDS,
+ no, DepInfo) },
+ { hlds_dependency_info_get_dependency_graph(DepInfo,
+ DepGraph) },
+ { relation__components(DepGraph, ComponentsSet) },
+ { list__filter_map(
+ (pred(ComponentSet::in, Component::out) is semidet :-
+ ( set__singleton_set(ComponentSet, C0) ->
+ relation__lookup_key(DepGraph, C0, C),
+ C = proc(PredId, _ProcId),
+ module_info_pred_info(HLDS,
+ PredId, PredInfo),
+ pred_info_import_status(PredInfo,
+ ImportStatus),
+ status_defined_in_this_module(
+ ImportStatus, yes)
+ ;
+ \+ set__singleton_set(ComponentSet, _)
+ ),
+ Component = set__to_sorted_list(ComponentSet)
+ ), set__to_sorted_list(ComponentsSet), DomList0) },
+ { list__condense(DomList0, DomList1) },
+ { list__map(relation__lookup_key(DepGraph), DomList1,
+ DomList) },
+
+ write_graph_nodes(DomList, DepGraph,
+ write_procedure_node(HLDS, Stream),
+ write_procedure_link(HLDS, Stream)),
+
+ io__write_string(Stream, "\n}\n"),
+
io__close_output(Stream)
;
{ IOResult = error(IOError) },
{ io__error_message(IOError, IOErrorString) },
{ require__error(IOErrorString) }
).
+
+:- pred write_procedure_node(module_info::in, io__output_stream::in,
+ pred_proc_id::in, io__state::di, io__state::uo) is det.
+
+write_procedure_node(HLDS, Stream, PredProcId) -->
+ io__set_output_stream(Stream, OldStream),
+ { PredProcId = proc(PredId, ProcId) },
+ { module_info_pred_proc_info(HLDS, PredProcId, _PredInfo, ProcInfo) },
+ { proc_info_reuse_information(ProcInfo, ReuseInfo) },
+
+ io__write_char('"'),
+ hlds_out__write_pred_proc_id(HLDS, PredId, ProcId),
+ io__write_char('"'),
+
+ ( { ReuseInfo = yes(_) } ->
+ io__write_string(" [style=filled,color=red,shape=box];\n")
+ ;
+ io__write_string(";\n")
+ ),
+
+ io__set_output_stream(OldStream, _).
+
+:- pred write_procedure_link(module_info::in, io__output_stream::in,
+ pred_proc_id::in, pred_proc_id::in,
+ io__state::di, io__state::uo) is det.
+
+write_procedure_link(HLDS, Stream, Parent, Child) -->
+ io__set_output_stream(Stream, OldStream),
+ { Parent = proc(ParentPredId, ParentProcId) },
+ { Child = proc(ChildPredId, ChildProcId) },
+
+ io__write_char('"'),
+ hlds_out__write_pred_proc_id(HLDS, ParentPredId, ParentProcId),
+ io__write_string("\" -> "),
+
+ io__write_char('"'),
+ hlds_out__write_pred_proc_id(HLDS, ChildPredId, ChildProcId),
+ io__write_string("\";\n"),
+
+ io__set_output_stream(OldStream, _).
+
:- pred write_prof_item( io__output_stream, pred(profiling_info, int),
profiling_info,
Index: sr_profile_run.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_profile_run.m,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 sr_profile_run.m
--- sr_profile_run.m 2000/10/18 22:38:10 1.1.2.1
+++ sr_profile_run.m 2000/10/23 14:33:48
@@ -36,7 +36,7 @@
{ collect_profiling_information( HLDS, Profiling) },
{ module_info_name( HLDS, ModuleName ) },
{ prog_out__sym_name_to_string( ModuleName, ModuleNameString) },
- sr_profile__write_profiling( ModuleNameString, Profiling ),
+ sr_profile__write_profiling( ModuleNameString, Profiling, HLDS ),
maybe_write_string( Verbose, "done.\n").
:- pred collect_profiling_information( module_info::in,
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list