Estimated hours taken: 3
Fix an omission in determinism analysis: make sure that a goal
with no output variables is considered to be in a single-solution context.
Also, implement pruning of multidet goals in det contexts.
(This fixes the long-standing problem with a
"Sorry, unimplemented: nondet goal in det context" error in code generation.)
compiler/det_analysis.m:
Make sure that a goal with no output variables is considered to
be in a single-solution context.
compiler/code_gen.pp:
Handle model_nondet goals in det contexts by wrapping them
inside a `generate_det_(pre_)commit' pair.
compiler/code_info.m:
Rename `generate_(pre_)commit' as `generate_semi_(pre_)commit',
and add a new pair of predicates `generate_det_(pre_)commit'.
Also fix restore_failure_cont so that it doesn't abort if
a multidet goal is called from within a det goal.
Estimated hours taken: 5
There was a problem where variables that die during forward
execution, and then become live again on backtracking were
not being handled correctly. There was some half-working code
to deal with the problem. It has now been fixed, and there
are some new test cases for the regression tests.
compiler/.cvsignore:
added *.ql since they become very irritating after a while...
compiler/inlining.m:
added a couple of comments
make a bit of the code more concise.
compiler/*.m:
changes to handle nondet-liveness correctly.
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
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.
compiler/*
Allow predicate and mode definitions, and predicate calls to have
module qualifiers. This allows a restricted form of predicate
name overloading.
compiler/llds.m, prog_io.m
In addition to above, these modules now write some labels in `*.c'
output files with module-name qualifiers. Predicate `main/2',
predicates of `mercury_builtin' and special predicates with names
like `__*__' are not qualified.
compiler/mercury_to_goedel.m
This module is probably a little more broken than before, as
module:qualifiers are ignored.
code_info:
Expose the predicate for producing a variable not into an arbitrary
location, but into a register.
tag_switch:
Produce the switched-on variable into a register, since we will
need it several times (to extract the primary tag, probably to
extract a secondary tag, and then -usually- to get some of its
fields).
jumpopt:
Added last call optimization for nondet predicates.
llds:
Added a new lval type to represent the succip slot of nondet
stack frames.
other files:
Changes required by the change to llds (there is a minor unrelated
change in vn_cost as well).
Tyson: please check my changes to code_info__get_shape_num and
garbage_out__write_liveval.
instructions, and the last argument from local labels. All these were
placeholders for info put in there by prof.m and used when emitting C
code.
The set of labels that serve as return points are now calculated in llds.m
just before each procedure has its C code generated. This set is passed to
output_instruction along with the label at the start of the procedure.
code_info.m:
Changed an XXX to a (more) meaningful comment, noting that
shapes__request_shape_number doesn't handle partial insts yet.
shapes.m:
Added more of the builtin types.
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.
code_info.m:
When doing a commit, make the curfr, redoip and maxfr live
so that garbage collection can figure out what is going
on (live values saved on both det & nondet stacks => commit).
code_gen.pp:
Fix a comment about an unimplemented thing.
code_info.m, code_gen.pp:
For the special case of a negated simple test
(ie X \= Y) generate better code. This only works
for the global success or failure of a predicate.
The next version of this fix will work for ->;
as well.
-------------------------------------------------------
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.
mercury_compile.pp llds.m:
fix occurences of A.B (use [A|B]) which were
causing problems trying to build a sicstus
compiler.
[the rest].m:
Fix the compiler so that calculator.m works.
This involved introducing an extra field into
the goal_info to keep track of variables that
become nondet-live.
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.
options.m:
Added the profiling option, which generates a file <module>.prof, which
contains the static call graph.
dependency_graph.m:
Predicate to output the static call graph in a form useful for the
profiler.
prof.m:
Scan's through the LLDS marking all labels that are continuation
labels. eg All label's cont_type field should be unknown now.
llds.m, code_info.m:
Minor changes so that the above stuff works.
code_info.m:
Change some comments in the generated code slightly.
ite_gen.m:
grab the instmap before generating the condition not
after in all three kinds of ite.
unify_gen.m:
grab and slap the code_info structure across the call
to generate_failure. This pair of calls should probably
be migrated into generate_failure. I'll check this out
soon (tomorrow).
call_gen.m code_gen.pp code_info.m garbage_out.m hlds.m llds.m
mercury_compile.pp shapes.m:
Output .garb files (with --gc accurate). This option overrides
information gleaned from the grades about GC.
Remove some of the magic numbers that were being used for
shape numbers.
*.m:
Changed the way the extra field in the label type is defined. Now
all labels are initially assumed to be 'unknown' and a seperate
profiling pass (to be implemented) will determine whether the label can
be accessed externally.
code*.m & *gen.m:
Implement an improved method of handling negated contexts.
The new method avoids saving things onto the stack before
an if-then-else or negation if it can.
Also, fix the implementation of nondet if-then-else so that
it does the soft cut 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.
code_info.m:
Bug fix: change generate_pre_commit and generate_commit so that
the values which need to be saved and restored are always pushed
onto the det stack, even in nondet predicates. The reason is
that if the committed goal fails, curfr is not valid, so we
can't restore the fields from the nondet stack.
(This way may well be more efficient anyway.)
disj_gen.m, ite_gen.m:
Handle the case when the current failure continuation is unknown
on entry to the disjunction or nondet if-then-else by creating
a new frame on the nondet stack. (Originally we just aborted
in this case; recently we "fixed" this, but it turned out that
the fix was not correct, for the same reason as the above-mentioned
bug in pre_commit/commit.
llds.m:
Add succfr/1 and prevfr/1 to the rval type in llds.m,
since they were needed by the above bug fixes.
(This caused dozens of changes elsewhere to handle the
new types.)
Also fix a trivial bug that I recently introduced which
prevented --mod-comments from working.
live_vars.m:
Fix bug in allocation of stack slots for nondet code.
(This is the one that caused the bug that ksiew and I found
when writing a calculator program.)
peephole.m:
Disable the succeed_discard() optimization, since it
causes incorrect code to be generated. It was replacing
modframe(do_fail) ... succeed() with
modframe(do_fail) ... succeed_discard() even when there were
instructions such as mkframe() in between.
modes.m, hlds.m:
When modechecking switches, record the binding of the switch variable
as we enter each case, so that we get the determinism analysis
right.
mercury_compile.pp:
Make sure that we set the exit status to be non-zero if we
find any errors.
typecheck.m, modes.m, undef_types.m, undef_modes.m:
Don't invoke type-checking if there are undefined types.
Don't invoke mode-checking if there are undefined modes.
This avoids the problem of the compiler aborting with an
internal error if there are undefined types/modes.
code_info.m:
Undo my recent changes to generate_pre_commit/generate_commit,
since they made the compiler buggy. I'm still not 100% sure why,
but I think that the optimization I was trying to make (to reduce
the number of instructions for a pre-commit/commit from 6 to 4) is
in fact not possible, since it doesn't preserve `curcp' (???).
Apologies to everyone for introducing the bug, and for
being so suspicious of everyone else's changes but not
suspicious enough of my own.
I can now build an almost-working stage2 compiler.
Unfortunately the stage2 compiler now fails when compiling
builtin_unify_float in mercury_builtin.m.
options.m call_gen.m code_gen.pp code_info.m code_util.m llds.m unify_gen.m:
A bunch of changes to implement the procs-per-c-function option.
This default is now `--procs-per-c-function 1', for reasonable
efficiency of compilation, but for efficiency of generated code
(e.g. when compiling benchmarks!)
use `--procs-per-c-function 0' (0 really means infinity).
I haven't tested this in any mode except asm_fast, so it's possible
that this change might break the other modes. If that turns out
to be the case, let me know. The symptom will be an error from
the C compiler or linker.
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.
frameopt:
fix the problem with destroying stack frames and creating
them again later, accessing detstackvars that were earlier
nominally destroyed.
vn_livemap:
renamed it to livemap since frameopt now uses it also.
value_number, vn_*:
Fixed some bugs. Reorganized the handling of blocks: they are now
put in at the last minute before llds writes out the code.
Made a start towards exploiting info about cheaper copies of
values.
optimize, options:
Made value_numbering an iterated optimization. Added a new
option to control how many times it is iterated together
with other the jumpopt, peephole and labelopt.
llds, call_gen, code_gen, code_info, middle_rec, opt_debug:
changed type of the argument of livevals to plain set.
Warning: in more than a week I haven't been able to fully test this change,
dur to kryten's flakiness and bugs upstream of the optimizer.
code_info.m:
Fix serious bug in code generation introduced by my last change
to code_info.m - in generate_commit, it was saving the redoip
of maxfr but restoring it into curfr.
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!!!)
code_exprn.m
code_info.m:
Fix an overly conservative sanity check.
mercury_compile.pp
typecheck.m:
Fix type errors due to the changed implementation of map.
Possibly these bits of code should be removed or something
so that map is properly abstract.
exprn_aux.nl:
a new module for manipulating rvals and lvals.
code_exprn.nl:
the new bottom level of the new code generator. This replaces
a large chunk of code_info.
*code* & *gen*:
various small changes to use the new bottom level of the
code generator.
io.nl:
Introduced a new predicate which ignore's any whitespace in the input.
Needs to have all the whitespace character's added to it.
*.nl and *.pp:
Changed the implementation of time profiling. Now during a compile,
the compiler identifies all the internal labels which can be accessed
externally, and marks them. At the moment, these are the continuation
labels of calls and the next disjunct in nondet disjunctions. Then
at the .mod output, it places a macro 'update_prof_current_proc' to
restore the profiling counter.
llds.nl:
Introduced an extra argument to the LLDS goto. It is the label
address of the Caller and is used for the profiling of tailcall's.
*.nl and *.pp:
Propagated the extra argument to all the appropiate files.
llds, code_info, opt_*, vn*:
Replaced curredoip with redoip(rval) to make references to other
redoips more efficient. Also, by turning modframe(L) into
redoip(curfr) = const(address_const(L)), value_number can now
optimize hijacking code better.
vn*:
If a disagreement on the desired value of an lvalue prevents value
number, try again after skipping to the first control point, since
this may cure the problem.
peephole, opt_util:
Now looking for successive modframes to optimize out.
disj_gen:
Put deterministic alternatives before others, mainly to make
the back mode of append easier to explain in the paper. :-(
mode_util:
Fixed scope error.
garbage_out:
Fixed some spelling and formatting errors.