diff: modules.m bug fix
Fergus Henderson
fjh at cs.mu.OZ.AU
Wed May 27 00:06:35 AEST 1998
compiler/modules.m:
Fix a bug where --generate-dependencies was writing out
an overly conservative set of dependencies.
Index: modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.71
diff -u -u -r1.71 modules.m
--- modules.m 1998/05/25 21:48:52 1.71
+++ modules.m 1998/05/26 14:03:44
@@ -1543,25 +1543,47 @@
ModuleString, "'."], Message) },
report_error(Message)
;
- globals__io_lookup_accumulating_option(intermod_directories,
- IntermodDirs),
generate_dependencies_write_dep_file(Module, DepsMap),
+
+ %
+ % compute the interface deps relation and
+ % the implementation deps relation from the deps map
+ %
{ relation__init(IntDepsRel0) },
{ relation__init(ImplDepsRel0) },
{ map__values(DepsMap, DepsList) },
{ deps_list_to_deps_rel(DepsList, DepsMap,
- IntDepsRel0, _IntDepsRel, ImplDepsRel0, ImplDepsRel) },
+ IntDepsRel0, IntDepsRel, ImplDepsRel0, ImplDepsRel) },
+
+ %
+ % compute the trans-opt deps ordering, by doing an
+ % approximate topological sort of the implementation deps,
+ % and then finding the subset of those for which of those
+ % we have (or can make) trans-opt files.
+ %
{ relation__atsort(ImplDepsRel, ImplDepsOrdering0) },
maybe_output_module_order(Module, ImplDepsOrdering0),
{ list__map(set__to_sorted_list, ImplDepsOrdering0,
ImplDepsOrdering) },
{ list__condense(ImplDepsOrdering, TransOptDepsOrdering0) },
+ globals__io_lookup_accumulating_option(intermod_directories,
+ IntermodDirs),
get_opt_deps(TransOptDepsOrdering0, IntermodDirs, ".trans_opt",
TransOptDepsOrdering),
- % XXX using ImplDepsOrdering here is wrong.
- % IntDeps is to little, ImplDeps is too much.
- % (Better too much than too little, though.)
- generate_dependencies_write_d_files(ImplDepsOrdering,
+
+ %
+ % compute the indirect dependencies: they are equal to the
+ % composition of the implementation dependencies
+ % with the transitive closure of the interface dependencies.
+ %
+ { relation__to_assoc_list(IntDepsRel, IntDepsAL) },
+ { relation__tc(IntDepsRel, TransIntDepsRel) },
+ { relation__to_assoc_list(TransIntDepsRel, TransIntDepsAL) },
+ { relation__compose(ImplDepsRel, TransIntDepsRel,
+ IndirectDepsRel) },
+ { relation__to_assoc_list(IndirectDepsRel, IndirectDepsAL) },
+
+ generate_dependencies_write_d_files(DepsList, IndirectDepsRel,
TransOptDepsOrdering, DepsMap)
).
@@ -1596,41 +1618,46 @@
{ set__to_sorted_list(SCC0, SCC) },
io__write_list(Stream, SCC, "\n", prog_out__write_sym_name).
-% generate_dependencies_write_d_files(Sccs, TransOptOrder, DepsMap, IO0, IO).
+
+% generate_dependencies_write_d_files(Modules, IntDepsRel, TransOptOrder,
+% DepsMap, IO0, IO):
% This predicate writes out the .d files for all the modules
-% in the Sccs list.
-% Sccs is a list of lists of modules. Each list of
-% modules represents a set of strongly connected components
-% of the module call graph.
+% in the Modules list.
+% IntDepsRel gives the interface dependency relation
+% (computed from the DepsMap).
% TransOptOrder gives the ordering that is used to determine
% which other modules the .trans_opt files may depend on.
-:- pred generate_dependencies_write_d_files(list(list(module_name))::in,
- list(module_name)::in, deps_map::in,
+:- pred generate_dependencies_write_d_files(list(deps)::in,
+ relation(module_name)::in, list(module_name)::in, deps_map::in,
io__state::di, io__state::uo) is det.
-generate_dependencies_write_d_files([], _, _) --> [].
-generate_dependencies_write_d_files([Scc | Sccs], TransOptOrder, DepsMap) -->
- { list__condense([Scc | Sccs], TransDeps) },
- generate_dependencies_write_d_files_2(Scc, TransDeps, TransOptOrder,
- DepsMap),
- generate_dependencies_write_d_files(Sccs, TransOptOrder, DepsMap).
+generate_dependencies_write_d_files([], _, _TransOptOrder, _DepsMap) --> [].
+generate_dependencies_write_d_files([Dep | Deps],
+ IndirectDepsRel0, TransOptOrder, DepsMap) -->
+ { Dep = deps(_, Module0) },
+
+ %
+ % Look up the indirect dependencies for this module
+ % from the indirect dependencies relation, and save
+ % them in the module_imports structure.
+ %
+ { module_imports_get_module_name(Module0, ModuleName) },
+ { relation__add_element(IndirectDepsRel0, ModuleName, ModuleKey,
+ IndirectDepsRel) },
+ { relation__lookup_from(IndirectDepsRel, ModuleKey,
+ IndirectDepsKeysSet) },
+ { set__to_sorted_list(IndirectDepsKeysSet, IndirectDepsKeys) },
+ { list__map(relation__lookup_key(IndirectDepsRel), IndirectDepsKeys,
+ IndirectDeps) },
+ { module_imports_set_indirect_deps(Module0, IndirectDeps, Module) },
-:- pred generate_dependencies_write_d_files_2(list(module_name)::in,
- list(module_name)::in, list(module_name)::in, deps_map::in,
- io__state::di, io__state::uo) is det.
-generate_dependencies_write_d_files_2([], _, _TransOptOrder, _DepsMap) --> [].
-generate_dependencies_write_d_files_2([ModuleName | ModuleNames],
- TransIntDeps, TransOptOrder, DepsMap) -->
- { map__lookup(DepsMap, ModuleName, deps(_, ModuleImports0)) },
- { module_imports_get_error(ModuleImports0, Error) },
-
%
% Compute the trans-opt dependencies for this module.
% To avoid the possibility of cycles, each module is
% only allowed to depend on modules that occur later
% than it in the TransOptOrder.
%
- { FindModule = lambda([Module::in] is semidet, (
- ModuleName \= Module )) },
+ { FindModule = lambda([OtherModule::in] is semidet, (
+ ModuleName \= OtherModule )) },
{ list__takewhile(FindModule, TransOptOrder, _, TransOptDeps0) },
( { TransOptDeps0 = [ _ | TransOptDeps1 ] } ->
% The module was found in the list
@@ -1643,15 +1670,13 @@
% Note that even if a fatal error occured for one of the files that
% the current Module depends on, a .d file is still produced, even
% though it probably contains incorrect information.
+ { module_imports_get_error(Module, Error) },
( { Error \= fatal } ->
- % Set the transitive interface dependencies for this module
- { module_imports_set_indirect_deps(ModuleImports0, TransIntDeps,
- ModuleImports) },
- write_dependency_file(ModuleImports, yes(TransOptDeps))
+ write_dependency_file(Module, yes(TransOptDeps))
;
[]
),
- generate_dependencies_write_d_files_2(ModuleNames, TransIntDeps,
+ generate_dependencies_write_d_files(Deps, IndirectDepsRel,
TransOptOrder, DepsMap).
% This is the data structure we use to record the dependencies.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list