for review: make HLDS mostly well-moded

Simon Taylor stayl at cs.mu.OZ.AU
Mon Feb 9 12:30:35 AEDT 1998


Hi Fergus,

Could you please review this.


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]
-	).
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.260
diff -u -r1.260 make_hlds.m
--- make_hlds.m	1998/02/04 07:17:36	1.260
+++ make_hlds.m	1998/02/07 15:10:41
@@ -43,8 +43,8 @@
 
 :- pred add_new_proc(pred_info, arity, list(mode), maybe(list(mode)),
 		maybe(list(is_live)), maybe(determinism),
-		term__context, pred_info, proc_id).
-:- mode add_new_proc(in, in, in, in, in, in, in, out, out) is det.
+		term__context, args_method, pred_info, proc_id).
+:- mode add_new_proc(in, in, in, in, in, in, in, in, out, out) is det.
 
 :- pred clauses_info_init(int::in, clauses_info::out) is det.
 
@@ -408,7 +408,7 @@
 			FuncName, Arity, PredIds) }
 	->
 		{ predicate_table_get_preds(PredTable0, Preds0) },
-		{ maybe_add_default_modes(PredIds, Preds0, Preds) },
+		{ maybe_add_default_modes(Module0, PredIds, Preds0, Preds) },
 		{ predicate_table_set_preds(PredTable0, Preds, PredTable) },
 		{ module_info_set_predicate_table(Module0, PredTable, Module) }
 	;
@@ -1398,7 +1398,8 @@
 				Func, FuncArity, [PredId])
 		->
 			module_info_pred_info(Module0, PredId, PredInfo0),
-			maybe_add_default_mode(PredInfo0, PredInfo, MaybeProc),
+			maybe_add_default_mode(Module0, PredInfo0, 
+				PredInfo, MaybeProc),
 			(
 				MaybeProc = no,
 				PredProcIds1 = PredProcIds0,
@@ -1683,8 +1684,10 @@
 		Context, ClausesInfo0, Status, Markers, none, predicate, 
 		ClassContext, Proofs, PredInfo0),
 	ArgLives = no,
+	module_info_globals(Module0, Globals),
+	globals__get_args_method(Globals, ArgsMethod),
 	add_new_proc(PredInfo0, Arity, ArgModes, yes(ArgModes),
-		ArgLives, yes(Det), Context, PredInfo, _),
+		ArgLives, yes(Det), Context, ArgsMethod, PredInfo, _),
 
 	module_info_get_predicate_table(Module0, PredicateTable0),
 	predicate_table_insert(PredicateTable0, PredInfo, may_be_unqualified, 
@@ -1723,12 +1726,12 @@
 		Status = Status1
 	).
 
-add_new_proc(PredInfo0, Arity, ArgModes, MaybeDeclaredArgModes,
-		MaybeArgLives, MaybeDet, Context, PredInfo, ModeId) :-
+add_new_proc(PredInfo0, Arity, ArgModes, MaybeDeclaredArgModes, MaybeArgLives, 
+		MaybeDet, Context, ArgsMethod, PredInfo, ModeId) :-
 	pred_info_procedures(PredInfo0, Procs0),
 	next_mode_id(Procs0, MaybeDet, ModeId),
 	proc_info_init(Arity, ArgModes, MaybeDeclaredArgModes, MaybeArgLives,
-		MaybeDet, Context, NewProc),
+		MaybeDet, Context, ArgsMethod, NewProc),
 	map__det_insert(Procs0, ModeId, NewProc, Procs),
 	pred_info_set_procedures(PredInfo0, Procs, PredInfo).
 
@@ -1803,8 +1806,9 @@
 
 		% add the mode declaration to the pred_info for this procedure.
 	{ ArgLives = no },
