mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
083d376e6598628362ee91c2da170febd83590f4
13 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c8725fb4bc |
Carve module_dep_info.m out of module_imports.m.
compiler/module_dep_info.m:
As above. The only change is added documentation.
compiler/parse_tree.m:
Include the new module in the parse_tree package.
compiler/notes/compiler_design.html:
Document the new module, and update the documentation of module_imports.m.
compiler/module_imports.m:
Delete the moved code, put the main data structure at the top,
and add some documentation for it.
compiler/compile_target_code.m:
compiler/generate_dep_d_files.m:
compiler/make.dependencies.m:
compiler/make.make_info.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/module_deps_graph.m:
Import module_dep_info.m, usually instead of module_imports.m,
sometimes beside module_imports.m.
|
||
|
|
114cfb482e |
Create and use module_dep_summary.
compiler/module_imports.m:
Until now, we stored the information we read in from .dep files
in module_and_imports structures in which most of the fields
were left filled-in with default values, which could be correct
only by accident.
This diff switches to storing information from .dep files in
a values of a type, module_dep_summary, that is made for this purpose.
With this type, it is obvious that the only fields that are ever
accessed are fields that have been properly filled in.
Delete the old predicate that constructed the half-filled-in
module_and_imports structure, since it is not needed anymore.
Also, delete the mcm_read construction method, since the deleted
predicate was its only user.
Since mmc --make operates both on values of this type *and* on
values of the old module_and_imports type, introduce a new type,
module_dep_info, which stores either one or the other,
and add the needed access predicates on this type.
Give a field of module_and_imports a more descriptive name.
compiler/make.m:
Switch to recording module_dep_infos for modules, instead of
just module_and_imports.
Replace some uses of maybes and pairs with bespoke types.
compiler/make.module_dep_file.m:
Store the result of reading a .dep file in a module_dep_summary,
not in a partially-filled-in module_and_imports.
compiler/module_deps_graph.m:
Store module_dep_infos in the deps_graph instead of module_and_imports
structures.
Delete a named mode, since mode "in" now works for functions
with the default mode.
compiler/make.dependencies.m:
Delete the maybe(option) field from dep_file, since it was *always*
set to "no".
Conform to the changes above.
compiler/make.util.m:
Add a new utility predicate, for use in make.dependencies.m.
Conform to the changes above.
compiler/generate_dep_d_files.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
Conform to the changes above.
compiler/compile_target_code.m:
Expect a module_dep_info instead of a module_and_imports,
since that is what our callers have.
Add an XXX for a surprising piece of code.
|
||
|
|
97fcb29811 |
Don't record anccestors in module_and_imports.
compiler/module_imports.m:
As above; delete the ancestors field, since users can compute its value
by calling get_ancestors_set on the module name.
On some initialization paths, the ancestors field used to be filled
with a dummy empty set, so this change should improve robustness.
compiler/deps_map.m:
compiler/grab_modules.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/module_deps_graph.m:
compiler/write_deps_file.m:
Conform to the changes in module_imports.m.
|
||
|
|
0d667a7c94 |
Add some access predicates for module_and_imports structures.
compiler/module_imports.m:
As above.
compiler/modules.m:
Use the new access predicates if relevant. Add a sanity check.
compiler/compile_target_code.m:
compiler/deps_map.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/mercury_compile_main.m:
compiler/module_deps_graph.m:
compiler/write_deps_file.m:
Use the new access predicates if relevant.
|
||
|
|
e6870d29f9 |
Make module_and_imports an abstract type.
compiler/module_imports.m:
Make the definition of module_and_imports private, to make future changes
to its structure easier.
Add the construction, deconstruction, getter and setter predicates
on the type that are now needed by the other compiler modules.
Put the related fields of module_and_imports next to each other.
Give some of the fields more descriptive names.
compiler/compile_target_code.m:
compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/mercury_compile_main.m:
compiler/module_deps_graph.m:
compiler/modules.m:
compiler/write_deps_file.m:
Conform to the changes above.
|
||
|
|
d967f36545 |
Improve error messages about unexpected module names, again.
When you get this message, the error may be in the module name that it
reports to be wrong, but it may be in the places that set the compiler's
expectations of what the name of the module should be. This latter is
very likely the case when one moves a module of the Mercury compiler
from one package to another. In such cases, the problems are the old modules
that continue to refer to the renamed module by its old name.
This diff improves the error message by indicating *precisely* the locations
that refer to the old name, since these are the locations that establish the
expectation that is not met.
compiler/module_imports.m:
Change the module_and_imports structure to record, for each imported
or used module, and for each child module, the location of the relevant
":- import_module" or ":- include_module" declaration(s).
compiler/deps_map.m:
When tracing references from module A to module B.C (either because
A imports B.C, or because A = B and A includes C), record the location
of the ":- import_module" or ":- include_module" declaration as a source
of the expectation that any file that contains module C will have
B.C as module C's fully qualified name. Since a module is usually imported
by more than one other module, there may be several sources of such
expectations.
compiler/parse_module.m:
Change the wording of the error message to reflect the change in what
the context denotes.
compiler/get_dependencies.m:
compiler/prog_item.m:
When returning the sets of modules imported, used or included by some
entities such as item blocks, return the contexts of those
imports/uses/includes as well.
compiler/compile_target_code.m:
compiler/hlds_module.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/mercury_compile_main.m:
compiler/module_deps_graph.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/write_deps_file.m:
Conform to the changes above.
tests/invalid/bad_module_name.err_exp:
Expect the updated error message.
|
||
|
|
cc9912faa8 |
Don't import anything in packages.
Packages are modules whose only job is to serve as a container for submodules. Modules like top_level.m, hlds.m, parse_tree.m and ll_backend.m are packages in this (informal) sense. Besides the include_module declarations for their submodules, most of the packages in the compiler used to import some modules, mostly other packages whose component modules their submodules may need. For example, ll_backend.m used to import parse_tree.m. This meant that modules in the ll_backend package did not have to import parse_tree.m before importing modules in the parse_tree package. However, this had a price. When we add a new module to the parse_tree package, parse_tree.int would change, and this would require the recompilation of ALL the modules in the ll_backend package, even the ones that did NOT import ANY of the modules in the parse_tree package. This happened even at one remove. Pretty much all modules in every one of the backend have to import one or more modules in the hlds package, and they therefore have import hlds.m. Since hlds.m imported transform_hlds.m, any addition of a new middle pass to the transform_hlds package required the recompilation of all backend modules, even in the usual case of the two having nothing to do with each other. This diff removes all import_module declarations from the packages, and replaces them with import_module declarations in the modules that need them. This includes only a SUBSET of their child modules and of the non-child modules that import them. |
||
|
|
62ec97d443 |
Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.
compiler/hlds_module.m:
We used to record the set of imported/used modules, and the set of
modules imported/used in the interface of the current module. However,
these sets
- did not record the distinction between imports and uses;
- did not allow distinction between single and multiple imports/uses;
- did not record the locations of the imports/uses.
The first distinction was needed only by module_qual.m, which *did*
pay attention to it; the other two were not needed at all.
To generate messages for imports/uses shadowing other imports/uses,
we need all three, so change the data structure storing such information
for *direct* imports to one that records all three of the above kinds
of information. (For imports made by read-in interface and optimization
files, the old set of modules approach is fine, and this diff leaves
the set of thus *indirectly* imported module names alone.)
compiler/unused_imports.m:
Use the extra information now available to generate a
severity_informational message about any import or use that is made
redundant by an earlier, more general import or use.
Fix two bugs in the code that generated warnings for just plain unused
modules.
(1) It did not consider that a use of the builtin type char justified
an import of char.m, but without that import, the type is not visible.
(2) It scanned cons_ids in goals in procedure bodies, but did not scan
cons_ids that have been put into the const_struct_db. (I did not update
the code here when I added the const_struct_db.)
Also, add a (hopefully temporary) workaround for a bug in
make_hlds_passes.m, which is noted below.
However, there are at least three problems that prevent us from enabling
--warn-unused-imports by default.
(1) In some places, the import of a module is used only by clauses for
a predicate that also has foreign procs. When compiled in a grade that
selects one of those foreign_procs as the implementation of the predicate,
the clauses are discarded *without* being added to the HLDS at all.
This leads unused_imports.m to generate an uncalled-for warning in such
cases. To fix this, we would need to preserve the Mercury clauses for
*all* predicates, even those with foreign procs, and do all the semantic
checks on them before throwing them away. (I tried to do this once, and
failed, but the task should be easier after the item list change.)
(2) We have two pieces of code to generate import warnings. The one in
unused_imports.m operates on the HLDS after type and mode checking,
while module_qual.m operates on the parse tree before the creation of
the HLDS. The former is more powerful, since it knows e.g. what types and
modes are used in the bodies of predicates, and hence can generate warnings
about an import being unused *anywhere* in a module, as opposed to just
unused in its interface.
If --warn-unused-imports is enabled, we will get two separate set of
reports about an interface import being unused in the interface,
*unless* we get a type or mode error, in which case unused_imports.m
won't be invoked. But in case we do get such errors, we don't want to
throw away the warnings from module_qual.m. We could store them and
throw them away only after we know we won't need them, or just get
the two modules to generate identical error_specs for each warning,
so that the sort_and_remove_dups of the error specs will do the
throwing away for us for free, if we get that far.
(3) The valid/bug100.m test case was added as a regression test for a bug
that was fixed in module_qual.m. However the bug is still present in
unused_imports.m.
compiler/make_hlds_passes.m:
Give hlds_module.m the extra information it now needs for each item_avail.
Add an XXX for a bug that cannot be fixed right now: the setting of
the status of abstract instances to abstract_imported. (The "abstract"
part is correct; the "imported" part may not be.)
compiler/intermod.m:
compiler/try_expand.m:
compiler/xml_documentation.m:
Conform to the change in hlds_module.m.
compiler/module_qual.m:
Update the documentation of the relationship of this module
with unused_imports.m.
compiler/hlds_data.m:
Document a problem with the status of instance definitions.
compiler/hlds_out_module.m:
Update the code that prints out the module_info to conform to the change
to hlds_module.m.
Print status information about instances, which was needed to diagnose
one of the bugs in unused_imports.m. Format the output for instances
nicer.
compiler/prog_item.m:
Add a convenience predicate.
compiler/prog_data.m:
Remove a type synonym that makes things harder to understand, not easier.
compiler/modules.m:
Delete an XXX that asks for the feature this diff implements.
Add another XXX about how that feature could be improved.
compiler/Mercury.options.m:
Add some more modules to the list of modules on which the compiler
should be invoked with --no-warn-unused-imports.
compiler/*.m:
library/*.m:
mdbcomp/*.m:
browser/*.m:
deep_profiler/*.m:
mfilterjavac/*.m:
Delete unneeded imports. Many of these shadow other imports, and some
are just plain unneeded, as shown by --warn-unused-imports. In a few
modules, there were a *lot* of unneeded imports, but most had just
one or two.
In a few cases, removing an import from a module, because it *itself*
does not need it, required adding that same import to those of its
submodules which *do* need it.
In a few cases, conform to other changes above.
tests/invalid/Mercury.options:
Test the generation of messages about import shadowing on the existing
import_in_parent.m test case (although it was also tested very thoroughly
when giving me the information needed for the deletion of all the
unneeded imports above).
tests/*/*.{m,*exp}:
Delete unneeded imports, and update any expected error messages
to expect the now-smaller line numbers.
|
||
|
|
ef44f50bee |
Eliminate the old module_defn item.
After my earlier changes to the item list, we used module_defns for only
two things: recording when one module includes another, and recording
when one module imports or uses another. After this diff, both those
pieces of information are stored separately in each item block.
This has two benefits.
The first benefit is that it allows us to use the type system to enforce
structural invariants about where include_module, import_module and use_module
declarations may appear. The one invariant that we now enforce is that
optimization files may not contain either include_module or import_module
declarations, though they may contain use_module declarations. I suspect that
there are also similar invariants about interface files, but finding them
requires something like this change.
The second benefit is that it allows traversals of item blocks to scan
only the part of the item block that may contain the object of interest.
While reading in interface and optimization files, we used to scan the
full item list several times to find included and imported modules; those
scans can now look at just the relevant information. Since the item lists
that need to be processed usually include all the declarations in a
substantial number of other modules, including some (such as list.m) that
have LOTS of declarations, the speedup can be substantial. On tools/speedtest,
the speedup is 1.5%.
compiler/prog_item.m:
Make the change described above.
Provide utility predicates on the new types representing include_module,
import_module and use_module declarations.
Move an old utility predicate from here to prog_io.m, since only prog_io.m
uses it.
compiler/module_imports.m:
Several fields of the module_imports type contained sets of module names,
but stored them as lists. Change these to actual sets, to distinguish them
from the lists whose order is actually important. (Basically, the order
of processing .trans_opt files is important, but the order in which
we read in .int0, .int3, .int2, .int and .opt files isn't.) In several
places, this also avoids the need for conversions of lists to sets
for set operations, and then back to lists.
compiler/modules.m:
This module had several predicates that processed list of module names.
Make these operate on sets of module names instead, and break each of them
into two predicates: one that decides whether there is a next module name,
and if yes whether it has been processed already, and one to do the actual
processing if needed. This avoid the need for excessive indentation.
The code that discovers what other modules' interface files may need
to be read is now simpler due to the updated item_block structure.
Remove the submodule whose job it was to discover what modules are included
in items or item blocks, since that task has now become trivial, and is
now done by a utility predicate in prog_item.m. Since this was the second
last submodule (of the original eight), the last submodule is now the
whole module. Therefore this module now has significantly greater cohesion
than it had before.
compiler/write_module_interface_files.m:
compiler/prog_io_item.m:
Parse include_module, import_module and use_module declarations as
markers, not as items.
compiler/prog_io.m:
Expect include_module, import_module and use_module declarations as
markers, not as items.
compiler/split_parse_tree_src.m:
Discover included submodules more simply with the updated item_block
structure.
compiler/compile_target_code.m:
Put the arguments of the predicates in this module in a more standard
order.
compiler/recompilation.version.m:
Conform to the above changes. Note a possible bug.
Use a bespoke type to replace some bools.
compiler/check_raw_comp_unit.m:
compiler/comp_unit_interface.m:
compiler/deps_map.m:
compiler/equiv_type.m:
compiler/generate_dep_d_files.m:
compiler/get_dependencies.m:
compiler/hlds_module.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make_hlds_passes.m:
compiler/mercury_compile.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_to_mercury.m:
compiler/module_deps_graph.m:
compiler/module_qual.m:
compiler/prog_io_find.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/trans_opt.m:
compiler/write_deps_file.m:
Conform to the above changes.
mdbcomp/sym_name.m:
Provide a utility predicate to get the set of ancestors of a module
as a set as well as a list.
tests/invalid/exported_unify3.err_exp:
tests/invalid/ii_parent.ii_child.err_exp:
Update the expected error messages, which refer to line numbers in
.int0 files, which have now changed, as we now put all import_module
declarations before ordinary items.
(Error messages shouldn't refer to automatically generated files,
but that is a separate concern.)
|
||
|
|
f91bad4579 |
Carve generate_dep_d_file.m out of modules.m.
The predicates in modules.m that generate .dep and .d files are independent
of the rest of that module, so moving them out into a new module improves
both modules' cohesion.
compiler/generate_dep_d_file.m:
New module containing the code moved out of modules.m, as well as
some code moved here from module_deps_graph.m, since it was called
only from here.
Give some predicates more descrriptive names.
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Mention the new module.
compiler/modules.m:
Remove the stuff moved to generate_dep_d_file.m.
compiler/make.program_target.m:
Move here a predicate from module_deps_graph.m, since it was only called
from here.
compiler/write_deps_file.m:
Move here a predicate from module_deps_graph.m, since it was only called
from here.
compiler/module_deps_graph.m:
Remove the stuff moved to generate_dep_d_file.m, make.program_target.m
or write_deps_file.m. What is left does only one job, and it is needed
by both generate_dep_d_file.m and make.program_target.m.
compiler/mercury_compile.m:
Conform to the changes above.
|
||
|
|
fe785c668b |
Consistently use set.is_empty and set.is_non_empty.
compiler/*.m:
deep_profiler/*.m:
As above.
library/set.m:
library/set_bbbtree.m:
library/set_ctree234.m:
library/set_ordlist.m:
library/set_tree234.m:
library/set_unordlist.m:
Add is_non_empty to the set modules that did not already have it.
(Some did, some didn't.)
Make the documentation of empty, is_empty, non_empty and is_non_empty
consistent.
|
||
|
|
38dc676f18 |
Record each kind of error when reading in files.
compiler/prog_io_error.m:
Replace the enum that used to record only whether we found no errors,
some nonfatal errors or some fatal errors, with a type that records
just what kinds of errors we found. Document each kind of error.
compiler/prog_io.m:
Record any errors using the new type. In some cases, we used to
forget fatal errors after finding nonfatal ones; now we don't.
compiler/read_modules.m:
Do not generate error messages about not being able to open a file
if we *could* open the file, but found other fatal errors inside it.
Factor out some common code.
compiler/intermod.m:
Ignore the error of not being able to open .opt files, but do not
ignore any other errors inside them. This fixes a long-standing piece
of strange-looking code.
compiler/module_imports.m:
Do not ignore old fatal errors if reading a new interface file
gets some new nonfatal errors. This fixes a long-standing XXX.
compiler/write_module_interface_files.m:
Do not ignore fatal errors when considering whether to write out interface
files. This fixes a long-standing XXX.
compiler/modules.m:
Generate better error messages for fatal errors inside modules
other than not being able to open the module.
compiler/deps_map.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile.m:
compiler/module_deps_graph.m:
compiler/recompilation.check.m:
compiler/trans_opt.m:
compiler/write_deps_file.m:
Conform to the change in prog_io_error.m.
|
||
|
|
10732f58da |
Improve the cohesion of modules.m.
Once upon a time, modules.m contained all the code in the compiler that dealt
with interface files, and it was by far the biggest module in the compiler
(almost 9000 lines). Once before, I moved cohesive bunches of functionality
out of modules.m into new modules, such as file_util.m and module_cmds.m.
This diff does likewise, creating three new modules.
Besides that main task, it has two minor algorithmic changes that should
have no overall effect on correctness. First, it merges some traversals of
the item list, which should yield a very minor speedup, and second,
in order to avoid the need for an undesirable module import, it eliminates
an unnecessary sorting of the item list that we used to do when reading
in interface files. (The sorting makes sense only when *creating* interface
files).
This diff also gives more meaningful names to some predicates.
compiler/module_deps_graph.m:
This new module defines the module dependency graph, and provides
predicates for building it and using it.
compiler/write_module_iterface_files.m:
This new module does what its name says it does.
compiler/item_util.m:
This new module contains utility predicates that deal with items that are
now needed in more than one module.
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Include the new modules.
compiler/write_deps_file.m:
Move some predicates here from modules.m, since they belong here.
E.g. one prints .d files, and related code to print .dv and .dep files
was already here.
compiler/mercury_compile.m:
Move a predicate here from modules.m, since it was only called from here,
and related code is also here.
compiler/prog_item.m:
Move a predicate here from modules.m, since it is a utility predicate
for a type that is defined here.
compiler/prog_type.m:
Move a predicate here from modules.m, since it is a utility predicate
for types, like all the other predicates in this module.
compiler/modules.m:
Remove the code that is now in other modules. Impose some structure
on the remaining code. (It used to be too jumbled up to make much sense of,
which was one reason why working with this code was unnecessarily hard).
compiler/deps_map.m:
Note the relationship to the new module module_deps_graph.m.
compiler/*.m:
Import the new modules as well as (or instead of) modules.m, and/or conform
to new names for predicates.
|