mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-22 21:03:53 +00:00
083d376e6598628362ee91c2da170febd83590f4
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3d1acbb7f4 | Update the style of the tabling tests. | ||
|
|
fdd141bf77 |
Clean up the tests in the other test directories.
tests/invalid/*.{m,err_exp}:
tests/misc_tests/*.m:
tests/mmc_make/*.m:
tests/par_conj/*.m:
tests/purity/*.m:
tests/stm/*.m:
tests/string_format/*.m:
tests/structure_reuse/*.m:
tests/submodules/*.m:
tests/tabling/*.m:
tests/term/*.m:
tests/trailing/*.m:
tests/typeclasses/*.m:
tests/valid/*.m:
tests/warnings/*.{m,exp}:
Make these tests use four-space indentation, and ensure that
each module is imported on its own line. (I intend to use the latter
to figure out which subdirectories' tests can be executed in parallel.)
These changes usually move code to different lines. For the tests
that check compiler error messages, expect the new line numbers.
browser/cterm.m:
browser/tree234_cc.m:
Import only one module per line.
tests/hard_coded/boyer.m:
Fix something I missed.
|
||
|
|
40d69de28a |
Make doubly sure that the tabling tests aren't run in grades that do not
support tabling. (The Makefiles in tests directory should prevent this, but in at least one grade on neptune this isn't currently happening and it's rendering that machine unusable - I'll fix the Makefile issue separately.) tests/tabling/*.m: Add require_feature_set pragmas to all the tabling tests to ensure they aren't accidently run in grades that don't support tabling. |
||
|
|
cdf0383b52 |
Fix a bunch of problems with tabling that I identified in Uppsala.
Estimated hours taken: 32
Branches: main
Fix a bunch of problems with tabling that I identified in Uppsala. These fall
into two categories.
First, the tabling transformations we were using were dividing work up
too finely. This had three bad effects. First, it caused too much time to be
spent on transmitting data to and from library predicates. Second, it made the
transformations hard to document and hard to explain in a paper. Third, it
caused us to misidentify just what the various forms of tabling have in common,
and what forms of tabling work for what determinisms. To fix this problem,
this diff reorients table_builtin.m and table_gen.m from being divided
primarily by determinism to being divided by evaluation method.
Second, we weren't being careful in separating out the parts of the tabling
data structures that are needed only for debugging the tabling system itself.
The fix for this is to introduce a new grade flag, MR_MINIMAL_MODEL_DEBUG,
intended for use by implementors only, to govern whether the tabling data
structures include debug-only components. (If this flag weren't a grade flag,
the sizes of data structures created in files with different values of this
flag could be inconsistent, which is something you don't want when debugging
the complex code of the tabling infrastructure.)
compiler/table_gen.m:
Reorganize the simple (loopcheck and memo) tabling transformations
completely. Instead of separate transformations for model_det and
model_semi predicates, have separate transformations for loopcheck
and memo predicates, since this makes it easier to see (and to ensure)
that the transformation follows the required scheme. Instead of
generating nested if-then-elses, generate switches when possible.
For model_semi loopcheck and memo predicates, generate Mercury code
that obeys our scope rules by not binding output variables in the
condition of the one remaining if-then-else.
Finetune the minimal model tabling transformation by combining some
operations where this improves clarity and performance.
Order the transformation predicates logically, and move the
documentation of each form of tabling next to the code implementing
that form of tabling.
Attach call_table_gen markers to the setup goals that now all
loopcheck, memo and minimal model tabled predicates have,
to avoid having to special case the last lookup goal, and to avoid
having to have separate code for lookups in call tables versus answer
tables.
Generate unique and more meaningful variable names. Change some
predicate names to be more meaningful, both here and in the
transformed code.
Factor out some common code, e.g. for generating lookup goals,
for generating instmap_deltas and for attaching hide_debug_event
markers to goals.
Report errors in cases where the arguments of a tabled predicate
aren't completely input or output.
compiler/hlds_pred.m:
Be more strict about the determinisms of tabled predicates; permit
only the determinisms we really support in all cases, and do not
permit the ones that may happen to work in some cases.
Conform to the change of the name of a builtin.
compiler/det_report.m:
Improve the error message for cases when the determinism is
incompatible with the selected tabling mechanism.
compiler/compile_target_code.m:
compiler/handle_options.m:
compiler/options.m:
Handle the new grade component.
library/private_builtin.m:
Provide a semipure analog of the imp predicate, a call to which makes
predicates semipure rather than impure, for use in table_builtin.m.
library/table_builtin.m:
runtime/mercury_tabling_preds.h:
Change the tabling primitives in the ways required by the changes to
the tabling transformations.
Group the primitives by the tabling methods they support, and change
their names to reflect this.
Change the implementation of each of the affected predicates to be
nothing more than the invocation of a macro defined in the new header
file runtime/mercury_tabling_preds.h. The objective of this change
is to make it possible for table_gen.m to replace sequences of calls
to predicates in table_builtin.m with a single extended foreign_proc
goal whose body just invokes the corresponding macros in sequence.
That change should improve performance by allowing the variables
that flow from one tabling primitive to another to stay in x86
registers, instead of being copied to and from Mercury abstract
machines registers, which on the x86 aren't real machine registers.
Benchmarking in Uppsala verified that this is a major cost.
Mark the foreign types used for tabling as can_pass_as_mercury_type;
this was the intended use of that assertion. Make them private to the
module, since the rest of the compiler can now handle this.
Delete the implementations of the predicates for duplicate checking
and for returning answers for completed subgoals. Profiling with gprof
has shown their performance to be critical to the performance of
minimal model tabling overall, and even with our recent changes,
the compiler still can't create optimal C code for them. They are
now implemented with handwritten code in mercury_minimal_model.c.
library/term.m:
Add two utility predicates for use by table_gen.m.
library/Mmakefile:
Since much of the implementation of table_builtin.m is now in
runtime/mercury_tabling_preds.h, make its object files depend
on that header file.
runtime/mercury_conf_params.h:
runtime/mercury_grade.h:
Include MR_MINIMAL_MODEL_DEBUG when computing the grade.
runtime/mercury_minimal_model.[ch]:
Add handwritten code to implement the predicates declared as external
in table_builtin.m.
Conform to the new names of the suspension and completion predicates.
Conform to the presence of debugging fields in tabling data structures
only if MR_MINIMAL_MODEL_DEBUG is defined.
Collect a lot more statistics than before.
Reorder some functions.
Instead of saving the whole generator stack each time, which the new
statistics showed to have O(n^2) behavior on some benchmarks, save only
the segment we need to save.
runtime/mercury_tabling.h:
Conform to the fact that loopcheck and memo predicates now have
separate sets of status values, and import mercury_tabling_preds.h.
runtime/mercury_tabling.c:
runtime/mercury_hash_lookup_or_add_body.h:
Move a huge macro out of mercury_tabling.c to the new file
mercury_hash_lookup_or_add_body.h for ease of editing, and modify it to
gather more statistics.
Make the statistics report easier to read.
runtime/Mmakefile:
Mention mercury_tabling_preds.h and mercury_hash_lookup_or_add_body.h.
runtime/mercury_wrapper.h:
Provide a mechanism (--tabling-statistics in MERCURY_OPTIONS)
that causes the runtime to print tabling statistics at the ends of
executions, for use in benchmarking.
doc/user_guide.texi:
Document --tabling-statistics. (Minimal model tabling is not yet
stable enough to be documented, which is why .dmm isn't documented
either.)
scripts/canonical_grade.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/parse_grade_options.sh-subr:
scripts/mgnuc.in:
Implement the new grade component.
trace/mercury_trace.c:
trace/mercury_trace_internal.c:
Conform to changes in the runtime.
tests/debugger/*.m:
Avoid now invalid combinations of determinism and evaluation method.
tests/debugger/*.exp:
Conform to new goal paths in procedures transformed by tabling.
tests/tabling/*.m:
For tests which had predicate whose determinisms isn't compatible
with the evaluation method, change the determinism if possible,
and the evaluation method otherwise, if either is possible.
Bring these tests up to date with our coding guidelines, since they
may now appear in papers.
tests/tabling/Mmakefile:
Disable the tests whose combination of determinism and evaluation
method is no longer supported, and in which neither one can be changed.
tests/tabling/loopcheck_no_loop.{m,exp}:
Make this test case tougher.
tests/tabling/test_tabling:
Make this script more robust in the face of different kinds of
test case failures.
tests/invalid/loopcheck.{m,err_exp}:
tests/invalid/Mmakefile:
Test that we get the expected error message for an invalid combination
of determinism and evaluation method. The new test invalid/loopcheck.m
is the old test tabling/loopcheck.m.
tests/valid/Mmakefile:
Use a more general pattern to test for minimal model grades,
now that we also use .dmm as a grade component.
|
||
|
|
6554ef7daa |
Replace "is" with "=".
Estimated hours taken: 2 Branches: main Replace "is" with "=". Add field names where relevant. Replace integers with counters where relevant. |
||
|
|
1eb831eb34 |
A major cleanup of the internals of tabling.
Estimated hours taken: 40
A major cleanup of the internals of tabling.
Tabling builds up two kinds of tables, both conceptually tries. For call
tables, there is one layer in the trie for each input argument; for answer
tables, there is one layer in the trie for each output argument. However,
the way each trie node is implemented depends on the type of the relevant
argument. In addition, what is stored at the tips of the call and answer tables
also depends on what kind of tabling (e.g. loopcheck, memo, minimal model)
is being performed on the current predicate, and (in some cases) on what
stage the execution of the current predicate has reached.
Previously, all trie nodes were declared with the C type Word **, and were
cast to their actual types at the point of use, with the casts mostly being
hidden inside macros. This arrangement lacked readability and was highly
error prone. I have replaced it with a system in which trie nodes are declared
with a C type which is a pointer to a union of all the possible actual types.
There are very few casts left in the internals of the tabling system; this
change replaces them with casts at the interface (in the predicates of
private_builtin.m) and the use of the various fields of the union.
library/private_builtin.m:
Changes to conform to the changed types in mercury_tabling.h.
In some cases, improve the debugging support.
Do not table the typeinfos of polymorphic types in the
table_lookup_insert_poly predicate; since those typeinfos
are also arguments, and since they appear before the polymorphic
arguments, they have already been tabled by the time
table_lookup_insert_poly is called.
library/private_builtin.m:
library/io.m:
Add an interface to a new function in the runtime to report
statistics about the operation of the tabling system.
runtime/mercury_tabling.h:
Define and document the new types.
Add macros for allocating memory for holding one or more structures.
Make the existing macros call the versions that check for malloc
returning NULL.
runtime/mercury_tabling_macros.h:
This new file contains macros that used to be part of the file
mercury_tabling.h. The macros call the functions defined in
mercury_tabling.c, but they also optionally print debugging messages.
runtime/Mmakefile:
Add mercury_tabling_macros.h to the list of header files.
runtime/mercury_tabling.c:
Conform to the new system of C types.
Recode the hash table routines to achieve code commonality, better
debugging and statistics gathering support, much greater readability,
and the following three performance benefits:
1. The old code used open addressing to resolve collisions. In many
uses of tabling, successive searches specify keys that have
neighboring hash values, which frequently leads to very long
searches (I have observed searches that searched more than half
the slots of the hash table.) The new code uses separate chaining
to resolve collisions.
2. The old code called GC_malloc whenever it inserted a new element
into the table. The new code amortizes this overhead over a
substantial (and configurable) number of insertions.
3. In order to check whether the hash table should be expanded, the
old code was executing a float multiplication and a float comparison
on every hash table access. The new code executes the float
multiplication only when the table size is changed; in the usual
case it only executes an integer comparison, which is much cheaper.
Recode the routines for tabling typeinfos for higher speed. Instead
of storing them in a binary search tree, which requires lots of
comparisons, store the address of the type_ctor_info in a hash table
and chain its argument typeinfos from that.
Add support for expandable tables, which are implemented as arrays
indexed by key - start. This is not used yet, but will be used for
I/O tabling soon.
runtime/mercury_stacks.c:
Conform to the new system of C types for tabling.
Improve the debugging support.
runtime/mercury_wrapper.c:
When debugging tabling, set stdout to be line buffered.
runtime/mercury_engine.h:
runtime/mercury_wrapper.c:
Add a new debugging flag, -dH, for debugging the operation of hash
tables.
In mercury_wrapper.c, sort the code fragments for for processing
the arguments of -d.
runtime/mercury_trace_base.c:
Disable the generation of nuisance debugging messages from Mercury
initialization code called before main, which may have been compiled
with MR_TABLE_DEBUG enabled.
runtime/mercury_conf_param.h:
Document MR_TABLE_STATISTICS as well as MR_TABLE_DEBUG.
trace/mercury_trace_internal.c:
Disable the generation of nuisance debugging messages from Mercury
code called by the debugger that may have been compiled with
MR_TABLE_DEBUG enabled, by turning off MR_tabledebug when MR_trace
is entered. We then turn MR_tabledebug back on (even if it wasn't
turned on in the first place) when executing debugger commands
that require it to be turned on in order to work.
tests/tabling/fib.m:
Improve the (commented out) debugging support. Start the search
for the right problem size closer to its probable end point.
tests/tabling/fib_{float,string,list}.{m,exp}:
New test cases to test the low-level routines for tabling floats,
strings, and user-defined types; they are all modified versions of fib.
tests/tabling/expand.{m,exp}:
tests/tabling/expand_float.{m,exp}:
tests/tabling/expand_poly.{m,exp}:
New test cases to test the code for resizing (i.e. expanding)
hash tables, and the code for handling polymorphic arguments.
tests/tabling/Mmakefile:
Enable the new test cases.
|