support them because NU-Prolog couldn't support them.)
This required two main changes:
(a) eliminating places where we explicitly assumed that character codes
ranged from 1 to 127.
(b) making sure that all conversions from `Char' to `Integer' are done
by first explicitly casting to `UnsignedChar'. This is necessary
to avoid potential problems on C compilers for which `char' is signed.
library/char.m:
library/char.nu.nl:
Replace the implementation of char__to_int as a big table
with an implementation using pragma c_code, so that it doesn't
assume that character codes range from 1 to 127.
Move the old implementation into a new file char.nu.nl,
since it's still needed for Prolog support.
Add new predicates char__min_char_value/1 and char__max_char_value/1.
library/Mmakefile:
Add char.nu.nl to the list of files needed for Prolog support.
library/lexer.m:
Rewrite io__get_token_[12] in the original (less efficient) way
that they were written before conway's change in revision 1.17,
to avoid assuming anything about the range of character codes.
(Once this change has bootstrapped, it might be worth going back
to the efficient version, modified of course to assume that
character codes range from 0..255 rather than 1..127.
However, at least for bootstrapping we need to use the less
efficient version.)
runtime/mercury_string.h:
Add `UnsignedChar' typedef.
library/string.m:
In string__to_int_list, make sure that the conversion from
`Char' to `Integer' is done by first explicitly casting to
`UnsignedChar'.
Also a few other minor fixes:
- remove an old XXX by using make_aligned_string()
- use `size_t' rather than `Word' for a string length;
- add a missing `const'
- remove an unnecessary cast to (char)
- change a `while (--p >= Str) { ...' to
`while (p > Str) { p--; ...', because pointing to
one before the start of an array is not strictly
ANSI-conformant.
compiler/switch_detection.m:
compiler/dense_switch.m:
Use char__min_char_value and char__max_char_value to avoid
assuming 7-bit chars. (We still don't get cross-compilation
between platforms with different size characters right yet,
but that's not a major issue right now.)
compiler/export.m:
Make sure that conversions from `Char' to `Word'
are done by first explicitly casting to `UnsignedChar'.
NEWS:
Mention that we now support 8-bit characters.
Mention the new predicates char__min_char_value/1 and
char__max_char_value/1, as well as int__int_min, int__int_max,
int__bits_per_int (which were added previously, with different
names, but not mentioned in the NEWS file).
Also make minor cleanups to a few of the other messages.
Estimated hours taken: 12
The first half of a change to introduce nondet pragma C goals.
This half makes the necessary modifications to the HLDS; the next
half will modify the LLDS and emit it.
prog_data:
Add a new pragma type for nondet pragma c_codes; these specify
the names of a a bunch of variables to save across backtracking,
and a list of label names to which backtracking may take place.
Rename is_recursive to may_call_mercury, since this is a more
direct expression of the meaning.
prog_io:
Move much of the functionality to new files.
prog_io_dcg, prog_io_goal, prog_io_pragma, prog_io_util:
New files, made up of pieces of prog_io.
hlds_goal:
Add an extra argument to the pragma_c_goals to store the extra
information present in the new type of pragma c_codes.
det_analysis:
Take into account that the new type of pragma_c goal may have
more than one solution.
goal_util:
Rename variables in the new field of pragma_cs.
live_vars:
Allocate stack slots to the saved variables in the new type of pragma_c
goals.
make_hlds:
Handle the new type of pragma_c goals.
mercury_output, hlds_out:
Output the new type of pragma_c goals.
garbage_out:
Rename type "det" to "frame_type".
others:
Ignore one more arg of pragma_c goals or import prog_io_util.
Estimated hours taken: 100
* Inter-module unused argument removal.
* Allow the user to specify which directories should be searched
for .opt files.
* Enhancements to simplify.m and common.m which will be useful for
partial deduction.
compiler/options.m
Added and documented options:
--intermod-unused-args to enable inter-module unused argument removal.
--intermod-directory <dir>, same as --search-directory except used
to locate .opt files.
--use-search-directories-for-intermod - use the search directories
for .opt files as well.
--warn-simple-code - a flag to control the warnings produced by
simplify.m so that they respect --inhibit-warnings.
compiler/unused_args.m
Use the unused argument info from the .opt file.
Clobber the dependency_info if any new preds were added.
compiler/hlds_module.m
Added a field to the module_info to store unused argument
information from .opt files.
compiler/prog_data.m
Add :- pragma unused_args to hold unused argument information.
This should only be used in .opt files.
compiler/make_hlds.m
Build the unused_arg_info field in the module_info.
Check that pragma unused_args only appears in .opt files.
Fill in the non-locals field in the goal_info for the builtin
stubs so that mode analysis computes the correct instmap delta.
compiler/intermod.m
Read in the unused argument information for the current module when
compiling to C. This is used to ensure that clauses are produced with
the correct number of removed arguments (it may be possible to remove
more arguments with the information from other modules).
Fix a bug in the handling of module qualified function calls and
higher-order predicate constants.
compiler/handle_options.m
Handle --intermod-unused-args and
--use-search-directories-for-intermod.
compiler/mercury_compile.m
Run the entire front end and polymorphism (not just up to
typechecking) when building the .opt file with
--intermod-unused-args.
Use the new interface to simplify.m, remove calls to excess.m
and common.m.
compiler/code_util.m
compiler/llds_out.m
When generating local code for a specialized version of a predicate
from another module, put this module's name on the label to avoid
link errors.
compiler/higher_order.m
Don't add the originating module name to the name of the specialized
version, since that is now done in code_util.m.
Clobber the dependency graph so that inlining will work on the
specialized versions in profiling grades (this will cause slightly
slower compilation in profiling grades, something I need to fix).
compiler/simplify.m
Merge a branching goal and an adjacent switch where the branches
of the first goal contain extra information about the switched
on variable of the second goal.
Merge the excess assignments and common subexpression elimination
passes into simplify.m.
compiler/excess.m
The functionality of this module is now in simplify.m, but I'll
leave it here for now.
compiler/instmap.m
Added predicates instmap__bind_var_to_functor and
instmap_delta_bind_var_functor to which take a var, cons_id
and an instmap and adjust the inst of the var. This is used to
update the instmap at the beginning of each case in a switch.
Fix a bug in merge_instmap_delta where variables whose inst had
information added in one branch of a switch, disj, or ite had that
changed inst included in the instmap_delta for the entire
branched goal.
compiler/mode_util.m
Use instmap_delta_bind_var_to_functor in recompute_instmap_delta.
Added predicate bind_inst_to_functor which takes a ground or bound
inst and a cons_id and adjusts the top level of the inst to be bound
to that cons_id. Other types of inst are left unchanged.
Change recompute_instmap_delta so that the switched on variable of
a switch is bound to the functor in each case even if the binding
unification has been removed. Added a boolean argument to request
recomputation of instmap_deltas for atomic goals.
compiler/modes.m
compiler/unique_modes.m
Make sure that the instmap_delta for each branch of a switch
includes the extra information added by the functor test.
compiler/common.m
Removed the goal traversal. Leave preds to be called by simplify.m
to optimise common unifications and calls.
Warn about and eliminate multiple calls to a predicate with the same
input arguments.
Replace deconstructions of known terms with assignments to the output
variables where this would not make more variables live at stack
flushes.
compiler/follow_code.m
Exported move_follow_code_select.
Don't move follow code into erroneous branches.
library/string.nu.nl
Added string__contains_char/2.
compiler/base_type_layout.m
compiler/special_pred.m
compiler/vn_order.m
library/mercury_builtin.m
Removed duplicate calls.
doc/user_guide.texi
Documented options.
tests/warnings/duplicate_call.m
tests/warnings/duplicate_call.exp
Test duplicate call warning.
Estimated hours taken: 0.5
Fix a bug that Philip reported to Zoltan regarding
spurious determinism errors in lambda expressions.
compiler/switch_detection.m:
When detecting switches in lambda expressions, we need to insert
the initial insts for the lambda variables in the instmap
before processing the lambda goal.
Estimated hours taken: 2.5
Switch from using a stack of store_maps in the code_info to govern what
goes where at the end of each branched structure to using the store map
fields of the goal expressions of those structures.
Fix variable names where they resembled the wrong kind of map(var, lval).
code_info:
Remove the operations on stacks of store maps.
Modify the generate_forced_saves and remake_with_store_map operations
to take a store_map parameter.
When making variables magically live, pick random unused variables
to hold them, since we can no longer use the guidance of the top
store map stack entry. This may lead to the generation of some
excess move instructions at non-reachable points in the code;
this will be fixed later.
code_gen:
Remove the store map push and pop invocations.
Modify the generate_forced_goal operation to take a store_map parameter.
code_exprn:
Export a predicate for use by code_info.
middle_rec, disj_gen, ite_gen, switch_gen,
dense_switch, lookup_switch, string_switch, tag_switch:
Pass the store map around to get it to invocations of the primitives
in code_gen and code_info that now need it.
goal_util:
Name apart the new follow_vars field in hlds__goal_infos.
(This should have been in the change that introduced that field.)
common, constraint, cse_detection, det_analysis, dnf, excess, follow_code,
intermod, lambda, lco, liveness, make_hlds, mode_util, modes, polymorphism,
quantification, simplify, switch_detection, typecheck, unique_modes,
unused_args:
Fix variable names.
follow_vars, store_alloc:
Add comments.
Estimated hours taken: 8
livemap:
Fix a long-standing bug that caused all fixpoint iterations to stop
too early. By causing value_numbering to miscompile the predicate
mercury_compile__maybe_unused_args, this bug caused the unwanted
printing of statistics for tests/warnings/unused_args_test.
Fix also another bug: we did not process the control rval in
computed gotos. To my knowledge this has never been tickled.
Redesign the interface of the exported predicate slightly to
make it more robust.
frameopt, value_number:
Use the modified interface of livemap.
switch_detection:
For a while now we have removed arms from switches if we knew from
the instantiation of the control variable that those arms could not be
executed. Sometimes this results in switches with no arms. If the
control variable of the switch is never used after the switch,
liveness won't see the occurrence in the switch construct as a use,
and will kill the variable too early, cause the code generator to
abort.
We now turn switches with no arms into "fail"; this improves the
code generated and avoids the bug. However, liveness should still
be changed to consider the occurrence of a variable in the first
arg of a switch a use.
code_gen, vn_block:
Formatting changes.
Estimated hours taken: 12
The main changes are
1 associating a name with the arguments of constructors
2 removing the follow_vars field from calls, higher-order calls
and complicated unifications, since they are not used
3 merging the follow_vars and store_alloc passes, since they logically
belong together
4 add a new module, lco, for detecting opportunities for last
call optimization modulo constructor application; it won't
actually apply the optimization until the mode system becomes
expressive enough to handle it (this module detects 529 opportunities
in the compiler and library)
5 make "-O3 --optimize-value-number" do the right thing; previously,
it used not to apply value numbering because the vnrepeat option
defaulted to zero
6 don't refer to .err2 files anymore; use .err instead.
prog_data:
The list associated with each value of type "constructor" now
contains not only the types of the arguments but their names as well.
equiv_type, hlds_data, hlds_out, make_hlds, mercury_to_{goedel,mercury},
mode_util, module_qual, shapes, type_util, unify_proc:
Modify the traversal of type definitions to account for the names
in the lists inside values of type "constructor".
prog_io:
Parse argument names. An unrelated change is that we now
check whether :- pred declarations give modes to some of their
arguments but not to all, in which case we return an error.
hlds_goal:
Remove the follow_vars field from calls, higher-order calls
and complicated unifications.
*.m:
Handle the new arities of calls, higher order calls and complicated
unifications.
mercury_compile:
Don't call follow_vars directly anymore, but do call lco if its option
is set. Also flush the main output before a call to maybe_report_stats
to prevent ugly output.
store_alloc:
Call follow_vars directly.
follow_vars:
Expose the initialization and traversal predicates for store_alloc.
lco:
Find opportunities for last call optimization modulo constructor
application.
passes_aux:
Add a HLDS traversal type for lco.
optimize:
Consider the vnrepeat count to be zero unless value numbering is on.
options:
Set the default value of vnrepeat to 1.
modules:
Don't refer to .err2 files.
Estimated hours taken: 20
Mode analyser reorganisation.
compiler/mode_util.m:
Removed: instmap_init/1, apply_instmap_delta/3, instmap_lookup_var/3,
instmapping_lookup_var/3, instmap_restrict/3, map_restrict/3 (all
moved to instmap.m).
compiler/hlds_goal.m:
Removed the declarations of instmap_delta, instmap and instmapping.
compiler/mode_errors.m:
Added report_mode_errors/2 (was modecheck_report_errors, from
modes.m).
compiler/modes.m:
Predicates now exported:
modecheck_goal/4
modecheck_goal_expr/5 (previously named modecheck_goal_2/5)
handle_extra_goals/8
mode_context_to_unify_context/3
Moved to mode_errors.m:
modecheck_report_errors/2
Moved to instmap.m:
compute_instmap_delta/4
instmap_merge/3
instmap_lookup_vars (was instmap_lookup_arg_list/3)
compute_instmap_delta/4
Moved to mode_debug.m:
Type port/0
mode_checkpoint/4
Moved to modecheck_call.m:
modecheck_call_pred/7
modecheck_higher_order_call/10
modecheck_higher_order_pred_call/4
modecheck_higher_order_func_call/7
Moved to modecheck_unify.m:
modecheck_unification/9
categorize_unify_var_var/12
categorize_unify_var_functor/11
categorize_unify_var_lambda/9
Moved to mode_info.m:
mode_info_error/4
mode_info_add_error/3
compiler/code_gen.pp, compiler/code_info.m, compiler/constraint.m,
compiler/cse_detection.m, compiler/det_analysis.m, compiler/det_util.m,
compiler/dnf.m, compiler/goal_util.m, compiler/higher_order.m,
compiler/hlds_out.m, compiler/hlds_pred.m, compiler/live_vars.m,
compiler/liveness.m, compiler/lookup_switch.m, compiler/polymorphism.m,
compiler/simplify.m, compiler/store_alloc.m, compiler/switch_detection.m,
compiler/transform.m, compiler/unused_args.m:
Imported instmap.m
New files:
compiler/instmap.m:
Handle operations associated with instmaps.
compiler/modecheck_unify.m:
Handle mode checking of unifications.
compiler/modecheck_call.m:
Handle mode checking of calls
compiler/mode_debug.m:
Code to trace the actions of the mode checker.
Estimated hours taken: 15
hlds_data:
Rename address_const to code_addr_const, and add base_type_info_const
as a new alternative in cons_id, and make corresponding changes
to cons_tag.
Make hlds_type__defn an abstract type.
llds:
Rename address_const to code_addr_const, and add data_addr_const
as a new alternative in rval_const.
Change type "label" to have four alternatives, not three:
local/2 (for internal labels), c_local (local to a C module),
local/1 (local a Mercury module but not necessarily to a C module,
and exported.
llds_out:
Keep track of the things declared previously, and don't declare them
again unnecessarily. Associate indentation with the following item
rather than the previous item (the influence of 244); this results
in braces being put in different places than previously, but should be
easier to maintain. Handle the new forms of addresses and labels.
Refer to c_local labels as STATIC when not using --split-c-files.
code_info:
Use a presently junk field to store a cell counter, which is used
to allocate distinguishing numbers to create'd cells. Previously
we used the label counter, which meant that label numbers changed
when we optimized away some creates. Handle the new forms of
addresses and labels.
exprn_aux:
Handle the new forms of addresses and labels. We are now more
precise in figuring out what label address forms will be considered
constants by the C compilers.
others:
Changes to handle the new forms of addresses and labels, and/or to
access hlds_type__defn as an abstract type.
Estimated hours taken: 4
Implement `recursive' and `non_recursive' pragma c_code declarations.
This allows the compiler to optimize cases when the C code
is known to not call Mercury code. It's also necessary
to allow C code which modifies the hp register to work
(such code must be declared `non_recursive', otherwise
the registers will be saved and restored over it).
To make things bootstrap OK, the old pragma c_code declarations
default to `non_recursive'.
prog_data.m, hlds_goal.m:
Add new field c_is_recursive to pragma c_code goals.
prog_io.m:
Parse the new `recursive' and `non_recursive' pragma c_code
declarations.
make_hlds.m:
Pass the c_is_recursive field from the parse tree to the HLDS.
live_vars.m:
For non-recursive C code, don't save variables on the stack.
code_gen.pp:
For non-recursive C code, don't save variables on the stack,
don't mark the succip as needing to be saved, and don't
call save_registers() and restore_registers().
*.m:
Change c_code/5 to c_code/6.
Estimated hours taken: 12
Implement higher-order functions.
Add higher-order function terms
(function lambda expressions, e.g. `Func = (func(X) = Y :- Y is 2 * X)'
and higher-order function calls (apply/N, e.g. `Z = apply(Func, 42)').
Add higher-order function insts and modes.
hlds_goal.m:
Add a new field pred_or_func to lambda_goal.
prog_data.m:
Add a new field pred_or_func to pred_inst_info.
prog_io.m:
Add support for parsing higher-order function terms and
higher-order function insts and modes.
make_hlds.m:
Add support for parsing higher-order function terms.
typecheck.m:
Add support for type-checking higher-order function calls
and higher-order function terms.
modes.m, mode_errors.m:
Add support for mode-checking higher-order function calls
and higher-order function terms.
higher_order.m:
Handle higher-order function types and insts.
hlds_pred.m:
Add new predicate pred_args_to_func_args, for extracting the
function arguments and function return from the arguments
of a predicate that is really a function.
*.m:
Minor changes to handle new pred_or_func field in lambda_goals
and pred_inst_infos.
Estimated hours taken: 20
det_analysis:
Make sure we don't change the goal being analyzed except possibly
for the introduction of `some's (which should not hurt anything).
Make sure we don't print any error messages except in the final
iteration, when all the inputs to the inference are stable.
If the --debug-detism options is set, print messages about the
progress of inference and checking.
Also moved some code around.
det_report:
Distinguish the handling of warning messages and error messages.
simplify:
Use the new ability of det_report to separate warnings and errors.
passes_aux:
Add a new generic pass form, for use by simplify.
option:
Add --debug-detism (as above), --aditi, which at the moment
only enables the disjunctive normal form transformation, and
--inlining/--no-inlining, which set the other three flags
involved in inlining depending on whether you want standard
inlining or none at all.
Follow_code used to be set twice and follow_vars not at all;
I fixed this.
Reenabled optimize_higher_order at -O3.
Moved value numbering to -O4 and pred_value_number to -O5.
This makes it easier to separate value numbering from the
other optimizations (which are likely to be more effective).
Divided options_help into sections to avoid excessive
compilation times.
store_alloc:
Base the store map on the follow_vars info attached to the
branched structure which I added recently, and not on the
follow_vars map being passed around, since it will be more accurate.
hlds_out:
Print information about follow_vars and store_maps when -D is given.
follow_code:
Undo an old hack that change to follow_vars has made counterproductive.
middle_rec:
Fix a bug uncovered by the change to follow_code. When looking for a
register to hold the counter, it is not enough to avoid picking a
register that appears in the recursive case; we must also avoid
registers that occur only in the base case.
livemap:
Mentioning the code address succip now causes the succip to be
considered live. This may or may not fix the bug with pred_value_number
miscompiling unused_args.m; the other changes have caused the input
to value numbering to change, and they no longer trigger the problem.
(Will try to test this later.)
mercury_compile:
Try to make sure that we print statistics only after passes that
were actually executed. Also, reduce the number of lookups of the
verbose option. Move some predicates so that the order of their
appearance matches the current order of invocation.
vn_table:
Loosen a sanity check to let xnuc2 pass through it.
code_exprn, switch_detection:
Minor changes.
Estimated hours taken: 24
Treat higher-order predicate calls as a new sort of goal,
rather than as calls to the special predicate call/N, in order to
remove the fixed limit on the number of arguments and on the modes
for call/N.
Also, remove the restriction on output arguments preceding input arguments
in lambda expressions.
hlds_goal.m:
Add new functor higher_order_call/6 to the hlds__goal type.
*.m:
Handle new functor higher_order_call/6.
arg_info.m:
Abstract things a bit more: the argument passing convention
for a procedure may be affected by that procedure's types,
modes, and code_model, as well as the arg_method.
follow_vars.m:
Pass down the args_method, since it is now needed for figuring
out the arg_info for unifications and higher-order calls.
follow_code.m:
Treat complicated unifications in the same way as calls.
lambda.m:
When creating lambda predicates, permute the arguments so
that all input arguments come before all output arguments.
call_gen.m:
When generating higher-order predicate calls, don't abort
if outputs precede inputs; instead, generate code assuming
that the called predicate's args have been permuted so that
the inputs to come before all the outputs.
Estimated hours taken: 8
A large step in cleaning up the determinism system.
simplify:
Determinism analysis should not modify the code of the procedures it
checks, yet we need to massage some goals to make them acceptable to
the code generator. The obvious solution is to perform this massaging
after analysis is finished. This is what this new module does.
det_util:
New module to hold types and predicates used in more than one module
involved with the determinism system. Some types and/or predicates
used to be in switch_detection, det_analysis, det_report, but the
misc_info type has been expanded and renamed det_info.
det_analysis:
Don't modify the goal being analyzed except to insert "some" goals.
This is important because the relevant part of det_analysis knows
only the current inferred determinism of the goal, not its final
determinism. The modification code is now in simplify (after some
fixes).
Import det_util. Move some utility preds to det_util.
Export more of the determinism tables; some are needed in simplify.
det_report:
Import det_util. Move some utility preds to det_util.
Add some more warning messages.
cse_detection:
Import det_util.
switch_detection:
Import det_util. Move some utility preds to det_util.
passes_aux:
Defined a predicate for traversing the HLDS hierarchy for processing
all the non-imported procedures.
Defined write_proc_progress_message to complement
write_progress_message (which has been renamed
write_pred_progress_message).
dead_proc_elim, modes, typecheck, unique_modes:
Use write_{proc/pred}_progress_message as appropriate.
hlds_out:
Add a new predicate hlds_out__write_pred_proc_id.
hlds_module:
Improve an abort message.
llds_out:
Formatting changes.
mercury_compile:
Call simplify__proc through the new traversal predicate in passes_aux.
Estimated hours taken: 8
options.m:
Rename branch_delay_slot to have_delay_slot.
Set optimize_delay_slot in -O2 only if have_delay_slot was set earlier.
This is possible now because the default optimization level is now
set in mc.
mercury_compile:
Change verbose output a bit to be more consistent.
dead_proc_elim:
Export the predicates that will eventually be needed by inlining.m.
inlining.m:
Use the information about the number of times each procedure is called
to inline local nonrecursive procedures that are called exactly once.
EXCEPT that this is turned off at the moment, since the inlining of
parse_dcg_goal_2 in prog_io, which this change enables, causes the
compiler to emit incorrect code.
prog_io:
Moved the data type definitions to prog_data. (Even though prog_io.m
is ten times the size of prog_data.m, the sizes of the .c files are
not too dissimilar.)
Estimated hours taken: 3
options:
Add a new option, --branch-delay-slot, intended for use by mc on
the basis of the configuattion script. It says whether the machine
architecture has delays slots on branches.
The setting of option should affect whether we set
--optimize-delay-slots at -O2, but this doesn't work yet.
hlds_goal:
Add an extra field to hold follow_vars infromation to disjunctions,
switches and if-then-elses. I intend to use this information to
generate better code.
*.m:
Changes to accommodate the extra field.
Estimated hours taken: 16
options:
Replace the word_size option with the two options bits_per_word and
bytes_per_word. The former is needed by lookup_switch, the latter by
value numbering.
lookup_switch:
Use the new option instead of word_size.
vn_type, vn_cost, vn_block, value_number:
Add a new type, vn_params, containing information such as the number
of bytes per word (from the option) and cost parameters. Use these
cost parameters to make more realistic decisions.
vn_filter:
New module to filter out unnecessary uses of temporary variables,
which gcc does unnecessarily badly on.
value_number, vn_verify:
Move verification completely to vn_verify. Tighten the verification
rules relating to tags where it concerns code sequences in which
the tag of an rval is taken in a statement before an if_val, but
loosen them to avoid spurious rejections of code sequences containing
arithmetic comparisons. Fix some missing cases from semidet switches
that may have lead to overly conservative decisions.
value_number, vn_order:
Vn_order was making an overly conservative assumption about where
to split an extended basic block if it couldn't be optimized together.
Move the decision to value_number and try to make it better. The new
heuristic is not enabled yet.
vn_debug:
Change the conditions under which one type of message is printed.
vn_flush:
Wrap some too long lines.
llds:
Fix a bug that would prevent profiling from working correctly on
value numbered code: we weren't scanning instructions inside blocks
when looking for return addresses.
peephole:
Enable an optimization previously left disabled by accident.
switch_detection, tag_switch:
Eliminate an unused argument.
Estimated hours taken: 10
hlds, hlds_module, hlds_pred, hlds_goal, hlds_data:
Divided the old hlds.m into four files:
hlds_module.m defines the data structures that deal with issues
that are wider than a single predicate. These data structures are
the module_info structure, dependency_info, the predicate table
and the shape table.
hlds_pred.m defined pred_info and proc_info, pred_id and proc_id.
hlds_goal.m defines hlds__goal, hlds__goal_{expr,info}, and the
other parts of goal structures.
hlsd_data.m defines the HLDS types that deal with issues related
to data and its representation: function symbols, types, insts, modes.
It also defines the types related to determinism.
hlds.m is now an empty module. I have not removed it from CVS
because we may need the name hlds.m again, and CVS does not like
the reuse of a name once removed.
other modules:
Import the necessary part of hlds.
det_analysis:
Define a type that was up to now improperly defined in hlds.m.
prog_io:
Move the definition of type determinism to hlds_data. This decision
may need to be revisited when prog_io is broken up.
dnf, lambda:
Simplify the task of defining predicates.
llds:
Fix some comments.
mercury_compile:
If the option -d all is given, dump all HLDS stages.
shape, unused_args:
Fix formatting.
Estimated hours taken: 8
mercury_compile:
Fix the pass structure, and start using a loose sequence of stage
numbers, to make it easier to add new stages without having to fiddle
stage numbers.
THIS DOES MEAN THAT ALL STAGE NUMBERS HAVE CHANGED NOW.
The stage number assignment scheme assigns 1 to 25 to the front end,
26 to 50 to the middle passes, and 51 to 99 to the back end.
hlds:
We had two types that combined a pred_id and a proc_id. One,
pred_proc_id, used a simple pair; the other, procedure_id, had a better
definition using a specific function symbol but was not used
anywhere else. I standardized on the name pred_proc_id, but using the
definition with a dedicated function symbol (proc).
I also defined a type pred_proc_list as a list of pred_proc_id.
To prepare for memoing, I added a new field to pred_info, which is
a list of markers, each requesting a specific transformation on the
predicate or indicating that the transformation has been done.
The inline request is now represented using such a marker. However,
the interface is backwards compatible.
constraint, dead_proc_elim, dependency_graph, det_analysis, det_report,
higher_order, unused_args:
Changes to conform to the new definition of pred_proc_id.
In two places removed definitions of predproclist, whose
equivalent pred_proc_list is now defined in hlds.m.
hlds_out, make_hlds, mercury_to_mercury, prog_io:
Add code to handle memo pragma declarations, using whenever possible
a version of the existing code for handling inline requests, but
generalized for handling any pragma that sets a marker.
switch_detection:
Rename the type cases_list to sorted_cases_list. This avoids a
name clash that creates a duplicate label and therefore screws up
the profiler, and is a better name anyway.
options:
Add a new option, --opt-space, that turns on optimizations that save
space and turns off optimizations that squander space.
handle_options:
Pass the special option handler to getopt.
frameopt:
For each labelled code sequence that tears down the stack frame but
does not use it, we used to create a parallel code sequence that omits
the teardown code, for use by gotos from locations that did not have
a stack frame. However, peepholing may discover that it is better
not to tear down the stack frame at the site of the goto after all,
so we need the original code sequence as well.
The current change fixes a bug that occurs if the original code
sequence is modified by another part of frameopt to omit teardown
code. In such cases, which are produced by --pred-value-number,
peepholing redirects a goto to a code sequence that it thinks tears
down the stack frame, but actually doesn't.
With this change, --pred-value-number now works.
llds:
Fix typos in a comment.
Estimated hours taken: 12
Fixes for two bugs in mode analysis, and
a first cut at support for `any' insts.
(The support for `any' is very preliminary,
has had only the most minimal of testing, and
doubtless has some bugs.)
inst_match.m mercury_to_mercury.m mode_util.m modes.m undef_modes.m
unique_modes.m prog_io.m:
Add new type of inst `any(uniqueness)' to prog_io.m, and
change inst_match.m, mode_util.m, and other places to handle
handle `any' insts.
inst_match.m:
Fix bug in inst_merge: when merging `unique(f(ground)) and `unique',
the result should be `ground', not `unique', since part of the
data structure may be shared. (This fix required adding several
new predicates: `merge_uniq_bound' etc.)
inst_match.m mercury_to_mercury.m mode_util.m modes.m polymorphism.m
prog_io.m switch_detection.m unique_modes.m:
Fix a design bug: in a `bound' inst, the list of bound_insts
must be sorted on the name+arity, not on the name+arg_insts.
To achieve this, I changed the type of the first argument of
functor/2 in the type bound_inst from `const' (just name) to
`cons_id' (name+arity).
Estimated hours taken: 7
dead_proc_elim:
A new pass to eliminate any procedures not reachable from the
exported modes of the exported predicates, either via calls or
by being mentioned in a higher order construct. Useful after
inlining and specialization passes have created orphan procedures.
options:
Added new option for enabling dead procedure elimination.
mercury_compile:
Call dead procedure elimination if its option is set.
This change displaces dump numbers after 13.
Also cleaned up the format of some of the verbose messages,
and removed some old, commented out code that isn't useful anymore.
Further work on the pass structure is required.
unused_args:
Cleaned up the format of some of the verbose messages,
hlds_out:
Print out the pred_id and status of each predicate; useful in looking
at what dead_proc_elim is doing.
hlds:
Added a predicate to return the exported procs of a pred.
Removed the randomization of pred_id's, which hasn't been required
for along time.
Exported the type pred_id for use by hlds_out. (This last may be
a temporary change.)
llds:
Make the extern declarations to the various bunch functions into
ANSI prototypes.
det_analysis:
Changes to make the cc component of at_most_many_cc "sticky" in the
various tables, i.e. if a goal is in a one solution context, any
conjunction, disjunction or switch containing it is also in a one
solution context. This need not propagate beyond quantification.
switch_detection:
Undid the unnecessary export of a predicate.
Updated a comment.
Estimated hours taken: 3
compiler/{cse,switch}_detection.m:
Fix bugs which lead to the wrong unification being hoisted
(cse_detection.m) or the wrong unification being marked
as never-failing (switch_detection.m). Make sure the difficult
cases are rejected as determinism errors rather than causing
incorrect code to be generated.
Estimated hours taken: 1.5
Undo dylan's changes in the names of some library entities,
by applying the following sed script
s/term_atom/term__atom/g
s/term_string/term__string/g
s/term_integer/term__integer/g
s/term_float/term__float/g
s/term_context/term__context/g
s/term_functor/term__functor/g
s/term_variable/term__variable/g
s/_term__/_term_/g
s/std_util__bool_/bool__/g
to all the `.m' and `.pp' files in the compiler and library directories.
The reason for undoing these changes was to minimize incompatibilities
with 0.4 (and besides, the changes were not a really good idea in the first
place).
I also moved `bool' to a separate module.
The main reason for that change is to ensure that the `__' prefix is
only used when it genuinely represents a module qualifier.
(That's what dylan's changes were trying to acheive, but `term__'
does genuinely represent a module qualifier.)
compiler/*.m:
Apply sed script above;
where appropriate, add `bool' to the list of imported modules.
Estimated hours taken: 4
More changes to finally fix the compiler so that it handles
Simon Taylor's nasty test case correctly.
Change unique_modes.m to invoke modecheck_unify_procs in unify_procs.m,
in case unique_modes.m adds new unify_requests for unification predicates
with `mostly_unique' modes.
switch_detection.m, cse_detection.m, det_analysis, unique_modes:
Export new predicates to process a single procedure at a time.
cse_detection.m:
Rearrange things so that it only redoes mode checking and switch
detection for the single procedure, not for a every mode of a predicate,
by calling `modecheck_proc' and `detect_switches_in_proc'.
hlds.m:
Add new field `can_process' to the proc_info.
modes.m, unique_modes.m:
Don't modecheck a procedure if its can_process field = no.
unify_proc.m:
Set the can_process field to `no' when adding unify procs after
a call to unify_proc__request_unify, and then back to yes again
when we are ready to process them in modecheck_unify_procs.
Add a new parameter to modecheck_unify_procs which specifies
whether we need to do ordinary mode checking or unique mode
checking. If we need to do unique mode checking, then after
doing ordinary mode checking, invoke `detect_switches_in_proc',
`cse_detect_in_proc', `determinism_check_proc', and
`unique_modes__check_proc' on the procedure.
unique_modes.m:
After checking ordinary predicates, invoke modecheck_unify_procs.
Add very_verbose progress messages.
Estimated hours taken: 6
Rearrange the ordering of the different phases in the compiler.
Moved lambda elimination (lambda.m) after unique_modes.m,
because mode analysis must have been fully completed before lambda
elimination, so that we get the right mode on the introduced
predicates. Also moved inlining.m and common.m after unique modes,
since they are optimization passes, not semantic checking passes.
The cse_detection.m, switch_detection.m, and determinism.m passes now
need to recursively traverse lambda goals. (Previously they assumed
that lambda goals had already been eliminated.)
mercury_compile.pp:
Move the inlining.m and common.m passes from semantic_phases
to middle_phases.
polymorphism.m:
Remove the code which called lambda.m.
switch_detection.m:
Recursively traverse lambda goals.
cse_detection.m:
Recursively traverse lambda goals.
Also, when redoing mode analysis and switch detection,
we shouldn't reinvoke lambda.m.
det_analysis.m, det_report.m:
Recursively traverse lambda goals, check for determinism
errors in them, and report them.
Also, print the calling predicate name & mode in the error
message for calls to predicates with cc_* determinism in
all-solutions contexts.
modes.m:
Add an extra argument to modecheck_unification that specifies
how we should recursively process lambda goals, so that we
can do the right thing when called from unique_modes.m.
The right thing in this case is to call unique_modes__check_goal
instead of modecheck_goal, and to then invoke lambda__transform_lambda
on the result.
unique_modes.m:
Make sure we don't clobber the predicate table, since we now
indirectly call lambda__transform_lambda, which inserts new
predicates into the table.
Also, simplify the code a little and add a sanity check.
lambda.m:
Make some changes that were needed because lambda.m now comes
directly after (unique_)modes.m not after polymorphism.m.
Estimated hours taken: _2___
Change names with badly placed double underscores (ie where the part of
a name before a double underscore is not the same as the module name.)
Reflect changes in the library interface.
compiler/*:
Use the newer, more correct form of the term and bool names.
Predicates "bool__" are now "std_util__bool" and labels of
the term ADT are now "term_" instead of "term__".
compiler/vn*.m:
change all names "vn__*" to a correct module prefix. All the
names remain qualified.
compiler/hlds.m:
s/\<is_builtin__/hlds__is_builtin_/g
s/\<dependency_info__/hlds__dependency_info_/g
compiler/unify_proc.m:
s/\<unify_proc_info__/unify_proc__info_/g
compiler/transform.m:
s/\<reschedule__conj/transform__reschedule_conj/g
Estimated hours taken: 2
compiler/switch_detection.m:
When creating switch statements, check the inst of the variable.
If it is known to be bound to a particular set of functors,
then delete unreachable cases, and then use those set of
functors to check against, rather than checking against all the
possible for functors for the type, to determine whether
or not the switch covers all possible cases.
excess:
A new pass to remove unnecessary assignment unifications.
mercury_compile:
Call the new excess assignment module.
options:
Add a new option, excess_assign, to control the new optimization.
Add another, num-real-regs, to specify how many of r1, r2 etc are
actually real registers. The default is now set to 5 for kryten;
later it should be supplied by the mc script, with a value determined
at configuration time.
tag_switch:
Use num-real-regs to figure out whether it is likely to be worthwhile
to eliminate the common subexpression of taking the primary tag of
a variable. Also fix an old performance bug: the test for when a
jump table is worthwhile was reversed.
value_number, vn_block:
Do value numbering on extended basic blocks, not basic blocks.
vn_debug:
Modify an information message.
labelopt:
Clean up an export an internal predicate for value numbering. Replace
bintree_set with set.
middle_rec:
Prepare for the generalization of middle recursion optimization
to include predicates with an if-then-else structure.
cse_detection:
Fix a bug: when hoisting a common desconstruction X = f(Yi), create
new variables for the Yi. This avoids problems with any of the Yis
appearing in other branches of the code.
goal_util:
Add a new predicate for use by cse_detection.
common:
Fix a bug: recompute instmap deltas, since they may be affected by the
optimization of common structures.
code_info:
Make an error message more explicit.
det_analysis:
Restrict import list to the needed modules.
*.m:
Import assoc_list.
The changes made allow declarations of the form:
:- pragma(c_code, predname(Varname1::mode1, Varname2::mode2, ...),
"Some C code to execute instead of a mercury clause;").
There are still a couple of minor problems to be fixed in the near future:
If there is a regular clause given as well as a pragma(c_code, ...) dec, it
is not handled well, and variables names '_' are not handled well.
prog_io.m:
parse the pragma(c_code, ...) dec.
hlds.m:
define a new hlds__goal_expr 'pragma_c_code'.
make_hlds.m:
insert the pragma(c_code, ...) dec. as a pragma_c_code into the hlds.
det_analysis.m:
infer that pragma_c_code goals are det.
modes.m:
convince the mode checker that the correct pragma variables are bound
etc.
quantification.m:
quantify the variables in the pragma(c_code, ...) dec.
code_gen.pp:
convert pragma_c_code into pragma_c (in the llds).
llds.m:
define a new instr, pragma_c. Output the pragma_c
hlds_out.m:
mercury_to_mercury.m:
mercury_to_goedel.m:
spit out pragma(c_code, ...) decs properly
*.m: handle the new pragma_c_code in the hlds or the new pragma_c in the llds
This set of changes includes most of the work necessary for
mode and determinism checking of higher-order predicates.
prog_io.m:
Change the syntax for lambda expressions: they need
to have a determinism declaration. Lambda
expressions must now look like this:
lambda([X::in, Y::out] is det, ...goal...).
^^^^^^
Note that both the modes and the determinism are mandatory,
not optional.
hlds.m:
Insert a determinism field in the lambda_goal structure.
hlds_out.m, inlining.m, make_hlds.m, modes.m, polymorphism.m, quantification.m,
switch_detection.m, typecheck.m:
Modified to use lambda_goal/4 rather than lambda_goal/3.
prog_io.m:
Add a new field to the `ground' inst, of type `maybe(pred_inst_info)'.
We use this to store the modes and determinism of higher-order
predicate terms.
code_info.m, inst_match.m, mercury_to_mercury.m, mode_util.m, modes.m,
polymorphism.m, shapes.m, undef_modes.m:
Modified to handle higher-order pred modes:
use ground/2 rather than ground/1.
(Note that modes.m still requires a bit more work on this.)
llds.m:
Add a new field to the call_closure/3 instruction to hold the
caller address for use with profiling, since the C macros
require a caller address.
dup_elim.m, frame_opt.m, garbage_out.m, live_map.m, middle_rec.m, opt_debug.m,
opt_util.m, value_number.m, vn_*.m:
Modified to use call_closure/4 rather than call_closure/3.
mercury_to_mercury.m:
Export mercury_output_det for use by hlds_out.m.
hlds.m:
Insert new `list(mode)' field in the lambda_goal/2 structure.
hlds_out.m, inlining.m, quantification.m, switch_detection.m,
Use lambda_goal/3 instead of lambda_goal/2.
parser.m, make_hlds.m, typecheck.m, modes.m:
Parse, typecheck, and modecheck lambda expressions.
mercury_to_mercury.m:
Export mercury_output_mode/4 for use by hlds_out.m.
switch_detection.m:
Fix the base case for detecting switchs, so that if there are
disjuncts left over, we convert those into a switch as well.
In particular, merge/3 is now a disj of two switches rather than
a disj of a switch and to extra disjuncts.
-------------------------------------------------------
Implement unique modes. We do not handle local aliasing yet, so this
is still not very useful, except for io__state. Destructive update is
not yet implemented. Also note that this really only implements
"mostly unique" variables that may be non-unique on backtracking - we
don't check that you don't backtrack over I/O, for example.
prog_io.m, mode_util.m, modes.m, inst_match.m:
Major changes to Handle unique modes.
mercury_to_mercury.m, polymorphism.m, prog_out.m, undef_modes.m:
Use `ground(Uniqueness)' rather than just `ground'.
compiler/*.m:
Fix compile errors now that unique modes are enforced: add a
few calls to copy/2, and comment out lots of unique mode
declarations that caused problems.
typecheck.m, mode_info.m:
Hack around the use of unique modes, which doesn't work
because we don't allow local aliasing yet: make the insts
`uniq_type_info' and `uniq_mode_info' not unique at all,
and add a call to copy/2 when extracting the io_state from
type_info or mode_info.
-------------------------------------------------------
Plus a couple of unrelated changes:
hlds.m:
Change the modes for the special predicates from `ground -> ground'
to `in', so that any error messages that show those modes
come out looking nicer.
Add a new shared_inst_table for shared versions of user-defined
insts.
mercury_to_goedel.m:
Use string__is_alnum_or_underscore.
context of the unification from which call was made. We we use this to generate
significantly better error messages. (There should be no more messages of the
form "call to __Unify__(blah blah blah) can fail".) Most of the files are
changed just to reflect this.
An unrelated change in det_analysis is that we now ensure the absence of
cycles by modifying the new inferred determinism in the light of the old
one, ensuring that any changes are monotonic.
In hlds_out, inhibit the printing of pseudo-imported predicates (unifications)
since nobody cares about them except sometimes Fergus.
unifications. See the comments at the top of unify_proc.m for
details of how it's done.
hlds.m:
Add new export statuses `pseudo_imported' and `pseudo_exported'
to handle unification predicates, which can now have complicated
modes.
code_gen.pp, code_info.m, common.m, constraint.m, cse_detection.m,
follow_code.m, follow_vars.m, hlds_out.m, inlining.m, live_vars,
make_hlds.m, mercury_compile.pp, modes.m, store_alloc.m,
switch_detection.m:
Handle pseudo_imported predicates.
modes.m, constraint.m:
Change modecheck to return an updated module_info, since
modechecking may insert new entries into the unify_requests
queue in the module_info. Make sure that modechecking
never inserts requests into the unify_requests queue
for code that has mode errors (or needs rescheduling).
call_gen.m, polymorphism.m:
Move duplicated code into unify_proc.m.
clause_to_proc.m:
Add new predicate clauses_to_proc for use by unify_proc.m.
unify_proc.m:
Implement complicated unifications with complicated modes.
hlds.m and lots of other files:
Change the type of the first two arguments of unify/5 in
hlds__goal_expr from `term, term' to `var, unify_rhs'
where unify_rhs is given by
:- type unify_rhs
---> var(var)
; functor(const, list(var))
; lambda_goal(list(var), hlds__goal).
This change was for two reasons: firstly, it simplifies the
code in a lot of places, and secondly, it is a step towards
implementing lambda closures and higher-order predicates
properly.
switch_detection:
Detect partial switches, i.e. disjunctions in which not all
disjuncts form part of the switch. We give preference to full
switches, and failing that, to partial switches with the most arms.
peephole, opt_util:
Fixed the code for the introduction of succeed_discard.
code_gen:
Fixed spelling error in error message.
code_info:
Made error message somewhat more informative.
cse_detection:
Removed debugging code; we now always repeat cse detection after
finding some cses.
det_analysis:
Added some comments.
value_number, vn_debug, vn_flush:
Changes to make debugging easier.
prog_io, hlds: Added the functor "multidet" to the type determinism.
Added types and predicates to relate determinism to its
two components, can_fail and soln_count.
Removed the functor "unspecified" from the type determinism,
substituting maybe(determinism) for determinism in proc_info.
Replaced the type category with the type code_model,
and added predicates to compute it from determinism.
det_analysis: Redone the analyses to work with determinism, not category
(or code_model). This should enable programmers to write
their own erroneous (and failure) predicates.
other files: Use the new and renamed types and access predicates.
compiler/*:
Add copyright messages.
Change all occurences of *.nl in comments to *.m.
compiler/mercury_compile.pp:
Change the output to the .dep files to use *.m rather than *.nl.
(NOTE: this means that `mmake' will not work any more if you
call your files *.nl!!!)
*.nl:
Replace all occurrences of `not(Vars, Goal)' with just
plain `not(Goal)'.
type_util.nl, switch_gen.nl:
Higher-order pred types are not user-defined types.
Add a `predtype' type category for them.
call_gen.nl:
Change call_closure/2 to call_closure/3 (with liveinfo).
Plus a little bit of random hacking.
det_analysis.nl:
Fix an old "XXX": implement `no_output_vars' properly.
This required threading InstMaps through everything.
modes.nl, inst_match.nl:
Move some predicates from modes.nl into a new module, inst_match.nl,
so that they can be used by det_analysis.nl.
hlds.nl, mode_util.nl:
Do some more work for propagating type info into modes.
hlds_out.nl:
Some minor cosmetic changes.
hlds.nl, prog_io.nl:
Add a couple of comments.
switch_detection.nl:
Search through nested conjunctions, which can be created as
a result of mode analysis.
typecheck.nl, unify_proc.nl:
Fix some determinism errors.
prog_io.nl:
Remove some stuff put in by squirrell:
don't recognize `=>', `<=', or `<=>' in DCG goals.
They don't make sense in DCG goals.
term.nl:
In term__create_var, use bit reversals rather than random numbers
to ensure that the binary trees remain balanced.
call_gen.nl:
For polymorphic unifications, generate a call to fatal_error().
code_gen.nl, hlds.nl, make_hlds.nl, modes.nl, unify_proc.nl:
Move the unify_request data structure from code_info to the HLDS,
and move the unify_request handling from code_gen.nl to modes.nl.
This is because we now generate HLDS code rather than LLDS code
for complicated unifications.
code_util.nl, hlds_out.nl:
Do some special name mangling for =/2.
float.nl, typecheck.nl, undef_types.nl, term.nl, hlds.nl:
Until we implement `float' properly, define it as an abstract type
in float.nl.
hlds.nl, make_hlds.nl:
Rename `local_pred, imported_pred, exported_pred' to just
`local, imported, exported' since they also apply to types, etc.,
not just to preds.
mercury_compile.pp, mercury_to_goedel.nl, prog_util.nl:
Replace to goedel__ prefixes in prog_util.nl with prog_util__.
std_util.nl:
Change the code for semidet_succeed to avoid determinism warning.
switch_detection.nl:
Improve switch detection by handling chained unifications.
We now detect switches in cases like the following:
( X = X1, X1 = a, ... ; X = X2, X2 = b, ... )