Add a predicate to the calendar module for testing if a year is a leap year.
Use a more efficient method for determining this than the existing code
in the implementation of this module used (and replace that code with
a call to the new predicate).
Add the function days_to_month/2, which is a strongly typed wrapper
for the implementation function max_day_in_month_for/2.
Add a new test case covering basic operations in the calendar module,
together with the newly added operations.
library/calendar.m:
As above.
NEWS.md:
Announce the new additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/calendar_basics.{m,exp}:
Add the new test case.
Due to a copy-and-paste error introduced in commit 05fd615471,
set_line_number/2 was incorrectly setting the line number of the
current output stream, not the current input stream.
library/io.m:
Fix the above bug.
tests/hard_coded/Mmakefile:
tests/hard_coded/bad_set_line_number.{m,exp}:
Add a regression test.
Add a test for date creation, which is missing from existing calendar test.
In particular, test for the presence of the init_date argument lower bound
checks that were added in commit 5512b1be7.
tests/hard_coded/Mmakefile:
tests/hard_coded/calendar_init_date.{m,exp}:
Add the new test case.
tests/hard_coded/truncate_to_int.m:
Add this test case to test operations that convert int64s, uint64s
and uint32s to ints *safely*.
For now, these conversions are implemented only for C. Until they
have Java and C# definitions as well, they are defined here.
tests/hard_coded/truncate_to_int.exp:
tests/hard_coded/truncate_to_int.exp2:
Expected outputs on 64 and 32 bit platforms.
tests/hard_coded/Mmakefile:
Enable the new case. For now, it will fail in non-C grades.
library/int.m:
library/int{8,16,64}.m:
library/uint.m:
library/uint(8,16,32,64}.m:
Add the new function.
NEWS.md:
Announce the additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/clamp_int*.{m,exp}:
tests/hard_coded/clamp_uint*.{m,exp}:
Add tests for the new functions.
tests/hard_coded/string_code_point.m:
Avoid an ambiguity due to this module defining its own version of clamp/3.
XXX we should replace the local one with a call to int.clamp/3, but this
module constructs ranges where Max < Min and aborts with the new one.
Until now, the only integer type we generated dense switches
(including lookup switches) for was int itself; we did not do so
for any sized and/or unsigned integer types.
compiler/switch_util.m:
Simplify the representation of whether a switch is on an integer type.
The new version makes it impossible to make the mistake that caused
bug582 in the first place: not having a single representation for
for the switch being on *any* kind of integer type.
This fix requires solving a problem we never had to solve before:
representing information such as the min and max case values
in a way that works for every integer type, signed or unsigned,
sized or not. The solution that this diff adopts is to use int32s
to represent those limits, which implies that whatever the type
of the integer value being switched on, we will generate a dense
or a lookup switch for it only if all case values fit into an int32.
Since case values over two billion are vanishingly rare, this should be
an acceptable restriction.
Use uints instead of ints to represent counts of things.
Delete an unneeded pair of arguments.
compiler/lookup_switch_util.m:
Conform to the changes in switch_util.m. Use some of the new types
there to make arguments in arguments lists less confusable.
Provide some new utility operations.
Add XXXs where the basic operations we need seem not to exist.
compiler/dense_switch.m:
compiler/lookup_switch.m:
Use the new types in switch_util.m that can represent switches
on any integer type.
compiler/ml_lookup_switch.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/switch_gen.m:
Conform to the changes above, and thereby gain the ability
to generate switches on integer types other than int itself.
library/int64.m:
Add a (commmented-out) declaration of an operation that could
help resolve one of the issues in new code in the modules above.
Similar operations would be needed in the modules of other
sized integer types as well.
library/library.m:
Fix a typo.
tests/hard_coded/bug582.{m,exp}:
Add a test case for this issue. Note that while we test whether
we get the expected output, there is no simple automatic way
to detect whether it was generated using a lookup table.
tests/hard_coded/Mmakefile:
Enable the new test case.
library/int32.m:
Add the new function.
NEWS.md:
As above.
tests/hard_coded/Mmakefile:
tests/hard_coded/clamp_int32.{m,exp}:
Add a test for the new function.
library/term_io.m:
foramt_term_nl/5 should call format_term_nl_with_op_table/6, *not*
format_term_with_op_table/6, otherwise the terminating ".\n" will
not be written.
tests/hard_coded/Mmakefile:
tests/hard_coded/format_term_nl.{exp,m}:
Add a regression test.
These were inadvertently broken by updates to programming style in
commit 185443d79.
library/rbree.m:
In the implementation of ucount, increment the count for the
current node.
tests/hard_coded/Mmakefile:
tests/hard_coded/rbtree_count.{m,exp}:
Add a regression test.
library/version_array2d.m:
For every predicate or function that takes an integer argument,
if that integer is required to be non-negative, add an unsigned version.
Add bounds checks to lookup (read) and set (write) operations.
Improve the documentation of the exported operations.
Add a new implementation of the function that returns the rows
of the array as a list of lists.
Improve variable names in operations that have new unsigned versions.
NEWS.md:
Announce the new operations.
tests/hard_coded/version_array2d_test.{m,exp}:
New test case to test the operation of version_array2d.m.
It is based on the applicable parts of version_array_test.m,
but with somewhat improved organization.
tests/hard_coded/Mmakefile:
Enable the new test case.
tests/hard_coded/version_array_test.m:
Minor style fixes.
If the compiler decides that a du type should use the direct-arg
representation for some of its constructors, it must include information
about that into the .opt file of the module defining the type, in the
form of `where direct_arg is' clauses, which will be used by modules
opt-importing that module and that type. That information was not being
included for du types defined in the *interface* section of a module.
Also fix a related issue that was uncovered: a word_aligned_pointer
assertion on a foreign_type definition would have no effect if there is
a no-tag du type definition for the same type constructor.
compiler/intermod.m:
compler/intermod_decide.m:
Make should_opt_export_type_defn and some_type_needs_to_be_written
succeed for `status_exported' du type definitions with direct-arg
constructors. While `status_exported' suggests those type
definitions would be redundant in .opt files, the information about
the direct-arg constructors is not redundant.
compiler/du_type_layout.m:
Add a is_word_aligned_ptr() value to the ComponentTypeMap if a
no-tag du type also has a foreign_type definition for the current
target language with a word_aligned_pointer assertion. Previously,
this was only being done for single ctor NON no-tag du types.
Add a XXX mentioning that we silently ignore word_aligned_pointer
assertions in other cases.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/direct_arg_opt.m:
tests/hard_coded/direct_arg_opt_helper_1.m:
tests/hard_coded/direct_arg_opt_helper_1.direct_arg_opt_helper_2.m:
tests/hard_coded/direct_arg_opt.exp:
Add a test case.
tests/hard_coded/Mmakefile:
Rename multi_arm_switch.m to multi_arm_switch_1.m, since there is
also a separate test named multi_arm_switch_2.m.
Shorten the name of the trans_intermod_user_equality test case
to trans_intermod_user_eq.
tests/hard_coded/Mercury.options:
As above.
Fix references to trans_intermod_user_eq's helper modules.
tests/hard_coded/multi_arm_switch_1.exp:
tests/hard_coded/multi_arm_switch_1.inp:
tests/hard_coded/multi_arm_switch_1.m:
tests/hard_coded/trans_intermod_user_eq.exp:
tests/hard_coded/trans_intermod_user_eq.m:
tests/hard_coded/trans_intermod_user_eq_helper_1.m:
tests/hard_coded/trans_intermod_user_eq_helper_2.m:
The existing test of the ranges module in the test suite consists of an
assortment of miscellaneous regression tests inherited from G12. Extend
this test to cover all of the predicates and functions exported by the
ranges module.
tests/hard_coded/test_ranges.{m,exp}:
As above.
tests/hard_coded/Mmakefile:
Move test_ranges to the list of tests that are *not* run in
deep profiling grades since it now catches exceptions.
When this new runtime option is specified, the runtime system will use
Deep.{data,procrep} as the names of the files it writes out.
runtime/mercury_engine.h:
Add a flag to the engine that records whether this option has been
specified or not.
runtime/mercury_wrapper.c:
Set the flag if/when we see the --deep-std-name option.
runtime/mercury_deep_profiling.c:
If the new flag is set, use Deep.{data,procrep} as filenames.
doc/user_guide.texi:
Document the new option.
tools/bootcheck:
Specify the new option for bootchecks.
tests/debugger/Mmakefile:
tests/declarative_debugger/Mmakefile:
tests/hard_coded/Mmakefile:
tests/par_conj/Mmakefile:
tests/stm/Mmakefile:
When specifying a value of MERCURY_OPTIONS that overrides the value
set by tools/bootcheck, include --deep-std-name in that value.
... in some previously overlooked test cases.
tests/debugger/Mercury.options:
tests/debugger/Mmakefile:
tests/debugger/completion.completion_helper_1.m:
tests/debugger/completion.completion_helper_2.completion_helper_3.m:
tests/debugger/completion.completion_helper_2.m:
tests/debugger/completion.exp:
tests/debugger/completion.inp:
tests/debugger/completion.m:
Rename completion.sub1.m to completion.completion_helper_1.m,
rename completion.sub2.m to completion.completion_helper_2.m, and
rename completion.sub2.sub3.m to
completion.completion_helper_2.completion_helper_3.m.
tests/debugger/poly_io_retry_1.exp:
tests/debugger/poly_io_retry_1.inp:
tests/debugger/poly_io_retry_1.m:
tests/debugger/poly_io_retry_2.exp:
tests/debugger/poly_io_retry_2.inp:
tests/debugger/poly_io_retry_2.m:
Rename poly_io_retry/poly_io_retry2 to poly_io_retry_[12].
tests/debugger/shallow.exp:
tests/debugger/shallow.m:
tests/debugger/shallow_helper_1.m:
Rename shallow2.m to shallow_helper_1.m.
tests/debugger/user_event_1.exp:
tests/debugger/user_event_1.inp:
tests/debugger/user_event_1.m:
Rename user_event to user_event_1, due to the existence of user_event_2.
tests/general/Mmakefile:
tests/general/det_complicated_unify_1.exp:
tests/general/det_complicated_unify_1.m:
tests/general/det_complicated_unify_2.exp:
tests/general/det_complicated_unify_2.m:
Rename det_complicated_unify/det_complicated_unify2 to
det_complicated_unify_[12]. Note: only det_complicated_unify_1
is currently enabled.
tests/general/double_error_1.exp:
tests/general/double_error_1.m:
tests/general/double_error_2.exp:
tests/general/double_error_2.m:
Rename double_error/double_error2 as double_error_[12].
tests/general/liveness_1.exp:
tests/general/liveness_1.m:
tests/general/liveness_2.exp:
tests/general/liveness_2.m:
Rename liveness/liveness2 as liveness_[12].
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/user_defined_equality_1.exp:
tests/hard_coded/user_defined_equality_1.m:
tests/hard_coded/user_defined_equality_2.exp:
tests/hard_coded/user_defined_equality_2.m:
Rename user_defined_equality/user_defined_equality2 as
user_defined_equality_[12].
tests/tabling/Mmakefile:
tests/tabling/expand_tuple_1.exp:
tests/tabling/expand_tuple_1.m:
tests/tabling/expand_tuple_2.exp:
tests/tabling/expand_tuple_2.m:
Rename expand_tuple/expand_tuple2 as expand_tuple_[12].
... in the general and hard_coded test case directories.
tests/general/Mercury.options:
tests/general/Mmakefile:
tests/general/commit_bug_1.exp:
tests/general/commit_bug_1.m:
Rename the commit_bug test case as commit_bug_1, due to the existence
of commit_bug_2.
tests/general/intermod_type.m:
tests/general/intermod_type_helper_1.m:
Rename intermod_type2.m as intermod_type_helper_1.m.
tests/general/nondet_ite_1.exp:
tests/general/nondet_ite_1.m:
Rename the nondet_ite test case as nondet_ite_1, due to the existence
of nondet_ite_[234].
tests/general/string_format_test_1.exp:
tests/general/string_format_test_1.exp2:
tests/general/string_format_test_1.exp3:
tests/general/string_format_test_1.m:
Rename the string_format_test test case as string_format_test_1,
due to the existence of string_format_test_[23].
tests/general/string_test_1.exp:
tests/general/string_test_1.m:
Rename the string_test test case as string_test_1,
due to the existence of string_test_2.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/array_test_1.exp:
tests/hard_coded/array_test_1.m:
tests/hard_coded/array_test_2.exp:
tests/hard_coded/array_test_2.m:
Rename the array_test and array_test2 test cases as
array_test_1 and array_test_2.
tests/hard_coded/bad_indirect_reuse_1.exp:
tests/hard_coded/bad_indirect_reuse_1.m:
tests/hard_coded/bad_indirect_reuse_2.exp:
tests/hard_coded/bad_indirect_reuse_2.m:
tests/hard_coded/bad_indirect_reuse_3.exp:
tests/hard_coded/bad_indirect_reuse_3.m:
tests/hard_coded/bad_indirect_reuse_4.exp:
tests/hard_coded/bad_indirect_reuse_4.m:
Rename the bad_indirect_reuse and bad_indirect_reuse[234] test cases
as bad_indirect_reuse_[1234].
tests/hard_coded/copy_pred_1.exp:
tests/hard_coded/copy_pred_1.m:
Rename the copy_pred test case as copy_pred_1, due to the existence
of copy_pred_2.
tests/hard_coded/curry_1.exp:
tests/hard_coded/curry_1.m:
tests/hard_coded/curry_2.exp:
tests/hard_coded/curry_2.m:
tests/hard_coded/curry_2_helper_1.m:
Rename the curry and curry2 test cases as curry_1 and curry_2,
and rename the curry2_test module as curry_2_helper_1.
tests/hard_coded/cycles_1.exp:
tests/hard_coded/cycles_1.m:
tests/hard_coded/cycles_2.exp:
tests/hard_coded/cycles_2.m:
Rename the cycles and cycles2 test cases as cycles_1 and cycles_2.
tests/hard_coded/delay_partial_test_1.exp:
tests/hard_coded/delay_partial_test_1.m:
tests/hard_coded/delay_partial_test_2.exp:
tests/hard_coded/delay_partial_test_2.m:
Rename the delay_partial_test and delay_partial_test2 test cases
as delay_partial_test_1 and delay_partial_test_2.
tests/hard_coded/dense_lookup_switch_1.exp:
tests/hard_coded/dense_lookup_switch_1.m:
tests/hard_coded/dense_lookup_switch_2.exp:
tests/hard_coded/dense_lookup_switch_2.m:
tests/hard_coded/dense_lookup_switch_3.exp:
tests/hard_coded/dense_lookup_switch_3.m:
tests/hard_coded/dense_lookup_switch_4.exp:
tests/hard_coded/dense_lookup_switch_4.m:
Rename the dense_lookup_switch and dense_lookup_switch[234] test cases
as dense_lookup_switch_[1234].
tests/hard_coded/dense_lookup_switch_non_1.exp:
tests/hard_coded/dense_lookup_switch_non_1.m:
tests/hard_coded/dense_lookup_switch_non_2.exp:
tests/hard_coded/dense_lookup_switch_non_2.m:
Rename the dense_lookup_switch_non and dense_lookup_non2 test cases
as dense_lookup_switch_non_[12].
tests/hard_coded/direct_arg_partial_inst_1.exp:
tests/hard_coded/direct_arg_partial_inst_1.m:
tests/hard_coded/direct_arg_partial_inst_2.exp:
tests/hard_coded/direct_arg_partial_inst_2.m:
Rename the direct_arg_partial_inst and direct_arg_partial_inst2 test cases
as direct_arg_partial_inst_[12].
tests/hard_coded/direct_arg_tags_1.exp:
tests/hard_coded/direct_arg_tags_1.m:
Rename the direct_arg_tags test case as direct_arg_tags_1, due to
the existence of direct_arg_tags_2.
tests/hard_coded/export_test_1.exp:
tests/hard_coded/export_test_1.m:
tests/hard_coded/export_test_2.exp:
tests/hard_coded/export_test_2.m:
Rename the export_test and export_test2 test cases as export_test_[12].
tests/hard_coded/follow_code_bug_1.exp:
tests/hard_coded/follow_code_bug_1.m:
Rename the follow_code_bug test case as follow_code_bug_1, due to
the existence of follow_code_bug_2.
tests/hard_coded/foreign_type_1.exp:
tests/hard_coded/foreign_type_1.m:
tests/hard_coded/foreign_type_2.exp:
tests/hard_coded/foreign_type_2.m:
tests/hard_coded/foreign_type_3.exp:
tests/hard_coded/foreign_type_3.m:
Rename the foreign_type and foreign_type[23] test cases
as foreign_type_[123].
tests/hard_coded/functor_ho_inst_1.exp:
tests/hard_coded/functor_ho_inst_1.m:
Rename the functor_ho_inst test case as functor_ho_inst_1, due to
the existence of functor_ho_inst_2.
tests/hard_coded/functor_ho_inst_excp_1.exp:
tests/hard_coded/functor_ho_inst_excp_1.m:
Rename the functor_ho_inst_excp test case as functor_ho_inst_excp_1,
due to the existence of functor_ho_inst_excp_2.
tests/hard_coded/higher_order_syntax_1.exp:
tests/hard_coded/higher_order_syntax_1.m:
tests/hard_coded/higher_order_syntax_2.exp:
tests/hard_coded/higher_order_syntax_2.m:
Rename the higher_order_syntax and higher_order_syntax2 test cases
as higher_order_syntax_[12].
tests/hard_coded/ho_order_1.exp:
tests/hard_coded/ho_order_1.m:
tests/hard_coded/ho_order_2.exp:
tests/hard_coded/ho_order_2.m:
Rename the ho_order and ho_order2 test cases as ho_order_[12].
tests/hard_coded/lco_pack_args_1.exp:
tests/hard_coded/lco_pack_args_1.m:
Rename the lco_pack_args test case as lco_pack_args_1, due to
the existence of lco_pack_args_[23].
tests/hard_coded/loop_inv_extra_test_1.inp:
tests/hard_coded/loop_inv_extra_test_1.m:
tests/hard_coded/loop_inv_extra_test_2.inp:
tests/hard_coded/loop_inv_extra_test_2.m:
Rename the loop_inv_test0 and loop_inv_test2 test cases as
loop_inv_extra_test_1 and loop_inv_extra_test_2 respectively.
Both these test cases test "extra" functionality that the compiler
does not currently have, and thus neither is currently enabled.
tests/hard_coded/loop_inv_test_2.exp:
tests/hard_coded/loop_inv_test_2.inp:
tests/hard_coded/loop_inv_test_2.m:
Rename the loop_inv_test test case as loop_inv_test_2,
because loop_inv_test_1 was already taken (see below).
tests/hard_coded/loop_inv_test_1.exp:
tests/hard_coded/loop_inv_test_1.inp:
tests/hard_coded/loop_inv_test_1.m:
tests/hard_coded/loop_inv_test_3.exp:
tests/hard_coded/loop_inv_test_3.m:
tests/hard_coded/loop_inv_test_4.exp:
tests/hard_coded/loop_inv_test_4.m:
Rename the loop_inv_test[134] test cases as loop_inv_test_[134].
tests/hard_coded/pprint_test_1.exp:
tests/hard_coded/pprint_test_1.m:
tests/hard_coded/pprint_test_2.exp:
tests/hard_coded/pprint_test_2.m:
Rename the pprint_test and pprint_test2 test cases as pprint_test_[12].
tests/hard_coded/quantifier_1.exp:
tests/hard_coded/quantifier_1.m:
tests/hard_coded/quantifier_2.exp:
tests/hard_coded/quantifier_2.m:
Rename the quantifier and quantifier2 test cases as quantifier_[12].
tests/hard_coded/random_1.exp:
tests/hard_coded/random_1.m:
tests/hard_coded/random_2.exp:
tests/hard_coded/random_2.m:
tests/hard_coded/random_3.exp:
tests/hard_coded/random_3.m:
Rename the random[123] test cases as random_[123].
tests/hard_coded/random_shuffle_1.exp:
tests/hard_coded/random_shuffle_1.m:
tests/hard_coded/random_shuffle_2.exp:
tests/hard_coded/random_shuffle_2.m:
Rename the random_shuffle[12] test cases as random_shuffle_[12].
tests/hard_coded/string_split_1.exp:
tests/hard_coded/string_split_1.m:
Rename the string_split test case as string_split_1, due to
the existence of string_split_2.
tests/hard_coded/string_switch_1.exp:
tests/hard_coded/string_switch_1.m:
tests/hard_coded/string_switch_2.exp:
tests/hard_coded/string_switch_2.m:
tests/hard_coded/string_switch_3.exp:
tests/hard_coded/string_switch_3.m:
tests/hard_coded/string_switch_4.exp:
tests/hard_coded/string_switch_4.m:
Rename the string_switch and string_switch[233] test cases
as string_switch_[1234].
tests/hard_coded/test_cord_1.exp:
tests/hard_coded/test_cord_1.m:
tests/hard_coded/test_cord_2.exp:
tests/hard_coded/test_cord_2.m:
tests/hard_coded/test_cord_3.exp:
tests/hard_coded/test_cord_3.m:
Rename the test_cord and test_cord[23] test cases as test_cord_[123].
tests/hard_coded/trace_goal_opt.m:
tests/hard_coded/trace_goal_opt_helper_1.m:
Rename the trace_goal_opt_2 module as trace_goal_opt_helper_1.
tests/hard_coded/tuple_test_1.exp:
tests/hard_coded/tuple_test_1.m:
tests/hard_coded/tuple_test_2.exp:
tests/hard_coded/tuple_test_2.m:
Rename the tuple_test and tuple_test2 test cases as tuple_test_[12].
tests/hard_coded/version_hash_table_test_1.exp:
tests/hard_coded/version_hash_table_test_1.m:
tests/hard_coded/version_hash_table_test_2.exp:
tests/hard_coded/version_hash_table_test_2.m:
Rename the version_hash_table_test and version_hash_table_test2
test cases as version_hash_table_test_[12].
tests/hard_coded/write_reg_1.exp:
tests/hard_coded/write_reg_1.m:
tests/hard_coded/write_reg_2.exp:
tests/hard_coded/write_reg_2.m:
Rename the write_reg[12] test cases as write_reg_[12].
compiler/parse_mutable.m:
compiler/parse_type_name.m:
As above.
tests/hard_coded/higher_order_mutable.{m,exp}:
A new test case for the new capability, checking whether we can call
a closure we got out of a mutable.
tests/hard_coded/Mmakefile:
Enable the new test case.
Add the following predicates to find the first or last occurrence of a
code point in a string:
find_first_char
We already had the code to implement contains_char.
Not strictly necessary as we have sub_string_search.
find_first_char_start
Safe wrapper for unsafe_find_first_char_start.
unsafe_find_first_char_start
This is just the body of find_first_char, which should be useful for
users. Not strictly needed as we have sub_string_search_start.
find_last_char
Commonly needed.
NOTE: I also considered these predicates but discarded them for now:
:- pred find_first_char_between(string::in, char::in,
int::in, int::in, int::out) is semidet.
:- pred find_last_char_between(string::in, char::in,
int::in, int::in, int::out) is semidet.
:- pred find_first_match_between(pred(char)::in(pred(in) is semidet),
string::in, int::in, int::in, int::out) is semidet.
:- pred find_last_match_between(pred(char)::in(pred(in) is semidet),
string::in, int::in, int::in, int::out) is semidet.
The _between predicates required a bit more code than I'd like, for the
amount of use that they would (I imagine) get. The _match predicates
were just conveniences over iterating over a string manually.
All four predicates would incur calls to strlen() in C grades,
which suggests adding "unsafe" versions as well.
library/string.m:
Add the predicates above.
Implement string.contains_char using string.find_first_char.
tests/hard_coded/Mmakefile:
tests/hard_coded/string_find_char.exp:
tests/hard_coded/string_find_char.exp2:
tests/hard_coded/string_find_char.m:
Add test case.
NEWS.md:
Announce additions.
This fixes Github issue #133.
The bug occurred after jumpopt.m transformed code of the form
% if (Cond) L1
% r1 = MR_FALSE
when followed immediately by
% <epilog>
% ...
% L1:
% r1 = MR_TRUE
% <epilog>
into code of the form
% r1 = Cond
% <epilog>
The transformation left both epilogs in the instruction sequence,
even though at least the first, and probably both, were now being dead code.
The problem arose because the compiler did not clean up either dead epilogue,
leading to failed assertion in a later code optimization pass.
compiler/optimize.m:
Fix the bug by forcing the execution of the passes that clean up dead code
if jumpopt makes any changes to the instruction sequence.
compiler/jumpopt.m:
When replacing an if_val instruction whose target and fallthrough
lead to two different semidet epilogues (one assigning 0 to r1 and
one assigning 1) with a single epilogue assigning to r1 the value
of a bool expression and then returning, delete all the instructions
following the if_val up to but not including the next label.
This is because replacing the if_val by by the new epilogue makes
those instructions unreachable.
The diffs for the next two files are not part of the fix, but I noticed
the need for them while hunting the bug.
compiler/opt_debug.m:
Give a predicate a more descriptive name, and simplify its code.
Make the dumps of computed goto instructions more readable, both
by printing each target on its own line, and by printing the value
corresponding to each target.
compiler/hlds_out_type_table.m:
Format the description of arguments' offsets in heap cells
in a way that is more readable. Print just one offset for an argument
in the usual case where it is not preceded by any nonarguments such as
type_infos/typeclass_infos (i.e. if its arg-only offset is the same
as its offset from the start of the heap cell). If those two offsets
differ, then include a description of each offset with its value.
Move the description of each du type's kind (i.e. whether it is an
enum type, notag type etc) to *before* the description of its
function symbols.
tests/hard_coded/gh133.{m,exp}:
A test case for this bug, derived from the one in github issue #133.
tests/hard_coded/Mmakefile:
Enable the new test case.
The modechecking for coerce did not take into account existentially
typed arguments in the term being coerced. There are two main changes:
1. If the input (sub)term being coerced has an existential type, the
result must have the same type. Therefore, we can use the inst
approximating the input (sub)term for the result.
2. Each existentially quantified type variable or existential class
constraint on a data constructor adds a type_info or type_class_info
to the resulting heap cell. Internally, the inst for that cell will
include insts for those extra arguments, which the modechecker for
coerce will need to be aware of.
Fixes GitHub issue #132
compiler/modecheck_coerce.m:
As above.
doc/reference_manual.texi:
Account for existential types in the description of
how modechecking of coerce works.
tests/hard_coded/Mmakefile:
tests/hard_coded/coerce_existq.exp:
tests/hard_coded/coerce_existq.m:
Add test case.
Fix a bug where the compiler generated incorrect code in C# and Java
grades when a subtype type definition did not repeat the field names of
its base type. Subtypes use the same data represention with their base
type, so in target code we must use the names of fields from the
base type instead of the subtype.
compiler/hlds_data.m:
Add a field to ctor_arg_repn to tell if a constructor argument
belongs to a subtype, and if so, the field name of the corresponding
constructor argument in the base type (if any).
compiler/du_type_layout.m:
Fill in the field appropriately for the ctor_arg_repn of a subtype
constructor argument.
Rename predicates which only deal with non-subtype du types,
for clarity.
Conform to changes elsewhere.
compiler/ml_code_util.m:
Make ml_gen_hld_field_name use the field name from the base type
if generating the field name for a subtype constructor argument.
compiler/ml_type_gen.m:
Pass MaybeBaseTypeCtor to ml_gen_hld_field_name.
compiler/add_special_pred.m:
compiler/equiv_type_hlds.m:
compiler/hlds_out_type_table.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_util.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/type_ctor_info.m:
Conform to changes.
compiler/mlds.m:
Add comment.
compiler/tag_switch_util.m:
Delete comment about the bug that this change fixes.
tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_field_names.exp:
tests/hard_coded/subtype_field_names.m:
Add test case.
NEWS.md:
Announce change.
For now, the implementation covers only non-lookup switches.
compiler/builtin_ops.m:
Generalize the existing offset_str_eq binary op by adding an optional
size parameter, which, if present, restricts the equality test to look at
the given number of code units at most.
compiler/llds_out_data.m:
compiler/mlds_to_c_data.m:
Generalize the output of binop rvals whose operation is offset_str_eq.
In llds_out_data.m, fix a bug in the original code. (This bug did not
lead to problems because before this diff, we never generated this op.)
compiler/string_switch_util.m:
Add a predicate that recognizes when a trie node that is NOT a leaf
nevertheless represents the top of a stick, which means that it has
only one possible next code unit, which itself may have only one
possible next code unit, and so on, until we reach a node that *does*
have two or more next code units. (One of those may be the code unit
of the string-ending NULL character.)
compiler/ml_string_switch.m:
Use the new predicate in string_switch_util.m to generate better code
for sticks. Instead of comparing each character in the stick individually
against the relevant code unit of the string being switched on, compare
them all at once using the new binary op.
compiler/ml_switch_gen.m:
Insist on both the host machine and the target machine
using the C backend.
compiler/string_switch.m:
Implement non-lookup trie switches. The code follows the approach used
in ml_string_switch.m as much as possible, but there are plenty of
differences caused by targeting the LLDS.
Rename some predicates to specify which switch implementation method
they belong to.
Write a comment just once, and refer to it from elsewhere instead of
duplicating it at each reference site.
compiler/switch_gen.m:
Enable the use of trie switches when the option values call for it,
and when the switch is not a lookup switch.
compiler/cse_detection.m:
Do not flood the output of mmc -V with messages that have nothing to do
with the module being compiled.
compiler/options.m:
Add a way to specify --no-allow-inlining on the command line.
This can help debug code generator changes like this, by disallowing
a transform that can modify the Mercury code whose compilation process
you are trying to debug. (The documentation of the --inlining option
implies that --no-inlining should do the same job, but it does not.)
The option is not documented for users.
compiler/string_encoding.m:
Provide a version of from_code_unit_list_in_encoding that allows
non-well-formed code unit sequences as input, and provide det versions
of both versions. This is for use by both string_switch.m and
ml_string_switch.m.
compiler/hlds_goal.m:
Document the properties of case_ids.
compiler/llds.m:
Document the possibility that string constants are not well formed.
compiler/bytecode.m:
compiler/code_util.m:
compiler/mlds_dump.m:
compiler/ml_global_data.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_java_data.m:
compiler/opt_debug.m:
Conform to the changes above.
library/string.m:
Replace the non-exported test predicate internal_encoding_is_utf8 with
an exported function that returns an enum specifying the string encoding.
NEWS.md:
Announce the new function.
runtime/mercury_string.h:
Add the C macro that implements the new form of the offset_str_eq
binary op.
tests/hard_coded/string_switch4.{m,exp}:
We have long had three copies of the exact same code, in string_switch.m,
string_switch2.m and string_switch3.m, which were compiled with
- no smart switch implementation
- smart switch implementation forced to use the hash table method
- smart switch implementation forced to use binary search method
Add this new copy, which is compiled with
- smart switch implementation forced to use the new trie method
tests/hard_coded/Mmakefile:
Add the new test case.
tests/hard_coded/Mercury.options:
Update the options of the test cases, and specify them for the new.
tests/hard_coded/string_switch.m:
tests/hard_coded/string_switch2.m:
tests/hard_coded/string_switch3.m:
Update the top-of-module comment block to be identical in all four copies
of this module.
Add a predicate to search a ranges value for a value and return the endpoints
of the range (if any) that the value is contained in.
library/ranges.m:
Add the new predicate.
NEWS.md:
Announce the addition.
tests/hard_coded/Mmakefile:
tests/hard_coded/test_ranges.{m,exp}:
Add a test case.
It is often necessary to be certain that a thread has terminated before
the rest of the program can continue. In some cases, signalling that a
thread is ABOUT to terminate (using any synchronisation device)
is insufficient: even after the last piece of Mercury code has run,
the thread still has additional cleanup code to run, which might include
arbitrary code in thread-specific data destructors, etc.
Introduce a predicate to create a joinable native thread,
and a predicate to wait for that thread to terminate (joining).
Joinable threads are only implemented for C backends for now.
library/thread.m:
Add new predicates spawn_native_joinable and join_thread.
Add a internal type thread_handle.
Rename the internal type thread_id type to thread_desc,
as thread_id is too similar to thread_handle.
tests/hard_coded/Mmakefile:
tests/hard_coded/spawn_native_joinable.exp:
tests/hard_coded/spawn_native_joinable.exp2:
tests/hard_coded/spawn_native_joinable.m:
Add test case.
NEWS.md:
Announce changes.
library/string.builder.m:
Add the predicate string.builder.format. We already have
string.writer.format, one of whose instances, the one for
string.builder.{handle,state}, does a string.format and adds
the resulting string to the given string builder. The new predicate
allows this to be done directly, without the type class overhead
(both conceptual overhead, and compilation time overhead) in cases
where the generality of type class is not needed, and in a way that
allows format strings in direct calls to string.builder.format
to be parsed and interpreted at compile-time, the same way as we
already do for calls to e.g. io.format.
NEWS.md:
Announce the new predicate.
compiler/format_call.m:
Specialize calls to string.builder.format. Use the code that specializes
calls to io.format, after suitable generalization.
compiler/builtin_lib_types.m:
mdbcomp/builtin_modules.m:
Add convenience functions needed by new code in format_call.m.
compiler/get_dependencies.m:
In the presence of (potential) calls to string.builder.format,
implicitly import the modules that define the predicates that
format_call.m may now generate calls to.
compiler/introduced_call_table.m:
List string.builder.append_string as a predicate that format_call.m
may now introduce calls to.
tests/hard_coded/test_builder_format.{m,exp}:
A new test case to test the new functionality.
tests/hard_coded/Mmakefile:
Enable the new test case.
tests/warnings/format_call_warning.m:
Fix indentation.
compiler/simplify_goal_conj.m:
Add conditionally-enabled code that can help debug problems with the code
that merges two successive switches on the same variable.
When doing such merges, do not insist on every cons_id that as an arm
in the second switch also having an arm in the first switch.
Document how situations can come about in which such insistence
would be wrong.
This fixes Mantis bug #570. The rest of the diff to the compiler directory
build the debugging infrastructure that lead to tracking down the bug.
compiler/simplify_info.m:
Include the progress stream in the simplify_info, for use by debugging code
such as what this diff adds to simplify_goal_conj.m.
Fix documentation rot.
compiler/simplify_proc.m:
Give the progress stream to simplify_info.m.
Make the argument order of some predicates match our guidelines.
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/pd_util.m:
compiler/size_prof.m:
compiler/stack_opt.m:
compiler/structure_sharing.analysis.m:
Conform to the changes above.
compiler/pd_debug.m:
Put the parts of some debugging code into meaningful groups.
tests/hard_coded/bug570.{m,exp}:
tests/hard_coded/bug570_can_fail.{m,exp}:
Two variants of the Mantis bug's test case. Both are needed for the
explanation in simplify_goal_conj.m.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
Enable the new test cases.
compiler/simplify_goal_conj.m:
Document the reason for this bug, Mantis bug #567, and fix it.
tests/hard_coded/bug567.{m,exp}:
The Mantis test case, renamed and with a long explanation of the bug
added.
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
Enable the new test case.
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.