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.
Estimated hours taken: 0.5
Branches: main
Replace more if-then-elses with switches (particularly on the
type builtin_state/0).
compiler/cse_detection.m:
compiler/deep_profiling.m:
compiler/dependency_graph.m:
compiler/follow_vars.m:
compiler/goal_form.m:
compiler/interval.m:
compiler/live_vars.m:
compiler/lp_rational.m:
compiler/pd_cost.m:
compiler/simplify.m:
compiler/tupling.m:
As above.
Estimated hours taken: 2
Branches: main
In several places, we used to use substitutions in which the substituted terms
had to be variables. This diff replaces those substitutions with simple
variable renamings, which can be used without the gymnatics that used to
be required to convert the resulting terms back into variables.
library/varset.m:
Supplement predicates that return substitutions in which the
replacement terms are always variables with predicates that return
the same information as variable renamings. Add a comment asking people
to use the new versions. (They aren't marked as obsolete yet).
compiler/prog_util.m:
Remove the substitute_vars predicate, which applied substitutions
whose range was restricted to variables.
compiler/prog_data.m:
Move predicates for applying renamings to non-HLDS data structures
here from hlds_goal.m, and add other predicates for performing
renamings to replace the functionality deleted from prog_util.m.
Replace a bool specifying whether every variable needs to be renamed
with a purpose-specific type.
compiler/hlds_goal.m:
Delete the predicates moved to prog_data.m.
compiler/*.m:
Conform to the changes above.
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.
Estimated hours taken: 2
Branches: main
Rearrange the fields of the goal_info structure in preparation for new
additions by Quan.
By making sure that the main hlds_goal_info type has only eight fields,
not ten, we get a 2% speedup on our usual compiler benchmark (since it avoids
having the Boehm allocator rounding up the cell size to 16 words). The moved
fields (the context and the info for constraint based mode analysis) are now
in the extra_goal_info subterm.
In the process of making this change, I noticed that the code to rename
variables in goals and goal_infos had three separate but related bugs:
- it did not rename variables in ctgc_infos in hlds_goal_infos
- it did not rename variables in mode_constraint_infos in hlds_goal_infos
- it did not rename variables in complicated_unifies in hlds_goal_exprs
This diff fixes those bugs. To avoid unnecessary inefficiency in the fixed code
and to make such bugs much less likely in the future, this diff also moves the
code for renaming variables in goals and goal_infos from goal_util to
hlds_goal.
The bug fix reduces the speedup to 1.1%, but this is still a good deal.
compiler/hlds_goal.m:
Make the changes described above.
compiler/goal_util.m:
Delete the stuff moved to hlds_goal.m, as well as an old unused
predicate.
compiler/quantification.m:
compiler/make_hlds_warn.m:
Delay extracting the context from goal_infos until it is needed
in the creation of an error message. This is useful since contexts
have been moved from the main hlds_goal_info structure to the
extra_goal_info substructure. In make_hlds_warn.m, this change
also allows us to pass around one fewer argument (the context arguments
were redundant, since we also always passed the goal_info that they
came from).
(The three other pieces of code that are responsible for most of the
calls to goal_info_get_context are the parts of the type checker, mode
checker and unique mode checker that conditionally update the current
context in e.g. the typecheck_info. Unfortunately, this technique of
delay-the-extraction cannot be applied to them.)
compiler/*.m:
Conform to the move of the rename predicates, mostly by deleting
unnecessary module qualifications.
Estimated hours taken: 48.
Branch: main.
Add an HLDS->HLDS transformation that implements region-based memory management.
This involves:
- adding calls to region builtin predicates for creating and removing regions.
- adding extra region arguments to procedure arguments and call sites.
- annotating construction unifications with information about which region a term
should be constructed in.
compiler/rbmm.region_transformation.m:
New file.
Transform the HLDS with region information to prepare for code
generation.
compiler/hlds_goal.m:
Add another type constructor for how_to_construct to allow
constructing terms in regions.
compiler/goal_util.m
compiler/hlds_out.m
compiler/ml_unify_gen.m
compiler/interval.m
compiler/structure_reuse.indirect.m
Simple change to suit with the above additional type constructor.
compiler/quantification.m
Change to suit with the additional type constructor.
compiler/rbmm.condition_renaming.m:
Change the algorithm so that the transformation needed to solve the
problem with if-then-else is derived after the region annotated
program has been transformed for solving the region resurrection
problem. This is needed because the solution to region resurrection
problem may introduce bindings of non-local region variables inside
the condition of if-then-elses.
compiler/rbmm.execution_path.m:
Correct a typo.
compiler/rbmm.m:
Add a new submodule region_transformation.
Call to region_transform to actually update the HLDS with region
information.
compiler/rbmm.region_resurrection_renaming.m:
Provide better comments. Reordering some predicates to suit with
the flow of computation.
compiler/rbmm.actual_region_arguments.m:
Before actual region arguments at a call site is returned in one group.
Now they are separated into "in" and "out" groups.
Estimated hours taken: 0.5
Branches: main
Switch on the how_to_construct/0 type in more places. This makes
it easier to identify places that may need to be updated when that
type changes.
compiler/interval.m:
compiler/quantification.m:
compiler/structure_reuse.indirect.m:
Replaces if-then-elses with switches.
Estimated hours taken: 2
Branches: main
Eliminate some code duplication by unifying the two goal_path types have had
until now: one in mdbcomp/program_representation.m and compiler/hlds_goal.m,
which differed in only one detail (whether we record the total number of arms
in a switch). The new type is in program_representation.m, but with the
definition from goal_path.m.
Add a "step_" prefix to the function symbols of the goal_path_step type,
to avoid ambiguity with the hlds goals the steps describe.
Turn the predicates operating on goal_paths into functions for greater
convenience of use.
mdbcomp/program_representation.m:
compiler/hlds_goal.m:
Make the change described above.
browser/*.m:
compiler/*.m:
mdbcomp/*.m:
slice/*.m:
Conform to the change above.
tests/debugger/*.exp:
Expect the extra information now available for goal path steps
describing switches.
Estimated hours taken: 10
Branches: main
This diff changes a few types from being defined as equivalent to a pair
to being discriminated union types with their own function symbol. This
was motivated by an error message (one of many, but the one that broke
the camel's back) about "-" being used in an ambiguous manner. It will
reduce the number of such messages in the future, and will make compiler
data structures easier to inspect in the debugger.
The most important type changed by far is hlds_goal, whose function symbol
is now "hlds_goal". Second and third in importance are llds.instruction
(function symbol "llds_instr") and prog_item.m's item_and_context (function
symbol "item_and_context"). There are some others as well.
In several places, I rearranged predicates to factor the deconstruction of
goals into hlds_goal_expr and hlds_goal_into out of each clause into a single
point. In many places, I changed variable names that used "Goal" to refer
to just hlds_goal_exprs to use "GoalExpr" instead. I also changed variable
names that used "Item" to refer to item_and_contexts to use "ItemAndContext"
instead. This should make reading such code less confusing.
I renamed some function symbols and predicates to avoid ambiguities.
I only made one algorithmic change (at least intentionally).
In assertion.m, comparing two goals for equality now ignores goal_infos
for all kinds of goals, whereas previously it ignored them for most kinds
of goals, but for shorthand goals it was insisting on them being equal.
This seemed to me to be a bug. Pete, can you confirm this?
Estimated hours taken: 2
Branches: main
Treat trace goals as quantifying the variables that occur in their io() and/or
state() components.
compiler/hlds_goal.m:
Extend trace scopes with a field for recording the set of quantified
variables.
compiler/add_clause.m:
Record the list of quantified variables.
compiler/quantification.m:
Treat the list of quantified variables as for other scopes.
compiler/hlds_out.m:
Write out the new field.
compiler/mercury_to_mercury.m:
Reorder the arguments of some predicates to make them easier to curry,
e.g. for the new code in hlds_out.m.
Rename some predicates to avoid ambiguities.
compiler/*.m:
Conform to the changes in hlds_goal.m and/or mercury_to_mercury.m.
tests/hard_coded/trace_goal_3.{m,exp}:
New test case to test the new functionality.
tests/hard_coded/Mmakefile:
Enable the new test case.
Estimated hours taken: 6
Branches: main
browser/*.m:
compiler/*.m:
Rename a bunch of predicates and function symbols to eliminate
ambiguities.
The only real change is factoring out some common code in the mlds
and llds code generators, replacing them with single definitions
in switch_util.m.
Estimated hours taken: 8
Branches: main
Get rid of a bunch more ambiguities by renaming predicates, mostly
in polymorphism.m, {abstract,build,ordering}_mode_constraints.m, prog_type.m,
and opt_debug.m in the compiler directory and term_io.m, term.m, parser.m,
and string.m in the library.
In some cases, when the library and the compiler defined the same predicate
with the same code, delete the compiler's copy and give it access to the
library's definition by exporting the relevant predicate (in the undocumented
part of the library module's interface).
NEWS:
Mention that the names of some library functions have changed.
library/*.m:
compiler/*.m:
mdbcomp/*.m:
browser/*.m:
Make the changes mentioned above, and conform to them.
test/general/string_test.m:
test/hard_coded/string_strip.m:
test/hard_coded/string_strip.exp:
Conform to the above changes.
Estimated hours taken: 1.5
Branches: main, release
Change the implementation of map.merge/3 so that it throws an exception if the
sets of keys of the input maps are not disjoint. This is more in keeping with
the documentation for that predicate which says they should be disjoint.
The existing implementation handled duplicate keys by inserting the key and
the smallest of the corresponding values into the output map. Some of the
code in the compiler seems to rely on this behaviour - this is (probably) a
bug but in at least in one instance, to do with merging RTTI varmaps
during higher-order specialisation, it's going to be a bit tricky to fix.
Rather than modify the compiler at the moment the old version of map.merge/3
is available as map.old_merge/3 and the compiler still uses this. (This
predicate is not included in the library reference manual.)
library/map.m:
Make map.merge/3 throw an exception if the sets of keys of the
input maps are not disjoint.
Add the implementor-only predicate map.old_merge/3 for use by the
compiler.
compiler/hlds_rtti.m:
compiler/interval.m:
compiler/prog_io.m:
compiler/tupling.m:
Conform to the above changes.
tests/hard_coded/map_merge_test.{m,exp}:
Test for the new behaviour.
tests/hard_coded/Makefile:
Don't run the above test in deep profiling grades since it
catches exceptions which the deep profiler cannot currently handle.
Estimated hours taken: 6
Branches: main
This diff contains no algorithmic changes. It merely renames apart a bunch more
function symbols to reduce ambiguity.
After this diff, the summary line from the mdb command "ambiguity -f" is
Total: 351 names used 975 times, maximum 31, average: 2.78
browser/*.m:
compiler/*.m:
Rename function symbols to eliminate ambiguities.
tests/debugger/declarative/dependency.exp:
tests/debugger/declarative/dependency2.exp:
Update the expected out where some internal function symbol names
appear in the output of the debugger. (This output is meant for
implementors only.)
Estimated hours taken: 70
Branches: main
Implement the trace goal construct we discussed, for now for the LLDS backends
only.
Since the syntax of trace goals is non-trivial, useful feedback on syntax
errors inside trace goal attributes is essential. With the previous setup, this
wasn't possible, since the code that turned terms into parse tree goals turned
*all* terms into goals; it couldn't recognize any errors, sweeping them under
the rug as calls. This diff changes that. Now, if this code recognizes a
keyword that indicates a particular construct, it insists on the rest of the
code following the syntax required for that construct, and returns error
messages if it doesn't.
We handle the trace goal attributes that specify state variables to be threaded
through the trace goal (either the I/O state or a mutable variable) in
add_clause.m, at the point at which we transform the list of items to the HLDS.
We handle the compile-time condition on trace goals in the invocation of
simplify at the end of semantics analysis, by eliminating the goal if the
compile-time condition isn't met. We handle run-time conditions on trace goals
partially in the same invocation of simplify: we transform trace goals with
runtime conditions into an if-then-else with the trace goal as the then part
and `true' as the else part, the condition being a foreign_proc that is handled
specially by the code generator, that special handling being to replace
the actual code of the foreign_proc (which is a dummy) with the evaluation of
the runtime condition.
Since these changes require significant changes to some of our key data
structures, I took the liberty of doing some renaming of function symbols
at the same time to avoid using ambiguities with respect to language keywords.
library/ops.m:
Add "trace" as an operator.
compiler/prog_data.m:
Define data types to represent the various attributes of trace goals.
Rename some function symbols to avoid ambiguities.
compiler/prog_item.m:
Extend the parse tree representation of goals with a trace goal.
compiler/mercury_to_mercury.m:
Output the new kind of goal and its components.
compiler/hlds_goal.m:
Extend the HLDS representation of scopes with a scope_reason
representing trace goals.
Add a mechanism (an extra argument in foreign_procs) to allow
the representation of goals that evaluate runtime trace conditions.
Since this requires modifying all code that traverses the HLDS,
do some renames that were long overdue: rename not as negation,
rename call as plain_call, and rename foreign_proc as
call_foreign_proc. These renames all avoid using language keywords
as function symbols.
Change the way we record goals' purities. Instead of optional features
to indicate impure or semipure, which is error-prone, use a plain
field in the goal_info, accessed in the usual way.
Add a way to represent that a goal contains a trace goal, and should
therefore be treated as if it were impure when considering whether to
optimize it away.
Reformat some comments describing function symbols.
compiler/hlds_out.m:
Output the new construct in the HLDS.
compiler/prog_io_util.m:
Generalize the maybe[123] types to allow the representation of more
than one error message. Add functions to extract the error messages.
Add a maybe4 type. Rename the function symbols of these types to
avoid massive ambiguity.
Change the order of some predicates to bring related predicates
next to each other.
compiler/prog_io.m:
compiler/prog_io_dcg.m:
compiler/prog_io_goal.m:
compiler/prog_io_pragma.m:
Rework these modules almost completely to find and accumulate syntax
errors as terms are being parsed. In some cases, this allowed us to
replace "XXX this is a hack" markers with meaningful error-reporting
code.
In prog_io_goal.m, add code for parsing trace goals.
In a bunch of places, update obsolete coding practices, such as using
nested chains of closures instead of simple sequential code, and
using A0 and A to refer to values of different types (terms and goals
respectively). Use more meaningful variable names.
Break up some too-large predicates.
compiler/superhomogeneous.m:
Find and accumulate syntax errors as terms are being parsed.
compiler/add_clause.m:
Add code to transform trace goals from the parse tree to the HLDS.
This is where the IO state and mutable variable attributes of trace
goals are handled.
Eliminate the practice of using the naming scheme Body0 and Body
to refer to values of different types (prog_item.goal and hlds_goal
respectively).
Use error_util for some error messages.
library/private_builtin.m:
Add the predicates referred to by the transformation in add_clause.m.
compiler/goal_util.m:
Rename a predicate to avoid ambiguity.
compiler/typecheck.m:
Do not print error messages about missing clauses if some errors have
been detected previously.
compiler/purity.m:
Instead of just computing purity, compute (and record) also whether
a goal contains a trace goal. However, treat trace goals as pure.
compiler/mode_info.m:
Add trace goals as a reason for locking variables.
Rename some function symbols to avoid ambiguity.
compiler/modes.m:
When analyzing trace goal scopes, lock the scope's nonlocal variables
to prevent them from being further instantiated.
compiler/det_analysis.m:
Insist on the code in trace goal scopes being det or cc_multi.
compiler/det_report.m:
Generate the error message if the code in a trace goal scope isn't det
or cc_multi.
compiler/simplify.m:
At the end of the front end, eliminate trace goal scopes if their
compile-time condition is false. Transform trace goals with runtime
conditions as described at the top.
Treat goals that contain trace goals as if they were impure when
considering whether to optimize them away.
compiler/mercury_compile.m:
Tell simplify when it is being invoked at the end of the front end.
Rename a predicate to avoid ambiguity.
compiler/trace_params.m:
Provide the predicates simplify.m need to be able to evaluate the trace
goal conditions regarding trace levels.
compiler/trace.m:
compiler/trace_gen.m:
Rename the trace module as trace_gen, since "trace" is now an operator.
Rename some predicates exported by the module, now that it is no longer
possible to preface calls with "trace." as a module qualifier.
compiler/notes/compiler_design.html:
Document this name change.
compiler/options.m:
Rename the trace option as trace_level internally, since "trace"
is now an operator. The user-visible name remains the same.
Add the new --trace-flag option.
Delete an obsolete option.
compiler/handle_options.m:
Rename the function symbols of the grade_component type,
since "trace" is now an operator.
compiler/llds.m:
Extend the LLDS with a mechanism to refer to C global variables.
For now, these are used to refer to C globals that will be created
by mkinit to represent the initial values of the environment variables
referred to by trace goals.
compiler/commit_gen.m:
Check that no trace goal with a runtime condition survives to code
generation; they should have been transformed by simplify.m.
compiler/code_gen.m:
Tell commit_gen.m what kind of scope it is generating code for.
compiler/pragma_c_gen.m:
Generate code for runtime conditions when handling the foreign_procs
created by simplify.m.
compiler/code_info.m:
Allow pragma_c_gen.m to record what environment variables it has
generated references to.
compiler/proc_gen.m:
Record the set of environment variables a procedure refers to
in the LLDS procedure header, for efficient access by llds_out.m.
compiler/llds_out.m:
Handle the new LLDS construct, and tell mkinit which environment
variables need C globals created for them.
compiler/pd_util.m:
Rename some predicates to avoid ambiguity.
compiler/*.m:
Conform to the changes above, mainly the renames of function symbols
and predicates, the changed signatures of some predicates, and the new
handling of purity.
util/mkinit.c:
Generate the definitions and the initializations of any C globals
representing the initial status (set or not set) of environment
variables needed by trace goals.
library/assoc_list.m:
Add some predicates that are useful in prog_io*.m.
library/term_io.m:
Minor cleanup.
tests/hard_coded/trace_goal_{1,2}.{m,exp}:
New test cases to test the new construct, identical except for whether
the trace goal is enabled at compile time.
tests/hard_coded/trace_goal_env_{1,2}.{m,exp}:
New test cases to test the new construct, identical except for whether
the trace goal is enabled at run time.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
Enable the new test cases.
tests/invalid/*.err_exp:
Update the expected output for the new versions of the error messages
now being generated.
Estimated hours taken: 3
Branches: main
Fix a bug reported by Peter Hawkins. The bug was that an predicate without
a declared determinism but whose inferred determinism was invalid for its
tabling declaration led to a compiler abort.
compiler/det_analysis.m:
Fix the main cause of the bug, which was that the check for the
compatibility of evaluation method and determinism was performed
only for predicates with declared determinisms, not those without.
Centralize the printing of determinism error messages, and sort
the messages first.
compiler/hlds_pred.m:
Fix the other half of the bug: the predicate that checked the
compatibility of evaluation method and determinism was too liberal
with minimal model predicates, letting through determinisms that the
tabling transformation cannot (yet) support.
compiler/det_report.m:
Fix the formatting of the error message.
compiler/prog_data.m:
Rename the function symbols of the type "determinism", to avoid
conflicts with language keywords.
compiler/*.m:
Conform to the change to prog_data.m.
tests/invalid/hawkins_mm_fail_reset.{m,err_exp}:
New test case for the bug being fixed.
tests/invalid/Mmakefile:
Enable the new test case.
tests/invalid/loopcheck.err_exp:
Expect the new format of the improved error message.
Estimated hours taken: 18
Branches: main
Move the univ, maybe, pair and unit types from std_util into their own
modules. std_util still contains the general purpose higher-order programming
constructs.
library/std_util.m:
Move univ, maybe, pair and unit (plus any other related types
and procedures) into their own modules.
library/maybe.m:
New module. This contains the maybe and maybe_error types and
the associated procedures.
library/pair.m:
New module. This contains the pair type and associated procedures.
library/unit.m:
New module. This contains the types unit/0 and unit/1.
library/univ.m:
New module. This contains the univ type and associated procedures.
library/library.m:
Add the new modules.
library/private_builtin.m:
Update the declaration of the type_ctor_info struct for univ.
runtime/mercury.h:
Update the declaration for the type_ctor_info struct for univ.
runtime/mercury_mcpp.h:
runtime/mercury_hlc_types.h:
Update the definition of MR_Univ.
runtime/mercury_init.h:
Fix a comment: ML_type_name is now exported from type_desc.m.
compiler/mlds_to_il.m:
Update the the name of the module that defines univs (which are
handled specially by the il code generator.)
library/*.m:
compiler/*.m:
browser/*.m:
mdbcomp/*.m:
profiler/*.m:
deep_profiler/*.m:
Conform to the above changes. Import the new modules where they
are needed; don't import std_util where it isn't needed.
Fix formatting in lots of modules. Delete duplicate module
imports.
tests/*:
Update the test suite to confrom to the above changes.
Estimated hours taken: 6
Branches: main
compiler/*.m:
Convert almost all the compiler modules to use . instead of __ as
the module qualifier.
In some cases, change the names of predicates and types to make them
meaningful without the module qualifier. In particular, most of the
types that used to be referred to with an "mlds__" prefix have been
changed to have a "mlds_" prefix instead of changing the prefix to
"mlds.".
There are no algorithmic changes.
Estimated hours taken: 5
Branches: main
Prepare for an extension of promise_equivalent_solutions that will allow us
to better handle values of user-defined types. The problem is that currently,
the deconstruction of a value of such a type can be followed only by code that
cannot fail, otherwise the cc_multi deconstruction is not in the required
single-solution context. If the following code is naturally semidet, this
can be worked around by turning it into det code returning a maybe and testing
the maybe outside the promise_equivalent_solutions, but this is inefficient,
and in any case it does not generalize to nondet code without even more
horrendous inefficiency and inconvenience. (You have to create a nondet closure
and call it outside the promise_equivalent_solutions.)
The solution I came up with is something is to have a construct that contains
- a list of deconstructions on types with user-defined equality,
- a goal, and
- the list of outputs of that goal.
The idea is that this would be transformed into a conjunction of the first and
second items, and wrapped inside a special kind of conj that provides a scope
for the implicit promise, which is that the set of solutions of the goal in
the second item doesn't depend on what concrete terms the deconstructions
in the first item return out of the set of concrete terms they *could* return.
The deconstructions in the first item would be marked to tell determinism
analysis to effectively ignore the fact that they involve user-defined
equality.
The actual addition of that construct is left for a future change, after we
agree on the syntax.
compiler/hlds_goal.m:
Generalize the existing promise_equivalent_solutions scope to a
promise_solutions scope with a flag that says whether in the source
code it was originally the existing "promise_equivalent_solutions"
construct or the new construct (which doesn't exist yet, but is
indicated by the symbol "same_solutions" for now).
Replace the conj and par_conj hlds_goal_exprs with a single goal
expression: conj with an additional argument which is either plain_conj
or parallel_conj. This was part of an earlier design in which a third
kind of disjunction took the role now assigned to the new kind of
promise_solutions scope, but turned out to be a good idea anyway,
since in many places the compiler does treat the two kinds of
conjunctions the same. This part of the change is responsible for the
fact that this change results in a net *reduction* of about 40 lines.
Move the most frequently used kinds of goal expressions to the front
of the type declaration to allow the compiler to make better decisions
about tag allocation.
Add the goal marker we will add to the deconstructions in the first
item.
Replace the true_goal and fail_goal predicates with functions to make
them easier to use, and rename their variants that take a context
argument to avoid unnecessary ambiguity.
compiler/*.m:
Conform to the change in hlds_goal.m.
Misc changes to make code more robust, e.g. replacing semidet
predicates on goal expressions with functions returning bool.
Misc cleanups, e.g. removal of unnecessary module qualifications
that made lines too long, renaming predicates whose names include
"disj" if they are also used to process parallel conjunctions (since in
both parallel conjunctions and in disjunctions the goals are
independent), and turning semidet predicates that switch on goal
expressions into bool functions (to make similar changes more rebust
in the future).
Estimated hours taken: 4
Branches: main
compiler/*.m:
Use expect/3 in place of require/2 throughout most of the
compiler.
Use unexpected/2 (or sorry/2) in place of error/1 in more
places.
Fix more dodgy assertion error messages.
s/map(prog_var, mer_type)/vartypes/ where the latter is meant.
Estimated hours taken: 4
Branches: main
Various cleanups for the modules in the compiler directory. The are
no changes to algorithms except the replacement of some if-then-elses
that would naturally be switches with switches and the replacement of
most of the calls to error/1.
compiler/*.m:
Convert calls to error/1 to calls to unexpected/2 or sorry/2 as
appropriate throughout most or the compiler.
Fix inaccurate assertion failure messages, e.g. identifying the
assertion failure as taking place in the wrong module.
Add :- end_module declarations.
Fix formatting problems and bring the positioning of comments
into line with our current coding standards.
Fix some overlong lines.
Convert some more modules to 4-space indentation. Fix some spots
where previous conversions to 4-space indentation have stuffed
the formatting of the code up.
Fix a bunch of typos in comments.
Use state variables in more places; use library predicates
from the sv* modules where appropriate.
Delete unnecessary and duplicate module imports.
Misc. other small cleanups.
Estimated hours taken: 6
Branches: main
Improve the error messages generated for determinism errors involving committed
choice contexts. Previously, we printed a message to the effect that e.g.
a cc pred is called in context that requires all solutions, but we didn't say
*why* the context requires all solutions. We now keep track of all the goals
to the right that could fail, since it is these goals that may reject the first
solution of a committed choice goal.
The motivation for this diff was the fact that I found that locating the
failing goal can be very difficult if the conjunction to the right is
a couple of hundred lines long. This would have been a nontrivial problem,
since (a) unifications involving values of user-defined types are committed
choice goals, and (b) we can expect uses of user-defined types to increase.
compiler/det_analysis.m:
Keep track of goals to the right of the current goal that could fail,
and include them in the error representation if required.
compiler/det_report.m:
Include the list of failing goals to the right in the representations
of determinism errors involving committed committed choice goals.
Convert the last part of this module that wasn't using error_util
to use error_util. Make most parts of this module just construct
error message specifications; print those specifications (using
error_util) in only a few places.
compiler/hlds_out.m:
Add a function for use by the new code in det_report.m.
compiler/error_util.m:
Add a function for use by the new code in det_report.m.
compiler/error_util.m:
compiler/compiler_util.m:
Error_util is still changing reasonably often, and yet it is
included in lots of modules, most of which need only a few simple
non-parse-tree-related predicates from it (e.g. unexpected).
Move those predicates to a new module, compiler_util.m. This also
eliminates some undesirable dependencies from libs to parse_tree.
compiler/libs.m:
Include compiler_util.m.
compiler/notes/compiler_design.html:
Document compiler_util.m, and fix the documentation of some other
modules.
compiler/*.m:
Import compiler_util instead of or in addition to error_util.
To make this easier, consistently use . instead of __ for module
qualifying module names.
tests/invalid/det_errors_cc.{m,err_exp}:
Add this new test case to test the error messages for cc contexts.
tests/invalid/det_errors_deet.{m,err_exp}:
Add this new test case to test the error messages for unifications
inside function symbols.
tests/invalid/Mmakefile:
Add the new test cases.
tests/invalid/det_errors.err_exp:
tests/invalid/magicbox.err_exp:
Change the expected output to conform to the change in det_report.m,
which is now more consistent.
Estimated hours taken: 8
Branches: main
Improve the error messages generated for determinism errors involving committed
choice contexts. Previously, we printed a message to the effect that e.g.
a cc pred is called in context that requires all solutions, but we didn't say
*why* the context requires all solutions. We now keep track of all the goals
to the right that could fail, since it is these goals that may reject the first
solution of a committed choice goal.
The motivation for this diff was the fact that I found that locating the
failing goal can be very difficult if the conjunction to the right is
a couple of hundred lines long. This would have been a nontrivial problem,
since (a) unifications involving values of user-defined types are committed
choice goals, and (b) we can expect uses of user-defined types to increase.
compiler/det_analysis.m:
Keep track of goals to the right of the current goal that could fail,
and include them in the error representation if required.
compiler/det_report.m:
Include the list of failing goals to the right in the representations
of determinism errors involving committed committed choice goals.
Convert the last part of this module that wasn't using error_util
to use error_util. Make most parts of this module just construct
error message specifications; print those specifications (using
error_util) in only a few places.
compiler/hlds_out.m:
Add a function for use by the new code in det_report.m.
compiler/error_util.m:
Add a function for use by the new code in det_report.m.
compiler/error_util.m:
compiler/compiler_util.m:
Error_util is still changing reasonably often, and yet it is
included in lots of modules, most of which need only a few simple
non-parse-tree-related predicates from it (e.g. unexpected).
Move those predicates to a new module, compiler_util.m. This also
eliminates some undesirable dependencies from libs to parse_tree.
compiler/libs.m:
Include compiler_util.m.
compiler/notes/compiler_design.html:
Document compiler_util.m, and fix the documentation of some other
modules.
compiler/*.m:
Import compiler_util instead of or in addition to error_util.
To make this easier, consistently use . instead of __ for module
qualifying module names.
tests/invalid/det_errors_cc.{m,err_exp}:
Add this new test case to test the error messages for cc contexts.
tests/invalid/det_errors_deet.{m,err_exp}:
Add this new test case to test the error messages for unifications
inside function symbols.
tests/invalid/Mmakefile:
Add the new test cases.
tests/invalid/det_errors.err_exp:
tests/invalid/magicbox.err_exp:
Change the expected output to conform to the change in det_report.m,
which is now more consistent.
Estimated hours taken: 8
Branches: main
compiler/*.m:
Rename the types 'type', 'inst' and 'mode' to 'mer_type', 'mer_inst'
and 'mer_mode'. This is to avoid the need to parenthesize these type
names in some contexts, and to prepare for the possibility of a parser
that considers those words to be reserved words.
Rename some other uses of those names (e.g. as item types in
recompilation.m).
Delete some redundant synonyms (prog_type, mercury_type) for mer_type.
Change some type names (e.g. mlds__type) and predicate names (e.g.
deforest__goal) to make them unique even without module qualification.
Rename the function symbols (e.g. pure, &) that need to be renamed
to avoid the need to parenthesize them. Make their replacement names
more expressive.
Convert some more modules to four space indentation.
Avoid excessively long lines, such as those resulting from the
automatic substitution of 'mer_type' for 'type'.
Estimated hours taken: 0.5
Branches: main
tools/subst:
A simple tool for performing substitutions on the source files of the
compiler.
compiler/*.m:
Change the names of the get predicates operating on module_infos to
include "get" in the name, for uniformity. This was done mostly by
the following sed script, with some manual cleanup afterwards to reduce
excessive line lengths.
s/module_info_types/module_info_get_type_table/
s/module_info_set_types/module_info_set_type_table/
s/module_info_insts/module_info_get_inst_table/
s/module_info_set_insts/module_info_set_inst_table/
s/module_info_modes/module_info_get_mode_table/
s/module_info_set_modes/module_info_set_mode_table/
s/module_info_ctors/module_info_get_cons_table/
s/module_info_set_ctors/module_info_set_cons_table/
s/module_info_classes/module_info_get_class_table/
s/module_info_set_classes/module_info_set_class_table/
s/module_info_instances/module_info_get_instance_table/
s/module_info_set_instances/module_info_set_instance_table/
s/module_info_superclasses/module_info_get_superclass_table/
s/module_info_set_superclasses/module_info_set_superclass_table/
s/module_info_assertion_table/module_info_get_assertion_table/
s/module_info_exclusive_table/module_info_get_exclusive_table/
s/module_info_ctor_field_table/module_info_get_ctor_field_table/
s/module_info_name/module_info_get_name/
s/module_info_globals/module_info_get_globals/
s/module_info_contains_foreign_types/module_info_get_contains_foreign_types/
s/module_info_num_errors/module_info_get_num_errors/
s/module_info_type_ctor_gen_infos/module_info_get_type_ctor_gen_infos/
s/module_info_stratified_preds/module_info_get_stratified_preds/
s/module_info_unused_arg_info/module_info_get_unused_arg_info/
s/module_info_exception_info/module_info_get_exception_info/
s/module_info_type_spec_info/module_info_get_type_spec_info/
s/module_info_no_tag_types/module_info_get_no_tag_types/
s/module_info_analysis_info/module_info_get_analysis_info/
s/module_info_aditi_top_down_procs/module_info_get_aditi_top_down_procs/
Estimated hours taken: 10
Branches: main
This diff cleans up a bunch of modules. It has no algorithmic changes
other than in the formatting of error messages.
compiler/error_util.m:
Delete the obsolete predicate append_punctuation, since the suffix
format component can now do more, and do it more easily.
compiler/goal_util.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/instmap.m:
compiler/const_prop.m:
Change the argument order of some the predicates exported by these
modules to make them easier to use with state variable syntax.
compiler/*.m:
Convert a bunch of these modules to four space indentation, and fix
departures from our coding style.
Conform to the changed argument order above.
Use suffixes instead of append_punctuation.
library/string.m:
Add string.foldl2.
tests/invalid/circ_*.err_exp:
tests/warnings/unused_args_*.exp:
Expect the updated error messages, which format sym_names consistently
the same way as other messages.
Estimated hours taken: 6
Branches: main
Optimize higher order calls by providing variants of the relevant code that
are specialized to a given number of explicitly given arguments.
runtime/mercury_ho_call.[ch]:
Define variants of do_call_closure and do_call_class_method
specialized to 0, 1, 2 or 3 explicit input arguments. Apart from
not needing to be passed the number of explicit input arguments
in a register, these avoid some runtime tests and unroll loops.
Harmonize the variable names used in the do_call_closure and
do_call_class_method variants. Since they are near-copies of each
other, factor out their documentation. (Factoring out the code itself
would be possible, but would not make maintenance easier and would make
the code harder to read.)
Provide a mechanism to gather statistics about the numbers of hidden
and explicit arguments if the macro MR_DO_CALL_STATS is set.
compiler/options.m:
Add options that specify how many of these variants exist. These
provide the necessary synchronization between the runtime and the
compiler. They are not meant to be set from the command line, even by
implementors.
runtime/mercury_conf_params.h:
Document MR_DO_CALL_STATS.
runtime/mercury_wrapper.c:
If MR_DO_CALL_STATS is set, print the gathered statistics when
execution ends.
runtime/mecury_mm_own_stack.c:
Fix a typo that prevented the stage2 library from linking in jump.gc
grade.
compiler/llds.m:
Provide a way to represent the labels of the new specialized variants.
compiler/llds__out.m:
Output the labels of the new specialized variants if required.
Convert to four-space indentation.
compiler/call_gen.m:
Call the specialized variants of do_call_closure or
do_call_class_method if they are applicable.
code_info/follow_vars.m:
code_info/interval.m:
code_info/tupling.m:
Conform to the change in call_gen.m.
code_info/dupproc.m:
code_info/exprn_aux.m:
code_info/livemap.m:
code_info/opt_util.m:
Conform to the change in llds.m.
compiler/code_info.m:
Minor style cleanups.
tools/bootcheck:
Enable the collection of statistics from the compilation of stage 3
and the test cases, for use when the stage 2 is built with
MR_DO_CALL_STATS enabled.
tools/ho_call_stats:
A new script to analyze the statistics collected.
tools/makebatch:
Add a new option --save-stage2-on-no-compiler, which is a variant of
the existing option --save-stage2-on-error.
Estimated hours taken: 15
Branches: main
Introduce a distinction between variables that are typed according to the
external view of a procedure, in which the types may contain an existentially
quantified type variable, and variables that are typed according to the
internal view of a procedure, in which existentially quantified type
variables may be bound to a known type. The distinction is maintained by
adding "exists_cast" goals which assign an internal variable to its
corresponding external variable.
Any output head variable which is existentially typed and for which the
external view differs from the internal view is replaced by a new variable.
An exists_cast goal is added to the end of the procedure which casts the
old headvar to the new one. We also do the same for any type_infos and
typeclass_infos that are output.
Exists casts are implemented as a variant on unsafe_cast generic calls.
We also add other variants to distinguish the different kinds of casts:
- equiv_casts for when the types are the same modulo equivalence
types;
- unsafe_type_casts for when the types are different but the insts
are compatible; and
- unsafe_type_inst_casts for when the type and inst are changed by
the cast.
The purpose of this change is to make it possible to include both the
internal and external views in the rtti_varmaps structure.
compiler/polymorphism.m:
Perform the transformation on proc_infos to include the exists_cast
goals. This is done at the end of the polymorphism transformation,
when we recompute the argument types for the newly transformed
procedure. The clauses_infos are left untouched by this
transformation, since after this stage they should no longer be used.
compiler/hlds_goal.m:
Modify the generic_call type to include the type of cast.
compiler/hlds_pred.m:
Modify the generic_call_id type to include the type of cast.
compiler/goal_util.m:
Add an argument to `generate_unsafe_cast' which specifies the type
of cast to generate.
compiler/higher_order.m:
Use the predicate in goal_util to generate the cast, instead of doing
it manually.
compiler/prog_rep.m:
All variants of the cast generic call are represented in the same
way. This is to avoid to the need to change the format of static
data in programs compiled with full declarative debugging. If we
do need the distinction to be made here, then that can be done as
a separate change.
compiler/purity.m:
Calls to private_builtin.unsafe_type_cast are translated into
unsafe_type_cast generic calls.
compiler/aditi_builtin_ops.m:
Use unsafe_type_inst_cast when casting between aditi_bottom_up
closures and their transformed versions.
compiler/common.m:
Use unsafe_type_cast when generating assignments for variables whose
types do not match exactly.
compiler/unify_proc.m:
Use equiv_type_cast when generating casts in unification, comparison
and initialisation clauses for equivalence types.
Use unsafe_type_cast when casting enum types to integers for the
purposes of comparison or unification.
compiler/*.m:
Handle the new generic_calls.
Estimated hours taken: 12
Branches: main
Replace the some() HLDS goal with a more general scope() goal, which can be
used not just for existential quantification but also for other purposes.
The main such purposes are new goal types that allow the programmer
to annotate arbitrary goals, and not just whole procedure bodies, with the
equivalents of promise_pure/promise_semipure and promise_only_solution:
promise_pure ( <impure/semipure goal> )
promise_semipure ( <impure goal> )
promise_equivalent_solutions [OutVar1, OutVar2] (
<cc_multi/cc_nondet goal that computed OutVar1 & OutVar2>
)
Both are intended to be helpful in writing constraint solvers, as well as in
other situations.
doc/reference_manual.texi:
Document the new constructs.
library/ops.m:
Add the keywords of the new constructs to the list of operators.
Since they work similarly to the "some" operator, they have the same
precedence.
compiler/hlds_goal.m:
Replace the some(Vars, SubGoal) HLDS construct, with its optional
keep_this_commit attribute, with the new scope(Reason, SubGoal)
construct. The Reason argument may say that this scope is an
existential quantification, but it can also say that it represents
a purity promise, the introduction of a single-solution context
with promise_equivalent_solutions, or a decision by a compiler pass.
It can also say that the scope represents a set of goals that all arise
from the unraveling of a unification between a variable and a ground
term. This was intended to speed up mode checking by significantly
reducing the number of delays and wakeups, but the cost of the scopes
themselves turned out to be bigger than the gain in modechecking speed.
Update the goal_path_step type to refer to scope goals instead of just
existential quantification.
compiler/prog_data.m:
Add new function symbols to the type we use to represent goals in items
to stand for the new Mercury constructs.
compiler/prog_io_goal.m:
Add code to read in the new language constructs.
compiler/prog_io_util.m:
Add a utility predicate for use by the new code in prog_io_goal.m.
compiler/make_hlds.m:
Convert the item representation of the new constructs to the HLDS
representation.
Document how the from_ground_term scope reason would work, but do not
enable the code.
compiler/purity.m:
When checking the purity of goals, respect the new promise_pure and
promise_semipure scopes. Generate warnings if such scopes are
redundant.
compiler/det_analysis.m:
Make the insides of promise_equivalent_solutions goals single solution
contexts.
compiler/det_report.m:
Provide mechanisms for reporting inappropriate usage of
promise_equivalent_solutions goals.
compiler/instmap.m:
Add a utility predicate for use by one of the modules above.
compiler/deep_profiling.m:
Use one of the new scope reasons to prevent simplify from optimizing
away commits of goals that have been made impure, instead of the old
keep_this_commit goal feature.
compiler/modes.m:
Handle from_ground_term scopes when present; for now, they won't be
present, since make_hlds isn't creating them.
compiler/options.m:
Add two new compiler options, for use by implementors only, to allow
finer control over the amount of output one gets with --debug-modes.
(I used them when debugging the performance of the from_ground_term
scope reason.) The options are --debug-modes-minimal and
--debug-modes-verbose.
compiler/handle_options.m:
Make the options that are meaningful only in the presence of
--debug-modes imply --debug-modes, since this allows more convenient
(shorter) invocations.
compiler/mode_debug.m:
Respect the new options when deciding how much data to print
when debugging of the mode checking process is enabled.
compiler/switch_detect.m:
Rename a predicate to make it differ from another predicate by more
than just its arity.
compiler/passes_aux.m:
Bring this module up to date with our current style guidelines,
by using state variable syntax where appropriate.
compiler/*.m:
Minor changes to conform to the change in the HLDS and/or parse tree
goal type.
mdbcomp/program_representation.m:
Rename the some goal to the scope goal, and the same for path steps,
to keep them in sync with the HLDS.
browser/declarative_tree.m:
Conform to the change in goal representations.
tests/hard_coded/promise_equivalent_solutions_test.{m,exp}:
A new test case to test the handling of the
promise_equivalent_solutions construct.
tests/hard_coded/Mmakefile:
Enable the new test.
tests/hard_coded/purity/promise_pure_test.{m,exp}:
A new test case to test the handling of the promise_pure and
promise_semipure constructs.
tests/hard_coded/purity/Mmakefile:
Enable the new test.
tests/invalid/promise_equivalent_solutions.{m,err_exp}:
A new test case to test the error messages for improper use of the
promise_pure and promise_semipure constructs.
tests/invalid/Mmakefile:
Enable the new test.
Estimated hours taken: 4
Branches: main
compiler/*.m:
Change a bunch of modules to import only one module per line, even
from the library.
compiler/mlds_to_il.m:
compiler/mlds_to_managed.m:
Convert these modules to our current coding style. Use state variables
where appropriate. Use predmode declarations where possible.
Estimated hours taken: two months
Branches: main
This change adds a tupling transformation to the compiler. It takes the HLDS
and tries to find opportunities for procedures to pass some arguments to each
as a tuple rather than as individual arguments.
compiler/interval.m:
compiler/stack_opt.m:
compiler/backend_libs.m:
Moved the predicate from stack_opt.m that builds up information about
intervals into a new module backend_libs__interval, and generalised it
for use by the tupling transformation. The predicate was called
`optimize_live_sets_in_goal' and was renamed to
`build_interval_info_in_goal'.
Also moved the predicate `record_decisions_in_goal'.
compiler/transform_hlds.m:
compiler/tupling.m:
New module `tranform_hlds__tupling'.
compiler/mercury_compile.m:
Added code to run the tupling pass.
Run a simplification pass after the untupling transformation. The
untupling transformation generates procedures that really should be
simplified, and it should help the tupling transformation (which runs
directly after untupling).
compiler/options.m:
Add the options --tuple, --tuple-trace-counts-file,
--tuple-costs-ratio and --tuple-min-args.
compiler/handle_options.m:
Disable --tuple when debugging is on.
compiler/hlds_goal.m:
compiler/common.m:
compiler/saved_vars.m
Add `tuple_opt' goal feature.
compiler/hlds_pred.m:
compiler/layout_out.m:
Add a new `tuple' functor for `pred_transformation'.
compiler/untupling.m:
Made the untupling transformation give better names to the head
variables in the untupled versions of procedures that it generates.
This is needed for the tupling transformation to find related head
variables between procedures in an SCC.
mdbcomp/trace_counts.m:
Add predicate `restrict_trace_counts_to_module'.
library/list.m:
Add `nth_member_lookup/3', a deterministic version of
`nth_member_search/3'.