for review: make HLDS well-moded [part 1]
Simon Taylor
stayl at cs.mu.OZ.AU
Mon Feb 9 16:32:12 AEDT 1998
Hi,
Sorry to people who get this twice - the first copy didn't get
past the 100K limit on mail to cat.
This is for Fergus to review.
Simon.
Estimated hours taken: 45
Assorted changes to make the HLDS type and mode correct
after lambda expansion. The HLDS is still not unique mode
correct after common structure elimination.
compiler/modecheck_unify.m
Avoid some aborts and mode errors when rerunning mode analysis,
especially those resulting from not_reached insts being treated
as bound.
compiler/unique_modes.m
compiler/hlds_pred.m
Added proc_info_inferred_never_succeeds, which checks whether
the procedure never succeeds according to the inferred determinism.
Use it during unique_mode analysis instead of proc_info_never_succeeds,
which uses the declared determinism.
compiler/mode_util.m
Fix a bug in recompute_instmap_delta_call to do with unreachable
instmaps.
compiler/hlds_pred.m
compiler/lambda.m
Add a field to the proc_info to record which args_method
should be used for this procedure. Procedures directly
called by do_call_*_closure must be compiled with
the compact argument convention to avoid the need to permute
the arguments so inputs come before outputs.
compiler/lambda.m
compiler/higher_order.m
Remove permutation of argument variables of lambda expressions
so the HLDS is type and mode correct and mode analysis can
be rerun.
compiler/arg_info.m
Added arg_info__ho_callable_args_method which returns
an args_method which can always be directly called by
do_call_*_closure (compact).
compiler/unify_gen.m
Abort if a closure is created for a procedure compiled
with the simple argument convention.
compiler/hlds_goal.m
compiler/lambda.m
Mode analysis was not storing the non-locals list on which the
uni_modes field of the construction of a lambda goal was computed.
If the nonlocals were renamed, the sort order could change, and
the non-locals could be incorrectly matched with the arguments
of the introduced lambda expression, causing a mode error. The
argument list is now stored.
compiler/*.m
Fill in the args_method field of proc_infos with the value
from the globals.
Handle the extra argument to the lambda_goal unify_rhs.
compiler/special_pred.m
library/mercury_builtin.m
Make the uniqueness of the comparison_result argument
of builtin_compare_* and the automatically generated
comparison procedures match that of compare/3. Unique mode
errors will still be introduced if any of the unique modes
of compare/3 are used.
runtime/mercury_ho_call.c
Remove code in do_call_*_closure to deal with the
simple args_method.
tests/valid/unreachable_code.m
Add a test case for a bogus higher-order unification
mode error in unreachable code.
Index: compiler/arg_info.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/arg_info.m,v
retrieving revision 1.25
diff -u -r1.25 arg_info.m
--- arg_info.m 1998/01/23 12:56:11 1.25
+++ arg_info.m 1998/02/07 09:01:04
@@ -24,8 +24,8 @@
:- interface.
:- import_module hlds_module, llds, globals, prog_data.
-:- pred generate_arg_info(module_info, args_method, module_info).
-:- mode generate_arg_info(in, in, out) is det.
+:- pred generate_arg_info(module_info, module_info).
+:- mode generate_arg_info(in, out) is det.
:- pred arg_info__unify_arg_info(args_method, code_model, list(arg_info)).
:- mode arg_info__unify_arg_info(in, in, out) is det.
@@ -34,6 +34,12 @@
module_info, list(arg_info)).
:- mode make_arg_infos(in, in, in, in, in, out) is det.
+ % Return an args_method for which mercury_ho_call.c can
+ % find the input arguments without permutation of the arguments
+ % so that inputs come before outputs.
+:- pred arg_info__ho_callable_args_method(args_method).
+:- mode arg_info__ho_callable_args_method(out) is det.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -46,30 +52,28 @@
% This whole section just traverses the module structure.
-generate_arg_info(ModuleInfo0, Method, ModuleInfo) :-
+generate_arg_info(ModuleInfo0, ModuleInfo) :-
module_info_preds(ModuleInfo0, Preds),
map__keys(Preds, PredIds),
- generate_pred_arg_info(PredIds, Method, ModuleInfo0, ModuleInfo).
+ generate_pred_arg_info(PredIds, ModuleInfo0, ModuleInfo).
-:- pred generate_pred_arg_info(list(pred_id), args_method,
- module_info, module_info).
-:- mode generate_pred_arg_info(in, in, in, out) is det.
+:- pred generate_pred_arg_info(list(pred_id), module_info, module_info).
+:- mode generate_pred_arg_info(in, in, out) is det.
-generate_pred_arg_info([], _Method, ModuleInfo, ModuleInfo).
-generate_pred_arg_info([PredId | PredIds], Method, ModuleInfo0, ModuleInfo) :-
+generate_pred_arg_info([], ModuleInfo, ModuleInfo).
+generate_pred_arg_info([PredId | PredIds], ModuleInfo0, ModuleInfo) :-
module_info_preds(ModuleInfo0, PredTable),
map__lookup(PredTable, PredId, PredInfo),
pred_info_procids(PredInfo, ProcIds),
- generate_proc_list_arg_info(PredId, ProcIds, Method,
- ModuleInfo0, ModuleInfo1),
- generate_pred_arg_info(PredIds, Method, ModuleInfo1, ModuleInfo).
+ generate_proc_list_arg_info(PredId, ProcIds, ModuleInfo0, ModuleInfo1),
+ generate_pred_arg_info(PredIds, ModuleInfo1, ModuleInfo).
-:- pred generate_proc_list_arg_info(pred_id, list(proc_id), args_method,
+:- pred generate_proc_list_arg_info(pred_id, list(proc_id),
module_info, module_info).
-:- mode generate_proc_list_arg_info(in, in, in, in, out) is det.
+:- mode generate_proc_list_arg_info(in, in, in, out) is det.
-generate_proc_list_arg_info(_PredId, [], _Method, ModuleInfo, ModuleInfo).
-generate_proc_list_arg_info(PredId, [ProcId | ProcIds], Method,
+generate_proc_list_arg_info(_PredId, [], ModuleInfo, ModuleInfo).
+generate_proc_list_arg_info(PredId, [ProcId | ProcIds],
ModuleInfo0, ModuleInfo) :-
module_info_preds(ModuleInfo0, PredTable0),
map__lookup(PredTable0, PredId, PredInfo0),
@@ -77,7 +81,7 @@
pred_info_arg_types(PredInfo0, _TVarSet, ArgTypes),
map__lookup(ProcTable0, ProcId, ProcInfo0),
- generate_proc_arg_info(ProcInfo0, Method, ArgTypes, ModuleInfo0,
+ generate_proc_arg_info(ProcInfo0, ArgTypes, ModuleInfo0,
ProcInfo),
map__det_update(ProcTable0, ProcId, ProcInfo, ProcTable),
@@ -85,15 +89,14 @@
map__det_update(PredTable0, PredId, PredInfo, PredTable),
module_info_set_preds(ModuleInfo0, PredTable, ModuleInfo1),
- generate_proc_list_arg_info(PredId, ProcIds, Method,
- ModuleInfo1, ModuleInfo).
+ generate_proc_list_arg_info(PredId, ProcIds, ModuleInfo1, ModuleInfo).
-:- pred generate_proc_arg_info(proc_info, args_method, list(type),
- module_info, proc_info).
-:- mode generate_proc_arg_info(in, in, in, in, out) is det.
+:- pred generate_proc_arg_info(proc_info, list(type), module_info, proc_info).
+:- mode generate_proc_arg_info(in, in, in, out) is det.
-generate_proc_arg_info(ProcInfo0, Method, ArgTypes, ModuleInfo, ProcInfo) :-
+generate_proc_arg_info(ProcInfo0, ArgTypes, ModuleInfo, ProcInfo) :-
proc_info_argmodes(ProcInfo0, ArgModes),
+ proc_info_args_method(ProcInfo0, Method),
proc_info_interface_code_model(ProcInfo0, CodeModel),
make_arg_infos(Method, ArgTypes, ArgModes, CodeModel, ModuleInfo,
@@ -127,6 +130,11 @@
% arguments start at register number 2.
% In the `compact' argument convention, we may use a single
% register for both an input arg and an output arg.
+ %
+ % lambda.m ensures that all procedures which are called directly
+ % from do_call_*_closure use the compact argument convention,
+ % so that mercury_ho_call.c can place the input arguments without
+ % knowing anything about the called procedure.
make_arg_infos(Method, ArgTypes, ArgModes, CodeModel, ModuleInfo, ArgInfo) :-
( CodeModel = model_semi ->
@@ -205,6 +213,10 @@
[arg_info(1, top_in), arg_info(2, top_in)]).
arg_info__unify_arg_info(_ArgsMethod, model_non, _) :-
error("arg_info: nondet unify!").
+
+%---------------------------------------------------------------------------%
+
+arg_info__ho_callable_args_method(compact).
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
Index: compiler/bytecode_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.34
diff -u -r1.34 bytecode_gen.m
--- bytecode_gen.m 1998/01/13 10:11:04 1.34
+++ bytecode_gen.m 1998/02/06 13:24:28
@@ -276,8 +276,7 @@
ByteInfo, Code) :-
determinism_to_code_model(Detism, CodeModel),
bytecode_gen__get_module_info(ByteInfo, ModuleInfo),
- module_info_globals(ModuleInfo, Globals),
- globals__get_args_method(Globals, ArgsMethod),
+ arg_info__ho_callable_args_method(ArgsMethod),
make_arg_infos(ArgsMethod, ArgTypes, ArgModes, CodeModel, ModuleInfo,
ArgInfo),
assoc_list__from_corresponding_lists(ArgVars, ArgInfo, ArgVarsInfos),
Index: compiler/call_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/call_gen.m,v
retrieving revision 1.119
diff -u -r1.119 call_gen.m
--- call_gen.m 1998/02/03 08:18:06 1.119
+++ call_gen.m 1998/02/07 10:10:29
@@ -158,22 +158,21 @@
% for a higher-order call,
% we split the arguments into inputs and outputs, put the inputs
% in the locations expected by do_call_<detism>_closure in
- % runtime/call.mod, generate the call to do_call_<detism>_closure,
- % and pick up the outputs from the locations that we know
- % runtime/call.mod leaves them in.
+ % runtime/mercury_ho_call.c, generate the call to
+ % do_call_<detism>_closure, and pick up the outputs from the
+ % locations that we know runtime/mercury_ho_call.c leaves them in.
%
- % lambda.m transforms the generated lambda predicates to
- % make sure that all inputs come before all outputs, so that
- % runtime/call.mod doesn't have trouble figuring out which registers
- % the arguments go in.
+ % lambda.m insist that procedures which are directly
+ % higher-order-called use the compact argument convertion,
+ % so that runtime/mercury_ho_call.c doesn't have trouble
+ % figuring out which registers the arguments go in.
%
call_gen__generate_higher_order_call(_OuterCodeModel, PredVar, Args, Types,
Modes, Det, GoalInfo, Code) -->
{ determinism_to_code_model(Det, CodeModel) },
- code_info__get_globals(Globals),
code_info__get_module_info(ModuleInfo),
- { globals__get_args_method(Globals, ArgsMethod) },
+ { arg_info__ho_callable_args_method(ArgsMethod) },
{ make_arg_infos(ArgsMethod, Types, Modes, CodeModel, ModuleInfo,
ArgInfos) },
{ assoc_list__from_corresponding_lists(Args, ArgInfos, ArgsInfos) },
@@ -266,15 +265,17 @@
% for a class method call,
% we split the arguments into inputs and outputs, put the inputs
% in the locations expected by do_call_<detism>_class_method in
- % runtime/call.mod, generate the call to do_call_<detism>_class_method,
- % and pick up the outputs from the locations that we know
- % runtime/call.mod leaves them in.
+ % runtime/mercury_ho_call.c, generate the call to
+ % do_call_<detism>_class_method, and pick up the outputs from the
+ % locations that we know runtime/mercury_ho_call.c leaves them in.
%
call_gen__generate_class_method_call(_OuterCodeModel, TCVar, MethodNum, Args,
Types, Modes, Det, GoalInfo, Code) -->
{ determinism_to_code_model(Det, InnerCodeModel) },
code_info__get_globals(Globals),
code_info__get_module_info(ModuleInfo),
+
+ % XXX must be compact
{ globals__get_args_method(Globals, ArgsMethod) },
{ make_arg_infos(ArgsMethod, Types, Modes, InnerCodeModel, ModuleInfo,
ArgInfo) },
Index: compiler/clause_to_proc.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.19
diff -u -r1.19 clause_to_proc.m
--- clause_to_proc.m 1998/02/03 07:03:01 1.19
+++ clause_to_proc.m 1998/02/06 01:22:14
@@ -37,27 +37,29 @@
% a default mode of `:- mode foo(in, in, ..., in) = out.'
% for functions that don't have an explicit mode declaration.
-:- pred maybe_add_default_modes(list(pred_id), pred_table, pred_table).
-:- mode maybe_add_default_modes(in, in, out) is det.
-
-:- pred maybe_add_default_mode(pred_info, pred_info, maybe(proc_id)).
-:- mode maybe_add_default_mode(in, out, out) is det.
+:- pred maybe_add_default_modes(module_info, list(pred_id),
+ pred_table, pred_table).
+:- mode maybe_add_default_modes(in, in, in, out) is det.
+
+:- pred maybe_add_default_mode(module_info, pred_info,
+ pred_info, maybe(proc_id)).
+:- mode maybe_add_default_mode(in, in, out, out) is det.
%-----------------------------------------------------------------------------%
:- implementation.
-:- import_module hlds_goal, hlds_data, prog_data, make_hlds.
+:- import_module hlds_goal, hlds_data, prog_data, make_hlds, globals.
:- import_module int, list, set, map, std_util.
-maybe_add_default_modes([], Preds, Preds).
-maybe_add_default_modes([PredId | PredIds], Preds0, Preds) :-
+maybe_add_default_modes(_, [], Preds, Preds).
+maybe_add_default_modes(ModuleInfo, [PredId | PredIds], Preds0, Preds) :-
map__lookup(Preds0, PredId, PredInfo0),
- maybe_add_default_mode(PredInfo0, PredInfo, _),
+ maybe_add_default_mode(ModuleInfo, PredInfo0, PredInfo, _),
map__det_update(Preds0, PredId, PredInfo, Preds1),
- maybe_add_default_modes(PredIds, Preds1, Preds).
+ maybe_add_default_modes(ModuleInfo, PredIds, Preds1, Preds).
-maybe_add_default_mode(PredInfo0, PredInfo, MaybeProcId) :-
+maybe_add_default_mode(ModuleInfo, PredInfo0, PredInfo, MaybeProcId) :-
pred_info_procedures(PredInfo0, Procs0),
pred_info_get_is_pred_or_func(PredInfo0, PredOrFunc),
(
@@ -87,9 +89,11 @@
Determinism = det,
pred_info_context(PredInfo0, Context),
MaybePredArgLives = no,
+ module_info_globals(ModuleInfo, Globals),
+ globals__get_args_method(Globals, ArgsMethod),
add_new_proc(PredInfo0, PredArity, PredArgModes,
yes(PredArgModes), MaybePredArgLives, yes(Determinism),
- Context, PredInfo, ProcId),
+ Context, ArgsMethod, PredInfo, ProcId),
MaybeProcId = yes(ProcId)
;
PredInfo = PredInfo0,
Index: compiler/cse_detection.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/cse_detection.m,v
retrieving revision 1.52
diff -u -r1.52 cse_detection.m
--- cse_detection.m 1998/01/13 10:11:25 1.52
+++ cse_detection.m 1998/02/06 01:22:13
@@ -215,13 +215,17 @@
detect_cse_in_goal_2(unify(A,B0,C,D,E), _, InstMap0, CseInfo0, CseInfo, Redo,
unify(A,B,C,D,E)) :-
- ( B0 = lambda_goal(PredOrFunc, Vars, Modes, Det, Goal0) ->
+ (
+ B0 = lambda_goal(PredOrFunc, NonLocalVars,
+ Vars, Modes, Det, Goal0)
+ ->
CseInfo0 = cse_info(_, _, ModuleInfo),
instmap__pre_lambda_update(ModuleInfo,
Vars, Modes, InstMap0, InstMap),
detect_cse_in_goal(Goal0, InstMap, CseInfo0, CseInfo, Redo,
Goal),
- B = lambda_goal(PredOrFunc, Vars, Modes, Det, Goal)
+ B = lambda_goal(PredOrFunc, NonLocalVars,
+ Vars, Modes, Det, Goal)
;
B = B0,
CseInfo = CseInfo0,
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.36
diff -u -r1.36 dead_proc_elim.m
--- dead_proc_elim.m 1998/01/16 06:44:35 1.36
+++ dead_proc_elim.m 1998/02/06 01:22:14
@@ -782,7 +782,7 @@
;
[]
).
-pre_modecheck_examine_unify_rhs(lambda_goal(_, _, _, _, Goal)) -->
+pre_modecheck_examine_unify_rhs(lambda_goal(_, _, _, _, _, Goal)) -->
pre_modecheck_examine_goal(Goal).
:- pred dead_pred_info_add_pred_name(sym_name::in, dead_pred_info::in,
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/det_analysis.m,v
retrieving revision 1.128
diff -u -r1.128 det_analysis.m
--- det_analysis.m 1998/01/13 10:11:33 1.128
+++ det_analysis.m 1998/02/06 01:22:14
@@ -493,8 +493,8 @@
det_infer_goal_2(unify(LT, RT0, M, U, C), GoalInfo, InstMap0, SolnContext,
DetInfo, _, _, unify(LT, RT, M, U, C), UnifyDet, Msgs) :-
(
- RT0 = lambda_goal(PredOrFunc, Vars, Modes, LambdaDeclaredDet,
- Goal0)
+ RT0 = lambda_goal(PredOrFunc, NonLocalVars, Vars,
+ Modes, LambdaDeclaredDet, Goal0)
->
(
determinism_components(LambdaDeclaredDet, _,
@@ -512,8 +512,8 @@
det_check_lambda(LambdaDeclaredDet, LambdaInferredDet,
Goal, GoalInfo, DetInfo, Msgs2),
list__append(Msgs1, Msgs2, Msgs3),
- RT = lambda_goal(PredOrFunc, Vars, Modes, LambdaDeclaredDet,
- Goal)
+ RT = lambda_goal(PredOrFunc, NonLocalVars, Vars,
+ Modes, LambdaDeclaredDet, Goal)
;
RT = RT0,
Msgs3 = []
Index: compiler/det_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/det_util.m,v
retrieving revision 1.14
diff -u -r1.14 det_util.m
--- det_util.m 1998/01/23 12:56:27 1.14
+++ det_util.m 1998/02/06 01:22:14
@@ -114,7 +114,7 @@
term__var_list_to_term_list(ArgVars, ArgTerms),
cons_id_and_args_to_term(ConsId, ArgTerms, RhsTerm),
term__unify(term__variable(X), RhsTerm, Subst0, Subst).
-interpret_unify(_X, lambda_goal(_PredOrFunc, _LambdaVars, _Modes, _Det, _Goal),
+interpret_unify(_X, lambda_goal(_POrF, _NonLocals, _Vars, _Modes, _Det, _Goal),
Subst0, Subst) :-
% For ease of implementation we just ignore unifications with
% lambda terms. This is a safe approximation, it just
Index: compiler/fact_table.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/fact_table.m,v
retrieving revision 1.15
diff -u -r1.15 fact_table.m
--- fact_table.m 1998/01/23 12:56:31 1.15
+++ fact_table.m 1998/02/06 13:05:58
@@ -2451,7 +2451,7 @@
fact_table_generate_c_code(PredName, PragmaVars, ProcID, PrimaryProcID,
ProcInfo, ArgTypes, ModuleInfo, ProcCode, ExtraCode) -->
fact_table_size(FactTableSize),
- globals__io_get_args_method(ArgsMethod),
+ { proc_info_args_method(ProcInfo, ArgsMethod) },
{ proc_info_argmodes(ProcInfo, ArgModes) },
{ proc_info_interface_determinism(ProcInfo, Determinism) },
{ fact_table_mode_type(ArgModes, ModuleInfo, ModeType) },
Index: compiler/follow_vars.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/follow_vars.m,v
retrieving revision 1.46
diff -u -r1.46 follow_vars.m
--- follow_vars.m 1998/01/13 10:11:58 1.46
+++ follow_vars.m 1998/02/08 02:11:55
@@ -34,9 +34,9 @@
:- pred find_final_follow_vars(proc_info, follow_vars).
:- mode find_final_follow_vars(in, out) is det.
-:- pred find_follow_vars_in_goal(hlds_goal, args_method, module_info,
+:- pred find_follow_vars_in_goal(hlds_goal, module_info,
follow_vars, hlds_goal, follow_vars).
-:- mode find_follow_vars_in_goal(in, in, in, in, out, out) is det.
+:- mode find_follow_vars_in_goal(in, in, in, out, out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -79,44 +79,43 @@
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
-find_follow_vars_in_goal(Goal0 - GoalInfo, ArgsMethod, ModuleInfo, FollowVars0,
+find_follow_vars_in_goal(Goal0 - GoalInfo, ModuleInfo, FollowVars0,
Goal - GoalInfo, FollowVars) :-
- find_follow_vars_in_goal_2(Goal0, ArgsMethod, ModuleInfo, FollowVars0,
- Goal, FollowVars).
+ find_follow_vars_in_goal_2(Goal0, ModuleInfo, FollowVars0,
+ Goal, FollowVars).
%-----------------------------------------------------------------------------%
-:- pred find_follow_vars_in_goal_2(hlds_goal_expr, args_method, module_info,
+:- pred find_follow_vars_in_goal_2(hlds_goal_expr, module_info,
follow_vars, hlds_goal_expr, follow_vars).
-:- mode find_follow_vars_in_goal_2(in, in, in, in, out, out) is det.
+:- mode find_follow_vars_in_goal_2(in, in, in, out, out) is det.
-find_follow_vars_in_goal_2(conj(Goals0), ArgsMethod, ModuleInfo, FollowVars0,
+find_follow_vars_in_goal_2(conj(Goals0), ModuleInfo, FollowVars0,
conj(Goals), FollowVars) :-
- find_follow_vars_in_conj(Goals0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_conj(Goals0, ModuleInfo, FollowVars0,
no, Goals, FollowVars).
% We record that at the end of each disjunct, live variables should
% be in the locations given by the initial follow_vars, which reflects
% the requirements of the code following the disjunction.
-find_follow_vars_in_goal_2(disj(Goals0, _), ArgsMethod, ModuleInfo, FollowVars0,
+find_follow_vars_in_goal_2(disj(Goals0, _), ModuleInfo, FollowVars0,
disj(Goals, FollowVars0), FollowVars) :-
- find_follow_vars_in_disj(Goals0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_disj(Goals0, ModuleInfo, FollowVars0,
Goals, FollowVars).
-find_follow_vars_in_goal_2(not(Goal0), ArgsMethod, ModuleInfo, FollowVars0,
+find_follow_vars_in_goal_2(not(Goal0), ModuleInfo, FollowVars0,
not(Goal), FollowVars) :-
- find_follow_vars_in_goal(Goal0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_goal(Goal0, ModuleInfo, FollowVars0,
Goal, FollowVars).
% We record that at the end of each arm of the switch, live variables
% should be in the locations given by the initial follow_vars, which
% reflects the requirements of the code following the switch.
-find_follow_vars_in_goal_2(switch(Var, Det, Cases0, _), ArgsMethod, ModuleInfo,
- FollowVars0,
+find_follow_vars_in_goal_2(switch(Var, Det, Cases0, _), ModuleInfo, FollowVars0,
switch(Var, Det, Cases, FollowVars0), FollowVars) :-
- find_follow_vars_in_cases(Cases0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_cases(Cases0, ModuleInfo, FollowVars0,
Cases, FollowVars).
% Set the follow_vars field for the condition, the then-part and the
@@ -137,22 +136,22 @@
% following the if-then-else.
find_follow_vars_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, _),
- ArgsMethod, ModuleInfo, FollowVars0,
+ ModuleInfo, FollowVars0,
if_then_else(Vars, Cond, Then, Else, FollowVars0),
FollowVarsCond) :-
- find_follow_vars_in_goal(Then0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_goal(Then0, ModuleInfo, FollowVars0,
Then1, FollowVarsThen),
goal_set_follow_vars(Then1, yes(FollowVarsThen), Then),
- find_follow_vars_in_goal(Cond0, ArgsMethod, ModuleInfo, FollowVarsThen,
+ find_follow_vars_in_goal(Cond0, ModuleInfo, FollowVarsThen,
Cond1, FollowVarsCond),
goal_set_follow_vars(Cond1, yes(FollowVarsCond), Cond),
- find_follow_vars_in_goal(Else0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_goal(Else0, ModuleInfo, FollowVars0,
Else1, FollowVarsElse),
goal_set_follow_vars(Else1, yes(FollowVarsElse), Else).
-find_follow_vars_in_goal_2(some(Vars, Goal0), ArgsMethod, ModuleInfo,
+find_follow_vars_in_goal_2(some(Vars, Goal0), ModuleInfo,
FollowVars0, some(Vars, Goal), FollowVars) :-
- find_follow_vars_in_goal(Goal0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_goal(Goal0, ModuleInfo, FollowVars0,
Goal, FollowVars).
% XXX These follow-vars aren't correct since the desired positions for
@@ -161,11 +160,12 @@
find_follow_vars_in_goal_2(
higher_order_call(PredVar, Args, Types, Modes, Det,
IsPredOrFunc),
- ArgsMethod, ModuleInfo, _FollowVars0,
+ ModuleInfo, _FollowVars0,
higher_order_call(PredVar, Args, Types, Modes, Det,
IsPredOrFunc),
FollowVars) :-
determinism_to_code_model(Det, CodeModel),
+ arg_info__ho_callable_args_method(ArgsMethod),
make_arg_infos(ArgsMethod, Types, Modes, CodeModel, ModuleInfo,
ArgInfo),
find_follow_vars_from_arginfo(ArgInfo, Args, FollowVars).
@@ -176,16 +176,18 @@
find_follow_vars_in_goal_2(
class_method_call(TypeClassInfoVar, Num, Args, Types, Modes,
Det),
- ArgsMethod, ModuleInfo, _FollowVars0,
+ ModuleInfo, _FollowVars0,
class_method_call(TypeClassInfoVar, Num, Args, Types, Modes,
Det),
FollowVars) :-
determinism_to_code_model(Det, CodeModel),
+ module_info_globals(ModuleInfo, Globals),
+ globals__get_args_method(Globals, ArgsMethod), % XXX must be compact.
make_arg_infos(ArgsMethod, Types, Modes, CodeModel, ModuleInfo,
ArgInfo),
find_follow_vars_from_arginfo(ArgInfo, Args, FollowVars).
-find_follow_vars_in_goal_2(call(A,B,C,D,E,F), _ArgsMethod, ModuleInfo,
+find_follow_vars_in_goal_2(call(A,B,C,D,E,F), ModuleInfo,
FollowVars0, call(A,B,C,D,E,F), FollowVars) :-
(
D = inline_builtin
@@ -195,17 +197,9 @@
find_follow_vars_in_call(A, B, C, ModuleInfo, FollowVars)
).
-find_follow_vars_in_goal_2(unify(A,B,C,D,E), ArgsMethod, _ModuleInfo,
+find_follow_vars_in_goal_2(unify(A,B,C,D,E), _ModuleInfo,
FollowVars0, unify(A,B,C,D,E), FollowVars) :-
(
- B = var(BVar),
- D = complicated_unify(_Mode, CanFail)
- ->
- determinism_components(Det, CanFail, at_most_one),
- determinism_to_code_model(Det, CodeModel),
- arg_info__unify_arg_info(ArgsMethod, CodeModel, ArgInfo),
- find_follow_vars_from_arginfo(ArgInfo, [A, BVar], FollowVars)
- ;
D = assign(LVar, RVar),
map__search(FollowVars0, LVar, DesiredLoc)
->
@@ -214,7 +208,7 @@
FollowVars = FollowVars0
).
-find_follow_vars_in_goal_2(pragma_c_code(A,B,C,D,E,F,G), _ArgInfo,
+find_follow_vars_in_goal_2(pragma_c_code(A,B,C,D,E,F,G),
_ModuleInfo, FollowVars,
pragma_c_code(A,B,C,D,E,F,G), FollowVars).
@@ -282,18 +276,18 @@
% model_det and model_semi disjunctions, they will never be
% entered at all.)
-:- pred find_follow_vars_in_disj(list(hlds_goal), args_method, module_info,
+:- pred find_follow_vars_in_disj(list(hlds_goal), module_info,
follow_vars, list(hlds_goal), follow_vars).
-:- mode find_follow_vars_in_disj(in, in, in, in, out, out) is det.
+:- mode find_follow_vars_in_disj(in, in, in, out, out) is det.
-find_follow_vars_in_disj([], _ArgsMethod, _ModuleInfo, FollowVars,
+find_follow_vars_in_disj([], _ModuleInfo, FollowVars,
[], FollowVars).
-find_follow_vars_in_disj([Goal0 | Goals0], ArgsMethod, ModuleInfo, FollowVars0,
+find_follow_vars_in_disj([Goal0 | Goals0], ModuleInfo, FollowVars0,
[Goal | Goals], FollowVars) :-
- find_follow_vars_in_goal(Goal0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_goal(Goal0, ModuleInfo, FollowVars0,
Goal1, FollowVars),
goal_set_follow_vars(Goal1, yes(FollowVars), Goal),
- find_follow_vars_in_disj(Goals0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_disj(Goals0, ModuleInfo, FollowVars0,
Goals, _FollowVars1).
%-----------------------------------------------------------------------------%
@@ -309,18 +303,17 @@
% its follow_vars) and to let different branches "vote" on
% what should be in registers.
-:- pred find_follow_vars_in_cases(list(case), args_method, module_info,
+:- pred find_follow_vars_in_cases(list(case), module_info,
follow_vars, list(case), follow_vars).
-:- mode find_follow_vars_in_cases(in, in, in, in, out, out) is det.
+:- mode find_follow_vars_in_cases(in, in, in, out, out) is det.
-find_follow_vars_in_cases([], _ArgsMethod, _ModuleInfo, FollowVars,
- [], FollowVars).
-find_follow_vars_in_cases([case(Cons, Goal0) | Goals0], ArgsMethod, ModuleInfo,
+find_follow_vars_in_cases([], _ModuleInfo, FollowVars, [], FollowVars).
+find_follow_vars_in_cases([case(Cons, Goal0) | Goals0], ModuleInfo,
FollowVars0, [case(Cons, Goal) | Goals], FollowVars) :-
- find_follow_vars_in_goal(Goal0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_goal(Goal0, ModuleInfo, FollowVars0,
Goal1, FollowVars),
goal_set_follow_vars(Goal1, yes(FollowVars), Goal),
- find_follow_vars_in_cases(Goals0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_cases(Goals0, ModuleInfo, FollowVars0,
Goals, _FollowVars1).
%-----------------------------------------------------------------------------%
@@ -328,13 +321,13 @@
% We attach the follow_vars to each goal that follows a goal
% that is not cachable by the code generator.
-:- pred find_follow_vars_in_conj(list(hlds_goal), args_method, module_info,
+:- pred find_follow_vars_in_conj(list(hlds_goal), module_info,
follow_vars, bool, list(hlds_goal), follow_vars).
-:- mode find_follow_vars_in_conj(in, in, in, in, in, out, out) is det.
+:- mode find_follow_vars_in_conj(in, in, in, in, out, out) is det.
-find_follow_vars_in_conj([], _ArgsMethod, _ModuleInfo, FollowVars,
+find_follow_vars_in_conj([], _ModuleInfo, FollowVars,
_AttachToFirst, [], FollowVars).
-find_follow_vars_in_conj([Goal0 | Goals0], ArgsMethod, ModuleInfo, FollowVars0,
+find_follow_vars_in_conj([Goal0 | Goals0], ModuleInfo, FollowVars0,
AttachToFirst, [Goal | Goals], FollowVars) :-
(
Goal0 = GoalExpr0 - _,
@@ -350,9 +343,9 @@
;
AttachToNext = yes
),
- find_follow_vars_in_conj(Goals0, ArgsMethod, ModuleInfo, FollowVars0,
+ find_follow_vars_in_conj(Goals0, ModuleInfo, FollowVars0,
AttachToNext, Goals, FollowVars1),
- find_follow_vars_in_goal(Goal0, ArgsMethod, ModuleInfo, FollowVars1,
+ find_follow_vars_in_goal(Goal0, ModuleInfo, FollowVars1,
Goal1, FollowVars),
(
AttachToFirst = yes,
Index: compiler/goal_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/goal_util.m,v
retrieving revision 1.41
diff -u -r1.41 goal_util.m
--- goal_util.m 1998/01/13 10:12:06 1.41
+++ goal_util.m 1998/02/08 23:36:27
@@ -305,8 +305,11 @@
goal_util__rename_unify_rhs(functor(Functor, ArgVars0), Must, Subn,
functor(Functor, ArgVars)) :-
goal_util__rename_var_list(ArgVars0, Must, Subn, ArgVars).
-goal_util__rename_unify_rhs(lambda_goal(PredOrFunc, Vars0, Modes, Det, Goal0),
- Must, Subn, lambda_goal(PredOrFunc, Vars, Modes, Det, Goal)) :-
+goal_util__rename_unify_rhs(
+ lambda_goal(PredOrFunc, NonLocals0, Vars0, Modes, Det, Goal0),
+ Must, Subn,
+ lambda_goal(PredOrFunc, NonLocals, Vars, Modes, Det, Goal)) :-
+ goal_util__rename_var_list(NonLocals0, Must, Subn, NonLocals),
goal_util__rename_var_list(Vars0, Must, Subn, Vars),
goal_util__rename_vars_in_goal(Goal0, Must, Subn, Goal).
@@ -476,10 +479,12 @@
set__insert(Set0, X, Set).
goal_util__rhs_goal_vars(functor(_Functor, ArgVars), Set0, Set) :-
set__insert_list(Set0, ArgVars, Set).
-goal_util__rhs_goal_vars(lambda_goal(_PredOrFunc, LambdaVars, _Modes, _Detism,
- Goal - _), Set0, Set) :-
- set__insert_list(Set0, LambdaVars, Set1),
- goal_util__goal_vars_2(Goal, Set1, Set).
+goal_util__rhs_goal_vars(
+ lambda_goal(_POrF, NonLocals, LambdaVars, _M, _D, Goal - _),
+ Set0, Set) :-
+ set__insert_list(Set0, NonLocals, Set1),
+ set__insert_list(Set1, LambdaVars, Set2),
+ goal_util__goal_vars_2(Goal, Set2, Set).
%-----------------------------------------------------------------------------%
Index: compiler/higher_order.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/higher_order.m,v
retrieving revision 1.40
diff -u -r1.40 higher_order.m
--- higher_order.m 1998/02/02 06:35:03 1.40
+++ higher_order.m 1998/02/06 01:22:14
@@ -32,8 +32,8 @@
:- import_module hlds_pred, hlds_goal, hlds_data, instmap, (inst).
:- import_module code_util, globals, make_hlds, mode_util, goal_util.
-:- import_module type_util, options, prog_data, quantification, (lambda).
-:- import_module mercury_to_mercury, inst_match.
+:- import_module type_util, options, prog_data, quantification.
+:- import_module mercury_to_mercury.
:- import_module assoc_list, bool, char, int, list, map, require, set.
:- import_module std_util, string, varset, term.
@@ -81,7 +81,7 @@
% necessary in profiling grades, since otherwise
% the dependency graph isn't built before here).
{ fixup_preds(PredProcs, NewPreds1, ModuleInfo3, ModuleInfo4) },
- { SpecializedPreds = [] ->
+ { SpecializedPreds \= [] ->
module_info_clobber_dependency_info(ModuleInfo4,
ModuleInfo5)
;
@@ -523,12 +523,11 @@
PredProcId, Changed, Info0, Info) :-
Info0 = info(PredVars, Requests0, NewPreds, Module),
(
- Goal0 = higher_order_call(PredVar0, Args0, _Types, Modes0,
+ Goal0 = higher_order_call(PredVar0, Args0, _Types, _Modes0,
_Det, _IsPredOrFunc)
->
PredVar = PredVar0,
- Args = Args0,
- Modes = Modes0
+ Args = Args0
;
error("higher_order.m: higher_order_call expected")
),
@@ -543,12 +542,7 @@
pred_info_name(PredInfo, PredName),
code_util__builtin_state(Module, PredId, ProcId, Builtin),
- % We need to permute the arguments so that inputs come before
- % outputs, since lambda.m will have done that to the arguments
- % of the closure.
- lambda__permute_argvars(Args, Modes, Module, PermutedArgs, _),
-
- list__append(CurriedArgs, PermutedArgs, AllArgs),
+ list__append(CurriedArgs, Args, AllArgs),
MaybeContext = no,
Goal1 = call(PredId, ProcId, AllArgs,
Builtin, MaybeContext,
@@ -1055,7 +1049,6 @@
PredInfo, Substitution0, Substitution, Goals) :-
HOArg = higher_order_arg(PredId, ProcId, Index, NumArgs, CurriedHOArgs),
list__index1_det(HeadVars0, Index, LVar),
- list__index1_det(ArgModes0, Index, LVarMode),
module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
CalledPredInfo, CalledProcInfo),
pred_info_arg_types(CalledPredInfo, CalledTVarset, CalledArgTypes0),
@@ -1093,41 +1086,15 @@
error("list__split failed")
),
(
- type_is_higher_order(LVarType, _PredOrFunc, LVarArgTypes0)
+ type_is_higher_order(LVarType, _PredOrFunc, LVarArgTypes)
->
- %
- % The called pred will have had its uncurried args permuted
- % to make input args precede output args, so
- % we need to do the same for the argument types of the
- % higher-order pred variable (LVar), before unifying
- % them with the types of the called predicate (which
- % we need to do, so that we can make appropriate type
- % substitutions).
- % To permute them, we need to know the modes of the LVarArgs.
- %
- (
- mode_get_insts(ModuleInfo, LVarMode,
- LVarInitialInst0, _LVarFinalInst),
- inst_expand(ModuleInfo, LVarInitialInst0,
- LVarInitialInst),
- LVarInitialInst = ground(_, yes(LVarPredInstInfo))
+ (
+ type_unify_list(LVarArgTypes, UnCurriedArgTypes, [],
+ Substitution0, Substitution1)
->
- LVarPredInstInfo = pred_inst_info(_, LVarArgModes0, _),
- lambda__permute_argvars(LVarArgTypes0, LVarArgModes0,
- ModuleInfo, LVarArgTypes, _LVarArgModes),
- (
- type_unify_list(LVarArgTypes,
- UnCurriedArgTypes, [],
- Substitution0, Substitution1)
- ->
- Substitution2 = Substitution1
- ;
- error("type error in specialized higher-order argument")
- )
+ Substitution2 = Substitution1
;
- error(
- "mode error in specialized higher-order argument"
- )
+ error("type error in specialized higher-order argument")
)
;
error("specialized argument not of higher-order type")
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_goal.m,v
retrieving revision 1.47
diff -u -r1.47 hlds_goal.m
--- hlds_goal.m 1998/01/25 06:05:22 1.47
+++ hlds_goal.m 1998/02/09 00:31:15
@@ -229,8 +229,16 @@
:- type unify_rhs
---> var(var)
; functor(cons_id, list(var))
- ; lambda_goal(pred_or_func, list(var), list(mode), determinism,
- hlds_goal).
+ ; lambda_goal(
+ pred_or_func,
+ list(var), % non-locals of the goal excluding
+ % the lambda quantified variables
+ list(var), % lambda quantified variables
+ list(mode), % modes of the lambda
+ % quantified variables
+ determinism,
+ hlds_goal
+ ).
:- type unification
% A construction unification is a unification with a functor
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_out.m,v
retrieving revision 1.187
diff -u -r1.187 hlds_out.m
--- hlds_out.m 1998/02/05 05:10:37 1.187
+++ hlds_out.m 1998/02/09 00:35:57
@@ -1330,9 +1330,11 @@
;
[]
).
-hlds_out__write_unify_rhs_3(lambda_goal(PredOrFunc, Vars, Modes, Det, Goal),
+hlds_out__write_unify_rhs_3(
+ lambda_goal(PredOrFunc, NonLocals, Vars, Modes, Det, Goal),
ModuleInfo, VarSet, AppendVarnums, Indent, MaybeType, TypeQual)
-->
+ { Indent1 is Indent + 1 },
(
{ PredOrFunc = predicate },
io__write_string("(pred("),
@@ -1340,7 +1342,6 @@
io__write_string(") is "),
mercury_output_det(Det),
io__write_string(" :-\n"),
- { Indent1 is Indent + 1 },
hlds_out__write_goal_a(Goal, ModuleInfo, VarSet, AppendVarnums,
Indent1, "", TypeQual),
hlds_out__write_indent(Indent),
@@ -1358,7 +1359,6 @@
io__write_string(") is "),
mercury_output_det(Det),
io__write_string(" :-\n"),
- { Indent1 is Indent + 1 },
hlds_out__write_goal_a(Goal, ModuleInfo, VarSet, AppendVarnums,
Indent1, "", TypeQual),
hlds_out__write_indent(Indent),
@@ -1369,6 +1369,19 @@
mercury_output_term(Type, TVarSet, no)
;
[]
+ ),
+ globals__io_lookup_string_option(verbose_dump_hlds, Verbose),
+ ( { string__contains_char(Verbose, 'n') } ->
+ ( { NonLocals \= [] } ->
+ hlds_out__write_indent(Indent1),
+ io__write_string("% lambda nonlocals: "),
+ mercury_output_vars(NonLocals, VarSet, AppendVarnums)
+ ;
+ []
+
+ )
+ ;
+ []
).
hlds_out__write_functor(Functor, ArgVars, VarSet, AppendVarnums) -->
@@ -2045,6 +2058,7 @@
{ proc_info_get_maybe_arg_size_info(Proc, MaybeArgSize) },
{ proc_info_get_maybe_termination_info(Proc, MaybeTermination) },
{ proc_info_typeinfo_varmap(Proc, TypeInfoMap) },
+ { proc_info_args_method(Proc, ArgsMethod) },
{ Indent1 is Indent + 1 },
hlds_out__write_indent(Indent1),
@@ -2079,6 +2093,10 @@
hlds_out__write_typeinfo_varmap(Indent, AppendVarnums, TypeInfoMap,
VarSet, TVarSet),
+ io__write_string("% args method: "),
+ hlds_out__write_args_method(ArgsMethod),
+ io__nl,
+
hlds_out__write_indent(Indent),
{ predicate_name(ModuleInfo, PredId, PredName) },
{ varset__init(ModeVarSet) },
@@ -2193,6 +2211,14 @@
io__write_string("model_semi").
hlds_out__write_code_model(model_non) -->
io__write_string("model_non").
+
+:- pred hlds_out__write_args_method(args_method, io__state, io__state).
+:- mode hlds_out__write_args_method(in, di, uo) is det.
+
+hlds_out__write_args_method(simple) -->
+ io__write_string("simple").
+hlds_out__write_args_method(compact) -->
+ io__write_string("compact").
:- pred hlds_out__write_indent(int, io__state, io__state).
:- mode hlds_out__write_indent(in, di, uo) is det.
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_pred.m,v
retrieving revision 1.44
diff -u -r1.44 hlds_pred.m
--- hlds_pred.m 1998/01/25 06:05:24 1.44
+++ hlds_pred.m 1998/02/09 00:59:17
@@ -14,7 +14,7 @@
:- interface.
:- import_module hlds_data, hlds_goal, hlds_module, llds, prog_data, instmap.
-:- import_module purity.
+:- import_module purity, globals.
:- import_module bool, list, map, std_util, term, varset.
:- import_module term_util.
@@ -763,8 +763,11 @@
SymName = qualified(ModuleName, PredName),
map__init(TVarMap), % later, polymorphism.m will fill this in.
map__init(TCVarMap), % later, polymorphism.m will fill this in.
+
+ module_info_globals(ModuleInfo0, Globals),
+ globals__get_args_method(Globals, ArgsMethod),
proc_info_create(VarSet, VarTypes, ArgVars, ArgModes, Detism,
- Goal0, Context, TVarMap, TCVarMap, ProcInfo),
+ Goal0, Context, TVarMap, TCVarMap, ArgsMethod, ProcInfo),
pred_info_create(ModuleName, SymName, TVarSet, ArgTypes, true,
Context, local, Markers, predicate, ClassContext,
ProcInfo, ProcId, PredInfo),
@@ -800,21 +803,22 @@
:- interface.
:- pred proc_info_init(arity, list(mode), maybe(list(mode)),
- maybe(list(is_live)), maybe(determinism), term__context, proc_info).
-:- mode proc_info_init(in, in, in, in, in, in, out) is det.
+ maybe(list(is_live)), maybe(determinism), term__context,
+ args_method, proc_info).
+:- mode proc_info_init(in, in, in, in, in, in, in, out) is det.
:- pred proc_info_set(maybe(determinism), varset, map(var, type), list(var),
list(mode), maybe(list(is_live)), hlds_goal, term__context,
stack_slots, determinism, bool, list(arg_info), liveness_info,
map(tvar, type_info_locn), map(class_constraint, var),
- maybe(arg_size_info), maybe(termination_info), proc_info).
+ maybe(arg_size_info), maybe(termination_info), args_method, proc_info).
:- mode proc_info_set(in, in, in, in, in, in, in, in, in, in, in, in, in, in,
- in, in, in, out) is det.
+ in, in, in, in, out) is det.
:- pred proc_info_create(varset, map(var, type), list(var), list(mode),
determinism, hlds_goal, term__context, map(tvar, type_info_locn),
- map(class_constraint, var), proc_info).
-:- mode proc_info_create(in, in, in, in, in, in, in, in, in, out) is det.
+ map(class_constraint, var), args_method, proc_info).
+:- mode proc_info_create(in, in, in, in, in, in, in, in, in, in, out) is det.
:- pred proc_info_set_body(proc_info, varset, map(var, type), list(var),
hlds_goal, proc_info).
@@ -833,11 +837,18 @@
:- mode proc_info_interface_code_model(in, out) is det.
% proc_info_never_succeeds(ProcInfo, Result):
- % return Result = yes if the procedure is known to never succeed.
+ % return Result = yes if the procedure is known to never succeed
+ % according to the declared determinism.
%
:- pred proc_info_never_succeeds(proc_info, bool).
:- mode proc_info_never_succeeds(in, out) is det.
+ % Same as proc_info_never succeeds, except uses the
+ % inferred determinism. Don't use this before determinism
+ % analysis.
+:- pred proc_info_inferred_never_succeeds(pred_info, proc_id, proc_info, bool).
+:- mode proc_info_inferred_never_succeeds(in, in, in, out) is det.
+
:- pred proc_info_varset(proc_info, varset).
:- mode proc_info_varset(in, out) is det.
@@ -946,6 +957,12 @@
:- pred proc_info_declared_argmodes(proc_info, list(mode)).
:- mode proc_info_declared_argmodes(in, out) is det.
+:- pred proc_info_args_method(proc_info, args_method).
+:- mode proc_info_args_method(in, out) is det.
+
+:- pred proc_info_set_args_method(proc_info, args_method, proc_info).
+:- mode proc_info_set_args_method(in, in, out) is det.
+
% For a set of variables V, find all the type variables in the types
% of the variables in V, and return set of typeinfo variables for
% those type variables. (find all typeinfos for variables in V).
@@ -1017,8 +1034,17 @@
% The termination properties of the
% procedure. Set by termination
% analysis.
- maybe(list(mode))
+ maybe(list(mode)),
% declared modes of arguments.
+ args_method
+ % The args_method to be used for
+ % the procedure. Usually this will
+ % be set to the value of the --args
+ % option stored in the globals.
+ % lambda.m will set this field to
+ % compact for procedures it creates
+ % which must be directly callable by
+ % a higher_order_call goal.
).
% Some parts of the procedure aren't known yet. We initialize
@@ -1029,7 +1055,7 @@
% will later provide the correct inferred determinism for it.
proc_info_init(Arity, Modes, DeclaredModes, MaybeArgLives,
- MaybeDet, MContext, NewProc) :-
+ MaybeDet, MContext, ArgsMethod, NewProc) :-
map__init(BodyTypes),
goal_info_init(GoalInfo),
varset__init(BodyVarSet0),
@@ -1047,33 +1073,33 @@
MaybeDet, BodyVarSet, BodyTypes, HeadVars, Modes, MaybeArgLives,
ClauseBody, MContext, StackSlots, InferredDet, CanProcess,
ArgInfo, InitialLiveness, TVarsMap, TCVarsMap, no, no,
- DeclaredModes
+ DeclaredModes, ArgsMethod
).
proc_info_set(DeclaredDetism, BodyVarSet, BodyTypes, HeadVars, HeadModes,
HeadLives, Goal, Context, StackSlots, InferredDetism,
CanProcess, ArgInfo, Liveness, TVarMap, TCVarsMap,
- ArgSizes, Termination, ProcInfo) :-
+ ArgSizes, Termination, ArgsMethod, ProcInfo) :-
ProcInfo = procedure(
DeclaredDetism, BodyVarSet, BodyTypes, HeadVars, HeadModes,
HeadLives, Goal, Context, StackSlots, InferredDetism,
CanProcess, ArgInfo, Liveness, TVarMap, TCVarsMap,
- ArgSizes, Termination, no).
+ ArgSizes, Termination, no, ArgsMethod).
proc_info_create(VarSet, VarTypes, HeadVars, HeadModes, Detism, Goal,
- Context, TVarMap, TCVarsMap, ProcInfo) :-
+ Context, TVarMap, TCVarsMap, ArgsMethod, ProcInfo) :-
map__init(StackSlots),
set__init(Liveness),
MaybeHeadLives = no,
ProcInfo = procedure(yes(Detism), VarSet, VarTypes, HeadVars, HeadModes,
MaybeHeadLives, Goal, Context, StackSlots, Detism, yes, [],
- Liveness, TVarMap, TCVarsMap, no, no, no).
+ Liveness, TVarMap, TCVarsMap, no, no, no, ArgsMethod).
proc_info_set_body(ProcInfo0, VarSet, VarTypes, HeadVars, Goal, ProcInfo) :-
ProcInfo0 = procedure(A, _, _, _, E, F, _,
- H, I, J, K, L, M, N, O, P, Q, R),
+ H, I, J, K, L, M, N, O, P, Q, R, S),
ProcInfo = procedure(A, VarSet, VarTypes, HeadVars, E, F, Goal,
- H, I, J, K, L, M, N, O, P, Q, R).
+ H, I, J, K, L, M, N, O, P, Q, R, S).
proc_info_interface_determinism(ProcInfo, Determinism) :-
proc_info_declared_determinism(ProcInfo, MaybeDeterminism),
@@ -1105,6 +1131,31 @@
)
).
+proc_info_inferred_never_succeeds(PredInfo, ProcId, ProcInfo, Result) :-
+ (
+ % We don't infer determinism for imported procedures
+ % or for class_method predicates.
+ (
+ pred_info_is_imported(PredInfo)
+ ;
+ pred_info_is_pseudo_imported(PredInfo),
+ hlds_pred__in_in_unification_proc_id(ProcId)
+ ;
+ pred_info_get_markers(PredInfo, Markers),
+ check_marker(Markers, class_method)
+ )
+ ->
+ proc_info_interface_determinism(ProcInfo, Determinism)
+ ;
+ proc_info_inferred_determinism(ProcInfo, Determinism)
+ ),
+ determinism_components(Determinism, _, HowMany),
+ ( HowMany = at_most_zero ->
+ Result = yes
+ ;
+ Result = no
+ ).
+
proc_info_arglives(ProcInfo, ModuleInfo, ArgLives) :-
proc_info_maybe_arglives(ProcInfo, MaybeArgLives),
( MaybeArgLives = yes(ArgLives0) ->
@@ -1130,58 +1181,80 @@
).
proc_info_declared_determinism(ProcInfo, A) :-
- ProcInfo = procedure(A, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(A, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_varset(ProcInfo, B) :-
- ProcInfo = procedure(_, B, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, B, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_vartypes(ProcInfo, C) :-
- ProcInfo = procedure(_, _, C, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, C, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_headvars(ProcInfo, D) :-
- ProcInfo = procedure(_, _, _, D, _, _, _, _, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, D, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_argmodes(ProcInfo, E) :-
- ProcInfo = procedure(_, _, _, _, E, _, _, _, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, E, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_maybe_arglives(ProcInfo, F) :-
- ProcInfo = procedure(_, _, _, _, _, F, _, _, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, F, _, _, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_goal(ProcInfo, G) :-
- ProcInfo = procedure(_, _, _, _, _, _, G, _, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, G, _, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_context(ProcInfo, H) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, H, _, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, H, _,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_stack_slots(ProcInfo, I) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, I, _, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, I,
+ _, _, _, _, _, _, _, _, _, _).
proc_info_inferred_determinism(ProcInfo, J) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, J, _, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ J, _, _, _, _, _, _, _, _, _).
proc_info_can_process(ProcInfo, K) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, K, _, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, K, _, _, _, _, _, _, _, _).
proc_info_arg_info(ProcInfo, L) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, _, L, _, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, L, _, _, _, _, _, _, _).
proc_info_liveness_info(ProcInfo, M) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, _, _, M, _, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, _, M, _, _, _, _, _, _).
proc_info_typeinfo_varmap(ProcInfo, N) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, _, _, _, N, _, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, _, _, N, _, _, _, _, _).
proc_info_typeclass_info_varmap(ProcInfo, O) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, _, _, _, _, O, _, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, O, _, _, _, _).
proc_info_get_maybe_arg_size_info(ProcInfo, P) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P, _, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, P, _, _, _).
proc_info_get_maybe_termination_info(ProcInfo, Q) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, Q, _).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, Q, _, _).
proc_info_maybe_declared_argmodes(ProcInfo, R) :-
- ProcInfo = procedure(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, R).
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, R, _).
+
+proc_info_args_method(ProcInfo, S) :-
+ ProcInfo = procedure(_, _, _, _, _, _, _, _, _,
+ _, _, _, _, _, _, _, _, _, S).
% :- type proc_info
% ---> procedure(
@@ -1231,67 +1304,112 @@
% % analysis.
% R maybe(list(mode))
% % declared modes of arguments.
-% ).
+% S args_method
+% % The args_method to be used for
+% % the procedure. Usually this will
+% % be set to the value of the --args
+% % option stored in the globals.
+% % lambda.m will set this field to
+% % compact for procedures it creates
+% % which must be directly callable by
+% % a higher_order_call goal.
+% ).
proc_info_set_varset(ProcInfo0, B, ProcInfo) :-
- ProcInfo0 = procedure(A, _, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, _, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_vartypes(ProcInfo0, C, ProcInfo) :-
- ProcInfo0 = procedure(A, B, _, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, _, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_headvars(ProcInfo0, D, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, _, E, F, G, H, I, J, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, _, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_argmodes(ProcInfo0, E, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, _, F, G, H, I, J, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, _, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_maybe_arglives(ProcInfo0, F, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, _, G, H, I, J, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, _, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_goal(ProcInfo0, G, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, _, H, I, J, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, _, H, I,
+ J, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_stack_slots(ProcInfo0, I, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, _, J, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, _,
+ J, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_inferred_determinism(ProcInfo0, J, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, _, K, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ _, K, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_can_process(ProcInfo0, K, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, _, L, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, _, L, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_arg_info(ProcInfo0, L, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, _, M, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, _, M, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_liveness_info(ProcInfo0, M, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, L, _, N, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, _, N, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_typeinfo_varmap(ProcInfo0, N, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, _, O, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, _, O, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_typeclass_info_varmap(ProcInfo0, O, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, _, P, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, _, P, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_maybe_arg_size_info(ProcInfo0, P, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, _, Q, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, _, Q, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_set_maybe_termination_info(ProcInfo0, Q, ProcInfo) :-
- ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, _, R),
- ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R).
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, _, R, S),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
+
+proc_info_set_args_method(ProcInfo0, S, ProcInfo) :-
+ ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, _),
+ ProcInfo = procedure(A, B, C, D, E, F, G, H, I,
+ J, K, L, M, N, O, P, Q, R, S).
proc_info_get_typeinfo_vars_setwise(ProcInfo, Vars, TypeInfoVars) :-
set__to_sorted_list(Vars, VarList),
Index: compiler/intermod.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/intermod.m,v
retrieving revision 1.43
diff -u -r1.43 intermod.m
--- intermod.m 1998/01/24 07:51:55 1.43
+++ intermod.m 1998/02/06 01:22:15
@@ -499,8 +499,8 @@
intermod_info::out) is det.
intermod__module_qualify_unify_rhs(_, var(Var), var(Var), yes) --> [].
-intermod__module_qualify_unify_rhs(_LVar, lambda_goal(A,B,Modes,D,Goal0),
- lambda_goal(A,B,Modes,D,Goal), DoWrite) -->
+intermod__module_qualify_unify_rhs(_LVar, lambda_goal(A,B,C,Modes,E,Goal0),
+ lambda_goal(A,B,C,Modes,E,Goal), DoWrite) -->
intermod__traverse_goal(Goal0, Goal, DoWrite),
intermod_info_get_module_info(ModuleInfo),
{ module_info_modes(ModuleInfo, ModeTable) },
Index: compiler/lambda.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/lambda.m,v
retrieving revision 1.38
diff -u -r1.38 lambda.m
--- lambda.m 1998/01/29 13:28:24 1.38
+++ lambda.m 1998/02/09 00:59:35
@@ -41,33 +41,28 @@
:- interface.
:- import_module hlds_module, hlds_pred, prog_data.
-:- import_module list, set, map, term, varset.
+:- import_module list, map, term, varset.
:- pred lambda__process_pred(pred_id, module_info, module_info).
:- mode lambda__process_pred(in, in, out) is det.
:- pred lambda__transform_lambda(pred_or_func, string, list(var), list(mode),
- determinism, set(var), hlds_goal, unification,
+ determinism, list(var), hlds_goal, unification,
varset, map(var, type), list(class_constraint), tvarset,
map(tvar, type_info_locn), map(class_constraint, var),
module_info, unify_rhs, unification, module_info).
:- mode lambda__transform_lambda(in, in, in, in, in, in, in, in, in, in, in, in,
in, in, in, out, out, out) is det.
- % Permute the list of variables so that inputs come before outputs.
-:- pred lambda__permute_argvars(list(Var), list(mode), module_info,
- list(Var), list(mode)).
-:- mode lambda__permute_argvars(in, in, in, out, out) is det.
-
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module hlds_goal, hlds_data, make_hlds.
-:- import_module prog_util, mode_util, inst_match, llds.
+:- import_module prog_util, mode_util, inst_match, llds, arg_info.
-:- import_module bool, string, std_util, require.
+:- import_module bool, set, string, std_util, require.
:- type lambda_info --->
lambda_info(
@@ -168,13 +163,13 @@
lambda__process_goal_2(unify(XVar, Y, Mode, Unification, Context), GoalInfo,
Unify - GoalInfo) -->
- ( { Y = lambda_goal(PredOrFunc, Vars, Modes, Det, LambdaGoal0) } ->
+ ( { Y = lambda_goal(PredOrFunc, NonLocalVars, Vars,
+ Modes, Det, LambdaGoal0) } ->
% for lambda expressions, we must convert the lambda expression
% into a new predicate
- { LambdaGoal0 = _ - GoalInfo0 },
- { goal_info_get_nonlocals(GoalInfo0, NonLocals0) },
- lambda__process_lambda(PredOrFunc, Vars, Modes, Det, NonLocals0,
- LambdaGoal0, Unification, Y1, Unification1),
+ lambda__process_lambda(PredOrFunc, Vars, Modes, Det,
+ NonLocalVars, LambdaGoal0,
+ Unification, Y1, Unification1),
{ Unify = unify(XVar, Y1, Mode, Unification1, Context) }
;
% ordinary unifications are left unchanged
@@ -234,7 +229,7 @@
lambda__process_cases(Cases0, Cases).
:- pred lambda__process_lambda(pred_or_func, list(var), list(mode), determinism,
- set(var), hlds_goal, unification, unify_rhs, unification,
+ list(var), hlds_goal, unification, unify_rhs, unification,
lambda_info, lambda_info).
:- mode lambda__process_lambda(in, in, in, in, in, in, in, out, out,
in, out) is det.
@@ -251,14 +246,14 @@
TVarMap, TCVarMap, POF, PredName, ModuleInfo).
lambda__transform_lambda(PredOrFunc, OrigPredName, Vars, Modes, Detism,
- OrigNonLocals0, LambdaGoal, Unification0, VarSet, VarTypes,
+ OrigVars, LambdaGoal, Unification0, VarSet, VarTypes,
Constraints, TVarSet, TVarMap, TCVarMap, ModuleInfo0, Functor,
Unification, ModuleInfo) :-
(
Unification0 = construct(Var0, _, _, UniModes0)
->
Var = Var0,
- UniModes = UniModes0
+ UniModes1 = UniModes0
;
error("polymorphism__transform_lambda: weird unification")
),
@@ -280,6 +275,14 @@
(
LambdaGoal = call(PredId0, ProcId0, CallVars,
_, _, PredName0) - _,
+ module_info_pred_proc_info(ModuleInfo0, PredId0, ProcId0, _,
+ Call_ProcInfo),
+
+ % check that this procedure uses an args_method which
+ % is always directly higher-order callable.
+ proc_info_args_method(Call_ProcInfo, Call_ArgsMethod),
+ arg_info__ho_callable_args_method(Call_ArgsMethod),
+
list__remove_suffix(CallVars, Vars, InitialVars),
% check that none of the variables that we're trying to
@@ -289,8 +292,6 @@
list__member(InitialVar, Vars)
),
- module_info_pred_proc_info(ModuleInfo0, PredId0, ProcId0, _,
- Call_ProcInfo),
proc_info_interface_code_model(Call_ProcInfo, Call_CodeModel),
determinism_to_code_model(Detism, CodeModel),
% Check that the code models are compatible.
@@ -304,28 +305,24 @@
% check that the curried arguments are all input
proc_info_argmodes(Call_ProcInfo, Call_ArgModes),
list__length(InitialVars, NumInitialVars),
- list__split_list(NumInitialVars, Call_ArgModes,
- CurriedArgModes, UncurriedArgModes),
+ list__take(NumInitialVars, Call_ArgModes, CurriedArgModes),
\+ ( list__member(Mode, CurriedArgModes),
\+ mode_is_input(ModuleInfo0, Mode)
- ),
- % and that all the inputs precede the outputs
- inputs_precede_outputs(UncurriedArgModes, ModuleInfo0)
+ )
->
ArgVars = InitialVars,
PredId = PredId0,
ProcId = ProcId0,
PredName = PredName0,
ModuleInfo = ModuleInfo0,
- NumArgVars = NumInitialVars
+ NumArgVars = NumInitialVars,
+ mode_util__modes_to_uni_modes(CurriedArgModes, CurriedArgModes,
+ ModuleInfo0, UniModes)
;
% Prepare to create a new predicate for the lambda
% expression: work out the arguments, module name, predicate
% name, arity, arg types, determinism,
- % context, status, etc. for the new predicate,
- % and permute the arguments so that all inputs come before
- % all outputs. (When the predicate is called, the arguments
- % will be similarly permuted, so they will match up.)
+ % context, status, etc. for the new predicate.
ArgVars = ArgVars1,
list__append(ArgVars, Vars, AllArgVars),
@@ -340,12 +337,12 @@
goal_info_get_context(LambdaGoalInfo, LambdaContext),
% the TVarSet is a superset of what it really ought be,
% but that shouldn't matter
- lambda__uni_modes_to_modes(UniModes, OrigArgModes),
+ lambda__uni_modes_to_modes(UniModes1, OrigArgModes),
% We have to jump through hoops to work out the mode
% of the lambda predicate. For introduced
% type_info arguments, we use the mode "in". For the original
- % non-local vars, we use the modes from `UniModes'.
+ % non-local vars, we use the modes from `UniModes1'.
% For the lambda var arguments at the end,
% we use the mode in the lambda expression.
@@ -355,29 +352,36 @@
map__from_corresponding_lists(ArgVars, InModes,
ArgModesMap),
- set__delete_list(OrigNonLocals0, Vars, OrigNonLocals),
- set__to_sorted_list(OrigNonLocals, OrigArgVars),
- map__from_corresponding_lists(OrigArgVars, OrigArgModes,
+ map__from_corresponding_lists(OrigVars, OrigArgModes,
OrigArgModesMap),
map__overlay(ArgModesMap, OrigArgModesMap, ArgModesMap1),
map__values(ArgModesMap1, ArgModes1),
+ % Recompute the uni_modes.
+ mode_util__modes_to_uni_modes(ArgModes1, ArgModes1,
+ ModuleInfo1, UniModes),
+
list__append(ArgModes1, Modes, AllArgModes),
+ map__apply_to_list(AllArgVars, VarTypes, ArgTypes),
- % Even after we've done all that, we still need to
- % permute the argument variables so that all the inputs
- % come before all the outputs.
-
- lambda__permute_argvars(AllArgVars, AllArgModes, ModuleInfo1,
- PermutedArgVars, PermutedArgModes),
- map__apply_to_list(PermutedArgVars, VarTypes, ArgTypes),
+ % Choose an args_method which is always directly ho_callable
+ % even if the inputs don't preceed the outputs in the
+ % declaration. mercury_ho_call.c requires that
+ % procedures which are directly higher-order-called use
+ % the compact args_method.
+ %
+ % Previously we permuted the argument variables so that
+ % inputs came before outputs, but that resulted in the
+ % HLDS not being type or mode correct which caused problems
+ % for some transformations and for rerunning mode analysis.
+ arg_info__ho_callable_args_method(ArgsMethod),
% Now construct the proc_info and pred_info for the new
% single-mode predicate, using the information computed above
- proc_info_create(VarSet, VarTypes, PermutedArgVars,
- PermutedArgModes, Detism, LambdaGoal, LambdaContext,
- TVarMap, TCVarMap, ProcInfo),
+ proc_info_create(VarSet, VarTypes, AllArgVars,
+ AllArgModes, Detism, LambdaGoal, LambdaContext,
+ TVarMap, TCVarMap, ArgsMethod, ProcInfo),
init_markers(Markers),
pred_info_create(ModuleName, PredName, TVarSet, ArgTypes,
@@ -423,66 +427,6 @@
UniMode = ((_Initial0 - Initial1) -> (_Final0 - _Final1)),
Mode = (Initial1 -> Initial1),
lambda__uni_modes_to_modes(UniModes, Modes).
-
-:- pred inputs_precede_outputs(list(mode), module_info).
-:- mode inputs_precede_outputs(in, in) is semidet.
-
- % succeed iff all the inputs in the list of modes precede the outputs
-
-inputs_precede_outputs([], _).
-inputs_precede_outputs([Mode | Modes], ModuleInfo) :-
- ( mode_is_input(ModuleInfo, Mode) ->
- inputs_precede_outputs(Modes, ModuleInfo)
- ;
- % the following is an if-then-else rather than a
- % negation purely because the compiler got an internal
- % error compiling it when it was a negation
- (
- list__member(OtherMode, Modes),
- mode_is_input(ModuleInfo, OtherMode)
- ->
- fail
- ;
- true
- )
- ).
-
- % permute a list of variables and a corresponding list of their modes
- % so that all the input variables precede all the output variables.
-
-lambda__permute_argvars(AllArgVars, AllArgModes, ModuleInfo,
- PermutedArgVars, PermutedArgModes) :-
- ( split_argvars(AllArgVars, AllArgModes, ModuleInfo,
- InArgVars, InArgModes, OutArgVars, OutArgModes) ->
- list__append(InArgVars, OutArgVars, PermutedArgVars),
- list__append(InArgModes, OutArgModes, PermutedArgModes)
- ;
- error("lambda__permute_argvars: split_argvars failed")
- ).
-
-:- pred split_argvars(list(Var), list(mode), module_info,
- list(Var), list(mode), list(Var), list(mode)).
-:- mode split_argvars(in, in, in, out, out, out, out) is semidet.
-
- % split a list of variables and a corresponding list of their modes
- % into the input vars/modes and the output vars/modes.
-
-split_argvars([], [], _, [], [], [], []).
-split_argvars([Var|Vars], [Mode|Modes], ModuleInfo,
- InVars, InModes, OutVars, OutModes) :-
- split_argvars(Vars, Modes, ModuleInfo,
- InVars0, InModes0, OutVars0, OutModes0),
- ( mode_is_input(ModuleInfo, Mode) ->
- InVars = [Var|InVars0],
- InModes = [Mode|InModes0],
- OutVars = OutVars0,
- OutModes = OutModes0
- ;
- InVars = InVars0,
- InModes = InModes0,
- OutVars = [Var|OutVars0],
- OutModes = [Mode|OutModes0]
- ).
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
More information about the developers
mailing list