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.
inst_match.m:
Add new predicate `inst_matches_binding'.
This is like `inst_matches_final', except that it ignores
differences in uniqueness.
modes.m, det_report.m, constraint.m:
Use `inst_matches_binding' rather than `inst_matches_final'
when testing whether a goal has no output variables.
This avoids some problems with unique modes.
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
Previously we didn't check if a unification was unifying with
a clobbered value. With these changes, we now do.
inst_match.m:
Add an extra parameter `unify_is_real' to `abstractly_unify_inst'.
The extra parameter specifies whether this is a "real" or "fake"
unification; if it is fake, unifications with clobbered values
are allowed.
modes.m:
Pass the above-mentioned new parameter to `abstractly_unify_inst'.
prog_io.m, hlds.m:
Store the above-mentioned new parameter in the unify_inst table.
mode_util.m:
Use the above-mentioned new parameter when looking up an inst
in the unify_inst table.
undef_modes.m, mercury_to_mercury.m:
More miscellaneous changes to handle new `unify_is_real' parameter.
modes.m:
Fix the bug that Zoltan reported in unique mode checking.
We should now detect most (not yet all) cases of using
`clobbered' insts.
[NOTE: This change might potentially break things; check
~fjh/log/test_mercury.out before doing a CVS update.]
code_exprn.m, modes.m:
Fix singleton variable warnings by deleting useless code.
shapes.m, typecheck.m:
Fix singleton variable warnings by renaming variables so that they
start with an underscore.
make_hlds.m:
Pass the context down into transform_goal_2, unravel_unification,
insert_arg_unifications, and append_arg_unifications, so that
the goal_info_context in the newly built HLDS is never empty.
This is needed because the new warn_singletons uses the context,
so it has to be valid.
unify_proc.m:
Pass a term__context to unravel_unification (as required by
above change).
quantification.m:
Rearrange some comments that got shifted a dozen
lines from the code they referred to.
vn_util.m:
Fix omission in Zoltan's changes with `succip(FramePointer)'
which caused "Software Error: unexpected lval in vn_...".
modes.m:
Optimize away unifications with dead variables.
(The code generator already does that, but by
that time we have already allocated unnecessary
stack slots for them.)
code_exprn.m:
Avoid generating sequences such as `r2 = r3; r3 = r2;'
when a register already contains the correct value.
(This change was in fact at least as much Tom's work as mine.)
store_alloc.m:
For disjunctions, we only want to allocate registers
for the variables that are output by the disjunction.
The inputs should go in framevars, not in registers.
This avoids much of the register-shuffling
in the code generated for e.g. list__member(out, in).
(This change was in fact at least as much Tom's work as mine.)
modes.m, mode_errors.m, mode_util.m:
Finish implementing mode checking of lambda expressions.
inst_match.m:
Mode checking of higher-order pred modes was slightly
too strict - relax it a little.
modes.m, mode_errors.m, mode_info.m:
For mode errors that occur in predicate calls,
record the argument number that they occurred in,
and print it out in mode error messages.
(This also fixes a bug where some of the determinism
error messages would say "in argument 0 of call to pred ...").
polymorphism.m:
A couple of minor simplifications.
frameopt:
Look inside blocks introduced by value numbering when looking
restorations of succip.
value_number, opt_util:
If we are using conservative garbage collection, disable value
numbering for blocks that allocate more than one cell on the heap.
This allows value numbering of most blocks to work in the absence
of -DALL_INTERIOR_POINTERS.
all other source files:
Clean up "blank" lines that nevertheless contain space or tab
characters.
modes.m, mode_util.m, inst_match.m:
Move the 800 lines of code for inst__merge,
abstractly_unify_inst, and the predicates they
call from modes.m into inst_match.m.
(modes.m was getting too huge.)
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.
modes.m:
Applied Fergus's fix to allow repeated modechecking after his
recent changes.
peephole:
Be more aggressive in optimizing instruction sequences created
by the replacement of tailcalls with the code from the start
of the procedure.
Lambda expressions now work, and you can now use polymorphic predicates
as higher-order pred terms. (Mode checking and determinism checking
are still not implemented, and the modes of call/N are very restrictive.
But these change makes solutions/2 a lot more useful now.)
hlds.m:
Comment out the stuff for recording num_warnings, since it
wasn't being used. Instead we now use that slot in the
module_info for a counter which holds a number to use to
name the predicates for lambda expressions. Add a new
predicate module_info_next_lambda_count/3 to get and
increment this counter.
modes.m:
Transform higher-order pred constants into lambda expressions.
(Also, use slightly more meaningful variable names in a few places.)
polymorphism.m:
Use module_info_next_lambda_count/3 to name the predicates
created for lambda expressions.
code_util.m:
Handle __LambdaGoal__ labels correctly.
quantification.m:
Fix ANOTHER bug in quantification of lambda expressions.
hlds_out.m:
Fix minor indentation problem in output of lambda expressions.
polymorphism.m:
When a lambda expression is encountered, convert it into a
new predicate. (Works OK, with one caveat: you can currently
only have one lambda expression per program.)
make_hlds.m:
Export a couple of predicates so that polymorphism.m can use
them when it is creating new predicates for lambda expressions.
modes.m:
Fix a problem with quantification of lambda goals.
Add some code to convert higher order predicate calls into
lambda expressions so that they get mode checked and
polymorphism-processed properly. (Unfinished, code
commented out.)
hlds.m:
Simplify the code for goal_info__remove_feature.
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.
modes:
When introducing new goals, give them a context, since it may be
needed for error messages in determinism analysis.
hlds_out:
Print the context of each goal if -V is set.
det_analysis:
Try to ensure that we don't print the names of introduced variables.
-------------------------------------------------------
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.
modes.m, unify_proc.m:
Fix obscure "map_lookup failed" bug triggered by a partially
instantiated mode of a complicated unification predicate, whose
procedure body contained a call the the same complicated
unification predicate in a different partially instantiated
mode.
constraint.m, cse_detection.m:
Change calls to modecheck to match new simplified interface.
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.
modes.m, typecheck.m, code_util.m:
Don't report a compile error if there is a higher-order pred
unification in a compiler-generated predicate. (Instead, delay
the error until run-time so that it only occurs if the higher-order
pred unification in question actually gets executed.)
compiler/Mmake:
Include the library .m files in the tags file.
hlds.m and lots of other places:
Change the type of the argument list of a HLDS `call' from
`list(term)' to `list(var)'.
modes.m:
When computing the cons_id for a construction/deconstruction
unification, check whether the cons_id is already present
in info for that unification, and if so use the existing cons_id.
This is necessary to make --common-goal work, since cse_detection
invokes mode analysis after polymorphism, and polymorphism
introduces code_address cons_ids which we must not throw away.
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.
modes.m:
Handle switches. (Originally we didn't handle them, since
switch detection comes after mode analysis, but now the
common-sub-expression hoisting pass reinvokes mode analysis,
so we need to handle them.)
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!!!)
prog_io.m:
Associate a term__context with every goal:
rename the type `goal' as `goal_expr' and add
`:- type goal == pair(goal_expr, term__context)'.
make_hlds.m, negation.m, mercury_to_mercury.m, mercury_to_goedel.m:
Change to handle new representation of goals.
modes.m, typecheck.m:
Use the term__context from the goals, since the above changes
make it meaningful now.
implication.m, make_hlds.m, mercury_compile.pp:
Fold the implication transformation into the make_hlds pass.
Net result: better error messages, but compilation time is worse.
Makefile.common:
Use mkdir -p.
Add mmake.sh.
Change the tags rule so that it gets the .pp files first.
Change the name of the compiler target from comp to mercury_compile.
Remove the rules for test.exe since they duplicate the auto-generated
ones in test.dep (which call the target `test' not `test.exe').
Remove the `code_gen' target. (Tom, if you need it, put it in
Makefile.params.)
Hack around with the installation rules (still in a state of flux).
options.nl:
Disable the --mod-comments option by default.
llds.nl:
Only output the gc livevals comment if --mod-comments is enabled.
mercury_compile.nl, prog_io.nl:
Handle `file not found' errors more cleanly.
When making the dependencies, assume that any files not found
are library files, so don't put them in the dependencies.
modes.nl:
Resolve type ambiguity introduced by change to prog_io.nl.
Mmake.rules Mmake.vars:
Split Makefile.mercury into two halves for use by mmake.
NOTE: I haven't removed Makefile.mercury yet, so any changes
need to be made in both places!
modes.nl:
Bug fix. We need to restore the old instmap after mode-checking
a negated goal. This is because even though a negated goal
can't bind any variables, it can add information about their bindings;
we need to make sure that if the negated goal fails (and so the
negation succeeds) we discard that information.
[This bug caused the compiler to generate incorrect code for
type_is_atomic(Type, ModuleInfo) :-
classify_type(Type, ModuleInfo, BuiltinType),
BuiltinType \= polymorphic_type,
BuiltinType \= pred_type,
BuiltinType \= user_type(_).
because it incorrectly optimized away the last test, thinking
that it was unreachable.
That in turn caused the stage 2 compiler to generate incorrect
code for one of the modes of list__append.
As you can imagine, it took me quite some time to track down
this bug ;-) ].
mode_util.nl, modes.nl, follow_code.nl:
Implement merge_instmap_delta properly, to fix a bug in
determinism analysis. This required threading the module_info
through various predicates.
Makefile.common:
Add new targets `mercury_compile.sicstus' (the Mercury compiler
compiled with Sicstus) and `mercury_compile.sicstus.debug'
(debugging version of the above).
*.nl:
Use Sicstus-compatible char and string escapes.
Avoid the use of explicit existential quantification.
Various other hacks to get things to parse correctly under Sicstus.
prog_io.nl:
Don't allow (A -> B) in DCGs, since NU-Prolog and Mercury give
it different semantics to Sicstus.
sp_builtin.nl, sp_lib.nl:
Split sp_builtin.nl into sp_builtin.nl and sp_lib.nl.
sp_conv.sed:
Add sed script which converts some character escapes so that
they work with Sicstus.
term_io.nl:
Remove term_io__prefix_op etc. since they aren't used anymore.
modes.nl:
Call module_info_remove_predid for predicates which have mode
errors, to avoid spurious flow-on errors during determinism
analysis.
Also fix bug in the check for higher-order unifications.
Makefile.common:
Add some targets for compiling the compiler and the library.
type_util.nl, dense_switch.nl, switch_gen.nl, polymorphism.nl:
Rename inttype, chartype, etc. as int_type, char_type, etc.
Add polymorphic_type.
modes.nl, mode_errors.nl:
Report an error for direct attempts to unify higher-order pred types.
(Of course, we don't catch indirect attempts via polymorphic types -
that would require global analysis. For them, we report the error
at runtime.)
modes.nl:
Remove unreachable code from conjuctions.
(XXX also should do this for if-then-else.)
options.nl:
Turn -p off by default. I'll turn it on again when it works ;-)
*.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.