The imports_012 operation computes the union of three subsets.
Since it is called frequently for the same modules, it can be worth
reusing a previously computed result.
This change improves the run time of a do-nothing build of Prince using
mmc --make on my machine from 1.20 s to 0.86 s.
compiler/make.dependencies.m:
Add code to support caching of dependency sets computed from other
dependency sets.
Enabling caching in imports_012.
compiler/make.make_info.m
compiler/make.top_level.m
Add a field to make_info to hold the cache results.
This change improves the run time of a do-nothing build of Prince using
mmc --make on my machine from 1.46 s to 1.19 s.
compiler/make.make_info.m:
Use version_hash_table for the target_file timestamps cache
instead of a tree234 map.
compiler/make.util.m:
Add function to initialised a target_file_timestamps.
Conform to change in type.
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.top_level.m:
Conform to change in type.
Add a comment about a possible change.
NEWS:
Mention all the user-visible changes below.
library/enum.m:
Add the typeclass uenum, which is a version of the existing enum typeclass
that maps items to uints, not ints. It also uses a semidet predicate,
not a semidet function, to get back to the item from the uint.
library/sparse_bitset.m:
library/fat_sparse_bitset.m:
Make these modules operate on uints, which means requiring the items
in the sets to be instances of uenum, not enum.
If a few places, improve loops by doing previously-repeated conversions
of [u]ints into <offset, bit-to-set> pairs just once.
library/counter.m:
Define ucounters, which allocate uints. Improve documentation.
library/digraph.m:
Change digraph_keys from ints to uints, since we put them into
sparse_bitsets.
library/int.m:
Make int an instance of the uenum typeclass. This can help users
who currently put ints into sparse_bitsets.
library/pprint.m:
Prettyprint sparse_bitsets as lists of uints.
library/term.m:
Make vars instances of uenum as well as enum.
library/uint.m:
Make uint an instance of the uenum typeclass.
Add the ubits_per_uint function, which allows some casts to be avoided.
compiler/make.deps_set.m:
Change the indexes we put into sparse_bitsets from ints to uints.
compiler/make.make_info.m:
Change the source of those indexes from ints to uints.
compiler/make.top_level.m:
compiler/make.util.m:
Conform to the changes above.
compiler/pre_quantification.m:
Change zones from ints to uints, since we put them into sparse_bitsets.
tests/hard_coded/int_uenum.{m,exp}:
tests/hard_coded/Mmakefile:
Enable the new test case.
tests/valid/use_import_only_for_instance.m:
Update this extract from library/digraph.m the same way as
library/digraph.m itself.
compiler/make.build.m:
Replace three polymorphic predicates that fold over lists of values
of type T with two, three and five monomorphic predicates respectively.
The monomorphic versions fold over lists of elements of specified types.
The list of monomorphic versions needed should be useful information for
simplifying the make package's overuse of higher order constructs.
The replaced predicates were mostly just interfaces to the predicates
that looped over the lists. This diff leaves those predicates alone.
compiler/make.dependencies.m:
Make the same change to deps_set_foldl3_maybe_stop_at_error and to
map_find_module_deps (only the first of which does a fold).
For map_find_module_deps, also change the argument order, because
operating on the second argument first, and on the first argument second,
is confusing.
compiler/make.make_info.m:
Replace a pair type, which some of the above fold operated over,
with a bespoke type, because its structure and semantics was related
to existing bespoke types.
compiler/make.program_target.m:
Conform to the changes above. In two cases, replaces nested folds
with sequences of folds, both because this is simpler, and because
it avoids the need for an extra variant of the fold.
compiler/make.module_target.m:
compiler/make.top_level.m:
compiler/make.track_flags.m:
compiler/make.util.m:
Conform to the changes above.
Previously, to look up the timestamp for a target_file we would first
compute a file name for that target_file, then look up the timestamp by
file name. This occurs frequently, so even though the computed file name
was cached, eliminating one of the two steps can be worthwhile.
This change therefore introduces a cache of timestamps indexed by
target_file, in addition to the existing cache of timestamps indexed
by file name.
Cache invalidation can be complicated because when a file is updated,
it is not straightforward to which target_file(s) may be affected.
Invalidating the entire cache is viable as it happens relatively
infrequently, and the cache will be quickly repopulated anyway.
This change improves the run time of a do-nothing build of Prince
on my machine from 1.7 s to 1.6 s.
compiler/make.make_info.m:
compiler/make.top_level.m:
Add a field to make_info to hold a cache of timestamps indexed by
target_file.
Delete the mki_search_file_name_cache field.
compiler/make.util.m:
Cache timestamps by target_file in get_target_timestamp.
Avoid computing file names until required.
Don't cache computed file names in get_file_name.
get_file_name is now called much less frequently, so caching the
result should not be necessary (but can be reintroduced if some
other code path requires it).
Clear out timestamps for target_files when a file is deleted.
compiler/make.module_target.m:
Delete old timestamp for a target_file when the target is made.
compiler/make.program_target.m:
Clear out timestamps for target_files when Java class files are
made.
In make_info we maintain a mapping between dependency_file and
dependency_file_index. Replace the type dependency_file used in those
maps with a new type, in which modules are referred to by module_index
instead of by module_name.
The reason for the change is that make.dependencies.of_3 is called
frequently to convert a module_index and module_target_type to a
dependency_file_index. With this change, it does not need to look up
the module_name corresponding to a module_index, but uses the
module_index as given. Also, using module_index instead of module_name
as part of a hash table key should be faster as (1) hashing is faster,
and (2) comparing keys within the same hash table bucket is faster.
This change improves the run time of a do-nothing build of Prince
on my machine from 1.8 s to 1.7 s.
compiler/make.dependencies.m:
Add the new type.
Don't need to call module_index_to_name in of_3.
Describe the `of' function.
compiler/make.make_info.m:
Replace dependency_file in the dependency file <-> index maps
with the new type.
compiler/make.util.m:
Add hash predicate for new type.
compiler/make.deps_set.m:
compiler/make.top_level.m:
Conform to changes.
This change reduces the average run time for a do-nothing build of
Prince on my machine from 3.1 s to 1.95 s, for a speedup of ~37%.
compiler/make.make_info.m:
Add a field to make_info to hold the result of indirect_imports.
compiler/make.dependencies.m:
Cache the result of indirect_imports in make_info.
We previously cached the foreign imports of a module.
find_module_foreign_imports always needs to compute the transitive
foreign imports (i.e. including the foreign imports of transitively
implementation-imported modules), so it had to take the union of a bunch
of sets after looking up cached results.
This change caches the transitive foreign imports of a module, avoiding
the bitset union operations, many/most of which turn out to be redundant.
It reduces the average run time for a do-nothing build of Prince on my
machine from 5.9 s to 3.1 s, for a speed up of ~47%.
compiler/make.dependencies.m:
Cache transitive foreign module imports instead of direct foreign
module imports.
Delete code to make use of va_map; it is no longer used.
(The va_map module may still be convenient to use in places where we
currently use version_array, so keep it around.)
compiler/make.deps_set.m:
Delete code to make use of va_map.
compiler/make.make_info.m:
Rename field.
compiler/make.top_level.m:
Conform to change.
compiler/make.module_dep_file.m:
When generating an error message about being unable to compute
dependencies due to being unable to open the file supposedly containing
a module, say whether that module was included or imported, instead of
just saying "module abc is imported or included by module def".
To make this possible, ...
compiler/make.make_info.m:
... change the slot in the make_info that holds the name of the
importing or including module ("def" in the above example) to say
whether it is importing or including the module in question ("abc"
in the example), and ...
compiler/make.dependencies.m:
... have this module fill in that slot.
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.
compiler/make.top_level.m:
compiler/make.track_flags.m:
compiler/make.make_info.m:
Carve these three modules out of make.m.
make.top_level.m contains the top level of the mmc --make algorithm.
make.track_flags.m contains code for keeping track of which options
were used to compile which modules.
make.make_info.m defines the make_info structure used by all the
submodules of make.m, as well as a few other utility types.
compiler/notes/compiler_design.html:
Document the new modules.
compiler/make.m:
Delete the code that has been moved to the new modules, leaving
make.m as purely a package.
Include make.build.m in the interface, so we can delete the forwarding
predicate we used to have here for use by mercury_compile_main.m.
compiler/Mercury.options:
Make make.top_level.m and make.track_flags inherit make.m's old
-no-warn-implicit-stream-calls option.
compiler/file_names.m:
Move a utility function about extensions here from make.m.
This also allows the removal of an undesirable module import of make.m
in write_deps_file.m.
compiler/make.build.m:
Move a type here from make.m, since it is needed to allow
mercury_compile_main.m call this module directly (i.e. not through
a forwarding predicate in make.m).
compiler/make.dependencies.m:
compiler/make.deps_set.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/options_file.m:
compiler/write_deps_file.m:
Conform to the changes above. This mostly means having each module make.X
actually import the modules it uses, instead of relying on make.m
importing them, and getting those imports via make.int0.
In a few cases, it means having each module make.X NOT import the modules
it does NOT use, since after the "package-ification" of make.m,
we now get warnings about these imports being unused.