+	globals__io_get_args_method(ArgsMethod),
 	{ add_new_proc(PredInfo0, Arity, Modes, yes(Modes), ArgLives,
-			MaybeDet, MContext, PredInfo, ProcId) },
+			MaybeDet, MContext, ArgsMethod, PredInfo, ProcId) },
 	{ map__det_update(Preds0, PredId, PredInfo, Preds) },
 	{ predicate_table_set_preds(PredicateTable1, Preds, PredicateTable) },
 	{ module_info_set_predicate_table(ModuleInfo0, PredicateTable,
@@ -1962,7 +1966,7 @@
 		{
 		pred_info_clauses_info(PredInfo1, Clauses0),
 		pred_info_typevarset(PredInfo1, TVarSet0),
-		maybe_add_default_mode(PredInfo1, PredInfo2, _),
+		maybe_add_default_mode(ModuleInfo0, PredInfo1, PredInfo2, _),
 		pred_info_procedures(PredInfo2, Procs),
 		map__keys(Procs, ModeIds)
 		},
@@ -2801,8 +2805,8 @@
 	warn_singletons([X | Vars], NonLocals, QuantVars, VarSet,
 			Context, CallPredId).
 
-warn_singletons_in_unify(X, lambda_goal(_PredOrFunc, LambdaVars, _Modes, _Det,
-				LambdaGoal),
+warn_singletons_in_unify(X, lambda_goal(_PredOrFunc, _NonLocals, LambdaVars, 
+				_Modes, _Det, LambdaGoal),
 			GoalInfo, QuantVars, VarSet, CallPredId, MI) -->
 	%
 	% warn if any lambda-quantified variables occur only in the quantifier
@@ -3695,8 +3699,16 @@
 				HLDS_Goal0, VarSet3, Info1, Info2),
 		insert_arg_unifications(Vars, Vars1, Context, head, no,
 			HLDS_Goal0, VarSet3, HLDS_Goal, VarSet, Info2, Info),
+
+			 % quantification will reduce this down to
+			 % the proper set of nonlocal arguments.
+		{ goal_util__goal_vars(HLDS_Goal, LambdaGoalVars0) }, 
+		{ set__delete_list(LambdaGoalVars0, Vars, LambdaGoalVars1) },
+		{ set__to_sorted_list(LambdaGoalVars1, LambdaNonLocals) },
+
 		{ create_atomic_unification(X,
-			lambda_goal(predicate, Vars, Modes, Det, HLDS_Goal),
+			lambda_goal(predicate, LambdaNonLocals, Vars, 
+				Modes, Det, HLDS_Goal),
 			Context, MainContext, SubContext, Goal) }
 	;
 	    {
@@ -3723,8 +3735,16 @@
 			HLDS_Goal0, VarSet3, Info1, Info2),
 		insert_arg_unifications(Vars, Vars1, Context, head, no,
 			HLDS_Goal0, VarSet3, HLDS_Goal, VarSet, Info2, Info),
+
+			 % quantification will reduce this down to
+			 % the proper set of nonlocal arguments.
+		{ goal_util__goal_vars(HLDS_Goal, LambdaGoalVars0) }, 
+		{ set__delete_list(LambdaGoalVars0, Vars, LambdaGoalVars1) },
+		{ set__to_sorted_list(LambdaGoalVars1, LambdaNonLocals) },
+
 		{ create_atomic_unification(X,
-		lambda_goal(predicate, Vars, Modes, Det, HLDS_Goal),
+			lambda_goal(predicate, LambdaNonLocals, Vars, 
+				Modes, Det, HLDS_Goal),
 			Context, MainContext, SubContext, Goal) }
 	;
 	    {
@@ -3754,8 +3774,16 @@
 				HLDS_Goal0, VarSet3, Info1, Info2),
 		insert_arg_unifications(Vars, Vars1, Context, head, no,
 			HLDS_Goal0, VarSet3, HLDS_Goal, VarSet, Info2, Info),
+
+			 % quantification will reduce this down to
+			 % the proper set of nonlocal arguments.
+		{ goal_util__goal_vars(HLDS_Goal, LambdaGoalVars0) }, 
+		{ set__delete_list(LambdaGoalVars0, Vars, LambdaGoalVars1) },
+		{ set__to_sorted_list(LambdaGoalVars1, LambdaNonLocals) },
+
 		{ create_atomic_unification(X,
-			lambda_goal(function, Vars, Modes, Det, HLDS_Goal),
+			lambda_goal(function, LambdaNonLocals, Vars, 
+				Modes, Det, HLDS_Goal),
 			Context, MainContext, SubContext, Goal) }
 	;
 	        % handle if-then-else expressions
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_compile.m,v
retrieving revision 1.74
diff -u -r1.74 mercury_compile.m
--- mercury_compile.m	1998/01/25 06:05:28	1.74
+++ mercury_compile.m	1998/02/08 04:26:57
@@ -1460,8 +1460,7 @@
 mercury_compile__map_args_to_regs(HLDS0, Verbose, Stats, HLDS) -->
 	maybe_write_string(Verbose, "% Mapping args to regs..."),
 	maybe_flush_output(Verbose),
-	globals__io_get_args_method(Args),
-	{ generate_arg_info(HLDS0, Args, HLDS) },
+	{ generate_arg_info(HLDS0, HLDS) },
 	maybe_write_string(Verbose, " done.\n"),
 	maybe_report_stats(Stats).
 
Index: compiler/mode_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mode_util.m,v
retrieving revision 1.104
diff -u -r1.104 mode_util.m
--- mode_util.m	1998/01/13 10:12:57	1.104
+++ mode_util.m	1998/02/06 01:22:16
@@ -1263,17 +1263,16 @@
 				ModuleInfo1)
 		->
 			ModuleInfo2 = ModuleInfo1,
-			Mode = (ArgInst0 -> UnifyInst),
-			recompute_instmap_delta_call_2(Args, InstMap,
-				Modes0, Modes, ModuleInfo2, ModuleInfo)
+			Mode = (ArgInst0 -> UnifyInst)
 		;
 			error("recompute_instmap_delta_call_2: unify_inst failed")
 		)
 	;
 		Mode = (not_reached -> not_reached),
-		Modes = [],
-		ModuleInfo = ModuleInfo0
-	).
+		ModuleInfo2 = ModuleInfo0
+	),
+	recompute_instmap_delta_call_2(Args, InstMap,
+		Modes0, Modes, ModuleInfo2, ModuleInfo).
 
 :- pred recompute_instmap_delta_unify(unification, unify_mode, unify_mode,
 	hlds_goal_info, instmap, instmap_delta, module_info, module_info).
Index: compiler/modecheck_call.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modecheck_call.m,v
retrieving revision 1.22
diff -u -r1.22 modecheck_call.m
--- modecheck_call.m	1998/02/03 07:03:10	1.22
+++ modecheck_call.m	1998/02/06 01:22:15
@@ -173,7 +173,7 @@
 	mode_info_get_preds(ModeInfo0, Preds),
 	mode_info_get_module_info(ModeInfo0, ModuleInfo),
 	map__lookup(Preds, PredId, PredInfo0),
-	maybe_add_default_mode(PredInfo0, PredInfo, _),
+	maybe_add_default_mode(ModuleInfo, PredInfo0, PredInfo, _),
 	pred_info_procedures(PredInfo, Procs),
 	map__keys(Procs, ProcIds),
 	pred_info_get_markers(PredInfo, Markers),
Index: compiler/modecheck_unify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.27
diff -u -r1.27 modecheck_unify.m
--- modecheck_unify.m	1998/01/30 06:12:52	1.27
+++ modecheck_unify.m	1998/02/09 01:17:02
@@ -258,8 +258,20 @@
 		module_info_pred_info(ModuleInfo0, ThisPredId, ThisPredInfo),
 		pred_info_typevarset(ThisPredInfo, TVarSet),
 		map__apply_to_list(Args, VarTypes, ArgTypes),
-		get_pred_id_and_proc_id(PName, PredOrFunc, TVarSet, ArgTypes,
-			ModuleInfo0, PredId, ProcId),
+		(
+			% If we are redoing mode analysis, use the
+			% pred_id and proc_id found before, to avoid aborting
+			% in get_pred_id_and_proc_id if there are multiple
+			% matching procedures.
+			Unification0 = construct(_, 
+				pred_const(PredId0, ProcId0), _, _)
+		->
+			PredId = PredId0,
+			ProcId = ProcId0
+		;
+			get_pred_id_and_proc_id(PName, PredOrFunc, TVarSet, 
+				ArgTypes, ModuleInfo0, PredId, ProcId)
+		),
 		module_info_pred_proc_info(ModuleInfo0, PredId, ProcId,
 					PredInfo, ProcInfo),
 
