The main aim of this change is to make the overall, high-level structure
of the compiler clearer, and to encourage better encapsulation of the
major components.
compiler/libs.m:
compiler/backend_libs.m:
compiler/parse_tree.m:
compiler/hlds.m:
compiler/check_hlds.m:
compiler/transform_hlds.m:
compiler/bytecode_backend.m:
compiler/aditi_backend.m:
compiler/ml_backend.m:
compiler/ll_backend.m:
compiler/top_level.m:
New files. One module for each of the major components of the
Mercury compiler. These modules contain (as separate sub-modules)
all the other modules in the Mercury compiler, except gcc.m and
mlds_to_gcc.m.
Mmakefile:
compiler/Mmakefile:
Handle the fact that the top-level module is now `top_level',
not `mercury_compile' (since `mercury_compile' is a sub-module
of `top_level').
compiler/Mmakefile:
Update settings of *FLAGS-<modulename> to use the appropriate
nested module names.
compiler/recompilation_check.m:
compiler/recompilation_version.m:
compiler/recompilation_usage.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/recompilation.version.m:
Convert the `recompilation_*' modules into sub-modules of the
`recompilation' module.
compiler/*.m:
compiler/*.pp:
Module-qualify the module names in `:- module', `:- import_module',
and `:- use_module' declarations.
compiler/base_type_info.m:
compiler/base_type_layout.m:
Deleted these unused empty modules.
compiler/prog_data.m:
compiler/globals.m:
Move the `foreign_language' type from prog_data to globals.
compiler/mlds.m:
compiler/ml_util.m:
compiler/mlds_to_il.m:
Import `globals', for `foreign_language'.
Mmake.common.in:
trace/Mmakefile:
runtime/Mmakefile:
Rename the %.check.c targets as %.check_hdr.c,
to avoid conflicts with compiler/recompilation.check.c.
Estimated hours taken: 10
Allow the native collector to work for nondet code, by generating layout
structures for the resumption points whose addresses can be put into
redoip slots in nondet stack frames.
If the program is compiled with both native gc and debugging, entries
to disjunctions will have two labels and two layout structures, one
for gc and one for the debugger. At the moment we make no attempt
to try to combine the two structures, since doing so would add significant
extra complexity. Optimizing this option combination will not be important
for a while yet anyway.
compiler/code_info.m:
Update the code that generates resume points to also optionally
generate layout structures for the stack labels.
compiler/disj_gen.m:
When we save the heap pointer, update not only the current code_info
but the saved code_info that represents the branch start position
as well, since the slot containing the saved heap pointer will be
live in each of the following disjuncts.
compiler/labelopt.m:
compiler/mercury_compile.m:
compiler/optimize.m:
compiler/value_number.m:
Arrange to pass the global_data structure to the label elimination
and value numbering passes. This is to (a) prevent the label
elimination pass from removing labels (e.g. stack resume labels)
that have layout structures, and (b) to prevent value numbering
for moving computations across such labels, since that would
invalidate the layout structure.
(The presence of pragma_c_code fragments in the generated code avoids
both these potential problems for layout structures that correspond
to trace events, but that solution would be suboptimal for resume
labels.)
compiler/hlds_module.m:
Add a utility predicate needed by optimize.m.
Estimated hours taken: 0.75
library/*.m:
compiler/*.m:
Undo Zoltan's bogus update of all the copyright dates.
The dates in the copyright header should reflect the years
in which the file was modified (and no, changes to the
copyright header itself don't count as modifications).
Estimated hours taken: 20
Give duplicate code elimination more teeth in dealing with similar arguments
of different function symbols. For the source code
:- type t1 ---> f(int)
; g(int, int).
:- pred p1(t1::in, int::out) is det.
p1(f(Y), Y).
p1(g(Y, _), Y).
we now generate the C code
Define_entry(mercury__xdup__p1_2_0);
r1 = const_mask_field(r1, (Integer) 0);
proceed();
thus avoiding the cost of testing the function symbol.
runtime/mercury_tags.h:
Add two new macros, mask_field and const_mask_field, that behave
just like field and const_field except that instead of stripping
off a known tag from the pointer, they strip (mask) off an unknown
tag.
compiler/llds.m:
Change the first argument of the lval field/3 from tag to maybe(tag).
Make the comments on some types more readable.
compiler/llds_out.m:
If the first arg of the lval field/3 is no, emit a (const_)mask_field
macro; otherwise, emit a (const_)field macro.
compiler/basic_block.m:
New module to convert sequences of instructions to sequences of
basic blocks and vice versa. Used in the new dupelim.m.
compiler/dupelim.m:
Complete rewrite to give duplicate code elimination more teeth.
Whereas previously we eliminated blocks of code only if they exactly
duplicated other blocks of code, we now look for blocks that can be
"anti-unified". For example, the blocks
r1 = field(mktag(0), r2, 0)
goto L1
and
r1 = field(mktag(1), r2, 0)
<fall through to L1>
anti-unify, with the most specific common generalization being
r1 = mask_field(r2, 0)
goto L1
If several basic blocks antiunify, we replace one copy with the
antiunified block and try to eliminate the others. We do not
eliminate blocks that can be fallen into, since eliminating them
would require introducing a goto, which would slow the code down.
compiler/peephole,m:
If a conditional branch to a label is followed by that label or
by an unconditional branch to that label, eliminate the branch.
Dupelim produces this kind of code.
compiler/{code_exprn,exprn_aux,lookup_switch,opt_debug,unify_gen}.m:
Minor changes required by the change to field/3.
compiler/{frameopt,jumpopt,labelopt,mercury_compile,optimize,value_number}.m:
s/__main/_main/ in predicate names.
compiler/jumpopt.m:
Add some documentation.
compiler/unify_gen.m:
Fix a module qualified predicate name reference that would not
work in Prolog.
compiler/notes/compiler_design.html:
Document the new file basic_block.m.
Estimated hours taken: 2
value_number:
Add two safety checks whose absence was bug. One of these replaces
an earlier, inadequate safety check in vn_block.
vn_block:
Remove that inadequate safety check, since now a more comprehensive
one is applied in value_number.
opt_util:
Opt_util__instr_labels now returns even those labels inside
code_addrs. This was needed for value_number.
labelopt:
Simplify the code based on the new capability of
opt_util__instr_labels.
dense_switch:
Break a too long line.
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: 20
vn_block:
Fix a typo which reflected a fundamental design error. When finding
cheaper copies of live lvals, for use in creating specialized copies
(parallels) of blocks jumped to from the current location, we used
to use the map reflecting the contents of lvals at the start of the
block, not at the point of the jump.
--pred-value-number, which uses the information computed by the
buggy predicate, actually bootstrapped some time ago despite
this fundamental bug!
value_number:
Fix a bug in the creation of parallel code sequences for computed
gotos. Add some more opprtunities for printing diagnostics.
Move code concerning final verification to vn_verify.
vn_verify:
Move the remaining code concerned with final verification from
value_number to vn_verify.
peephole:
Add a new pattern, which transforms the sequence
incr_sp N; goto L2; L1; incr_sp N; L2
into just
L1; incr_sp N; L2
The pattern is of course more broadly applicable, but I have seen
it only when it involves a single incr_sp between the two labels.
(The longer pattern can be introduced by frameopt.)
opt_util:
Look inside blocks when checking whether an instruction can fall
through. This improves the performance of labelopt.
vn_table:
Make the type vn_table abstract; add, export and use access functions.
vn_util:
Remove a noop predicate, since now it won't ever be made to do
anything.
vn_cost:
Refine debugging output.
vn_debug:
Add some more debugging routines.
opt_debug:
Add some more debugging routines.
det_analysis:
Remove an unused argument.
labelopt:
Formatting change.
Estimated hours taken: 6
arg_info:
Add support for the compact argument passing convention. The proper
handling of higher order calls etc is still missing.
globals:
Added a third global type, args_method, current either "old" or
"compact".
passes_aux:
Moved some auxiliary predicates from mercury_compile and options
to passes_aux.
constraint, det_analysis, make_hlds, modules, optimize, undef_types:
Import and refer to passes_aux.
mercury_compile, handle_options:
Remove the predicates moved to passes_aux. Also move the option
postprocessing code to a new module, handle_options.
Another change is that we stop after syntax errors if the new option
--halt-at-syntax-errors is set.
handle_option:
New module for option postprocessing.
options:
Remove the option lookup predicates, which were obsolete.
Add new options --args, --halt-at-syntax-errors and --opt-level.
Add a special handler for --opt-level.
lookup_switch:
Call getopt to look up options, not options.
value_number, vn_block:
Extended basic blocks with more than one incr_hp pose a problem for
value numbering when using boehm_gc, because value numbering coalesces
all the allocations into one. Previously we did not optimize such
sequences. I modified value numbering to divide up such blocks into
smaller blocks, each with at most one incr_hp, and optimize these.
At the moment, some of these blocks contain deeply nested field
refs, which value numbering is very slow to handle; code_exprn
should be modified to fix these.
value_number:
Rename usemap to useset, since this is more accurate.
Fixed a bug in --pred-value-number, which manifested itself as
the generation of duplicate labels.
labelopt:
Rename usemap to useset, since this is more accurate.
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.
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.
frameopt:
Make the teardown map bidirectional, and export it.
peephole:
Add a new pattern to handle cases generated by fulljump optimization.
This pattern uses the teardownmap, but it is disabled for the moment.
optimize:
Pass the teardown map where it is needed, and make sure we do a
peephole pass immediately after frameopt to use the teardownmap
while it is still valid.
jumpopt:
Rename a variable.
labelopt:
A block being eliminated may have the last remaining reference
to the label starting another block. Therefore on the last invocation
of labelopt, we iterate to a fixpoint before returning.
opt_debug:
Add a predicate to help debug bidirectional teardown maps.
opt_util:
Liberalized some optimizations, but the changes are disabled for the
moment.
value_number:
Pass an empty teardown map to peephole. Loosen the sanity check on
tags a bit.
vn_order:
If the new value of a location depends on its old value,
avoid creating a circularity in the preferred order relation.
Such circularity may be broken arbitrarily, even though we have
a clear preference.
vn_flush:
Modify the criteria for saving the old value stored in a location
about to be overwritten, in an effort to eliminate useless copies
of old values.
vn_util:
Tighten the requirement for classifying a use as a "real" use,
also in the effort to eliminate useless saves of old values.
Recognize some more expression patterns as yieldsing known
results. Move some functionality from vn_flush to vn_util,
since it is needed by the other modification.
-------------------------------------------------------
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.
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!!!)
value_number, vn_util, opt_util, opt_debug:
Fixed a bug with allowed incr_hp to overwrite its target without saving
it. Reorganized the handling of incr_sp and decr_sp to make sure they
never get reordered with respect to control flow instructions.
llds:
Fixed the output of temp declarations for blocks.
frameopt:
Generalized the set up patterns accepted as starting a det procedure.
labelopt:
Added a source-level option to remove eliminated instructions instead
of turning them into comments, and made it the default.
optimize:
After value numbering, perform jump optimization as well as peepholing
and label optimization.
now in dense_switch, string_switch and tag_switch, with the original
if-then-else implementation and the code that decides on optimizations
still in switch_gen.
Added options to replace the magic numbers governing the choice of switch
method.
Added comments to frameopt, jumpopt, labelopt and peephole.
- optimize.nl is the main loop of the optimizer. It calls functions in
jumpopt, peephole, labelopt, frameopt and value_number.
- jumpopt.nl does short-circuiting of jumps to jumps and finds tailcalls.
- peephole.nl now just does the local pattern-match optimizations.
- labelopt.nl eliminates dead labels and dead code.
Renamed the options related to optimization.
*** IMPORTANT: the --optimize flag now enables optimize.nl, not C optimization.
C optimization is signalled via the -c-optimize flag. Both flags are on by
default.