compiler/typecheck_error_undef.m:
If we are reporting an error for a reference to an undefined predicate,
check whether any predicates exist whose names are "close enough"
to the name of the referenced predicate, and if yes, add to the
error message a line containing "(Did you mean x, y or z?)".
(Doing the same for references to undefined functions is future work.
The two are separate because things that look like function references
can also refer to e.g. data constructors.)
library/edit_distance.m:
Add this new module to implement the "close enough" check.
This new module is similar to the existing edit_seq.m module,
but it is designed to serve different requirements, and it seems to me
to be far from trivial to write code to meet both sets of requirements
at once.
library/library.m:
library/MODULES_DOC:
Include the new module in the standard library.
NEWS.md:
Announce the new library module.
tests/hard_coded/edit_distance_test_closest.{m,exp}:
tests/hard_coded/edit_distance_test_cost.{m,exp}:
Two new test cases, each of which tests one of the two predicates
exported by the new library module.
tests/hard_coded/Mmakefile:
Enable the new test cases.
tests/invalid/qual_basic_test2.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/undef_symbol.err_exp:
tests/invalid_submodules/undef_mod_qual.err_exp:
Expect the new "did you mean" additions to error messages.
Given a switch arm that matches several cons_ids, and which contains
one or more switches on the *same* variable, such as the arm for
f1/f2/f3/f4 below,
(
(X = f1 ; X = f2 ; X = f3 ; X = f4),
...
(
X = f1,
...
;
(X = f2 ; X = f3),
...
;
X = f4,
...
),
...
;
...
)
this new optimization
- partitions the set of cons_id in that arm (in this case, {f1,f2,f3,f4})
as finely as needed by any other the switches on X in that arm
(in this case, that is three partitions containing {f1}, {f2,f3} and {f4}),
- splits that original switch arm into N arms, one arm for each partition,
making a copy of the switch arm's goal for each partition,
- restricts any switches on the original switch variable (in this case, X)
inside the copy of the arm goal inside each new case to only the cons_ids
in that case's partition, and then replacing any resulting one-arm switches
with the just goal inside that one arm.
The code resulting from these three steps will include some code duplication
(some of the pieces of code denoted by ... in the example above would be
duplicated), but it will need to execute fewer transfers of control.
This is worthwhile because (a) the branch instructions used to implement
switches are hard to predict unless most paths through the nested switches
are rarely if ever taken, and (b) the pipeline breaks caused by branches
that are not correctly predicted are one of the two major contributors
to the runtime of Mercury programs. (The other major contributors are
data cache misses.)
The implementation of this option has two major parts.
- Part 1 consists of discovering whether a procedure body contains
any code in which a switch on a variable is nested inside an arm
of another switch on that same variable. For any instance of such
a pair of switches, it records the identity of the variable and
the set of cons_ids of the outermost arm.
- Part 2 consists of actually transforming the procedure body
by splitting each outermost switch arm thus recorded. (This part
contains all three of the steps above.)
We integrate part 1 with the usual procedure body traversal of the
simplification pass, which makes it quite cheap. In most procedure bodies,
it won't find any nested switches meeting its criteria. We execute part 2,
which is relatively expensive, only if it does.
compiler/simplify_info.m:
Add a new type, switch_arm, which represents one arm of a switch.
Add a new field to the simplify_nested_context type. Its type
is list(switch_arm), and it represents the stack of switch arms (if any)
that the goal currently being simplified is inside. simplify_goal_switch.m
uses this field to detect switches that occur inside an arm of an
ancestor goal that is also a switch on the same variable.
Add a new field to the simplify_info, a set of switch_arms,
that denotes the set of switch arms from which that detection
has actually happened, and which should therefore be
partitioned and split.
compiler/simplify_goal_switch.m:
Add the code for doing the detection and recording mentioned just above.
This is the Part 1 mentioned above.
compiler/split_switch_arms.m:
This new module implements the splitting up process.
This is the Part 2 mentioned above.
compiler/simplify.m:
Include the new module in the simplify subpackage of the check_hlds
package.
compiler/notes/compiler_design.html:
Document the new module.
compiler/simplify_proc.m:
Invoke split_switch_arms.m (part 2) if the part of simplify_goal_switch.m
implementing part 1 has found any work for it to do.
compiler/simplify_tasks.m:
Add split_switch_arms as one of the tasks that simplification
may be asked to do. Set its default value from the value of
a new optimization option that, when specified, calls for it to be done.
compiler/options.m:
Add this option, --split-switch-arms.
Change the internal name of an existing option,
everything_in_one_c_function, to the one expected by
tools/make_optimization_options_middle.
Replace the part of this file that is constructed by
tools/make_optimization_options_middle.
doc/user_guide.texi:
Document the new option.
tools/make_optimization_options_db:
Add --split-switch-arms to the optimization tuple.
Fix software rot by
- renaming optimize_tailcalls to optimize_mlds_tailcalls inside the
optimization tuple, as it has been in options.m, and
- deleting erlang_switch_on_strings_as_atoms from the opt_tuple,
as it has been from options.m.
tools/make_optimization_options_end:
Enable the new option by default at optimization level 2.
tools/make_optimization_options_middle:
Fix bugs in this script, which generates compiler/optimization_options.m.
One bug was that it referred to the opt_level and opt_space options
by the wrong name (optopt_level and optopt_space respectively).
The other bug was that it expected opt_level to be a string_special option,
when it is an int_special option.
Make the handler_file this script generates easier to put into options.m
by not generating a line that (a) already exists in options.m, and
(b) would need to have a comma put after it, if one wanted this line
to replace the copy already in options.m.
compiler/optimization_options.m:
Rebuild this file after the changes above.
compiler/simplify_goal_unify.m:
Conform to the changes above.
compiler/inst_merge.m:
Mark two predicates, inst_merge_[34], to be inlined. The intention
is that inst_merge_4 should be inlined into inst_merge_3, and then
inst_merge_3 should be inlined inside inst_merge_2; that would then
generate six levels of switches, three on one of the insts to be
merged and three on the other, which the new optimization could
then flatten. Unfortunately, inlining does not do this yet.
tests/hard_coded/test_split_switch_arms.{m,exp}:
A new test case for the the new transformation.
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
Enable the new test case, and specify the new option for it.
tests/hard_coded/Mmakefile:
Invoke cl appropriately to compile nonascii_gen.
Handle the .exe extension where necessary.
tests/DEFNS_FOR_TESTS.in:
Add a variable that says of we are using MSVC.
tests/hard_coded/*.m:
Rename modules as mentioned above.
In a few cases, where the main module's name itself had a suffix,
such as "_mod_a" or "_main", remove that suffix. This entails
renaming the .exp file as well. (In some cases, this meant that
the name of a helper module was "taken over" by the main module
of the test case.)
Update all references to the moved modules.
General updates to programming style, such as
- replacing DCG notation with state var notation
- replacing (C->T;E) with (if C then T else E)
- moving pred/func declarations to just before their code
- replacing io.write/io.nl sequences with io.write_line
- replacing io.print/io.nl sequences with io.print_line
- fixing too-long lines
- fixing grammar errors in comments
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
Update all references to the moved modules.
Enable the constant_prop_int test case. The fact that it wasn't enabled
before is probably an accident. (When constant_prop_int.m was created,
the test case was added to a list in the Mmakefile, but that list
was later removed due to never being referenced.)
tests/hard_coded/constant_prop_int.{m,exp}:
Delete the calls to shift operations with negative shift amounts,
since we have added a compile-time error for these since the test
was originally created.
library/test_bitset.m:
Instead of comparing just one bitset module (tree_bitset by default)
against set_ordlist, compare all of them (tree_bitset, sparse_bitset,
and fat_sparse_bitset) against set_ordlist.
tests/hard_coded/test_bitsets.{m,exp}:
Rename this test case from test_tree_bitset to test_bitsets, since
(through library/test_bitset.m) we now test ALL bitset implementations,
not just tree_bitset.
tests/hard_coded/Mmakefile:
Refer to the test by its new name.
The current implementation of the unsigned conversion specifiers (i.e. %x, %X,
%o, %u) for fixed-size 8-, 16- and 32-bit signed integers works by casting
theses values into (word-sized) ints and then using the existing code for
formatting ints as unsigned values. This does not work for negative values as
they are being sign extended when converted to ints. For example,
io.format("%x", [i8(min_int8)], !IO)
prints:
ffffffffffffff80 (on a 64-bit machine)
rather than just:
80
Fix the above problem by casting ints, int8s, int16s etc. that are being
formatted as unsigned values to uints and using the uint formatting code.
NOTE: the formatting code for 64-bit integers follows a different code path
and is not affected by any of this.
library/string.format.m:
Implement unsigned conversion specifiers for non-64-bit signed
integers by casting to uint and using the uint formatting code.
Add predicates for converting signed integers into uints.
The format_unsigned_int_* predicates can be deleted after this change
is installed.
compiler/format_call.m:
Implement unsigned conversion specifiers for non-64-bit signed
integers by casting to uint and using the uint formatting code.
compiler/introduced_call_table.m:
Update the table of introduced predicates.
compiler/options.m:
Add an option that can be used to test whether this fix is
installed.
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
tests/hard_coded/opt_format_sign_extend.{m,exp}:
Test that formatting code introduced by the compiler does not
accidentally sign-extend negative values.
tests/string_format/string_format_{o,x,u}.{m,exp,exp2}:
Make these tests much more comprehensive then they previously
were.
library/std_util.m:
Make std_util.pow/3 throw an exception if it is called with a negative
integer as its second argument.
tests/hard_coded/Mmakefile:
tests/hard_coded/func_exp.{m,exp}:
Add a test of pow/3.
NEWS:
Announce the above change.
The implementation of digraph.rtc was incorrect (as demonstrated in the
new test case), which meant that digraph.tc was also incorrect.
library/digraph.m:
Fix the implementation of rtc (reflexive transitive closure):
- Following the algorithm used in digraph.cliques, it needs to
traverse the graph G in *reverse* depth-first order.
- To find the clique containing a vertex X, it needs to do a DFS on
the *reversed* graph to find the vertices with a path to X.
The vertices that were previously unvisited will be members of
the same clique as X.
- Previously it found the "followers" of the elements of the clique,
and the followers of those followers, then added edges from the
members of the current clique to those followers. However, that
only includes vertices two steps removed from the clique.
I have fixed it to add edges to *all* vertices reachable from
members of the clique.
Add straightforward implementations of tc and rtc for comparison.
Add some comments.
tests/hard_coded/Mmakefile:
tests/hard_coded/digraph_tc.exp:
tests/hard_coded/digraph_tc.inp:
tests/hard_coded/digraph_tc.m:
Add test case.
NEWS:
Announce the fixes.
The recent change to sparse_bitsets broke the lex library in extras.
Specifically, we now now need to make characters an instance of the
uenum typeclass. This diff does so.
library/char.m:
Add predicates and functions for converting between unsigned integers
and characters.
Make characters an instance of the uenum typeclass.
tests/hard_coded/Mmakefile:
tests/hard_coded/char_uint_conv.{m,exp,exp2}:
Add a test of the above conversions.
NEWS:
Announce the additions.
extras/lex/lex.m:
Conform to recent changes.
NEWS:
Mention all the user-visible changes below.
library/enum.m:
Add the typeclass uenum, which is a version of the existing enum typeclass
that maps items to uints, not ints. It also uses a semidet predicate,
not a semidet function, to get back to the item from the uint.
library/sparse_bitset.m:
library/fat_sparse_bitset.m:
Make these modules operate on uints, which means requiring the items
in the sets to be instances of uenum, not enum.
If a few places, improve loops by doing previously-repeated conversions
of [u]ints into <offset, bit-to-set> pairs just once.
library/counter.m:
Define ucounters, which allocate uints. Improve documentation.
library/digraph.m:
Change digraph_keys from ints to uints, since we put them into
sparse_bitsets.
library/int.m:
Make int an instance of the uenum typeclass. This can help users
who currently put ints into sparse_bitsets.
library/pprint.m:
Prettyprint sparse_bitsets as lists of uints.
library/term.m:
Make vars instances of uenum as well as enum.
library/uint.m:
Make uint an instance of the uenum typeclass.
Add the ubits_per_uint function, which allows some casts to be avoided.
compiler/make.deps_set.m:
Change the indexes we put into sparse_bitsets from ints to uints.
compiler/make.make_info.m:
Change the source of those indexes from ints to uints.
compiler/make.top_level.m:
compiler/make.util.m:
Conform to the changes above.
compiler/pre_quantification.m:
Change zones from ints to uints, since we put them into sparse_bitsets.
tests/hard_coded/int_uenum.{m,exp}:
tests/hard_coded/Mmakefile:
Enable the new test case.
tests/valid/use_import_only_for_instance.m:
Update this extract from library/digraph.m the same way as
library/digraph.m itself.
We don't need to prevent building the 'parse' test on platforms that
don't support static linking any more, as the static linking aspect of
that test case was disabled in commit fd088a4f6.
tests/hard_coded/Mmakefile:
Delete conditions to avoid static linking on some platforms.
Rename STATIC_LINK_PROGS to DEBUG_PROGS.
Since the compiler now refuses to allow debugging in parallel grades,
tests that require debugging need to be skipped over in low-level
parallel grades or deleted.
tests/hard_coded/Mmakefile:
Disable 'parse' test in parallel grades as it happens to link with
debug libraries.
tests/par_conj/Mercury.options:
tests/par_conj/Mmakefile:
tests/par_conj/par_ddeath.exp:
tests/par_conj/par_ddeath.m:
tests/par_conj/par_ddeath_2.exp:
tests/par_conj/par_ddeath_2.m:
Delete par_ddeath and par_ddeath_2 tests that once triggered a
compiler abort with --trace deep in parallel grades.
I don't think there is much value in keeping them around.
tests/valid/Mmake.valid.common:
Skip LLDS_PROGS (i.e. test cases that required debugging) in
parallel grades.
tests/valid/Mercury.options:
tests/valid/Mmakefile:
tests/valid/untuple_bug.m:
Delete untuple_bug. It tests an old bug in the untupling
transformation, which was more a programming exercise than something
that should be used anyway.
tests/hard_coded/.gitignore:
tests/hard_coded/Mmakefile:
tests/hard_coded/getopt_maybe_option.exp:
tests/hard_coded/getopt_maybe_option.m:
Add test case for preceding fix for maybe_string options.
library/pretty_printer.m:
Replace the indent_stack data structure with one that
- can represent deep indentation in a compact data structure,
as long as that indentation consists only of standard indents, and
- can tell you how many code points the current indent stack consists of
*without* counting the code points in all the individual indent pieces
every time.
This yields a big speedup, because the code used to spend a very large
fraction of its time (between 40 and 50%) just counting the code points
in indentation. This was on stress test data which had very deep
indentation, but the cost would have been substantial even on moderately
indented docs.
Now that the indent_stack can represent more than one level of indentation
in one data structure, print up to 30 levels of standard indentation
with just one call to stream.put. By amortizing the overheads of stream.put
over a must larger part of the output, this also yields a significant
speedup.
Move the indent_stack type and its (significantly expanded) set of
operations to after the code that outputs docs, since it is just an
implementation detail (though as explained above, an important detail).
tests/hard_coded/pretty_printer_stress_test.{m,data,exp}:
A stress test for the pretty_printer whose profiling lead to the
identification of the performance problems fixed above.
tests/hard_coded/Mmakefile:
Enable the new test case, now that it is not too expensive to run
on every bootcheck.
library/string.m:
Fix string.all_match to fail if the string being tested contains
any ill-formed code unit sequences.
Fix the Mercury implementation of string.contains_char to continue
searching for the character past any ill-formed code unit sequences.
The foreign code implementations already did so.
Fix unsafe_index_next_repl and unsafe_prev_index_repl in C grades.
We indexed the C string with `ReplacedCodeUnit = Str[Index]' but
since Mercury strings have the C type `char *', ReplacedCodeUnit
could take on a negative value. When ReplacedCodeUnit == -1,
the caller would assume there is a valid encoding of a code point
beginning at Index, and therefore return `not_replaced' instead of
`replaced_code_unit(255)'.
Add casts to `unsigned char' in other places where we index C
strings.
Clarify documentation.
Document that string.duplicate_char may throw an exception.
tests/hard_coded/string_all_match.m:
tests/hard_coded/string_all_match.exp:
tests/hard_coded/string_all_match.exp2:
Add test for string.all_match.
tests/hard_coded/contains_char_2.m:
tests/hard_coded/contains_char_2.exp:
Delete older test case for string.contains_char.
tests/hard_coded/string_contains_char.m:
tests/hard_coded/string_contains_char.exp:
tests/hard_coded/string_contains_char.exp2:
Add better test for string.contains_char.
tests/hard_coded/Mmakefile:
Enable the tests.
NEWS:
Announce the changes.
Add a new predicate that tests if string contains any characters that succeed
for a given test predicate.
library/string.m:
Add the new predicate.
compiler/options.m:
Replace the predicate string_contains_whitespace/1 defined here
with a call to the new library predicate.
NEWS:
Announce the new predicate.
tests/hard_coded/Mmakefile:
tests/hard_coded/string_contains_match.{m,exp}:
Add a test of the new predicate.
library/ra_list.m:
As above.
Rename ra_list_lookup to ra_list_search, since it fails if the item
to be accessed does not exist. Add a version, ra_list_lookup, which
aborts in that case.
Add predicates to append two ra_lists, and to convert ra_lists
to just plain lists.
Change the argument order of some predicates to be more
state variable friendly.
Add some documentation.
library/bt_array.m:
Delete the moved code, and update the references to the changed predicates.
library/Mercury.options:
Now that the ra_list predicates have been moved to their own module,
stop giving bt_array.m a free pass on inconsistent predicate order.
library/MODULES_DOC:
library/library.m:
Add ra_list.m as a documented module of the Mercury standard library.
library/array.m:
Delete a predicate that served as a test for an ancient bug fix.
NEWS:
Announce both the new ra_list module, and the deletion of the predicate
from array.m.
tests/hard_coded/array_sort.m:
Don't call the predicate deleted from array.m.
tests/hard_coded/ra_list_test.{m,exp}:
A new test case to test operations on ra_lists.
tests/hard_coded/Mmakefile:
Enable the new test case.
library/cord.m:
Add is_singleton/2, foldr2/6 and foldr3/8.
NEWS:
Announce the above additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/test_cord3.{m,exp}:
Add a test of is_singleton/2 (and is_empty/1).
There is an issue on Linux/aarch64 with older versions of gcc where a
commit performed on a thread using the gcc __builtin_longjmp function
causes an assertion failure in pthread_create() if the Mercury runtime
is dynamically linked:
pthread_create.c:430: start_thread: Assertion `freesize < pd->stackblock_size' failed.
or a crash if the Mercury runtime is statically linked:
*** Mercury runtime: caught segmentation violation ***
cause: address not mapped to object
The gcc versions tested are:
BAD - gcc version 6.3.0 20170516 (Debian 6.3.0-18) from Debian 9
BAD - gcc version 8.3.0 (Debian 8.3.0-2) from Debian 10
OK - gcc version 10.2.1 20210110 (Debian 10.2.1-6) from Debian 11
on Debian with glibc.
runtime/mercury.h:
Define MR_USE_GCC_BUILTIN_SETJMP_LONGJMP if we decide to use gcc's
__builtin_setjmp and __builtin_longjmp functions instead of the
standard functions.
Use standard setjmp/longjmp on aarch64 if gcc version is < 10.
Update the comment for MR_builtin_jmp_buf to refer to the GCC manual
instead of the GCC source code. Use an array of 'intptr_t's instead
of 'void *'s, to match the manual.
tests/hard_coded/Mmakefile
tests/hard_coded/thread_commit.m:
tests/hard_coded/thread_commit.exp:
tests/hard_coded/thread_commit.exp2:
Add test case.
to allow even very long disjunctions to be parsed in constant stack space.
This fixes Mantis bug #559.
compiler/prog_item.m:
We used to represent a disjunction like ( GoalA ; GoalB ; GoalC ; GoalD )
in the parse tree as
disj_expr(ContextA, GoalA,
disj_expr(ContextB, GoalB,
disj_expr(ContextC, GoalC,
GoalD)))
To enable the changes in parse_goal.m and parse_dcg_goal.m, switch over
to representing them as
disj_expr(ContextA, GoalA, GoalB, [GoalC, GoalD])
The type of this term enforces the invariant that a disjunction
must have at least two disjuncts.
The fact that this throws away ContextB and ContextC is not a problem;
they were never used, being thrown away when converting the parse tree
to the HLDS.
compiler/parse_goal.m:
compiler/parse_dcg_goal.m:
After seeing the first comma in the above disjunction, these parsers
used to (1) parse its left operand, GoalA, (2) parse its right operand,
( GoalB ; GoalC ; GoalD), and then (3) check for errors. This code
was prevented from being tail recursive both by the presence of step 3,
and the fact that step 2 indirectly invokes another predicate that
(until my previous change to parse_goal.m) had a different determinism.
Fix the first issue by having the new predicate parse_goal_disjunction,
and its DCG variant, accumulate errors *alongside* disjuncts,
to be checked just once, at the end, outside the loop. Fix the second
issue by having parse_goal_disjunction test whether the right operand
of the semicolon has the form of a disjunction, and if it does,
recursing on it directly. This makes parse_goal_disjunction
self-tail-recursive, which should allow it to process disjunctions
of arbtrary length using fixed stack space (in grades that support
tail recursion, that is).
Move the code to flatten disjunctions from goal_expr_to_goal.m to
these modules, because it is simpler to get the right result this way
in DCG clauses (for non-DCG clauses, it works simply either way).
compiler/goal_expr_to_goal.m:
Convert the updated parse tree representation of disjunctions to HLDS,
and don't flatten disjunctions here anymore.
compiler/parse_item.m:
Add some infrastructure for debugging changes like this.
compiler/add_clause.m:
Improve the infrastructure of debugging changes like this, by making it
more selective.
To make this possible, pass the predicate name to a predicate
that did not need it before. Fix the argument order of that predicate.
compiler/make_hlds_warn.m:
Don't flatten parse tree disjunctions, since the code constructing them
has done it already.
compiler/get_dependencies.m:
compiler/module_qual.collect_mq_info.m:
compiler/parse_tree_out_clause.m:
compiler/prog_item_stats.m:
compiler/prog_util.m:
Conform to the change in prog_item.m.
compiler/instance_method_clauses.m:
Conform to the change in add_clause.m.
tests/hard_coded/flatten_disjunctions.{m,exp}:
A new test case both testing and documenting the need for flattening
disjunctions.
tests/hard_coded/Mmakefile:
Enable the new test case.
tests/invalid/require_switch_arms_detism.err_exp:
Expect updated numbers for anonymous variables. This is due to
goal_expr_to_goal.m now processing disjuncts in a different order
than before.
This fixes Mantis bug #557.
compiler/module_qual.qualify_items.m:
When module qualifying checked type, inst and mode definitions,
- qualify the checked definition as appropriate to the module section
where the definition's body is, and
- do not discard any error messages generated by this process in favor of
the error messages (if any) generated by qualifying the source
definitions the checked definition was constructed from.
The source of the Mantis #557 bug was that in a type definition,
an argument type was (a) uniquely qualifiable in the interface section,
but (b) was ambiguous in the implementation section, due to an extra
module import being visible in the implementation section. The first
change above fixes this bug. The second change is there to ensure that
if we set the flag that says we found a non-uniquely-module-qualifiable
type, inst or mode name, the error message we generate when we do that
won't be discarded. The second change also means that such errors get
two error messages generated for them, but since we always sort
error_specs and any remove duplicates, this is not a problem.
tests/hard_coded/bug557.{m,exp}:
tests/hard_coded/bug557_helper.m:
The test case for this bug, with a comment explaining the bug.
tests/hard_coded/Mmakefile:
Enable the new test case.
Add predicates for writing the UTF-8 encoding of strings to binary output
streams.
library/io.m:
library/io.primitives_write.m:
Add the new predicates.
NEWS:
Announce the additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/write_binary_utf8.{m,exp}:
Add a test of the new predicates.
It has been deprecated since Mercury 20.01.
library/random.m:
Delete the old generator.
library/array.m:
Delete the predicate random_permutation/4.
NEWS:
Announce the above.
tests/hard_coded/string_hash.m:
Update this test to use the new RNG framework.
tests/hard_coded/Mmakefile:
tests/hard_coded/random_permutation.{m,exp}:
tests/hard_coded/random_simple.{m,exp}:
Delete these tests, they were specific to the old RNG.
extras/curs/samples/nibbles.m:
extras/solver_types/library/any_array.m:
Replace use of the old RNG.
library/list.m:
Add the above predicates to the list module.
NEWS:
Announce the new predicates.
tests/hard_coded/fold_tests.{m,exp}:
Test case for the new functionality.
tests/hard_coded/Mmakefile:
Enable the new test case.
We inadventently wrote out 'coerce' casts in .opt files as:
V_2 = 'coerce expression'(V_3).
In commit 233874403f, cast_type_to_string
was changed to return "coerce expression" instead of simply "coerce"
for a slight improvement in mode errors.
compiler/hlds_out_goal.m:
Don't use the result of cast_type_to_string when when writing out
coerce casts.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/coerce_opt.exp:
tests/hard_coded/coerce_opt.m:
tests/hard_coded/coerce_opt_2.m:
Add test case.
This fixes the second problem identified by Mantis bug #548.
compiler/ml_tag_switch.m:
Detect the circumstances in which this problem would arise.
In such cases, simply fail, and let ml_switch_gen.m fall back
to implementing the switch as an if-then-else chain.
compiler/ml_switch_gen.m:
Implement that fallback.
compiler/switch_util.m:
The new code in ml_tag_switch.m needs to thread a fourth piece of state
through the predicate it passes to group_cases_by_ptag, so change
its argument list to accommodate such predicates. And since some other
modules pass the same predicates to group_cases_by_ptag and
string_binary_cases, make the same change in the argument list
of that predicate as well.
Delete one stray comment, and note that another comment seems misplaced.
compiler/ml_string_switch.m:
compiler/string_switch.m:
compiler/switch_case.m:
compiler/tag_switch.m:
Conform to the changes in switch_util.m.
tests/hard_coded/bug548.exp:
tests/hard_coded/Mmakefile:
Enable the previously-added test case for Mantis #548, after
add an .exp file for it.
library/int32.m:
Add the above casts.
NEWS:
Announce the additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/int32_int{8,16,64}.{m,exp}:
Add tests of the new functions.
While these casts can be implemented by casting via uint, the resulting
code is less readable than code that uses direct casts.
library/uint32.m:
Add cast_from_uint16/1 and cast_to_uint16/1.
NEWS:
Announce the above additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/uint32_uint16_casts.{m,exp}:
Add tests for the new casts.
While these casts can be implemented by casting via uint, the resulting code is
less readable than code that uses direct casts.
library/uint16.m:
library/uint32.m:
library/uint64.m:
Add cast_from_uint8/1 and cast_to_uint8/1 to these modules.
NEWS:
Announce the above additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/uint{16,32,64}_uint_casts.{m,exp}:
Add tests for the new casts.
runtime/mercury_string.h:
As above. Valid code points in the ranges [1D800, 1DFFF] and
[10D800, 10DFFF] were treated like invalid surrogates because the
high bits were masked away.
tests/hard_coded/Mmakefile:
tests/hard_coded/char_not_surrogate.exp:
tests/hard_coded/char_not_surrogate.m:
tests/hard_coded/string_not_surrogate.exp:
tests/hard_coded/string_not_surrogate.m:
Add test cases.
This is to support upcoming changes to how these conversions are implemented.
tests/hard_coded/uint{16,64}_to_string.{m,exp}:
Add the new tests.
tests/hard_coded/uint32_to_string.m:
Adjust a comment.
tests/hard_coded/Mmakefile:
Add the new tests.
compiler/parse_goal.m:
Fix typo: A <= B was parsed as B => B.
tests/hard_coded/Mmakefile:
tests/hard_coded/implication.exp:
tests/hard_coded/implication.m:
Add test case.
NEWS:
Announce change.
In C grades, uint32_to_string/1 is currently implemented by doing the
following:
1. Calling sprintf() to write the string into a buffer on the stack.
2. Calling strlen() on the buffer to determine the actual number of digits.
3. Allocate the appropriate amount of space on the heap.
4. Copying the string from the buffer on to the heap.
The benchmark included in this diff contains a number of alternative
implementations, all of which avoid much of the above overhead.
All of these implementations work by computing the required number of digits,
allocating space on the heap and then writing the digits into the string
backwards.
library/string.m:
Replace uint32_to_string with a faster implementation.
(This is alternative 1 in the benchmark program below.)
tests/hard_coded/Mmakefile:
tests/hard_coded/uint32_to_string.{m,exp}:
A test of uint32 to string.
benchmarks/progs/integer_to_string/uint32_conversion.m:
A program for benchmarking various uint32 to string conversion
implementations.
Add a test of uint -> uint64 conversion.
library/uint64.m:
Fix a typo that broke uint64.cast_from_uint/1.
tests/hard_coded/Mmakefile:
tests/hard_coded/from_uint_uint64.{m,exp,exp2}:
Add a test of uint -> uint64 conversion.
tests/hard_coded/from_int_int*.m:
tests/hard_coded/from_uint_uint*.m:
Fix errors in comments.
library/uint16.m:
library/uint32.m:
library/uint64.m:
library/uint8.m:
Add to each of these modules whichever subset of {from_uint, det_from_uint,
cast_from_uint} makes sense for that module.
tests/hard_coded/from_uint_uint8.{m,exp}:
tests/hard_coded/from_uint_uint16.{m,exp}:
tests/hard_coded/from_uint_uint32.{m,exp}:
Three new test cases to test the changes to uint{8,16,32}.m.
The change to uint64.m will be tested later.
tests/hard_coded/Mmakefile:
Enable the new test cases.
library/string.m:
Add ways to convert strings to uints.
NEWS:
Announce the new predicates and functions.
compiler/common.m:
The code that tries to optimize X = f(...) into X = Y if Y already
contains f(...) used to insist on the X = f(...) construction unification
being marked as a dynamic unification, i.e. one that constructs a term
on the heap on each invocation. This was part of the fix of Mantis bug
#493, which affected only the MLDS code generator, but for LLDS backend,
in the presence of --loop-invariants, it prevented a constant propagation
optimization that we had a test for (tests/hard_coded/constant_prop_2).
So make both backends happy by insisting on construct_dynamically
only for the MLDS backend.
compiler/simplify_info.m:
Record for common.m whether the backend we are targeting pays
any attention to whether a cell is construct_dynamically.
Replace some bools with bespoke types, to eliminate the risk of confusion.
compiler/hlds_goal.m:
For each construction unification marked construct_statically, record
whether the term was "born static" by being created as a static term
by a compiler pass, or whether it is a user-written unification that was
"marked static" by mark_static_terms.m. Document the meaning of both.
(I originally thought this distinction would be useful in the bug fix,
but it turned out not to be.)
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/polymorphism.m:
compiler/polymorphism_type_info.m:
Record compiler-generated static terms as born static.
compiler/mark_static_terms.m:
Mark discovered-to-be-static terms as marked static.
compiler/hlds_out_goal.m:
compiler/interval.m:
compiler/liveness.m:
compiler/loop_inv.m:
compiler/ml_unify_gen_construct.m:
compiler/quantification.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/simplify_goal.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_scope.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.versions.m:
compiler/unify_gen_construct.m:
compiler/var_locn.m:
Conform to the changes above.
tests/hard_coded/constant_prop_loop_inv.{m,exp}:
A new test case. It contains the part of the constant_prop_2 test case
that used to fail in LLDS grades with --loop-invariants.
tests/hard_coded/Mercury.options:
Specify --loop-invariants for the new test case, even if it is not
specified for constant_prop_2.
tests/hard_coded/Mmakefile:
Enable the new test case.
tests/hard_coded/constant_prop_2.m:
Fix programming style.
Add an attribute may_not_export_body to prevent a foreign_proc from
being opt-exported. Also add may_export_body for completeness.
compiler/prog_data_foreign.m:
Add type to represent those attributes.
Add a field for that attribute to pragma_foreign_proc_attributes,
plus getters and setters.
compiler/parse_pragma_foreign.m:
Parse may_export_body and may_not_export_body attributes on
foreign_proc declarations.
Detect conflicting attributes.
compiler/parse_tree_out_pragma.m:
Write out may_export_body and may_not_export_body attributes.
compiler/intermod.m:
Do not write a foreign_proc with may_not_export_body to .opt files.
compiler/simplify_proc.m:
Report an error if a foreign_proc with may_export_body is
also marked with pragma no_inline.
compiler/add_mutable_aux_preds.m:
Mark auxiliary predicates for mutables with may_not_export_body
instead of may_not_duplicate. This allows calls to those predicates
to be inlined.
doc/reference_manual.texi:
Document the new attributes.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/intermod_may_export_body.exp:
tests/hard_coded/intermod_may_export_body.m:
tests/hard_coded/intermod_may_export_body2.m:
tests/invalid/Mmakefile:
tests/invalid/test_may_export_body.err_exp:
tests/invalid/test_may_export_body.m:
Add test cases.
vim/syntax/mercury.vim:
Update vim syntax file.
NEWS:
Announce addition.
Since values of a subtype are tested for equality or compared
by first converting to the base type then testing/comparing,
it means that subtypes implicitly inherited any user-defined
equality/comparison from the base type. Allowing a subtype to also
define its own equality/comparison predicates seems more confusing
than useful, so disallow it.
compiler/prog_data.m:
Add a option noncanon_subtype to maybe_canonical.
compiler/add_type.m:
Report an error if a subtype defined in the current module
has user-defined equality or comparison.
Set the maybe_canonical field of hlds_type_defn for a subtype if the
if the base type is noncanonical. Setting it to noncanon() makes the
type_ctor_info have a MR_TypeCtorRep value of
MR_TYPECTOR_REP_*_USEREQ.
compiler/unify_proc.m:
Handle subtypes ahead of (other) noncanonical types when generating
unify or compare proc clauses.
compiler/dead_proc_elim.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/post_term_analysis.m:
compiler/special_pred.m:
Conform to changes.
doc/reference_manual.texi:
Document change.
tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_user_compare.exp:
tests/hard_coded/subtype_user_compare.m:
tests/hard_coded/subtype_user_compare2.m:
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/subtype_user_compare.err_exp:
tests/invalid/subtype_user_compare.m:
Add test cases.
library/uint8.m:
library/uint16.m:
library/uint64.m:
Add functions for setting, clearing, flipping and testing
the individual bits of a uint8, uint16 and uint64 values.
NEWS:
Announce the new functions.
tests/hard_coded/Mmakefile:
tests/hard_coded/bit_access_uint{8,16,64}.{m,exp}:
Add a test case.
library/uint32.m:
Add functions for setting, clearing, flipping and testing
the individual bits of a uint32 value.
NEWS:
Announce the new functions.
tests/hard_coded/Mmakefile:
tests/hard_coded/bit_access_uint32.{m,exp}:
Add a test case.
compiler/switch_util.m:
Rename dont_need_bit_vec_check variant of need_bit_vec_check to
dont_need_bit_vec_check_no_gaps.
Add dont_need_bit_vec_check_with_gaps (see below).
Make type_range return the correct min and max values used by a
subtype enum type. For now, it fails unless the range of values
is contiguous.
Make find_int_lookup_switch_params use the min and max values for a
type returned by type_range, not assuming 0 to the max value.
Make find_int_lookup_switch_params return
dont_need_bit_vec_check_with_gaps when a bit vector check is not
required before a table lookup, yet the table is expected to contain
dummy rows. This is the case for a cannot_fail switch on a subtype
enum type type, where the subtype does not use some values between
the min and max values.
compiler/dense_switch.m:
Make tagged_case_list_is_dense_switch use the min and max values for
a type returned by type_range, not assuming 0 to the max value.
compiler/ml_lookup_switch.m:
Expect the generated lookup table to contain dummy rows or not
depending on dont_need_bit_vec_check_{with_gaps,no_gaps}.
Conform to change to need_bit_vec_check.
compiler/lookup_switch.m:
compiler/ml_string_switch.m:
Conform to change to need_bit_vec_check.
tests/hard_coded/Mmakefile:
tests/hard_coded/dense_lookup_switch4.exp:
tests/hard_coded/dense_lookup_switch4.m:
tests/hard_coded/dense_lookup_switch_non2.exp:
tests/hard_coded/dense_lookup_switch_non2.m:
Add test cases.
doc/reference_manual.texi:
Define the standard ordering of a subtype to be the same as that of
its base type.
Suggest that subtype constructors should be declared in the same
order as in the supertype.
compiler/add_type.m:
Warn if a subtype's constructors are declared in a different
relative order to the supertype.
compiler/unify_proc.m
Generate unify/compare procs for subtypes that cast to the base type
then call the unify/compare proc for the base type. This was
previously done only for the high-level data representation.
tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_order.exp:
tests/hard_coded/subtype_order.m:
tests/warnings/Mmakefile:
tests/warnings/subtype_order.exp:
tests/warnings/subtype_order.m:
Add test cases.