diff: output module dependency ordering
Simon Taylor
stayl at cs.mu.oz.au
Wed Oct 15 13:58:03 AEST 1997
Hi,
Could someone please review this?
Simon.
Estimated hours taken: 1
Added option --generate-module-ordering which prints out the module
during dependency generation. This is useful for improving the
effectiveness of termination analysis.
compiler/options.m
compiler/handle_options.m
Added option --generate-module-ordering.
compiler/modules.m
Compute and print out the ordering.
doc/user_guide.texi
Document --generate-module-ordering.
Index: handle_options.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/handle_options.m,v
retrieving revision 1.32
diff -u -r1.32 handle_options.m
--- handle_options.m 1997/10/09 09:38:36 1.32
+++ handle_options.m 1997/10/15 00:45:26
@@ -303,6 +303,11 @@
option_implies(make_optimization_interface, optimize_unused_args,
bool(no)),
+ % The information needed for generating the module ordering
+ % is only available while generating the dependencies.
+ option_implies(generate_module_order, generate_dependencies,
+ bool(yes)),
+
% If --use-search-directories-for-intermod is true, append the
% search directories to the list of directories to search for
% .opt files.
Index: modules.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modules.m,v
retrieving revision 1.41
diff -u -r1.41 modules.m
--- modules.m 1997/10/09 09:38:59 1.41
+++ modules.m 1997/10/15 02:27:29
@@ -147,7 +147,7 @@
:- import_module passes_aux, prog_out, mercury_to_mercury.
:- import_module prog_io_util, globals, options, intermod, module_qual.
:- import_module bool, string, set, map, term, varset, dir, std_util, library.
-
+:- import_module assoc_list, relation.
% Read in the .int3 files that the current module depends on,
% and use these to qualify all items in the interface as much as
@@ -610,6 +610,7 @@
% check whether we couldn't read the main `.m' file
%
{ map__lookup(DepsMap, Module, deps(_, Error, _, _, _)) },
+ globals__io_lookup_bool_option(verbose, Verbose),
( { Error = fatal } ->
{ string__append_list(["fatal error reading module `",
Module, "'."], Message) },
@@ -619,22 +620,54 @@
% now, write the `.dep' file
%
{ string__append(Module, ".dep", DepFileName) },
- globals__io_lookup_bool_option(verbose, Verbose),
maybe_write_string(Verbose, "% Creating auto-dependency file `"),
maybe_write_string(Verbose, DepFileName),
maybe_write_string(Verbose, "'...\n"),
- io__open_output(DepFileName, Result),
- ( { Result = ok(DepStream) } ->
+ io__open_output(DepFileName, DepResult),
+ ( { DepResult = ok(DepStream) } ->
generate_dep_file(Module, DepsMap, DepStream),
io__close_output(DepStream),
maybe_write_string(Verbose, "% done\n")
;
{ string__append_list(["can't open file `", DepFileName,
- "' for output."], Message) },
- report_error(Message)
+ "' for output."], DepMessage) },
+ report_error(DepMessage)
+ ),
+ globals__io_lookup_bool_option(generate_module_order, Order),
+ ( { Order = yes } ->
+ { string__append(Module, ".order", OrdFileName) },
+ maybe_write_string(Verbose, "% Creating module order file `"),
+ maybe_write_string(Verbose, OrdFileName),
+ maybe_write_string(Verbose, "'...\n"),
+ io__open_output(OrdFileName, OrdResult),
+ ( { OrdResult = ok(OrdStream) } ->
+ { relation__init(DepsRel0) },
+ { map__to_assoc_list(DepsMap, DepsList) },
+ { deps_map_to_deps_rel(DepsList, DepsMap,
+ DepsRel0, DepsRel) },
+ { relation__atsort(DepsRel, DepsOrdering) },
+ io__write_list(OrdStream, DepsOrdering, "\n\n",
+ write_module_scc(OrdStream)),
+ io__close_output(OrdStream),
+ maybe_write_string(Verbose, "% done\n")
+ ;
+ { string__append_list(["can't open file `",
+ OrdFileName, "' for output."], OrdMessage) },
+ report_error(OrdMessage)
+ )
+ ;
+ []
)
).
+:- pred write_module_scc(io__output_stream::in, set(module_name)::in,
+ io__state::di, io__state::uo) is det.
+
+write_module_scc(Stream, SCC0) -->
+ { set__to_sorted_list(SCC0, SCC) },
+ io__write_list(Stream, SCC, "\n", io__write_string).
+
+
% This is the data structure we use to record the dependencies.
% We keep a map from module name to information about the module.
@@ -648,6 +681,9 @@
list(string) % fact table dependencies
).
+ % deps_rel(Module1, Module2) means Module1 is imported by Module2.
+:- type deps_rel == relation(string).
+
% This is the predicate which creates the above data structure.
:- pred generate_deps_map(list(string), deps_map, deps_map,
@@ -686,6 +722,30 @@
% Recursively process the remaining modules
generate_deps_map(Modules2, DepsMap3, DepsMap).
+
+ % Construct a dependency relation of all the modules in the program.
+:- pred deps_map_to_deps_rel(assoc_list(string, deps), deps_map,
+ deps_rel, deps_rel).
+:- mode deps_map_to_deps_rel(in, in, in, out) is det.
+
+deps_map_to_deps_rel([], _, Rel, Rel).
+deps_map_to_deps_rel([Module - Deps | DepsList], DepsMap, Rel0, Rel) :-
+ Deps = deps(_, ModuleError, IntDeps, ImplDeps, _),
+ ( ModuleError \= fatal ->
+ relation__add_element(Rel0, Module, ModuleRelKey, Rel1),
+ AddDeps =
+ lambda([Dep::in, Relation0::in, Relation::out] is det, (
+ relation__add_element(Relation0, Dep,
+ DepRelKey, Relation1),
+ relation__add(Relation1, DepRelKey,
+ ModuleRelKey, Relation)
+ )),
+ list__foldl(AddDeps, IntDeps, Rel1, Rel2),
+ list__foldl(AddDeps, ImplDeps, Rel2, Rel3)
+ ;
+ Rel3 = Rel0
+ ),
+ deps_map_to_deps_rel(DepsList, DepsMap, Rel3, Rel).
% Write out the `.dep' file, using the information collected in the
% deps_map data structure.
Index: options.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/options.m,v
retrieving revision 1.207
diff -u -r1.207 options.m
--- options.m 1997/10/09 09:39:02 1.207
+++ options.m 1997/10/15 02:20:57
@@ -74,6 +74,7 @@
; make_optimization_interface
; make_transitive_opt_interface
; generate_dependencies
+ ; generate_module_order
; convert_to_mercury
; convert_to_goedel
; typecheck_only
@@ -301,6 +302,7 @@
option_defaults_2(output_option, [
% Output Options (mutually exclusive)
generate_dependencies - bool(no),
+ generate_module_order - bool(no),
make_short_interface - bool(no),
make_interface - bool(no),
make_optimization_interface - bool(no),
@@ -578,6 +580,7 @@
% output options (mutually exclusive)
long_option("generate-dependencies", generate_dependencies).
+long_option("generate-module-order", generate_module_order).
long_option("make-short-interface", make_short_interface).
long_option("make-short-int", make_short_interface).
long_option("make-interface", make_interface).
@@ -1144,6 +1147,11 @@
io__write_string("\t-M, --generate-dependencies\n"),
io__write_string("\t\tOutput `Make'-style dependencies for the module\n"),
io__write_string("\t\tand all of its dependencies to `<module>.dep'.\n"),
+ io__write_string("\t--generate-module-order\n"),
+ io__write_string("\t\tOutput the strongly connected components of the module\n"),
+ io__write_string("\t\tdependency graph in top-down order to `<module>.order'.\n"),
+ io__write_string("\t\tImplies --generate-dependencies.\n"),
+
io__write_string("\t-i, --make-int, --make-interface\n"),
io__write_string("\t\tWrite the module interface to `<module>.int',\n"),
io__write_string("\t\tand write the short interface to `<module>.int2'\n"),
Index: user_guide.texi
===================================================================
RCS file: /home/staff/zs/imp/mercury/doc/user_guide.texi,v
retrieving revision 1.100
diff -u -r1.100 user_guide.texi
--- user_guide.texi 1997/10/09 09:39:41 1.100
+++ user_guide.texi 1997/10/15 02:20:11
@@ -1292,6 +1292,11 @@
Output ``Make''-style dependencies for the module
and all of its dependencies to @file{@var{module}.dep}.
+ at item --generate-module-order
+Output the strongly connected components of the module
+dependency graph in top-down order to @file{@var{module}.order}.
+Implies --generate-dependencies.
+
@sp 1
@item -i
@itemx --make-int
More information about the developers
mailing list