[m-rev.] diff: four-space hlds_goal
Zoltan Somogyi
zs at cs.mu.OZ.AU
Tue Aug 16 20:42:07 AEST 2005
compiler/hlds_goal.m:
Convert this modules to four-space indentation to reduce the number
of bad line breaks. Fix some departures from our coding standards.
Change the can_cgc type from a synonym of bool to a discriminated union
type isomorphic to bool. Make goal_is_atomic more robust. Delete
duplicate comments.
compiler/*.m:
Conform to the change to can_cgc.
Zoltan.
cvs diff: Diffing .
Index: goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.109
diff -u -b -r1.109 goal_util.m
--- goal_util.m 12 Aug 2005 05:14:10 -0000 1.109
+++ goal_util.m 16 Aug 2005 08:28:02 -0000
@@ -1229,7 +1229,7 @@
UniMode = (Inst0 -> Inst0) - (Inst0 -> Inst0),
UnifyContext = unify_context(explicit, []),
Unification = deconstruct(Var, ConsId, ArgVars, UniModes,
- can_fail, no),
+ can_fail, cannot_cgc),
ExtraGoal = unify(Var, functor(ConsId, no, ArgVars),
UniMode, Unification, UnifyContext),
set__singleton_set(NonLocals, Var),
Index: higher_order.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.130
diff -u -b -r1.130 higher_order.m
--- higher_order.m 12 Aug 2005 05:14:10 -0000 1.130
+++ higher_order.m 16 Aug 2005 08:28:37 -0000
@@ -2270,7 +2270,7 @@
Goal = unify(Arg, functor(ConsId, no, [UnwrappedArg]),
in_mode - out_mode,
deconstruct(Arg, ConsId, [UnwrappedArg], UniModes,
- cannot_fail, no),
+ cannot_fail, cannot_cgc),
unify_context(explicit, [])) - GoalInfo.
%-------------------------------------------------------------------------------
Index: hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.133
diff -u -b -r1.133 hlds_goal.m
--- hlds_goal.m 12 Aug 2005 05:14:10 -0000 1.133
+++ hlds_goal.m 16 Aug 2005 08:36:14 -0000
@@ -1,4 +1,6 @@
%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
% Copyright (C) 1996-2005 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
@@ -39,140 +41,150 @@
:- type hlds_goal_expr
- % A conjunction.
- % NOTE: conjunctions must be fully flattened before
- % mode analysis. As a general rule, it is a good idea
- % to keep them flattened.
- %
---> conj(hlds_goals)
+ % A conjunction. NOTE: conjunctions must be fully flattened before
+ % mode analysis. As a general rule, it is a good idea to keep them
+ % flattened.
- % A predicate call.
- % Initially only the sym_name, arguments, and context
- % are filled in. Type analysis fills in the
- % pred_id. Mode analysis fills in the
- % proc_id and the builtin_state field.
- %
; call(
+ % A predicate call. Initially only the sym_name, arguments,
+ % and context are filled in. Type analysis fills in the
+ % pred_id. Mode analysis fills in the proc_id and
+ % builtin_state fields.
+
call_pred_id :: pred_id,
- % which predicate are we calling?
+ % Which predicate are we calling?
+
call_proc_id :: proc_id,
- % which mode of the predicate?
+ % Which mode of the predicate?
+
call_args :: list(prog_var),
- % the list of argument variables
+ % The list of argument variables.
+
call_builtin :: builtin_state,
- % is the predicate builtin, and if yes,
+ % Is the predicate builtin, and if yes,
% do we generate inline code for it?
+
call_unify_context :: maybe(call_unify_context),
- % was this predicate call originally
+ % Was this predicate call originally
% a unification? If so, we store the
% context of the unification.
+
call_sym_name :: sym_name
- % the name of the predicate
+ % The name of the predicate.
)
+ ; generic_call(
% A generic call implements operations which are too
% polymorphic to be written as ordinary predicates in Mercury
- % and require special casing, either because their arity
- % is variable, or they take higher-order arguments of
- % variable arity.
- % This currently includes higher-order calls, class-method
- % calls, Aditi calls and the Aditi update goals.
+ % and require special casing, either because their arity is
+ % variable, or they take higher-order arguments of variable
+ % arity. This currently includes higher-order calls,
+ % class-method calls, Aditi calls and the Aditi update goals.
%
- ; generic_call(
gcall_details :: generic_call,
+
gcall_args :: list(prog_var),
- % the list of argument variables
+ % The list of argument variables.
+
gcall_modes :: list(mode),
% The modes of the argument variables.
% For higher_order calls, this field
% is junk until after mode analysis.
% For aditi_builtins, this field
% is junk until after purity checking.
+
gcall_detism :: determinism
- % the determinism of the call
+ % The determinism of the call.
)
- % Deterministic disjunctions are converted
- % into switches by the switch detection pass.
- %
; switch(
+ % Deterministic disjunctions are converted into switches
+ % by the switch detection pass.
+
switch_var :: prog_var,
- % the variable we are switching on
+ % The variable we are switching on.
+
switch_canfail :: can_fail,
- % whether or not the switch test itself
+ % Whether or not the switch test itself
% can fail (i.e. whether or not it
- % covers all the possible cases)
+ % covers all the possible cases).
+
switch_cases :: list(case)
)
- % A unification.
- % Initially only the terms and the context
- % are known. Mode analysis fills in the missing information.
- %
; unify(
+ % A unification. Initially only the terms and the context
+ % are known. Mode analysis fills in the missing information.
+
unify_lhs :: prog_var,
- % the variable on the left hand side
- % of the unification.
- % NOTE: for convenience this field
- % is duplicated in the unification
- % structure below.
+ % The variable on the left hand side
+ % of the unification. NOTE: for
+ % convenience this field is duplicated
+ % in the unification structure below.
+
unify_rhs :: unify_rhs,
- % whatever is on the right hand side
- % of the unification
+ % Whatever is on the right hand side
+ % of the unification.
+
unify_mode :: unify_mode,
- % the mode of the unification
+ % the mode of the unification.
+
unify_kind :: unification,
- % this field says what category of
+ % This field says what category of
% unification it is, and contains
- % information specific to each category
+ % information specific to each category.
+
unify_context :: unify_context
- % the location of the unification
+ % The location of the unification
% in the original source code
- % (for use in error messages)
+ % (for use in error messages).
)
+ ; disj(hlds_goals)
% A disjunction.
% NOTE: disjunctions should be fully flattened.
- %
- ; disj(hlds_goals)
- % A negation.
- %
; not(hlds_goal)
+ % A negation.
+ ; scope(
% A scope which may be the scope of a quantification,
% or may be introduced by a compiler transformation.
% See the documentation of scope_reason for what the
% compiler may do with the scope.
- %
- ; scope(
+
scope_reason :: scope_reason,
some_goal :: hlds_goal
)
+ ; if_then_else(
% An if-then-else,
% `if some <Vars> <Condition> then <Then> else <Else>'.
% The scope of the locally existentially quantified variables
% <Vars> is over the <Condition> and the <Then> part,
% but not the <Else> part.
- %
- ; if_then_else(
+
ite_exist_vars :: list(prog_var),
% The locally existentially quantified
% variables <Vars>.
+
ite_cond :: hlds_goal, % The <Condition>
ite_then :: hlds_goal, % The <Then> part
ite_else :: hlds_goal % The <Else> part
)
- % Foreign code from a pragma foreign_proc(...) decl.
- %
; foreign_proc(
+ % Foreign code from a pragma foreign_proc(...) decl.
+
foreign_attr :: pragma_foreign_proc_attributes,
+
foreign_pred_id :: pred_id,
- % The called predicate
+ % The called predicate.
+
foreign_proc_id :: proc_id,
- % The mode of the predicate
+ % The mode of the predicate.
+
foreign_args :: list(foreign_arg),
foreign_extra_args :: list(foreign_arg),
% Extra arguments added when compiler
@@ -180,22 +192,20 @@
% code into a foreign proc than the
% declared interface of the called
% Mercury procedure would allow.
+
foreign_impl :: pragma_foreign_code_impl
% Extra information for model_non
% pragma_foreign_codes; none for others.
)
- % Parallel conjunction.
- %
; par_conj(hlds_goals)
+ % Parallel conjunction.
- % shorthand goals
- %
+ ; shorthand(shorthand_goal_expr).
+ % Goals that stand for some other, usually bigger goal.
% All shorthand goals are eliminated during or shortly after
- % the construction of the hlds, so most passes of the compiler
+ % the construction of the HLDS, so most passes of the compiler
% will just call error/1 if they occur.
- %
- ; shorthand(shorthand_goal_expr).
% Instances of these `shorthand' goals are implemented by a
% hlds --> hlds transformation that replaces them with
@@ -214,12 +224,12 @@
---> bi_implication(hlds_goal, hlds_goal).
:- type scope_reason
+ ---> exist_quant(list(prog_var))
% The goal inside the scope construct has the listed variables
% existentially quantified. The compiler may do whatever
% preserves this fact.
- %
- ---> exist_quant(list(prog_var))
+ ; promise_equivalent_solutions(list(prog_var))
% Even though the code inside the scope may have multiple
% solutions, the creator of the scope (which may be the user
% or a compiler pass) promises that all these solutions are
@@ -237,9 +247,8 @@
% The promise is valid only if the list of outputs of the goal
% inside the scope is a subset of the variables listed here.
% If it is not valid, the compiler must emit an error message.
- %
- ; promise_equivalent_solutions(list(prog_var))
+ ; promise_purity(implicit_purity_promise, purity)
% The goal inside the scope implements an interface of the
% specified purity, even if its implementation uses less pure
% components.
@@ -249,9 +258,8 @@
% just whole procedure bodies. The implicit_purity_promise
% says whether or not the compiler requires explicit purity
% annotations on the goals inside the scope.
- %
- ; promise_purity(implicit_purity_promise, purity)
+ ; commit(force_pruning)
% This scope exists to delimit a piece of code
% with at_most_many components but with no outputs,
% whose overall determinism is thus at_most_one,
@@ -261,9 +269,8 @@
%
% If the argument is force_pruning, then the outer goal will
% succeed at most once even if the inner goal is impure.
- %
- ; commit(force_pruning)
+ ; barrier(removable)
% The scope exists to prevent other compiler passes from
% arbitrarily moving computations in or out of the scope.
% This kind of scope can only be introduced by program
@@ -282,9 +289,8 @@
%
% A barrier says nothing about the determinism of either
% the inner or the outer goal, or about pruning.
- %
- ; barrier(removable)
+ ; from_ground_term(prog_var).
% The goal inside the scope, which should be a conjunction,
% results from the conversion of one ground term to
% superhomogeneous form. The variable specifies what the
@@ -292,8 +298,6 @@
%
% This kind of scope is not intended to be meaningful after
% mode analysis, and should be removed after mode analysis.
- %
- ; from_ground_term(prog_var).
:- type removable
---> removable
@@ -308,12 +312,11 @@
% Information for calls
%
- % There may be two sorts of "builtin" predicates - those that we
- % open-code using inline instructions (e.g. arithmetic predicates),
- % and those which are still "internal", but for which we generate
- % a call to an out-of-line procedure. At the moment there are no
- % builtins of the second sort, although we used to handle call/N
- % that way.
+ % There may be two sorts of "builtin" predicates - those that we open-code
+ % using inline instructions (e.g. arithmetic predicates), and those which
+ % are still "internal", but for which we generate a call to an out-of-line
+ % procedure. At the moment there are no builtins of the second sort,
+ % although we used to handle call/N that way.
:- type builtin_state
---> inline_builtin
@@ -378,10 +381,9 @@
simple_call_id % name of the called method
)
- % cast(Input, Output).
- % Assigns `Input' to `Output', performing a type
- % and/or inst cast.
; cast(cast_type)
+ % cast(Input, Output): Assigns `Input' to `Output', performing
+ % a type and/or inst cast.
; aditi_builtin(
aditi_builtin,
@@ -417,7 +419,7 @@
:- pred hlds_goal__generic_call_id(generic_call::in, call_id::out) is det.
% Determine whether a generic_call is calling
- % a predicate or a function
+ % a predicate or a function.
%
:- func generic_call_pred_or_func(generic_call) = pred_or_func.
@@ -436,28 +438,26 @@
; functor(
rhs_functor :: cons_id,
rhs_is_exist_constr :: is_existential_construction,
- % The `is_existential_construction'
- % field is only used after
- % polymorphism.m strips off
- % the `new ' prefix from
- % existentially typed constructions.
+ % The `is_existential_construction' field
+ % is only used after polymorphism.m strips
+ % off the `new ' prefix from existentially
+ % typed constructions.
rhs_args :: list(prog_var)
)
; lambda_goal(
rhs_purity :: purity,
rhs_p_or_f :: pred_or_func,
rhs_eval_method :: lambda_eval_method,
- % should be `normal' except for
+ % Should be `normal' except for
% closures executed by Aditi.
rhs_aditi :: fix_aditi_state_modes,
rhs_nonlocals :: list(prog_var),
- % non-locals of the goal excluding
- % the lambda quantified variables
+ % Non-locals of the goal excluding
+ % the lambda quantified variables.
rhs_lambda_quant_vars :: list(prog_var),
- % lambda quantified variables
+ % Lambda quantified variables.
rhs_lambda_modes :: list(mode),
- % modes of the lambda
- % quantified variables
+ % Modes of the lambda quantified variables.
rhs_detism :: determinism,
rhs_lambda_goal :: hlds_goal
).
@@ -467,25 +467,29 @@
:- type is_existential_construction == bool.
:- type unification
+
+ ---> construct(
% A construction unification is a unification with a functor
% or lambda expression which binds the LHS variable,
% e.g. Y = f(X) where the top node of Y is output,
% Constructions are written using `:=', e.g. Y := f(X).
- ---> construct(
construct_cell_var :: prog_var,
- % the variable being constructed
- % e.g. Y in above example
+ % The variable being constructed,
+ % e.g. Y in above example.
+
construct_cons_id :: cons_id,
- % the cons_id of the functor
- % f/1 in the above example
+ % The cons_id of the functor
+ % f/1 in the above example.
+
construct_args :: list(prog_var),
- % the list of argument variables
+ % The list of argument variables
% [X] in the above example
% For a unification with a lambda
% expression, this is the list of
% the non-local variables of the
% lambda expression.
+
construct_arg_modes :: list(uni_mode),
% The list of modes of the arguments
% sub-unifications.
@@ -493,6 +497,7 @@
% expression, this is the list of
% modes of the non-local variables
% of the lambda expression.
+
construct_how :: how_to_construct,
% Specify whether to allocate
% statically, to allocate dynamically,
@@ -501,9 +506,11 @@
% Constructions for which this
% field is `reuse_cell(_)' are
% described as "reconstructions".
+
construct_is_unique :: cell_is_unique,
% Can the cell be allocated
% in shared data.
+
term_size_slot :: maybe(term_size_value)
% The value `yes' tells the code
% generator to reserve an extra slot,
@@ -522,83 +529,81 @@
% has been run.
)
+ ; deconstruct(
% A deconstruction unification is a unification with a functor
% for which the LHS variable was already bound,
% e.g. Y = f(X) where the top node of Y is input.
% Deconstructions are written using `==', e.g. Y == f(X).
% Note that deconstruction of lambda expressions is
% a mode error.
- %
- ; deconstruct(
+
deconstruct_cell_var :: prog_var,
% The variable being deconstructed
% e.g. Y in the above example.
+
deconstruct_cons_id :: cons_id,
% The cons_id of the functor,
% e.g. f/1 in the above example
+
deconstruct_args :: list(prog_var),
% The list of argument variables,
% e.g. [X] in the above example.
+
deconstruct_arg_modes :: list(uni_mode),
% The lists of modes of the argument
% sub-unifications.
+
deconstruct_can_fail :: can_fail,
% Whether or not the unification
% could possibly fail.
+
deconstruct_can_cgc :: can_cgc
% Can compile time GC this cell,
- % ie explicitly deallocate it
+ % i.e. explicitly deallocate it
% after the deconstruction.
)
- % Y = X where the top node of Y is output,
- % written Y := X.
- %
; assign(
+ % Y = X where the top node of Y is output, written Y := X.
+
assign_to_var :: prog_var,
assign_from_var :: prog_var
)
- % Y = X where the type of X and Y is an atomic
- % type and they are both input, written Y == X.
- %
; simple_test(
+ % Y = X where the type of X and Y is an atomic type and
+ % they are both input, written Y == X.
+ %
test_var1 :: prog_var,
test_var2 :: prog_var
)
- % Y = X where the type of Y and X is not an
- % atomic type, and where the top-level node
- % of both Y and X is input. May involve
- % bi-directional data flow. Implemented
- % using out-of-line call to a compiler
- % generated unification predicate for that
- % type & mode.
- %
; complicated_unify(
+ % Y = X where the type of Y and X is not an atomic type,
+ % and where the top-level node of both Y and X is input.
+ % May involve bi-directional data flow. Implemented using
+ % out-of-line call to a compiler generated unification
+ % predicate for that type & mode.
+
compl_unify_mode :: uni_mode,
% The mode of the unification.
+
compl_unify_can_fail :: can_fail,
- % Whether or not it could possibly fail
+ % Whether or not it could possibly
+ % fail.
+
+ % When unifying polymorphic types such as map/2, we need to
+ % pass type_info variables to the unification procedure for
+ % map/2 so that it knows how to unify the polymorphically
+ % typed components of the data structure. Likewise for
+ % comparison predicates. This field records which type_info
+ % variables we will need. This field is set by polymorphism.m.
+ % It is used by quantification.m when recomputing the
+ % nonlocals. It is also used by modecheck_unify.m, which
+ % checks that the type_info variables needed are all ground.
+ % It is also checked by simplify.m when it converts
+ % complicated unifications into procedure calls.
- % When unifying polymorphic types such as
- % map/2, we need to pass type_info variables
- % to the unification procedure for map/2
- % so that it knows how to unify the
- % polymorphically typed components of the
- % data structure. Likewise for comparison
- % predicates.
- % This field records which type_info variables
- % we will need.
- % This field is set by polymorphism.m.
- % It is used by quantification.m
- % when recomputing the nonlocals.
- % It is also used by modecheck_unify.m,
- % which checks that the type_info
- % variables needed are all ground.
- % It is also checked by simplify.m when
- % it converts complicated unifications
- % into procedure calls.
compl_unify_typeinfos :: list(prog_var)
% The type_info variables needed
% by this unification, if it ends up
@@ -614,12 +619,14 @@
% the cell being created.
).
- % `yes' iff the cell is available for compile time garbage collection.
- % Compile time garbage collection is when the compiler
- % recognises that a memory cell is no longer needed and can be
- % safely deallocated (ie by inserting an explicit call to free).
- %
-:- type can_cgc == bool.
+ % `can_cgc' iff the cell is available for compile time garbage collection.
+ % Compile time garbage collection is when the compiler recognises that
+ % a memory cell is no longer needed and can be safely deallocated
+ % (by inserting an explicit call to free).
+ %
+:- type can_cgc
+ ---> can_cgc
+ ; cannot_cgc.
% A unify_context describes the location in the original source
% code of a unification, for use in error messages.
@@ -634,85 +641,84 @@
% unification within a clause
%
:- type unify_main_context
- % an explicit call to =/2
---> explicit
+ % An explicit call to =/2.
- % a unification in an argument of a clause head
; head(
- int % the argument number
- % (first argument == no. 1)
+ % A unification in an argument of a clause head.
+
+ int % The argument number (first argument == no. 1)
)
- % a unification in the function result term of a clause head
; head_result
+ % A unification in the function result term of a clause head.
- % a unification in an argument of a predicate call
; call(
- call_id, % the name and arity of the predicate
- int % the argument number (first arg == 1)
+ % A unification in an argument of a predicate call.
+
+ call_id, % The name and arity of the predicate.
+ int % The argument number (first arg == 1).
)
- % a unification added by some syntactic transformation
- % (e.g. for handling state variables.)
; implicit(
- string % used to explain the source of the
- % unification
+ % A unification added by some syntactic transformation
+ % (e.g. for handling state variables).
+
+ string % Used to explain the source of the unification.
).
% A unify_sub_context describes the location of sub-unification
- % (which is unifying one argument of a term)
- % within a particular unification.
+ % (which is unifying one argument of a term) within a particular
+ % unification.
%
:- type unify_sub_context
== pair(
- cons_id, % the functor
- int % the argument number (first arg == 1)
+ cons_id, % The functor.
+ int % The argument number (first arg == 1).
).
:- type unify_sub_contexts == list(unify_sub_context).
- % A call_unify_context is used for unifications that get
- % turned into calls to out-of-line unification predicates,
- % and functions. It records which part of the original source
- % code the unification (which may be a function application)
- % occurred in.
+ % A call_unify_context is used for unifications that get turned into
+ % calls to out-of-line unification predicates, and functions. It records
+ % which part of the original source code the unification (which may be
+ % a function application) occurred in.
%
:- type call_unify_context
---> call_unify_context(
- prog_var, % the LHS of the unification
- unify_rhs, % the RHS of the unification
- unify_context % the context of the unification
+ prog_var, % The LHS of the unification.
+ unify_rhs, % The RHS of the unification.
+ unify_context % The context of the unification.
).
- % Information on how to construct the cell for a
- % construction unification. The `construct_statically'
- % alternative is set by the `mark_static_terms.m' pass,
- % and is currently only used for the MLDS back-end
- % (for the LLDS back-end, the same optimization is
- % handled by var_locn.m).
- % The `reuse_cell' alternative is not yet used.
+ % Information on how to construct the cell for a construction unification.
+ % The `construct_statically' alternative is set by the mark_static_terms.m
+ % pass, and is currently only used for the MLDS back-end (for the LLDS
+ % back-end, the same optimization is handled by var_locn.m). The
+ % `reuse_cell' alternative is not yet used.
%
:- type how_to_construct
- ---> construct_statically( % Use a statically initialized
- % constant
+ ---> construct_statically(
+ % Use a statically initialized constant.
+
args :: list(static_cons)
)
- ; construct_dynamically % Allocate a new term on the
- % heap
- ; reuse_cell(cell_to_reuse). % Reuse an existing heap cell
-
- % Information on how to construct an argument for
- % a static construction unification. Each such
- % argument must itself have been constructed
- % statically; we store here a subset of the fields
- % of the original `construct' unification for the arg.
- % This is used by the MLDS back-end.
+ ; construct_dynamically
+ % Allocate a new term on the heap
+
+ ; reuse_cell(cell_to_reuse).
+ % Reuse an existing heap cell.
+
+ % Information on how to construct an argument for a static construction
+ % unification. Each such argument must itself have been constructed
+ % statically; we store here a subset of the fields of the original
+ % `construct' unification for the arg. This is used by the MLDS back-end.
%
:- type static_cons
---> static_cons(
- cons_id, % the cons_id of the functor
- list(prog_var), % the list of arg variables
- list(static_cons) % how to construct the args
+ cons_id, % The cons_id of the functor.
+ list(prog_var), % The list of arg variables.
+ list(static_cons) % How to construct the args.
).
% Information used to perform structure reuse on a cell.
@@ -740,10 +746,9 @@
:- type unify_mode == pair(mode, mode).
:- type uni_mode ---> pair(inst) -> pair(inst).
- % Each uni_mode maps a pair
- % of insts to a pair of new insts
- % Each pair represents the insts
- % of the LHS and the RHS respectively
+ % Each uni_mode maps a pair of insts to a pair of new insts
+ % Each pair represents the insts of the LHS and the RHS
+ % respectively.
%-----------------------------------------------------------------------------%
%
@@ -895,11 +900,15 @@
---> constraint % This is included if the goal is
% a constraint. See constraint.m
% for the definition of this.
+
; from_head % This goal was originally in the head of the
% clause, and was put into the body by the
% superhomogeneous form transformation.
+
; (impure) % This goal is impure. See hlds_pred.m.
+
; (semipure) % This goal is semipure. See hlds_pred.m.
+
; not_impure_for_determinism
% This goal should not be treated as impure
% for the purpose of computing its determinism.
@@ -907,38 +916,46 @@
% transformations that insert impure code into
% existing goals, and wish to keep the old
% determinism of those goals.
+
; stack_opt % This goal was created by stack slot
% optimization. Other optimizations should
% assume that it is there for a reason, and
% therefore should refrain from "optimizing"
% it away, even though it is a copy of another,
% previous goal.
- ; tuple_opt % This goal was create by the tupling
- % optimization. The comment for the stack slot
- % optimization above applies here.
- ; call_table_gen % This goal generates the variable that
- % represents the call table tip. If debugging
- % is enabled, the code generator needs to save
- % the value of this variable in its stack slot
- % as soon as it is generated; this marker
- % tells the code generator when this happens.
+
+ ; tuple_opt % This goal was create by the tupling optimization.
+ % The comment for the stack slot optimization above
+ % applies here.
+
+ ; call_table_gen % This goal generates the variable that represents
+ % the call table tip. If debugging is enabled, the
+ % code generator needs to save the value of this
+ % variable in its stack slot as soon as it is
+ % generated; this marker tells the code generator
+ % when this happens.
+
; preserve_backtrack_into
% Determinism analysis should preserve
% backtracking into goals marked with this
% feature, even if their determinism puts an
% at_most_zero upper bound on the number of
% solutions they have.
+
; save_deep_excp_vars
% This goal generates the deep profiling
% variables that the exception handler needs
% to execute the exception port code.
+
; hide_debug_event
% The events associated with this goal should
% be hidden. This is used e.g. by the tabling
% transformation to preserve the set of events
% generated by a tabled procedure.
+
; tailcall % This goal represents a tail call. This marker
% is used by deep profiling.
+
; keep_constant_binding
% This feature should only be attached to
% unsafe_cast goals that cast a value of an
@@ -947,6 +964,7 @@
% is known to be bound to a given constant,
% then the second variable should be set
% to the corresponding local tag value.
+
; dont_warn_singleton
% Don't warn about singletons in this goal.
% Intended to be used by the state variable
@@ -980,15 +998,15 @@
% of quantification as well, we simply make it
% mark the unifications it creates, and get
% the singleton warning code to respect it.
+
; mode_check_clauses_goal.
- % This goal is the main disjunction of a
- % predicate with the mode_check_clauses pragma.
- % No compiler pass should try to invoke
- % quadratic or worse algorithms on the arms
- % of this goal, since it probably has many
- % arms (possibly several thousand). This
- % feature may be attached to switches as well
- % as disjunctions.
+ % This goal is the main disjunction of a predicate
+ % with the mode_check_clauses pragma. No compiler
+ % pass should try to invoke quadratic or worse
+ % algorithms on the arms of this goal, since it
+ % probably has many arms (possibly several
+ % thousand). This feature may be attached to
+ % switches as well as disjunctions.
% We can think of the goal that defines a procedure to be a tree,
% whose leaves are primitive goals and whose interior nodes are
@@ -1010,7 +1028,8 @@
%
:- type goal_path == list(goal_path_step).
-:- type goal_path_step ---> conj(int)
+:- type goal_path_step
+ ---> conj(int)
; disj(int)
; switch(int, int)
; ite_cond
@@ -1025,11 +1044,12 @@
% Convert a goal path to a string, using the format documented
% in the Mercury user's guide.
+ %
:- pred goal_path_to_string(goal_path::in, string::out) is det.
%-----------------------------------------------------------------------------%
%
-% get/set predicates for the extra_goal_info strucutre.
+% Get/set predicates for the extra_goal_info strucutre..
%
:- func goal_info_get_ho_values(hlds_goal_info) = ho_values.
@@ -1039,7 +1059,7 @@
%-----------------------------------------------------------------------------%
%
-% Miscellaneous utility procedures for dealing with HLDS goals
+% Miscellaneous utility procedures for dealing with HLDS goals.
%
% Convert a goal to a list of conjuncts.
@@ -1160,7 +1180,6 @@
% With alias tracking, the instmap_delta will be correct only if
% the variable being assigned to has no aliases.
%
- %
:- pred make_int_const_construction(prog_var::in, int::in,
hlds_goal::out) is det.
:- pred make_string_const_construction(prog_var::in, string::in,
@@ -1233,16 +1252,18 @@
% by aditi_builtin_ops.m before code generation.
%
:- type aditi_builtin
- --->
+
+ ---> aditi_tuple_update(
% Insert or delete a single tuple into/from a base relation.
% Arguments:
% the arguments of tuple to insert
% aditi__state::di, aditi__state::uo
- aditi_tuple_update(
+
aditi_tuple_update,
pred_id % base relation to insert into
)
+ ; aditi_bulk_update(
% Insert/delete/modify operations which take
% an input closure.
% Arguments:
@@ -1274,7 +1295,7 @@
% q(DB, X, Y)
% ),
% aditi_bulk_delete(pred p/3, DeletePred).
- ; aditi_bulk_update(
+
aditi_bulk_update,
pred_id,
aditi_builtin_syntax
@@ -1296,9 +1317,9 @@
% Reference Manual).
%
:- type aditi_builtin_syntax
- ---> pred_term % e.g.
- % aditi_bulk_insert(p(_, X) :- X = 1).
- ; sym_name_and_closure. % e.g.
+ ---> pred_term % e.g. aditi_bulk_insert(p(_, X) :- X = 1).
+ ; sym_name_and_closure.
+ % e.g.
% aditi_insert(p/2,
% (pred(_::in, X::out) is nondet:-
% X = 1)
@@ -1369,8 +1390,7 @@
NamesModes = [NameMode | NamesModesTail],
Types = [Type | TypesTail]
->
- make_foreign_args(VarsTail, NamesModesTail, TypesTail,
- ArgsTail),
+ make_foreign_args(VarsTail, NamesModesTail, TypesTail, ArgsTail),
Arg = foreign_arg(Var, NameMode, Type),
Args = [Arg | ArgsTail]
;
@@ -1390,8 +1410,7 @@
hlds_goal__generic_call_id(higher_order(_, Purity, PorF, Arity),
generic_call(higher_order(Purity, PorF, Arity))).
-hlds_goal__generic_call_id(
- class_method(_, _, ClassId, MethodId),
+hlds_goal__generic_call_id(class_method(_, _, ClassId, MethodId),
generic_call(class_method(ClassId, MethodId))).
hlds_goal__generic_call_id(cast(CastType), generic_call(cast(CastType))).
hlds_goal__generic_call_id(aditi_builtin(Builtin, Name),
@@ -1415,16 +1434,16 @@
% NB. Don't forget to check goal_util__name_apart_goalinfo
% if this structure is modified.
-:- type hlds_goal_info --->
- goal_info(
+:- type hlds_goal_info
+ ---> goal_info(
determinism :: determinism,
- % the overall determinism of the goal
+ % The overall determinism of the goal
% (computed during determinism analysis)
% [because true determinism is undecidable,
- % this may be a conservative approximation]
+ % this may be a conservative approximation].
instmap_delta :: instmap_delta,
- % the change in insts over this goal
+ % The change in insts over this goal
% (computed during mode analysis)
% [because true unreachability is undecidable,
% the instmap_delta may be reachable even
@@ -1449,32 +1468,12 @@
context :: prog_context,
nonlocals :: set(prog_var),
- % the non-local vars in the goal,
- % i.e. the variables that occur both inside
- % and outside of the goal.
- % (computed by quantification.m)
+ % The non-local vars in the goal, i.e. the
+ % variables that occur both inside and outside
+ % of the goal. (computed by quantification.m)
% [in some circumstances, this may be a
% conservative approximation: it may be
- % a superset of the real non-locals]
-
-% code_gen_nonlocals :: maybe(set(prog_var)),
-% % the non-local vars in the goal,
-% % modified slightly for code generation.
-% % The difference between the code-gen nonlocals
-% % and the ordinary nonlocals is that arguments
-% % of a reconstruction which are taken from the
-% % reused cell are not considered to be
-% % `code_gen_nonlocals' of the goal.
-% % This avoids allocating stack slots and
-% % generating unnecessary field extraction
-% % instructions for those arguments.
-% % Mode information is still computed using
-% % the ordinary non-locals.
-% %
-% % If the field has value `no', the ordinary
-% % nonlocals are used instead. This will
-% % be the case if the procedure body does not
-% % contain any reconstructions.
+ % a superset of the real non-locals].
features :: set(goal_feature),
% The set of used-defined "features" of
@@ -1495,8 +1494,8 @@
% passes, e.g closure analysis.
).
-:- type mode_constraint_goal_info --->
- mode_constraint_goal_info(
+:- type mode_constraint_goal_info
+ ---> mode_constraint_goal_info(
mci_occurring_vars :: set(prog_var),
% Inst_graph nodes that are reachable from
% variables that occur in the goal.
@@ -1516,6 +1515,7 @@
).
:- pragma inline(goal_info_init/1).
+
goal_info_init(GoalInfo) :-
Detism = erroneous,
instmap_delta_init_unreachable(InstMapDelta),
@@ -1523,18 +1523,17 @@
term__context_init(Context),
set__init(Features),
GoalInfo = goal_info(Detism, InstMapDelta, Context, NonLocals,
- Features, [], no, no_code_gen_info,
- hlds_goal_extra_info_init).
+ Features, [], no, no_code_gen_info, hlds_goal_extra_info_init).
:- pragma inline(goal_info_init/2).
+
goal_info_init(Context, GoalInfo) :-
Detism = erroneous,
instmap_delta_init_unreachable(InstMapDelta),
set__init(NonLocals),
set__init(Features),
GoalInfo = goal_info(Detism, InstMapDelta, Context, NonLocals,
- Features, [], no, no_code_gen_info,
- hlds_goal_extra_info_init).
+ Features, [], no, no_code_gen_info, hlds_goal_extra_info_init).
goal_info_init(NonLocals, InstMapDelta, Detism, Purity, GoalInfo) :-
term__context_init(Context),
@@ -1716,8 +1715,7 @@
purity_features(Purity, FeaturesToRemove, FeaturesToAdd),
goal_info_get_features(GoalInfo0, Features0),
Features = set__union(list_to_set(FeaturesToAdd),
- set__difference(Features0,
- list_to_set(FeaturesToRemove))),
+ set__difference(Features0, list_to_set(FeaturesToRemove))),
goal_info_set_features(GoalInfo0, Features, GoalInfo)
).
@@ -1827,10 +1825,6 @@
% Miscellaneous utility procedures for dealing with HLDS goals
%
- % Convert a goal to a list of conjuncts.
- % If the goal is a conjunction, then return its conjuncts,
- % otherwise return the goal as a singleton list.
- %
goal_to_conj_list(Goal, ConjList) :-
( Goal = (conj(List) - _) ->
ConjList = List
@@ -1838,10 +1832,6 @@
ConjList = [Goal]
).
- % Convert a goal to a list of parallel conjuncts.
- % If the goal is a conjunction, then return its conjuncts,
- % otherwise return the goal as a singleton list.
- %
goal_to_par_conj_list(Goal, ConjList) :-
( Goal = par_conj(List) - _ ->
ConjList = List
@@ -1849,10 +1839,6 @@
ConjList = [Goal]
).
- % Convert a goal to a list of disjuncts.
- % If the goal is a disjunction, then return its disjuncts
- % otherwise return the goal as a singleton list.
- %
goal_to_disj_list(Goal, DisjList) :-
( Goal = disj(List) - _ ->
DisjList = List
@@ -1860,11 +1846,6 @@
DisjList = [Goal]
).
- % Convert a list of conjuncts to a goal.
- % If the list contains only one goal, then return that goal,
- % otherwise return the conjunction of the conjuncts,
- % with the specified goal_info.
- %
conj_list_to_goal(ConjList, GoalInfo, Goal) :-
( ConjList = [Goal0] ->
Goal = Goal0
@@ -1872,11 +1853,6 @@
Goal = conj(ConjList) - GoalInfo
).
- % Convert a list of parallel conjuncts to a goal.
- % If the list contains only one goal, then return that goal,
- % otherwise return the parallel conjunction of the conjuncts,
- % with the specified goal_info.
- %
par_conj_list_to_goal(ConjList, GoalInfo, Goal) :-
( ConjList = [Goal0] ->
Goal = Goal0
@@ -1884,11 +1860,6 @@
Goal = par_conj(ConjList) - GoalInfo
).
- % Convert a list of disjuncts to a goal.
- % If the list contains only one goal, then return that goal,
- % otherwise return the disjunction of the conjuncts,
- % with the specified goal_info.
- %
disj_list_to_goal(DisjList, GoalInfo, Goal) :-
( DisjList = [Goal0] ->
Goal = Goal0
@@ -1914,17 +1885,14 @@
),
conjoin_goal_and_goal_list(Goal1, GoalList, Goal).
- % Negate a goal, eliminating double negations as we go.
- %
negate_goal(Goal, GoalInfo, NegatedGoal) :-
(
- % eliminate double negations
+ % Eliminate double negations.
Goal = not(Goal1) - _
->
NegatedGoal = Goal1
;
- % convert negated conjunctions of negations
- % into disjunctions
+ % Convert negated conjunctions of negations into disjunctions.
Goal = conj(NegatedGoals) - _,
all_negated(NegatedGoals, UnnegatedGoals)
->
@@ -1976,11 +1944,12 @@
HasForeign = goal_has_foreign(Goal2)
;
GoalExpr = if_then_else(_, Cond, Then, Else),
- ( goal_has_foreign(Cond) = yes ->
- HasForeign = yes
- ; goal_has_foreign(Then) = yes ->
- HasForeign = yes
- ; goal_has_foreign(Else) = yes ->
+ (
+ ( goal_has_foreign(Cond) = yes
+ ; goal_has_foreign(Then) = yes
+ ; goal_has_foreign(Else) = yes
+ )
+ ->
HasForeign = yes
;
HasForeign = no
@@ -2000,13 +1969,15 @@
%
:- func goal_has_foreign_shorthand(shorthand_goal_expr) = bool.
-goal_has_foreign_shorthand(bi_implication(Goal2, Goal3)) = HasForeign :-
- ( goal_has_foreign(Goal2) = yes ->
- HasForeign = yes
- ; goal_has_foreign(Goal3) = yes ->
- HasForeign = yes
+goal_has_foreign_shorthand(bi_implication(GoalA, GoalB)) =
+ (
+ ( goal_has_foreign(GoalA) = yes
+ ; goal_has_foreign(GoalB) = yes
+ )
+ ->
+ yes
;
- HasForeign = no
+ no
).
goal_list_has_foreign([]) = no.
@@ -2019,12 +1990,25 @@
%-----------------------------------------------------------------------------%
-goal_is_atomic(conj([])).
-goal_is_atomic(disj([])).
-goal_is_atomic(generic_call(_,_,_,_)).
-goal_is_atomic(call(_,_,_,_,_,_)).
-goal_is_atomic(unify(_,_,_,_,_)).
-goal_is_atomic(foreign_proc(_,_,_,_,_,_)).
+goal_is_atomic(Goal) :-
+ goal_is_atomic(Goal) = yes.
+
+:- func goal_is_atomic(hlds_goal_expr) = bool.
+
+goal_is_atomic(unify(_, _, _, _, _)) = yes.
+goal_is_atomic(generic_call(_, _, _, _)) = yes.
+goal_is_atomic(call(_, _, _, _, _, _)) = yes.
+goal_is_atomic(foreign_proc(_, _, _, _, _, _)) = yes.
+goal_is_atomic(conj(Conj)) =
+ ( Conj = [] -> yes ; no ).
+goal_is_atomic(disj(Disj)) =
+ ( Disj = [] -> yes ; no ).
+goal_is_atomic(if_then_else(_, _, _, _)) = no.
+goal_is_atomic(not(_)) = no.
+goal_is_atomic(switch(_, _, _)) = no.
+goal_is_atomic(scope(_, _)) = no.
+goal_is_atomic(par_conj(_)) = no.
+goal_is_atomic(shorthand(_)) = no.
%-----------------------------------------------------------------------------%
@@ -2059,8 +2043,7 @@
ApplyDelta = (pred(Goal::in, Delta0::in, Delta::out) is det :-
Goal = _ - GoalInfo,
goal_info_get_instmap_delta(GoalInfo, Delta1),
- instmap_delta_apply_instmap_delta(Delta0, Delta1,
- test_size, Delta)
+ instmap_delta_apply_instmap_delta(Delta0, Delta1, test_size, Delta)
),
instmap_delta_init_reachable(InstMapDelta0),
list__foldl(ApplyDelta, Goals, InstMapDelta0, InstMapDelta).
@@ -2103,8 +2086,7 @@
set_goal_contexts_2(Context, switch(Var, CanFail, Cases0),
switch(Var, CanFail, Cases)) :-
list__map(
- (pred(case(ConsId, Goal0)::in, case(ConsId, Goal)::out)
- is det :-
+ (pred(case(ConsId, Goal0)::in, case(ConsId, Goal)::out) is det :-
set_goal_contexts(Context, Goal0, Goal)
), Cases0, Cases).
set_goal_contexts_2(Context, scope(Reason, Goal0), scope(Reason, Goal)) :-
@@ -2121,8 +2103,7 @@
Goal = foreign_proc(_, _, _, _, _, _).
set_goal_contexts_2(Context, shorthand(ShorthandGoal0),
shorthand(ShorthandGoal)) :-
- set_goal_contexts_2_shorthand(Context, ShorthandGoal0,
- ShorthandGoal).
+ set_goal_contexts_2_shorthand(Context, ShorthandGoal0, ShorthandGoal).
:- pred set_goal_contexts_2_shorthand(prog_context::in,
shorthand_goal_expr::in, shorthand_goal_expr::out) is det.
@@ -2243,9 +2224,8 @@
UniMode = ((ground_inst - free_inst) -> (ground_inst - ground_inst)),
list__duplicate(Arity, UniMode, UniModes),
UnifyContext = unify_context(explicit, []),
- CanGC = no,
- Unification = deconstruct(Var, ConsId, Args,
- UniModes, cannot_fail, CanGC),
+ Unification = deconstruct(Var, ConsId, Args, UniModes, cannot_fail,
+ cannot_cgc),
Unify = unify(Var, Rhs, UnifyMode, Unification, UnifyContext),
set__list_to_set([Var | Args], NonLocals),
list__duplicate(Arity, ground_inst, DeltaValues),
@@ -2303,8 +2283,7 @@
GoalInfo ^ extra_goal_info ^ extra_info_ho_vals.
goal_info_set_ho_values(Values, !GoalInfo) :-
- !:GoalInfo = !.GoalInfo ^ extra_goal_info
- ^ extra_info_ho_vals:= Values.
+ !:GoalInfo = !.GoalInfo ^ extra_goal_info ^ extra_info_ho_vals := Values.
%-----------------------------------------------------------------------------%
@@ -2312,6 +2291,4 @@
this_file = "hlds_goal".
-%-----------------------------------------------------------------------------%
-:- end_module hlds_goal.
%-----------------------------------------------------------------------------%
Index: ml_unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.81
diff -u -b -r1.81 ml_unify_gen.m
--- ml_unify_gen.m 22 Mar 2005 06:40:10 -0000 1.81
+++ ml_unify_gen.m 16 Aug 2005 08:30:20 -0000
@@ -182,13 +182,13 @@
% unification fails, it is the responsibility of the
% structure reuse phase to ensure that this is safe.
%
- CanCGC = yes,
+ CanCGC = can_cgc,
ml_gen_var(!.Info, Var, VarLval),
Stmt = atomic(delete_object(VarLval)),
CGC_Statements = [mlds__statement(Stmt,
mlds__make_context(Context)) ]
;
- CanCGC = no,
+ CanCGC = cannot_cgc,
CGC_Statements = []
),
Statements0 = Unif_Statements `list__append`
Index: modecheck_unify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.82
diff -u -b -r1.82 modecheck_unify.m
--- modecheck_unify.m 16 Aug 2005 07:11:28 -0000 1.82
+++ modecheck_unify.m 16 Aug 2005 08:30:49 -0000
@@ -725,11 +725,6 @@
Unification = deconstruct(X, ConsId, ArgVars, ArgModes0, Det,
CanCGC)
;
-/* ### In clause for predicate `check_hlds.modecheck_unify.split_complicated_subunifies/7': */
-/* ### in argument 1 of call to predicate `unexpected/2': */
-/* ### error: undefined symbol `this_file/0'. */
-/* ### In clause for predicate `check_hlds.modecheck_unify.split_complicated_subunifies/7': */
-/* ### error: undefined predicate `unexpected/2'. */
unexpected(this_file, "split_complicated_subunifies_2 failed")
)
;
@@ -830,11 +825,6 @@
Unification0, Unification, GoalInfo2, GoalInfo),
Goal = unify(X, Y, Mode, Unification, FinalUnifyContext)
;
-/* ### In clause for predicate `check_hlds.modecheck_unify.create_var_var_unification/5': */
-/* ### in argument 1 of call to predicate `unexpected/2': */
-/* ### error: undefined symbol `this_file/0'. */
-/* ### In clause for predicate `check_hlds.modecheck_unify.create_var_var_unification/5': */
-/* ### error: undefined predicate `unexpected/2'. */
unexpected(this_file, "modecheck_unify__create_var_var_unification")
).
@@ -873,11 +863,6 @@
; LiveY = dead ->
Unification = assign(Y, X)
;
-/* ### In clause for predicate `check_hlds.modecheck_unify.categorize_unify_var_var/13': */
-/* ### in argument 1 of call to predicate `unexpected/2': */
-/* ### error: undefined symbol `this_file/0'. */
-/* ### In clause for predicate `check_hlds.modecheck_unify.categorize_unify_var_var/13': */
-/* ### error: undefined predicate `unexpected/2'. */
unexpected(this_file, "categorize_unify_var_var: free-free unify!")
)
;
@@ -959,11 +944,6 @@
( Unification0 = complicated_unify(_, _, UnifyTypeInfoVars0) ->
UnifyTypeInfoVars = UnifyTypeInfoVars0
;
-/* ### In clause for predicate `check_hlds.modecheck_unify.modecheck_complicated_unify/11': */
-/* ### in argument 1 of call to predicate `unexpected/2': */
-/* ### error: undefined symbol `this_file/0'. */
-/* ### In clause for predicate `check_hlds.modecheck_unify.modecheck_complicated_unify/11': */
-/* ### error: undefined predicate `unexpected/2'. */
unexpected(this_file, "modecheck_complicated_unify")
),
Unification = complicated_unify(UniMode, CanFail, UnifyTypeInfoVars),
@@ -1110,11 +1090,6 @@
RHS = functor(cons(qualified(PredModule, PredName), Arity),
no, ArgVars)
;
-/* ### In clause for predicate `check_hlds.modecheck_unify.categorize_unify_var_lambda/11': */
-/* ### in argument 1 of call to predicate `unexpected/2': */
-/* ### error: undefined symbol `this_file/0'. */
-/* ### In clause for predicate `check_hlds.modecheck_unify.categorize_unify_var_lambda/11': */
-/* ### error: undefined predicate `unexpected/2'. */
unexpected(this_file,
"categorize_unify_var_lambda - reintroduced lambda goal")
)
@@ -1221,7 +1196,8 @@
true
)
),
- Unification = deconstruct(X, ConsId, ArgVars, ArgModes, CanFail, no)
+ Unification = deconstruct(X, ConsId, ArgVars, ArgModes, CanFail,
+ cannot_cgc)
).
% Check that any type_info or type_class_info variables
Index: simplify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.147
diff -u -b -r1.147 simplify.m
--- simplify.m 16 Aug 2005 07:11:28 -0000 1.147
+++ simplify.m 16 Aug 2005 08:31:12 -0000
@@ -1187,7 +1187,7 @@
Bound = bound(shared, [functor(ConsId, [])]),
UMode = ((Unique -> Bound) - (Bound -> Bound)),
RHS = functor(ConsId, no, []),
- UKind = deconstruct(R, ConsId, [], [], can_fail, no),
+ UKind = deconstruct(R, ConsId, [], [], can_fail, cannot_cgc),
UContext = unify_context(implicit(
"replacement of inequality with call to compare/3"), []),
UfyExpr = unify(R, RHS, UMode, UKind, UContext),
@@ -1997,7 +1997,8 @@
list__map(InstToUniMode, ArgInsts, UniModes),
UniMode = (Inst0 -> Inst0) - (Inst0 -> Inst0),
UnifyContext = unify_context(explicit, []),
- Unification = deconstruct(Var, ConsId, ArgVars, UniModes, can_fail, no),
+ Unification = deconstruct(Var, ConsId, ArgVars, UniModes, can_fail,
+ cannot_cgc),
ExtraGoal = unify(Var, functor(ConsId, no, ArgVars),
UniMode, Unification, UnifyContext),
set__singleton_set(NonLocals, Var),
cvs diff: Diffing notes
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list