Estimated hours taken: 24
Treat higher-order predicate calls as a new sort of goal,
rather than as calls to the special predicate call/N, in order to
remove the fixed limit on the number of arguments and on the modes
for call/N.
Also, remove the restriction on output arguments preceding input arguments
in lambda expressions.
hlds_goal.m:
Add new functor higher_order_call/6 to the hlds__goal type.
*.m:
Handle new functor higher_order_call/6.
arg_info.m:
Abstract things a bit more: the argument passing convention
for a procedure may be affected by that procedure's types,
modes, and code_model, as well as the arg_method.
follow_vars.m:
Pass down the args_method, since it is now needed for figuring
out the arg_info for unifications and higher-order calls.
follow_code.m:
Treat complicated unifications in the same way as calls.
lambda.m:
When creating lambda predicates, permute the arguments so
that all input arguments come before all output arguments.
call_gen.m:
When generating higher-order predicate calls, don't abort
if outputs precede inputs; instead, generate code assuming
that the called predicate's args have been permuted so that
the inputs to come before all the outputs.
Estimated hours taken: 8
options.m:
Rename branch_delay_slot to have_delay_slot.
Set optimize_delay_slot in -O2 only if have_delay_slot was set earlier.
This is possible now because the default optimization level is now
set in mc.
mercury_compile:
Change verbose output a bit to be more consistent.
dead_proc_elim:
Export the predicates that will eventually be needed by inlining.m.
inlining.m:
Use the information about the number of times each procedure is called
to inline local nonrecursive procedures that are called exactly once.
EXCEPT that this is turned off at the moment, since the inlining of
parse_dcg_goal_2 in prog_io, which this change enables, causes the
compiler to emit incorrect code.
prog_io:
Moved the data type definitions to prog_data. (Even though prog_io.m
is ten times the size of prog_data.m, the sizes of the .c files are
not too dissimilar.)
Estimated hours taken: 3
options:
Add a new option, --branch-delay-slot, intended for use by mc on
the basis of the configuattion script. It says whether the machine
architecture has delays slots on branches.
The setting of option should affect whether we set
--optimize-delay-slots at -O2, but this doesn't work yet.
hlds_goal:
Add an extra field to hold follow_vars infromation to disjunctions,
switches and if-then-elses. I intend to use this information to
generate better code.
*.m:
Changes to accommodate the extra field.
Estimated hours taken: 2
compiler/lambda.m:
Re-enable the optimization of not introducing separate
predicates for lambda expressions when not necessary,
after fixing it so that it doesn't attempt to curry output
arguments in cases such as
lambda([Y::out] is det, q(_, Y))
where q/2 is declared as
:- pred q(int::out, int::out) is det.
Estimated hours taken: 10
hlds, hlds_module, hlds_pred, hlds_goal, hlds_data:
Divided the old hlds.m into four files:
hlds_module.m defines the data structures that deal with issues
that are wider than a single predicate. These data structures are
the module_info structure, dependency_info, the predicate table
and the shape table.
hlds_pred.m defined pred_info and proc_info, pred_id and proc_id.
hlds_goal.m defines hlds__goal, hlds__goal_{expr,info}, and the
other parts of goal structures.
hlsd_data.m defines the HLDS types that deal with issues related
to data and its representation: function symbols, types, insts, modes.
It also defines the types related to determinism.
hlds.m is now an empty module. I have not removed it from CVS
because we may need the name hlds.m again, and CVS does not like
the reuse of a name once removed.
other modules:
Import the necessary part of hlds.
det_analysis:
Define a type that was up to now improperly defined in hlds.m.
prog_io:
Move the definition of type determinism to hlds_data. This decision
may need to be revisited when prog_io is broken up.
dnf, lambda:
Simplify the task of defining predicates.
llds:
Fix some comments.
mercury_compile:
If the option -d all is given, dump all HLDS stages.
shape, unused_args:
Fix formatting.
Estimated hours taken: 12
Implement functional syntax. You can now use `:- func' in a similar manner
to `:- pred'. For example, `:- func foo(int, int) = int.' declares a function,
and `:- mode foo(in, in) = out.' defines a mode for it. You can write clauses
for functions, such as `foo(X, Y) = Z :- Z is 2*X + Y.' Any term in the
head or body of a clause can be a function call, e.g. `bar(X, Y, foo(X, Y))'.
Until we have implemented a proper Mercury debugger, this syntax
should not be used (except that I might reimplement the functions
provided by Prolog's is/2 predicate using this syntax, rather than
the current special-case hack in the parser).
prog_io.m:
Add syntax for declaring and defining functions.
Disallow the use of `=' to define modes, as in `:- mode foo = bar.'
(Instead, you should use `::'. `==' is also allowed.)
Also, use higher-order predicates to simplify some of the rather
repetitious parsing code.
mercury_to_mercury.m, mercury_to_goedel.m, make_hlds.m, modules.m:
Handle new functional syntax.
typecheck.m:
Add support for functions, function types such as `func(int) = int',
and currying. (But there's currently no equivalent to call/N for
functions, so function types and currying aren't very useful yet.)
undef_types.m:
Add support for function types.
modes.m:
Convert function calls into predicate calls.
(This must be done after typechecking is complete,
so I put it in mode analysis.)
hlds.m:
Add new field `pred_or_func' to the pred_info.
hlds_out.m:
Print out the `pred_or_func' field.
higher_order.m, unused_args.m, lambda.m, dnf.m:
Pass extra pred_or_func argument to pred_info_init to specify that
the thing being created is a predicate, not a function.
constraint.m, dependency_graph.m, hlds_out.m:
`mercury_output_mode_subdecl' has been renamed
`mercury_output_pred_mode_subdecl'.
prog_util.m:
Add new predicate split_type_and_mode/3.
llds.m:
Print out
/* code for predicate '*'/3 in mode 0 */
rather than
/* code for predicate */3 in mode 0 */
to avoid a syntax error in the generated C code.
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.
Estimated hours taken: 16
This check-in combines several changes.
* Change mercury_compile.pp so that it continues as far as possible
after errors.
* Split the parts of mercury_compile.pp which handle module
imports and exports into a new module called `modules.m'.
* Move the polymorphism.m pass after determinism analysis and unique mode
checking. This is because unique_modes.m may change the mode in which
a unification predicate is called; as a result, we need to do mode
checking, determinism analysis, and unique mode checking for new
modes of unification predicates which are requested only after
unique mode checking. That won't work if we have done polymorphism.m
in between mode checking and determinism analysis, since unification
predicates are created without type_info arguments, and polymorphism.m
cannot be run on just one predicate at a time. (NB. I haven't changed
unique_modes.m to actually do this yet.)
I also had to move lambda.m after polymorphism.m, since polymorphism.m
doesn't handle higher-order pred constants.
* Fix determinism analyis of simple_test unifications.
The compiler would think that a unification of an inst such as
`bound(foo)' with itself could fail. The problem is that there is no
`can_fail' field for simple_test unifications, so determinism.m just
assumes that they can all fail. I fixed this by changing modes.m to
optimize away simple_tests that cannot fail.
* Fix determinism analyis of complicated_unifications.
Again, determinism analysis just assumed that all complicated_unifications
were semidet, because unify_proc.m always declared the out-of-line
unification predicates to be semidet. The fix was to pass the determinism
inferred during mode analysis to unify_proc__request_unify.
However, the '='(in, in) mode still needs to be semidet - its address is
taken and put into the type_infos, and so it needs to have the
right interface. To handle det '='(in, in) unifications, the
determinism also needs to be passed to unify_proc__search_mode_num,
which will select the '='(in, in) mode only if the determinism is
semidet. (It would of course be better to optimize det '='(in, in)
unifications to `true', but they are unlikely to occur much in real
code anyway, so that is a low priority.)
* Compute the instmap deltas for all variables, not just the non-local
variables of a goal, because variables which are not present in a goal
can become nondet live if the goal is e.g. a nondet call.
mercury_compile.pp:
- Rearrange the order of the passes as described above.
- Add code to call check_undef_types and check_undef_modes
directly rather than via typecheck.m/modes.m.
Stop only if we get an undef error; if we get any other
sort of type/mode error, we can keep going.
- Move lots of code to modules.m.
modules.m:
New file, containing code moved from mercury_compile.pp.
polymorphism.m:
Make sure that the goals that we generate have the correct
determinism annotations. Handle switches.
Put back the call to lambda__transform_lambda.
lambda.m:
Put back the stuff that allowed lambda.m to be called from
polymorphism.m.
modes.m, unify_proc.m, call_gen.m, polymorphism.m,
Pass the determinism of the unification to unify_proc__request_unify,
so that it can declare the right determinism for the unification
predicate. (Previously it just assumed that all complicated
unifications were `semidet'.)
Also pass the determinism to unify_proc__search_mode_num, so that
it will generate a new unification pred for deterministic '='(in,in)
unifications rather than calling the existing semidet one.
modes.m, typecheck.m:
Remove the calls to check_undefined_types and check_undefined_modes.
They are now instead called directly from mercury_compile.pp.
modes.m:
Don't call lambda__transform_lambda.
Optimize away simple_tests that cannot fail.
modes.m, unique_modes.m:
Call mode_info_get_instmap/2 rather than mode_info_get_vars_instmap/3.
mode_info.m:
Delete the predicate mode_info_get_vars_instmap/3.
Estimated hours taken: 6
Rearrange the ordering of the different phases in the compiler.
Moved lambda elimination (lambda.m) after unique_modes.m,
because mode analysis must have been fully completed before lambda
elimination, so that we get the right mode on the introduced
predicates. Also moved inlining.m and common.m after unique modes,
since they are optimization passes, not semantic checking passes.
The cse_detection.m, switch_detection.m, and determinism.m passes now
need to recursively traverse lambda goals. (Previously they assumed
that lambda goals had already been eliminated.)
mercury_compile.pp:
Move the inlining.m and common.m passes from semantic_phases
to middle_phases.
polymorphism.m:
Remove the code which called lambda.m.
switch_detection.m:
Recursively traverse lambda goals.
cse_detection.m:
Recursively traverse lambda goals.
Also, when redoing mode analysis and switch detection,
we shouldn't reinvoke lambda.m.
det_analysis.m, det_report.m:
Recursively traverse lambda goals, check for determinism
errors in them, and report them.
Also, print the calling predicate name & mode in the error
message for calls to predicates with cc_* determinism in
all-solutions contexts.
modes.m:
Add an extra argument to modecheck_unification that specifies
how we should recursively process lambda goals, so that we
can do the right thing when called from unique_modes.m.
The right thing in this case is to call unique_modes__check_goal
instead of modecheck_goal, and to then invoke lambda__transform_lambda
on the result.
unique_modes.m:
Make sure we don't clobber the predicate table, since we now
indirectly call lambda__transform_lambda, which inserts new
predicates into the table.
Also, simplify the code a little and add a sanity check.
lambda.m:
Make some changes that were needed because lambda.m now comes
directly after (unique_)modes.m not after polymorphism.m.
Estimated hours taken: 0.2
Add the module name to name of LambdaGoal predicates.
compiler/lambda.m:
Prepend the module name to __LambdaGoal__, as name clashes
occur with native gc (because static symbols become global).
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
Estimated hours taken: 3
Added better warnings and error messages. Fixed bug with having
pragma(c_code, ...) decs for different modes of the same pred, and with having
clauses and pragma(c_code, ...) decs.
hlds.m:
Added a fields to the pred_info indicating whether the pred contained
pragma(c_code, ...) decs, clauses, or was currently empty. Also
updated the access predicates, and require a new argument for
pred_info_init
lambda.m:
Pass the new argument to pred_info_init
make_hlds.m:
Improve error messages and warnings. Fix bug with pragma decs for
different modes, and bug with clauses an pragmas for same pred.
Estimated hours taken: 15
(Debugging 3 people * 3 hours, design 2 hours, coding 4 hours.)
Fix design error which led to the bug reported by Philip Dart:
cse_detection was reinvoking mode analysis, which converted
higher-order pred terms into lambda expressions, but was
not reinvoking polymorphism.m, and so they remained as
lambda expressions, which caused the code generator to generate
incorrect code.
compiler/polymorphism.m:
Move the stuff for handling lambda expressions into
a new file lambda.m.
compiler/lambda.m:
New file. Contains the lambda expression handling
stuff from polymorphism.m, plus new code to traverse
the HLDS for a predicate applying this transformation
to each lambda expression in the procedure bodies
for that predicate.
compiler/cse_detection.m:
After re-running mode analysis, invoke lambda__process_pred
to transform away lambda expressions.