Commit Graph

8 Commits

Author SHA1 Message Date
Julien Fischer
ee5e325924 Workaround a hole in exception analysis that was causing it to incorrectly
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.
2006-05-30 03:19:40 +00:00
Julien Fischer
3bfe62429c Transform lambda expressions into separate predicates when
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.
2005-08-04 09:43:16 +00:00
Julien Fischer
6ce720be87 Add the foreign proc. attribute `will_not_throw_exception'.
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.
2004-12-10 07:03:45 +00:00
Julien Fischer
980afa90c5 Add an analysis that tries to identify those procedures
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.
2004-10-16 15:08:55 +00:00
Julien Fischer
acc6161006 Fix a bug in the termination analysis that causes a software error
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.
2003-12-15 07:11:06 +00:00
Julien Fischer
caa865fd92 Fix a bug in the termination analyser where setting the termination
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.
2003-12-08 03:42:16 +00:00
Julien Fischer
6028b6c1b1 Fix a bug that caused the termination analyser to abort when using
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.
2003-10-08 05:12:40 +00:00
Simon Taylor
47a4d62dc1 Improve the test framework to make it easier to find out which tests
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.
2002-08-17 13:52:35 +00:00