@@ -310,8 +322,8 @@
 		% construct the lambda expression, and then go ahead
 		% and modecheck this unification in its new form
 		%
-		Functor0 = lambda_goal(PredOrFunc, LambdaVars, LambdaModes,
-					LambdaDet, LambdaGoal),
+		Functor0 = lambda_goal(PredOrFunc, ArgVars0, LambdaVars, 
+				LambdaModes, LambdaDet, LambdaGoal),
 		modecheck_unification( X0, Functor0, Unification0, UnifyContext,
 				GoalInfo0, HowToCheckGoal, Goal,
 				ModeInfo2, ModeInfo)
@@ -326,10 +338,11 @@
 			Goal, ModeInfo0, ModeInfo)
 	).
 
-modecheck_unification(X, lambda_goal(PredOrFunc, Vars, Modes0, Det, Goal0),
-			Unification0, UnifyContext, _GoalInfo, HowToCheckGoal,
-			unify(X, RHS, Mode, Unification, UnifyContext),
-			ModeInfo0, ModeInfo) :-
+modecheck_unification(X, 
+		lambda_goal(PredOrFunc, ArgVars, Vars, Modes0, Det, Goal0),
+		Unification0, UnifyContext, _GoalInfo, HowToCheckGoal,
+		unify(X, RHS, Mode, Unification, UnifyContext),
+		ModeInfo0, ModeInfo) :-
 	%
 	% First modecheck the lambda goal itself:
 	%
@@ -408,20 +421,20 @@
 	% Now modecheck the unification of X with the lambda-expression.
 	%
  
-	set__to_sorted_list(NonLocals, ArgVars),
+	RHS0 = lambda_goal(PredOrFunc, ArgVars, Vars, Modes, Det, Goal),
 	modecheck_unify_lambda(X, PredOrFunc, ArgVars, Modes,
-			Det, Unification0, Mode, Unification,
-			ModeInfo10, ModeInfo),
-	RHS = lambda_goal(PredOrFunc, Vars, Modes, Det, Goal).
+			Det, RHS0, Unification0, Mode, RHS, Unification,
+			ModeInfo10, ModeInfo).
 
 :- pred modecheck_unify_lambda(var, pred_or_func, list(var),
-			list(mode), determinism, unification,
-			pair(mode), unification, mode_info, mode_info).
-:- mode modecheck_unify_lambda(in, in, in, in, in, in,
-			out, out, mode_info_di, mode_info_uo) is det.
-
-modecheck_unify_lambda(X, PredOrFunc, ArgVars, LambdaModes, LambdaDet,
-		Unification0, Mode, Unification, ModeInfo0, ModeInfo) :-
+		list(mode), determinism, unify_rhs, unification,
+		pair(mode), unify_rhs, unification, mode_info, mode_info).
+:- mode modecheck_unify_lambda(in, in, in, in, in, in, in,
+			out, out, out, mode_info_di, mode_info_uo) is det.
+
+modecheck_unify_lambda(X, PredOrFunc, ArgVars, LambdaModes, 
+		LambdaDet, RHS0, Unification0, Mode, RHS, Unification, 
+		ModeInfo0, ModeInfo) :-
 	mode_info_get_module_info(ModeInfo0, ModuleInfo0),
 	mode_info_get_instmap(ModeInfo0, InstMap0),
 	instmap__lookup_var(InstMap0, X, InstOfX),
@@ -442,8 +455,8 @@
 		inst_lists_to_mode_list(ArgInsts, ArgInsts, ArgModes),
 		categorize_unify_var_lambda(ModeOfX, ArgModes,
 				X, ArgVars, PredOrFunc,
-				Unification0, ModeInfo1,
-				Unification, ModeInfo2),
+				RHS0, Unification0, ModeInfo1,
+				RHS, Unification, ModeInfo2),
 		modecheck_set_var_inst(X, Inst, ModeInfo2, ModeInfo)
 	;
 		set__list_to_set([X], WaitingVars),
@@ -462,7 +475,8 @@
 		ModeOfY = (InstOfY -> Inst),
 		Mode = ModeOfX - ModeOfY,
 			% return any old garbage
