My commit afe2887882 broke the ability
to run the test suite outside of a bootcheck by executing "mmake runtests"
in the tests directory. This diff fixes that.
tests/Mmake.common:
Don't define "TESTS_DIR = ..". While every single tests/*/Mmakefile
defined it as such, I overlooked the fact that tests/Mmakefile itself
defined it ".", referring to the same directory from a different starting
point. Document this easily-overlooked fact.
Rename the old runtests target, which after afe2887 runs the tests
in a single directory, as runtests_dir, to leave the target name
"runtests" itself free for tests/Mmakefile to use.
tests/Mmakefile:
Define "TESTS_DIR = .", and add a target "runtests" which invokes
"mmake runtests_dir" in each test directory.
tools/bootcheck:
Invoke "mmake runtests_dir" instead of "mmake runtests" in each
test directory.
Initialize a variable just before it is used.
tests/*/Mmakefile:
Add back the definition "TESTS_DIR = .."
A long time ago, test directories such as hard_coded had subdirectories
such as hard_coded/typeclasses. These have since been flattened out
(e.g. hard_coded/typeclasses is now just typeclasses), but there were
still remnants of the old approach. This diff deletes those remnants.
tests/*/Mmakefile:
Delete the TESTS_DIR and the SUBDIRS mmake variables; TESTS_DIR
was always set to "..", and SUBDIRS to the empty string.
Delete any references to the make variable NOT_WORKING, since
it is never used.
tests/Mmake.common:
Document that Mmakefiles in test directories don't have to set
TESTS_DIR and SUBDIRS anymore. Fix the formatting of the documentation
of the make variables they do still have to set.
Delete the targets and actions for handling subdirectories of
test directories, since there aren't any.
tests/Mmakefile:
Simplify some code.
tests/Mmake.common:
Don't invoke any actions in the clean_local and realclean_local
targets, since if using mmc --make, the builtin mmake rules
have actions for those targets as well, and make can't handle
more than one action for a target having actions. Replace those
actions with dependencies on other, unique targets that have
the actions instead.
tests/*/Mmakefile:
Avoid actions in clean_local and realclean_local targets the same way.
Sort the test names in some directories that didn't already do so.
Delete some obsolete comments.
Fix style.
tests/valid/Mmake.valid.common:
As for the Mmakefiles above, and also move the definition of a make
variable before it is needed.
tests/Mmake.common:
Replace the -j1 in the runtests_local target used by all the test
directories with $(MAYBE_J1).
tests/*/Mmakefile:
Define MAYBE_J1 it as the empty string in test directories in which
different tests don't share source files.
Define MAYBE_J1 as -j1 in test directories in which
different tests do share source files.
tests/submodules/sub2_a.m:
Add this copy of sub_a.m to allow tests in the submodules directory
to be done in parallel.
tests/submodules/accessibility2.m:
Import sub2_a.m instead of sub_a.m.
tests/warnings/ambig_types_high_level.m:
Add this copy of ambig_types.m to allow tests in the warnings directory
to be done in parallel.
tests/warnings/ambig_high_level.m:
Import ambig_types_high_level.m instead of ambig_types.m.
This file-specific setting will override a default setting of expandtabs
in $HOME/.vimrc.
*/Makefile:
*/Mmakefile:
As above.
tests/hard_coded/.gitignore:
Don't ignore the purity subdir. This ignore must have been left over
from when purity.m was a test in hard_coded, not hard_coded/purity,
and it ignored an executable, not a directory.
Branches: main
Allow testing of java grade. Requires using `mmc --make' for now.
This patch does not attempt to fix test failures.
tests/Mmake.common:
Delete unneeded Java-specific rule, which was broken.
tests/benchmarks/Mmakefile:
tests/general/Mmakefile:
tests/general/string_format/Mmakefile:
tests/grade_subdirs/Mmakefile:
tests/hard_coded/Mmakefile:
tests/recompilation/Mmakefile:
tests/term/Mmakefile:
tests/valid/Mmakefile:
Don't deliberately disable tests in java grade.
tests/*.m:
Add Java foreign code.
Write dummy procedures instead of abusing `:- external'.
Estimated hours taken: 0.2
Branches: main
tests/*/Mmakefile:
Sort the lists of tests in each directory. (We usually keep each list
sorted, but then we concatenate several lists, which loses the order.)
This gives you a better idea of how far a bootcheck still has to go.
tools/bootcheck:
Build the interface files before the rest of the files in the library
directory. Again, this gives you a better idea of how far a bootcheck
still has to go.
Make the dependencies for the slice subdirectory of the stage2 at the
same time as the other subdirs; don't let it be caught later.
library/Mmakefile:
Build the interface files in the right order.
Estimated hours taken: 3.5
Branches: main, release
Workaround a hole in exception analysis that was causing it to incorrectly
conclude that polymorphic procedures that might throw an exception would not.
The problem involved types like the following:
:- type foo
---> foo1
; foo2(bar).
:- type bar ... where equality is bar_equals.
where bar_equals is a predicate that may throw an exception.
The problem was that calls to builtin.unify (and by extension all procedures
the analysis considers conditional) with arguments of type foo were not being
treated as possibly throwing an exception. This is because exception analysis
was considering only the head of the type and not what was contained in the
body. In particular it missed the situation above where a type with
user-defined equality was embedded in a monomorphic type.
The workaround in this diff restricts exception analysis to declaring
polmorphic procedures not to throw an exception only if the properties of the
type can be determined by examining the head of the type. In practice this
means restricting it to enumerations and to types exported by the standard
library. In the case of the latter, the information is hardcoded into the
analyser. (The above is in reference to so-called type-exceptions, exceptions
that result from a call to a user-defined equality or comparison predicate
that throws an exception - the behaviour of polymorphic procedures with
user-exceptions, exceptions (ultimately) caused by a call to throw/1, is
unchanged.)
The long term fix is to add an analysis that analyses type definitions for
features of interest to other optimizations, e.g. whether they contain other
types that have user-defined equality or whether they contain existentially
quantified constructors. (Such an analysis will also eventually be required
for things like trail-usage optimization and the experimental optimization for
removing the overhead of minimal model tabling.)
compiler/exception_analysis.m:
Fix the handling of polymorphism so that we don't erroneously
conclude that procedures that may throw exceptions do not.
tests/term/Makefile:
tests/term/Mercury.options:
tests/term/exception_analysis_test2.m:
tests/term/exception_analysis_test2.trans_opt_exp:
Add a test case for the above problem and also check that
we handle enumerations with user-defined equality correctly.
Estimated hours taken: 1
Branches: main
Transform lambda expressions into separate predicates when
building the (transitive-)intermodule interfaces. Closure
analysis will not work unless this has been done.
Add a test case for the termination analysis of generic calls.
compiler/mercury_compile.m:
When building the (transitive-)intermodule optimization
interface for a module, make sure that we transform
lambda expressions if we are also going to run
closure analysis.
tests/term/Mercury.options:
tests/term/Mmakefile:
tests/term/generic_call.m:
tests/term/generic_call.trans_opt_exp:
A test case for the termination analysis of generic calls.
Estimated hours taken: 1
Branches: main
Workaround the failure of some of the test cases in the term directory
in the .debug and .decldebug grades. The test cases were not failing
as such, it was just that the argument size information produced by the
termination2 analysis in the debug grades looks a little different.
tests/term/Mmakefile:
Allow the test cases in the term directory to have multiple
expected outputs by allowing for .trans_opt_exp2 files.
tests/term/select.trans_opt_exp2:
tests/term/occur.trans_opt_exp2:
tests/term/pl4_01.trans_opt_exp2:
The argument size information produced by the termination2
analysis for these test cases in debug grades contains redundant
constraints. The redundant constraints are slipping by some of
redundancy checks because the order of the constraints differs
in the debug grades (due to differences in the HLDS between grades).
While removing these redundant constraints is certainly
possible, doing so is a relatively low priority task.
Estimated hours taken: 1
Branches: main
Enable the support for writing out termination2_info pragmas
in the .opt and .trans_opt files.
Test both termination analyses when running the test suite.
compiler/term_constr_main.m:
compiler/trans_opt.m:
Uncomment the code that causes termination2_info pragmas
to be written out the .opt and .trans_opt files.
tests/term/Mmakefile:
Run the new termination analyser on these tests as well.
tests/term/*.trans_opt_exp:
Include the expected termination2_info pragmas.
Estimated hours taken: 6
Branches: main
Add the foreign proc. attribute `will_not_throw_exception'.
This allows the user to promise the exception analysis that
foreign procs that do not have determinism erroneous and make
calls back to Mercury will not throw an exception.
The behaviour for erroneous foreign procs and those that do
not make calls back to Mercury is unchanged.
compiler/prog_data.m:
compiler/prog_io_pragma.m:
Handle the new attribute.
compiler/exception_analysis.m:
If the user has provided the `will_not_throw_exception'
attribute on a foreign proc that makes calls back to
Mercury then set then have the exception analysis
take account of this information.
Fix a typo.
compiler/det_analysis.m:
compiler/det_report.m:
Emit an error if the `will_not_throw_exception'
attribute is used on foreign procs. that have
been declared erroneous.
doc/reference_manual.texi:
Mention the new foreign proc attribute.
tests/term/Mmakefile:
tests/term/Mercury.options:
tests/term/promise_no_throw_exception.m:
tests/term/promise_no_throw_exception.trans_opt_exp:
tests/invalid/Mmakefile:
tests/invalid/erroneous_promise_throw.m:
tests/invalid/erroneous_proimse_throw.err_exp:
Test cases for the above.
vim/syntax/mercury.vim:
Highlight the annotation appropriately.
Estimated hours taken: 70
Branches: main
Add an analysis that tries to identify those procedures
in a module that will not throw an exception.
(I guess it may be more accurate to call it a non-exception analysis).
For those procedures that might throw exceptions the
analysis further tries to distinguish between those
that throw an exception as a result of a call to throw
and those that throw an exception as a result of a
call to a unification/comparison predicate that may involve
calls to user-defined equality/comparison predicates that throw
exceptions.
This sort of thing used to be done by the termination analysis,
where being able to prove termination was equated with not
throwing an exception. This no longer works now that
the termination analyser considers exception.throw/1 to
be terminating - and in fact it never quite worked anyway
because the termination analyser was not handling things
like foreign code and user-defined equality and comparison
predicates correctly.
There are currently a few limitations, the main ones being:
* we currently use transitive-intermodule optimization rather
than the intermodule-analysis framework. This may causes
problems when their are cycles in the module dependency graph.
* we currently assume that all calls to higher-order predicates
may result in an exception being thrown.
* we currently assume that all foreign procs that make calls
back to Mercury may throw exceptions.
* we currently assume that all solver types and existentially
quantified types might result in an exception being thrown.
It should be possible to remove these limitations in later
versions.
This diff also modifies the cannot_loop_or_throw family of
predicates in goal_form.m. There are now two versions of each
predicate; one that can make use of information from the
termination and exception analyses and one that cannot.
compiler/exception_analysis.m:
The new analysis.
compiler/prog_data.m:
compiler/prog_io_pragma.m:
Handle `:- pragma exceptions(...' in .opt and .trans_opt files.
compiler/hlds_module.m:
Attach information to each module about whether each procedure
in the module may throw an exception.
compiler/goal_form.m:
Rewrite the predicates in this module so that they can
optionally use information from the exception analysis.
compiler/constraint.m:
compiler/goal_util.m:
compiler/rl.m:
compiler/simplify.m:
Use information from exception and termination analyses
when performing various optimizations.
compiler/type_util.m:
Add a new predicate type_util.type_is_existq/2 that tests
whether a type is existentially quantified or not.
compiler/mercury_compile.m:
compiler/mercury_to_mercury.m:
compiler/modules.m:
compiler/options.m:
compiler/module_qual.m:
compiler/make_hlds.m:
compiler/recompilation.version.m:
compiler/trans_opt.m:
compiler/transform_hlds.m:
Minor changes needed by the above.
NEWS:
compiler/notes/compiler_design.html:
doc/user_guide.texi:
Mention the new analysis.
tests/README:
Include a description of the term directory.
tests/term/Mercury.options:
tests/term/Mmakefile:
tests/term/exception_analysis_test.m:
tests/term/exception_analysis_test.trans_opt_exp:
Add a test for the new analysis.
Estimated hours taken: 19
Branches: main
Change how the termination analysis deals with foreign_procs.
Add `terminates' and `does_not_terminate' as foreign proc attributes.
Currently the termination analysis assumes that all procedures implemented
via the foreign language interface will terminate. For foreign code
that does not make calls back to Mercury this is generally the behaviour
we want but for foreign code that does make calls back to Mercury we should
not assume termination because we do not know what Mercury procedures may be
called.
This change alters the termination analysis so that in the absence of
of any user supplied information foreign_procs that do not call Mercury
are considered terminating and those that do make calls back to Mercury
are non-terminating. This new behaviour is safer than the old behaviour.
For example some of the compiler's optimization passes may rely on
information from the termination analysis about whether or not a predicate
will terminate.
The second part of this diff adds `terminates' and `does_not_terminate'
as foreign_proc attributes. This is a cleaner way of specifying termination
properties than pragma terminates/does_not_terminate and it is also
more flexible than the pragmas. For example, in cases where procedures have
both foreign and Mercury clauses, pragma terminates/does_not_terminate
declarations will apply to both. Foreign code attributes allows us to
specify the termination properties of the foreign clauses and leave the
termination analysis to work out the termination properties of the
Mercury clauses.
compiler/hlds_pred.m:
compiler/prog_data.m:
compiler/prog_io_pragma:
Handle terminates/does_not_terminate as foreign proc attributes.
compiler/term_errors.m:
compiler/term_traversal.m:
compiler/termination.m:
Handle terminates/does_not_terminate as foreign proc attributes.
Check that the foreign proc attributes do not conflict with any
termination pragmas that the user has supplied.
Modify assumptions about the termination of foreign procs.
compiler/term_util.m:
Move some utility predicates to this module.
doc/reference_manual.texi:
Document new foreign proc attributes and the new behaviour
of the termination analysis for foreign_procs.
Fix a typo.
tests/term/Mmakefile:
tests/term/foreign_valid.m:
tests/term/foreign_valid.trans_opt_exp:
tests/warnings/Mmakefile:
tests/warnings/Mercury.options:
tests/warnings/foreign_term_invalid.m:
tests/warnings/foreign_term_invalid.exp:
Test cases for the above.
Estimated hours taken: 10
Branches: main
Fix a bug in the termination analysis that causes a software error
during pass 2. This is due to a sanity check failing.
The bug in pass 1 occurred when the analyser detected a call to a procedure
that had an infinite change constant. If the call affected the size
of any of the variables in the caller then the analyser marked it as an
error and aborted the remainder of pass 1. Any other procedures in the
SCC were not checked and their change constant was set to infinite.
The analyser did not (correctly) consider a infinite change constant to be a
fatal error, ie. one that would result in nontermination, so it ran pass 2.
However, since the remainder of the SCC had not been analysed during pass 1
it had not been determined if any of those procedures made calls to
procedures that had been marked as nonterminating. Pass 2 assumes the
opposite, namely that any SCC that is analysing will contain no calls
to procedures that have been marked as nonterminating since pass 1
should have detected this.
This diff fixes that problem by checking the remainder of the SCC for
nonterminating calls if the usual pass 1 is aborted.
compiler/term_pass1.m:
Make sure that all of the SCC is checked for calls to nonterminating
procedures when the analysis is abandoned due to a non-fatal error.
Add a comment about why this is necessary.
Add an end_module declaration.
compiler/term_pass2.m:
Document some assumptions that this module makes.
compiler/term_traversal:
Fix some formatting.
tests/term/Mmakefile:
tests/term/Mercury.options:
tests/term/inf_const_bug.m:
tests/term/inf_const_bug.trans_opt_exp
Add a new test case.
Estimated hours taken: 2
Branches: main
Fix a bug in the termination analyser where setting the termination
norm to `num-data-elems' causes the an internal abort when analysing
code involving existential typeclass constraints.
The bug is caused by the length of the list of arguments of a
functor differing from the length of the list in the weight table that
tells the compiler which arguments to count when computing the size
of that functor.
The length mismatch is caused by typeinfo related variables that
are introduced by the compiler for existentially typed terms. The
termination analyser includes them but the weight table does not.
I committed a diff a few months ago that partially fixed this problem,
but programs that use existential typeclass constraints break that fix
as well.
The diff implements the easiest solution to all this which is to
have the termination analyser remove all the typeinfo related arguments
of a term before calling term_norm.functor_norm/9.
This diff also fixes a few things in the tests/term directory, namely
making sure that we actually run the tests, updating the module qualifier
in a few .trans_opt_exp files and updating some comments.
compiler/term_norm.m:
Ignore any typeinfo related arguments that a term has when
building the weight table.
compiler/term_traversal.m:
Remove any typeinfo related arguments from the lists of
arguments and modes before computing the size of a term.
tests/term/Mercury.options:
tests/term/existential_error3.m:
tests/term/existential_error3.trans_opt_exp:
Add a regression test for this bug.
tests/term/Mmakefile:
Make sure the $(TESTS) and $(PROGS) variables are fully defined
before Mmake.common is included, otherwise the tests will not run.
Add the new regression test.
tests/term/existential_error1.m:
tests/term/existential_error2.m:
The code that caused these bugs has been moved from term_util.m
to term_norm.m. Update the references to the old filename.
tests/term/*.trans_opt_exp:
Replaces instances of `:' as the module qualifier with `.'.
Quite a few tests cases were failing because the .trans_opt
files use the latter.
Estimated hours taken: 10
Branches: main
Fix a bug that caused the termination analyser to abort when using
the `num-data-elems' norm whilst analysing code that (de)constructs
existentially typed data types.
compiler/term_util.m:
When building the weight table add any type_infos to the list
of non-recursive arguments otherwise term_util.functor_norm/9 will
throw an exception when processing an existentially typed data item.
When calculating the weight do not add arguments that correspond
to type_info related variables.
tests/term/existential_error1.m:
tests/term/existential_error2.m:
tests/term/existential_error1.trans_opt_exp:
tests/term/existential_error2.trans_opt_exp:
Tests cases for above.
tests/term/Mmakefile:
tests/term/Mercury.options:
Add new test cases. Specify which norm to use on a case-by-case
basis.
Estimated hours take: 5.5
Branches: main
Fix a bug in the termination analyser that caused it to ignore
pragma terminates/does_not_terminate declarations.
BUGS:
Delete the description of the bug regarding does_not_terminate
pragmas.
compiler/error_util:
Add a predicate describe_several_pred_names/3.
compiler/term_errors:
Add an error type indicating that the cause of non-termination was
inconsistent termination pragmas.
compiler/termination:
Fix a bug that caused pragma terminates and pragma does_not_terminate
declarations to be ignored.
Check that SCCs in the call-graph have not been annotated with
termination pragmas that are inconsistent.
Remove some old style lambda expressions.
doc/reference_manual.texi:
Describe how pramga terminates/does_not_terminate interact with
mutually recursive procedures.
tests/term/Mmakefile:
tests/term/pragma_non_term.m:
tests/term/pragma_non_term.trans_opt_exp:
tests/term/pragma_term.m:
tests/term/pragam_term.trans_opt_exp:
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
tests/warnings/pragma_term_conflict.m:
tests/warnings/pragma_term_conflict.exp:
Add some test cases for the termination pragmas.
Estimated hours taken: 14
Branches: main
Modifications to the test suite to allow testing in grade java.
mercury/tools/test_mercury:
Set-up the required CLASSPATH variable.
tests/Mmake.common:
Added a rule to build `.out' files when the grade is java.
tests/benchmarks/Mmakefile:
Enable only the working tests for the benckmarks directory.
tests/dppd/Mmakefile:
tests/general/Mmakefile:
tests/general/accumulator/Mmakefile:
tests/general/string_format/Mmakefile:
tests/general/structure_reuse/Mmakefile:a
tests/grade_subdirs/Mmakefile:
tests/hard_coded/Mmakefile:
tests/hard_coded/exceptions/Mmakefile:
tests/hard_coded/purity/Mmakefile:
tests/hard_coded/sub-modules/Mmakefile:
tests/hard_coded/typeclasses/Mmakefile:
tests/recompilation/Mmakefile
tests/term/Mmakefile:
tests/valid/Mmakefile:
Disable test cases for grade java.
tests/recompilation/test_functions:
Add framework needed to do recompilation testing for the java grade.
Estimated hours taken: 30
Branches: main
Improve the test framework to make it easier to find out which tests
failed and to reduce disk usage (important in debug grades).
Allow the tests to be run with `mmc --make' (still some failures).
Allow the user to run only the failing tests from a previous
run by using `mmake ERROR_FILE=runtests.errs', where runtests.errs
is the log file from the previous run.
tests/Mmake.common:
tests/*/Mmakefile:
Move common code (such as the code to deal with subdirectories)
to Mmake.common.
Run the tests using `mmake runtests' rather than using slightly
different runtests scripts in each directory.
Add to the output from `mmake runtests' to make it easier to
identify which tests failed in which grades.
Move per-module options into Mercury.options files so they
can be read by `mmc --make'.
Remove the last of the NU-Prolog support.
Consistently use the main module name when listing tests.
Some directories (e.g. invalid) were using the source file
name.
tests/process_log.awk:
Collect the parts of the output relating to failing tests.
tests/generate_exp:
tests/handle_options:
tests/subdir_runtests:
tests/startup:
tests/shutdown:
tests/*/runtests:
tests/recompilation/TESTS:
Removed.
tests/recompilation/test_functions:
Make sure the old result file is removed before starting
each test.
Put the mmake output for tests which are supposed to fail
into a different file for each test.
tests/warnings/Mmakefile:
Use %.c rather than $(cs_subdir)%.c in a rule.
The $(cs_subdir) part doesn't work with `mmc --make',
and isn't necessary any more (modules.m generates a rule
`module.c: $(cs_subdir)module.c').
tests/README:
Updated.
tools/bootcheck:
tools/test_mercury:
Use `mmake runtests' instead of the `runtests' script.
Add a `-f' (`--failing-tests') option to bootcheck which
runs only the failing tests from the last run.
tools/test_mercury:
tools/run_all_tests_from_cron:
Use the new framework to summarize test failures.
Estimated hours taken: 1
tools/bootcheck:
If the new --test-params option is given, copy the stage 2 Mmake.params
file to the tests directory. This capability is required to test
changes such as compiling the library without special preds and
the test cases with special preds. You get a lot of spurious errors
if a test case assumes that since it was compiled with special
preds, all other modules it is linked with are also compiled with
special preds, and thus makes calls to non-existent special preds
for the types defined in the library.
tests/*/Mmakefile:
tests/*/*/Mmakefile:
Include Mmake.params from the top level tests directory if it exists.
Estimated hours taken: 2
Mmakefile:
Rather than redefining the rule to make .trans_opt files, pass the
extra arguments through the EXTRA_MCFLAGS variable.
This fixes a bug that the test cases in the term directory were
failing as the correct arguments were no longer being passed to
mmake --trans-intermod-opt.
Estimated hours taken: 0.5
Fix bugs that were stopping *.res and *.out files being cleaned up properly.
tests/Mmake.common:
tests/general/accumulator/Mmakefile:
tests/invalid/Mmakefile:
tests/misc_tests/Mmakefile:
tests/tabling/Mmakefile:
tests/term/Mmakefile:
tests/valid/Mmakefile:
tests/warnings/Mmakefile:
Make cleaning tasks depend on (real)clean_local rather than
(real)clean. This is because tests/startup and tests/shutdown
use the *_local targets.
tests/general/Mmakefile:
Fix bugs in the recursive mmake calls.
Estimated hours taken: 0.5
tests/term/Mmakefile:
The setting of some optimization flags can require information
(including termination information) about some non-interface
procedures to be included in the .trans_opt file if intermodule
optimization is specified. For consistent results even when the
default sets of flags vary, we now disable the flags that can
have this effect.
tests/term/associative.trans_opt_exp:
Restrict the output to what you get without intermodule optimization
flags.
Estimated hours taken: 6
Fix some problems with the `--use-subdirs' option.
The compiler itself now compiles and bootstraps fine with --use-subdirs.
compiler/modules.m:
Put `.h' files in the source directory, rather than
in the `Mercury/hs' subdirectory.
compiler/mercury_compile.m:
scripts/Mmake.rules:
If `--use-subdirs' is enabled, pass `-I.' to the C compiler,
so that #include statements work relative to the source directory
rather than relative to the `Mercury/cs' subdirectory.
scripts/Mmake.vars.in:
Define $(cs_subdir), $(os_subdir) etc. variables;
these are set to the directory to use for .c, .o, etc. files,
(including the trailing `/'), or to the empty string,
if --use-subdirs is not set.
scripts/Mmake.rules:
Use $(cs_subdir), $(os_subdir) etc. to avoid the code
duplication created by my previous change to handle
--use-subdirs.
Also add lots of comments, and reorder the code
in a more logical order.
Mmakefile:
library/Mmakefile:
compiler/Mmakefile:
profiler/Mmakefile:
tests/term/Mmakefile:
tests/valid/Mmakefile:
Use $(cs_subdir), $(os_subdir) etc. to fix a few hard-coded
file-names (e.g. *.dep, *_init.[co], tree234.o) that were
used in some of the rules.
library/Mmakefile:
Add `rm -f tags' to the rule for `mmake realclean'.
tools/bootcheck:
Add `--use-subdirs' option (defaults to setting of the
MMAKE_USE_SUBDIRS environment variable).
Change the code which compares the stage2 & stage3 C files
to use the appropriate location for them based on the
setting of this option.
Estimated hours taken: 0.25
tests/term/Mmakefile:
Rename the `list' and `map' modules as `my_list' and `my_map',
to avoid a name clash with the standard library modules.
Since we now install the `.trans_opt' files for the standard
library modules, the name clash broke the test case.
(I forgot to include the change to Mmakefile in my previous commit.)
Estimated hours taken: 0.5
tests/term/Mmakefile:
Use `$(FOO:%=%.bar)' instead of the more concise
(though perhaps more cryptic) `$(FOO:=.bar)',
since the latter does not work with some old buggy
versions of GNU Make (in particuluar version 3.69).
Estimated hours taken: 1
tests/term/runtests:
tests/term/Mmakefile:
Rewrite the code for running the termination tests in the `term'
directory so that it is done in a similar way to the way that
the tests in the other test directories are run. This fixes
a bug where the test harness had `lmc3' instead of `$(MC)'.
It also makes things more consistent, ensures that the tests
will take notice of the usual runtests options and mmake variable
settings, and allows the tests to be run in parallel (e.g. -j8).
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.