Estimated hours taken: 0.1
bootcheck:
Link a smaller number of modules at a time to the stage2 directories.
This ought to fix the problem with muse's argument vector overflowing.
test_mercury:
Fix a comment.
Estimated hours taken: 0.25
Fixed bug which caused a map__lookup failure when a pragma(export, ...)
declaration was made for a proc which was not exported from the module (ie.
not in the interface section).
dead_proc_elim.m:
Never eliminate a proc which is a pragma_exported_proc.
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: 6
A bunch of bug-fixes to get the reverse C interface working.
live_vars.m:
Enable the previously commented-out code to save variables
on the stack before a pragma_c_code, because the C code may
recursively call Mercury which would clobber the registers.
code_gen.pp:
Before generating code for a pragma_c_code, make sure we save the
variables and succip on the stack, because the C code may
recursively call Mercury which would clobber the registers
(r1, r2, ...) and succip; conversely, make sure that after generating
the pragma_c_code, we call code_info__clear_all_registers so
that the code generator knows the registers have been clobbered and
will use the saved values on the stack.
Also add calls to save_registers() and restore_registers() to
match the calls to restore_registers() and save_registers() in
export.m; these save/restore the genuine physical machine
registers (global register variables) to/from the fake_reg
array, which is necessary since the intervening C code may use
those registers if it doesn't #include "regs.h".
(They're callee-save, so the C code will restore the old
value when its finished, but that is not enough if you have
Mercury calls C calls Mercury, and the inner Mercury wants to
use the register values for sp, hp, curfr, and maxfr.)
call_gen.m:
Export call_gen__save_variables for use by code_gen.pp.
make_hlds.m:
Fix a slightly misleading error message.
Estimated hours taken: 0.25
(Plus some unknown amount of Tom's debugging time.)
compiler/llds_out.m:
Cast integers literals to (Integer), so that
an expression like (1 << N) uses 64 bits rather than 32.
This fixes a problem with --bits-per-word 64.
Estimated hours taken: 0.25
tools/test_mercury:
(Temporarily) add --lookup-switch-req-density 101 to disable
lookup switches, so that Tom's change will bootstrap check.
Estimated hours taken: 6
runtime/engine.mod:
Increase the size of the zone allocated for local variables
from 1k to 10k, because some of the code on the Alphas (specifically
some code in library/string.c) was overflowing the 1k limit
as a result of a large C function comprised of 10 large Mercury
procedures (string__format...) which had lots of inlined calls to
string predicates implemented with pragma c_code.
(This was what was causing the recent illegal instruction
errors on the Alpha.)
Estimated hours taken: 0.5
During the profiling signal handler it was possible that some memory would
have to be malloc'd. If the signal occured during another malloc then
internal state of malloc would get corrupted and hey presto seg fault.
Now memory for the profiler gets malloc'd in big chunks so to reduce the
chance of a malloc inside a malloc.
For a run of the compile now only do 4 malloc's instead of 6000.
profiler/prof_mem.*:
The new memory management scheme for profiling.
profiler/prof.c:
Changes to use the new scheme.
profiler/Mmake:
Add the prof_mem.* stuff.
Estimated hours taken: 2
code_util:
Update a comment.
dead_proc_elim:
Fix a progress message.
hlds_out:
Put a comment sign before each switch arm's "X has functor f"
output, since this is not proper Prolog or Mercury syntax.
make_hlds:
Temporarily allow the definition of builtins, to permit bootchecking
while unary builtins are added.
prog_io:
Improve the handling of DCG variables in if-then-elses the same way
I recently improved disjunctions. Also factor out a bit of common
code.
Estimated hours taken: 0.25
scripts/mc.in:
Back out Zoltan's change to pass --num-real-r-regs instead
of --num-real-regs, since it prevents bootstrapping.
We need to wait until the rest of his changes have been
installed everywhere before recommitting this change.
Estimated hours taken: 0.5
notes/CODING_STANDARDS:
Add more detailed guidelines on layout of comments,
if-then-elses and type definitions. Mention that
language features such as functions shouldn't be used yet.
Estimated hours taken: 0.1
boehm_gc/Makefile:
Don't pass -fpic, since this isn't needed on any current
architectures, and apparently it causes problems compiling
things on some versions of Linux.
Estimated hours taken: 2
bootcheck, binary, linear:
Link to absolute, not relative path names, since relative path names
do not work back across symbolic links.
binary, linear:
Allow the user to give an initial list of suspects.
assemble, binary, linear:
Allow negative searches, i.e. searches in which the base version is
the bad version and we want to see which module "fixes" the problem
caused by the other modules, as opposed to normal searches in which
we are looking for the module that introduces the problem.
Estimated hours taken: 4
call.mod, solutions.mod, type_info.h:
Make the code work with --args compact
wrapper.mod:
Increase the default det stack size to 2Mb.
Estimated hours taken: 6
float, int:
Add reverse modes for the arithmetic predicates and functions,
and make unary plus and minus builtins.
io.m, mercury_builtin, std_util, string:
Make the C code work with --args compact.
In std_util, reduce the number of comment formats used from 4 to 2.
Estimated hours taken: 30+
arg_info:
Fix allocation to work properly for --args compact.
bytecode*:
Handle complex deconstruction unifications. Not really tested because
I can't find a test case.
bytecode_gen, call_gen, code_util:
Use the new method to handle builtin predicates/functions. We now
handle reverse mode arithmetic and unary plus/minus as builtins.
code_gen, code_init, follow_vars, hlds_pred:
Put back the initial follow_vars field of the proc_info, since this
may allow the code generator to emit better code at the starts of
of predicates.
inlining:
Don't inline recursive predicates.
goals_util:
Add a predicate to find out if a goal calls a particular predicate.
Used in inlining to find out if a predicate is recursive.
unused_args:
Remove code that used to set the mode of unused args to free->free.
Since this changes the arg from top_in to top_unused *without* code
in other modules being aware of the change, this screws up --args
compact.
llds, llds_out, garbage_out:
Prepare for the move to the new type_info structure by adding a new
"module" type for defining structures holding type_infos. Not
currently generated or output.
llds, opt_debug, opt_util, vn_type, vn_cost, vn_temploc:
Change the argument of temp to be a reg, not an int, allowing
floating point temporaries.
vn_type:
Add information about the number of floating point registers and
temporaries to the parameter structure (these are currently unused).
llds, dupelim, frameopt, livemap, middle_rec, value_number, vn_filter,
vn_verify:
Add an extra field to blocks giving the number of float temporaries.
options:
Add parameters to configure the number of floating point registers
and temporaries.
mercury_compile:
Add an extra excess assign phase at the start of the middle pass.
This should reduce the size of the code manipulated by the other
phases, and gives more accurate size information to inlining.
(The excess assign phase before code generation is I think still
needed since optimizations can introduce such assignments.)
value_number:
Optimize code sequences before and after assignments to curfr
separately, since such assignments change the meaning of framevars.
This fixes the bug that caused singleton variable warnings to contain
garbage.
vn_block, vn_flush, vn_order, vn_util:
Add special handling of assignments to curfr. This is probably
unnecessary after my change to value_number, and will be removed
again shortly :-(
vn_flush:
Improve the code generated by value numbering (1) by computing values
into the place that needs them in some special circumstances, and
(2) by fixing a bug that did not consider special registers to be
as fast as r1 etc.
vn_util:
Improve the code generated by value numbering by removing duplicates
from the list of uses of a value before trying to find out if there
is more than one use.
simplify:
Avoid overzealous optimization of main --> { ..., error(...) }.
handle_options:
Fix an error message.
code_aux:
Break an excessive long line.
Estimated hours taken: 0.2
NEWS:
Document our new ability to perform reverse mode arithmetic.
configure.in:
Rename NUM_REAL_TEMPS to NUM_REAL_R_TEMPS, since we may want to have
float temps some day.
Estimated hours taken: 0.1
pragma_c_code_unused_var.m:
Change the name of a variable from String to Msg, since String
is a C type name.
pragma_c_code_unused_var.exp:
Change String to Msg and update the format of the expected message.
Estimated hours taken: 3.0
Handle det disjunctions. We emit code to try each disjunct one by one
(like semidet disjunctions), until we get to a disjunct that is det
(there must be at least one), we generate code for the det disjunct
and then we're done.
eg
( A
; B
; C % det
; D
)
becomes equivalent to
(A -> true
;B -> true
;C
)
except for output bindings....
compiler/code_info.m:
Improve the message for a compiler abort.
(I didn't get the whole change right first shot - sprung!)
compiler/code_gen.pp:
forward the handling of det disjunctions rather than aborting.
compiler/disj_gen.m:
new code for handling det disjunctions.
Estimated hours taken: 1
prog_util:
Add a predicate to rename variables in the kinds of goals we have in
items. (We already have similar predicates for terms and for
hlds_goals).
prog_io:
We used to expand ( p ; q ) in DCG clauses to become
( p(DCG1, DCG2) ; q(DCG1, DCG3), DCG2 = DCG3 ). These extra
unifications can pile up rather badly; in the new version of lexer.m,
two 128-way switches each ended up with 90 unifications in the last
arm. This is very bad for performance. Instead of adding unifications
to make sure that both arms of a disjunction put the final stream value
in the same variable, we now use renaming when possible.
Estimated hours taken: 12
Four loosely related changes to improve mode inference.
--------------------
(1) Fix a problem with inference of unique modes.
Previously it was sufficient to just look at the final insts of the
mode and check whether they were `clobbered' or not in order to tell
which arguments will be dead on exit from this procedure. However,
that doesn't work for inferred modes, where the final inst will
initially be `not_reached'. Previously mode inference just assumed that
all arguments to a predicate were live, but that prevents it from being
able to infer `di' modes. So I've added a new field to the proc_info
to record which arguments are required to be dead on exit.
I've also changed mode analysis so that it checks that such
arguments really are dead. This means you can declare both `di' and
`ui' modes of a predicate, and so long as you declare the `di' one
first, mode checking should handle this overloading. It also means
that errors such as passing a variable which is live to a procedure with
a `di' mode argument are caught earlier, with a potentially better
error message; mode checking may also be able to reorder such calls,
so that the `di' mode pred is scheduled last. Mode inference now
notices if an argument is dead, and if so will try infering a `di'
mode.
hlds_pred.m:
Add a new field to the proc_info, the `maybe_arglives', of type
`maybe(list(is_live))'. If set, this records whether or not the
arguments are required to be dead after the procedure or not.
Add an access predicate which checks whether this is set,
and returns either the value set, or if no value special value
is set, looks up a value based on the modes by calling get_arg_lives
from mode_util.m.
make_hlds.m:
Add a MaybeArgLives parameter to add_new_pred.
(Also change the error messages about pragmas to reflect
the new pragma syntax.)
clause_to_proc.m, unify_proc.m:
Pass MaybeArgLives = no to add_new_pred.
modes.m, mode_errors.m:
Use the new arglives field. When mode-checking a call (or
higher-order call), check that all the variables which are
required to be dead really are dead.
unique_modes.m:
Use the new arglives field.
mode_util.m:
Add predicate `get_arg_lives', for use by modes.m and hlds_pred.m.
--------------------
(2) Fix a problem with mode inference looping.
It was checking whether a fixpoint had been reached by comparing the
(un-normalised) inferred final insts with the previously recorded final
insts (which had been normalised). Instead, it has to normalise the
insts before the comparison.
modes.m:
When doing mode analysis of an inferred mode, normalise the insts
before checking whether they've changed, rather than vice versa.
--------------------
(3) Fix a problem with the computation of liveness for mode-analysis
of if-then-elses that was detected when I tried to bootcheck the above
changes.
modes.m, unique_modes.m:
When mode-checking if-then-elses, the variables in the "else"
should not be considered live when checking the condition.
(They're nondet-live, but not live with regard to forward execution.)
--------------------
(4) Reduce the occurrence of mode inference inferring spurious
`in(not_reached)' modes.
modes.m:
If the top-level inst of a variable becomes `not_reached', set
the whole instmap to `unreachable'.
Estimated hours taken: 0.25
mercury/Mmake.common.in:
Add `--no-infer-types --no-infer-modes --halt-at-warn' as the
default MCFLAGS.
*** IMPORTANT NOTE: if you have set MCFLAGS in your
*** Mmake.params file, you should change your Mmake.params
*** file to set EXTRA_MCFLAGS instead.
Estimated hours taken: 0.5
compiler/mercury_compile.pp:
Fix a bug with the `--typecheck-only' option: although it stopped
the front-end pass after typechecking, the compiler still tried
to do the middle pass and hence got an internal error.
(Thanks to Mark Brown for the bug report.)
Estimated hours taken: 0.5
compiler/modes.m:
Fix a bug in mode inference: I had commented out the call to
set the instmap to unreachable when we encounter a call to
a new mode, but it turns out that this it is necessary for
correctness.
Estimated hours taken: 4
compiler/{mode_errors.m,mode_info.m,modes.m,unique_modes.m}:
Fix the handling of error message contexts for mode errors
so that it does say `in call to predicate foo/2' when it
means `in call to function foo/1'.
Estimated hours taken: 0.25
tests/hard_coded:
Add a test (which we do not yet pass, so I haven't added it to
the list of tests to run automatically) for the case of
defining a function and constructor with the same name, arity,
and the same argument and return types.
Estimated hours taken: 24
Add preliminary support for mode inference.
hlds_pred.m, hlds_out.m:
Add a new pred marker `infer_modes'.
make_hlds.m:
If there are no declared modes for a predicate,
set the `infer_modes' marker in the pred_info.
modes.m:
Implement mode inference.
When we see a call to a predicate with the `infer_modes' marker
set, then if the call does not match any of the modes we've
already inferred for the predicate, create a new inferred mode;
the initial insts are set to the normalised argument insts, and
the final insts are initially set to not_reached. When
analysing such a predicate, rather than checking whether the
inferred final insts match the declared final insts, just
replace the old final insts with the normalised version of the
newly inferred insts. Change the top-level to repeat mode
analysis until a fixpoint is reached. We need to "normalise"
insts to a bounded approximation avoid non-termination due to
infinite expansion.
Also fix a bug which meant that using `inst constrained == any.'
didn't work - the checks for `any' weren't calling `inst_expand'.
mode_util.m:
Change the predicates `inst_is_ground', `inst_is_unique', etc.
so that they consider `not_reached' insts to satisfy the
condition.
mode_errors.m:
Change the message for predicates with no mode declaration.
Add code for printing out inferred mode declarations.
clause_to_proc.m:
Add a new predicate copy_module_clauses_to_procs
to call copy_clauses_to_procs for a list of pred_ids.
We call this from modes.m at the start of each fixpoint iteration.
Estimated hours taken: 0.25
prog_data.m, prog_io.m:
Rename the `pragma' type as `pragma_type', to avoid bootstrapping
problems caused by my change to make `pragma' an operator.
Estimated hours taken: 0.25
scripts/mmake.in:
Check for `Mmakefile' as an alternative to `Mmake'.
(This change is so I can rename scripts/Mmake as Mmakefile
to avoid a conflict with scripts/mmake on systems with
case-insensitive file systems, e.g. Windows 95.)
Estimated hours taken: 0.5
compiler/prog_util.m:
Fix a bug (caused by a cut-and-paste variable numbering error) in
the expansion of equivalence types in `:- func' declarations.
(Thanks to Tyson for the bug report.)
Estimated hours taken: 0.5
compiler/labelopt.m
In the two places that a set of labels was being constructed
by iterating over a list and doing set__inserts, construct a
list of labels and use set__insert_list since this changes
the complexity of the algorithm from O(N^2) to O(NlgN).
compiler/code_gen.pp:
Add a comment about shuffling r1 when generating code for
semidet pragmas.
Estimated hours taken: 4.0
(plus time fooling round with profiling)
After doing some profiling, I found some ways to improve the
speed of parsing. These changes turn some chains of ->;s into
switchs so that a dense switch can be used.
These changes improve compilation time by several percent
(I forget the number right now - 3% sounds familiar).
library/lexer.m:
Turn a couple of chained if-then-elses into switches
(each with 128 branches!).
Implement rev_char_list_to_string in C instead of calling
list__reverse and char_list_to_string.
library/char.m:
expand char__is_alnum_or_underscore to use a switch rather
than if-then-elses.
Estimated hours taken: 0.5
compiler/typecheck.m:
Add back the call to maybe_add_default_mode that I earlier removed.
make_hlds.m now calls maybe_add_default_mode for functions which
have `:- func' declarations, but the call here is still necessary
for functions which aren't declared.
Estimated hours taken: 0.5
Fix an infinite loop bug in type inference.
(N.B. There is still another infinite loop bug which remains unfixed.)
compiler/typecheck.m:
Fix a bug in type inference: to determine whether the types
had changed (i.e. whether the fixpoint had been reached),
it was checking whether the types were identical, but it
needs to instead check whether they are identical up to renaming;
this caused an infinite loop in type inference.
Also add code to print out the inferred types after each fixpoint
iteration if --debug-types is enabled, rather than just at the end.