-		Unification = Unification0
+		Unification = Unification0,
+		RHS = RHS0
 	).
 
 :- pred modecheck_unify_functor(var, (type), cons_id, list(var), unification,
@@ -626,14 +640,16 @@
 		%
 		% modecheck_unification sometimes needs to introduce
 		% new goals to handle complicated sub-unifications
-		% in deconstructions.  But this should never happen
-		% during unique mode analysis.
-		% (If it did, the code would be wrong since it
+		% in deconstructions. The only time this can happen
+		% during unique mode analysis is if the instmap is 
+		% unreachable, since inst_is_bound succeeds for not_reached.
+		% (If it did in other cases, the code would be wrong since it
 		% wouldn't have the correct determinism annotations.)
 		%
 		(
 			HowToCheckGoal = check_unique_modes,
-			ExtraGoals \= no_extra_goals
+			ExtraGoals \= no_extra_goals,
+			instmap__is_reachable(InstMap0)
 		->
 			error("unique_modes.m: re-modecheck of unification encountered complicated sub-unifies")
 		;
@@ -826,22 +842,30 @@
 			determinism_components(Det, CanFail, _),
 			UniMode = ((IX - IY) -> (FX - FY)),
 			Unification = complicated_unify(UniMode, CanFail),
+			mode_info_get_instmap(ModeInfo0, InstMap0),
 			(
 				type_is_higher_order(Type, PredOrFunc, _)
 			->
-				% we do not want to report this as an error
+				% We do not want to report this as an error
 				% if it occurs in a compiler-generated
 				% predicate - instead, we delay the error
 				% until runtime so that it only occurs if
-				% the compiler-generated predicate gets called
+				% the compiler-generated predicate gets called.
+				% We don't report an error if the instmap is
+				% unreachable since not_reached counts
+				% as bound.
 				mode_info_get_predid(ModeInfo0, PredId),
 				module_info_pred_info(ModuleInfo0, PredId,
 						PredInfo),
-				( code_util__compiler_generated(PredInfo) ->
-					ModeInfo = ModeInfo0
+				( 
+				    ( code_util__compiler_generated(PredInfo) 
+				    ; instmap__is_unreachable(InstMap0)
+				    )
+				->
+				    ModeInfo = ModeInfo0
 				;
-					set__init(WaitingVars),
-					mode_info_error(WaitingVars,
+				    set__init(WaitingVars),
+				    mode_info_error(WaitingVars,
 			mode_error_unify_pred(X, error_at_var(Y), Type, PredOrFunc),
 						ModeInfo0, ModeInfo)
 				)
@@ -901,14 +925,16 @@
 % be deterministic or semideterministic.
 
 :- pred categorize_unify_var_lambda(mode, list(mode),
-			var, list(var), pred_or_func,
-			unification, mode_info, unification, mode_info).
-:- mode categorize_unify_var_lambda(in, in, in, in, in,
-			in, mode_info_di, out, mode_info_uo) is det.
-
-categorize_unify_var_lambda(ModeOfX, ArgModes0, X, ArgVars, PredOrFunc,
-		Unification0, ModeInfo0, Unification, ModeInfo) :-
+			var, list(var), pred_or_func, unify_rhs, unification, 
+			mode_info, unify_rhs, unification, mode_info).
+:- mode categorize_unify_var_lambda(in, in, in, in, in, in,
+			in, mode_info_di, out, out, mode_info_uo) is det.
+
+categorize_unify_var_lambda(ModeOfX, ArgModes0, X, ArgVars,
+		PredOrFunc, RHS0, Unification0, ModeInfo0, RHS, 
+		Unification, ModeInfo) :-
 	% if we are re-doing mode analysis, preserve the existing cons_id
+	list__length(ArgVars, Arity),
 	( Unification0 = construct(_, ConsId0, _, _) ->
 		ConsId = ConsId0
 	; Unification0 = deconstruct(_, ConsId1, _, _, _) ->
@@ -916,15 +942,47 @@
 	;
 		% the real cons_id will be computed by polymorphism.m;
 		% we just put in a dummy one for now
-		list__length(ArgVars, Arity),
 		ConsId = cons(unqualified("__LambdaGoal__"), Arity)
 	),
 	mode_info_get_module_info(ModeInfo0, ModuleInfo),
 	mode_util__modes_to_uni_modes(ArgModes0, ArgModes0,
 						ModuleInfo, ArgModes),
+	mode_info_get_instmap(ModeInfo0, InstMap),
+		% If the instmap is unreachable, the code will 
+		% get pruned away, so don't report an error.
 	(
+		instmap__is_unreachable(InstMap)
+	->
+		ModeInfo = ModeInfo0,
+		RHS = RHS0,
+		Unification = construct(X, ConsId, ArgVars, ArgModes)
+	;
 		mode_is_output(ModuleInfo, ModeOfX)
 	->
+		( 
+			% lambda expressions must already have been expanded
+			% if a pred_const is present.
+			ConsId = pred_const(PredId, ProcId)
+		->
+			( 
+				RHS0 = lambda_goal(_, _, _, _, _, Goal),
+				Goal = call(PredId, ProcId, _, _, _, _) - _
+			->
+				module_info_pred_info(ModuleInfo,
+					PredId, PredInfo),
+				pred_info_module(PredInfo, PredModule),
+				pred_info_name(PredInfo, PredName),
+				RHS = functor(
+					cons(qualified(PredModule, PredName),
+						Arity),
+					ArgVars)	
+			;
+				error("categorize_unify_var_lambda - \
+					reintroduced lambda goal")
+			)
+		;
+			RHS = RHS0
+		),
 		Unification = construct(X, ConsId, ArgVars, ArgModes),
 		ModeInfo = ModeInfo0
 	;
@@ -938,7 +996,8 @@
 					Type, PredOrFunc),
 				ModeInfo0, ModeInfo),
 		% return any old garbage
-		Unification = Unification0
+		Unification = Unification0,
+		RHS = RHS0
 	).
 
 % categorize_unify_var_functor works out which category a unification
@@ -1002,7 +1061,11 @@
 		;
 			% Otherwise, it can fail
 			CanFail = can_fail,
-			( type_is_higher_order(TypeOfX, PredOrFunc, _) ->
+			mode_info_get_instmap(ModeInfo0, InstMap0),
+			( 
+				type_is_higher_order(TypeOfX, PredOrFunc, _),
+				instmap__is_reachable(InstMap0)
+			->
 				set__init(WaitingVars),
 				mode_info_error(WaitingVars,
 			mode_error_unify_pred(X,
Index: compiler/modes.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modes.m,v
retrieving revision 1.218
diff -u -r1.218 modes.m
--- modes.m	1998/01/30 06:12:54	1.218
+++ modes.m	1998/02/06 01:22:16
@@ -1006,10 +1006,11 @@
 
 unify_rhs_vars(var(Var), [Var]).
 unify_rhs_vars(functor(_Functor, Vars), Vars).
-unify_rhs_vars(lambda_goal(_PredOrFunc, LambdaVars, _Modes, _Det,
-			_Goal - GoalInfo), Vars) :-
+unify_rhs_vars(lambda_goal(_PredOrFunc, LambdaNonLocals, LambdaVars, 
+			_Modes, _Det, _Goal - GoalInfo), Vars) :-
 	goal_info_get_nonlocals(GoalInfo, NonLocals0),
-	set__delete_list(NonLocals0, LambdaVars, NonLocals),
+	set__delete_list(NonLocals0, LambdaVars, NonLocals1),
+	set__insert_list(NonLocals1, LambdaNonLocals, NonLocals),
 	set__to_sorted_list(NonLocals, Vars).
 
 append_extra_goals(no_extra_goals, ExtraGoals, ExtraGoals).
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/polymorphism.m,v
retrieving revision 1.125
diff -u -r1.125 polymorphism.m
--- polymorphism.m	1998/02/04 03:21:34	1.125
+++ polymorphism.m	1998/02/06 01:22:16
@@ -704,16 +704,17 @@
 		;
 			{ error("polymorphism: type_to_type_id failed") }
 		)
-	; { Y = lambda_goal(PredOrFunc, Vars, Modes, Det, LambdaGoal0) } ->
+	; 
+		{ Y = lambda_goal(PredOrFunc, ArgVars, Vars,
+			Modes, Det, LambdaGoal0) }
+	->
 		% for lambda expressions, we must recursively traverse the
 		% lambda goal and then convert the lambda expression
 		% into a new predicate
-		{ LambdaGoal0 = _ - GoalInfo0 },
-		{ goal_info_get_nonlocals(GoalInfo0, OrigNonLocals) },
 		polymorphism__process_goal(LambdaGoal0, LambdaGoal1),
 		polymorphism__fixup_quantification(LambdaGoal1, LambdaGoal),
 		polymorphism__process_lambda(PredOrFunc, Vars, Modes,
-				Det, OrigNonLocals, LambdaGoal, Unification,
+				Det, ArgVars, LambdaGoal, Unification,
 				Y1, Unification1),
 		{ Goal = unify(XVar, Y1, Mode, Unification1, Context)
 				- GoalInfo }
@@ -956,7 +957,7 @@
 	).
 
 :- pred polymorphism__process_lambda(pred_or_func, list(var),
-		list(mode), determinism, set(var), hlds_goal, unification,
+		list(mode), determinism, list(var), hlds_goal, unification,
 		unify_rhs, unification, poly_info, poly_info).
 :- mode polymorphism__process_lambda(in, in, in, in, in, in, in, out, out,
 		in, out) is det.
Index: compiler/purity.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/purity.m,v
retrieving revision 1.7
diff -u -r1.7 purity.m
--- purity.m	1998/01/29 13:31:42	1.7
+++ purity.m	1998/02/06 01:22:16
@@ -569,8 +569,8 @@
 		pure, NumErrors0, NumErrors) -->
 	{ Unif0 = unify(A,RHS0,C,D,E) },
 	{ Unif  = unify(A,RHS,C,D,E) },
-	(   { RHS0 = lambda_goal(F, G, H, I, Goal0 - Info0) } ->
-		{ RHS = lambda_goal(F, G, H, I, Goal - Info0) },
+	(   { RHS0 = lambda_goal(F, G, H, I, J, Goal0 - Info0) } ->
+		{ RHS = lambda_goal(F, G, H, I, J, Goal - Info0) },
 		compute_expr_purity(Goal0, Goal, Info0, PredInfo, ModuleInfo,
 				    yes, Purity, NumErrors0, NumErrors1),
 		error_if_closure_impure(GoalInfo, Purity,
Index: compiler/quantification.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/quantification.m,v
retrieving revision 1.58
diff -u -r1.58 quantification.m
--- quantification.m	1998/01/22 07:29:40	1.58
+++ quantification.m	1998/02/06 01:22:13
@@ -352,10 +352,12 @@
 	{ set__list_to_set(ArgVars, Vars) },
 	quantification__set_nonlocals(Vars).
 implicitly_quantify_unify_rhs(
-		lambda_goal(PredOrFunc, LambdaVars0, Modes, Det, Goal0),
+		lambda_goal(PredOrFunc, LambdaNonLocals0,
+			LambdaVars0, Modes, Det, Goal0),
 		Unification0,
 		Context,
-		lambda_goal(PredOrFunc, LambdaVars, Modes, Det, Goal),
+		lambda_goal(PredOrFunc, LambdaNonLocals,
+			LambdaVars, Modes, Det, Goal),
 		Unification
 		) -->
 
@@ -400,6 +402,7 @@
 	{ set__init(LambdaOutsideVars) },
 	quantification__set_lambda_outside(LambdaOutsideVars),
 	implicitly_quantify_goal(Goal1, Goal),
+
 	quantification__get_nonlocals(NonLocals0),
 		% lambda-quantified variables are local
 	{ set__delete_list(NonLocals0, LambdaVars, NonLocals) },
@@ -409,6 +412,19 @@
 	quantification__set_nonlocals(NonLocals),
 
 	%
+	% Work out the list of non-local curried arguments to the lambda
+	% expression. This set must only ever decrease, since the first
+	% approximation that make_hlds uses includes all variables in the 
+	% lambda expression except the quantified variables.
+	%
+	{ Goal = _ - LambdaGoalInfo },
+	{ goal_info_get_nonlocals(LambdaGoalInfo, LambdaGoalNonLocals) },
+	{ IsNonLocal = lambda([V::in] is semidet, (
+			set__member(V, LambdaGoalNonLocals)
+		)) },
+	{ list__filter(IsNonLocal, LambdaNonLocals0, LambdaNonLocals) },
+
+	%
 	% For a unification that constructs a lambda expression,
 	% the argument variables of the construction are the non-local
 	% variables of the lambda expression.  So if we recompute the
@@ -660,8 +676,11 @@
 quantification__unify_rhs_vars(functor(_Functor, ArgVars), Set0, LambdaSet,
 		Set, LambdaSet) :-
 	set__insert_list(Set0, ArgVars, Set).
-quantification__unify_rhs_vars(lambda_goal(_PredOrFunc, LambdaVars, _Modes,
-		_Detism, Goal), Set, LambdaSet0, Set, LambdaSet) :-
+quantification__unify_rhs_vars(
+		lambda_goal(_POrF, _NonLocals, LambdaVars, _M, _D, Goal), 
+		Set, LambdaSet0, Set, LambdaSet) :-
+	% Note that the NonLocals list is not counted, since all the 
+	% variables in that list must occur in the goal.
 	quantification__goal_vars(Goal, GoalVars),
 	set__delete_list(GoalVars, LambdaVars, GoalVars1),
 	set__union(LambdaSet0, GoalVars1, LambdaSet).
Index: compiler/simplify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/simplify.m,v
retrieving revision 1.52
diff -u -r1.52 simplify.m
--- simplify.m	1998/01/13 10:13:36	1.52
+++ simplify.m	1998/02/06 01:23:44
@@ -562,8 +562,8 @@
 simplify__goal_2(Goal0, GoalInfo0, Goal, GoalInfo, Info0, Info) :-
 	Goal0 = unify(LT0, RT0, M, U0, C),
 	(
-		RT0 = lambda_goal(PredOrFunc, Vars, Modes, LambdaDeclaredDet,
-			LambdaGoal0)
+		RT0 = lambda_goal(PredOrFunc, NonLocals, Vars, 
+			Modes, LambdaDeclaredDet, LambdaGoal0)
 	->
 		simplify_info_enter_lambda(Info0, Info1),
 		simplify_info_get_common_info(Info1, Common1),
@@ -583,8 +583,8 @@
 		simplify__goal(LambdaGoal0, LambdaGoal, Info3, Info4),
 		simplify_info_set_common_info(Info4, Common1, Info5),
 		simplify_info_set_instmap(Info5, InstMap1, Info6),
-		RT = lambda_goal(PredOrFunc, Vars, Modes, LambdaDeclaredDet,
-			LambdaGoal),
+		RT = lambda_goal(PredOrFunc, NonLocals, Vars, Modes, 
+			LambdaDeclaredDet, LambdaGoal),
 		simplify_info_leave_lambda(Info6, Info),
 		Goal = unify(LT0, RT, M, U0, C),
 		GoalInfo = GoalInfo0
Index: compiler/special_pred.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/special_pred.m,v
retrieving revision 1.19
diff -u -r1.19 special_pred.m
--- special_pred.m	1998/01/24 05:44:22	1.19
+++ special_pred.m	1998/02/08 02:59:54
@@ -76,11 +76,11 @@
 	out_mode(Out).
 
 special_pred_info(compare, Type,
-		 "__Compare__", [ResType, Type, Type], [Out, In, In], det) :-
+		 "__Compare__", [ResType, Type, Type], [Uo, In, In], det) :-
 	construct_type(qualified("mercury_builtin", "comparison_result") - 0,
 							[], ResType),
 	in_mode(In),
-	out_mode(Out).
+	uo_mode(Uo).
 
 :- pred in_mode((mode)::out) is det.
 
@@ -90,6 +90,9 @@
 
 out_mode(user_defined_mode(qualified("mercury_builtin", "out"), [])).
 
+:- pred uo_mode((mode)::out) is det.
+
+uo_mode(user_defined_mode(qualified("mercury_builtin", "uo"), [])).
 
 	% Given the mangled predicate name and the list of argument types,
 	% work out which type this special predicate is for.
Index: compiler/store_alloc.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/store_alloc.m,v
retrieving revision 1.58
diff -u -r1.58 store_alloc.m
--- store_alloc.m	1998/01/13 10:13:39	1.58
+++ store_alloc.m	1998/02/06 13:20:54
@@ -47,11 +47,10 @@
 	module_info_globals(ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, follow_vars, ApplyFollowVars),
 	( ApplyFollowVars = yes ->
-		globals__get_args_method(Globals, ArgsMethod),
 		proc_info_goal(ProcInfo0, Goal0),
 
 		find_final_follow_vars(ProcInfo0, FollowVars0),
-		find_follow_vars_in_goal(Goal0, ArgsMethod, ModuleInfo,
+		find_follow_vars_in_goal(Goal0, ModuleInfo,
 			FollowVars0, Goal1, FollowVars),
 		Goal1 = GoalExpr1 - GoalInfo1,
 		goal_info_set_follow_vars(GoalInfo1, yes(FollowVars),
Index: compiler/stratify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/stratify.m,v
retrieving revision 1.14
diff -u -r1.14 stratify.m
--- stratify.m	1998/01/13 10:13:42	1.14
+++ stratify.m	1998/02/06 01:22:17
@@ -800,8 +800,8 @@
 		% lambda goal have addresses taken. this is not
 		% always to case, but should be a suitable approximation for
 		% the stratification analysis
-		RHS = lambda_goal(_PredOrFunc, _Vars, _Modes, _Determinism,
-		                                Goal - _GoalInfo)
+		RHS = lambda_goal(_PredOrFunc, _NonLocals, _Vars, 
+				_Modes, _Determinism, Goal - _GoalInfo)
 	->
 		get_called_procs(Goal, [], CalledProcs),
 		set__insert_list(HasAT0, CalledProcs, HasAT)
@@ -901,8 +901,8 @@
 		% lambda goal have addresses taken. this is not
 		% always to case, but should be a suitable approximation for
 		% the stratification analysis
-		RHS = lambda_goal(_PredOrFunc, _Vars, _Modes, _Determinism,
-		                                Goal - _GoalInfo)
+		RHS = lambda_goal(_PredOrFunc, _NonLocals, _Vars, 
+				_Modes, _Determinism, Goal - _GoalInfo)
 	->
 		get_called_procs(Goal, Calls0, Calls)
 	;
Index: compiler/switch_detection.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/switch_detection.m,v
retrieving revision 1.79
diff -u -r1.79 switch_detection.m
--- switch_detection.m	1998/01/13 10:13:44	1.79
+++ switch_detection.m	1998/02/06 01:22:13
@@ -174,14 +174,15 @@
 
 detect_switches_in_goal_2(unify(A,RHS0,C,D,E), __GoalInfo, InstMap0,
 		VarTypes, ModuleInfo, unify(A,RHS,C,D,E)) :-
-	( RHS0 = lambda_goal(PredOrFunc, Vars, Modes, Det, Goal0) ->
+	( RHS0 = lambda_goal(PredOrFunc, NonLocals, Vars, Modes, Det, Goal0) ->
 		% we need to insert the initial insts for the lambda
 		% variables in the instmap before processing the lambda goal
 		instmap__pre_lambda_update(ModuleInfo, 
 			Vars, Modes, InstMap0, InstMap1),
 		detect_switches_in_goal(Goal0, InstMap1, VarTypes, ModuleInfo,
 			Goal),
-		RHS = lambda_goal(PredOrFunc, Vars, Modes, Det, Goal)
+		RHS = lambda_goal(PredOrFunc, NonLocals, 
+			Vars, Modes, Det, Goal)
 	;
 		RHS = RHS0
 	).
Index: compiler/typecheck.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/typecheck.m,v
retrieving revision 1.230
diff -u -r1.230 typecheck.m
--- typecheck.m	1998/02/05 05:10:52	1.230
+++ typecheck.m	1998/02/06 01:22:17
@@ -333,7 +333,8 @@
 			% declarations are module qualified, unless undefined
 			% modes were found by an earlier pass.
 			% 
-			maybe_add_default_mode(PredInfo1, PredInfo2, _),
+			maybe_add_default_mode(ModuleInfo,
+				PredInfo1, PredInfo2, _),
 			copy_clauses_to_procs(PredInfo2, PredInfo3),
 			pred_info_arg_types(PredInfo3, _, ArgTypes),
 			pred_info_procedures(PredInfo3, Procs1),
@@ -1611,8 +1612,9 @@
 typecheck_unification(X, functor(F, As), functor(F, As)) -->
 	typecheck_unify_var_functor(X, F, As),
 	perform_context_reduction.
-typecheck_unification(X, lambda_goal(PredOrFunc, Vars, Modes, Det, Goal0),
-			 lambda_goal(PredOrFunc, Vars, Modes, Det, Goal)) -->
+typecheck_unification(X, 
+		lambda_goal(PredOrFunc, NonLocals, Vars, Modes, Det, Goal0),
+		lambda_goal(PredOrFunc, NonLocals, Vars, Modes, Det, Goal)) -->
  	typecheck_lambda_var_has_type(PredOrFunc, X, Vars),
 	typecheck_goal(Goal0, Goal).
 
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/unify_gen.m,v
retrieving revision 1.88
diff -u -r1.88 unify_gen.m
--- unify_gen.m	1998/01/23 12:57:05	1.88
+++ unify_gen.m	1998/02/06 01:22:17
@@ -63,7 +63,7 @@
 :- implementation.
 
 :- import_module hlds_module, hlds_pred, prog_data, code_util.
-:- import_module mode_util, type_util, code_aux, hlds_out, tree.
+:- import_module mode_util, type_util, code_aux, hlds_out, tree, arg_info.
 :- import_module bool, string, int, map, term, require, std_util.
 
 :- type uni_val		--->	ref(var)
@@ -332,6 +332,15 @@
 	{ map__lookup(Preds, PredId, PredInfo) },
 	{ pred_info_procedures(PredInfo, Procs) },
 	{ map__lookup(Procs, ProcId, ProcInfo) },
+
+	% lambda.m should ensure that only predicates using the compact
+	% argument passing convention occur in closures.
+	{ arg_info__ho_callable_args_method(ArgsMethod) },
+	( { proc_info_args_method(ProcInfo, ArgsMethod) } ->
+		[]
+	;	
+		{ error("unify_gen__generate_construction_2: pred constant not callable") }
+	),
 %
 % We handle currying of a higher-order pred variable as a special case.
 % We recognize
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/unify_proc.m,v
retrieving revision 1.64
diff -u -r1.64 unify_proc.m
--- unify_proc.m	1998/01/12 13:28:51	1.64
+++ unify_proc.m	1998/02/06 01:22:17
@@ -258,8 +258,10 @@
 	map__lookup(Preds0, PredId, PredInfo0),
 	list__length(ArgModes, Arity),
 	DeclaredArgModes = no,
+	module_info_globals(ModuleInfo0, Globals),
+	globals__get_args_method(Globals, ArgsMethod),
 	add_new_proc(PredInfo0, Arity, ArgModes, DeclaredArgModes,
-		ArgLives, MaybeDet, Context, PredInfo1, ProcId),
+		ArgLives, MaybeDet, Context, ArgsMethod, PredInfo1, ProcId),
 
 	%
 	% copy the clauses for the procedure from the pred_info to the
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/unique_modes.m,v
retrieving revision 1.45
diff -u -r1.45 unique_modes.m
--- unique_modes.m	1998/01/30 06:12:58	1.45
+++ unique_modes.m	1998/02/08 02:21:54
@@ -453,10 +453,12 @@
 	% first off, try using the existing mode
 	%
 	mode_info_get_module_info(ModeInfo0, ModuleInfo),
-	module_info_pred_proc_info(ModuleInfo, PredId, ProcId0, _, ProcInfo),
+	module_info_pred_proc_info(ModuleInfo, PredId, ProcId0,
+		PredInfo, ProcInfo),
 	proc_info_argmodes(ProcInfo, ProcArgModes0),
 	proc_info_interface_code_model(ProcInfo, CodeModel),
-	proc_info_never_succeeds(ProcInfo, NeverSucceeds),
+	proc_info_inferred_never_succeeds(PredInfo, ProcId0,
+		ProcInfo, NeverSucceeds),
 	unique_modes__check_call_modes(ArgVars, ProcArgModes0, CodeModel,
 				NeverSucceeds, ModeInfo1, ModeInfo2),
 
Index: library/mercury_builtin.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/mercury_builtin.m,v
retrieving revision 1.91
diff -u -r1.91 mercury_builtin.m
--- mercury_builtin.m	1998/01/27 04:47:40	1.91
+++ mercury_builtin.m	1998/02/08 03:01:21
@@ -186,33 +186,33 @@
 
 :- pred builtin_unify_int(int::in, int::in) is semidet.
 :- pred builtin_index_int(int::in, int::out) is det.
-:- pred builtin_compare_int(comparison_result::out, int::in, int::in) is det.
+:- pred builtin_compare_int(comparison_result::uo, int::in, int::in) is det.
 
 :- pred builtin_unify_character(character::in, character::in) is semidet.
 :- pred builtin_index_character(character::in, int::out) is det.
-:- pred builtin_compare_character(comparison_result::out, character::in,
+:- pred builtin_compare_character(comparison_result::uo, character::in,
 	character::in) is det.
 
 :- pred builtin_unify_string(string::in, string::in) is semidet.
 :- pred builtin_index_string(string::in, int::out) is det.
-:- pred builtin_compare_string(comparison_result::out, string::in, string::in)
+:- pred builtin_compare_string(comparison_result::uo, string::in, string::in)
 	is det.
 
 :- pred builtin_unify_float(float::in, float::in) is semidet.
 :- pred builtin_index_float(float::in, int::out) is det.
-:- pred builtin_compare_float(comparison_result::out, float::in, float::in)
+:- pred builtin_compare_float(comparison_result::uo, float::in, float::in)
 	is det.
 
 :- pred builtin_unify_pred((pred)::in, (pred)::in) is semidet.
 :- pred builtin_index_pred((pred)::in, int::out) is det.
-:- pred builtin_compare_pred(comparison_result::out, (pred)::in, (pred)::in)
+:- pred builtin_compare_pred(comparison_result::uo, (pred)::in, (pred)::in)
 	is det.
 
 % The following two preds are used for index/1 or compare/3 on
 % non-canonical types (types for which there is a `where equality is ...'
 % declaration).
 :- pred builtin_index_non_canonical_type(T::in, int::out) is det.
-:- pred builtin_compare_non_canonical_type(comparison_result::out,
+:- pred builtin_compare_non_canonical_type(comparison_result::uo,
 		T::in, T::in) is det.
 
 :- pred unused is det.
Index: runtime/mercury_ho_call.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_ho_call.c,v
retrieving revision 1.5
diff -u -r1.5 mercury_ho_call.c
--- mercury_ho_call.c	1997/12/20 11:11:30	1.5
+++ mercury_ho_call.c	1998/02/07 13:52:37
@@ -136,22 +136,9 @@
 	*/
 Define_label(det_closure_return);
 {
-	int	i, num_in_args, num_out_args;
-
 	MR_succip = pop(); /* restore succip */
-	num_in_args = pop(); /* restore the input arg counter */
-	num_out_args = pop(); /* restore the ouput arg counter */
-
-#ifdef	COMPACT_ARGS
-#else
-	save_registers();
-
-	for (i = 1; i <= num_out_args; i++) {
-		virtual_reg(i) = virtual_reg(i+num_in_args);
-	}
-
-	restore_registers();
-#endif
+	pop(); /* restore the input arg counter */
+	pop(); /* restore the ouput arg counter */
 
 	proceed();
 }
@@ -171,7 +158,6 @@
 
 	save_registers();
 
-#ifdef	COMPACT_ARGS
 	if (num_in_args < 3) {
 		for (i = 1; i <= num_extra_args; i++) {
 			virtual_reg(i+num_in_args) = virtual_reg(i+3);
@@ -185,21 +171,6 @@
 	for (i = 1; i <= num_in_args; i++) {
 		virtual_reg(i) = field(0, closure, i+1); /* copy args */
 	}
-#else
-	if (num_in_args < 2) {
-		for (i = 1; i <= num_extra_args; i++) {
-			virtual_reg(1+i+num_in_args) = virtual_reg(i+3);
-		}
-	} else if (num_in_args > 2) {
-		for (i = num_extra_args; i>0; i--) {
-			virtual_reg(1+i+num_in_args) = virtual_reg(i+3);
-		}
-	} /* else do nothing because i == 2 */
-
-	for (i = 1; i <= num_in_args; i++) {
-		virtual_reg(i+1) = field(0, closure, i+1); /* copy args */
-	}
-#endif
 
 	restore_registers();
 
@@ -212,22 +183,9 @@
 	*/
 Define_label(semidet_closure_return);
 {
-	int	i, num_in_args, num_out_args;
-
 	MR_succip = pop(); /* restore succip */
-	num_in_args = pop(); /* restore the input arg counter */
-	num_out_args = pop(); /* restore the ouput arg counter */
-
-#ifdef	COMPACT_ARGS
-#else
-	save_registers();
-
-	for (i = 1; i <= num_out_args; i++) {
-		virtual_reg(i+1) = virtual_reg(i+1+num_in_args);
-	}
-
-	restore_registers();
-#endif
+	pop(); /* restore the input arg counter */
+	pop(); /* restore the ouput arg counter */
 
 	proceed();
 }
@@ -273,22 +231,6 @@
 	*/
 Define_label(nondet_closure_return);
 {
-	int	i, num_in_args, num_out_args;
-
-	num_in_args = framevar(1); /* restore the input arg counter */
-	num_out_args = framevar(0); /* restore the ouput arg counter */
-
-#ifdef	COMPACT_ARGS
-#else
-	save_registers();
-
-	for (i = 1; i <= num_out_args; i++) {
-		virtual_reg(i) = virtual_reg(i+num_in_args);
-	}
-
-	restore_registers();
-#endif
-
 	succeed();
 }
 
Index: tests/valid/unreachable_code.m
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/unreachable_code.m,v
retrieving revision 1.1
diff -u -r1.1 unreachable_code.m
--- unreachable_code.m	1995/11/14 08:03:46	1.1
+++ unreachable_code.m	1998/02/08 05:55:01
@@ -4,6 +4,7 @@
 :- type foo ---> foo.
 
 :- pred p(foo::in, foo::in) is semidet.
+:- pred q(int::in, foo::in, foo::in) is semidet.
 
 :- implementation.
 :- import_module require.
@@ -11,5 +12,15 @@
 p(X, Y) :-
 	error("err"),
 	X = Y.
+
+	% We used to report a bogus mode error for this.
+q(Int, X, Y) :-
+	Int = 1,
+	( Int = 2 ->
+		Pred = p
+	;
+		Pred = p
+	),
+	call(Pred, X, Y).
 
 %-----------------------------------------------------------------------------%



More information about the developers mailing list