Estimated hours taken: 45
Assorted changes to make the HLDS type and mode correct
after lambda expansion. The HLDS is still not unique mode
correct after common structure elimination.
compiler/det_analysis.m
Make sure the inferred_determinism field of the proc_info is filled
in correctly for imported procedures and class methods.
compiler/mode_util.m
Fix a bug in recompute_instmap_delta_call to do with unreachable
instmaps. This caused an abort a couple of months ago when
compiling with --deforestation (not yet committed), but
can't currently be reproduced.
compiler/hlds_pred.m
compiler/lambda.m
Add a field to the proc_info to record which args_method
should be used for this procedure. Procedures directly
called by do_call_*_closure must be compiled with
the `compact' argument convention to avoid the need to permute
the arguments so inputs come before outputs.
compiler/lambda.m
compiler/higher_order.m
Remove permutation of argument variables of lambda expressions
so the HLDS is type and mode correct and mode analysis can
be rerun. Otherwise, rerunning mode analysis will fail on
tests/hard_coded/ho_order.m.
compiler/arg_info.m
Added arg_info__ho_call_args_method which returns
an args_method which can always be directly called by
do_call_*_closure (`compact').
Added arg_info__args_method_is_ho_callable to check that
a given args_method can be directly called.
compiler/unify_gen.m
Abort if a closure is created for a procedure compiled
with the simple argument convention.
compiler/hlds_goal.m
compiler/lambda.m
Mode analysis was not storing the non-locals list on which the
uni_modes field of the construction of a lambda goal was computed.
If the nonlocals were renamed, the sort order could change, and
the non-locals could be incorrectly matched with the arguments
of the introduced lambda expression, causing a mode error. The
argument list is now stored.
This caused rerunning mode-checking on tests/valid/lazy_list.m
after polymorphism to fail.
compiler/*.m
Fill in the args_method field of proc_infos with the value
from the globals.
Handle the extra argument to the lambda_goal unify_rhs.
compiler/follow_vars.m
Remove code to handle complicated unifications, since
they should be removed by polymorphism.m.
compiler/special_pred.m
library/mercury_builtin.m
Make the uniqueness of the comparison_result argument
of builtin_compare_* and the automatically generated
comparison procedures match that of compare/3. Unique mode
errors will still be introduced if polymorphism.m specializes
calls to any of the unique modes of compare/3 and then mode analysis
is rerun, since the compiler-generated comparison procedures
only implement the (uo, in, in) mode. (This is not yet a problem
because currently we don't rerun mode analysis.)
runtime/mercury_ho_call.c
Remove code in do_call_*_closure to deal with the
`simple' args_method. Since the output arguments no longer
need to be moved, the closure call is now a tailcall.
Remove some magic numbers.
compiler/modecheck_unify.m
Avoid some aborts and mode errors when rerunning mode analysis,
especially those resulting from not_reached insts being treated
as bound.
Avoid aborting on higher-order predicate constants with multiple
modes if lambda expansion has already been run.
tests/valid/higher_order.m
Add a test case for an abort in mode analysis when
compiling with --deforestation (not yet committed),
due to a predicate constant for a procedure with multiple
modes.
tests/valid/unreachable_code.m
Add a test case for bogus higher-order unification
mode errors in unreachable code.
Estimated hours taken: 40
Implement nondet pragma C codes.
runtime/mercury_stacks.h:
Define a new macro, mkpragmaframe, for use in the implementation
of nondet pragma C codes. This new macro includes space for a
struct with a given sruct tag in the nondet stack frame being created.
compiler/{prog_data.m,hlds_goal.m}:
Revise the representation of pragma C codes, both as the item and
in the HLDS.
compiler/prog_io_pragma.m:
Parse nondet pragma C declarations.
Fix the indentation in some places.
compiler/llds.m:
Include an extra argument in mkframe instructions. This extra argument
gives the details of the C structure (if any) to be included in the
nondet stack frame to be created.
Generalize the LLDS representation of pragma C codes. Instead of a
fixed sequence of <assign from inputs, user c code, assign to outputs>,
let the sequence contain these elements, as well as arbitrary
compiler-generated C code, in any order and possibly with repetitions.
This flexibility is needed for nondet pragma C codes.
Add a field to pragma C codes to say whether they can call Mercury.
Some optimizations can do a better job if they know that a pragma C
code cannot call Mercury.
Add another field to pragma C codes to give the name of the label
they refer to (if any). This is needed to prevent labelopt from
incorrectly optimizing away the label definition.
Add a new alternative to the type pragma_c_decl, to describe the
declaration of the local variable that points to the save struct.
compiler/llds_out.m:
Output mkframe instructions that specify a struct as invoking the new
mkpragmaframe macro, and make sure that the struct is declared just
before the procedure that uses it.
Other minor changes to keep up with the changes to the representation
of pragma C code in the LLDS, and to make the output look a bit nicer.
compiler/pragma_c_gen.m:
Add code to generate code for nondet pragma C codes. Revise the utility
predicates and their data structures a bit to make this possible.
compiler/code_gen.m:
Add code for the necessary special handling of prologs and epilogs
of procedures defined by nondet pragma C codes. The prologs need
to be modified to include a programmer-defined C structure in the
nondet stack frame and to communicate the location of this structure
to the pragma C code, whereas the functionality of the epilog is
taken care of by the pragma C code itself.
compiler/make_hlds.m:
When creating a proc_info for a procedure defined by a pragma C code,
we used to insert unifications between the headvars and the vars of
the pragma C code into the body goal. We now perform substitutions
instead. This removes a factor that would complicate the generation
of code for nondet pragma C codes.
Pass a moduleinfo down the procedures that warn about singletons
(and other basic scope errors). When checking whether to warn about
an argument of a pragma C code not being mentioned in the C code
fragment, we need to know whether the argument is input or output,
since input variables should appear in some code fragments in a
nondet pragma C code and must not appear in others. The
mode_is_{in,out}put checks need the moduleinfo.
(We do not need to check for any variables being mentioned where
they shouldn't be. The C compiler will fail in the presence of any
errors of that type, and since those variables could be referred
to via macros whose definitions we do not see, we couldn't implement
a reliable test anyway.)
compiler/opt_util.m:
Recognize that some sorts of pragma_c codes cannot affect the data
structures that control backtracking. This allows peepholing to
do a better job on code sequences produced for nondet pragma C codes.
Recognize that the C code strings inside some pragma_c codes refer to
other labels in the procedure. This prevents labelopt from incorrectly
optimizing away these labels.
compiler/dupelim.m:
If a label is referred to from within a C code string, then do not
attempt to optimize it away.
compiler/det_analysis.m:
Remove a now incorrect part of an error message.
compiler/*.m:
Minor changes to conform to changes to the HLDS and LLDS data
structures.
Estimated hours taken: 25
Handle inference of mostly-unique (not just unique) modes.
compiler/unique_modes.m:
Change the handling of calls so that if the mode originally selected
by ordinary mode analysis (modes.m) won't work, then it now calls
modecheck_call_pred to introduce a new mode for the predicate.
compiler/unify_proc.m:
Generalize the existing "unify request queue" so that
it can handle requests for any kind of predicate, not
just for unification predicates, and hence rename the
`unify_request' table which contains it as the `proc_request' table.
compiler/hlds_module.m:
Rename the `unify_request' table as the `proc_request' table.
compiler/modecheck_call.m:
When introducing new modes for predicates, do this by adding them
to the request queue. This ensures that when we do get around
to processing predicates added in unique mode analysis, we will
run mode analysis, switch detection, and determinism analysis
before doing unique mode analysis. To make this work, we
need to pass down a `maybe(determinism)' argument indicating
the determinism of the newly added procedure. unique_modes.m
sets this to the determinism inferred for the mode originally
inferred by modes.m. That should be OK, because uniqueness
should not affect determinism.
Also change modecheck_call_proc to return a `Changed' flag
indicating whether we need to rerun fixpoint analysis.
And change `get_var_insts_and_lives' to return `dead' for
mostly_unique modes, not just for unique modes, so that
we can infer `mdi' modes.
compiler/modes.m:
Instead of analyzing everything to a fixpoint, and then
analyzing the queued unification procedures, change it so
that analysis of queued procedures is part of each fixpoint
iteration.
When doing ordinary mode analysis for calls, pass `no' as the
new `maybe(determinism)' argument to modecheck_call_pred.
compiler/constraint.m:
compiler/cse_detection.m:
Ignore the new output argument for modecheck_call_proc.
compiler/mode_util.m:
Add code to insts_to_mode to recognize `muo', `mui', and `mdi'
modes and use the corresponding abbreviations (previously this
was done only for `uo', `ui', `di', `in' and `out').
tests/valid/mostly_uniq_mode_inf.m:
A test case for the above change.
Estimated hours taken: 60
A rewrite of termination analysis to make it significantly easier to modify,
and to extend its capabilities.
compiler/error_util.m:
A new file containing code that makes it easier to generate
nicely formatted error messages.
compiler/termination.m:
Updates to reflect the changes to the representation of termination
information.
Instead of doing pass 1 on all SCCs and then pass 2 on all SCCs,
we now do both pass 1 and 2 on an SCC before moving on to the next.
Do not insist that either all procedures in an SCC are
compiler-generated or all are user-written, since this need not be
true in the presence of user-defined equality predicates.
Clarify the structure of the code that handles builtins and compiler
generated predicates.
Concentrate all the code for updating module_infos in this module.
Previously it was scattered in several places in several files.
Put all the code for writing out termination information at the
end of the module in a logical order.
compiler/term_traversal.m:
A new file containing code used by both pass 1 and pass 2 to
traverse procedure bodies.
compiler/term_pass1.m:
Use the new traversal module.
Clarify the fixpoint computation on the set of output supplier
arguments.
Remove duplicates from the list of equations given to the solver.
This avoids a det stack overflow in lp.m when doing termination
analysis on options.m.
If an output argument of a predicate makes sense only in the absence
of errors, then return it only in the absence of errors.
compiler/term_pass2.m:
Use the new traversal module. Unlike the previous code, this allows us
to ignore recursive calls with input arguments bigger than the head
if those calls occur after goals that cannot succeed (since those
calls will never be reached).
Implement a better way of doing single argument analysis, which
(unlike the previous version) works in the presence of mutual recursion
and other calls between the recursive call and the start of the clause.
Implement a more precise way of checking for recursions that don't
cause termination problems. We now allow calls from p to q in which
the recursive input supplier arguments can grow, provided that on
any path on which q can call p, directly or indirectly, the recursive
input supplier arguments shrink by a greater amount.
If an output argument of a predicate makes sense only in the absence
of errors, then return it only in the absence of errors.
compiler/term_util.m:
Updates to reflect the changes to the representation of termination
information.
Reorder to put related code together.
Change the interface of several predicates to better reflect the
way they are used.
Add some more utility predicates.
compiler/term_errors.m:
Small changes to the set of possible errors, and major changes in
the way the messages are printed out (we now use error_util).
compiler/options.m:
Change --term-single-arg from being a bool to an int option,
whose value indicates the maximum size of an SCC in which we try
single argument analysis. (Large SCCs can cause single-arg analysis
to require a lot of iterations.)
Add an (int) option that controls the max number of paths
that we are willing to analyze (analyzing too many paths can cause
det stack overflow).
Add an (int) option that controls the max number of causes of
nontermination that we print out.
compiler/hlds_pred.m:
Use two separate slots in the proc_info to hold argument size data
and termination info, instead of the single slot used until now.
The two kinds of information are produced and used separately.
Make the layout of the get and set procedures for proc_infos more
regular, to facilitate later updates.
The procedures proc_info_{,set_}variables did the same work as
proc_info_{,set_}varset. To eliminate potential confusion, I
removed the first set.
compiler/*.m:
Change proc_info_{,set_}variables to proc_info_{,set_}varset.
compiler/hlds_out.m:
compiler/make_hlds.m:
compiler/mercury_to_mercury.m:
Change the code to handle the arg size data and the termination
info separately.
compiler/prog_data.m:
Change the internal representation of termination_info pragmas to
hold the arg size data and the termination info separately.
compiler/prog_io_pragma.m:
Change the external representation of termination_info pragmas to
group the arg size data together with the output supplier data,
to which it is logically connected.
compiler/module_qual.m:
compiler/modules.m:
Change the code to accommodate the change to the internal
representation of termination_info pragmas.
compiler/notes/compiler_design.html:
Fix some documentation rot, and clarify some points.
Document termination analysis.
doc/user_guide.texi:
Document --term-single-arg and the new options.
Remove spaces from the ends of lines.
library/bag.m:
Add a new predicate, bag__least_upper_bound.
Fix code that would do the wrong thing if executed by Prolog.
Remove spaces from the ends of lines.
library/list.m:
Add a new predicate, list__take_upto.
library/set{,_ordlist}.m:
Add a new predicate, set{,_ordlist}__count.
tests/term/*:
A bunch of new test cases to test the behaviour of termination
analysis. They are the small benchmark suite from our paper.
tests/Mmakefile:
Enable the new test case directory.
Estimated hours taken: 500 or so
This change implements typeclasses. Included are the necessary changes to
the compiler, runtime and library.
compiler/typecheck.m:
Typecheck the constraints on a pred by adding constraints for each
call to a pred/func with constraints, and eliminating constraints
by applying context reduction.
While reducing the constraints, keep track of the proofs so that
polymorphism can produce the tyepclass_infos for eliminated
constraints.
compiler/polymorphism.m:
Perform the source-to-source transformation which turns code with
typeclass constraints into code without constraints, but with extra
"typeclass_info", or "dictionary" parameters.
Also, rather than always having a type_info directly for each type
variable, sometimes the type_info is hidden inside a typeclass_info.
compiler/bytecode*.m:
Insert some code to abort if bytecode generation is used when
typeclasses are used.
compiler/call_gen.m:
Generate code for a class_method_call, which forms the body of a class
method (by selecting the appropriate proc from the typeclass_info).
compiler/dead_proc_elim.m:
Don't eliminate class methods if they are potentially used outside
the module
compiler/hlds_data.m:
Define data types to store:
- the typeclass definitions
- the instances of a class
- "constraint_proof". ie. the proofs of redundancy of a
constraint. This info is used by polymorphism to construct the
typeclass_infos for a constraint.
- the "base_tyepclass_info_constant", which is analagous the
the base_type_info_constant
compiler/hlds_data.m:
Define the class_method_call goal. This goal is inserted into the
body of class method procs, and is responsible for selecting the
appropriate part of the typeclass_info to call.
compiler/hlds_data.m:
Add the class table and instance table to the module_info.
compiler/hlds_out.m:
Output info about base_typeclass_infos and class_method_calls
compiler/hlds_pred.m:
Change the representation of the locations of type_infos from "var"
to type_info_locn, which is either a var, or part of a typeclass_info,
since now the typeclass_infos contain the type_infos for the type that
they constrain.
Add constraints to the pred_info.
Add constraint_proofs to the pred_info (so that typeclass.m can
annotate the pred_info with the reasons that constraints were
eliminated, so that polymorphism.m can in turn generate the
typeclass_infos for the constraints).
Add the "class_method" marker.
compiler/lambda.m:
A feable attempt at adding class ontexts to lambda expressions,
untested and almost certainly not working.
compiler/llds_out.m:
Output the code addresses for do_*det_class_method, and output
appropriately mangled symbol names for base_typeclass_infos.
compiler/make_hlds.m:
Add constraints to the types on pred and func decls, and add
class and instance declarations to the class_table and instance_table
respectively.
compiler/mercury_compile.m:
Add the check_typeclass pass.
compiler/mercury_to_mercury.m:
Output constraints of pred and funcs, and output typeclass and instance
declarations.
compiler/module_qual.m:
Module qualify typeclass names in pred class contexts, and qualify the
typeclass and instance decls themselves.
compiler/modules.m:
Output typeclass declarations in the short interface too.
compiler/prog_data.m:
Add the "typeclass" and "instance" items. Define the types to store
information about the declarations, including class contexts on pred
and func decls.
compiler/prog_io.m:
Parse constraints on pred and func declarations.
compiler/prod_out.m:
Output class contexts on pred and func decls.
compiler/type_util.m:
Add preds to apply a substitution to a class_constraint, and to
a list of class constraints. Add type_list_matches_exactly/2. Also
add typeclass_info and base_typeclass_info as types which should not
be optimised as no_tag types (seeing that we cheat a bit about their
representation).
compiler/notes/compiler_design.html:
Add notes on module qualification of class contexts. Needs expansion
to include more stuff on typeclasses.
compiler/*.m:
Various minor changes.
New Files:
compiler/base_typeclass_info.m:
Produce one base_typeclass_info for each instance declaration.
compiler/prog_io_typeclass.m:
Parse typeclass and instance declarations.
compiler/check_typeclass.m:
Check the conformance of an instance declaration to the typeclass
declaration, including building up a proof of how superclass
constraints are satisfied so that polymorphism.m is able to construct
the typeclass_info, including the superclass typeclass_infos.
library/mercury_builtin.m:
Implement that base_typeclass_info and typeclass_info types, as
well as the predicates type_info_from_typeclass_info/3 to extract
a type_info from a typeclass_info, and superclass_from_typeclass_info/3
for extracting superclasses.
library/ops.m:
Add "typeclass" and "instance" as operators.
library/string.m:
Add a (in, uo) mode for string__length/3.
runtime/mercury_ho_call.c:
Implement do_call_*det_class_method, which are the pieces of code
responsible for extracting the correct code address from the
typeclass_info, setting up the arguments correctly, then executing
the code.
runtime/mercury_type_info.h:
Macros for accessing the typeclass_info structure.
Estimated hours taken: 1
Fix a bug for the case of a higher-order function call in code
with common sub-expression; mercury 0.7 failed this test, reporting
"Software Error: modecheck fails when repeated", due to confusion
between h.o. _function_ call and h.o. _predicate_ call.
compiler/hlds_goal.m:
Add `pred_or_func' field to HLDS higher_order_calls.
compiler/modes.m:
compiler/modecheck_call.m:
compiler/hlds_out.m:
compiler/*.m:
Add code to handle new field for higher_order_call goals.
tests/valid/Mmake:
tests/valid/ho_func_call.m:
Regression test for the above-mentioned bug.
Estimated hours taken: 20
Reorganisation of modules to do with the inst data type.
This is actually the first installment of the alias tracking mode
checker in disguise. A very good disguise. The rationale for
this reorganisation is to reduce coupling in the part of the mode
checker which is _not_ in this change (ie most of it).
Alias tracking requires a new kind of inst, alias(inst_key), where
an inst_key is a handle on some other sub-inst. With it goes a
data structure in which to store dereferenced insts and all the
operations which go with it. This code will go in the new module
inst.m so that it doesn't have to go in prog_data.m. (I briefly
considered putting it in instmap.m however this introduces some
bad coupling since instmap.m imports hlds_module.m. Putting it
in prog_data.m would cause hlds_*.m to depend on prog_data.m,
but we have designed things so that the dependencies go in the
other direction.)
The remainder of the reorganisation is a general cleanup: the
inst testing predicates (inst_is_*) have been moved out of
mode_util because they are not actually operations on modes at
all, and have been moved into inst_match. inst_match has then
been split because otherwise it would be 2000 lines long and
will get significantly bigger when aliasing is added. Roughly
speaking, any operations which create new insts from old ones
have been moved into a new module, inst_util while any operations
which test the values of insts remain in inst_match.
Also included are the removal of some NU-Prologisms since the
NU-Prolog version of the compiler is no longer supported. Two
changes here:
- Removal of some when declarations.
- A gross hack in inst_is_*_2, where two copies of
the same inst were passed into the predicate so that
one could be switched on. Thank NU-Prolog's lack of
common subexpression elimination.
compiler/inst.m:
New module which contains the data types inst, uniqueness,
pred_inst_info, bound_inst.
compiler/inst_util.m:
New module which contains predicates which perform mode
checking-like operations on insts.
Moved in:
abstractly_unify_inst, abstractly_unify_inst_functor,
inst_merge, make_mostly_uniq_inst (from inst_match.m)
compiler/inst_match.m:
Moved out:
inst_merge, make_mostly_uniq_inst,
abstractly_unify_inst, abstractly_unify_inst_functor
(to inst_util.m)
Moved in:
inst_is_*, inst_list_is_*, bound_inst_list_is_*
(from mode_util.m)
Now exported:
unique_matches_initial/2, unique_matches_final/2
inst_contains_instname/3, pred_inst_matches/3
(They are required by inst_util.m, and they are
useful in their own right.)
compiler/instmap.m:
instmap_delta_lookup_var/3 reincarnated as
instmap_delta_search_var/3. The reason for this change is
that previously, instmap_delta_lookup_var simply returned
`free' if the searched-for var did not occur in the
instmap_delta. This is somewhat non-obvious behaviour.
instmap_delta_search_var/3 fails in such a situation.
compiler/mode_util.m:
Moved out:
inst_is_*, inst_list_is_*, bound_inst_list_is_*
(to inst_match.m)
(These are not really operations on modes.)
compiler/modecheck_call.m:
Moved in modecheck_higher_order_func_call/5, from modecheck_unify.m
compiler/modecheck_unify.m:
Moved out modecheck_higher_order_func_call/5, to modecheck_call.m
where it should have been all along.
compiler/prog_data.m:
Moved out the types inst, uniqueness, pred_inst_info,
bound_inst (to inst.m).
compiler/common.m:
compiler/cse_detection.m:
compiler/fact_table.m:
compiler/higher_order.m:
compiler/hlds_data.m:
compiler/hlds_goal.m:
compiler/hlds_out.m:
compiler/intermod.m:
compiler/liveness.m:
compiler/llds.m:
compiler/make_hlds.m:
compiler/mercury_to_mercury.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/modes.m:
compiler/module_qual.m:
compiler/polymorphism.m:
compiler/prog_io.m:
compiler/prog_io_util.m:
compiler/prog_util.m:
compiler/simplify.m:
compiler/switch_detection.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
Miscellaneous minor changes to cope with the above changes.
compiler/notes/compiler_design.html:
Document the new modules.
Estimated hours taken: 0.25
compiler/cse_detection.m:
Fix a variable numbering error: s/ModuleInfo0/ModuleInfo3/
in a call to `hlds_out__write_pred_id' in a progress message.
Estimated hours taken: 14
Implemented a :- use_module directive. This is the same as
:- import_module, except all uses of the imported items
must be explicitly module qualified.
:- use_module is implemented by ensuring that unqualified versions
of items only get added to the HLDS symbol tables if they were imported
using import_module.
Indirectly imported items (from `.int2' files) and items declared in `.opt'
files are treated as if they were imported with use_module, since all uses
of them should be module qualified.
compiler/module_qual.m
Keep two sets of type, mode and inst ids, those which can
be used without qualifiers and those which can't.
Renamed some predicates which no longer have unique names since
'__' became a synonym for ':'.
Made mq_info_set_module_used check whether the current item is in
the interface, rather than relying on its caller to do the check.
Removed init_mq_info_module, since make_hlds.m now uses the
mq_info built during the module qualification pass.
compiler/prog_data.m
Added a pseudo-declaration `used', same as `imported' except uses of
the following items must be module qualified.
Added a type need_qualifier to describe whether uses of an item
need to be module qualified.
compiler/make_hlds.m
Keep with the import_status whether current item was imported
using a :- use_module directive.
Use the mq_info structure passed in instead of building a new one.
Ensure unqualified versions of constructors only get added to the
cons_table if they can be used without qualification.
compiler/hlds_module.m
Added an extra argument to predicate_table_insert of type
need_qualifier.
Only add predicates to the name and name-arity indices if they
can be used without qualifiers.
Changed the structure of the module-name-arity index, so that
lookups can be made without an arity, such as when type-checking
module qualified higher-order predicate constants. This does not
change the interface to the module_name_arity index.
Factored out some common code in predicate_table_insert which
applies to both predicates and functions.
compiler/hlds_pred.m
Removed the opt_decl import_status. It isn't needed any more
since all uses of items declared in .opt files must now be
module qualified.
Added some documentation about when the clauses_info is valid.
compiler/intermod.m
Ensure that predicate and function calls in the `.opt' file are
module qualified. Use use_module instead of import_module in
`.opt' files.
compiler/modules.m
Handle use_module directives.
Report a warning if both use_module and import_module declarations
exist for the same module.
compiler/mercury_compile.m
Collect inter-module optimization information before module
qualification, since it can't cause conflicts any more. This means
that the mq_info structure built in module_qual.m can be reused in
make_hlds.m, instead of building a new one.
compiler/prog_out.m
Add a predicate prog_out__write_module_list, which was moved
here from module_qual.m.
compiler/typecheck.m
Removed code to check that predicates declared in `.opt' files
were being used appropriately, since this is now handled by
use_module.
compiler/*.m
Added missing imports, mostly for prog_data and term.
NEWS
compiler/notes/todo.html
doc/reference_manual.texi
Document `:- use_module'.
tests/valid/intermod_lambda_test.m
tests/valid/intermod_lambda_test2.m
tests/invalid/errors.m
tests/invalid/errors2.m
Test cases.
Estimated hours taken: 1.5
Fix a determinism analysis abort which was caused by det_analysis.m not
updating the instmap to include the initial insts of the lambda variables
before processing a lambda goal. This problem was also present in
cse_detection.m and simplify.m.
compiler/cse_detection.m
compiler/det_analysis.m
compiler/simplify.m
Make sure that the instmap is updated before processing a lambda goal.
compiler/switch_detection.m
compiler/instmap.m
Move some code to update the instmap before a lambda goal from
switch_detection.m into a new predicate
instmap__update_for_lambda_modes/5.
tests/valid/Mmake
tests/valid/lambda_instmap_bug.m
Regression test.
Estimated hours taken: 3
Fix a bug in inlining of polymorphic pragma c_code procedures.
The bug was that if the actual argument type has a specific type
of say `float', then the C variable for the corresponding formal
parameter will be declared to have type `Float', whereas without
inlining the argument type would have been polymorphic and so
the C variable would have been declared to have type `Word'.
Hence we need to keep track of the original argument types,
before any inlining or specialization has occurred, and use
these original argument types to determine how to declare
the C variables, rather than using the actual argument types
for this particular specialization.
compiler/hlds_goal.m:
Add a new field to pragma_c_code goals, holding the
original argument types (before any inlining or specialization)
of the pragma_c_code procedure.
compiler/make_hlds.m:
Initialize this field with the declared argument types for
the pragma c_code procedure.
compiler/polymorphism.m:
Update this field to account for the inserted type_info variables.
compiler/code_gen.m:
Pass this field to pragma_c_gen.m.
compiler/pragma_c_gen.m:
Use the original argument types field for the pragma variable
declarations, rather than looking up the actual types of the
arguments.
compiler/*.m:
Trivial changes to handle new field.
compiler/live_vars.m:
Comment out some code to avoid a warning about `fail'
in the condition of an if-then-else.
Estimated hours taken: 3
Replace calls to map__set with calls to either map__det_insert or
map__det_update. In some cases this required a small amount of code
reorganization.
Estimated hours taken: 8
Enable the code to treat `__' as an alternative syntax for module
qualification, after fixing various places in the compiler where
we use `__' in ways that are incompatible with this.
compiler/prog_io.m:
compiler/prog_io_goal.m:
Uncomment the code to handle `__' as module qualification.
compiler/intermod.m:
compiler/hlds_module.m:
compiler/modecheck_unify.m:
Fix bugs in the handling of module qualified higher-order terms.
compiler/*.m:
s/hlds__/hlds_/g
compiler/passes_aux.m:
s/process__/process_/g
compiler/pragma_c_gen.m:
compiler/code_gen.m:
s/code_gen__/pragma_c_gen__/ for the predicates defined in
pragma_c_gen.m (this ought to have been done when the code
was first moved from code_gen.m to pragma_c_gen.m).
compiler/llds.m:
s/llds__proc_id/llds_proc_id/g
The reason for this was to avoid ambiguity between proc_id
in hlds_pred.m and llds__proc_id in llds.m.
compiler/quantification.m:
compiler/make_hlds.m:
compiler/mercury_to_c.m:
s/goal_vars/quantification__goal_vars/g
The reason for this was to avoid ambiguity between goal_vars
in quantification.m and goal_util__goal_vars in goal_util.m.
compiler/dupelim.m:
compiler/optimize.m:
s/dupelim__main/dupelim_main/g
The reason for this change is that a program can only
have one main/2 predicate.
compiler/prog_io_dcg.m:
Remove the old "temporary hack" to strip off and ignore
io__gc_call/1, since the new handling of `__' broke it.
It was only useful for optimizing NU-Prolog performance,
which we don't care about anymore.
compiler/mercury_compile.m:
compiler/modules.m:
compiler/intermod.m:
compiler/prog_io.m:
Remove occurrences of io__gc_call.
compiler/llds_out.m:
compiler/base_type_info.m:
Ensure that we properly handle the special hacks in mercury_builtin
where predicates from other modules (e.g. term__context_init)
are defined in mercury_builtin because they are needed for
type_to_term and term_to_type. llds_out.m: don't put
`mercury_builtin' in the mangled names for those symbols.
base_type_info.m: handle types whose status is "imported"
in their own module.
Estimated hours taken: 12
The first half of a change to introduce nondet pragma C goals.
This half makes the necessary modifications to the HLDS; the next
half will modify the LLDS and emit it.
prog_data:
Add a new pragma type for nondet pragma c_codes; these specify
the names of a a bunch of variables to save across backtracking,
and a list of label names to which backtracking may take place.
Rename is_recursive to may_call_mercury, since this is a more
direct expression of the meaning.
prog_io:
Move much of the functionality to new files.
prog_io_dcg, prog_io_goal, prog_io_pragma, prog_io_util:
New files, made up of pieces of prog_io.
hlds_goal:
Add an extra argument to the pragma_c_goals to store the extra
information present in the new type of pragma c_codes.
det_analysis:
Take into account that the new type of pragma_c goal may have
more than one solution.
goal_util:
Rename variables in the new field of pragma_cs.
live_vars:
Allocate stack slots to the saved variables in the new type of pragma_c
goals.
make_hlds:
Handle the new type of pragma_c goals.
mercury_output, hlds_out:
Output the new type of pragma_c goals.
garbage_out:
Rename type "det" to "frame_type".
others:
Ignore one more arg of pragma_c goals or import prog_io_util.
Estimated hours taken: 0.5
The only significant change in this checkin is that liveness.m now
tries to compute the best resume_locs for negations (it already did
for if-then-elses and disjunctions; leaving out negations was an
oversight in my earlier checkin).
The other changes are only syntactic:
I have removed the cont-lives and nondet-lives field from goal_info,
since they are not used anymore.
I have replaced the nondet-lives field in code_info, which is not used
anymore, with a follow-vars field, which is not used yet (but will be).
Some of the "read" access predicates in hlds_goal did not have "get" in
their name; I added them.
Estimated hours taken: 2.5
Switch from using a stack of store_maps in the code_info to govern what
goes where at the end of each branched structure to using the store map
fields of the goal expressions of those structures.
Fix variable names where they resembled the wrong kind of map(var, lval).
code_info:
Remove the operations on stacks of store maps.
Modify the generate_forced_saves and remake_with_store_map operations
to take a store_map parameter.
When making variables magically live, pick random unused variables
to hold them, since we can no longer use the guidance of the top
store map stack entry. This may lead to the generation of some
excess move instructions at non-reachable points in the code;
this will be fixed later.
code_gen:
Remove the store map push and pop invocations.
Modify the generate_forced_goal operation to take a store_map parameter.
code_exprn:
Export a predicate for use by code_info.
middle_rec, disj_gen, ite_gen, switch_gen,
dense_switch, lookup_switch, string_switch, tag_switch:
Pass the store map around to get it to invocations of the primitives
in code_gen and code_info that now need it.
goal_util:
Name apart the new follow_vars field in hlds__goal_infos.
(This should have been in the change that introduced that field.)
common, constraint, cse_detection, det_analysis, dnf, excess, follow_code,
intermod, lambda, lco, liveness, make_hlds, mode_util, modes, polymorphism,
quantification, simplify, switch_detection, typecheck, unique_modes,
unused_args:
Fix variable names.
follow_vars, store_alloc:
Add comments.
Estimated hours taken: 12
The main changes are
1 associating a name with the arguments of constructors
2 removing the follow_vars field from calls, higher-order calls
and complicated unifications, since they are not used
3 merging the follow_vars and store_alloc passes, since they logically
belong together
4 add a new module, lco, for detecting opportunities for last
call optimization modulo constructor application; it won't
actually apply the optimization until the mode system becomes
expressive enough to handle it (this module detects 529 opportunities
in the compiler and library)
5 make "-O3 --optimize-value-number" do the right thing; previously,
it used not to apply value numbering because the vnrepeat option
defaulted to zero
6 don't refer to .err2 files anymore; use .err instead.
prog_data:
The list associated with each value of type "constructor" now
contains not only the types of the arguments but their names as well.
equiv_type, hlds_data, hlds_out, make_hlds, mercury_to_{goedel,mercury},
mode_util, module_qual, shapes, type_util, unify_proc:
Modify the traversal of type definitions to account for the names
in the lists inside values of type "constructor".
prog_io:
Parse argument names. An unrelated change is that we now
check whether :- pred declarations give modes to some of their
arguments but not to all, in which case we return an error.
hlds_goal:
Remove the follow_vars field from calls, higher-order calls
and complicated unifications.
*.m:
Handle the new arities of calls, higher order calls and complicated
unifications.
mercury_compile:
Don't call follow_vars directly anymore, but do call lco if its option
is set. Also flush the main output before a call to maybe_report_stats
to prevent ugly output.
store_alloc:
Call follow_vars directly.
follow_vars:
Expose the initialization and traversal predicates for store_alloc.
lco:
Find opportunities for last call optimization modulo constructor
application.
passes_aux:
Add a HLDS traversal type for lco.
optimize:
Consider the vnrepeat count to be zero unless value numbering is on.
options:
Set the default value of vnrepeat to 1.
modules:
Don't refer to .err2 files.
Estimated hours taken: 20
Mode analyser reorganisation.
compiler/mode_util.m:
Removed: instmap_init/1, apply_instmap_delta/3, instmap_lookup_var/3,
instmapping_lookup_var/3, instmap_restrict/3, map_restrict/3 (all
moved to instmap.m).
compiler/hlds_goal.m:
Removed the declarations of instmap_delta, instmap and instmapping.
compiler/mode_errors.m:
Added report_mode_errors/2 (was modecheck_report_errors, from
modes.m).
compiler/modes.m:
Predicates now exported:
modecheck_goal/4
modecheck_goal_expr/5 (previously named modecheck_goal_2/5)
handle_extra_goals/8
mode_context_to_unify_context/3
Moved to mode_errors.m:
modecheck_report_errors/2
Moved to instmap.m:
compute_instmap_delta/4
instmap_merge/3
instmap_lookup_vars (was instmap_lookup_arg_list/3)
compute_instmap_delta/4
Moved to mode_debug.m:
Type port/0
mode_checkpoint/4
Moved to modecheck_call.m:
modecheck_call_pred/7
modecheck_higher_order_call/10
modecheck_higher_order_pred_call/4
modecheck_higher_order_func_call/7
Moved to modecheck_unify.m:
modecheck_unification/9
categorize_unify_var_var/12
categorize_unify_var_functor/11
categorize_unify_var_lambda/9
Moved to mode_info.m:
mode_info_error/4
mode_info_add_error/3
compiler/code_gen.pp, compiler/code_info.m, compiler/constraint.m,
compiler/cse_detection.m, compiler/det_analysis.m, compiler/det_util.m,
compiler/dnf.m, compiler/goal_util.m, compiler/higher_order.m,
compiler/hlds_out.m, compiler/hlds_pred.m, compiler/live_vars.m,
compiler/liveness.m, compiler/lookup_switch.m, compiler/polymorphism.m,
compiler/simplify.m, compiler/store_alloc.m, compiler/switch_detection.m,
compiler/transform.m, compiler/unused_args.m:
Imported instmap.m
New files:
compiler/instmap.m:
Handle operations associated with instmaps.
compiler/modecheck_unify.m:
Handle mode checking of unifications.
compiler/modecheck_call.m:
Handle mode checking of calls
compiler/mode_debug.m:
Code to trace the actions of the mode checker.
Estimated hours taken: 1
Fix another bug in the handling of `any' insts.
cse_detection.m:
Hoist common sub-expressions that involve `any' insts, not
just those that involve ground insts. (We still can't hoist them
if they involve `free' insts, since that would create aliasing
which the current mode system can't handle.)
Estimated hours taken: 4
Implement `recursive' and `non_recursive' pragma c_code declarations.
This allows the compiler to optimize cases when the C code
is known to not call Mercury code. It's also necessary
to allow C code which modifies the hp register to work
(such code must be declared `non_recursive', otherwise
the registers will be saved and restored over it).
To make things bootstrap OK, the old pragma c_code declarations
default to `non_recursive'.
prog_data.m, hlds_goal.m:
Add new field c_is_recursive to pragma c_code goals.
prog_io.m:
Parse the new `recursive' and `non_recursive' pragma c_code
declarations.
make_hlds.m:
Pass the c_is_recursive field from the parse tree to the HLDS.
live_vars.m:
For non-recursive C code, don't save variables on the stack.
code_gen.pp:
For non-recursive C code, don't save variables on the stack,
don't mark the succip as needing to be saved, and don't
call save_registers() and restore_registers().
*.m:
Change c_code/5 to c_code/6.
Estimated hours taken: 12
Implement higher-order functions.
Add higher-order function terms
(function lambda expressions, e.g. `Func = (func(X) = Y :- Y is 2 * X)'
and higher-order function calls (apply/N, e.g. `Z = apply(Func, 42)').
Add higher-order function insts and modes.
hlds_goal.m:
Add a new field pred_or_func to lambda_goal.
prog_data.m:
Add a new field pred_or_func to pred_inst_info.
prog_io.m:
Add support for parsing higher-order function terms and
higher-order function insts and modes.
make_hlds.m:
Add support for parsing higher-order function terms.
typecheck.m:
Add support for type-checking higher-order function calls
and higher-order function terms.
modes.m, mode_errors.m:
Add support for mode-checking higher-order function calls
and higher-order function terms.
higher_order.m:
Handle higher-order function types and insts.
hlds_pred.m:
Add new predicate pred_args_to_func_args, for extracting the
function arguments and function return from the arguments
of a predicate that is really a function.
*.m:
Minor changes to handle new pred_or_func field in lambda_goals
and pred_inst_infos.
Estimated hours taken: 24
Treat higher-order predicate calls as a new sort of goal,
rather than as calls to the special predicate call/N, in order to
remove the fixed limit on the number of arguments and on the modes
for call/N.
Also, remove the restriction on output arguments preceding input arguments
in lambda expressions.
hlds_goal.m:
Add new functor higher_order_call/6 to the hlds__goal type.
*.m:
Handle new functor higher_order_call/6.
arg_info.m:
Abstract things a bit more: the argument passing convention
for a procedure may be affected by that procedure's types,
modes, and code_model, as well as the arg_method.
follow_vars.m:
Pass down the args_method, since it is now needed for figuring
out the arg_info for unifications and higher-order calls.
follow_code.m:
Treat complicated unifications in the same way as calls.
lambda.m:
When creating lambda predicates, permute the arguments so
that all input arguments come before all output arguments.
call_gen.m:
When generating higher-order predicate calls, don't abort
if outputs precede inputs; instead, generate code assuming
that the called predicate's args have been permuted so that
the inputs to come before all the outputs.
Estimated hours taken: 8
A large step in cleaning up the determinism system.
simplify:
Determinism analysis should not modify the code of the procedures it
checks, yet we need to massage some goals to make them acceptable to
the code generator. The obvious solution is to perform this massaging
after analysis is finished. This is what this new module does.
det_util:
New module to hold types and predicates used in more than one module
involved with the determinism system. Some types and/or predicates
used to be in switch_detection, det_analysis, det_report, but the
misc_info type has been expanded and renamed det_info.
det_analysis:
Don't modify the goal being analyzed except to insert "some" goals.
This is important because the relevant part of det_analysis knows
only the current inferred determinism of the goal, not its final
determinism. The modification code is now in simplify (after some
fixes).
Import det_util. Move some utility preds to det_util.
Export more of the determinism tables; some are needed in simplify.
det_report:
Import det_util. Move some utility preds to det_util.
Add some more warning messages.
cse_detection:
Import det_util.
switch_detection:
Import det_util. Move some utility preds to det_util.
passes_aux:
Defined a predicate for traversing the HLDS hierarchy for processing
all the non-imported procedures.
Defined write_proc_progress_message to complement
write_progress_message (which has been renamed
write_pred_progress_message).
dead_proc_elim, modes, typecheck, unique_modes:
Use write_{proc/pred}_progress_message as appropriate.
hlds_out:
Add a new predicate hlds_out__write_pred_proc_id.
hlds_module:
Improve an abort message.
llds_out:
Formatting changes.
mercury_compile:
Call simplify__proc through the new traversal predicate in passes_aux.
Estimated hours taken: 3
options:
Add a new option, --branch-delay-slot, intended for use by mc on
the basis of the configuattion script. It says whether the machine
architecture has delays slots on branches.
The setting of option should affect whether we set
--optimize-delay-slots at -O2, but this doesn't work yet.
hlds_goal:
Add an extra field to hold follow_vars infromation to disjunctions,
switches and if-then-elses. I intend to use this information to
generate better code.
*.m:
Changes to accommodate the extra field.
Estimated hours taken: 10
hlds, hlds_module, hlds_pred, hlds_goal, hlds_data:
Divided the old hlds.m into four files:
hlds_module.m defines the data structures that deal with issues
that are wider than a single predicate. These data structures are
the module_info structure, dependency_info, the predicate table
and the shape table.
hlds_pred.m defined pred_info and proc_info, pred_id and proc_id.
hlds_goal.m defines hlds__goal, hlds__goal_{expr,info}, and the
other parts of goal structures.
hlsd_data.m defines the HLDS types that deal with issues related
to data and its representation: function symbols, types, insts, modes.
It also defines the types related to determinism.
hlds.m is now an empty module. I have not removed it from CVS
because we may need the name hlds.m again, and CVS does not like
the reuse of a name once removed.
other modules:
Import the necessary part of hlds.
det_analysis:
Define a type that was up to now improperly defined in hlds.m.
prog_io:
Move the definition of type determinism to hlds_data. This decision
may need to be revisited when prog_io is broken up.
dnf, lambda:
Simplify the task of defining predicates.
llds:
Fix some comments.
mercury_compile:
If the option -d all is given, dump all HLDS stages.
shape, unused_args:
Fix formatting.
Estimated hours taken: 3
compiler/{cse,switch}_detection.m:
Fix bugs which lead to the wrong unification being hoisted
(cse_detection.m) or the wrong unification being marked
as never-failing (switch_detection.m). Make sure the difficult
cases are rejected as determinism errors rather than causing
incorrect code to be generated.
Estimated hours taken: 8
Fix a bug which caused the compiler to miscompile
value_number__substitute_access_vns.
compiler/cse_detection.m:
In find_bind_var_for_cse, ensure that if the variable which
we are trying to hoist is bound to a different functor than
the one we're searching for, then we stop searching for
a match. This is necessary, because the code that checks
for a match assumes that the variable we're trying to hoist
has not yet been bound.
Estimated hours taken: 1.5
Undo dylan's changes in the names of some library entities,
by applying the following sed script
s/term_atom/term__atom/g
s/term_string/term__string/g
s/term_integer/term__integer/g
s/term_float/term__float/g
s/term_context/term__context/g
s/term_functor/term__functor/g
s/term_variable/term__variable/g
s/_term__/_term_/g
s/std_util__bool_/bool__/g
to all the `.m' and `.pp' files in the compiler and library directories.
The reason for undoing these changes was to minimize incompatibilities
with 0.4 (and besides, the changes were not a really good idea in the first
place).
I also moved `bool' to a separate module.
The main reason for that change is to ensure that the `__' prefix is
only used when it genuinely represents a module qualifier.
(That's what dylan's changes were trying to acheive, but `term__'
does genuinely represent a module qualifier.)
compiler/*.m:
Apply sed script above;
where appropriate, add `bool' to the list of imported modules.
Estimated hours taken: 4
More changes to finally fix the compiler so that it handles
Simon Taylor's nasty test case correctly.
Change unique_modes.m to invoke modecheck_unify_procs in unify_procs.m,
in case unique_modes.m adds new unify_requests for unification predicates
with `mostly_unique' modes.
switch_detection.m, cse_detection.m, det_analysis, unique_modes:
Export new predicates to process a single procedure at a time.
cse_detection.m:
Rearrange things so that it only redoes mode checking and switch
detection for the single procedure, not for a every mode of a predicate,
by calling `modecheck_proc' and `detect_switches_in_proc'.
hlds.m:
Add new field `can_process' to the proc_info.
modes.m, unique_modes.m:
Don't modecheck a procedure if its can_process field = no.
unify_proc.m:
Set the can_process field to `no' when adding unify procs after
a call to unify_proc__request_unify, and then back to yes again
when we are ready to process them in modecheck_unify_procs.
Add a new parameter to modecheck_unify_procs which specifies
whether we need to do ordinary mode checking or unique mode
checking. If we need to do unique mode checking, then after
doing ordinary mode checking, invoke `detect_switches_in_proc',
`cse_detect_in_proc', `determinism_check_proc', and
`unique_modes__check_proc' on the procedure.
unique_modes.m:
After checking ordinary predicates, invoke modecheck_unify_procs.
Add very_verbose progress messages.
Estimated hours taken: 6
Rearrange the ordering of the different phases in the compiler.
Moved lambda elimination (lambda.m) after unique_modes.m,
because mode analysis must have been fully completed before lambda
elimination, so that we get the right mode on the introduced
predicates. Also moved inlining.m and common.m after unique modes,
since they are optimization passes, not semantic checking passes.
The cse_detection.m, switch_detection.m, and determinism.m passes now
need to recursively traverse lambda goals. (Previously they assumed
that lambda goals had already been eliminated.)
mercury_compile.pp:
Move the inlining.m and common.m passes from semantic_phases
to middle_phases.
polymorphism.m:
Remove the code which called lambda.m.
switch_detection.m:
Recursively traverse lambda goals.
cse_detection.m:
Recursively traverse lambda goals.
Also, when redoing mode analysis and switch detection,
we shouldn't reinvoke lambda.m.
det_analysis.m, det_report.m:
Recursively traverse lambda goals, check for determinism
errors in them, and report them.
Also, print the calling predicate name & mode in the error
message for calls to predicates with cc_* determinism in
all-solutions contexts.
modes.m:
Add an extra argument to modecheck_unification that specifies
how we should recursively process lambda goals, so that we
can do the right thing when called from unique_modes.m.
The right thing in this case is to call unique_modes__check_goal
instead of modecheck_goal, and to then invoke lambda__transform_lambda
on the result.
unique_modes.m:
Make sure we don't clobber the predicate table, since we now
indirectly call lambda__transform_lambda, which inserts new
predicates into the table.
Also, simplify the code a little and add a sanity check.
lambda.m:
Make some changes that were needed because lambda.m now comes
directly after (unique_)modes.m not after polymorphism.m.
Estimated hours taken: _2___
Change names with badly placed double underscores (ie where the part of
a name before a double underscore is not the same as the module name.)
Reflect changes in the library interface.
compiler/*:
Use the newer, more correct form of the term and bool names.
Predicates "bool__" are now "std_util__bool" and labels of
the term ADT are now "term_" instead of "term__".
compiler/vn*.m:
change all names "vn__*" to a correct module prefix. All the
names remain qualified.
compiler/hlds.m:
s/\<is_builtin__/hlds__is_builtin_/g
s/\<dependency_info__/hlds__dependency_info_/g
compiler/unify_proc.m:
s/\<unify_proc_info__/unify_proc__info_/g
compiler/transform.m:
s/\<reschedule__conj/transform__reschedule_conj/g
Estimated hours taken: 15
(Debugging 3 people * 3 hours, design 2 hours, coding 4 hours.)
Fix design error which led to the bug reported by Philip Dart:
cse_detection was reinvoking mode analysis, which converted
higher-order pred terms into lambda expressions, but was
not reinvoking polymorphism.m, and so they remained as
lambda expressions, which caused the code generator to generate
incorrect code.
compiler/polymorphism.m:
Move the stuff for handling lambda expressions into
a new file lambda.m.
compiler/lambda.m:
New file. Contains the lambda expression handling
stuff from polymorphism.m, plus new code to traverse
the HLDS for a predicate applying this transformation
to each lambda expression in the procedure bodies
for that predicate.
compiler/cse_detection.m:
After re-running mode analysis, invoke lambda__process_pred
to transform away lambda expressions.
Estimated hours taken: 0.1
compiler/cse_detection.m:
Rename a function symbol.
compiler/middle_rec.m:
Fix earlier overhast commit.
compiler/options.m:
Change help message for --num-real-regs.
excess:
A new pass to remove unnecessary assignment unifications.
mercury_compile:
Call the new excess assignment module.
options:
Add a new option, excess_assign, to control the new optimization.
Add another, num-real-regs, to specify how many of r1, r2 etc are
actually real registers. The default is now set to 5 for kryten;
later it should be supplied by the mc script, with a value determined
at configuration time.
tag_switch:
Use num-real-regs to figure out whether it is likely to be worthwhile
to eliminate the common subexpression of taking the primary tag of
a variable. Also fix an old performance bug: the test for when a
jump table is worthwhile was reversed.
value_number, vn_block:
Do value numbering on extended basic blocks, not basic blocks.
vn_debug:
Modify an information message.
labelopt:
Clean up an export an internal predicate for value numbering. Replace
bintree_set with set.
middle_rec:
Prepare for the generalization of middle recursion optimization
to include predicates with an if-then-else structure.
cse_detection:
Fix a bug: when hoisting a common desconstruction X = f(Yi), create
new variables for the Yi. This avoids problems with any of the Yis
appearing in other branches of the code.
goal_util:
Add a new predicate for use by cse_detection.
common:
Fix a bug: recompute instmap deltas, since they may be affected by the
optimization of common structures.
code_info:
Make an error message more explicit.
det_analysis:
Restrict import list to the needed modules.
*.m:
Import assoc_list.
1. A bug fix and a new warning for quantification
quantification.m:
Fix bug in renaming apart of lambda goals: it used to
sort the lambda variables. Improve efficiency slightly.
Add some comments for quantification__rename_apart.
Use more informative variable names in a couple of places.
quantification.m, make_hlds.m, mercury_to_mercury.pp, options.m:
Add code to quantification.m to detect variables with
overlapping scopes, and pass back a list of warnings.
Add code to make_hlds.m to print out the warnings, if
the new option warn_overlapping_scopes was enabled (as
it is by default). Add code to options.m and
mercury_to_mercury.pp to handle the new warning
option.
common.m, cse_detection.m, follow_code.m, unify_proc.m,
Add an extra argument `_Warnings' to calls to
`implicitly_quantify_clause_body', as required by the
above change.
goal_util.m:
Export the predicate goal_util__rename_var_list for use by
quantification.m.
2. A (very incomplete) start to a new backend which will generate
high-level, debuggable C code.
options.m:
Add new option --high-level-C.
mercury_to_mercury.pp:
Handle new option.
mercury_to_c.m:
New file.
llds.m, hlds_out.m:
Export predicates for use by mercury_to_c.m.
The changes made allow declarations of the form:
:- pragma(c_code, predname(Varname1::mode1, Varname2::mode2, ...),
"Some C code to execute instead of a mercury clause;").
There are still a couple of minor problems to be fixed in the near future:
If there is a regular clause given as well as a pragma(c_code, ...) dec, it
is not handled well, and variables names '_' are not handled well.
prog_io.m:
parse the pragma(c_code, ...) dec.
hlds.m:
define a new hlds__goal_expr 'pragma_c_code'.
make_hlds.m:
insert the pragma(c_code, ...) dec. as a pragma_c_code into the hlds.
det_analysis.m:
infer that pragma_c_code goals are det.
modes.m:
convince the mode checker that the correct pragma variables are bound
etc.
quantification.m:
quantify the variables in the pragma(c_code, ...) dec.
code_gen.pp:
convert pragma_c_code into pragma_c (in the llds).
llds.m:
define a new instr, pragma_c. Output the pragma_c
hlds_out.m:
mercury_to_mercury.m:
mercury_to_goedel.m:
spit out pragma(c_code, ...) decs properly
*.m: handle the new pragma_c_code in the hlds or the new pragma_c in the llds
quantification.m:
Make implicit quantification rename apart vars that
are local to distinct scopes. This will help in the
singleton variable warning pass once the latter has
been changed to work on the HLDS.
These changes also allow goals of the form:
.... X ....,
some [X] Goal
which were previously not allowed.
cse_detection.m:
A 1 line bugfix from Zoltan.
det_analysis.m:
Rather than redoing quantification, construct
a correct goal_info directly in det__disj_to_ite/3.
optimize.pp:
Fix a singleton variable. Zoltan, there is an
XXX for you to read and remove if the fix is
correct.
common.m, cse_detection.m, det_analysis.m,
follow_code.m, make_hlds.m, polymorphism.m,
unify_proc.m:
Fix the calls to implicitly_quantify_clause_body and
implicity_quantify_goal.
TODO:
Update a couple of things.
parser.m:
Add a map(string, var) to the state so that varset
can be simplified.
varset.m:
Simplfy the varset structure so that the binding
of names to variables is cheaper.
-------------------------------------------------------
Implement unique modes. We do not handle local aliasing yet, so this
is still not very useful, except for io__state. Destructive update is
not yet implemented. Also note that this really only implements
"mostly unique" variables that may be non-unique on backtracking - we
don't check that you don't backtrack over I/O, for example.
prog_io.m, mode_util.m, modes.m, inst_match.m:
Major changes to Handle unique modes.
mercury_to_mercury.m, polymorphism.m, prog_out.m, undef_modes.m:
Use `ground(Uniqueness)' rather than just `ground'.
compiler/*.m:
Fix compile errors now that unique modes are enforced: add a
few calls to copy/2, and comment out lots of unique mode
declarations that caused problems.
typecheck.m, mode_info.m:
Hack around the use of unique modes, which doesn't work
because we don't allow local aliasing yet: make the insts
`uniq_type_info' and `uniq_mode_info' not unique at all,
and add a call to copy/2 when extracting the io_state from
type_info or mode_info.
-------------------------------------------------------
Plus a couple of unrelated changes:
hlds.m:
Change the modes for the special predicates from `ground -> ground'
to `in', so that any error messages that show those modes
come out looking nicer.
Add a new shared_inst_table for shared versions of user-defined
insts.
mercury_to_goedel.m:
Use string__is_alnum_or_underscore.
modes.m, unify_proc.m:
Fix obscure "map_lookup failed" bug triggered by a partially
instantiated mode of a complicated unification predicate, whose
procedure body contained a call the the same complicated
unification predicate in a different partially instantiated
mode.
constraint.m, cse_detection.m:
Change calls to modecheck to match new simplified interface.
context of the unification from which call was made. We we use this to generate
significantly better error messages. (There should be no more messages of the
form "call to __Unify__(blah blah blah) can fail".) Most of the files are
changed just to reflect this.
An unrelated change in det_analysis is that we now ensure the absence of
cycles by modifying the new inferred determinism in the light of the old
one, ensuring that any changes are monotonic.
In hlds_out, inhibit the printing of pseudo-imported predicates (unifications)
since nobody cares about them except sometimes Fergus.
hlds:
Removed the notion of "internal determinism"; commits are now indicated
through "some" goals. Renamed the predicate module_info_shapes to
module_info_get_shapes. Will later change other predicates also to
get consistent naming.
hlds_out:
Removed printing of internal determinisms.
det_analysis:
Changes to accommodate the new way of signalling commits. The comments
on optimizations have been modified to reflect the need for information
about whether goals can raise exceptions. Exported two predicates for
use by follow_code.
live_vars:
Changes to accommodate the new way of signalling commits.
code_gen:
Shift the handling of commits to "some" goals. Some predicates
had three versions, one for each code model; these have been
simplified significantly. The sequence of predicates has also
been rationalised a bit. There is still room for improvement
on both fronts.
disj_gen, ite_gen, middle_rec:
Changed calls to modified predicates in code_gen.
common:
When this pass changes A == f(B, C), D := f(B, C) into A == f(B, C),
D := A, it can change the scopes of A, B and C. The pass did not
take this into account; now it does. The pass is still disabled
until it has been more adequately tested.
mercury_compile:
Moved followcode into the back end. We now thread ModuleInfo through
the backend instead of Shapes, since follow_code modifies other parts
of ModuleInfo as well. Rationalised the stage numbers, WHICH MEANS
-d NUMBERS HAVE CHANGED.
follow_code:
Follow_code is now after determinism analysis, so that we can check
that it does not change the determinism of the branched structure
we are pushing code into. We now push not just builtins but also the
first call after the branched structure into the branched structure,
since this will reduce register shuffling. Made a start on pushing code
into the fronts of branched structures, when some code before the branch
point is useful only in one branch.
options:
Added an option prev_code for the (incomplete) functionality in
follow_code.
vn_flush:
Moved a comment about future functionality to where it now belongs.
cse_detection:
Removed obsolete debugging predicate.
unifications. See the comments at the top of unify_proc.m for
details of how it's done.
hlds.m:
Add new export statuses `pseudo_imported' and `pseudo_exported'
to handle unification predicates, which can now have complicated
modes.
code_gen.pp, code_info.m, common.m, constraint.m, cse_detection.m,
follow_code.m, follow_vars.m, hlds_out.m, inlining.m, live_vars,
make_hlds.m, mercury_compile.pp, modes.m, store_alloc.m,
switch_detection.m:
Handle pseudo_imported predicates.
modes.m, constraint.m:
Change modecheck to return an updated module_info, since
modechecking may insert new entries into the unify_requests
queue in the module_info. Make sure that modechecking
never inserts requests into the unify_requests queue
for code that has mode errors (or needs rescheduling).
call_gen.m, polymorphism.m:
Move duplicated code into unify_proc.m.
clause_to_proc.m:
Add new predicate clauses_to_proc for use by unify_proc.m.
unify_proc.m:
Implement complicated unifications with complicated modes.
options:
Cleanup of the option set. Main change is making linking the default,
and the replacement of -g, --compile and --link by -e, -C and -c.
WARNING: this makes the compiler inconsistent with the standard mmake
configuration, so don't do a cvs update yet unless you know what you
are doing.
conf:
Find out at configuration time how many bits the --tags low option
uses.
mercury_compile:
With the help of conf, we now make sure --tags and --num-tag-bits
are consistent. We use the new set of options. We also generate
program-specific .clean rules in .dep files.
make_tags:
Mercury_compile now makes sure that --tags and --num-tag-bits are
consistent, so make_tags need not do it.
mode_errors:
Use the new set of options.
llds:
Changes to introduce the new option use_macro_for_redo_fail and
change --mod-comments into --auto-comments.
cse_detection:
We now print the messages about redoing mode analysis, switch detection
and cse detection only if very verbose is on.
typecheck:
The error message for wrong number of arguments now gives the actual
number and the right number(s).
value_number:
Tighten the sanity check; theold version wasn't tight enough for
the code generated for prof.m.
hlds.m and lots of other files:
Change the type of the first two arguments of unify/5 in
hlds__goal_expr from `term, term' to `var, unify_rhs'
where unify_rhs is given by
:- type unify_rhs
---> var(var)
; functor(const, list(var))
; lambda_goal(list(var), hlds__goal).
This change was for two reasons: firstly, it simplifies the
code in a lot of places, and secondly, it is a step towards
implementing lambda closures and higher-order predicates
properly.
code_gen.pp:
Put the comment about the contents of stack slots before the initial
label, since this way it will be preserved by optimizations.
cse_detection.m:
Extended the search to look for cses in if-then-elses and switches
as well as disjunctions. Removed InstmapDelta from preds in which it
was not being used.
det_analysis.m:
Make the diagnosis routines more robust. The changes here avoid the
Philip's problems with lexical.m.
jumpopt.m:
Minor formatting changes.
livemap.m:
Avoid duplicating livevals instructions when optimizations are
repeated, since this can confuse some optimizations.
llds.m:
Minor documentation change.
make_hlds.m:
Minor formatting change.
mercury_compile.pp:
Do not map arguments to registers if any semantic errors have been
found.
middle_rec.m and code_aux.m:
Apply middle recursion only if tail recursion is not possible,
since tail recursion yields more efficient code.
opt_util.m:
Added a predicate to recognize constant conditions in if_vals.
Modified a predicate to make it better suited for frameopt.
optimize.pp:
Changed the way optimizations were repeated to allow better control.
Repeat peephole once more after frameopt, since the new frameopt
can benefit from this.
options.m:
Removed the --compile-to-c option, which was obsolete. Added an
option for predicate-wide value numbering, which is off by default.
Changed some of the default values of optimization flags to reduce
compilation time while holding the loss of speed of generated code
to a minimum.
peephole.m:
Look for if_vals whose conditions are constants, and eliminate the
if_val or turn it into a goto depending on the value of the constant.
Generalized the condition for optimizing incr_sp/decr_sp pairs.
value_number.m:
Added a prepass to separate primary tag tests in if-then-elses from
the test of the secondary tag, which requires dereferencing the
pointer.
Added sanity check routines to test two aspects of the generated code.
First, whether it produces the same values for the live variables as
the original code, and second, whether it has moved any dereferences
of a pointer before a test of the tag of that pointer. If either test
fails, we use the old instruction sequence.
vn_debug.m:
New messages to announce the failure of the sanity checks. They are
enabled by default, but of course can only appear if value numbering
is turned on (it is still off by default).
vn_flush.m:
Threaded a list of forbidden lvals (lvals that may not be assigned to)
through the flushing routines. When saving the old value of an lval
that is being assigned to, we use this list to avoid modifying any of
the values used on the right hand side of the assignment, even if the
saving of an old value results in assignment that requires another
save, and so on recursively.
When the flushing of a node_lval referred to a shared vn, the uses of
the access vns of the node_lvals were not being adjusted properly.
Now they are.
vn_order.m:
The ctrl_vn phase of the ordering was designed to ensure that all
nodes that need not come before a control node come after it. However,
nodes were created after this phase operated, causing leakage of some
value nodes in front of control nodes. Some of these led to pointer
dereferences before tag tests, causing bus errors. The ctrl_vn phase
is now last to avoid this problem.
vn_table.m:
Added an extra interface predicate to support the sanity checks in
value_number.
vn_util.m:
The transformation of c1-e2 into (0-e2)+c1 during vnrval simplification
could lead to an infinite loop in the compiler if c1 was zero. A test
for this case now prevents the loop.