compiler/intermod.m:
We used to put predicate declarations and definitions into .opt files
in order of pred_id. Since pred_ids are allocated sequentially, this
meant that the order of the pragmas in .*opt files recording analysis
results was determined by the order of the predicate declarations
in the .m file, and if this changes, everything that depends on the
.opt file has to be recompiled. Change this to put the pragmas into
an order based on the predicates' names, arities, and pred_or_func flag.
Precede each block of analysis results (one block per pragma type)
with a blank line, to make .*opt files a bit easier to read by revealing
their structure.
When printing analysis results for all the procedures of a predicate,
don't get a list of proc_ids and then look them up one by one; just
iterated over all the proc_infos in the proc_table.
Rename some predicates to make their names fit into the naming scheme
used in the rest of the module.
compiler/hlds_module.m:
compiler/hlds_pred.m:
The results of the exception, trailing and mm_tabling analyses
used to be stored in the module_info as maps from pred_proc_ids
to the results about the procedure. Change this to store them
in the proc_info of the procedure, since any code that looks up
the results of an analysis typically also wants to look up other
information in the proc_info as well. (intermod.m certainly does.)
The results of the termination, structure sharing and structure reuse
analysis were already stored in the proc_info.
compiler/add_pragma.m:
When reading in exceptions, trailing and mm_tabling pragmas,
add their information to the named procedure's proc_info,
not to a map in the module_info.
compiler/exception_analysis.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
Put analysis results into procedures' proc_infos, not into a map
in the module_info, and if need be, look it up there as well.
compiler/goal_form.m:
Look up the results of exception_analysis in procedures' proc_infos,
not in a map in the module_info.
compiler/lco.m:
Work around a bug in lco.m itself exposed by the move of analysis
results to proc_infos. When lco.m duplicates the proc_info of a procedure
that it optimizes, it now duplicates its analysis results as well.
The duplication is correct in a sense, since any results of the exception,
trailing and mm_tabling analysis that hold for the original procedure
have to hold for the duplicate copy as well, but interestingly, this extra
precision causes simplify to believe that the call from the original
procedure to duplicated procedure is dead code that can be eliminated,
since it is det and appears to have no outputs. In fact, it does have
outputs, but it returns those outputs via impure calls to store_at_ref.
While the call to store_at_ref in the duplicated procedure is marked
as impure, the call to the duplicate procedure in the original procedure
is NOT (yet) so marked.
compiler/parse_tree_out_pred_decl.m:
When printing parts of predicate declarations, e.g. as parts of pragmas
that record analysis results, don't take as an argument a context that
will never be used.
compiler/add_clause.m:
compiler/dependency_graph.m:
compiler/hlds_out_pred.m:
compiler/make_hlds_error.m:
compiler/mode_errors.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/typecheck.m:
Conform to the changes in parse_tree_out_pred_decl.m above.
tests/term/*.trans_opt_exp:
Expect the same termination analysis results as before, just in
predicate name order, and with a blank line before each block.
Estimated hours taken: 0.1
Branches: main
tests/term/*.trans_opt_exp:
Update the expected outputs of these test cases.
These have changed because of the recent change
to termination2_info pragmas.
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: 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.