Estimated hours taken: 2
hlds_goal:
Change the definition of is_builtin to use less space.
bytecode_gen, code_aux, code_gen, code_util, dependency_graph, follow_code,
higher_order, inlining, live_vars, make_hlds, modecheck_unify, modes,
polymorphism, stratify, unused_args:
Fixes to accommodate the change to is_builtin.
Estimated hours taken: 3
An overhaul of the code saving and restoring heap pointers and tickets,
and some other changes that affect the interface of code_info.
code_info:
The predicates that handle save heap pointers and tickets now return
the slot these things are stored in; the predicates that restore
and/or discard these values must give them back. This should avoid
the problem we used to have with the same slot being used to store
both a heap pointer and a ticket.
Rename some predicates to better reflect their purpose.
Accept pre_ and post_goal_update preds and the type lookup preds from
code_aux, since this is where they belong.
code_aux:
Move pre_ and post_goal_update preds and the type lookup preds to
code_info, since that is where they belong.
call_gen:
Fix the bug that broke nondet tailcalls for the case when the tailcall
is a higher order call.
code_gen:
Use the new way of saving and restoring heap pointers. We now save
tickets across negations; the absence of code to do this was a bug.
disj_gen:
Use the new way of saving and restoring heap pointers and tickets.
Avoid restoring anything in the first disjunct. In pruned disjunctions,
avoid saving the heap pointer more than once. (This does mean that
we may restore it in some cases were we didn't used to, but such cases
can be expected to be quite rare.)
ite_gen:
Use the new way of saving and restoring heap pointers and tickets.
dense_switch, lookup_switch, middle_rec, unify_gen:
Rename some called predicates as required by the changes to the
other modules.
Estimated hours taken: 3
code_info:
Restructure into several submodules to give the module logical
structure. Make very slight alterations in the interface.
call_gen, code_gen:
Use the new interface of code_info.
code_aux:
Add comments.
code_util:
Fix a bug caught by Fergus' review.
disj_gen, ite_gen, liveness:
Fix some comments.
Estimated hours taken: 0.5
The only significant change in this checkin is that liveness.m now
tries to compute the best resume_locs for negations (it already did
for if-then-elses and disjunctions; leaving out negations was an
oversight in my earlier checkin).
The other changes are only syntactic:
I have removed the cont-lives and nondet-lives field from goal_info,
since they are not used anymore.
I have replaced the nondet-lives field in code_info, which is not used
anymore, with a follow-vars field, which is not used yet (but will be).
Some of the "read" access predicates in hlds_goal did not have "get" in
their name; I added them.
Estimated hours taken: _____
Take the code generator a big step closer to notes/ALLOCATION.
The new code generator emits code that is smaller and faster than
the code we used to emit.
Nondet liveness is no longer used; nondet live sets are always empty.
In code that was being modified anyway, remove its handling. Other
uses will be removed later (this keeps this change from being far too big;
as it is it is merely too big). Similarly for cont-lives.
In several places, clarify the code that gathers several code pieces together.
call_gen:
Unset the failure continuation and flush the resume vars to
their stack slots before nondet calls.
Move the code that decides whether a nondet call can be a tailcall
to code_info.
code_aux:
Remove the code to handle resume points, since these are now
handled in the specific constructs that need them. Replace it
with a sanity check.
code_exprn:
Add a predicate to place multiple vars.
code_gen:
Remove the predicate code_gen__generate_forced_goal, since it
packaged together some operations that should be executed at different
times.
Don't unset the failure continuation after every nondet goal;
this is now done in the constructs that need it.
Modify the handling of negation to use resume point info
according to notes/ALLOCATION.
Remove the predicate code_gen__ensure_vars_are_saved which was
use to save all lives variables to the stack before nondet
disjunctions and if-then-elses; we don't do that anymore.
code_info:
Significantly simplify and document the handling of failure
continuations, and make the types involved abstract types.
Factor out common code in the handling of det and semi commits.
Keep track of "zombies", variables that are dead wrt forward
execution but whose values we need because they may be needed
at a resume point we can reach.
Remove several now unneeded predicates, and introduce new
predicates to help other modules.
code_util:
Add a couple of predicates to check whether ia goal cannot fail before
flushing all variables to the stack, and whether a goal cannot flush
any variables to the stack. These are used in liveness to decide
which entry labels will be needed at resume points.
disj_gen:
Unify the handling of det and semi disjunctions. Model the code
handling of nondet disjunctions on the code handling pruned
disjunctions. It is possible that the handling of nondet and pruned
disjunctions can also be unified; the new code should make this
significantly easier.
Make the code conform to notes/ALLOCATION. This means saving
only the variables mentioned in the resume_point field, not
flushing all live variables to the stack at the start of a
nondet disjunction, handling zombies, and using the new method
of flushing variables at the ends of branched structures.
ite_gen:
Unify the handling of det and semi if-then-elses. Model the code
handling of nondet if-then-elses on the code handling det/semi
if-then-elses. It is possible that the handling of nondet and pruned
if-then-elses can also be unified; the new code should make this
significantly easier.
Make the code conform to notes/ALLOCATION. This means saving
only the variables mentioned in the resume_point field, not
flushing all live variables to the stack at the start of a
nondet if-then-else, handling zombies, and using the new method
of flushing variables at the ends of branched structures.
Apply the new rules about liveness in if-then-elses, which say that
the else part is parallel not to the then part but to the conjunction
of the condition and the then part.
dense_switch, lookup_switch, string_switch, switch_gen, tag_switch, middle_rec:
Use the new method of flushing variables at the ends of branched
structures. Don't call remake_with_store map; switch_gen will do so.
Fix an old bug in lookup_switch.
The code in switch_gen which looked for the special case of a two-way
switch used to use a heuristic to decide which one was recursive and
which one was a base case. We now check the codes of the cases.
hlds_goal:
Adjust the structure of the resume_point field to make it easier
to use. Add a more convenient access predicate.
hlds_out:
Don't print the nondet liveness and cont live fields, since they are
not used anymore. Comment out the printing of the context field,
which is rarely useful. Modify the printing of the resume_point field
to conform to its new definition.
live_vars:
Use the resume_point field, not the nondetlives field, to decide
which variables may be needed on backward execution. Remove some
code copied from liveness.m.
liveness:
Put the several pieces of information we thread through the traversal
predicates into a single tuple.
Don't put variables which are local to one branch of a branched
structure into the post-birth sets of other branches.
Apply the new rules about liveness in if-then-elses, which say that
the else part is parallel not to the then part but to the conjunction
of the condition and the then part. Variables that are needed in the
else part but not in the condition or the then part now die in at the
start of the condition (they will be protected by the resume point on
the condition).
We now treat pruned and non-pruned disjunctions the same way
wrt deadness; the old way was too conservative (it had to be).
We still mishandle branches which produce some variables but
can't succeed.
mercury_compile:
Liveness now prints its own progress message with -V; support this.
store_alloc:
When figuring out what variables need to be saved across calls,
make sure that we put in interference arcs between those variables
and those that are required by enclosing resume points.
Don't compute cont-lives, since they are not used anymore.
livemap:
Fix the starting comment.
Estimated hours taken: 3
code_aux, code_info:
Start using resume_point information to save variables to their
stack slots when they become forward dead.
code_gen, middle_rec:
Handle the code fragments that can now result from pre and post
goal updates.
live_vars:
Make sure that variables that can be put into stack slots at
resumption points get stack slots allocated to them.
liveness:
Fix a bug in the computation of resume_point sets.
llds_common:
Fix some comments.
Estimated hours taken: 6
Another step towards implementing notes/ALLOCATION.
hlds_goal:
Define a new type that gives the information associated with
resumption points. Add a field of this type to goal_info, and the
associated operations.
Change the layout of the access predicates to make the code_info
structure easier to modify in the future.
liveness:
Fill in the resume_point fields of goals that establish
resumption points.
hlds_out:
Print the new resume_point field of goal_info.
Allow the printing of base_type_infos on the right hand sides
of unifications.
code_info:
Reuse the stack of store maps field, which we don't use anymore,
to store the stack of resumption-point variable sets. Add operations
on this new stack.
Remove the slot that holds the code model of the current procedure,
since it is used rarely and can be easily looked up in the proc_info,
which we also store. Reuse the slot to store the maximum number of
stack pushes, eliminating the pair used to store it previously.
Change the layout of the access predicates to make the code_info
structure easier to modify in the future.
code_gen:
Don't pass the code model to code_info__init.
code_exprn:
Make an abort message more specific.
hlds_pred:
Fix typos.
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: 3
hlds_goal:
Documented the distinction between the three kinds of uses we have
for map(var, lval): stack_slots, store_map and follow_vars.
Added a new field, follow_vars, to hlds__goal_info.
follow_vars:
Attach the follow_vars information to the kinds of goals listed
in notes/ALLOCATION.
hlds_out:
Print out the follow_vars field. Make some other outputs easier to
read.
hlds_pred:
Remove the follow_vars field of the proc_info, since the follow_vars
of the goal_info of the goal of the procedure has taken its place.
code_gen:
Use the follow_vars field from the main goal's goal_info, rather
than the follow_vars field of the proc_info.
store_alloc:
Attach the last follow_vars not to the proc_info but to the main goal.
Estimated hours taken: 0.75
The first step towards the implementation of the new ALLOCATION strategy:
renamed call_info to stack_slots.
There are no algorithmic changes in this checkin.
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: 24
A bunch of changes required to fix problems in code generation for
model_det and model_semi disjunctions.
simplify.m:
Don't convert all model_det and model_semi disjunctions into
if-then-elses, because that doesn't work if the disjuncts
have output variables, which can happen (e.g. with cc_nondet
disjunctions)
disj_gen.m:
Fix a bug in the code generation for semidet disjunctions:
don't forget to jump to the end of the disjunction after
each disjunct!
liveness.m, live_vars.m, store_alloc.m, disj_gen.m:
Treat backtracking in model_det and model_semi disjunctions
as shallow backtracking rather than deep backtracking.
This means that rather than pushing all live variables
onto the stack at the start of a model_det/semi disjunction,
and using the nondet_lives to keep track of them, we instead
treat these disjunctions a bit more like an if-then-else and
use the ordinary liveness/deadness to keep track of them.
code_aux.m:
Change code_aux__pre_goal_update so that it only applies
the post-deaths if the goal is atomic. Applying the
*post*-deaths to the set of live variables in the *pre*-goal
update only makes sense for atomic goals.
(I think previously we only ever generated post-deaths
for atomic goals, but now we generate them also for
goals inside model_det or model_semi disjunctions.)
code_gen.pp, middle_rec.m:
Pass an is-atomic flag to code_aux__pre_goal_update.
hlds_goal.m:
Add some comments.
goal_util.m:
Fix bugs in goal_util__name_apart_goalinfo.
It wasn't applying the substitution to all the
appropriate fields.
code_exprn.m:
Improve the error message for one of the internal errors.
hlds_out.m:
Print the stack slot allocations in the HLDS dump again.
Estimated hours taken: 1
Since NU-Prolog hasn't been capable of executing the compiler for a long time
now, I have removed the .pp files and replaced them with .m files.
code_gen, mercury_compile, optimize:
Remove NU-Prolog specific code.
Mmake:
Don't refer to the .pp files.
dnf:
Add the capability of transforming all procedures regardless of
markers. This will be useful when generating idiomatic Prolog code.
mercury_to_goedel, polymorphism:
Fix comments.