mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
083d376e6598628362ee91c2da170febd83590f4
109 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
307b1dc148 |
Split up error_util.m into five modules.
compiler/error_spec.m:
This new module contains the part of the old error_util.m that defines
the error_spec type, and some functions that can help construct pieces
of error_specs. Most modules of the compiler that deal with errors
will need to import only this part of the old error_util.m.
This change also renames the format_component type to format_piece,
which matches our long-standing naming convention for variables containing
(lists of) values of this type.
compiler/write_error_spec.m:
This new module contains the part of the old error_util.m that
writes out error specs, and converts them to strings.
This diff marks as obsolete the versions of predicates that
write out error specs to the current output stream, without
*explicitly* specifying the intended stream.
compiler/error_sort.m:
This new module contains the part of the old error_util.m that
sorts lists of error specs and error msgs.
compiler/error_type_util.m:
This new module contains the part of the old error_util.m that
convert types to format_pieces that generate readable output.
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Include and document the new modules.
compiler/error_util.m:
The code remaining in the original error_util.m consists of
general utility predicates and functions that don't fit into
any of the modules above.
Delete an unneeded pair of I/O states from the argument list
of a predicate.
compiler/file_util.m:
Move the unable_to_open_file predicate here from error_util.m,
since it belongs here. Mark another predicate that writes
to the current output stream as obsolete.
compiler/hlds_error_util.m:
Mark two predicates that wrote out error_spec to the current output
stream as obsolete, and add versions that take an explicit output stream.
compiler/Mercury.options:
Compile the modules that call the newly obsoleted predicates
with --no-warn-obsolete, for the time being.
compiler/*.m:
Conform to the changes above, mostly by updating import_module
declarations, and renaming format_component to format_piece.
|
||
|
|
28f0000487 | Rename predicates to avoid ambiguities. | ||
|
|
546b5325d6 | Improve programming style. | ||
|
|
d76c7bf617 |
Break up inst_util.m and mode_util.m.
This step significantly improves module cohesion.
compiler/inst_abstract_unify.m:
New module carved out of inst_util.m, which does abstract unifications
on insts.
compiler/inst_merge.m:
New module carved out of inst_util.m, which merges insts.
compiler/inst_lookup.m:
New module carved partly out of inst_util.m and partly out of mode_util.m,
which looks up insts in the module_info, and then possibly expands out
the result.
compiler/mode_test.m:
New module carved out of mode_util.m, whose predicates
perform tests on modes.
compiler/mode_top_functor.m:
New module carved out of mode_util.m, which computes top_functor_modes
from modes.
compiler/inst_mode_type_prop.m:
New module carved out of mode_util.m, which propagates type information
into both insts and modes.
compiler/recompute_instmap_deltas.m:
New module carved out of mode_util.m, which recomputes goals'
instmap_deltas.
compiler/inst_test.m:
Move here the predicates in inst_util.m that perform tests on insts.
compiler/inst_util.m:
compiler/mode_util.m:
Delete the code that this diff moves to other modules.
compiler/check_hlds.m:
Add the new modules to the check_hlds package, the package that also
contains inst_util.m and mode_util.m. (Some of these modules could
be argued to fit better in the hlds package, but moving them there
would not be desirable while they depend on code that is still in the
check_hlds package.)
compiler/notes/compiler_design.html:
Document the new modules.
compiler/add_pragma_tabling.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/error_msg_inst.m:
compiler/fact_table.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/inst_match.m:
compiler/inst_user.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/lambda.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lookup_util.m:
compiler/loop_inv.m:
compiler/mark_tail_calls.m:
compiler/ml_args_util.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_util.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/oisu_check.m:
compiler/par_conj_gen.m:
compiler/pd_util.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/proc_requests.m:
compiler/prog_rep.m:
compiler/push_goals_together.m:
compiler/rbmm.region_transformation.m:
compiler/saved_vars.m:
compiler/simplify_goal_switch.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_pass2.m:
compiler/term_util.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_util.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
Conform to the changes above by importing the required new modules,
sometimes in addition to inst_util.m or mode_util.m, but more usually
instead of them.
|
||
|
|
1ce46c2797 |
Pair lambda arg vars with their modes.
compiler/hlds_goal.m:
This enforces the invariant that the there is one mode par argument var.
Document that that "nonlocals" field of the lambda actually contains
the variables that will be put into the closure.
compiler/assertion.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/delay_partial_inst.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/hhf.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/hlds_statistics.m:
compiler/implementation_defined_literals.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_warn.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_ordering.m:
compiler/mode_util.m:
compiler/modecheck_unify.m:
compiler/old_type_constraints.m:
compiler/polymorphism.m:
compiler/polymorphism_lambda.m:
compiler/pre_quantification.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/simplify_goal_unify.m:
compiler/stratify.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unused_args.m:
compiler/unused_imports.m:
Conform to the change above.
|
||
|
|
0d7c8a7654 |
Specify pred or func for all pragmas.
*/*.m:
As above.
configure.ac:
Require the installed compiler to support this capability.
|
||
|
|
206cc8503b |
Revisit valid vs all proc_ids in a pred_info.
compiler/hlds_pred.m:
We have several predicates that retrieve selected subsets of all
the proc_ids in a pred_info. For those that retrieve the proc_ids
of only valid procedures, put "valid" into their names.
Fix a bug in the implementation of pred_info_all_non_imported_proc_ids,
which, despite its name, used to return the proc_ids of only the
*valid* non-imported procedures.
The distinction between all procedures and only valid procedures
only really matters between mode analysis and the end of the front end.
A procedure is valid if it has no mode errors, so before mode analysis,
all procedures are valid by default, and if any procedure has any
mode errors, the compiler should terminate after the front end is done.
However, the distinction matters for readability, so this diff changes
things so that we get all proc_ids in code executed before mode analysis,
and valid proc_ids after the front end, with calls handled on a case-by-
case basis in between.
The distinction also matters in the presence of errors. For example,
we shouldn't tell users that a predicate has no modes when it has
modes that all happen to be invalid, and we should dump procedures
into .hlds_dump files even if they are invalid, since their invalidity
may be exactly what the user is trying to debug.
compiler/*.m:
Make the changes described above.
In some places, fix bad programming style.
|
||
|
|
9789375cc5 |
Make pre-HLDS passes use file-kind-specific parse trees.
Replacing item blocks file-kind-specific kinds of section markers with
file-kind-specific parse trees has several benefits.
- It allows us to encode the structural invariants of each kind of file
we read in within the type of its representation. This makes the detection
of any accidental violations of those invariants trivial.
- Since each file-kind-specific parse tree has separate lists for separate
kinds of items, code that wants to operate on one or a few kinds of items
can just operate on those kinds of items, without having to traverse
item blocks containing many other kinds of items as well. The most
important consequence of this is not the improved efficiency, though
that is nice, but the increased clarity of the code.
- The new design is much more flexible. For example, it should be possible
to record that e.g. an interface file we read in as a indirect dependency
(i.e. a file we read not because its module was imported by the module
we are compiling, but because its module was imported by *another* imported
module) should be used *only* for the purpose it was read in for. This should
avoid situations where deleting an import of A from a module, because it
is not needed anymore, leads the compiler to generate an error message
about a missing import of module B. This can happen if (a) module B
always *should* have been imported, since it is used, but (b) module A's
import of module B lead to module B's interface being available *without*
an import of B.
Specifically, this flexibility should enable us to establish each module's
.int file as the single source of truth about how values of each type
defined in that module should be represented. When compiling each source
file, this approach requires the compiler to read in that module's .int file
but using only the type_repn items from that .int file, and nothing else.
- By recording a single parse tree for each file we have read, instead of
a varying number of item blocks, it should be significantly easier to
derive the contents of .d files directly from the records of those
parse trees, *without* having to maintain a separate set of fields
in the module_and_imports structure for that purpose. We could also
trivially avoid any possibility of inconsistencies between these two
different sources of truth. (We currently fill in the fields used to
drive the generation of .d files using two different pieces of code,
one used for --generate-dependencies and one used for all other invocations,
and these two *definitely* generate inconsistent results, as the significant
differences in .d files between (a) just after an invocation of
--generate-dependencies and (b) just after any other compiler invocation
can witness.)
This change is big and therefore hard to review. Therefore in many files,
this change adds "XXX CLEANUP" comments to draw attention to places that
have issues that should be fixed, but whose fixes should come later, in
separate diffs.
compiler/module_imports.m:
The compiler uses the module_and_imports structure defined here
to go from a raw compilation unit (essentially a module to be compiled)
to an augmented compilation unit (a raw compilation unit together
with all the interface and optimization files its compilation needs).
We used to store the contents of both the source file and of
the interface and optimization files in the module_and_imports structure
as item blocks. This diff replaces all those item blocks with
file-kind-specific parse trees, for the reasons mentioned above.
Separate out the .int0 files of ancestors modules from the .intN
files for N>0 of directly imported modules. (Their item blocks
used to be stored in the same list.)
Maintain a database of the source, interface and optimization files
we have read in so far. We use it to avoid reading in interface files
if we have already read in a file for the same module that contains
strictly more information (either an interface file with a smaller
number as a suffix, or the source file itself).
Shorten some field names.
compiler/prog_item.m:
Define data structures for storing information about include_module,
import_module and use_module declarations, both in a form that allows
the representation of possibly erroneous code in actual source files,
and in checked-and-cleaned-up form which is guaranteed to be free
of the relevant kinds of errors. Add a block comment at the start
of the module about the need for this distinction.
Define parse_tree_module_src, a data structure for representing
the source code of a single module. This is different from the existing
parse_tree_src type, which represents the contents of a single source file
but which may contain *more* than one module, and also different from
a raw_compilation_unit, which is based on item blocks and is thus
unable to express to invariants such as "no clauses in the interface".
Modify the existing parse_tree_intN types to express the distinction
mentioned just above, and to unify them "culturally", i.e. if they
store the same information, make them store it using the same types.
Fix a mistake by allowing promises to appear in .opt files.
I originally ruled them out because the code that generates .opt files
does not have any code to write out promises, but some of the predicates
whose clauses it writes out have goal_type_promise, which means that
they originated as promises, and get written out as promises.
Split the existing pragma item kind into three item kinds, which have
different invariants applying to them.
- The decl (short for declarative) pragmas give the compiler some
information, such as that a predicate is obsolete or that we
want to type specialize some predicate or function, that is in effect
part of the module's interface. Decl pragmas may appear in module
interfaces, and the compiler may put them into interface files;
neither statement is true of the other two kinds of pragmas.
- The impl (short for implementation) pragmas are named so
precisely because they may appear only in implementation sections.
They give the compiler information that is private to that module.
Examples include foreign_decls, foreign_codes, foreign_procs,
and promises of clause equivalence, and requests for inlining,
tabling etc. These will never be put into interface files,
though some of them can affect the compilation of other modules
by being included in .opt files.
- The gen (short for generated) pragmas can never (legally) appear
in source files at all. They record the results of compiler
analyses e.g. about which arguments of a predicate are unused,
or what exceptions a function can throw, and accordingly they
should only ever occur in compiler-generated interface files.
Use the new type differences between the three kinds of pragmas
to encode the above invariants about which kinds of pragmas can appear
where into the various kinds of parse trees.
Make the augmented compilation unit, which is computed from
the final module_and_imports structure, likewise switch from
storing item blocks to storing the whole parse trees of the
files that went into its construction. With each such parse tree,
record *why* we read it, since this controls what permissions
the source module being compiled has for access to the entities
in the parse tree.
Simplify the contains_foreign_code type, since one of three
function symbols was equivalent to one possible use of another
function symbol.
Provide a way to record which method of which class a compiler-generated
predicate is for. (See hlds_pred.m below.)
Move the code of almost all utility operations to item_util.m
(which is imported by many fewer modules than prog_item.m),
keeping just the most "popular" ones.
compiler/item_util.m:
Move most of the previously-existing utility operations here from
prog_item.m, most in a pretty heavily modified form.
Add a whole bunch of other utility operations that are needed
in more than one other module.
compiler/convert_parse_tree.m:
Provide predicates to convert from raw compilation units to
parse_tree_module_srcs, and vice versa (though the reverse
shouldn't be needed much longer).
Update the conversion operations between the general parse_tree_int
and the specific parse_tree_intN forms for the changes in prog_item.m
mentioned above. In doing so, use a consistent approach, based on
new operations in item_util.m, to detect errors such as duplicate
include_module and import/use_module declarations in all kinds
of parse trees.
Enforce the invariants that the types of parse trees of various kinds
can now express in types, generating error messages for their violations.
Delete some utility operations that have been moved to item_util.m
because now they are also needed by other modules.
compiler/grab_modules.m:
Delete code that did tests on raw compilation units that are now done
when that raw compilation unit is converted to a parse_tree_module_src.
Use the results of the checks done during that conversion to decide
which modules are imported/used and in which module section.
Record a single reason for why we reading in each interface and
optimization file. The code of make_hlds_separate_items.m will use
this reason to set up the appropriate permissions for each item
in those files.
Use separate code for handling different kinds of interface and
optimization files. Using generic traversal code was acceptable economy
when we used the same data structure for every kind of interface file,
but now that we *can* express different invariants for different kinds
of interface and optimization file, we want to execute not just different
code for each kind of file, but the data structures we want to work on
are also of different types. Using file-kind-specific code is a bit
longer, but it is significantly simpler and more robust, and it is
*much* easier to read and understand.
Delete the code that separates the parts of the implementation section
that are exported to submodules, and the part that isn't, since that task
is now done in make_hlds_separate_items.m.
Pass a database of the files we have read through the relevant predicates.
Give some predicates more meaningful names.
compiler/notes/interface_files.html:
Note a problem with the current operation of grab_modules.
compiler/get_dependencies.m:
Add operations to gather implicit references to builtin modules
(which have to be made available even without an explicit import_module
or use_module declaration) in all kinds of parse trees. These have
more code overall, but will be at runtime, since we need only look at
the item kinds that may *have* such implicit references.
Add a mechanism to record the result of these gathering operations
in import_and_or_use_maps.
Give some types, function symbols, predicates and variables
more meaningful names.
compiler/make_hlds_separate_items.m:
When we stored the contents of the source module and the
interface and optimization files we read in to augment it
in the module_and_imports structure as a bunch of item blocks,
the job of this module was to separate out the different kinds of items
in the item blocks, returning a single list of each kind of item,
with each such item being packaged up with its status (which encodes
a set of permissions saying what the source module is allowed
to do with it).
Now that the module_and_imports structure stores this info in
file-kind-specific parse trees, all of which have separate lists
for each kind of item and none of which contain item blocks,
the job of this module has changed. Now its job is to convert
the reason why each file was read in into the (one or more) statuses
that apply to the different kinds of items stored in it, wrap up
each item with its status, and return the resulting overall list
of status/item pairs for each kind of item.
compiler/read_modules.m:
Add predicates that, when reading an interface file, return its contents
in the tightest possible file-kind-specific parse tree.
Refine the database of files we have read to allow us to store
more file-kind-specific parse trees.
Don't require that files in the database have associated timestamps,
since in some cases, we read files we can put into the database
*without* getting their timestamps.
Allow the database to record that an attempt to read a file failed.
compiler/split_parse_tree_src.m:
Rearchitect how this module separates out nested submodules from within
the main module in a file.
Another of the jobs of this module is to generate error messages for
when module A includes module B twice, whether via nesting or via
include_module declarations, with one special exception for the case
where A's interface contains nested submodule A.B's interface,
and A's implementation contains nested submodule A.B's implementation.
The problem ironically was that while it reported duplicate include_module
declarations as errors, split_parse_tree_src.m also *generated*
duplicate include_module declarations. Since it replaced each nested
submodule occurrence with an include_module declaration, in the scenario
above, it generated two include_module declarations for A.B. Even worse,
the interface incarnation of submodule A.B could contain
(the interface of) its own nested submodule A.B.C, while its
implementation incarnation could contain (the implementation section of)
A.B.C. Each occurrence of A.B.C would be its only occurrence in the
including part of its parent A.B, which means local tests for duplicates
do not work. (I found this out the hard way.)
The solution we now adopt adds include_module declarations to the
parents of any submodule only once the parse tree of the entire
file has been processed, since only then do we know all the
includer/included relationships among nested modules. Until then,
we just record such relationships in a database as we discover them,
reporting duplicates when needed (e.g. when A includes B twice
*in the same section*), but not reporting duplicates when not needed
(e.g. when A.B includes A.B.C in *different* sections).
compiler/prog_data.m:
Add a new type, pf_sym_name_and_arity, that exactly specifies
a predicate or function. It is a clone of the existing simple_call_id
type, but its name does NOT imply that the predicate or function
is being called.
Add XXXs that call for some other improvements in type names.
compiler/prog_data_foreign.m:
Give a type, and the operations on that type, a more specific name.
compiler/error_util.m:
Add an id field to all error_specs, which by convention should be
filled in with $pred. Print out the value in this field if the compiler
is invoked with the developer-only option --print-error-spec-id.
This allows a person debugging the compiler find out where in the code
an undesired error message is coming from significantly easier
than was previously possible.
Most of the modules that have changes only "to conform to the changes
above" will be for this change. In many cases, the updated code
will also simplify the creation of the affected error_specs.
Fix a bug that looked for a phase in only one kind of error_spec.
Add some utility operations needed by other parts of this change.
Delete a previously internal function that has been moved to
mdbcomp/prim_data.m to make it accessible in other modules as well.
compiler/Mercury.options:
Ask the compiler to warn about dead predicates in every module
touched by this change (at least in one its earlier versions).
compiler/add_foreign_enum.m:
Replace a check for an inappropriately placed foreign_enum declaration
with a sanity check, since with this diff, the error should be caught
earlier.
compiler/add_mutable_aux_preds.m:
Delete a check for an inappropriately placed mutable declaration,
since with this diff, the error should be caught earlier.
compiler/add_pragma.m:
Instead of adding pass2 and pass3 pragmas, add decl and impl and
generated pragmas.
Delete the tests for generated pragma occurring anywhere except
.opt files, since those tests are now done earlier.
Shorten some too-long predicate names.
compiler/comp_unit_interface.m:
Operate on as specific kinds of parse trees as the interface of this
module will allow. (We could operate on more specific parse trees
if we changed the interface, but that is future work).
Use the same predicates for handling duplicate include_module,
import_module and use_module declarations as everywhere else.
Delete the code of an experiment that shouldn't be needed anymore.
compiler/equiv_type.m:
Replace code that operated on item blocks with code that operates
on various kinds of parse trees.
Move a giant block of comments to the front, where it belongs.
compiler/hlds_module.m:
Add a field to the module_info that lets us avoid generating
misleading error messages above missing definitions of predicates
or functions when those definitions were present but were not
added to the HLDS because they had errors.
Give a field and its access predicates a more specific name.
Mark a spot where an existing type cannot express everything
it is supposed to.
compiler/hlds_pred.m:
For predicates which the compiler creates to represent a class method
(the virtual function, in OOP terms), record not just this fact,
but the id of the class and of the method. Using this extra info
in progress messages (with mmc -V) prevents the compiler from printing e.g.
% Checking typeclass constraints on class method
% Checking typeclass constraints on class method
% Checking typeclass constraints on class method
when checking three such predicates.
compiler/make.m:
Provide a slot in the make_info structure to allow the database
of the files we have read in to be passed around.
compiler/make_hlds_error.m:
Delete predicates that are needed in just one other module,
and have therefore been moved there.
compiler/make_hlds_passes.m:
Add decl, impl and generated pragma separately, instead of adding
pass2 and pass3 pragmas separately.
Do not generate error messages for clauses, initialises or finalises
in module interfaces, since with this diff, such errors should be
caught earlier.
compiler/mercury_compile_main.m:
compiler/recompilation.check.m:
Explicitly pass around the expanded database of parse trees
of files that have been read in.
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
Collect module qualification information, and do module qualification
respectively on parse trees of various kinds, not item blocks.
Take information about what the module may do with the contents
of each interface or optimization file from the record of why
we read that file, not from the section markers in item blocks.
Break up some too-large predicates by carving smaller ones out of them.
compiler/options.m:
Add an option to control whether errors and/or warnings detecting
when deciding what should go into a .intN file be printed,
thus (potentially) preventing the creation of that file.
Add commented-out documentation for a previously totally undocumented
option.
doc/user_guide.texi:
Document the new option.
NEWS:
Announce the new option.
Mention that we now generate warnings for unused import_module and
use_module declarations in the interface even if the module has
submodules.
compiler/write_module_interface_files.m:
Let the new option control whether we filter out any messages generated
when deciding what should go into a .intN file.
compiler/parse_item.m:
Delete actually_read_module_opt, since it is no longer needed;
its callers now call actually_read_module_{plain,trans}_opt instead.
Delete unneeded arguments from some predicates.
compiler/parse_module.m:
Delete some long unused predicates.
compiler/parse_pragma.m:
When parsing pragmas, wrap them up in the new decl, impl or generated
pragma kinds.
compiler/parse_tree_out.m:
Add predicates to write out each of the file-kind-specific parse trees.
compiler/parse_tree_out_pragma.m:
Add predicates to write out decl, impl and generated pragmas.
compiler/polymorphism.m:
Add a conditionally-enabled progress message, which can be useful
in tracking down problems.
compiler/prog_item_stats.m:
Conform NOT to the changes above beyond what is needed to let this module
compile. Let that work be done the next time the functionality of
this module is needed, by which time the affected data structures
maybe have changed further.
compiler/typecheck.m:
Fix a performance problem. With intermodule optimization, we read in
.opt files, some of which (e.g. list.opt and int.opt) contain promises.
These promises are read in as predicates with goal_type_promise,
but they do not have declarations of the types of their arguments
(since promises do not have declarations as such). Those argument types
therefore have to be inferred. That inference replaces the original
"I don't know" argument types with their actual types.
The performance problem is that when we change the recorded argument types
of a predicate, we require another loop over all the predicates in the
module, so that any calls to this predicate can be checked against
the updated types. This is as it should be for callable predicates,
but promises are not callable. So if all the *only* predicates whose
recorded argument types change during the first iteration to fixpoint
are promises, then a second iteration is not needed, yet we used to do it.
The fix is to replace the "Have the recorded types of this predicate
changed?" boolean flag with a bespoke enum that says "Did the checking
of this predicate discover a need for another iteration", and not
setting it when processing predicates whose type is goal_type_promise.
compiler/typecheck_errors.m:
Do not generate an error message for a predicate missing its clauses
is the clauses existed but were not added to the HLDS because they were
in the interface section.
When reporting on ambiguities (when a call can match more than one
predicate or function), sort the possible matches before reporting
them.
compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/canonicalize_interface.m:
compiler/check_for_missing_type_defns.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/dead_proc_elim.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/field_access.m:
compiler/find_module.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/handle_options.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/introduce_parallelism.m:
compiler/layout_out.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
compiler/mmakefiles.m:
compiler/mode_errors.m:
compiler/mode_robdd.equiv_vars.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/oisu_check.m:
compiler/old_type_constraints.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_inst_mode_name.m:
compiler/parse_mutable.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/parse_type_name.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/parse_util.m:
compiler/parse_vars.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/prog_event.m:
compiler/prog_mode.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_proc.m:
compiler/state_var.m:
compiler/stratify.m:
compiler/style_checks.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
Conform to the changes above.
mdbcomp/prim_data.m:
Move a utility function on pred_or_funcs here from a compiler module,
to make it available to other compiler modules as well.
scripts/compare_s1s2_lib:
A new script that helped debug this diff, and may help debug
similar diffs the future. It can compare (a) .int* files, (b) .*opt
files, (c) .mh/.mih files or (d) .c files between the stage 1 and
stage 2 library directories. The reason for the restriction
to the library directory is that any problems affecting the
generation of any of these kinds of files are likely to manifest
themselves in the library directory, and if they do, the bootcheck
won't go on to compile any of the other stage 2 directories.
tests/debugger/breakpoints.a.m:
tests/debugger/breakpoints.b.m:
Move import_module declarations to the implementation section
when they are not used in the interface. Until now, the compiler
has ignored this, but this diff causes the compiler to generate
a warning for such misplaced import_module declarations even modules
that have submodules. The testing of such warnings is not the point
of the breakpoints test.
tests/invalid/Mercury.options:
Since the missing_interface_import test case tests error messages
generated during an invocation of mmc --make-interface, add the
new option that *allows* that invocation to generate error messages.
tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/warnings/ambiguous_overloading.exp:
Expect the updated error messages for ambiguity, in which
the possible matches are sorted.
tests/invalid/bad_finalise_decl.m:
tests/invalid/bad_initialise_decl.m:
Fix programming style.
tests/invalid/bad_item_in_interface.err_exp:
Expect an error message for a foreign_export_enum item in the interface,
where it should not be.
tests/invalid/errors.err_exp:
Expect the expanded wording of a warning message.
tests/invalid/foreign_enum_invalid.err_exp:
Expect a different wording for an error message. It is more "standard"
but slightly less informative.
tests/invalid_submodules/children2.m:
Move a badly placed import_module declaration, to avoid having
the message the compiler now generates for it from affecting the test.
tests/submodules/parent2.m:
Move a badly placed import_module declaration, to avoid having
the message the compiler now generates for it from affecting the test.
Update programming style.
|
||
|
|
f359612be1 |
Don't let internal insts such as $typed_inst(...) reach users.
compiler/hlds_error_util.m:
Make the functions that describe procedures in terms of the modes of their
arguments take a parameter that says whether we should generate output
for ordinary users (who expect Mercury insts) or for developers who
want to debug things (who want all the details they can get).
Until now, we always generated output for developers, which is not always
what we want.
compiler/det_analysis.m:
compiler/det_report.m:
compiler/stratify.m:
When generating error messages, ask for insts to be output as standard
Mercury.
|
||
|
|
ae4b736fdd |
Implement warnings for suspicious recursion.
compiler/simplify_goal_call.m:
If the --warn-suspicious-recursion option is set, and if the warning
isn't disabled, generate warnings for two different kinds of suspicious
recursion. They are both related to, but separate from, the warning
we have long generated for infinite recursion, which occurs when
the input args of a recursive call are the same as the corresponding
args in the clause head.
Both kinds suspicious recursion look at the input args of a recursive call
that are NOT the same as the corresponding args in the clause head.
Both require these args to have non-unique modes. (If they have unique
modes, then the depth of the recursion may be controlled by state outside
the view of the Mercury compiler, which means that a warning would be
likely to be misleading.)
The first kind is when all these args use state variable notation.
Most of the time, we use state var notation to denote the data structures
updated by the recursive code; having variables using such notation
*controlling* the recursion is much less common, and much more likely
to be unintended. The motivation for the new option was this infinitely
looping code, which resulted from neglecting to s/[X | Xs]/Xs/ after
cutting-and-pasting the clause head to the recursive call.
p([X | Xs], !S) :-
...,
p([X | Xs], !S).
The other kind of suspicious recursive call we warn about involve
input arguments where the base names of the input arguments (the part
before any numeric suffixes) seem be switched between the clause head
and the recursive call, as here:
q(As0, Bs0, ...) :-
...,
q(Bs1, As, ...).
compiler/mercury_compile_main.m:
Disable style warnings when invoked with --make-optimization-interface
or its transitive variant. Without this, warnings about suspicious
recursion would get reported in such invocations.
Move a test from a callee to a caller to allow the callee to be
less indented.
compiler/options.m:
Export functionality to mercury_compile_main.m to make the above possible.
library/string.m:
Add a predicate to convert a string to *reverse* char list directly.
Note a discrepancy between the documentation and the implementation
of the old predicate the new one is based on (which converts a string
to a forward char list).
NEWS:
Note the new predicate in string.m.
compiler/cse_detection.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/distance_granularity.m:
compiler/frameopt.m:
compiler/inst_util.m:
compiler/lp_rational.m:
compiler/matching.m:
compiler/modes.m:
compiler/old_type_constraints.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_arguments.m:
compiler/recompilation.usage.m:
compiler/stratify.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.indirect.m:
compiler/typeclasses.m:
compiler/use_local_vars.m:
deep_profiler/callgraph.m:
deep_profiler/canonical.m:
library/bit_buffer.read.m:
library/bit_buffer.write.m:
library/calendar.m:
library/diet.m:
library/lexer.m:
library/parser.m:
library/parsing_utils.m:
library/ranges.m:
library/set_ctree234.m:
library/set_tree234.m:
library/string.parse_util.m:
library/tree234.m:
library/varset.m:
mdbcomp/program_representation.m:
mdbcomp/rtti_access.m:
profiler/demangle.m:
Avoid warnings for suspicious recursion. In most cases, do this by
wrapping disable_warning scopes around the affected recursive calls;
in a few cases, do this by changing the code.
tests/warnings/suspicious_recursion.{m,exp}:
A test case for the new warnings.
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
Enable the new test case.
|
||
|
|
15aa457e12 | Delete $module arg from calls to unexpected. | ||
|
|
7231df1666 |
Simplify hlds_dependency_graph.m.
compiler/hlds_dependency_graph.m:
Make module_info_ensure_dependency_info return the dependency info,
so that the caller does not have to get it separately.
Simplify the type class used in the module: make it cover only the
operation used in traversing goals. Making it cover the operations
used in traversing predicates as well takes more code and adds more
complexity than it saves.
Rewrite the code that traverses predicates to avoid code duplication.
The tests for whether a predicate or procedure should be processed
used to be duplicated, and in one case the duplication was imperfect,
i.e. two different pieces of code implicitly made inconsistent assumptions
about each other. Rewriting the code so that code that adds arcs to the
digraph accepts the decisions of the code that added the nodes to the
digraph eliminates this problem.
Factor out the common code for adding a new edge to the digraph.
Traversing a predicate or procedure does not guarantee that we will add it
to the digraph as a node. To reflect this, add a "maybe" prefix to the
names of the affected predicates.
Put related predicates next to each other.
compiler/closure_analysis.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/exception_analysis.m:
compiler/inlining.m:
compiler/rbmm.interproc_region_lifetime.m:
compiler/rbmm.points_to_analysis.m:
compiler/stratify.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
Conform to the first change above.
|
||
|
|
dea4368f7d |
Make each SCC in the dependency graph a set, not a list.
This is to make the data type follow the inherent semantics of SCCs
more closely, and enforce the invariant that a procedure can appear
in the SCC only once.
Also, rename the list of SCCs from "dependency_ordering", which does
not give a clue about *which way* the SCCs are ordered, to "bottom_up_sccs",
which does.
compiler/dependency_graph.m:
Make the changes described above.
Document why we reverse the list generated by digraph.atsort.
library/digraph.m:
Document the order in which digraph.atsort returns the list of SCCs.
Note that the last step of atsort is to reverse the list, which
its caller in compiler/dependency_graph.m will then immediately
re-reverse.
Document the order in which digraph.tsort and digraph.dfs return
a list of items.
Give some variables more meaningful names, and make the argument order
of some predicates conform to our conventions.
compiler/hlds_out_module.m:
Add code to print out the dependency info in the module_info, if asked.
doc/user_guide.texi:
Document the dump string option that asks for this.
compiler/hlds_dependency_graph.m:
Make the same changes for hlds_dependency_info as dependency_graph.m
did to just plain dependency_info.
compiler/hlds_pred.m:
Make the scc type expand to a set, not a list, of pred_proc_ids.
compiler/dep_par_conj.m:
compiler/stratify.m:
Conform to the changes above, and simplify some code.
compiler/closure_analysis.m:
compiler/ctgc.util.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/exception_analysis.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/inlining.m:
compiler/lco.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mode_constraints.m:
compiler/rbmm.interproc_region_lifetime.m:
compiler/rbmm.points_to_analysis.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_errors.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_main.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/term_errors.m:
compiler/term_pass1.m:
compiler/term_pass2.m:
compiler/term_util.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
Conform to the changes above.
|
||
|
|
48a08881a5 | Fix some bad predicate and variable names. | ||
|
|
6b4bffb8e6 |
Address a review comment simplifying some code
compiler/stratify.m:
As above.
|
||
|
|
c0b2dd20d4 | Post-commit review comments for the previous diff. | ||
|
|
e2ffb8d01a |
Reorganise dependency graph code
This change moves code that could be generic/common out of
hlds_dependency_graph.m into dependency_graph.m. It also moves some code
from hlds_module.m into hlds_dependency_graph.m where it makes more sense.
compiler/dependency_graph.m:
New module.
Make the accessors predicates functions and give them more sensible
names.
Create a new accessors to get a version or the dependency ordering,
condensed into a single list.
compiler/hlds_dependency_graph.m:
Build the dependency_info structure in a more straightforward way. It
can easily be created with a single call rather than three. The
dependency ordering information is now calculated by dependency_graph.m.
Make build_dependency_graph, build_proc_dependency_graph and
build_pred_dependency_graph functions rather than predicates.
compiler/hlds_module.m:
As above.
compiler/closure_analysis.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/exception_analysis.m:
compiler/granularity.m:
compiler/hlds_dependency_graph.m:
compiler/inlining.m:
compiler/lco.m:
compiler/libs.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mode_constraints.m:
compiler/par_loop_control.m:
compiler/rbmm.interproc_region_lifetime.m:
compiler/rbmm.points_to_analysis.m:
compiler/stratify.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
Conform to changes.
|
||
|
|
65171172fd |
Move dependency_graph module
Move the dependency_graph module from transform_hlds to the hlds parent
module. Rename the dependency_graph.m file to hlds_dependency_graph.m
This change will allow us to move generic dependency_graph code to
dependency_graph.m.
compiler/dependency_graph.m -> hlds_dependency_graph.m:
compiler/hlds.m:
compiler/transform_hlds.m:
As above.
compiler/closure_analysis.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/exception_analysis.m:
compiler/granularity.m:
compiler/inlining.m:
compiler/lco.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mode_constraints.m:
compiler/par_loop_control.m:
compiler/rbmm.interproc_region_lifetime.m:
compiler/rbmm.points_to_analysis.m:
compiler/stratify.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
Conform to changes.
|
||
|
|
bc6cfcd9bd |
Add consider_used pragmas for may-be-needed-later predicates.
Delete some other predicates that won't be needed later. |
||
|
|
2a866ba063 | 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.
|
||
|
|
4e3af446ef |
Give some verbose error explanations only once.
compiler/error_util.m:
Some of the messages we print if --verbose-errors are enabled just explain
what an always-printed error message means. If a compiler invocation
reports several instances of an error, the explanation is useful
only the first time. This diff provides a mechanism for printing
such verbose messages only once per invocation of write_error_specs.
compiler/*.m:
Specify verbose_once for verbose error message components which are
(a) not specific to the specific instance of the error they are generated
for, and (b) whose usefulness/size ratio is not high enough. Part (b)
means that it is ok to repeatedly print a single-line reminder,
but not a 20-line missive that reads like an extract from the
reference manual.
In one case, make an error message clearer.
tests/invalid/*.err_exp:
tests/warnings/*.exp:
Expect the new, slimmed-down output.
|
||
|
|
c1402f8b99 |
Clean up hlds_module.m.
compiler/hlds_module.m:
Put related fields of the module_sub_info next to each other.
Some of those fields contained lists that were built reversed,
in order to avoid O(N^2) behavior when repeatedly adding new items
to the end of the list. Replace these with cords, which did not exist
when those fields were first added.
Give some fields and their getter/setter predicates more descriptive
names.
Separate out both the declarations and definitions of the getter and
setter predicates, and put them into the same order as the (updated)
order of the fields. Put the utility predicates (those that are more
complicated than just getters or setters) into an order based on
what fields they work on, following the same order.
Improve the operation of some of the utility predicates, e.g. replacing
a nondet predicate with a det predicate returning a set.
Delete an unused type.
Conform to the changes in the modules imported by hlds_module.m,
e.g. pred_table.m, prog_data.m and prog_foreign.m.
compiler/pred_table.m:
We used to store the set of valid pred ids as two lists, again to avoid
O(N^2) behavior. Replace the two lists with a set. This allows
looking up the set *without* updating the pred_table, or, when
the pred_table is within the module_info, updating the module_info.
Instead of allowing callers to replace the set of valid pred ids wholesale,
enforce the documented invariant on that set by only allowing deletions.
Conform to the changes above.
compiler/add_pragma.m:
compiler/bytecode_gen.m:
compiler/check_typeclass.m:
compiler/compile_target_code.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/dependency_graph.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/float_regs.m:
compiler/foreign.m:
compiler/higher_order.m:
compiler/hlds_module.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/introduce_parallelism.m:
compiler/lambda.m:
compiler/liveness.m:
Conform to the changes above.
In many places, the change to how the valid pred ids are stored
allows us to avoid creating new module_infos.
In some places, fix style issues I noticed while working on the above.
compiler/llds.m:
compiler/mercury_compile_llds_back_end.m:
Conform to the changes above.
Move a type from llds.m to mercury_compile_llds_back_end.m, since
only the latter uses it.
compiler/prog_data.m:
compiler/prog_foreign.m:
Replace some types that used to hold reversed lists with cords.
In prog_foreign.m, represent the two kinds of foreign code that
do NOT define procedures with similarly named types.
Delete a type (user_foreign_code) that duplicated another type.
Replace an equivalence type with a notag type, for safety.
compiler/recompilation.usage.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
Now that we have direct access to the set of visible modules,
simplify the logic of some code dealing with those modules.
compiler/module_imports.m:
Put some related fields next to each other.
compiler/llds_out_file.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_passes.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/ml_proc_gen.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
compiler/mode_constraints.m:
compiler/modes.m:
compiler/modules.m:
compiler/passes_aux.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/pred_table.m:
compiler/proc_gen.m:
compiler/prog_item.m:
compiler/purity.m:
compiler/rbmm.condition_renaming.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.live_region_analysis.m:
compiler/rbmm.live_variable_analysis.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_arguments.m:
compiler/rbmm.region_instruction.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/stratify.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.domain.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/tabling_analysis.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/trans_opt.m:
compiler/try_expand.m:
compiler/type_constraints.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/write_deps_file.m:
|
||
|
|
efb56544ed |
Speed up pred_info's setter predicates a bit.
compiler/hlds_pred.m:
If the new value of a field of pred_info is likely to be bit-identical
to the old value, then test the old and new bits for equality in the
setter, and if they are the same, do not allocate a new pred_info
structure that is guaranteed to be the same as the old one.
By avoiding unnecessary memory turnover, this speeds up the compiler a bit,
though I cannot nail down by how much. I measured it several times, with
the results being no change, a speedup of 1%, and a speedup of 2%.
Remove the unused setter predicate for the attributes field.
Rename some access predicates to pred_infos to better reflect what they do.
Add a distinguishing prefix to the fields of pred_infos.
compiler/*.m:
Conform to the changes above.
|
||
|
|
fe785c668b |
Consistently use set.is_empty and set.is_non_empty.
compiler/*.m:
deep_profiler/*.m:
As above.
library/set.m:
library/set_bbbtree.m:
library/set_ctree234.m:
library/set_ordlist.m:
library/set_tree234.m:
library/set_unordlist.m:
Add is_non_empty to the set modules that did not already have it.
(Some did, some didn't.)
Make the documentation of empty, is_empty, non_empty and is_non_empty
consistent.
|
||
|
|
500948d549 |
Break up mdbcomp/prim_data.m. The new modules have much better cohesion.
mdbcomp/sym_name.m:
New module, containing the part of the old prim_data.m that
dealt with sym_names.
mdbcomp/builtin_modules.m:
New module, containing the part of the old prim_data.m that
dealt with builtin modules.
mdbcomp/prim_data.m:
Remove the things that are now in the two new modules.
mdbcomp/mdbcomp.m:
deep_proiler/Mmakefile:
slice/Mmakefile:
Add the two new modules.
browser/*.m:
compiler/*.m:
deep_proiler/*.m:
mdbcomp/*.m:
slice/*.m:
Conform to the above changes.
|
||
|
|
6d43c71948 |
Implement semantic checks for oisu (order independent state update) pragmas.
Estimated hours taken: 30
Branches: main
Implement semantic checks for oisu (order independent state update) pragmas.
compiler/hlds_pred.m:
Record for each procedure whether it implements an operation
on a oisu type, and if yes, what kind of operation.
compiler/hlds_module.m:
Add to module_infos a data structure that lists the oisu pragmas
in the module, and the procedures mentioned in them. These are intended
to be used later during code generation.
compiler/add_pragma.m:
Add such pragmas to the HLDS, after checking whatever properties
can be checked during the creation of the HLDS.
compiler/oisu_check.m:
A new module, whose job it is to check those aspects of oisu pragmas
that can be checked only after other semantics are complete on the
module.
compiler/check_hlds.m:
Add the new module.
compiler/notes/compiler_design.html:
Document the new module.
compiler/mercury_compile_front_end.m:
Invoke the new module.
compiler/error_util.m:
Add the new semantic check as a phase.
compiler/mercury_to_mercury.m:
Fix typos in the code for writing out oisu pragmas.
compiler/prog_io_pragmas.m:
Fix typos in the code for reading in oisu pragmas.
compiler/module_qual.m:
Improve the error messages generated for any problems discovered during
module qualification inside pragmas, by writing out what *kind* of
pragma the problem was discovered in.
compiler/modules.m:
Fix a bug: oisu pragmas *can* appear in module interfaces.
compiler/stratify.m:
Give a predicate a better interface and a name.
compiler/hlds_goal.m:
Remove a duplicate comment.
compiler/make_hlds_passes.m:
Fix formatting.
tests/hard_coded/oisu_check_main.{m,exp}:
tests/hard_coded/oisu_check_db.m:
A new multimodule test case, which uses oisu pragmas correctly.
tests/invalid/oisu_check_add_pragma_errors.{m,err_exp}:
A new test case, which tests add_pragma.m's ability to diagnose
the problems it is supposed to diagnose.
tests/invalid/oisu_check_semantic_errors.{m,err_exp}:
A new test case, which tests oisu_check.m's ability to diagnose
the problems it is supposed to diagnose.
tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
Enable the new test cases.
|
||
|
|
ee63cb8d84 |
Heavily polymorphic code, such as that generated by g12, often builds the same
Estimated hours taken: 80 Branches: main Heavily polymorphic code, such as that generated by g12, often builds the same typeinfos and typeclass infos over and over again. We have long had caches that avoid building a new typeinfo or typeclass info if some variable in the current scope already contains the right value, but a program that has many scopes may still build the same typeinfo or typeclass info many times. If that typeinfo or typeclass info is a ground term, the code generators will recognize that fact, and will turn all the constructions of that ground term in different scopes into referencess to the same constant structure. However, in the meantime, the program can be much bigger than necessary. In the motivating test case for this change, a single call to fdic_post is preceded by 133 goals that build the four typeclass infos it needs. The main idea of this diff is to construct constant typeinfos and typeclass infos out of line, in a separate data structure. Polymorphism then binds variables representing typeinfo and typeclass infos to reference to these constant structures. In the motivating example, this allows polymorphism.m to insert just four goals before the call to fdic_post, the minimal possible number: one for each typeclass info that predicate needs. On Leslie's bug344 program, this change speeds up the compiler by a factor of five to eight (reducing compile time from about 80 or 85 seconds to 10 or 15). There is a drawback to this scheme, but it is minor. That drawback is that once a constant structure is entered into our database of constant structures, it cannot (yet) be removed. Even if all the references to a constant structure are eliminated by optimizations, the structure will remain. ------------------------------------------ CHANGES IN THE FRONT END compiler/const_struct.m: A new module to look after our new database of constant structures. Currently, its use is enable only on the LLDS and MLDS C backends. compiler/hlds.m: compiler/notes/compiler_design.html: Add the new module to the HLDS package. compiler/hlds_module.m: Include the constant structure database in the module_info. compiler/hlds_data.m: Add two new cons_ids, which refer to typeinfos and typeclass infos implemented as constant structures. Move the code for calculating the number of extra instance args in base_typeclass_infos here from base_typeclass_info.m, since polymorphism.m now needs it too. We can now also eliminate the duplicate copy of that code in higher_order.m. Make an independent optimization: make the restrict_list_elements function more efficient by avoiding redundant tests. compiler/polymorphism.m: When building typeinfo and typeclass infos, keep track of whether the structure being built is constant. If it is, then put it in the database of constant structures, and replace the code building it with a simple reference to that new entry. Since I now expect most goal sequences inserted before goals to be short, consistent use lists of goals to represent these, since the costs of conversions to and from cord form are unlikely to be paid back by the higher efficiency of cord operations on longer sequences. When we want to get the typeclass info of a superclass out of the typeclass info of a subclass, if the typeclass info of the subclass is known, do the extraction here. We used to do this optimization only in higher_order.m, but doing so here reduces the size of the HLDS between polymorphism.m and higher_order.m, and thus improves compilation time. Reorganize some of the structure of this module to make the above changes possible. In particular, our new approach requires making snapshots of the varsets and vartypes, and later restoring those snapshots if the variables allocated turn out to be unnecessary, due to all of them describing the components of a constant structure. The correctness of such code is much easier to check if the taking and restoring of each snapshot takes places in a single predicate. Remove the code moved to higher_order.m. Add some debugging code for now. If no issues arise in the next few weeks, it can be deleted. compiler/modecheck_unify.m: Treat unifications whose right hand side has a cons_id referring to a constant structure specially. compiler/base_typeclass_info.m: Replace the code that is now in num_extra_instance_args with a call to that predicate. Put the arguments of some predicates in a more logical order. compiler/higher_order.m: When looking up the components of existing typeclass infos, handle cases where those typeclass infos are constant structures. Give some types, fields and variables better names. Avoid a redundant map search. Avoid some redundant tests by providing separate predicates to handle higher order calls and method calls. Move the predicate is_typeclass_info_manipulator here from polymorphism.m, since this is the only module that uses that predicate. ------------------------------------------ CHANGES IN THE LLDS BACKEND: compiler/llds.m: Add a type to map constant structure numbers to rvals together with their LLDS types. Introduce a type to represent rvals together with their LLDS types. compiler/mercury_compile_llds_back_end.m: Before we generate code for the predicates of the module, convert the constant structures to typed LLDS rvals. Create a map mapping each constant structure number to the corresponding typed rvals. compiler/proc_gen.m: Take that map, and put it into the code_info, to allow references to those structures to be translated. Put the arguments of some predicates into a more logical order. compiler/code_info.m: Include a map giving the representation of each constant structure in the code_info. compiler/unify_gen.m: Add the predicates needed to convert the constant structures of a module to LLDS rvals. For now, this code works only on the kinds of constant structures generated by polymorphism.m. Handle unifications whose right hand side is a reference to a constant structure. compiler/global_data.m: compiler/stack_layout.m: Use the new typed_rval type where relevant. ------------------------------------------ CHANGES IN THE MLDS BACKEND: compiler/ml_proc_gen.m: Before we generate code for the predicates of the module, convert the constant structures to typed MLDS rvals. Create a map mapping each constant structure number to the corresponding typed rvals. Factor out some code into a predicate of its own. compiler/ml_gen_info.m: Include a map giving the representation of each constant structure in the ml_gen_info. Also add to the ml_gen_info an indication of what GC system we are generating code for, since the code generator needs to know this often. compiler/ml_unify_gen.m: Add the predicates needed to convert the constant structures of a module to MLDS rvals. For now, this code works only on the kinds of constant structures generated by polymorphism.m. Handle unifications whose right hand side is a reference to a constant structure. Simplify some existing code. ------------------------------------------ MINOR CHANGES: mdbcomp/prim_data.m: Add a predicate that gets both the module name and the base name from a sym_name at the same time. This is used for minor speedups in other code updated in this diff. compiler/dead_proc_elim.m: Scan constant structures for references to entities that need to be kept alive. compiler/term_constr_build.m: compiler/term_traversal.m: Do not build size constraints from references to constant structures. The sizes of constant terms don't change, so they are irrelevant when building constraints for finding argument size changes. ------------------------------------------ TRIVIAL CHANGES TO CONFORM TO OTHER CHANGES: compiler/hlds_out_module.m: Print out the constant structure database if asked. doc/user_guide.tex: Document how to ask for it. compiler/hlds_out_util.m: Print out the new cons_ids. compiler/hlds_out_mode.m: Print out the new cons_ids in insts. Remove a compiler abort, to help debug a problem. Improve the structure of a predicate. compiler/hlds_out_goal.m: Fix some missing newlines. compiler/hlds_code_util.m: Add some utility predicates needed by the modules above. Conform to the changes above. compiler/mlds_to_il.m: Reorder some predicates. Conform to the changes above. compiler/bytecode_gen.m: compiler/ctgc.selector.m: compiler/dependency_graph.m: compiler/erl_unify_gen.m: compiler/export.m: compiler/implementation_defined_literals.m: compiler/inst_check.m: compiler/llds_out_globals.m: compiler/mercury_to_mercury.m: compiler/ml_global_data.m: compiler/ml_switch_gen.m: compiler/ml_type_gen.m: compiler/module_qual.m: compiler/prog_rep.m: compiler/prog_type.m: compiler/prog_util.m: compiler/rbmm.execution_path.m: compiler/switch_gen.m: compiler/switch_util.m: compiler/type_ctor_info.m: compiler/unused_imports.m: compiler/var_locn.m: compiler/xml_documentation.m: Conform to the changes above. ------------------------------------------ OTHER INDEPENDENT CHANGES: compiler/handle_options.m: Add a dump option that is useful for debugging when working on polymorphism.m and constant structures. compiler/equiv_type_hlds.m: Fix an old performance bug: make the code handling try goals keep the old memory cells representing such goals, instead of rebuilding them, if no changes took place inside them. compiler/ml_accurate_gc.m: Move a test earlier, to allow us to avoid more work in the common case. compiler/erl_code_gen.m: compiler/error_util.m: compiler/hhf.m: compiler/inst_util.m: compiler/ml_code_util.m: compiler/ml_util.m: compiler/mlds_to_c.m: compiler/modecheck_call.m: compiler/modecheck_util.m: compiler/post_typecheck.m: compiler/size_prof.m: compiler/stack_opt.m: compiler/stratify.m: compiler/unused_args.m: compiler/post_type_analysis.m: library/erland_rtti_implementation.m: Minor cleanups. ------------------------------------------ CHANGES TO THE TEST SUITE: tests/invalid/any_passed_as_ground.err_exp2: tests/invalid/invalid_default_func_1.err_exp2: tests/invalid/invalid_default_func_3.err_exp2: tests/invalid/try_detism.err_exp2: Add second expected output files for these tests. We need alternate expected outputs because the numbers of some of the typeinfo variables mentioned in error message are different depending on whether or not const structures are enabled. |
||
|
|
b86f973fa9 |
Allow the use of Mercury abstract machine float registers for passing
Branches: main Allow the use of Mercury abstract machine float registers for passing double-precision float arguments in higher order calls. In of itself this is not so useful for typical Mercury code. However, as all non-local procedures are potentially the targets of higher order calls, without this change first order calls to non-local procedures could not use float registers either. That is the actual motivation for this change. The basic mechanism is straightforward. As before, do_call_closure_* is invoked to place the closure's hidden arguments into r1, ..., rN, and extra input arguments shifted into rN+1, etc. With float registers, extra input arguments may also be in f1, f2, etc. and the closure may also have hidden float arguments. Optimising for calls, we order the closure's hidden arguments so that all float register arguments come after all regular register arguments in the vector. Having the arguments out of order does complicate code which needs to deconstruct closures, but that is not so important. Polymorphism complicates things. A closure with type pred(float) may be passed to a procedure expecting pred(T). Due to the `float' argument type, the closure expects its argument in a float register. But when passed to the procedure, the polymorphic argument type means it would be called with the argument in a regular register. Higher-order insts already contain information about the calling convention, without which a higher-order term cannot be called. We extend higher-order insts to include information about the register class required for each argument. For example, we can distinguish between: pred(in) is semidet /* arg regs: [reg_f] */ and pred(in) is semidet /* arg regs: [reg_r] */ Using this information, we can create a wrapper around a higher-order variable if it appears in a context requiring a different calling convention. We do this in a new HLDS pass, called float_regs.m. Note: Mercury code has a tendency to lose insts for higher-order terms, then "recover" them by hacky means. The float_regs pass depends on higher-order insts; it is impossible to create a wrapper for a procedure without knowing how to call it. The float_regs pass will report errors which we otherwise accepted, due to higher-order insts being unavailable. It should be possible for the user to adjust the code to satisfy the pass, though the user may not understand why it should be necessary. In most cases, it probably really *is* unnecessary. We may be able to make the float_regs pass more tolerant of missing higher-order insts in the future. Class method calls do not use float registers because I didn't want to deal with them yet. compiler/options.m: compiler/handle_options.m: Always enable float registers in low-level C grades when floats are wider than a word. compiler/make_hlds_passes.m: Always allow double word floats to be stored unboxed in cells on C grades. compiler/hlds_goal.m: Add an extra field to `generic_call' which gives the register class to use for each argument. This is set by the float_regs pass. compiler/prog_data.m: Add an extra field to `pred_inst_info' which records the register class to use for each argument. This is set by the float_regs pass. compiler/hlds_pred.m: Add a field to `proc_sub_info' which lists the headvars which must be passed via regular registers despite their types. Add a field to `pred_sub_info' to record the original unsubstituted argument types for instance method predicates. compiler/check_typeclass.m: In the pred_info of an instance method predicate, record the original argument types before substituting the type variables for the instance. compiler/float_regs.m: compiler/transform_hlds.m: Add the new HLDS pass. compiler/mercury_compile_middle_passes.m: Run the new pass if float registers are enabled. compiler/lambda.m: Export the predicate to produce a predicate from a lambda. This is reused by float_regs.m to create wrapper closures. Add an argument to `expand_lambda' to set the reg_r_headvars field on the newly created procedure. Delete some unused fields from `lambda_info'. compiler/arg_info.m: Make `generate_proc_arg_info' no longer always use regular registers for calls to exported procedures. Do always use regular registers for class methods calls. Add a version of `make_arg_infos' which takes an explicit list of argument registers. Rename the previous version. Add `generic_call_arg_reg_types' to return the argument registers for a generic call. Add a version of `compute_in_and_out_vars' which additionally separates arguments for float and regular registers. compiler/call_gen.m: Use float registers for argument passing in higher-order calls, as directed by the new field in `generic_call'. compiler/code_util.m: Add a function to encode the number of regular and float register arguments when making a higher-order call. compiler/llds.m: Say that the `do_call_closure_N' functions only work for zero float register arguments. compiler/follow_vars.m: compiler/interval.m: Account for the use of float registers by generic call goals in these passes. compiler/unify_gen.m: Move float register arguments to the end of a closure's hidden arguments vector, after regular register arguments. Count hidden regular and float register arguments separately, but encode them in the same word in the closure. This is preferable to using two words because it reduces the differences between grades with and without float registers present. Disable generating code which creates a closure from an existing closure, if float registers exist. That code does not understand the reordered hidden arguments vector yet. compiler/continuation_info.m: Replace an argument's type_info in the closure layout if the argument is a float *and* is passed via a regular register, when floats are normally passed via float registers. Instead, give it the type_info for `private_builtin.float_box'. compiler/builtin_lib_types.m: Add function to return the type of `private_builtin.float_box/0'. compiler/hlds_out_goal.m: compiler/hlds_out_pred.m: compiler/mercury_to_mercury.m: Dump the new fields added to `generic_call', `pred_inst_info' and `proc_sub_info'. compiler/prog_type.m: Add helper predicate. compiler/*.m: Conform to changes. library/private_builtin.m: Add a type `float_box'. runtime/mercury_ho_call.h: Describe the modified closure representation. Rename the field which counts the number of hidden arguments to prevent it being used incorrectly, as it now encodes two numbers (potentially). Add macros to unpack the encoded field. runtime/mercury_ho_call.c: Update the description of how higher-order calls work. Update code which extracts closure arguments to take account the arguments being reordered in the hidden arguments vector. runtime/mercury_deep_copy.c: runtime/mercury_deep_copy_body.h: runtime/mercury_layout_util.c: runtime/mercury_ml_expand_body.h: Update code which extracts closure arguments to take account the arguments being reordered in the hidden arguments vector. runtime/mercury_type_info.c: runtime/mercury_type_info.h: Add helper function. tools/make_spec_ho_call: Update the generated do_call_closure_* functions to place float register arguments. tests/hard_coded/Mercury.options: tests/hard_coded/Mmakefile: tests/hard_coded/ho_float_reg.exp: tests/hard_coded/ho_float_reg.m: Add new test case. tests/hard_coded/copy_pred.exp: tests/hard_coded/copy_pred.m: tests/hard_coded/deconstruct_arg.exp: tests/hard_coded/deconstruct_arg.exp2: tests/hard_coded/deconstruct_arg.m: Extend test cases with float arguments in closures. tests/debugger/higher_order.exp2: Add alternative output, changed due to closure wrapping. tests/hard_coded/ho_univ_to_type.m: Adjust test case so that the float_regs pass does not report errors about missing higher-order insts. compiler/notes/compiler_design.html: Describe the new module. Delete a duplicated paragraph. compiler/notes/todo.html: TODO: Delete one hundred billion year old todos. |
||
|
|
585c1d623c |
Fix a problem with from_ground_term scopes.
Estimated hours taken: 20 Branches: main Fix a problem with from_ground_term scopes. When they are built, the scopes are tentantively marked as from_ground_term_construct scopes, and the unifications inside them are in a top down order. Mode analysis therefore expected the unifications inside from_ground_term_construct scopes to have that order. The problem was that mode analysis, when it confirmed that a from_ground_term scope is indeed a from_ground_term_construct scope, itself reversed the order of the unifications, putting them in a bottom up order. When mode analysis is reinvoked, either for unique mode checking, or after cse_detection finds common subexpressions, this meant that mode analysis found the unifications in the "wrong" order, and therefore disregarded the scope, discarding all its performance benefits. This diff separates out the two notions that we previously conflated. The scope kind from_ground_term_construct now refers only to scopes which are definitely known to construct ground terms. We can know that only after mode analysis. Until then, from_ground_term scopes are now marked as from_ground_term_initial. The two kinds have different though overlapping sets of invariants; in particular, they promise different orderings of the unifications in the scope. This diff reduces the time needed to compile mas_objects.data.m from about 221 seconds to about 8. compiler/hlds_goal.m: Add the from_ground_term_initial kind. Document the invariants that each kind of from_ground_term scope promises. compiler/superhomogeneous.m: Mark from_ground_term scopes initially as from_ground_term_initial, not from_ground_term_construct. compiler/post_typecheck.m: Make the predicate that converts function calls that look like unifications (such as X = int.min) into actual function calls say whether it performed such a conversion. compiler/purity.m: Use the new functionality in post_typecheck.m to convert from_ground_term_initial scopes into from_ground_term_other scopes if the conversion of a unification into a call means that we have to break an invariant expected of from_ground_term_initial scopes. compiler/cse_detection.m: compiler/switch_detection.m: Maintain the invariants we now expect of from_ground_term_deconstruct scopes. compiler/modecheck_goal.m: Maintain the invariants we now expect of the different from_ground_term scopes. Avoid traversing such scopes if a previous invocation of mode analysis says we can. Optimize away from_ground_term_construct scopes if the variable being constructed is not needed later. compiler/quantification.m: If the variable named in a from_ground_term_initial or from_ground_term_construct scope is not referred to outside the scope, set the nonlocals set of the scope to empty, which allows later compiler passes to optimize it away. Avoid some unnecessary work by the compiler. compiler/add_trail_ops.m: compiler/closure_analysis.m: compiler/constraint.m: compiler/dead_proc_elim.m: compiler/deep_profile.m: compiler/deforest.m: compiler/delay_construct.m: compiler/delay_partial_inst.m: compiler/dep_par_conj.m: compiler/dependency_graph.m: compiler/exception_analysis.m: compiler/follow_code.m: compiler/follow_vars.m: compiler/goal_form.m: compiler/goal_util.m: compiler/granularity.m: compiler/inlining.m: compiler/interval.m: compiler/lambda.m: compiler/lco.m: compiler/middle_rec.m: compiler/mode_util.m: compiler/parallel_to_plain.m: compiler/simplify.m: compiler/stm_expand.m: compiler/stratify.m: compiler/tabling_analysis.m: compiler/term_pass1.m: compiler/try_expand.m: compiler/tupling.m: compiler/untupling.m: compiler/unused_args.m: Avoid traversing from_ground_term_deconstruct scopes in cases where the invariants that now hold (mainly the absence of anything but deconstruct unifications) make such traversals unnecessary. compiler/live_vars.m: compiler/liveness.m: compiler/structure_reuse.lbu.m: Add comments about exploiting from_ground_term_deconstruct scopes. compiler/det_analysis.m: compiler/hlds_out_goal.m: compiler/polymorphism.m: compiler/saved_vars.m: compiler/unique_modes.m: Handle from_ground_term_initial scopes. compiler/handle_options.m: Add a dump verbosity option that is useful for comparing HLDS dumps created by two different compilers. compiler/type_util.m: Minor speedup. compiler/mode_info.m: compiler/modecheck_conj.m: compiler/prog_data.m: compiler/rbmm.region_transformation.m: compiler/typecheck.m: Improve documentation. |
||
|
|
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. |
||
|
|
9ae7fe6b70 |
Change the argument ordering of predicates in the set module.
Branches: main Change the argument ordering of predicates in the set module. library/set.m: Change predicate argument orders to match the versions in the svset module. Group function definitions with the corresponding predicates rather than at the end of the file. Delete Ralph's comments regarding the argument order in the module interface: readers of the library reference guide are unlikely to be interested in his opinion of the argument ordering ten or so years ago. Add extra modes for set.map/3 and set.map_fold/5. library/svset.m: library/eqvclass.m: library/tree234.m: library/varset.m: browser/*.m: compiler/*.m: deep_profiler/*.m: mdbcomp/trace_counts.m: extras/moose/grammar.m: extras/moose/lalr.m: extras/moose/moose.m: tests/hard_coded/bitset_tester.m: Conform to the above change. NEWS: Announce the above changes. |
||
|
|
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.
|
||
|
|
022b559584 |
Make error messages for require_complete_switch scopes report the missing
Estimated hours taken: 8 Branches: main Make error messages for require_complete_switch scopes report the missing functors. Knowing which functors are missing requires knowing not only the set of functors in the switched-on variable's type, but also which of these functors have been eliminated by earlier tests, which requires having the instmap at the point of entry to the switch. Simplification, which initially detected unmet require_complete_switch requirements, does not have the instmap, and threading the instmap through it would make it significantly less efficient. So instead we now detect any problems with require_complete_switch scopes (and require_detism scopes, which are similar) during determinism checking. compiler/det_report.m: Factor out the code for finding the missing functors in conventional determinism errors, to allow it to be used for this new purpose. Check whether the requirements of require_complete_switch and require_detism scopes are met IF the predicate has any such scopes. compiler/det_analysis.m: compiler/det_util.m: Record whether the predicate has any such scopes. compiler/hlds_pred.m: Add a predicate marker that allows this recording. compiler/simplify.m: Delete the code that checks the require_complete_switch and require_detism scopes. Keep the code that deletes those scopes. (We have to do that here because determinism error reporting never updates the goal). compiler/prog_out.m: Delete an unused predicate. compiler/*.m: Remove unnecesary imports as flagged by --warn-unused-imports. |
||
|
|
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. |
||
|
|
543fc6e342 |
Change the way the typechecker iterates over the predicates of the program.
Estimated hours taken: 12 Branches: main Change the way the typechecker iterates over the predicates of the program. We used to do it by looking up each predicate in the module_info, typechecking it, and putting it back into the module_info. We now do it by converting the predicate table into a list, iterating over the list transforming each pred_info in it, converting the updated list back to a predicate table. The original intention of this change was to allow different predicates to be typechecked in parallel by removing a synchronization bottleneck: the typechecking of a predicate now doesn't have to wait for the typechecking of the previous predicate to generate the updated version of the module_info. However, it turned out that the change is good for sequential execution as well, improving the time on tools/speedtest from 11.33 seconds to 11.08 seconds, a speedup of 2.2%. On tools/speedtest -l, which tests the compilation of more modules, the speedup is even better: 3.1% (from 32.63 to 31.60s). compiler/typecheck.m: Implement the above change. compiler/hlds_module.m: compiler/pred_table.m: Add a new operation, setting the list of valid pred_ids, now needed by typecheck.m, to both modules. Make the names of the predicates for accessing the predicate table more expressive, and make them conform to our naming conventions. compiler/*.m: Trivial changes to conform to the change in hlds_module.m. library/assoc_list.m: Add new predicates used by the new version of typecheck.m (at some time in its development). NEWS: Mention the new predicates. library/list.m: Improve documentation that is now copied to assoc_list.m. tools/speedtest: Make the test command more easily configurable. |
||
|
|
cc1711071e |
Make all the pre-HLDS and front-end passes of the compiler gather up
Estimated hours taken: 50 Branches: main Make all the pre-HLDS and front-end passes of the compiler gather up all their error messages and print them all at once, in sorted order, unless the user asked for progress messages, in which case we print all the errors accumulated so far just before each printing each progress message. This should make error message output significantly easier to interpret. compiler/module_imports.m: Add a new field to the module_imports structure (the main pre-HLDS representation of the parse tree) to hold the list of error messages generated so far. Rename the module_imports structure as the module_and_imports structure, since it holds the module's items as well as information about its imports. Update the access predicates to encourage getting the items, the error messages and the error indication all at once. Add mechanisms for updating the error indication and the error messages. Add a distinguishing prefix to the field names of the structure. compiler/error_util.m: compiler/hlds_error_util.m: Add facilities for printing error messages in batches. In error_util.m, delete an unused argument from several predicates. compiler/mercury_compile.m: compiler/intermod.m: Gather up error messages to print in batches. In the parts of the code affected by the above, explicitly pass around a globals structure, instead of having all the predicates get it of the I/O state. Since some code (e.g. the start recompilation system) still uses the copy in the I/O state, we ensure that this copy is kept in sync with the explicitly passed around copy. Rename some predicates to avoid ambiguities. compiler/modules.m: Return errors in the module_and_imports structure, not separately. Gather up error messages to print in batches. Explicitly pass around globals structures. compiler/read_modules.m: Rename the read_modules type to have_read_module_map, since this is more explicit. For each module we have already read, remember not just the items we read from it, but also the error messages we generated during the reading. This is so these error messages can be printed together with other errors from other sources. Explicitly pass around globals structures. compiler/prog_io.m: compiler/purity.m: compiler/stratify.m: Rename several predicates to avoid ambiguities. compiler/modes.m: Change the interface of the main predicate to avoid the need for a lambda expression in mercury_compile.m. compiler/recompilation.check.m: Add a distinguishing prefix to the field names of a structure. Fix a wrong definition of this_file. Conform to the changes above. compiler/compiler_target_code.m: compiler/deps_map.m: compiler/make.m: compiler/make.dependencies.m: compiler/make.module_dep_file.m: compiler/make.module_target.m: compiler/make.program_target.m: compiler/make.util.m: compiler/make_hlds.m: compiler/make_hlds_passes.m: compiler/trans_opt.m: compiler/write_deps_file.m: Conform to the changes above. compiler/add_clause.m: compiler/add_pragma.m: compiler/state_var.m: Add an import of io, since their parent make_hlds.m does not import io anymore. In add_pragma, update an error message that did not mention trseg as well as tr as indicating a trailing grade. tests/hard_coded/Mmakefile: Move two tests that cannot pass in debug grades due to the lack of tail recursion to the list containing the other tests with this property. tests/invalid/test_feature_set.err_exp: Update the expected output of this test to expect the updated error message from add_pragma. tests/invalid/test_feature_set.err_exp2: Add this file as the expected output for trailing grades. tests/invalid/*.err_exp: tests/warnings/*.err_exp: Update the expected output for many tests to expect the error messages in sorted order. |
||
|
|
0329ea98ec |
Make all the front-end passes that do not currently return errors as a
Estimated hours taken: 3 Branches: main Make all the front-end passes that do not currently return errors as a list of error specifications do so. Use trace goals to print progress and debugging messages. compiler/implementation_defined_literals.m: compiler/inst_check.m: compiler/polymorphism.m: compiler/simplify.m: compiler/stratify.m: compiler/switch_detection.m: compiler/try_expand.m: Effect the change described above. In stratify.m, replace some booleans with purpose-specific types. compiler/error_util.m: Add support for inst_check.m's new needs. compiler/passes_aux.m: Update the traversal alternative used by simplify to meet simplify's new needs. compiler/mercury_compile.m: Conform to the changes above. Amongst other things, this means printing the error specifications returned by the various passes. compiler/structure_sharing.analysis.m: Conform to the changes above. compiler/prop_mode_constraints.m: Minor style cleanups. tests/warnings/inst_with_no_type.exp: Expect the new, properly sorted output. |
||
|
|
d69ba1a1f0 |
Include the type_ctor in cons_ids for user-defined types.
Estimated hours taken: 32 Branches: main Include the type_ctor in cons_ids for user-defined types. The intention is two-fold: - It prepares for a future in which we allow more than one function symbol to with the same name to be defined in a module. - It makes the HLDS code more self-contained. In many places, processing construction and deconstruction unifications required knowing which type the cons_id belongs to, but until now, code couldn't know that unless it kept track of the type of the variable unified with the cons_id. With this diff, user-defined cons_ids are represented as cons(SymName, Arity, TypeCtor) The last field is filled in during post-typecheck. After that time, any module qualification in the SymName (which may initially be partial) is redundant, since it is also available in the TypeCtor. In the future, we could make all those SymNames be just unqualified(_) at that time. We could also replace the current maps in HLDS type definitions with full cons_id keys with just name/arity keys (since the module qualifier is a given for any given type definition), we could also support partially qualified cons_ids in source code using a map from name/arity pairs to a list of all the type_ctors that have function symbols with that name/arity, instead of our current practice of inserting all possible partially module qualified version of every cons_id into a single giant table, and we could do the same thing with the field names table. This diff also separates tuples out from user-defined types, since in many respects they are different (they don't have a single type_ctor, for starters). It also separates out character constants, since they were alreay treated specially in most places, though not in some places where they *ought* to have been treated specially. Take the opportunity to give some other cons_ids better names. compiler/prog_data.m: Make the change described above, and document it. Put the implementations of the predicates declared in each part of this module next to the declarations, instead of keeping all the code until the very end (where it was usually far from their declarations). Remove three predicates with identical definitions from inst_match.m, inst_util.m and mode_constraints.m, and put the common definition in prog_data.m. library/term_io.m: Add a new predicate that is basically a reversible version of the existing function espaced_char, since the definition of char_consts needs reversibilty. compiler/post_typecheck.m: For functors of user-defined types, record their type_ctor. For tuples and char constants, record them as such. compiler/builtin_lib_types.m: compiler/parse_tree.m: compiler/notes/compiler_design.html: New module to centralize knowledge about builtin types, specially handled library types, and their function symbols. Previously, the stuff now in this module used to be in several different places, including prog_type.m and stm_expand.m, and some of it was duplicated. mdbcomp/prim_data.m: Add some predicates now needed by builtin_lib_types.m. compiler/builtin_ops.m: Factor out some duplicated code. compiler/add_type.m: Include the relevant type_ctors in the cons_ids generated in type definitions. compiler/hlds_data.m: Document an existing type better. Rename a cons_tag in sync with its corresponding cons_id. Put some declarations into logical order. compiler/hlds_out.m: Rename a misleadingly-named predicate. compiler/prog_ctgc.m: compiler/term_constr_build.m: Add XXXs for questionable existing code. compiler/add_clause.m: compiler/add_heap_ops.m: compiler/add_pragma.m: compiler/add_pred.m: compiler/add_trail_ops.m: compiler/assertion.m: compiler/bytecode_gen.m: compiler/closure_analysis.m: compiler/code_info.m: compiler/complexity.m: compiler/ctgc_selector.m: compiler/dead_proc_elim.m: compiler/deep_profiling.m: compiler/delay_partial_inst.m: compiler/dependency_graph.m: compiler/det_analysis.m: compiler/det_report.m: compiler/distance_granularity.m: compiler/erl_rtti.m: compiler/erl_unify_gen.m: compiler/export.m: compiler/field_access.m: compiler/foreign.m: compiler/format_call.m: compiler/hhf.m: compiler/higher_order.m: compiler/hlds_code_util.m: compiler/hlds_desc.m: compiler/hlds_goal.m: compiler/implementation_defined_literals.m: compiler/inst_check.m: compiler/inst_graph.m: compiler/inst_match.m: compiler/inst_util.m: compiler/instmap.m: compiler/intermod.m: compiler/interval.m: compiler/lambda.m: compiler/lco.m: compiler/make_tags.m: compiler/mercury_compile.m: compiler/mercury_to_mercury.m: compiler/middle_rec.m: compiler/ml_closure_gen.m: compiler/ml_code_gen.m: compiler/ml_code_util.m: compiler/ml_switch_gen.m: compiler/ml_type_gen.m: compiler/ml_unify_gen.m: compiler/ml_util.m: compiler/mlds_to_c.m: compiler/mlds_to_java.m: compiler/mode_constraints.m: compiler/mode_errors.m: compiler/mode_ordering.m: compiler/mode_util.m: compiler/modecheck_unify.m: compiler/modes.m: compiler/module_qual.m: compiler/polymorphism.m: compiler/prog_ctgc.m: compiler/prog_event.m: compiler/prog_io_util.m: compiler/prog_mode.m: compiler/prog_mutable.m: compiler/prog_out.m: compiler/prog_type.m: compiler/prog_util.m: compiler/purity.m: compiler/qual_info.m: compiler/rbmm.add_rbmm_goal_infos.m: compiler/rbmm.execution_path.m: compiler/rbmm.points_to_analysis.m: compiler/rbmm.region_transformation.m: compiler/recompilation.usage.m: compiler/rtti.m: compiler/rtti_out.m: compiler/rtti_to_mlds.m: compiler/simplify.m: compiler/simplify.m: compiler/special_pred.m: compiler/ssdebug.m: compiler/stack_opt.m: compiler/stm_expand.m: compiler/stratify.m: compiler/structure_reuse.direct.detect_garbagem: compiler/superhomoegenous.m: compiler/switch_detection.m: compiler/switch_gen.m: compiler/switch_util.m: compiler/table_gen.m: compiler/term_constr_build.m: compiler/term_norm.m: compiler/try_expand.m: compiler/type_constraints.m: compiler/type_ctor_info.m: compiler/type_util.m: compiler/typecheck.m: compiler/typecheck_errors.m: compiler/unify_gen.m: compiler/unify_proc.m: compiler/unify_modes.m: compiler/untupling.m: compiler/unused_imports.m: compiler/xml_documentation.m: Minor changes, mostly to ignore the type_ctor in cons_ids in places where it is not needed, take the type_ctor from the cons_id in places where it is more convenient, conform to the new names of some cons_ids, conform to the changes in hlds_out.m, and/or add now-needed imports of builtin_lib_types.m. In some places, the handling previously applied to cons/2 (which included tuples and character constants as well as user-defined function symbols) is now applied only to user-defined function symbols or to user-defined function symbols and tuples, as appropriate, with character constants being handled more like the other kinds of constants. In inst_match.m, rename a whole bunch of predicates to avoid ambiguities. In prog_util.m, remove two predicates that did almost nothing yet were far too easy to misuse. |
||
|
|
cc8923b7f7 |
Add support for `try' goals, syntactic sugar on top of the exception handling
Branches: main Add support for `try' goals, syntactic sugar on top of the exception handling predicates in the standard library. The syntax is documented in the reference manual. Currently one of the proposed try parameters, io(!IO), is implemented. Try goals are implemented by *two* source-to-source transformations, one at the parse tree level, then a later one on the HLDS. The reason for this is given in try_expand.m. library/ops.m: Add three new operators: try, catch, catch_any. library/exception.m: Add forwarding predicates so that code generated by the try goal transformation doesn't need to import `univ'. compiler/prog_item.m: Add representations of try goals to parse tree. compiler/prog_io_goal.m: Parse try goals. Unrelated: fix spelling of "parameter". compiler/add_clause.m: Perform the initial transformation on try goals. compiler/hlds_goal.m: Add try goals to HLDS, as shorthand goals. compiler/try_expand.m: New module to perform the latter transformation on try goals. compiler/check_hlds.m: Import the new module. compiler/mercury_compile.m: Call the try_expand pass near the end of the front-end pass. compiler/module_imports.m: Implicitly import `exception' if a `try' goal is seen. compiler/det_analysis.m: Conform to addition of try goals in HLDS. Make it not wrap a commit scope around the intermediate try goal (as it might if there are no outputs) as it is inappropriate. compiler/prog_util.m: Conform to parse tree changes. compiler/assertion.m: compiler/build_mode_constraints.m: compiler/cse_detection.m: compiler/delay_partial_inst.m: compiler/dependency_graph.m: compiler/det_report.m: compiler/equiv_type_hlds.m: compiler/format_call.m: compiler/goal_form.m: compiler/goal_path.m: compiler/goal_util.m: compiler/hlds_out.m: compiler/intermod.m: compiler/lambda.m: compiler/make_hlds_warn.m: compiler/mercury_to_mercury.m: compiler/mode_util.m: compiler/modes.m: compiler/module_qual.m: compiler/ordering_mode_constraints.m: compiler/polymorphism.m: compiler/post_typecheck.m: compiler/prop_mode_constraints.m: compiler/purity.m: compiler/quantification.m: compiler/simplify.m: compiler/stm_expand.m: compiler/stratify.m: compiler/structure_reuse.lfu.m: compiler/switch_detection.m: compiler/type_constraints.m: compiler/typecheck.m: compiler/unique_modes.m: compiler/unused_imports.m: Conform to changes in HLDS. compiler/il_peephole.m: compiler/ilasm.m: compiler/ilds.m: compiler/mlds_to_il.m: Rename some symbols to avoid the new keywords. library/exception.m: Add two helper predicates for the try goal transformations. doc/reference_manual.texi: NEWS: Document and announce the new language feature. compiler/notes/compiler_design.html: Note new compiler module. tests/hard_coded/Mmakefile: tests/hard_coded/try_syntax_1.exp: tests/hard_coded/try_syntax_1.m: tests/hard_coded/try_syntax_2.exp: tests/hard_coded/try_syntax_2.m: tests/hard_coded/try_syntax_3.exp: tests/hard_coded/try_syntax_3.m: tests/hard_coded/try_syntax_4.exp: tests/hard_coded/try_syntax_4.m: tests/hard_coded/try_syntax_5.exp: tests/hard_coded/try_syntax_5.m: tests/hard_coded/try_syntax_6.exp: tests/hard_coded/try_syntax_6.m: tests/hard_coded/try_syntax_7.exp: tests/hard_coded/try_syntax_7.m: tests/invalid/Mmakefile: tests/invalid/try_bad_params.err_exp: tests/invalid/try_bad_params.m: tests/invalid/try_io_else.err_exp: tests/invalid/try_io_else.m: Add test cases. tests/debugger/declarative/catch.m: The module name is now a keyword so requires brackets. tests/invalid/trace_goal_env.err_exp: Update test case for fixed spelling for "parameter". vim/syntax/mercury.vim: Add try, catch, catch_any as keywords. |
||
|
|
edda5238a1 |
Fix two bugs preventing the use of or_else alternatives to atomic
transaction scopes and nested atomic scopes.
The main issue was the code assuming that the inner stm interface variables
were the same for the main goal and the or_else goals, but quantification
renames these variables to be distinct.
library/stm_builtin.m
Rename stm_from_outer_to_inner_io and stm_from_inner_to_outer_io, dropping
the _io suffix. They are used when the outer type is stm as well as io.
compiler/hlds_goal.m
Add a field to the atomic_goal structure to hold the names of the STM
interface variables used in each or_else alternative, since quantification
renames these variables to be distinct from those used in the main atomic
goal.
compiler/purity.m
Insert calls to the (renamed) dummy predicates stm_from_outer_to_inner and
stm_from_inner_to_outer regardless of the type of the outer variable,
instead of using the nonexistent stm_from_*_to_*_stm versions when the
outer type is stm. Also use the inner STM interface variables specific to
each or_else alternative when generating these calls.
compiler/quantification.m
Explicitly rename the inner STM interface variables in each of the or_else
alternatives before calling implicitly_quantify_disj, so that the new names
of these variables can be stored in the atomic_goal structure.
compiler/typecheck.m
Ensure all the inner STM interface variables are typed stm, not just the
ones in the main goal.
compiler/add_clause.m
compiler/assertion.m
compiler/build_mode_constraints.m
compiler/cse_detection.m
compiler/delay_partial_inst.m
compiler/dependency_graph.m
compiler/det_analysis.m
compiler/det_report.m
compiler/equiv_type_hlds.m
compiler/format_call.m
compiler/goal_form.m
compiler/goal_path.m
compiler/goal_util.m
compiler/hlds_out.m
compiler/intermod.m
compiler/lambda.m
compiler/make_hlds_warn.m
compiler/mode_util.m
compiler/modes.m
compiler/ordering_mode_constraints.m
compiler/polymorphism.m
compiler/post_typecheck.m
compiler/prop_mode_constraints.m
compiler/simplify.m
compiler/stm_expand.m
compiler/stratify.m
compiler/structure_reuse.lfu.m
compiler/switch_detection.m
compiler/unique_modes.m
compiler/unused_imports.m
Updated to reflect the extra field in atomic_goal.
|
||
|
|
5ad9a27793 |
Speed up the compiler's handling of code that constructs large ground terms
Estimated hours taken: 80
Branches: main
Speed up the compiler's handling of code that constructs large ground terms
by specializing the treatment of such code.
This diff reduces the compilation time for training_cars_full.m from 106.9
seconds to 30.3 seconds on alys, my laptop. The time on tools/speedtest
stays pretty much the same.
compiler/hlds_goal.m:
Record the classification of from_ground_term scopes as purely
constructing terms, purely deconstructing them or something other.
Fix an old potential bug: variables inside the construct_how fields
of unifications weren't being renamed along with other variables.
This is a bug if any part of the compiler later looks at those
variables. (I am not sure whether or not this happens.)
compiler/superhomogenous.m:
Provisionally mark newly constructed static terms as being
from_ground_term_construct. Mode checking will either confirm this
or change the scope kind.
compiler/options.m:
compiler/handle_options.m:
Add a new option, from_ground_term_threshold, that allows the user to
set the boundary between ground terms that get scopes and ground terms
do not. I plan to experiment with different settings later.
compiler/modes.m:
Make this classification. For scopes that construct ground terms,
use a specialized algorithm that avoids quadratic behavior.
(It does not access the unify_inst_table, which is where the
factor of N other than the length of the goal list came from.)
The total size of the instmap_deltas, if printed out, still looks like
O(N^2) in size, but due to structure sharing it needs only O(N) memory.
For scopes that construct ground terms, set the determinism information
so that det_analysis.m doesn't have to traverse such scopes.
When handling disjunctions, check whether some nonlocals of the
disjunctions are constructed by from_ground_term_construct scopes.
For any such nonlocals, set their insts to just ground, throwing away
the precise information we have about exactly what function symbols
they and ALL their subterms are bound to. This is HUGE win, since
it allows us avoid spending a lot of time building a huge merge_inst
table, which later passes of the compiler (e.g. equiv_type_hlds) would
then have to spend similarly huge times traversing.
This approach does have a down side. If lots of arms of a disjunction
bind a nonlocal to a large ground term, but a few bind it to a SMALL
ground term, a term below the from_ground_term_threshold, this
optimization won't kick in. That could be one purpose of the new
option. It isn't documented yet; I will seek feedback about its
usefulness first.
compiler/modecheck_unify.m:
Handle the three different kinds of right hand sides separately.
This yields a small speedup, because now we don't test rhs_vars and
rhs_functors (the common right hand sides) for a special case
(goals containing "any" insts) that is applicable only to
rhs_lambda_goals.
compiler/unique_modes.m:
Don't traverse scopes that construct ground terms, since modes.m has
already done everything that needs to be done.
compiler/det_analysis.m:
Don't traverse scopes that construct ground terms, since modes.m has
already done the needed work.
compiler/instmap.m:
Add a new predicate for use by modes.m.
Many predicate names in this module were quite uninformative; give them
informative names.
compiler/polymorphism.m:
If this pass invalidates the from_ground_term_construct invariants,
then mark the relevant scope as from_ground_term_other.
Delete two unused access predicates.
compiler/equiv_type_hlds.m:
Don't traverse scopes that construct ground terms, since modes.m
ensures that their instmap deltas do not contain typed insts, and
thus the scope cannot contain types that need to be expanded.
Convert some predicates to single clauses.
compiler/goal_form.m:
compiler/goal_util.m:
In predicates that test goals for various properties, don't traverse
scopes that construct ground terms when the outcome of the test
is the same for all such scopes.
Convert some predicates to single clauses.
compiler/simplify.m:
Do not look for common structs in from_ground_term_construct scopes,
both because this speeds up the compiler, and because retaining
references to ground terms is in fact a pessimization, not an
optimization. This is because (a) those references need to be stored in
stack slots across calls, and (b) the C code generators ensure that
the cells representing ground terms will be shared as needed.
If all arms of a switch are from_ground_term_construct scopes,
do not merge the instmap_deltas from those arms, since this is
both time-consuming (even after the other changes in this diff)
and extremely unlikely to improve the instmap_delta.
Disable common_struct in from_ground_term_construct scopes,
since for these scopes, it is actually a pessimization.
Do not delete from_ground_term_construct scopes, since many
compiler passes can now use them.
Do some manual deforestation, break up some large predicates,
and give better names to some.
compiler/liveness.m
Special-case the handling from_ground_term_construct scopes. This
allows us to traverse them just once instead of three times, and this
traversal is simpler and faster than any of the three.
In some traversals, we were switching on the goal type twice; once
in e.g. detect_liveness_in_goal_2, and once by calling
goal_expr_has_subgoals. Eliminate the double switching by merging
the relevant predicates. (The double-switching structure was easier
to work with before we had multi-cons-id switches.)
compiler/typecheck.m:
Move a lookup after a test, so we don't have to do it if the test
fails.
Provide a specialized mode for a predicate. This should allow the
compiler to eliminate an argument and a test in the common case.
Note a possible chance for a speedup.
compiler/typecheck_info.m:
Don't apply empty substitutions to the types of a possibly very large
set of variables.
compiler/quantification.m:
Don't quantify from_ground_term_construct scopes. They are created
correctly quantified, and any compiler pass that invalidates that
quantification also removes the from_ground_term_construct mark.
Don't apply empty renamings to a possibly very large set of variables.
Move the code for handling scopes to its own predicate, to avoid
overwhelming the code that handles other kinds of goals. Even from
this, factor out the renaming code, since it is needed only for
some kinds of scopes.
Make some predicate names better reflect what the predicate does.
compiler/pd_cost.m:
For from_ground_term_construct scopes, instead of computing their cost
by adding up the costs of the goals inside, make their cost a constant,
since binding a variable to a static term takes constant time.
compiler/pd_info.m:
Add prefixes on field names to avoid ambiguities.
compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/closure_analysis.m:
compiler/constraint.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/exception_analysis.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/granularity.m:
compiler/higher_order.m:
compiler/implicit_parallelism.m:
compiler/inlining.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/loop_inv.m:
compiler/middle_rec.m:
compiler/mode_util.m:
compiler/parallel_to_plain_conj.m:
compiler/saved_vars.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/stratify.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.lbu.m:
compiler/structure_sharing.analysis.m:
compiler/switch_detection.analysis.m:
compiler/trail_analysis.m:
compiler/term_pass1.m:
compiler/tupling.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
These passes have nothing to do in from_ground_term_construct scopes,
so don't traverse them.
In some modules (e.g. dead_proc_elim), some traversals had to be kept.
In loop_inv.m, replace a code structure that updated accumulators
with functions (which prevented the natural use of state variables),
that in lots of places reconstructed the term it had just
deconstructed, and obscured the identical handling of different kinds
of goals, with a structure based on predicates, state variables and
shared code for different goal types where possible.
In store_alloc.m, avoid some double switching on the same value.
In stratify.m, unneeded_code.m and unused_args.m, rename predicates
to avoid ambiguities.
compiler/goal_path.m:
compiler/goal_util.m:
compiler/implementation_defined_literals.m:
compiler/intermode.m:
compiler/mark_static_terms.m:
compiler/ml_code_gen.m:
compiler/mode_ordering.m:
compiler/ordering_mode_constraints.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/rbmm.actual_region_arguments.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.condition_renaming.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.region_transformation.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lfu.m:
compiler/structure_reuse.versions.m:
compiler/term_const_build.m:
compiler/term_traversal.m:
compiler/unused_imports.m:
Mark places where we cannot (yet) special case
from_ground_term_construct scopes.
In structure_reuse.lfu.m, turn nested if-then-elses into a switch in.
compiler/size_prof.m:
Turn from_ground_term_construct scopes into from_ground_term_other
scopes, since in term size profiling grades, we need to attach sizes to
terms.
Give predicates better names.
compiler/*.m:
Minor changes to conform to the changes above.
compiler/make_hlds_passes.m:
With -S, print statistics after the third pass over items, since
this is the time-consuming one.
compiler/mercury_compile.m:
Conform to the new names of some predicates.
When declining to output a HLDS dump because it would be identical to
the previous dump, don't confuse the user either by being silent about
the decision, or by leaving an old dump laying around that could be
mistaken for a new one.
tools/binary:
tools/binary_step:
Bring these tools up to date.
compiler/Mmakefile:
Add an int3s target for use by the new code in the tools. The
Mmakefiles in the other directories with Mercury code already have
such a target.
compiler/notes/allocation.html:
Fix an out-of-date reference.
tests/debugger/polymorphic_ground_term.{m,inp,exp}:
New test case to check whether liveness.m handles typeinfo liveness
of ground terms correctly.
tests/debugger/Mmakefile:
Enable the new test case.
tests/debugger/polymorphic_output.{m,exp}:
Fix tab/space mixup.
|
||
|
|
b000cb322e |
Provide compiler support for Software Transactional Memory through the new
Estimated hours taken: 80 by zs, and lots more by lmika Branches: main Provide compiler support for Software Transactional Memory through the new atomic goal. This work was done by Leon Mika; I merely brought it up to date, resolved conflicts, and cleaned up a few things. There are still several aspects that are as yet incomplete. library/ops.m: Add the operators needed for the syntax of atomic scopes. library/stm_builtin.m: Add the builtin operations needed for the implementation of atomic goals. compiler/hlds_goal.m: Add a new HLDS goal type, which represents an atomic goal and its possible fallbacks (in case an earlier goal throws an exception). Rename the predicate goal_is_atomic as goal_expr_has_subgoals, since now its old name would be misleading. compiler/prog_data.m: compiler/prog_item.m: Add a parse tree representation of the new kind of goal. compiler/prog_io_goal.m: Parse the new kind of goal. compiler/add_clause.m: Translate atomic goals from parse tree form to HLDS. compiler/typecheck.m: compiler/typecheck_errors.m: Do type checking of atomic goals. compiler/modes.m: Do mode checking of atomic goals, and determine whether they are nested or not. compiler/unique_modes.m: Do unique mode checking of atomic goals. compiler/stm_expand.m: New module to expand atomic goals into sequences of simpler goals. library/stm_builtin.m: Add the primitives needed by the transformation. Improve the existing debugging support. mdbcomp/prim_data.m: Add utility functions to allow stm_expand.m to refer to modules in the library. mdbcomp/program_representation.m: Expand the goal_path type to allow the representation of components of atomic goals. compiler/notes/compiler_design.html: Document the new module. compiler/transform_hlds.m: Include the new module in the compiler. compiler/mercury_compile.m: Invoke the STM transformation. compiler/hlds_module.m: Add an auxiliary counter used by the STM transformation. compiler/hlds_pred.m: Add a new predicate origin: the STM transformation. compiler/modules.m: Import the STM builtin module automatically if the module contains any atomic goals. compiler/assertion.m: compiler/bytecode_gen.m: compiler/clause_to_proc.m: compiler/code_gen.m: compiler/code_info.m: compiler/code_util.m: compiler/constraint.m: compiler/cse_detection.m: compiler/deep_profiling.m: compiler/code_util.m: compiler/delay_construct.m: compiler/delay_partial_inst.m: compiler/dep_par_conj.m: compiler/dependency_graph.m: compiler/det_analysis.m: compiler/det_report.m: compiler/distance_granularity.m: compiler/equiv_type_hlds.m: compiler/erl_code_gen.m: compiler/exception_analysis.m: compiler/follow_code.m: compiler/format_call.m: compiler/goal_form.m: compiler/goal_path.m: compiler/goal_util.m: compiler/granularity.m: compiler/hlds_out.m: compiler/implicit_parallelism.m: compiler/inlining.m: compiler/intermod.m: compiler/lambda.m: compiler/layout_out.m: compiler/lco.m: compiler/lookup_switch.m: compiler/make_hlds_warn.m: compiler/mark_static_terms.m: compiler/mercury_to_mercury.m: compiler/middle_rec.m: compiler/ml_code_gen.m: compiler/mode_constraint_robdd.m: compiler/mode_constraints.m: compiler/mode_errors.m: compiler/mode_info.m: compiler/mode_util.m: compiler/ordering_mode_constraints.m: compiler/pd_cost.m: compiler/pd_util.m: compiler/polymorphism.m: compiler/post_typecheck.m: compiler/prog_rep.m: compiler/prog_type.m: compiler/prop_mode_constraints.m: compiler/rbmm.actual_region_arguments.m: compiler/rbmm.add_rbmm_goal_info.m: compiler/rbmm.condition_renaming.m: compiler/rbmm.execution_path.m: compiler/rbmm.points_to_analysis.m: compiler/rbmm.region_transformation.m: compiler/saved_vars.m: compiler/simplify.m: compiler/size_prog.m: compiler/smm_common.m: compiler/structure_reuse.direct.choose_reuse.m: compiler/structure_reuse.direct.detect_garbage.m: compiler/structure_reuse.indirect.m: compiler/structure_reuse.lbu.m: compiler/structure_reuse.lfu.m: compiler/structure_reuse.versions.m: compiler/structure_sharing.analysis.m: compiler/switch_detection.m: compiler/unused_imports.m: compiler/granularity.m: compiler/granularity.m: Conform to the changes above. Mostly this means handling the new kind of goal. compiler/add_heap_ops.m: compiler/add_trail_ops.m: compiler/build_mode_constraints.m: compiler/closure_analysis.m: compiler/dead_proc_elim.m: compiler/deforest.m: compiler/follow_vars.m: compiler/higher_order.m: compiler/live_vars.m: compiler/liveness.m: compiler/loop_inv.m: compiler/module_qual.m: compiler/prog_util.m: compiler/purity.m: compiler/quantification.m: compiler/store_alloc.m: compiler/stratify.m: compiler/tabling_analysis.m: compiler/term_constr_build.m: compiler/term_pass1.m: compiler/term_traversal.m: compiler/trailing_analysis.m: Conform to the changes above. Mostly this means handling the new kind of goal. Switch syntax from clauses to disj. runtime/mercury_stm.[ch]: Implement the primitives needed by the STM transformation. Add more debugging support to the existing primitives. library/term.m: Generalize get_term_context to work on terms of all kinds. |
||
|
|
7460aadbf8 |
Implement higher-order any' insts. Pred or func expressions with an any'
Estimated hours taken: 100 Branches: main Implement higher-order `any' insts. Pred or func expressions with an `any' inst may bind non-local solver variables, but themselves must not be called in a negated context. (The existing ground pred and func expressions may not bind non-local solver variables, but may be called in a negated context.) Higher-order `any' insts are specified by using `any_pred' and `any_func' in place of `pred' and `func', respectively. We implement these insts by adding a new field to the any/1 constructor of mer_inst, which is identical to the ground_inst_info field of the ground/2 constructor. Both are given the new type `ho_inst_info'. We then relax the locking of non-local variables in these pred and func expressions, and extend call/N and apply/N to also accept the new insts (provided the variables are not locked). We also store the groundness (ho_ground or ho_any) of each lambda expression in a unification, in a new field in the rhs_lambda_goal constructor. NEWS: Mention the new feature. compiler/prog_data.m: Rename the ground_inst_info type ho_inst_info, and update its documentation. Add the ho_inst_info field to the any constructor in mer_inst. compiler/hlds_goal.m: Add the rhs_groundness field to rhs_lambda_goal in unify_rhs. compiler/inst_match.m: Propagate inst matching into the pred_inst_infos of any insts, if they exist. compiler/inst_util.m: Propagate abstract unification and inst merging into the pred_inst_infos of any insts, if they exist. May use of this information when building ground, any, shared and mostly_unique versions of insts. compiler/modecheck_call.m: Allow an `any' inst as the pred (func) argument to call/N (apply/N), but check that the variable is not locked. If the variable is locked, report a mode error which suggests using the ground inst. (We could also suggest that the goal be made impure, but it is best to point users towards the pure approach.) compiler/modecheck_unify.m: Relax the locking of non-locals when processing non-ground lambda goals. Update documentation. compiler/mode_util.m: Propagate type information into the pred_inst_infos of any insts. compiler/mode_errors.m: Change the purity error "lambda should be impure" to "lambda should be any", since this is better advice. Also provide an example of correct syntax if the verbose errors option is given. compiler/prog_io_goal.m: Parse the new kinds of expressions, returning the groundness along with the existing information about lambda expressions. compiler/superhomogeneous.m: Use the above groundness when building the lambda unification. compiler/prog_io_util.m: Parse the new kind of insts, filling in the new ho_inst_info field where appropriate. compiler/polymorphism.m: Handle the new fields. Assume that the shorthand form of lambda expressions always defines a ground inst -- if users want non-ground higher-order expressions they will need to use an explicit any_pred or any_func expression. compiler/equiv_type_hlds.m: Replace equivalent types in the pred_inst_infos of `any' insts. compiler/module_qual.m: Module qualify the pred_inst_infos of `any' insts. compiler/recompilation.usage.m: compiler/unused_imports.m: Look for items or imports used by insts in the pred_inst_infos of `any' insts. compiler/hlds_out.m: compiler/mercury_to_mercury.m: Output the new lambda expressions and insts in the correct format. compiler/type_util.m: Treat all pred and func types as solver types. (Effectively they are, since all such types can now have non-ground values, with call/N and apply/N acting as constraints.) compiler/lambda.m: Pass the groundness value when building procedures for lambda expressions. This is not currently required for anything. doc/reference_manual.texi: Document the new feature, and update existing documentation on solver types and negated contexts. tests/valid/Mmakefile: tests/valid/ho_any_inst.m: New test case for some valid code using higher-order any insts. tests/invalid/Mmakefile: tests/invalid/ho_any_inst.err_exp: tests/invalid/ho_any_inst.m: New test case for some illegal code. tests/invalid/anys_in_negated_contexts.err_exp: Update expected error message for this test case. We now report that the expression should be `any', rather than impure. compiler/*.m: Handle the new fields. |
||
|
|
9ad83d648d |
Convert predicates that used to have one clause for each kind of
Estimated hours taken: 12 Branches: main compiler/*.m: Convert predicates that used to have one clause for each kind of HLDS goal into explicit disjunctions, since this gives the debugger a meaningful name for each argument. In some cases, this exposed arguments that were used by *no* clause. In other cases, it allowed factoring out common code, as well as code that *should* have been common but wasn't. Put the disjuncts in a meaningful order. In too many cases, they were almost random. Merge the resulting predicates into their parents, in places where the Prolog indexing one could get from separate clauses was the only reason for separating those predicates from their parents in the first place. Similarly, merge child predicates handling generic call kinds and such back into the main predicate where this improves clarity. In some cases, this allows putting the extraction of hlds_goal_expr from a hlds_goal into one place, instead of repeating it in lots of places. Give some predicates more descriptive names. In some cases, rationalize argument order. In some cases, rationalize the order of predicates in the module. Replace some uses of booleans with purpose-specific types. Give some fields names, and put type-identifying prefixes on the names of other fields, to make tag files work better. In some cases, reorder fields to them put into related groups. Use more standard and/or more descriptive variable names Use a standard syntax for if-then-else in each module. Follow our style convention for comments. |
||
|
|
cc88711d63 |
Implement true multi-cons_id arm switches, i.e. switches in which we associate
Estimated hours taken: 40
Branches: main
Implement true multi-cons_id arm switches, i.e. switches in which we associate
more than one cons_id with a switch arm. Previously, for switches like this:
(
X = a,
goal1
;
( X = b
; X = c
),
goal2
)
we duplicated goal2. With this diff, goal2 won't be duplicated. We still
duplicate goals when that is necessary, i.e. in cases which the inner
disjunction contains code other than a functor test on the switched-on var,
like this:
(
X = a,
goal1
;
(
X = b,
goalb
;
X = c
goalc
),
goal2
)
For now, true multi-cons_id arm switches are supported only by the LLDS
backend. Supporting them on the MLDS backend is trickier, because some MLDS
target languages (e.g. Java) don't support the concept at all. So when
compiling to MLDS, we still duplicate the goal in switch detection (although
we could delay the duplication to just before code generation, if we wanted.)
compiler/options.m:
Add an internal option that tells switch detection whether to look for
multi-cons_id switch arms.
compiler/handle_options.m:
Set this option based on the back end.
Add a version of the "trans" dump level that doesn't print unification
details.
compiler/hlds_goal.m:
Extend the representation of switch cases to allow more than one
cons_id for a switch arm.
Add a type for representing switches that also includes tag information
(for use by the backends).
compiler/hlds_data.m:
For du types, record whether it is possible to speed up tests for one
cons_id (e.g. cons) by testing for the other (nil) and negating the
result. Recording this information once is faster than having
unify_gen.m trying to compute it from scratch for every single
tag test.
Add a type for representing a cons_id together with its tag.
compiler/hlds_out.m:
Print out the cheaper_tag_test information for types, and possibly
several cons_ids for each switch arm.
Add some utility predicates for describing switch arms in terms of
which cons_ids they are for.
Replace some booleans with purpose-specific types.
Make hlds_out honor is documentation, and not print out detailed
information about unifications (e.g. uniqueness and static allocation)
unless the right character ('u') is present in the control string.
compiler/add_type.m:
Fill in the information about cheaper tag tests when adding a du type.
compiler/switch_detection.m:
Extend the switch detection algorithm to detect multi-cons_id switch
arms.
When entering a switch arm, update the instmap to reflect that the
switched-on variable can now be bound only to the cons_ids that this
switch arm is for. We now need to do this, because if the arm contains
another switch on the same variable, computing the can_fail field of
that switch correctly requires us to know this information.
(Obviously, an arm for a single cons_id is unlikely to have switch on
the same variable, and for arms for several cons_ids, we previously
duplicated the arm and left the unification with the cons_id in each
copy, and this unification allowed the correct handling of any later
switches. However, the code of a multi-cons_id switch arm obviously
cannot have a unification with each cons_id in it, which is why
we now need to get the binding information from the switch itself.)
Replace some booleans with purpose-specific types, and give some
predicates better names.
compiler/instmap.m:
Provide predicates for recording that a switched-on variable has
one of several given cons_ids, for use at the starts of switch arms.
Give some predicates better names.
compiler/modes.m:
Provide predicates for updating the mode_info at the start of a
multi-cons_id switch arm.
compiler/det_report.m:
Handle multi-cons_id switch arms.
Update the instmap when entering each switch arm, since this is needed
to provide good (i.e. non-misleading) error messages when one switch on
a variable exists inside another switch on the same variable.
Since updating the instmap requires updating the module_info (since
the new inst may require a new entry in an inst table), thread the
det_info through as updateable state.
Replace some multi-clause predicate definitions with single clauses,
to make it easier to print the arguments in mdb.
Fix some misleading variable names.
compiler/det_analysis.m:
Update the instmap when entering each switch arm and thread the
det_info through as updateable state, since the predicates we call
in det_report.m require this.
compiler/det_util.m:
Handle multi-cons_id switch arms.
Rationalize the argument order of some access predicates.
compiler/switch_util.m:
Change the parts of this module that deal with string and tag switches
to optionally convert each arm to an arbitrary representation of the
arm. In the LLDS backend, the conversion process generated code for
the arm, and the arm's representation is the label at the start of
this code. This way, we can duplicate the label without duplicating
the code.
Add a new part of this module that associates each cons_id with its
tag, and (during the same pass) checks whether all the cons_ids are
integers, and if so what are min and max of these integers (needed
for dense switches). This scan is needed because the old way of making
this test had single-cons_id switch arms as one of its basic
assumptions, and doing it while adding tags to each case reduces
the number of traversals required.
Give better names to some predicates.
compiler/switch_case.m:
New module to handle the tasks associated with managing multi-cons_id
switch arms, including representing them for switch_util.m.
compiler/ll_backend.m:
Include the new module.
compiler/notes/compiler_design.html:
Note the new module.
compiler/llds.m:
Change the computed goto instruction to take a list of maybe labels
instead of a list of labels, with any missing labels meaning "not
reached".
compiler/string_switch.m:
compiler/tag_switch.m:
Reorganize the way these modules work. We can't generate the code of
each arm in place anymore, since it is now possible for more than one
cons_id to call for the execution of the same code. Instead, in
string_switch.m, we generate the codes of all the arms all at once,
and construct the hash index afterwards. (This approach simplifies
the code significantly.)
In tag switches (unlike string switches), we can get locality benefits
if the code testing for a cons_id is close to the code for that
cons_id, so we still try to put them next to each other when such
a locality benefit is available.
In both modules, the new approach uses a utility predicate in
switch_case.m to actually generate the code of each switch arm,
eliminating several copies the same code in the old versions of these
modules.
In tag_switch.m, don't create a local label that simply jumps to the
code address do_not_reached. Previously, we had to do this for
positions in jump tables that corresponded to cons_ids that the switch
variable could not be bound to. With the change to llds.m, we now
simply generate a "no" instead.
compiler/lookup_switch.m:
Get the info about int switch limits from our caller; don't compute it
here.
Give some variables better names.
compiler/dense_switch.m:
Generate the codes of the cases all at once, then assemble the table,
duplicate the labels as needed. This separation of concerns allows
significant simplifications.
Pack up all the information shared between the predicate that detects
whether a dense switch is appropriate and the predicate that actually
generates the dense switch.
Move some utility predicates to switch_util.
compiler/switch_gen.m:
Delete the code for tagging cons_ids, since that functionality is now
in switch_util.m.
The old version of this module could call the code generator to produce
(i.e. materialize) the switched-on variable repeatedly. We now produce
the variable once, and do the switch on the resulting rval.
compiler/unify_gen.m:
Use the information about cheaper tag tests in the type constructor's
entry in the HLDS type table, instead of trying to recompute it
every time.
Provide the predicates switch_gen.m now needs to perform tag tests
on rvals, as opposed to variables, and against possible more than one
cons_id.
Allow the caller to provide the tag corresponding to the cons_id(s)
in tag tests, since when we are generating code for switches, the
required computations have already been done.
Factor out some code to make all this possible.
Give better names to some predicates.
compiler/code_info.m:
Provide some utility predicates for the new code in other modules.
Give better names to some existing predicates.
compiler/hlds_code_util.m:
Rationalize the argument order of some predicates.
Replace some multi-clause predicate definitions with single clauses,
to make it easier to print the arguments in mdb.
compiler/accumulator.m:
compiler/add_heap_ops.m:
compiler/add_pragma.m:
compiler/add_trail_ops.m:
compiler/assertion.m:
compiler/build_mode_constraints.m:
compiler/check_typeclass.m:
compiler/closure_analysis.m:
compiler/code_util.m:
compiler/constraint.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/dupproc.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/foreign.m:
compiler/format_call.m:
compiler/frameopt.m:
compiler/goal_form.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/implicit_parallelism.m:
compiler/inlining.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lambda.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/livemap.m:
compiler/liveness.m:
compiler/llds_out.m:
compiler/llds_to_x86_64.m:
compiler/loop_inv.m:
compiler/make_hlds_warn.m:
compiler/mark_static_terms.m:
compiler/middle_rec.m:
compiler/ml_tag_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/mode_util.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/pd_cost.m:
compiler/pd_into.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/purity.m:
compiler/quantification.m:
compiler/rbmm.actual_region_arguments.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.condition_renaming.m:
compiler/rbmm.execution_paths.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.usage.m:
compiler/saved_vars.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/store_alloc.m:
compiler/stratify.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/tupling.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches.
compiler/ml_string_switch.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches.
Give some predicates better names.
compiler/dependency_graph.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches. Change the order of arguments
of some predicates to make this easier.
compiler/bytecode.m:
compiler/bytecode_data.m:
compiler/bytecode_gen.m:
Make the changes necessary to conform to the changes above, principally
to handle multi-cons_id arm switches. (The bytecode interpreter
has not been updated.)
compiler/prog_rep.m:
mdbcomp/program_representation.m:
Change the byte sequence representation of goals to allow switch arms
with more than one cons_id. compiler/prog_rep.m now writes out the
updated representation, while mdbcomp/program_representation.m reads in
the updated representation.
deep_profiler/mdbprof_procrep.m:
Conform to the updated program representation.
tools/binary:
Fix a bug: if the -D option was given, the stage 2 directory wasn't
being initialized.
Abort if users try to give that option more than once.
compiler/Mercury.options:
Work around bug #32 in Mantis.
|
||
|
|
672f77c4ec |
Add a new compiler option. --inform-ite-instead-of-switch.
Estimated hours taken: 20 Branches: main Add a new compiler option. --inform-ite-instead-of-switch. If this is enabled, the compiler will generate informational messages about if-then-elses that it thinks should be converted to switches for the sake of program reliability. Act on the output generated by this option. compiler/simplify.m: Implement the new option. Fix an old bug that could cause us to generate warnings about code that was OK in one duplicated copy but not in another (where a switch arm's code is duplicated due to the case being selected for more than one cons_id). compiler/options.m: Add the new option. Add a way to test for the bug fix in simplify. doc/user_guide.texi: Document the new option. NEWS: Mention the new option. library/*.m: mdbcomp/*.m: browser/*.m: compiler/*.m: deep_profiler/*.m: Convert if-then-elses to switches at most of the sites suggested by the new option. At the remaining sites, switching to switches would have nontrivial downsides. This typically happens with the switched-on type has many functors, and we treat one or two specially (e.g. cons/2 in the cons_id type). Perform misc cleanups in the vicinity of the if-then-else to switch conversions. In a few cases, improve the error messages generated. compiler/accumulator.m: compiler/hlds_goal.m: (Rename and) move insts for particular kinds of goal from accumulator.m to hlds_goal.m, to allow them to be used in other modules. Using these insts allowed us to eliminate some if-then-elses entirely. compiler/exprn_aux.m: Instead of fixing some if-then-elses, delete the predicates containing them, since they aren't used, and (as pointed out by the new option) would need considerable other fixing if they were ever needed again. compiler/lp_rational.m: Add prefixes to the names of the function symbols on some types, since without those prefixes, it was hard to figure out what type the switch corresponding to an old if-then-else was switching on. tests/invalid/reserve_tag.err_exp: Expect a new, improved error message. |
||
|
|
0dfb9c4874 |
New module for directed graphs. This is essentially the relation
Estimated hours taken: 12
Branches: main
library/digraph.m:
New module for directed graphs. This is essentially the relation
module but with more consistent terminology, and with argument
ordering that suits state variables. Other differences with the
relation module:
- The digraph_key type has a phantom type parameter, which helps to
ensure that keys from one digraph are not used with another digraph.
- Exports a version of digraph.reduced which also returns the mapping
between the original digraph keys and the new ones.
- The implementation of compose/3 doesn't try to use the "domain" and
"range" of the graphs (which is meaningless in the relation module
anyway).
- New, more efficient algorithm for is_dag/1. Correctness proof is
documented.
- components/2 uses a more efficient data representation, and avoids
some intermediate data structures.
- reduced/{2,3} avoids some intermediate data structures.
- tc/2 avoids some intermediate data structures.
library/library.m:
Add the new module.
library/relation.m:
Document that this module is deprecated in favour of digraph.
Flag relation.init/{0,1} as obsolete (it would be better to flag
the entire module, or the relation/1 type as obsolete, but Mercury
does not support this).
NEWS:
Mention that the new module supersedes relation.m and svrelation.m.
compiler/*.m:
profiler/*.m:
Use the digraph module rather than the relation module.
|
||
|
|
168f531867 |
Add new fields to the goal_info structure for region based memory management.
Estimated hours taken: 4 Branches: main Add new fields to the goal_info structure for region based memory management. The fields are currently unused, but (a) Quan will add the code to fill them in, and then (b) I will modify the code generator to use the filled in fields. compiler/hlds_goal.m: Make the change described above. Group all the procedures that access goal_info components together. Some of the getters were predicates while some were functions, so this diff changes them all to be functions. (The setters remain predicates.) compiler/*.m: Trivial changes to conform to the change in hlds_goal.m. In simplify.m, break up a huge (800+ line) predicate into smaller pieces. |
||
|
|
b56885be93 |
Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail.
Estimated hours taken: 12 Branches: main Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail. The problem was not in lco.m, but in follow_code.m. In some cases, (specifically, the LCMC version of insert_2 in sparse_bitset.m), follow_code.m moved an impure goal (store_at_ref) into the arms of an if-then-else without marking those arms, or the if-then-else, as impure. The next pass, simplify, then deleted the entire if-then-else, since it had no outputs. (The store_at_ref that originally appeared after the if-then-else was the only consumer of its only output.) The fix is to get follow_code.m to make branched control structures such as if-then-elses, as well as their arms, semipure or impure if a goal being moved into them is semipure or impure, or if they came from an semipure or impure conjunction. Improve the optimization of the LCMC version of sparse_bitset.insert_2, which had a foreign_proc invocation of bits_per_int in it: replace such invocations with a unification of the bits_per_int constant if not cross compiling. Add a new option, --optimize-constructor-last-call-null. When set, LCMC will assign NULLs to the fields not yet filled in, to avoid any junk happens to be there from being followed by the garbage collector's mark phase. This diff also makes several other changes that helped me to track down the bug above. compiler/follow_code.m: Make the fix described above. Delete all the provisions for --prev-code; it won't be implemented. Don't export a predicate that is not now used anywhere else. compiler/simplify.m: Make the optimization described above. compiler/lco.m: Make sure that the LCMC specialized procedure is a predicate, not a function: having a function with the mode LCMC_insert_2(in, in) = in looks wrong. To avoid name collisions when a function and a predicate with the same name and arity have LCMC applied to them, include the predicate vs function status of the original procedure included in the name of the new procedure. Update the sym_name of calls to LCMC variants, not just the pred_id, because without that, the HLDS dump looks misleading. compiler/pred_table.m: Don't have optimizations like LCMC insert new predicates at the front of the list of predicates. Maintain the list of predicates in the module as a two part list, to allow efficient addition of new pred_ids at the (logical) end without using O(N^2) algorithms. Having predicates in chronological order makes it easier to look at HLDS dumps and .c files. compiler/hlds_module.m: Make module_info_predids return a module_info that is physically updated though logically unchanged. compiler/options.m: Add --optimize-constructor-last-call-null. Make the options --dump-hlds-pred-id, --debug-opt-pred-id and --debug-opt-pred-name into accumulating options, to allow the user to specify more than one predicate to be dumped (e.g. insert_2 and its LCMC variant). Delete --prev-code. doc/user_guide.texi: Document the changes in options.m. compiler/code_info.m: Record the value of --optimize-constructor-last-call-null in the code_info, to avoid lookup at every cell construction. compiler/unify_gen.m: compiler/var_locn.m: When deciding whether a cell can be static or not, make sure that we never make static a cell that has some fields initialized with dummy zeros, to be filled in for real later. compiler/hlds_out.m: For goals that are semipure or impure, note this fact. This info was lost when I changed the representation of impurity from markers to a field. mdbcomp/prim_data.m: Rename some ambiguous function symbols. compiler/intermod.m: compiler/trans_opt.m: Rename the main predicates (and some function symbols) of these modules to avoid ambiguity and to make them more expressive. compiler/llds.m: Don't print line numbers for foreign_code fragments if the user has specified --no-line-numbers. compiler/make.dependencies.m: compiler/mercury_to_mercury.m: compiler/recompilation.usage.m: Don't use io.write to write out information to files we may need to parse again, because this is vulnerable to changes to the names of function symbols (e.g. the one to mdbcomp/prim_data.m). The compiler still contains some uses of io.write, but they are for debugging. I added an item to the todo list of the one exception, ilasm.m. compiler/recompilation.m: Rename a misleading function symbol name. compiler/parse_tree.m: Don't import recompilation.m here. It is not needed (all the components of parse_tree that need recompilation.m already import it themselves), and deleting the import avoids recompiling almost everything when recompilation.m changes. compiler/*.m: Conform to the changes above. compiler/*.m: browser/*.m: slice/*.m: Conform to the change to mdbcomp. library/sparse_bitset.m: Use some better variable names. |