mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
083d376e6598628362ee91c2da170febd83590f4
44 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b6178ef723 |
Delete prog_out.m, moving its code to other modules.
compiler/parse_tree_out_cons_id.m:
Move the predicates and functions in prog_out.m that deal with cons_ids
to this module.
compiler/parse_tree_out_sym_name.m:
Move the predicates and functions in prog_out.m that deal with sym_names
and similar entities to this module.
compiler/parse_tree_out_type.m:
Move the predicates and functions in prog_out.m that deal with types
to this module.
compiler/parse_tree_out_misc.m:
Move the predicates and functions in prog_out.m that deal with simple
types to this module.
Delete mercury_output_det and mercury_format_det, replacing all their
uses with calls to mercury_det_to_string.
compiler/prog_out.m:
Delete this module.
compiler/parse_tree.m:
Delete prog_out from the parse_tree package.
compiler/Mercury.options:
compiler/notes/compiler_design.html:
Delete references to prog_out.m.
compiler/*.m:
Update imports and any explicit module qualifications to account
for the moved code.
tools/filter_sort_imports:
Automatically filter out any repeated imports. This can help with
changes like this that redistribute the contents of one module to other
modules. In this case, after a global replacement of prog_out's import
with the import of parse_tree_out_misc, this updated script could
remove this changed import from modules that already imported
parse_tree_out_misc.
|
||
|
|
cf66008788 |
Stop using exceptions in the analysis package.
compiler/analysis.m:
compiler/analysis.file.m:
Instead of throwing an exception when we find an unexpected version
number or an unrecognized item in a file, construct an error_spec
describing the problem, add it to the list, and continue processing,
if this is possible.
In some places, pass around the information needed for the construction
of meaningful error messages.
Note a limitation of the new approach to error handling (that it inherits
from the old approach).
Instead of reading in each item in analysis request/result files
separately, read in their whole files all at once, and just parse it
item by item.
Stop marking module_cmds as an unwanted dependency; it defines
undate_interface_return_changed, which is required for this module's job.
Give some predicates more meaningful names.
compiler/error_spec.m:
Fix some documentation rot.
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
Act on the error_specs that the analysis package can now return.
|
||
|
|
1659e9e2cb |
Use explicit streams in analysis*.m.
compiler/analysis.m:
compiler/analysis.file.m:
Switch to using explicit streams.
Use io.format when relevant.
Give some fields, predicates and variables more meaningful names.
Replace some rafe-isms with code in our usual coding style.
Add XXXs for possible future improvements.
Replace the flag that says whether debug is enabled with a maybe
wrapped around the stream where debug output should go.
compiler/handle_options.m:
Initialize the maybe debug stream.
compiler/Mercury.options:
Stop disabling the warning for the use of implicit streams
for analysis.m and analysis.file.m.
|
||
|
|
07f877bc3f |
Carve term_context.m out of term.m.
library/term.m:
library/term_context.m:
As above.
Rename the term.context type as term_context.term_context, with
term.context now being defined as an equivalence type.
Replace the context_init function and predicate and the dummy_context_init
function with just one function: dummy_context. This name includes
the important part (the fact that it return a *dummy* context) and deletes
the nonimportant part (dummy contexts are just about never updated,
so the function does not really "initialize" them).
Reduce function/predicate pairs that do the same thing to just a function.
library/MODULES_DOC:
library/library.m:
Add the new module to the list of standard library modules.
NEWS:
Mention the new module, and the obsoleting of the moved predicates
and functions in term.m.
compiler/*.m:
library/*.m:
Conform to the changes above.
|
||
|
|
752bb66f5b |
Carve four modules out of term.m.
Most modules that imported the old term.m need only a small subset
of its functionality. After this diff, most modules that used to import
term.m will need to import just one more module, and will import many
fewer predicates and functions in total.
library/term_int.m:
A new module carved out of term.m containing the predicates
that recognize terms containing integers, and the functions
that construct such terms.
While this job has *some* similarity to the job of the existing
term_conversion.m module, most modules in the compiler use only one
of those two modules, so merging them would not be a good idea.
library/term_subst.m:
A new module carved out of term.m containing code to do
substitutions and renames of various kinds.
Rename the occurs predicate as var_occurs_in_subst_term,
and occurs_list as var_occurs_in_subst_terms, since the latter
are much more descriptive. Change the argument order to match
the new names (var, subst, term/terms), as the old one did not
even have the term/terms and the substitution next to each other,
even though neither makes sense without the other.
library/term_unify.m:
A new module carved out of term.m containing code to do unifications.
Give all the predicates more meaningful names:
unify_term -> unify_terms
unify_term_list -> unify_term_lists
unify_term_dont_bind -> unify_terms_dont_bind
unify_term_list_dont_bind -> unify_term_lists_dont_bind
list_subsumes -> first_term_list_subsumes_second
library/term_vars.m:
A new module carved out of term.m containing code that find variables
in terms.
Give all the predicates more meaningful names:
vars -> vars_in_term
vars_2 -> vars_in_term_acc
vars_list -> vars_in_terms
contains_var -> term_contains_var
contains_var_list -> terms_contain_var
Don't move the function version of vars_2 to term_vars.m, effectively
deleting it, since operations that update an accumulator are awkward
for functions.
library/term.m:
Keep the moved predicates and functions in term.m, but
- change their implementation to simply call the moved copy, and
- obsolete the original in favor of the moved copy.
Eventually, after either the next release or the release after the next,
we should delete the obsoleted predicates and functions.
library/MODULES_DOC:
library/library.m:
Add the new modules as documented parts of the standard library.
browser/interactive_query.m:
compiler/analysis.file.m:
compiler/det_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_passes.m:
compiler/parse_class.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_sym_name.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/typecheck.m:
library/io.m:
library/term_conversion.m:
library/varset.m:
Conform to the changes above.
|
||
|
|
25b4b67403 |
Carve io.file.m out of io.m.
library/io.file.m:
library/io.m:
Move two sections of io.m, the "file handling predicates" section
and the "handling temporary files" section to the new submodule io.file.m.
Leave behind in io.m "forwarding predicates", predicates that do nothing
except call the moved predicates in io.file.m, to provide backward
compatibility. But do mark the forwarding predicates as obsolete,
to tell people to update their (at their leisure, since the obsoleteness
warning can be turned off).
Also leave behind in io.m the definitions of the two types used
by some parameters of some of the moved predicates. Document the reason
why this is done.
library/MODULES_DOC:
List the new module among the documented modules.
NEWS:
Announce the changes.
browser/browse.m:
browser/interactive_query.m:
browser/listing.m:
compiler/analysis.file.m:
compiler/compile_target_code.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_util.m:
compiler/handle_options.m:
compiler/make.build.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_cmds.m:
compiler/parse_module.m:
compiler/passes_aux.m:
compiler/prog_event.m:
compiler/recompilation.check.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
deep_profiler/conf.m:
deep_profiler/mdprof_cgi.m:
library/dir.m:
mdbcomp/program_representation.m:
ssdb/ssdb.m:
Call the file operation predicates directly in io.file.m, not indirectly
through io.m.
In two modules, add a #include of fcntl.h in C code. These modules contain
C code that needs this #include, but until now, they got it via a copy
in an automatically generated C header file of a foreign_decl pragma
in io.m that contained that #include. This diff moves that foreign_decl
to io.file.m, removing that crutch.
tests/debugger/browser_test.m:
tests/hard_coded/bit_buffer_test.m:
tests/hard_coded/bitmap_test.m:
tests/hard_coded/construct_bug.m:
tests/hard_coded/dir_fold.m:
tests/hard_coded/dir_test.m:
tests/hard_coded/read_binary_int16.m:
tests/hard_coded/read_binary_int32.m:
tests/hard_coded/read_binary_int64.m:
tests/hard_coded/read_binary_uint16.m:
tests/hard_coded/read_binary_uint32.m:
tests/hard_coded/read_binary_uint64.m:
tests/hard_coded/read_bitmap_size.m:
tests/hard_coded/remove_file.m:
tests/hard_coded/write_binary.m:
tests/hard_coded/write_binary_int8.m:
tests/hard_coded/write_binary_multibyte_int.m:
tests/hard_coded/write_binary_uint8.m:
Call the file operation predicates directly in io.file.m, not indirectly
through io.m.
|
||
|
|
e657a091e4 |
Encode the arity kind in the type in pred lookups.
compiler/pred_table.m:
Some predicates in this module have traditionally taken an arity argument
that *included* function result arguments, while others took an arity
arguments that *excluded* function result arguments. While the difference
was documented, it was not enforced in the types. Change this by
switching the two kinds of arities to pred_form_arities and user_arities
respectively.
Change the internal data structures to specify in the types
that they operate on user_arities.
Change the operation of lookup_builtin_pred_proc_id as part of the
change to goal_util.m (described below).
compiler/goal_util.m:
When looking up the pred_info of a builtin, callers used to pass to the
predicates that did that (generate_simple_call and generate_foreign_proc)
a list of the arguments of the call without specifying which arguments
were type_info/typeclass_info arguments added by polymorphism.
This meant that the length of the argument list was *not* necessarily
the called predicate or function's pred form arity, but could exceed it
by the number of arguments added by polymorphism. The only reason this
worked was because the lookup_builtin_pred_proc_id procedure they used
to look up the named predicate in the pred table compensated for it
- by doing a lookup on the original arity plus one, if the lookup on the
original arity failed, and
- in all the calls to generate_simple_call and generate_foreign_proc,
the number of arguments added by polymorphism was either zero or one.
Nevertheless, the system was fragile. It could have broken either
- because when looking up the arity that included a type_info argument,
(e.g. one typeinfo and two original args) the lookup could have found
a false match (a predicate with the same name with three original args),
- or because a new call to a new builtin could need to specify two or more
arguments added by polymorphism.
Fix this issue by
- requiring calls to generate_simple_call and generate_foreign_proc
to pass the arguments added by polymorphism separately, so the number
of the original arguments specifies the predicate's pred_form_arity, and
- deleting the code in lookup_builtin_pred_proc_id that tried to
compensate for the presence of an "unannounced" typeinfo argument.
compiler/analysis.m:
Change the type of a slot in a structure from arity to pred_form_arity,
since that seems to have been how that slot was used.
compiler/recompilation.check.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
Conform to the changes above, but only in a minimal fashion,
because I don't *know* whether the values of type 'arity' passed around
in the recompilation modules represent user arities or pred form arities.
Record my guesses, but also record the fact that they are *only* guesses.
Mark suspect code with "XXX ARITY BUG".
compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/stm_expand.m:
compiler/table_gen.m:
Conform to the changes above.
Rationalize the argument order of the internal module-specific predicates
they use to generate calls to builtins.
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/analysis.file.m:
compiler/check_typeclass.m:
compiler/complexity.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/format_call.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/higher_order.m:
compiler/hlds_module.m:
compiler/intermod.m:
compiler/lco.m:
compiler/make_hlds_passes.m:
compiler/mmc_analysis.m:
compiler/modecheck_goal.m:
compiler/par_loop_control.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/pred_table.m:
compiler/purity.m:
compiler/rbmm.region_transformation.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_unify.m:
compiler/size_prof.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unify_proc.m:
Conform to the changes above.
|
||
|
|
b64f0fbedc |
Add a "mercury_term_" prefix to lexer.m/parser.m.
library/mercury_term_lexer.m:
library/mercury_term_parser.m:
As above.
NEWS:
Announce the change.
browser/interactive_query.m:
compiler/analysis.file.m:
compiler/fact_table.m:
compiler/make.module_dep_file.m:
compiler/parse_module.m:
compiler/parse_tree_out_term.m:
compiler/recompilation.used_file.m:
library/MODULES_DOC:
library/char.m:
library/integer.m:
library/io.m:
library/library.m:
library/ops.m:
library/term.m:
library/term_io.m:
mdbcomp/trace_counts.m:
tests/hard_coded/impl_def_lex.m:
tests/hard_coded/impl_def_lex_string.m:
tests/hard_coded/lco_pack_args_3.m:
tests/hard_coded/lexer_bigint.m:
tests/hard_coded/lexer_ints.m:
tests/hard_coded/lexer_zero.m:
tests/hard_coded/parse_number_from_string.m:
tests/valid_seq/nested_module_bug.m:
Conform to the change.
|
||
|
|
bd0b747f6e |
Use explicit streams in several modules.
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma_tabling.m:
compiler/check_libgrades.m:
compiler/deep_profiling.m:
compiler/goal_expr_to_goal.m:
compiler/options_file.m:
compiler/pickle.m:
compiler/process_util.m:
compiler/state_var.m:
compiler/superhomogeneous.m:
Ad above.
compiler/Mercury.options:
Do not pass --no-warn-implicit-stream-calls when compiling these modules.
compiler/analysis.file.m:
compiler/mercury_compile_main.m:
Conform to the changes above.
|
||
|
|
94f475f9d7 |
Allow prog_out.m's callers to use explicit streams.
compiler/prog_out.m:
For every predicate that writes output to the current output stream,
ensure that there is another predicate with the same name that takes
an explicit stream as an additional arguments.
Some of these predicates already existed under different names,
but that name difference prevents --warn-implicit-stream-calls
from warning about the implicit stream use. Fix that.
Delete write_quoted_module_name, since it is a synonym for
write_quoted_sym_name (since the compiler' current code depends on
module_name being a synonym for sym_name in lots of places already).
compiler/add_clause.m:
compiler/analysis.file.m:
compiler/closure_analysis.m:
compiler/higher_order.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/pd_debug.m:
compiler/recompilation.check.m:
compiler/smm_common.m:
compiler/source_file_map.m:
compiler/structure_reuse.indirect.m:
Conform to the changes in prog_out.m. There is no switchover
to explicit streams in this diff; that will come later.
|
||
|
|
4455f0450e |
Specify output streams in some places.
Besides this main purpose, this diff also replaces code that calls
io.write_string several times in a row with code that prints the
thing to be printed in one go with io.format. In a couple of places,
this has caught (and fixed) bugs where we wanted to put `' quotes
around a filename, but printed only one of the two quotes.
compiler/file_util.m:
Provide alternatives to the existing maybe_report_stats,
maybe_write_string and maybe_flush_output predicates that explicitly
specify the output stream.
Rename report_error_to_stream as report_error, to allow
--warn-implicit-stream-calls to report calls to the existing report_error
predicate, which does not take an explicit output stream.
Add a module_name argument to the output_to_file_stream predicate,
to allow its code to figure out where to print both progress and
error messages.
compiler/module_cmds.m:
Add a module_name argument to the predicates that update interface,
to allow their code to figure out where to print both progress and
error messages.
For now, leave the predicates that issue commands that are not
clearly linked to a single module using implicit streams.
compiler/pd_debug.m:
compiler/analysis.file.m:
Specify output streams in some places.
In other places, doing so would require redoing the whole debug
infrastructure, since the current one is based on higher order predicates
that always write to the non-explicitly-specified *current* output stream.
compiler/passes_aux.m:
Provide predicates that get progress, debug and error streams
given a module_info, by extracting the globals and the module name
from the module_info, and then calling the predicates in globals.m
to get those streams. Doing this sequence of actions here factors out
what would otherwise be repeated code in many other parts of the compiler.
Delete two predicates that were not used anywhere in the compiler.
compiler/deforest.m:
compiler/export.m:
compiler/intermod.m:
compiler/llds_out_file.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/recompilation.usage.m:
compiler/simplify_goal_conj.m:
compiler/type_assign.m:
compiler/typecheck.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
Use explicit streams everywhere where --warn-implicit-stream-calls
says this is possible.
compiler/Mercury.options:
Specify --warn-implicit-stream-calls for the modules above
with the listed exceptions, and with the exception of the modules
for which it was already specified.
compiler/compile_target_code.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
Conform to the changes above.
|
||
|
|
5f50259d16 |
Write to explicitly named streams in many modules.
Right now, most parts of the compiler write to the "current output stream".
This was a pragmatic choice at the time, but has not aged well. The problem
is that the answer to the question "where is the current output stream going?"
is not obvious in *all* places in the compiler (although it is obvious in
most). When using such implicit streams, finding where the output is going
to in a given predicate requires inspecting not just the ancestors of that
predicate, but also all their older siblings (since any of them could have
changed the current stream), *including* their entire call trees. This is
usually an infeasible task. By constrast, if we explicitly pass streams
to all output operations, we need only follow the places where the variable
representing that stream is bound, which the mode system makes easy.
This diff switches large parts of the compiler over to doing output only
to explicitly passed streams, never to the implicit "current output stream".
The parts it switches over are the parts that rely to a significant degree
on the innermost change, which is to the "output" typeclass in
parse_tree_out_info.m. This is the part that has to be switched over to
explicit streams first, because (a) many modules such as mercury_to_mercury.m
rely on the output typeclass, and (b) most other modules that do output
call predicates in these modules. Starting anywhere else would be like
building a skyscraper starting at the top.
This typeclass, output(U), has two instances: output(io), and output(string),
so you could output either to the current output stream, or to a string.
To allow the specification of the destination stream in the first case,
this diff changes the typeclass to output(S, U) with a functional dependency
from U to S, with the two instances being output(io.text_output_stream, io)
and output(unit, string). (The unit arg is ignored in the second case.)
There is a complication with the output typeclass method, add_list, that
outputs a list of items. The complication is that each item is output
by a predicate supplied by the caller, but the separator between the items
(usually a comma) is output by add_list itself. We don't want to give
callers of this method the opportunity to screw up by specifying (possibly
implicitly) two different output streams for these two purposes, so we want
(a) the caller to tell add_list where to put the separators, and then
(b) for add_list, not its caller, tell the user-supplied predicate what
stream to write to. This works only if the stream argument is just before
the di,uo pair of I/O state arguments, which differs from our usual practice
of passing the stream at or near the left edge of the argument list,
not near the right. The result of this complication is that two categories
of predicates that are and are not used to print items in a list differ
in where they put the stream in their argument lists. This makes it easy
to pass the stream in the wrong argument position if you call a predicate
without looking up its signature, and may require *changing* the argument
order when a predicate is used to print an item in a list for the first time.
A complete switch over to always passing the stream just before !IO
would fix this inconsistency, but is far to big a change to make all at once.
compiler/parse_tree_out_info.m:
Make the changes described above.
Add write_out_list, which is a variant of io.write_list specifically
designed to address the "complication" described above. It also has
the arguments in an order that is better suited for higher-order use.
Make the same change to argument order in the class method add_list
as well.
Almost all of the following changes consist of passing an extra stream
argument to output predicates. In some places, where I thought this would
aid readability, I replaced sequences of calls to output predicates
with a single io.format.
compiler/prog_out.m:
This module had many predicates that wrote things to the current output
stream. This diff adds versions of these predicates that take an
explicit stream argument.
If the originals are still needed after the changes to the other modules,
keep them, but add "_to_cur_stream" to the end of their names.
Otherwise, delete them. (Many of the changes below replace
write_xyz(..., !IO) with io.write_string(Stream, xyz_to_string(...), !IO),
especially when write_xyz did nothing except call xyz_to_string
and wrote out the result.)
compiler/c_util.m:
Add either an explicit stream argument to the argument list, or a
"_current_stream" suffix to the name, of every predicate defined
in this module that does output.
Add a new predicate to print out the block comment containing
input for mkinit. This factors out common code in the LLDS and MLDS
backends.
compiler/name_mangle.m:
Delete all predicates that used to write to the current output stream,
after replacing them if necessary with functions that return a string,
which the caller can print to wherever it wants. (The "if necessary"
part is there because some of the "replacement" functions already
existed.)
When converting a proc_label to a string, *always* require the caller
to say whether the label prefix should be added to the string,
instead of silently assuming "yes, add it", as calls to one of the old,
now deleted predicates had it.
compiler/file_util.m:
Add output_to_file_stream, a version of output_to_file which
simply passes the output file stream it opens to the predicate
that is intended to define the contents of the newly created or
updated file. The existing output_to_file, which instead sets
and resets the current output stream around the equivalent
predicate call, is still needed e.g. by the MLDS backend,
but hopefully for not too long.
compiler/mercury_to_mercury.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_clause.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_out_pred_decl.m:
compiler/parse_tree_out_term.m:
compiler/parse_tree_out_type_repn.m:
Change the code writing out parse trees to explicitly pass a stream
to every predicate that does output.
In some places, this allows us to avoid changing the identity
of the current output stream.
compiler/hlds_out.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
Change the code writing out HLDS code to explicitly pass a stream
to every predicate that does output. (The changes to these modules
belong in this diff because these modules call many of the output
predicates in the parse tree package.)
In hlds_out_util.m, delete some write_to_xyz(...) predicates that wrote
the result of xyz_to_string(...) to the current output stream.
Replace calls to the deleted predicates with calls to io.write_string
with the string being written being computed by xyz_to_string.
Add a predicate to hlds_out_util.m that outputs a comment containing
the current context, if it is valid. This factors out code that used
to be common to several of the other modules.
In a few places in hlds_out_module.m, the new code generates a
slighly different set of blank lines, but this should not be a problem.
compiler/layout_out.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/opt_debug.m:
compiler/rtti_out.m:
Change the code writing out the LLDS to explicitly pass a stream
to every predicate that does output. (The changes to these modules
belong in this diff because layout_out.m and rtti_out.m call
many of the output predicates in the parse tree package,
and through them, the rest of the LLDS backend is affected as well.)
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
Replace code that sets and resets the current output stream
with code that simply passes an explicit output stream to a
predicate that now *takes* an explicit stream as an argument.
compiler/accumulator.m:
compiler/add_clause.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/cse_detection.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/error_msg_inst.m:
compiler/export.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/ite_gen.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lp_rational.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_c_global.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/optimize.m:
compiler/passes_aux.m:
compiler/pd_debug.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/prog_ctgc.m:
compiler/push_goals_together.m:
compiler/rat.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/rtti.m:
compiler/saved_vars.m:
compiler/simplify_goal_conj.m:
compiler/stack_opt.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/superhomogeneous.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/unneeded_code.m:
compiler/write_deps_file.m:
Conform to the changes above, mostly by passing streams explicitly.
compiler/hlds_dependency_graph.m:
Conform to the changes above, mostly by passing streams explicitly.
Move a predicate's definition next it only use.
compiler/Mercury.options:
Specify --warn-implicit-stream-calls for all the modules in which
this diff has replaced all implicit streams with explicit streams.
(Unfortunately, debugging this diff has shown that --warn-implicit-
stream-calls detects only *some*, and not *all*, uses of implicit
streams.)
library/term_io.m:
Fix documentation.
|
||
|
|
6223e79ee1 | Make pred defn order match decl order. | ||
|
|
c2f92d5454 |
Partition extensions into ".m" and "all others".
This is a first step towards a much finer grained partition.
compiler/file_names.m:
Split the ext type into ext_src and ext_other, as mentioned above.
Add the first predicate for checking whether a string falls into
a given category of extensions.
Add an XXX proposing a better solution for an old problem that does not
actually arise in practice.
compiler/compile_target_code.m:
Split the two-moded predicate maybe_pic_object_file_extension into
two separate one-mode predicates, one for each old mode. The
implementations of the two modes were already separate, because
the two modes already did different jobs: while one went from PIC
to an "extension", the other went from an "extension string" to PIC.
Until now, "extension" and "extension string" were equivalent;
after this diff, they aren't anymore.
Delete an unused argument.
compiler/make.util.m:
Split the two-moded predicate target_extension into
two separate one-mode predicates, one for each old mode,
for the same reason as maybe_pic_object_file_extension above:
the fact that "extension" and "extension string" are now distinct.
compiler/options_file.m:
Move debug infrastructure here from mercury_compile_main.m, to help
debug possible problems with options files. (I had such a problem
while writing this diff.)
Improve how progress messages are printed.
compiler/options.m:
Make an error message more useful.
compiler/mercury_compile_main.m:
Add infrastructure for debugging possible problems with command lines.
(I had such a problem while writing this diff.)
compiler/analysis.m:
Conform to the changes above. Put the arguments of some methods
into the same order as similar predicates in file_names.m.
compiler/find_module.m:
Conform to the changes above. Delete an unused argument,
compiler/analysis.file.m:
compiler/du_type_layout.m:
compiler/elds_to_erlang.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_kind.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.deps_set.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/prog_foreign.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/source_file_map.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
|
||
|
|
52c0919975 |
Make filename extensions a separate type, ...
... to allow later changes to its definition.
compiler/file_names.m:
We used to represent filename extensions simply as strings. This meant
all calls to the predicates in file_names.m that convert module names
to file names with various suffixes had to go through a complicated
sequence of tests that effectively partition the extensions into
several classes, with all extensions in a class being treated the same
but different classes being treated differently. And since this general
translation process is quite convoluted (which is not helped by it
being spread across several predicates), it is very hard to construct
a correctness argument for it.
It would be better to represent the different classes of extensions
explicitly, in a du type, with each function symbol of that type
representing all the extensions in the corresponding class (in the sense
of the paragraph above). However, getting there in one diff would make
that diff far too hard to test and to review. So this first diff
starts by simply making extension a notag type.
The above is the first step in implementing one old XXX. This diff
fully implements another old XXX, which is to make the argument order
of several predicates friendly to higher order code.
Add infrastructure for profiling how often this code makes directories.
Delete an unused type.
Add comments outlining proposed future improvements.
compiler/analysis.file.m:
compiler/analysis.m:
compiler/compile_target_code.m:
compiler/du_type_layout.m:
compiler/elds_to_erlang.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_kind.m:
compiler/find_module.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/module_imports.m:
compiler/parse_tree_out.m:
compiler/prog_foreign.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
Conform to the change to file_names.m.
Consistently use "Ext" for the abstract representation of extensions
and "ExtStr" for their string representation.
In a few places, add "XXX EXT" where the code manipulates extensions
as strings in a way that potentially inferferes with the partition
of extensions into classes.
In a few places, rename predicates to avoid ambiguities. factor out
common code, delete unneeded arguments, replace bools with bespoke types,
and make similar minor improvements.
In a few places, remove rafe-isms, such as the use ^elem.
|
||
|
|
c1bdd2100b | Delete unneeded $module args from aborts. | ||
|
|
e08b8505e9 | Import the parents of *all* imported modules. | ||
|
|
123df4a333 |
Address review comments from Peter.
library/term.m:
library/term_conversion.m:
library/term_io.m:
As above.
compiler/analysis_file.m:
compiler/hlds_out_goal.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/parse_class.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_sym_name.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
Conform to the above changes.
|
||
|
|
e6e295a3cc |
Generalise the representation of integers in the term module.
In preparation for supporting uint literals and literals for the fixed size
integer types, generalise the representation of integers in the term module, so
that for every integer literal we record its base, value (as an arbitrary
precision integer), signedness and size (the latter two based on the literal's
suffix or lack thereof).
Have the lexer attach information about the integer base to machine sized ints;
we already did this for the 'big_integer' alternative but not the normal one.
In conjunction with the first change, this fixes a problem where the compiler
was accepting non-decimal integers in like arity specifications. (The
resulting error messages could be improved, but that's a separate change.)
Support uints in more places; mark other places which require further work with
XXX UINT.
library/term.m:
Generalise the representation of integer terms so that we can store
the base, signedness and size of a integer along with its value.
In the new design the value is always stored as an arbitrary precision
integer so we no longer require the big_integer/2 alternative; delete it.
Add some utility predicates that make it easier to work with integer terms.
library/term_conversion.m:
library/term_io.m:
Conform to the above changes,
Add missing handling for uints in some spots; add XXX UINT comments
in others -- these will be addressed later.
library/lexer.m:
Record the base of word sized integer literals.
library/parser.m:
compiler/analysis_file.m:
compiler/fact_table.m:
compiler/get_dependencies.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/parse_class.m:
compiler/parse_inst_mode_name.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_sym_name.m:
compiler/parse_tree_out_term.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/superhomogeneous.m:
mdbcomp/trace_counts.m:
samples/calculator2.m:
extras/moose/moose.m:
Conform to the above changes.
tests/hard_coded/impl_def_lex.exp:
tests/hard_coded/impl_def_lex_string.exp:
tests/hard_coded/lexer_bigint.exp*:
tests/hard_coded/lexer_zero.exp*:
tests/hard_coded/parse_number_from_string.exp*:
tests/hard_coded/term_to_unit_test.exp:
Update these expected outputs.
|
||
|
|
d7022606d4 |
Call the parser with explicit streams.
compiler/analysis.file.m:
compiler/make.module_dep_file.m:
compiler/parse_module.m:
compiler/recompilation.check.m:
When calling the parser, explicitly specify the stream to read
the term from; don't touch the current input stream.
compiler/find_module.m:
Pass the stream to read from explicitly to parse_module.m.
|
||
|
|
7f2d21f219 |
Make the analysis typeclass a bit more general.
compiler/analysis.m:
Give the analysis typeclass the ability for a compiler to report
which analyses it can do, and turn a semidet function into a semidet
predicate.
compiler/analysis.file.m:
compiler/mmc_analysis.m:
Conform to the above.
|
||
|
|
f1df5d2dd1 |
Give parsing-related modules more meaningful names.
The mapping from the old to the new module names is:
prog_io -> parse_module
prog_io_dcg -> parse_dcg_goal
prog_io_error -> parse_error
prog_io_find -> find_module
prog_io_goal -> parse_goal
prog_io_inst_mode_defn -> parse_inst_mode_defn
prog_io_inst_mode_name -> parse_inst_mode_name
prog_io_iom -> parse_types
prog_io_item -> parse_item
prog_io_mutable -> parse_mutable
prog_io_pragma -> parse_pragma
prog_io_sym_name -> parse_sym_name
prog_io_type_defn -> parse_type_defn
prog_io_type_name -> parse_type_name
prog_io_typeclass -> parse_class
prog_io_util -> parse_util
prog_io_vars -> parse_vars
unparse -> parse_tree_to_term
|
||
|
|
0e31c22bee | Convert (C->T;E) to (if C then T else E). | ||
|
|
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.
|
||
|
|
1f80bf0acd |
Delete the module_specifier type.
compiler/prog_data.m:
The module_specifier type was defined to be a synonym for sym_name,
but the module_name type is meant for the same purposes, and has the
same definition, so it is redundant. Delete it.
compiler/hlds_module.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/make_hlds_passes.m:
compiler/prog_io_item.m:
compiler/prog_out.m:
compiler/prog_util.m:
compiler/try_expand.m:
compiler/typecheck_errors.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
Replace uses of module_specifier with module_name, not just in types,
but also in the names of the predicates that operate on them, and in the
field names that refer to them.
compiler/analysis.file.m:
Avoid an ambiguity.
compiler/make.module_dep_file.m:
Delete a commented piece of code.
compiler/mercury_to_mercury.m:
Delete an unused predicate.
|
||
|
|
13b6f03f46 |
Module qualify end_module declarations.
compiler/*.m:
Module qualify the end_module declarations. In some cases, add them.
compiler/table_gen.m:
Remove an unused predicate, and inline another in the only place
where it is used.
compiler/add_pragma.m:
Give some predicates more meaningful names.
|
||
|
|
16bd4acd2f |
Shorten lines longer than 79 characters.
Estimated hours taken: 2 Branches: main compiler/*.m: Shorten lines longer than 79 characters. |
||
|
|
01cb7f1640 |
When looking up slots in typeclassinfos, we need variables to hold
Estimated hours taken: 1 Branches: main compiler/polymorphism.m: When looking up slots in typeclassinfos, we need variables to hold the values of the indexes of the slots. If possible, do not generate a new variable for this: instead, reuse an existing integer constant previously generated by the polymorphism transformation. Make all the parts of the polymorphism transformation that need variables holding integer constants use the same mechanism to create them. compiler/add_pragma.m: compiler/analysis.file.m: compiler/make.dependencies.m: compiler/make.module_dep_file.m: compiler/make.module_target.m: compiler/recompilation.usage.m: compiler/recompilation.version.m: compiler/structure_reuse.direct.choose_reuse.m: library/bit_buffer.read.m: mdbcomp/feedback.automatic_parallelism.m: Add a bunch of imports. They are of modules that are imported in the relevant module's ancestor, but my compiler is giving me errors without them being duplicated. |
||
|
|
295415090e |
Convert almost all remaining modules in the compiler to use
Estimated hours taken: 6 Branches: main compiler/*.m: Convert almost all remaining modules in the compiler to use "$module, $pred" instead of "this_file" in error messages. In a few cases, the old error message was misleading, since it contained an incorrect, out-of-date or cut-and-pasted predicate name. tests/invalid/unresolved_overloading.err_exp: Update an expected output containing an updated error message. |
||
|
|
9f68c330f0 |
Change the argument order of many of the predicates in the map, bimap, and
Branches: main
Change the argument order of many of the predicates in the map, bimap, and
multi_map modules so they are more conducive to the use of state variable
notation, i.e. make the order the same as in the sv* modules.
Prepare for the deprecation of the sv{bimap,map,multi_map} modules by
removing their use throughout the system.
library/bimap.m:
library/map.m:
library/multi_map.m:
As above.
NEWS:
Announce the change.
Separate out the "highlights" from the "detailed listing" for
the post-11.01 NEWS.
Reorganise the announcement of the Unicode support.
benchmarks/*/*.m:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
extras/*/*.m:
mdbcomp/*.m:
profiler/*.m:
tests/*/*.m:
ssdb/*.m:
samples/*/*.m
slice/*.m:
Conform to the above change.
Remove any dependencies on the sv{bimap,map,multi_map} modules.
|
||
|
|
8a28e40c9b |
Add the predicates sorry, unexpected and expect to library/error.m.
Estimated hours taken: 2 Branches: main Add the predicates sorry, unexpected and expect to library/error.m. compiler/compiler_util.m: library/error.m: Move the predicates sorry, unexpected and expect from compiler_util to error. Put the predicates in error.m into the same order as their declarations. compiler/*.m: Change imports as needed. compiler/lp.m: compiler/lp_rational.m: Change imports as needed, and some minor cleanups. deep_profiler/*.m: Switch to using the new library predicates, instead of calling error directly. Some other minor cleanups. NEWS: Mention the new predicates in the standard library. |
||
|
|
4ebe3d0d7e |
Stop storing globals in the I/O state, and divide mercury_compile.m
Estimated hours taken: 60 Branches: main Stop storing globals in the I/O state, and divide mercury_compile.m into smaller, more cohesive modules. (This diff started out as doing only the latter, but it became clear that this was effectively impossible without the former, and the former ended up accounting for the bulk of the changes.) Taking the globals out of the I/O state required figuring out how globals data flowed between pieces of code that were often widely separated. Such flows were invisible when globals could be hidden in the I/O state, but now they are visible, because the affected code now passes around globals structures explicitly. In some cases, the old flow looked buggy, as when one job invoked by mmc --make could affect the globals value of its parent or the globals value passed to the next job. I tried to fix such problems when I saw them. I am not 100% sure I succeeded in every case (I may have replaced old bugs with new ones), but at least now the flow is out in the open, and any bugs should be much easier to track down and fix. In most cases, changes the globals after the initial setup are intended to be in effect only during the invocation of a few calls. This used to be done by remembering the initial values of the to-be-changed options, changing their values in the globals in the I/O state, making the calls, and restoring the old values of the options. We now simply create a new version of the globals structure, pass it to the calls to be affected, and then discard it. In two cases, when discovering reasons why (1) smart recompilation should not be done or (2) item version numbers should not be generated, the record of the discovery needs to survive this discarding. This is why in those cases, we record the discovery by setting a mutable attached to the I/O state. We use pure code (with I/O states) both to read and to write the mutables, so this is no worse semantically than storing the information in the globals structure inside the I/O state. (Also, we were already using such a mutable for recording whether -E could add more information.) In many modules, the globals information had to be threaded through several predicates in the module. In some places, this was made more difficult by predicates being defined by many clauses. In those cases, this diff converts those predicates to using explicit disjunctions. compiler/globals.m: Stop storing the globals structure in the I/O state, and remove the predicates that accessed it there. Move a mutable and its access predicate here from handle_options.m, since here is when the mutables treated the same way are. In a couple of cases, the value of an option is available in a mutable for speed of access from inside performance-critical code. Set the values of those mutables from the option when the processing of option values is finished, not when it is starting, since otherwise the copies of each option could end up inconsistent. Validate the reuse strategy option here, since doing it during ctgc analysis (a) is too late, and (b) would require an update to the globals to be done at an otherwise inconvenient place in the code. Put the reuse strategy into the globals structure. Two fields in the globals structure were unused. One (have_printed_usage) was made redundant when the one predicate that used it itself became unused; the other (source_file_map) was effectively replaced by a mutable some time ago. Delete these fields from the globals. Give the fields of the globals structure a distinguishing prefix. Put the type declarations, predicate declarations and predicate definitions in a consistent order. compiler/source_file_map.m: Record this module's results only in the mutable (it serves as a cache), not in globals structure. Use explicitly passed globals structure for other purposes. compiler/handle_options.m: Rename handle_options as handle_given_options, since it does not process THE options to the program, but the options it is given, and even during the processing of a single module, it can be invoked up the three times in a row, each time being given different options. (It was up to four times in a row before this diff.) Make handle_given_options explicitly return the globals structure it creates. Since it does not take an old global structure as input and globals are not stored in the I/O state, it is now clear that the globals structure it returns is affected only by the default values of the options and the options it processes. Before this diff, in the presence of errors in the options, handle_options *could* return (implicitly, in the I/O state) the globals structure that happened to be in the I/O state when it was invoked. Provide a separate predicate for generating a dummy globals based only on the default values of options. This allows by mercury_compile.m to stop abusing a more general-purpose predicate from handle_options.m, which we no longer export. Remove the mutable and access predicate moved to globals.m. compiler/options.m: Document the fact that two options, smart_recompilation and generate_item_version_numbers, should not be used without seeing whether the functionalities they call for have been disabled. compiler/mercury_compile_front_end.m: compiler/mercury_compile_middle_passes.m: compiler/mercury_compile_llds_back_end.m: compiler/mercury_compile_mlds_back_end.m: compiler/mercury_compile_erl_back_end.m: New modules carved out of the old mercury_compile.m. They each cover exactly the areas suggested by their names. Each of the modules is more cohesive than the old mercury_compile.m. Their code is also arranged in a more logical order, with predicates representing compiler passes being defined in the order of their invocation. Some of these modules export predicates for use by their siblings, showing the dependencies between the groups of passes. compiler/top_level.m: compiler/notes/compiler_design.html: Add the new modules. compiler/mark_static_terms.m: Move this module from the ml_backend package to the hlds package, since (a) it does not depend on the MLDS in any way, and (b) it is also needed by a compiler pass (loop invariants) in the middle passes. compiler/hlds.m: compiler/ml_backend.m: compiler/notes/compiler_design.html: Reflect mark_static_terms.m's change of package. compiler/passes_aux.m: Move the predicates for dumping out the hLDS here from mercury_compile.m, since the new modules also need them. Look up globals in the HLDS, not the I/O state. compiler/hlds_module.m: Store the prefix (common part) of HLDS dump file names in the HLDS itself, so that the code moved to passes_aux.m can figure out the file name for a HLDS dump without doing system calls. Give the field names of some structures prefixes to avoid ambiguity. compiler/mercury_compile.m: Remove the code moved to the other modules. This module now looks after only option handling (such as deciding whether to generate .int3 files, .int files, .opt files etc), and the compilation passes up to and including the creation of the first version of the HLDS. Everything after that is subcontracted to the new modules. Simplify and make explicit the flow of globals information. When invoking predicates that could disable smart recompilation, check whether they have done so, and if yes, update the globals accordingly. When compiling via gcc, we need to link into the executable the object files of any separate C files we generate for C code foreign_procs, which we cannot translate into gcc's internal structures without becoming a C compiler as well as a Mercury compiler. Instead of adding such files to the accumulating option for extra object files in the globals structure, we return their names using the already existing mechanism we have always used to link the object files of fact tables into the executable. Give several predicates more descriptive names. Put predicates in a more logical order. compiler/make.m: compiler/make.dependencies.m: compiler/make.module_target.m: compiler/make.module_dep_file.m: compiler/make.program_target.m: compiler/make.util.m: Require callers to supply globals structures explicitly, not via the I/O state. Afterward pass them around explicitly, passing modified versions to mercury_compile.m when invoking it with module- and/or task-specific options. Due the extensive use of partial application for higher order code in these modules, passing around the globals structures explicitly is quite tricky here. There may be cases where a predicate uses an old globals structure it got from a closure instead of the updated module- and/or task-specific globals it should be using, or vice versa. However, it is just as likely that, this diff fixes old problems by preventing the implicit flow of updated-only-for-one-invocation globals structures back to the original invoking context. Although I have tried to be careful about this, it is also possible that in some places, the code is using an updated-for-an-invocation globals structure in some but not all of the places where it SHOULD be used. compiler/c_util.m: compiler/compile_target_code.m: compiler/compiler_util.m: compiler/error_util.m: compiler/file_names.m: compiler/file_util.m: compiler/ilasm.m: compiler/ml_optimize.m: compiler/mlds_to_managed.m: compiler/module_cmds.m: compiler/modules.m: compiler/options_file.m: compiler/pd_debug.m: compiler/prog_io.m: compiler/transform_llds.m: compiler/write_deps_file.m: Require callers to supply globals structures explicitly, not via the I/O state. In some cases, the explicit globals structure argument allows a predicate to dispense with the I/O states previously passed to it. In some modules, rename some predicates, types and/or function symbols to avoid ambiguity. compiler/read_modules.m: Require callers to supply globals structures explicitly, not via the I/O state. Record when smart recompilation and the generation of item version numbers should be disabled. compiler/opt_debug.m: compiler/process_util.m: Require callers to supply the needed options explicitly, not via the globals in the I/O state. compiler/analysis.m: compiler/analysis.file.m: compiler/mmc_analysis.m: Make the analysis framework's methods take their global structures as explicit arguments, not as implicit data stored in the I/O state. Stop using `with_type` and `with_inst` declarations unnecessarily. Rename some predicates to avoid ambiguity. compiler/hlds_out.m: compiler/llds_out.m: compiler/mercury_to_mercury.m: compiler/mlds_to_c.m: compiler/mlds_to_java.m: compiler/optimize.m: Make these modules stop accessing the globals from the I/O state. Do this by requiring the callers of their top predicates to explicitly supply a globals structure. To compensate for the cost of having to pass around a representation of the options, look up the values of the options of interest just once, to make further access much faster. (In the case of mlds_to_c.m, the code already did much of this, but it still had a few accesses to globals in the I/O state that this diff eliminates.) If the module exports a predicate that needs these pre-looked-up options, then export the type of this data structure and its initialization function. compiler/frameopt.m: Since this module needs only one option from the globals, pass that option instead of the globals. compiler/accumulator.m: compiler/add_clause.m: compiler/closure_analysis.m: compiler/complexity.m: compiler/deforest.m: compiler/delay_construct.m: compiler/elds_to_erlang.m: compiler/exception_analysis.m: compiler/fact_table.m: compiler/intermod.m: compiler/mode_constraints.m: compiler/mode_errors.m: compiler/pd_util.m: compiler/post_term_analysis.m: compiler/recompilation.usage.m: compiler/size_prof.usage.m: compiler/structure_reuse.analysis.m: compiler/structure_reuse.direct.choose_reuse.m: compiler/structure_reuse.direct.m: compiler/structure_sharing.analysis.m: compiler/tabling_analysis.m: compiler/term_constr_errors.m: compiler/term_constr_fixpoint.m: compiler/term_constr_initial.m: compiler/term_constr_main.m: compiler/term_constr_util.m: compiler/trailing_analysis.m: compiler/trans_opt.m: compiler/typecheck_info.m: Look up globals information from the HLDS, not the I/O state. Conform to the changes above. compiler/gcc.m: compiler/maybe_mlds_to_gcc.pp: compiler/mlds_to_gcc.m: Look up globals information from the HLDS, not the I/O state. Conform to the changes above. Convert these modules to our current programming style. compiler/termination.m: Look up globals information from the HLDS, not the I/O state. Conform to the changes above. Report some warnings with error_specs, instead of immediately printing them out. compiler/export.m: compiler/il_peephole.m: compiler/layout_out.m: compiler/rtti_out.m: compiler/liveness.m: compiler/make_hlds.m: compiler/make_hlds_passes.m: compiler/mlds_to_il.m: compiler/mlds_to_ilasm.m: compiler/recompilation.check.m: compiler/stack_opt.m: compiler/superhomogeneous.m: compiler/tupling..m: compiler/unneeded_code.m: compiler/unused_args.m: compiler/unused_import.m: compiler/xml_documentation.m: Conform to the changes above. compiler/equiv_type_hlds.m: Give the field names of a structure prefixes to avoid ambiguity. Stop using `with_type` and `with_inst` declarations unnecessarily. compiler/loop_inv.m: compiler/pd_info.m: compiler/stack_layout.m: Give the field names of some structures prefixes to avoid ambiguity. compiler/add_pragma.m: Add notes. compiler/string.m: NEWS: Add a det version of remove_suffix, for use by new code above. |
||
|
|
77a6a6c10c |
Implement several more changes that together speed up compilation time
Estimated hours taken: 16 Branches: main Implement several more changes that together speed up compilation time on training_cars_full by 12%, and also improve tools/speedtest -h by 7.2% and tools/speedtest by 1.6%. The first change is designed to eliminate the time that the compiler spends constructing error messages that are then ignored. The working predicates of prog_io_sym_name used to always return a single result, which either gave a description of the thing being looked, or an error message. However, in many places, the caller did not consider not finding the thing being looked for to be an error, and thus threw away the error message, keeping only the "not found" indication. For each predicate with such callers, this diff provides a parallel predicate that indicates "not found" simply by failing. This allows us to eliminate the construction of the error message, the preparation for the construction of the error message (usually by describing the context), and the construction of the "ok" wrapper. The second change is to specialize the handling of from_ground_term_construct scopes in the termination analyzer. To make this easier, I also cleaned up of the infrastructure of the termination analyzer. The third change is to avoid traversing from_ground_term_construct scopes in quantification.m when finding the variables in a goal, since termination analysis no longer needs the information it gathers. The fourth change is to avoid traversing second and later conjuncts in conjunctions twice. The first step in handling conjunctions is to call implicitly_quantify_conj, which builds up a data structure that pairs each conjunct with the variables that occur free in all the conjuncts following it. However, after this was done and each conjunct was annotated with its nonlocals, we used to compute the variables that occur free in the conjunction as a whole from scratch. This diff changes the code so that we now compute that set based on the information we gathered earlier, avoiding a redundant traversal. The fifth change is to create specialized, lower-arity versions of many of the predicates in quantification.m. These versions are intended for traversals that take place after the compiler has replaced lambda expressions with references to separate procedures. These traversals do not need to pass around arguments representing the variables occurring free in the (now non-existent) lambda expressions. compiler/prog_io_sym_name.m: Make the first change described above. Change some predicate names to adopt a consistent naming scheme in which predicates that do the same job and differ only in how they handle errors have names that differ only in a "try_" prefix. Add some predicate versions that do common tests on the output of the base versions. For example, try_parse_sym_name_and_no_args is a version of try_parse_sym_name_and_args that insists on finding an empty argument list. Remove the unused "error term" argument that we used to need a while ago. Move some predicate definitions to make their order match the order of their declarations. Turn a predicate into a function for its caller's convenience. compiler/term_constr_build.m: Make the second change described above by modeling each from_ground_term_construct scope as a single unification, assigning the total size of the ground term to the variable being built. compiler/term_constr_util.m: Put the arguments of some predicates into a more standard order. compiler/lp_rational.m: Change the names of some function symbols to avoid both the use of graphic characters that require quoting and clashes with other types. Change the names of some predicates to make their purpose clear, and to avoid ambiguity. compiler/quantification.m: Make the third, fourth and fifth changes described above. compiler/*.m: Conform to the changes above. |
||
|
|
cc9423e35d |
Rationalize the way the MLDS code generator handles global data structures.
Estimated hours taken: 80
Branches: main
Rationalize the way the MLDS code generator handles global data structures.
The previous way was somewhat perverse in several respects.
The first respect was that static Mercury terms were translated into global
MLDS definitions, those MLDS definitions were turned into local definitions,
and then later turned back into global definitions. However, while they were
local definitions, they were part of the list of definitions processed
by ml_elim_nested. Since the complexity of ml_elim_nested is at least O(n^2)
and probably O(n^3) or worse, and since the definitions representing static
terms could increase the value of n from dozens or hundred to many thousands,
this was a BAD IDEA, especially since by construction, the MLDS definitions
representing ground terms cannot have other definitions nested inside them.
This problem was the main reason why previously the compiler took effectively
forever to compile any program with large tables of facts in MLDS grades.
The second respect has to do with the fact that terms are represented as tagged
pointers to memory cells. When generating an MLDS definition (a static cell)
for a ground term, ml_unify_gen.m remembered the name of the MLDS variable
representing the static cell, but forgot the tag on the pointer. So when
that ground term was used as an argument in another, bigger ground term,
it had to figure out the tag all over again. The argument of the
construct_statically functor in construct unifications had as its sole purpose
the provision of the data needed by this recomputation.
The third respect was that the code generator could generate duplicate
definitions (same variable name, same content) when two conjoined goals
referred to two or more type_infos or pseudo_type_infos for the same type.
The code generator used to handle it by wrapping a scope around the later
definitions, which (a) wasted memory, and (b) could yield warnings from
the C compiler about shadowed declarations. This problem used to prevent
the compiler from bootchecking in grade hlc_nest.gc; with this diff,
we can again bootcheck in grade hlc_nest.gc.
The fourth respect was that the code generator's record of which variables are
bound to constant terms was inaccurate, because it was never reset. If a
variable was bound to a constant term in one branch of a control structure,
the MLDS code generator state's record of this binding was still there
when the compiler generated code for the later branches of that control
structure. It did not use the record, but it was still there.
The MLDS code generator also used a horribly inefficient algorithm for figuring
out which Mercury variables should have their corresponding MLDS variables
declared at a given goal. It gathered up all the goals's variables, and then
gathered up all the variables in the goal's immediate subgoals. This meant
that the entire goal had to be traversed TWICE, with the second traversal
being needed only because the first one gathered too much information.
Those traversals were a huge performance problem on programs with large static
terms, since their representation is large conjunctions of unifications,
which have large numbers of variables. To add insult to injury, the traversals
used ordered lists to represent the sets, which meant that (given the ascending
variable numbers in from_ground_term scopes), adding the n'th unification's
new variable to the set took O(n) time, with the complexity of the whole
algorithm being quadratic.
Besides fixing these problems, this diff makes the MLDS code generator
handle from_ground_term_construct scopes specially, in a streamlined fashion,
just as the LLDS backend has done for a while now. It also fixes a bunch
of other performance problems pointed out by profiling.
This diff reduces the compilation time on the training_cars_150.m benchmark,
which has nothing but ground terms, from 94+ seconds to less than 2 seconds,
a 98% speedup. (This is with from_ground_term scopes enabled, as is
appropriate.) For ordinary programs, compilation time in grade hlc.gc
is reduced by about 3%.
compiler/ml_global_data.m:
A new module that manages the MLDS code generator's records about
static definitions. It separates those definitions into different
categories based on what kind of processing they need. At the moment,
the categories are: definitions of cells for ground terms and
definitions of cells for RTTI, with the latter being subdivided
into those that may need to be processed by ml_elim_nested
and those that are known not to need such processing.
It also records whether we have generated representation for a
type_info or pseudo_type yet, so that we can avoid generating duplicate
definitions. This, and the code that uses this, fixes the third
problem.
compiler/ml_backend.m:
compiler/notes/compiler_design.html:
Add the new module.
compiler/goal_util.m:
Add a warning about the bad complexity of goal_vars.
compiler/hlds_goal.m:
Remove the static_cons type, since it is no longer needed.
Remove the static_cons argument of the construct_statically
functor of the how_to_construct type.
Fix an out-of-date comment about from_ground_term scopes.
compiler/mark_static_terms.m:
Change the data structure being threaded through this module
from being a map(prog_var, static_cons) to a set_tree234(prog_var),
since we no longer need the information stored in static_conses.
compiler/modes.m:
Do not compute static_conses.
compiler/mlds.m:
Put the information about global data into a separate field of
the MLDS, since some classes of such data can have their treatment
optimized.
Put the arguments of some functions into a more logical order.
Give some function symbol names prefixes to avoid ambiguities.
Change or add some field name prefixes to avoid ambiguities.
Avoid the unnecessary use of higher order code in handling the flags of
MLDS definitions. The new code is simpler as well as faster than the
old.
compiler/ml_code_util.m:
Make ml_global_data a part of the MLDS code generator state. This
allows a bunch of predicates in the MLDS code generator to no longer
return lists of definitions, since those definitions are now put
into this new part of ml_gen_info, which ml_elim_nested won't touch.
This is part of the solution of the first problem.
Replace the field that mapped vars to the name of the global static
definition involved in representing the ground term bound to that var
with a field that maps the var to the actual rval (which will be a
tagged pointer to that static definition), though we also remember
the variable's type, since this is needed for making decisions about
boxing. This is part of the solution for the second problem.
Rename the extra_defns field of the ml_gen_info to the
closure_wrapper_defns field, since this is the only thing that
it is used for.
Add fields to the ml_gen_info holding the value of the --highlevel-data
option and the compilation target, since these are needed very often,
and looking them up in the globals is too slow.
Access all fields of ml_gen_info via access predicates, not via field
notation, so that the number of accesses to each field can be measured
by deep profiling.
Separate the ml_gen_info structure into a main structure whose fields
are frequently updated and which fits into an 8-word block of memory,
and a substructure whose fields are read-only or rarely updated.
This should help improve memory performance.
Provide more useful access predicates to some of the counters,
and make them harder to confuse by using fewer type synonyms.
Provide some more convenient predicates for creating auxiliary MLDS
variables (those that do not correspond to Mercury variables).
Delete ml_join_decls, since fixing the third problem means that it is
no longer needed.
Delete some other predicates whose job has been taken over by
ml_global_data.m.
Put the arguments of some predicates into a more logical order.
Rename some predicates to avoid ambiguities.
compiler/ml_code_gen.m:
As part of the fix for the repeated traversals of parts of the
procedure body with goal_vars, we now have to run quantification
before generating MLDS for a procedure. Quantification does in
one optimized pass what the old code used to do in many unoptimized
passes. However, since quantification can change the HLDS, this
requires a small change in the module's interface. HLDS dump 499
now dumps to the HLDS version *output* by MLDS code generation,
not the HLDS version that is its input.
Use the (now guaranteed accurate) nonlocals fields of the goal and
its immediate subgoals to figure out what variables need to declared at
each goal. This fixes the fifth problem.
Special case from_ground_term_construct scopes. (This code recognizes
such scopes; the code that handles them is in ml_unify_gen.m.)
Use trace goals to print progress messages.
Avoid the use of io.format and string.format (see below).
Group the predicates of this module a bit more meaningfully.
(A really good order requires more reordering, but that will be
a separate change.)
Give some predicates more meaningful names.
Add predicates that allow the convenient implementation of branched
control structures.
Use them in the implementation of the branched control structures
handled in this module
Together, these solve the fourth problem.
compiler/ml_switch_gen.m:
compiler/ml_string_switch.m:
Use them in the implementation of the branched control structures
handled in these modules.
Use the new module to generate constant data.
compiler/ml_unify_gen.m:
Implement the changes described at the top.
Divide ml_gen_new_object, a predicate that used to be 220 lines long,
into several pieces, one for each different method of constructing new
objects (memory cells).
Delete the (extensive) code that used to recreate the tags on
pointers to static cells. This code used to also recreate static
arguments in their entirety if they were NOT pointers to cells,
e.g. if they were integers or floats or strings, so we now record
the values of such non-tagged-pointer constant terms also.
Put the arguments of some predicates into a more logical order.
In addition, some predicates now need ml_global_data threaded through
them, but avoid returning lists of definitions.
compiler/ml_call_gen.m:
Simplify the interface of the predicate that decides on boxing and
unboxing, making it callable from places that do not have a full code
generator state (such as the streamlined code in ml_unify_gen handling
from_ground_term_construct scopes).
Avoid the unnecessary use of higher order code.
Rename a predicate to avoid ambiguity.
compiler/ml_closure_gen.m;
Generate the closure layout information as static global data.
compiler/ml_elim_nested.m:
Thread the globals through this module instead of the I/O state,
since the only thing the I/O state was used for was accessing the
globals.
Traverse only the small subset of global data that needs to be
traversed.
compiler/ml_type_gen.m:
Use trace goals to print progress messages.
Replace a semidet predicate with a function returning a tailored type,
for improved robustness.
Look up stuff in the globals structure less frequently, by reusing the
results of past lookups.
compiler/rtti_to_mlds.m:
Restructure the code in this module in two respects.
First, instead of having predicates returning lists of
MLDS definitions, make them add those definitions to a ml_global_data
data structure threaded through the module. Since the ml_global_data
structure records which type_infos and pseudo_type_infos we have
already generated definitions for, this allows us to avoid generating
duplicate static cells for them. This allows us to avoid the old
code's roundabout way of handling of such cells.
Second, several predicates of this module returned initializers,
which their caller then stuck into a static definition. This diff
changes things so that wherever possible, the predicate that computes
the initializers also creates the cell definition. This improves the
code's cohesion.
Also, rename some predicates where, after the above changes, their old
names are no longer appropriate.
compiler/mlds_to_c.m:
Avoid the use of io.format and string.format, since (after the more
extensive changes described at the top of this log message) this
turned out to account for a nontrivial percentage of the compiler's
runtime.
Instead of repeatedly looking up the values of some options
in a copy of the globals obtained from the I/O state, thread
through this module a term that records all the information
that this module needs from globals.
Threading this data through this module instead of looking something
upo in the I/O state leads to a slight slowdown, but not having to do
option lookups in large trees leads to a larger speedup.
Rename some predicates to ambiguity.
Convert some predicate definitions from multiple clauses into one,
for clarity.
Conform to the changes in the structure of the MLDS.
compiler/mlds_to_gcc.m:
Conform to the changes in the structure of the MLDS.
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
Conform to the changes in the structure of the MLDS.
Pass the globals to this module instead of looking it up in the
I/O state.
Rename some predicates to ambiguity.
Avoid the unnecessary use of higher order code.
In mlds_to_managed.m, thread a previously frequently-looked-up value
through the module.
compiler/typecheck_info.m:
The code for expanding equivalence types in a procedure's vartypes
field used to iterate on the keys of the vartypes map, and then
looked up the associated values in the map. This diff replaces hat
with new code that iterates on an association list that puts the
value right next to its key (a list that the old code just threw away).
The var/type assoc list we compute is still sorted on the variables,
so create the new vartypes map not by repeated insertion, but
directly (using map.from_sorted_assoc_list).
compiler/purity.m:
Add a note about a possible future speedup.
compiler/prog_io_sym_name.m:
Rename a predicate to avoid an ambiguity, and to make its purpose
clearer.
compiler/globals.m:
compiler/handle_options.m:
compiler/mlds_to_il.m:
Check whether the mmc option that specifies the IL version number is
well formed at the start of the compilation, in handle_options.m,
when all the other option values are checked if needed, rather than
when generating IL code. This way, we can generate an error message,
not a compiler abort.
The IL version number is now recorded in the globals structure.
compiler/make_hlds_warn.m:
Do not descend into from_ground_term scopes, since by construction,
they cannot contain singleton variables.
compiler/analysis.file.m:
compiler/deep_profiling..m:
compiler/field_access.m:
compiler/hlds_out.m:
compiler/interval.m:
compiler/liveness.m:
compiler/loop_inv.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile.m:
compiler/loop_inv.m:
compiler/ml_tailcall.m:
compiler/module_qual.m:
compiler/prog_ctgc.m:
compiler/prog_io_dcg.m:
compiler/prog_io_goal.m:
compiler/prog_io_pragma.m:
compiler/prog_io_typeclass.m:
compiler/prog_io_util.m:
compiler/quantification.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/structure_reuse.indirect.m:
compiler/superhomogeneous.m:
compiler/var_locn.m:
Conform to the changes above.
compiler/unused_args.m:
Fix an ambiguous predicate name.
tests/hard_coded/float_field.{m,exp}:
Add some more test situations to this test case. These test
the handling of notag types in static terms more thoroughly
than before.
|
||
|
|
1abc2f39a0 |
Continue the breakup of the monster module prog_io.m.
Estimated hours taken: 3 Branches: main Continue the breakup of the monster module prog_io.m. compiler/prog_io.m: compiler/prog_io_mutable.m: compiler/prog_io_sym_name.m: Move the code in prog_io.m for dealing with declarations for mutables and for parsing symbol names and specifiers into two new modules. compiler/parse_tree.m: compiler/notes/compiler_design.html: Add the new modules. compiler/*.m: Import prog_io_sym_name instead of (or, in a couple of cases, as well as) prog_io. |
||
|
|
c25abffbc3 |
Modules names beginning with capital letters were not being quoted in
Branches: main Modules names beginning with capital letters were not being quoted in `.imdg' files, so they could not be read back in properly. compiler/analysis.file.m: Call `write_quoted_sym_name' instead of `write_sym_name'. compiler/prog_out.m: Describe `write_quoted_sym_name' more accurately in its comment. |
||
|
|
c3fcb07f78 |
Add a caching feature for `mmc --make' so as to avoid reparsing the same
Branches: main Add a caching feature for `mmc --make' so as to avoid reparsing the same `.analysis' files repeatedly when many modules in the program or library import similar sets of modules. An `.analysis_cache' file contains a binary representation of the parsed information in its corresponding `.analysis' file. These can be faster to load, under certain conditions. Cache files are stored in `Mercury/analysis_cache' or `Mercury/<grade>/<arch>/Mercury/analysis_cache' for the duration of a single make target. Afterwards the directory is deleted. This avoids stale cache files lying around which are incompatible between different versions of the compiler, host platform, etc. compiler/libs.m: compiler/pickle.m: Add a module in libs to un/serialise arbitrary data structures. compiler/options.m: Add `--analysis-file-cache' and `--analysis-file-cache-dir <dir>' (internal option). compiler/analysis.file.m: Read and write analysis cache files if the cache directory is set. Cache files are written after `.analysis' files are written (if changed) or after an `.analysis' file is read (if it didn't exist). compiler/make.program_target.m: For certain targets, set up the analysis cache directory before running the build procedure, and remove it afterwards. compiler/module_cmds.m: Add a version of update_interface that returns whether the interface file changed. doc/user_guide.texi: Add commented out documentation for `--analysis-file-cache'. |
||
|
|
a00596c283 |
The file modules.m contains lots of different kinds of functionality.
Estimated hours taken: 16 Branches: main The file modules.m contains lots of different kinds of functionality. While much of it belongs together, much of it does not. This diff moves most of the functionality that does not belong with the rest to several new modules: libs.file_util parse_tree.deps_map parse_tree.file_names parse_tree.module_cmds parse_tree.module_imports parse_tree.read_module parse_tree.write_deps_file To make them coherent, move some predicates from hlds.passes_aux, parse_tree.prog_io and parse_tree.prog_out to the new modules, making them more accessible, reducing the required access from the hlds package to parse_tree, or from the parse_tree package to libs. In the same spirit, this diff also moves some simple predicates and functions dealing with sym_names from prog_util.m to mdbcomp/prim_data.m. This allows several modules to avoid depending on parse_tree.prog_util. Rename some of the moved predicates and function symbols where this avoids ambiguity. (There were several that differed from other predicates or function symbols only in arity.) Replace several uses of bools with purpose-specific types. This makes some of the code significantly easier to read. This diff moves modules.m from being by far the largest module, to being only the seventh largest, from 8900+ lines to just 4200+. It also reduces the number of modules that import parse_tree.modules considerably; most modules that imported it now import only one or two of the new modules instead. Despite the size of the diff, there should be no algorithmic changes. compiler/modules.m: compiler/passes_aux.m: compiler/prog_io.m: compiler/prog_out.m: Delete the moved functionality. compiler/file_util.m: New module in the libs package. Its predicates search for files and do simple error or progress reporting. compiler/file_names.m: New module in the parse_tree package. It contains predicates for converting module names to file names. compiler/module_cmds.m: New module in the parse_tree package. Its predicates handle the commands for manipulating interface files of various kinds. compiler/module_import.m: New module in the parse_tree package. It contains the module_imports type and its access predicates, and the predicates that compute various sorts of direct dependencies (those caused by imports) between modules. compiler/deps_map.m: New module in the parse_tree package. It contains the data structure for recording indirect dependencies between modules, and the predicates for creating it. compiler/read_module.m: New module in the parse_tree package. Its job is reading in modules, both human-written and machine-written (such as interface and optimization files). compiler/write_deps_file.m: New module in the parse_tree package. Its job is writing out makefile fragments. compiler/libs.m: compiler/parse_tree.m: Include the new modules. compiler/notes/compiler_design.m: Document the new modules. mdbcomp/prim_data.m: compiler/prog_util.m: Move the predicates that operate on nothing but sym_names from prog_util to prim_data. Move get_ancestors from modules to prim_data. compiler/prog_item.m: Move stuff that looks for foreign code in a list of items here from modules.m. compiler/source_file_map.m: Note why this module needs to be in the parse_tree package. compiler/add_pred.m: compiler/add_special_pred.m: compiler/analysis.file.m: compiler/analysis.m: compiler/assertion.m: compiler/check_typeclass.m: compiler/compile_target_code.m: compiler/cse_detection.m: compiler/det_analysis.m: compiler/elds_to_erlang.m: compiler/exception_analysis.m: compiler/export.m: compiler/fact_table.m: compiler/higher_order.m: compiler/hlds_module.m: compiler/hlds_pred.m: compiler/intermod.m: compiler/llds_out.m: compiler/make.dependencies.m: compiler/make.m: compiler/make.module_dep_file.m: compiler/make.module_target.m: compiler/make.program_target.m: compiler/make.util.m: compiler/make_hlds_passes.m: compiler/maybe_mlds_to_gcc.pp: compiler/mercury_compile.m: compiler/mlds.m: compiler/mlds_to_c.m: compiler/mlds_to_gcc.m: compiler/mlds_to_ilasm.m: compiler/mlds_to_java.m: compiler/mmc_analysis.m: compiler/mode_constraints.m: compiler/mode_debug.m: compiler/modes.m: compiler/module_qual.m: compiler/optimize.m: compiler/passes_aux.m: compiler/proc_gen.m: compiler/prog_foreign.m: compiler/prog_io.m: compiler/prog_io_util.m: compiler/prog_mutable.m: compiler/prog_out.m: compiler/pseudo_type_info.m: compiler/purity.m: compiler/recompilation.check.m: compiler/recompilation.usage.m: compiler/simplify.m: compiler/structure_reuse.analysis.m: compiler/structure_reuse.direct.detect_garbage.m: compiler/structure_reuse.direct.m: compiler/structure_sharing.analysis.m: compiler/tabling_analysis.m: compiler/term_constr_main.m: compiler/termination.m: compiler/trailing_analysis.m: compiler/trans_opt.m: compiler/type_util.m: compiler/typecheck.m: compiler/typecheck_info.m: compiler/unify_proc.m: compiler/unused_args.m: compiler/unused_imports.m: compiler/xml_documentation.m: Minor changes to conform to the changes above. |
||
|
|
36b7bd4ea0 |
Store call and answer patterns as terms in `.analysis' (and related) files and
Branches: main Store call and answer patterns as terms in `.analysis' (and related) files and not strings. It's easier to convert complex patterns to/from terms than strings. Also change the module names and function-ids while we're at it. compiler/analysis.m: Replace the `to_string' typeclass with a `to_term' typeclass. Make call and answer patterns convert to/from terms instead of strings. compiler/analysis.file.m: Read/write terms for call and answer patterns. Read/write module names and function-ids with more natural syntax than the term representations of internal data structures. Bump the analysis file version number. Move some code around. Use promise_equivalent_solutions goals instead of promise_equivalent_solution_io. compiler/exception_analysis.m: compiler/structure_reuse.analysis.m: compiler/structure_sharing.analysis.m: compiler/tabling_analysis.m: compiler/trailing_analysis.m: compiler/unused_args.m: Conform to `to_term' typeclass interface. tests/analysis/ctgc/reuse_runtest.sh: tests/analysis/excp/excp_runtest.sh: tests/analysis/sharing/sharing_runtest.sh: tests/analysis/unused_args/unused_args_runtest.sh: Update test scripts for changed file formats. compiler/mercury_compile.m: Print verbose messages and report stats when reading in files for intermodule analysis. |
||
|
|
6eab527191 |
More changes to the intermodule analysis framework.
Branches: main More changes to the intermodule analysis framework. This patch mainly deals with incorrect treatment of :- external procedures, opt_imported procedures, and forcing the correct reanalyses when answers change or requests are satisfied. - Previously, the way to ensure that a module M is reanalysed if a request in module N is satisfied was, while analysing M: assume an answer for the procedure in N; record that as a result in N; and record that M has a dependency on that answer. When N is analysed, if the real answer is better than the assumed answer, M would be marked `suboptimal' and later reanalysed. That's complicated and wasn't always done correctly. Now we remember the module which makes a request. When the request is satisfied, we mark the requesting module as `suboptimal'. This also means the `.analysis' file of a module will only be modified when analysing that module and no others, which should be useful for parallel builds. - In most analyses we weren't recording results for exported `:- external' procedures as we don't have their clauses and don't analyse them. Other modules would happily make requests for `:- external' procedures, which would never be satisfied. - We shouldn't make intermodule requests for `opt_imported' procedures as we actually have their clauses. Even if the request is satisfied, we'd probably not look them up since we do have their clauses. - If a module M opt_imports a procedure P from module N (its clauses are available while analysing M) then M also needs to depend on any answers required by P. Otherwise a change to an answer required by P won't cause M to be reanalysed. - There doesn't seem to be any reason to keep track of the analysis status of individual results. If an answer changes requiring another module to be reanalysed, the *whole module* will be marked suboptimal or invalid. And if that results in changed answers, its dependant modules will be marked. This patch doesn't remove the status of individual results but makes them always `optimal'. compiler/analysis.m: Remember the name of the module being analysed in the analysis_info. Simplify some predicate interfaces with this information. Remember whether we're currently making an analysis file or just reading from them. Make the record_* predicates do nothing in the latter case, so the caller doesn't need to check. Also make the record predicates do the right thing if the callee module is non-local, e.g. don't make requests to non-local modules. Automatically add a request if depending on a result that doesn't exist. Add a procedure to return the existing call patterns for a procedure, regardless of whether the module has been marked `invalid'. Add some assertions to check the analysis framework is being used as intended. Minor cleanups. compiler/analysis.file.m: Record the module that made the request in `.request' files. Bump the analysis file version number. compiler/hlds_module.m: Pass extra arguments to `init_analysis_info'. compiler/hlds_pred.m: Add `pred_info_is_imported_not_external' which doesn't succeed on `:- external' procedures (defined in the current module), unlike `pred_info_is_imported'. compiler/exception_analysis.m: compiler/tabling_analysis.m: compiler/trailing_analysis.m: compiler/unused_args.m: Record results for `:- external' procedures. Don't look up results for our own `:- external' procedures from the analysis registry. In general, fix many spots where external procs would be treated as imported. Write out results for procedures which are exported to submodules. Conform to analysis framework changes. Remove some redundant checks which have been moved into the framework. compiler/mercury_compile.m: Conform to analysis framework changes. compiler/structure_reuse.analysis.m: Be careful not to read in requests and call patterns for `opt_imported' procedures as if they were defined in the current module. If depending on an answer that doesn't exist, also make a request for that answer. Conform to analysis framework changes. Write out messages when removing useless reuse version procedures. compiler/structure_reuse.indirect.m: Use `pred_info_is_imported_not_external' so as not to look up results for our own `:- external' procedures from the analysis registry. Treat `opt_imported' procedures as intra-module as far as requests are concerned. We need to satisfy requests for them in the current compiler invocation rather than when analysing imported modules. compiler/structure_sharing.analysis.m: Fix treatment of `:- external' procedures. Conform to analysis framework changes. compiler/structure_sharing.domain.m: Don't return suboptimal when unable to look up a result. compiler/mmc_analysis.m: Replace pred_or_func_name_arity_to_func_id by a higher-level predicate. tests/Mmakefile: tests/analysis/Mmakefile: tests/analysis/common.sh: tests/analysis/excp/Mercury.options: tests/analysis/excp/Mmakefile: tests/analysis/excp/excp_m1.m.exception: tests/analysis/excp/excp_m1.m.no_exception: tests/analysis/excp/excp_m2.m: tests/analysis/excp/excp_m3.m: tests/analysis/excp/excp_runtest.sh: tests/analysis/ext/Mercury.options: tests/analysis/ext/Mmakefile: tests/analysis/ext/ext.m: tests/analysis/ext/ext2.m: tests/analysis/ext/ext2_runtest.sh: tests/analysis/ext/ext_runtest.sh: tests/analysis/sharing/Mercury.options: tests/analysis/sharing/Mmakefile: tests/analysis/sharing/sharing_m1.m.no_share: tests/analysis/sharing/sharing_m1.m.share: tests/analysis/sharing/sharing_m2.m: tests/analysis/sharing/sharing_m3.m: tests/analysis/sharing/sharing_runtest.sh: tests/analysis/table/Mercury.options: tests/analysis/table/Mmakefile: tests/analysis/table/table_m1.m.no_tabling: tests/analysis/table/table_m1.m.tabling: tests/analysis/table/table_m2.m: tests/analysis/table/table_m3.m: tests/analysis/table/table_runtest.sh: tests/analysis/trail/Mercury.options: tests/analysis/trail/Mmakefile: tests/analysis/trail/trail_m1.m.no_trail: tests/analysis/trail/trail_m1.m.trail: tests/analysis/trail/trail_m2.m: tests/analysis/trail/trail_m3.m: tests/analysis/trail/trail_runtest.sh: tests/analysis/unused_args/Mercury.options: tests/analysis/unused_args/Mmakefile: tests/analysis/unused_args/ua_m1.m.no_unused_args: tests/analysis/unused_args/ua_m1.m.unused_args: tests/analysis/unused_args/ua_m2.m: tests/analysis/unused_args/ua_m3.m: tests/analysis/unused_args/unused_args_runtest.sh: Add test cases. |
||
|
|
0d60ca704c |
The --intermodule-analysis' option was broken in that touching a .m' file
Branches: main The `--intermodule-analysis' option was broken in that touching a `.m' file would cause its `.analysis' file to be remade (correct) but then all the target code files which depend on that `.analysis' file would be remade, even if the `.analysis' file should be unchanged. Fix that by making analysis files work like other interface files: the timestamp on the `.analysis' file reflects the last time it was changed, and the `.analysis_date' file reflects the last time the module was analysed. To that end we need to move the module status out of the `.analysis' file into a corresponding `.analysis_status' file. Then analysing other modules will only touch the `.analysis_status' file. `.analysis_status' are not installed. compiler/analysis.m: compiler/analysis.file.m: Separate predicates for reading/writing the module status from the module analysis results proper. Use the usual technique of writing analysis results to `.analysis.tmp' and only updating the `.analysis' file if its changed. Write analysis results for a single function-id in sorted order to remove spurious differences. Use some standard interface file handling predicates. compiler/make.util.m: Simplify the special treatment of timestamps for `.analysis' files. compiler/make.module_target.m: compiler/make.program_target.m: Conform to interface changes. |
||
|
|
2e3b81442c |
Make the structure sharing analysis capable of using the intermodule analysis
Branches: main Make the structure sharing analysis capable of using the intermodule analysis framework. This requires changes to the analysis framework. Structure sharing answer patterns need information from the module_info and proc_info in order to be compared. In Simon Taylor's original analysis framework implementation, this would have been provided for by a `FuncInfo' parameter in the `partial_order' typeclass. I removed it two years ago as it was causing difficulties which couldn't be solved cleanly while the analysis framework was not specific to the Mercury compiler. Also, there were no analyses at the time which needed FuncInfos. Now that we do require it, and the analysis framework has been made Mercury specific, we can restore the `FuncInfo' parameter. Also make some more simplifications to the analysis framework. compiler/analysis.m: compiler/analysis.file.m: Remove the `module_id' type and replace occurrences by `module_name'. Remove "extra info" facilities. They were intended for storing information needed by intermodule inlining and higher order specialisation but now that information is in `.opt' files, even when using `--intermodule-analysis'. Change `func_id' from a string to a structured type so we can extract its components easily. Add a message argument to the `invalid_analysis_file' functor so when we throw an exception due to being unable to parse a `.analysis' we get a meaningful message. Change the `.analysis' file format to account for the changes to `module_id' and `func_id'. Bump the file version number. Add a `FuncInfo' parameter to the `partial_order' typeclass, as explained above. Add a `no_func_info' dummy type. Add a `get_func_info' method to the `analysis' framework. When updating the analysis files after analysing a module, we need to be able to materialise FuncInfos for each procedure in order to compare its call or answer patterns. This is what couldn't be added cleanly while the analysis framework was not specific to the Mercury compiler. compiler/structure_sharing.analysis.m: Make the structure sharing analysis capable of using the analysis framework, i.e. use imported answers from the analysis registry, record new answers, dependencies and requests, and keeping track of the optimality of results during analysis. compiler/structure_sharing.domain.m: Add `sharing_as_and_status' to pair `sharing_as' with an `analysis_status'. Make `sharing_as_table' record the `analysis_status' alongside a sharing domain. Update access predicates. Move `sharing_as' into the interface section as it is needed by structure_sharing.m to convert between `sharing_as' and `structure_sharing_answer' values for the analysis framework. When we can't look up the sharing result for an `:- external' predicate, that should not be a sign that the analysis is non-optimal since we can't get a better result by reanalysis. Make special predicates be approximated by `bottom' sharing as we know they don't introduce sharing. Avoid an assertion failure in removing subsumed sharing pairs from a sharing set. compiler/ctgc.util.m: Make `pred_requires_no_analysis' not succeed on special predicates (unify, compare, index, init) which causes the analysis to assume all possible sharing between its arguments, whereas we know that those predicates don't introduce any sharing. Also make `pred_requires_no_analysis' not succeed on `:- external' predicates. compiler/ctgc.selector.m: Make type_on_path_2 fail instead of aborting if asked to select a subtype which turns out to be existentially typed. compiler/structure_reuse.direct.m: Don't run direct structure reuse on compiler generated special predicates. We need to handle them specifically now due to the change to `pred_requires_no_analysis'. compiler/structure_reuse.indirect.m: Don't run indirect structure reuse on compiler generated special predicates, as for the direct reuse pass. Conform to change to `top_feedback'. Change a semidet function to a predicate. compiler/hlds_pred.m: compiler/hlds_out.m: Change `structure_sharing_info' to associate an analysis status with the structure sharing domain of a procedure (if any). Add a type `structure_sharing_domain_and_status' for this. compiler/prog_data.m: Make `top_feedback' a structured type instead of a string. Divide the reasons that we might approximate structure sharing by `top' into different classes. compiler/exception_analysis.m: compiler/tabling_analysis.m: compiler/trailing_analysis.m: Conform to analysis framework changes. compiler/unused_args.m: Conform to analysis framework changes. Move the predicate arity from the call pattern into a FuncInfo, where it belongs. Bump the analysis version number. compiler/prog_ctgc.m: compiler/structure_reuse.direct.detect_garbage.m: Conform to change to `top_feedback'. compiler/make.dependencies.m: compiler/make.module_target.m: compiler/make.program_target.m: compiler/make.util.m: Conform to removal of `module_id' type. compiler/mercury_compile.m: Call mm_tabling_analysis, structure sharing and structure reuse passes when making `.analysis' files. Conform to removal of `module_id' type. compiler/mmc_analysis.m: Add structure sharing to the list of analyses. Add `func_id_to_ppid'. Conform to analysis framework changes. compiler/ctgc.fixpoint_table.m: Replace a semidet function by a predicate. |
||
|
|
8c4bcaf297 |
Make the intermodule analysis framework not require the I/O state for looking
Estimated hours taken: 6
Branches: main
Make the intermodule analysis framework not require the I/O state for looking
up and recording analysis results. The I/O state was required because
analysis files were loaded "on demand" but in most cases this was pointless.
Now we just load all the analysis files of transitively imported modules
before we run anything that uses the analysis framework.
compiler/analysis.file.m:
compiler/analysis.m:
Make the main change above.
Use `unexpected' instead of `error' for fatal errors.
Replace `{Call, Answer, analysis_status}' tuples by a new type
`analysis_result'.
Rename the existing existentially-typed `analysis_result' to
`some_analysis_result'.
Remove the `module_is_local' method from the `compiler' typeclass.
Replace it by a plain procedure that takes an `analysis_info' as
input, instead of using the I/O state.
Use trace goals for debugging output, where we no longer have the I/O
state.
Clean up some code.
compiler/mercury_compile.m:
Before running anything that uses the analysis framework, read in all
the analysis files which might be needed.
compiler/mmc_analysis.m:
Delete `module_is_local' method.
compiler/constraint.m:
compiler/deforest.m:
compiler/exception_analysis.m:
compiler/goal_form.m:
compiler/goal_util.m:
compiler/pd_util.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
compiler/unused_args.m:
Conform to the changes above.
Don't thread I/O state through procedures which no longer require it.
|
||
|
|
ef81b66625 |
Move the intermodule analysis framework into the `compiler' directory, in
Estimated hours taken: 2 Branches: main Move the intermodule analysis framework into the `compiler' directory, in preparation for making it specific to the Mercury compiler, rather than having it generic in case some fictional being might want to use it with a .NET compiler one day. This will make it easier to use and modify. compiler/analysis.file.m: compiler/analysis.m: Copy these files from the `analysis' directory. compiler/top_level.m: Include analysis.m as a new package. compiler/Mercury.options: Add a bug workaround line from analysis/Mercury.options. analysis/Mercury.options: analysis/Mmakefile: analysis/analysis.file.m: analysis/analysis.m: analysis/mer_analysis.m: Replace the contents of these files with comments that the analysis framework is now in the `compiler' directory. We don't actually delete them so their histories remain easily accessible. analysis/README: Mention that the code has been moved. compiler/notes/compiler_design.html: compiler/notes/overall_design.html: Update documentation. Mmake.workspace: Mmakefile: configure.in: compiler/.mgnuc_copts: compiler/COMP_FLAGS.in: compiler/Mmakefile: deep_profiler/.mgnuc_copts: scripts/Mmake.vars.in: scripts/c2init.in: scripts/mercury_config.in: scripts/prepare_tmp_dir_fixed_part.in: tools/binary: tools/binary_step: tools/bootcheck: tools/lmc.in: tools/make_arena: compiler/notes/coding_standards.html: Remove references to the `analysis' directory and `libmer_analysis'. |