Estimated hours taken: 20
Add support for `pragma import', which is a simplified form of
`pragma c_code'. With `pragma import', the user specifies only
the C function name, rather than a C code fragment, and the
Mercury compiler handles the argument-passing automatically.
TODO
- add documentation to doc/reference_manual.texi.
WISHLIST
- change `pragma import' and `pragma export'
to take an additional parameter indicating the language
(e.g. C, Prolog, Ada, Fortran, etc.) and/or calling
convention
compiler/prog_data.m:
Add `pragma import' to the parse tree data structure.
compiler/prog_io_pragma.m:
Add code to parse `pragma import' declarations.
compiler/mercury_to_mercury.m:
Add code to pretty-print `pragma import' declarations.
compiler/module_qual.m:
Add code to module-qualify `pragma import' declarations.
compiler/make_hlds.m:
Add code to process `pragma import' declarations,
by converting them to clauses with HLDS `c_code' instructions.
compiler/export.m:
Declare `export__exclude_argument_type' in the interface,
for use by the code for handling `pragma import' in make_hlds.m.
Change the documentation to say that this procedure is used for
both exported and imported procedures.
compiler/notes/compiler_design.html:
Document how the compiler handles `pragma import' declarations.
tests/hard_coded/Mmakefile:
tests/hard_coded/pragma_import.m:
tests/hard_coded/pragma_import.exp:
Add some test cases for `pragma import'.
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.
The purpose of this diff is to allow Mercury programs to contain
impure Mercury code without the compiler changing its behavior
inappropriately, while still allowing the compiler to aggressively
optimize pure code. To do this, we require impure predicates to be so
declared, and calls to impure predicates to be flagged as such. We
also allow predicates implemented in terms of impure predicates to be
promised to be pure; lacking such a promise, any predicate that calls
an impure predicate is assumed to be impure.
At the moment, we don't allow impure functions (only predicates),
though some of the work necessary to support them has been done.
Note that to make the operators work properly, the precedence of the
`pred' and `func' operators has been changed from 1199 to 800.
Estimated hours taken: 150
compiler/purity.m:
New compiler pass for purity checking.
compiler/hlds_goal.m:
Add `impure' and `semipure' to the goal_feature enum.
compiler/hlds_out.m:
compiler/typecheck.m:
compiler/special_pred.m:
Fixed code that prints predicate name to write something more
helpful for special (compiler-generated) predicates. Added
code to print new markers. Added purity argument to
mercury_output_pred_type. New public predicate
special_pred_description/2 provides an english description for
each compiler-generated predicate.
compiler/hlds_pred.m:
Add `impure' and `semipure' to marker enum. Added new
public predicates to get predicate purity and whether or not
it's promised to be pure.
compiler/prog_data.m:
compiler/mercury_to_mercury.m:
compiler/prog_io.m:
compiler/prog_io_goal.m:
compiler/prog_io_pragma.m:
compiler/prog_io_dcg.m:
compiler/prog_util.m:
compiler/equiv_type.m:
compiler/intermod.m:
compiler/mercury_to_c.m:
compiler/module_qual.m:
Add purity argument to pred and func items. Add new `impure'
and `semipure' operators. Add promise_pure pragma. Add
purity/2 wrapper to goal_expr type.
compiler/make_hlds.m:
compiler/mercury_to_goedel.m:
Added purity argument to module_add_{pred,func},
clauses_info_add_pragma_c_code, and to pred and func items.
Handle promise_pure pragma. Handle purity/2 wrapper used to
handle user-written impurity annotations on goals.
compiler/mercury_compile.m:
Add purity checking pass between type and mode checking.
compiler/mode_errors.m:
Distinguish mode errors caused by impure goals preventing
goals being delayed.
compiler/modes.m:
Don't delay impure goals, and ensure before scheduling an
impure goal that no goals are delayed. Actually, we go ahead
and try to schedule goals even if impurity causes a problem,
and then if it still doesn't mode check, then we report an
ordinary mode error. Only if the clause would be mode correct
except for an impure goal do we report it as an impurity problem.
compiler/simplify.m:
Don't optimize away non-pure duplicate calls. We could do
better and still optimize duplicate semipure goals without an
intervening impure goal, but it's probably not worth the
trouble. Also don't eliminate impure goals on a failing branch.
compiler/notes/compiler_design.html:
Documented purity checking pass.
doc/reference_manual.texi:
Document purity system.
doc/transition_guide.texi:
library/nc_builtin.nl:
library/ops.m:
library/sp_builtin.nl:
New operators and new precdence for `pred' and `func'
operators.
tests/hard_coded/purity.m
tests/hard_coded/purity.exp
tests/hard_coded/Mmakefile:
tests/invalid/purity.m
tests/invalid/purity_nonsense.m
tests/invalid/purity.err_exp
tests/invalid/purity_nonsense.err_exp
tests/invalid/Mmakefile:
Test cases for purity.
Estimated hours taken: 1
Improve the error messages for certain kinds of syntax errors,
where variables occur in places that they shouldn't.
compiler/prog_io_goal.m:
Change parse_qualified_term to take an extra argument,
the "containing" term, in case the term being parsed
is a term__variable, which will not have a term__context.
Use the new argument to give better error messages.
compiler/make_hlds.m:
compiler/prog_io.m:
compiler/prog_io_dcg.m:
compiler/prog_io_pragma.m:
compiler/prog_io_util.m:
Changed calls to parse_qualified_term to pass the new argument.
tests/invalid/Mmakefile:
tests/invalid/vars_in_wrong_places.m:
tests/invalid/vars_in_wrong_places.err_exp:
Test cases for the above change.
Estimated hours taken: 500
Add termination analysis to the compiler. The termination analysis
annotates each procinfo structure with termination information stating
whether each procedure is guaranteed to terminate.
Add transitive intermodule optimization to the compiler. Transitive
intermodule optimization uses .trans_opt files to store optimization
information. The difference between .trans_opt files and .opt files is
that .trans_opt files may depend on other .trans_opt files, whereas .opt
files may only depend on a .m file.
compiler/termination.m:
New file. The main module which controls the termination
analysis.
compiler/term_pass1.m:
New file. This file implements the first pass of the
termination analysis which attempts to derive relationships
between the relative sizes of variables. This information is
used by term_pass2.m
compiler/term_pass2.m:
New file. The second pass of the termination analysis attempts
to prove that each predicate or function in the program is
guaranteed to terminate.
compiler/term_util.m:
New file. Contains utilities which are used in various stages
of the termination analysis.
compiler/term_errors.m:
New file. Contains predicates for printing out error messages
produced by termination analysis.
compiler/trans_opt.m:
New file. This module contains predicates for both reading in
and writing .trans_opt files.
compiler/globals.m:
compiler/handle_options.m:
compiler/options.m:
Various modifications to handle the new options. Some of the
new options imply other options, and the `--termination-norm'
option is a string option which needs processing.
compiler/hlds_goal.m:
Added a comment that the list(uni_mode) subfield of construct,
and the unify_mode subfield of unify are not necessarily valid
when the unification applies to higher order terms.
compiler/hlds_out.m:
Added code to output termination information, as well as code to
print out the new markers.
compiler/hlds_pred.m:
Added the termination subfield to the proc_info structure and
added code to support it. Also added support for the new
markers.
compiler/make_hlds.m:
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/prog_io_pragma.m:
Added support for the new pragmas, `termination_info',
`teminates', `check_termination' and `does_not_terminate'.
compiler/prog_data.m:
Added the new pragmas to the pragma_type. Also reformatted the
type declarations to conform with the coding specifications.
compiler/prog_io.m:
Reformatted some code and comments.
compiler/mercury_compiler.m:
Added code to call the termination analyser and to call the
predicate which creates .trans_opt files.
doc/reference_manual.texi:
Documented the termination analysis and the new pragmas.
doc/user_guide.texi:
Documented the new options.
Estimated hours taken: 3
Implement `:- pragma no_inline'. This pragma prevents the compiler from
inlining predicates.
compiler/higher_order.m:
compiler/unused_args.m:
Create new preds using entire marker list, rather than just
inlining.
compiler/hlds_out.m:
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
compiler/prog_data.m:
compiler/prog_io_pragma.m:
Add code to support no_inline marker and pragma.
compiler/hlds_pred.m:
Add `no_inline' marker.
Create new preds using entire marker list, rather than just
inlining.
Change `pred_info_is_inlined' to `pred_info_requested_inlining',
as it was inappropriately named, and added
`pred_info_requested_no_inlining'.
compiler/inlining.m:
Don't inline predicates with pragma no_inlines
compiler/intermod.m:
Use `pred_info_requested_inlining'.
compiler/make_hlds.m:
Add code to check for conflicting markers, check for conflicts
between `inline' and `no_inline' markers.
Add `no_inline' markers.
Rename pragma_set_markers as pragma_add_markers, as it was
actually adding extra markers to what was already there.
doc/reference_manual.texi:
Document no_inline.
tests/hard_coded/Mmake:
tests/invalid/Mmake:
tests/hard_coded/no_inline.exp:
tests/hard_coded/no_inline.m:
tests/invalid/inline_conflict.err_exp:
tests/invalid/inline_conflict.m:
Add test cases for no_inline and conflicts between inline and
no_inline.
Estimated hours taken: 7
Making the types pred_id and proc_id (almost) abstract.
compiler/code_util.m:
Changed the type of several predicates:
code_util__make_uni_label/4 (arg 3 was int, now proc_id)
code_util__inline_builtin/4 (arg 3 was proc_id, now int)
Added predicate code_util__translate_builtin_2/6.
compiler/hlds_module.m:
Moved invalid_pred_id/1 to hlds_pred.m
compiler/hlds_pred.m:
Types pred_id/0 and proc_id are now abstract.
Added predicates:
hlds_pred__initial_pred_id/1, hlds_pred__initial_proc_id/1,
hlds_pred__next_pred_id/2, hlds_pred__next_proc_id/2,
pred_id_to_int/2, proc_id_to_int/2,
hlds_pred__in_in_unification_proc_id/1
Moved predicate invalid_pred_id/1 (from hlds_module.m).
compiler/*.m:
Miscellaneous minor changes to cast pred/proc_ids to ints
where appropriate.
Estimated hours taken: 1.5
Allow `pragma export' declarations for imported predicates.
compiler/prog_io_pragma.m:
Don't require the module name for `pragma export' declarations
to match the name of the current module.
compiler/export.m:
Use pred_info_arg_types to get the argument types,
rather than proc_info_var_types; this way is simpler,
and works for imported predicates.
Estimated hours taken: 0.5
compiler/prog_io_pragma.m:
Add support for the old `pragma c_code' syntax, with the
`is_recursive' or `may_call_mercury' argument first rather than
second, for backwards compatibility.
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.