for review: new method of handling failures, part 3 of 6

Zoltan Somogyi zs at cs.mu.OZ.AU
Thu Jul 2 16:21:25 AEST 1998


Index: compiler/basic_block.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/basic_block.m,v
retrieving revision 1.5
diff -u -r1.5 basic_block.m
--- basic_block.m	1998/06/09 02:11:59	1.5
+++ basic_block.m	1998/06/29 08:18:22
@@ -160,7 +160,7 @@
 	;
 		Labels = []
 	).
-possible_targets(mkframe(_, _, _, _), []).
+possible_targets(mkframe(_, _), []).
 possible_targets(modframe(_), []).
 possible_targets(label(_), []).
 possible_targets(goto(CodeAddr), Targets) :-
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.122
diff -u -r1.122 call_gen.m
--- call_gen.m	1998/05/16 07:29:43	1.122
+++ call_gen.m	1998/05/17 07:06:55
@@ -37,25 +37,9 @@
 			hlds_goal_info, code_tree, code_info, code_info).
 :- mode call_gen__generate_call(in, in, in, in, in, out, in, out) is det.
 
-:- pred call_gen__generate_det_builtin(pred_id, proc_id, list(var),
+:- pred call_gen__generate_builtin(code_model, pred_id, proc_id, list(var),
 			code_tree, code_info, code_info).
-:- mode call_gen__generate_det_builtin(in, in, in, out, in, out) is det.
-
-:- pred call_gen__generate_semidet_builtin(pred_id, proc_id, list(var),
-			code_tree, code_info, code_info).
-:- mode call_gen__generate_semidet_builtin(in, in, in, out, in, out) is det.
-
-:- pred call_gen__generate_nondet_builtin(pred_id, proc_id, list(var),
-			code_tree, code_info, code_info).
-:- mode call_gen__generate_nondet_builtin(in, in, in, out, in, out) is
-					erroneous.
-
-/* DEAD CODE
-:- pred call_gen__generate_complicated_unify(var, var, uni_mode, can_fail,
-					code_tree, code_info, code_info).
-:- mode call_gen__generate_complicated_unify(in, in, in, in, out, in, out)
-	is det.
-*/
+:- mode call_gen__generate_builtin(in, in, in, in, out, in, out) is det.
 
 :- pred call_gen__partition_args(assoc_list(var, arg_info),
 						list(var), list(var)).
@@ -100,17 +84,12 @@
 		% save possibly unknown variables on the stack as well
 		% if they may be needed on backtracking, and figure out the
 		% call model
-	call_gen__prepare_for_call(CodeModel, FlushCode, CallModel, _),
+	call_gen__prepare_for_call(CodeModel, FlushCode, CallModel, _, _),
 
 		% move the input arguments to their registers
 	code_info__setup_call(ArgsInfos, caller, SetupCode),
 
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ trace__prepare_for_call(TraceInfo, TraceCode) }
-	;
-		{ TraceCode = empty }
-	),
+	trace__prepare_for_call(TraceCode),
 
 		% figure out what locations are live at the call point,
 		% for use by the value numbering optimization
@@ -155,17 +134,17 @@
 %---------------------------------------------------------------------------%
 
 	%
-	% for a higher-order call,
+	% 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/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.
+	% runtime/mercury_ho_call.c, generate the call to that code,
+	% and pick up the outputs from the locations that we know
+	% the runtime system leaves them in.
 	%
-	% lambda.m ensures 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.
+	% Lambda.m transforms the generated lambda predicates to
+	% make sure that all inputs come before all outputs, so that
+	% the code in the runtime system doesn't have trouble figuring out
+	% which registers the arguments go in.
 	%
 
 call_gen__generate_higher_order_call(_OuterCodeModel, PredVar, Args, Types,
@@ -178,12 +157,11 @@
 		ArgInfos) },
 	{ assoc_list__from_corresponding_lists(Args, ArgInfos, ArgsInfos) },
 	{ call_gen__partition_args(ArgsInfos, InVars, OutVars) },
-	code_info__succip_is_used,
 	{ set__list_to_set(OutVars, OutArgs) },
 	call_gen__save_variables(OutArgs, SaveCode),
 
 	call_gen__prepare_for_call(CodeModel, FlushCode, CallModel,
-		RuntimeAddr),
+		DoHigherCall, _),
 
 		% place the immediate input arguments in registers
 		% starting at r4.
@@ -228,19 +206,13 @@
 			"Assign number of output arguments"
 	]) },
 
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		{ trace__prepare_for_call(TraceInfo, TraceCode) }
-	;
-		{ TraceCode = empty }
-	),
-
+	trace__prepare_for_call(TraceCode),
 	code_info__get_next_label(ReturnLabel),
 	{ CallCode = node([
 		livevals(LiveVals)
 			- "",
-		call(RuntimeAddr, label(ReturnLabel), OutLiveVals, CallModel)
-			- "setup and call higher order pred",
+		call(DoHigherCall, label(ReturnLabel), OutLiveVals, CallModel)
+			- "Setup and call higher order pred",
 		label(ReturnLabel)
 			- "Continuation label"
 	]) },
@@ -263,16 +235,17 @@
 %---------------------------------------------------------------------------%
 
 	%
-	% for a class method call,
+	% 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/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.
+	% runtime/mercury_ho_call.c, generate the call to that code,
+	% and pick up the outputs from the locations that we know
+	% the runtime system leaves them in.
 	%
+
 call_gen__generate_class_method_call(_OuterCodeModel, TCVar, MethodNum, Args,
 		Types, Modes, Det, GoalInfo, Code) -->
-	{ determinism_to_code_model(Det, InnerCodeModel) },
+	{ determinism_to_code_model(Det, CodeModel) },
 	code_info__get_globals(Globals),
 	code_info__get_module_info(ModuleInfo),
 
@@ -282,40 +255,15 @@
 	;
 		{ error("Sorry, typeclasses with simple args_method not yet implemented") }
 	),
-	{ make_arg_infos(ArgsMethod, Types, Modes, InnerCodeModel, ModuleInfo,
+	{ make_arg_infos(ArgsMethod, Types, Modes, CodeModel, ModuleInfo,
 		ArgInfo) },
 	{ assoc_list__from_corresponding_lists(Args, ArgInfo, ArgsAndArgInfo) },
 	{ call_gen__partition_args(ArgsAndArgInfo, InVars, OutVars) },
-	call_gen__generate_class_method_call_2(InnerCodeModel, TCVar, 
-		MethodNum, InVars, OutVars, GoalInfo, Code).
-
-:- pred call_gen__generate_class_method_call_2(code_model, var, int, list(var),
-		list(var), hlds_goal_info, code_tree, code_info, code_info).
-:- mode call_gen__generate_class_method_call_2(in, in, in, in, in, in, out, in,
-		out) is det.
-
-call_gen__generate_class_method_call_2(CodeModel, TCVar, Index, 
-		InVars, OutVars, GoalInfo, Code) -->
-	code_info__succip_is_used,
 	{ set__list_to_set(OutVars, OutArgs) },
 	call_gen__save_variables(OutArgs, SaveCode),
-	(
-		{ CodeModel = model_det },
-		{ CallModel = det },
-		{ RuntimeAddr = do_det_class_method },
-		{ FlushCode = empty }
-	;
-		{ CodeModel = model_semi },
-		{ CallModel = semidet },
-		{ RuntimeAddr = do_semidet_class_method },
-		{ FlushCode = empty }
-	;
-		{ CodeModel = model_non },
-		code_info__may_use_nondet_tailcall(TailCall),
-		{ CallModel = nondet(TailCall) },
-		{ RuntimeAddr = do_nondet_class_method },
-		code_info__unset_failure_cont(FlushCode)
-	),
+	call_gen__prepare_for_call(CodeModel, FlushCode, CallModel,
+		_, DoMethodCall),
+
 		% place the immediate input arguments in registers
 		% starting at r5.
 	call_gen__generate_immediate_args(InVars, 5, InLocs, ImmediateCode),
@@ -332,14 +280,13 @@
 	),
 	{ call_gen__outvars_to_outargs(OutVars, FirstArg, OutArguments) },
 	{ call_gen__output_arg_locs(OutArguments, OutLocs) },
-
 	code_info__get_instmap(InstMap),
 	{ goal_info_get_instmap_delta(GoalInfo, InstMapDelta) },
 	{ instmap__apply_instmap_delta(InstMap, InstMapDelta,
 		AfterCallInstMap) },
-
 	call_gen__generate_return_livevals(OutArgs, OutLocs, AfterCallInstMap, 
 		OutLiveVals),
+
 	code_info__produce_variable(TCVar, TCVarCode, TCVarRVal),
 	(
 		{ TCVarRVal = lval(reg(r, 1)) }
@@ -347,78 +294,75 @@
 		{ CopyCode = empty }
 	;
 		{ CopyCode = node([
-			assign(reg(r, 1), TCVarRVal) - "Copy typeclass info"
-		])}
+			assign(reg(r, 1), TCVarRVal)
+				- "Copy typeclass info"
+		]) }
 	),
 	{ list__length(InVars, NInVars) },
 	{ list__length(OutVars, NOutVars) },
-	{ SetupCode = tree(CopyCode, node([
-			assign(reg(r, 2), const(int_const(Index))) -
-				"Index of class method in typeclass info",
-			assign(reg(r, 3), const(int_const(NInVars))) -
-				"Assign number of immediate input arguments",
-			assign(reg(r, 4), const(int_const(NOutVars))) -
-				"Assign number of output arguments"
-		])
-	) },
+	{ SetupCode = node([
+		assign(reg(r, 2), const(int_const(MethodNum))) -
+			"Index of class method in typeclass info",
+		assign(reg(r, 3), const(int_const(NInVars))) -
+			"Assign number of immediate input arguments",
+		assign(reg(r, 4), const(int_const(NOutVars))) -
+			"Assign number of output arguments"
+	]) },
+
+	trace__prepare_for_call(TraceCode),
 	code_info__get_next_label(ReturnLabel),
-	{ TryCallCode = node([
-		livevals(LiveVals) - "",
-		call(RuntimeAddr, label(ReturnLabel), OutLiveVals, CallModel)
-			- "setup and call class method",
-		label(ReturnLabel) - "Continuation label"
+	{ CallCode = node([
+		livevals(LiveVals)
+			- "",
+		call(DoMethodCall, label(ReturnLabel), OutLiveVals, CallModel)
+			- "Setup and call class method",
+		label(ReturnLabel)
+			- "Continuation label"
 	]) },
+
 	call_gen__rebuild_registers(OutArguments),
-	(
-		{ CodeModel = model_semi }
-	->
-		code_info__generate_failure(FailCode),
-		code_info__get_next_label(ContLab),
-		{ TestSuccessCode = node([
-			if_val(lval(reg(r, 1)), label(ContLab)) -
-				"Test for success"
-		]) },
-		{ ContLabelCode = node([label(ContLab) - ""]) },
-		{ CallCode =
-			tree(TryCallCode,
-			tree(TestSuccessCode,
-			tree(FailCode,
-			     ContLabelCode))) }
-	;
-		{ CallCode = TryCallCode }
-	),
+	call_gen__handle_failure(CodeModel, FailHandlingCode),
+
 	{ Code =
 		tree(SaveCode,
 		tree(FlushCode,
 		tree(ImmediateCode,
 		tree(TCVarCode,
+		tree(CopyCode,
 		tree(SetupCode,
-		     CallCode)))))
+		tree(TraceCode,
+		tree(CallCode,
+		     FailHandlingCode))))))))
 	}.
 
 %---------------------------------------------------------------------------%
 
 :- pred call_gen__prepare_for_call(code_model, code_tree, call_model,
-	code_addr, code_info, code_info).
-:- mode call_gen__prepare_for_call(in, out, out, out, in, out) is det.
+	code_addr, code_addr, code_info, code_info).
+:- mode call_gen__prepare_for_call(in, out, out, out, out, in, out) is det.
 
-call_gen__prepare_for_call(CodeModel, FlushCode, CallModel, RuntimeAddr) -->
+call_gen__prepare_for_call(CodeModel, FlushCode, CallModel, Higher, Method) -->
+	code_info__succip_is_used,
 	(
 		{ CodeModel = model_det },
 		{ CallModel = det },
-		{ RuntimeAddr = do_det_closure },
+		{ Higher = do_det_closure },
+		{ Method = do_det_class_method },
 		{ FlushCode = empty }
 	;
 		{ CodeModel = model_semi },
 		{ CallModel = semidet },
-		{ RuntimeAddr = do_semidet_closure },
+		{ Higher = do_semidet_closure },
+		{ Method = do_semidet_class_method },
 		{ FlushCode = empty }
 	;
 		{ CodeModel = model_non },
 		code_info__may_use_nondet_tailcall(TailCall),
 		{ CallModel = nondet(TailCall) },
-		{ RuntimeAddr = do_nondet_closure },
-		code_info__unset_failure_cont(FlushCode)
+		{ Higher = do_nondet_closure },
+		{ Method = do_nondet_class_method },
+		code_info__flush_resume_vars_to_stack(FlushCode),
+		code_info__set_resume_point_and_frame_to_unknown
 	).
 
 :- pred call_gen__handle_failure(code_model, code_tree, code_info, code_info).
@@ -426,13 +370,16 @@
 
 call_gen__handle_failure(CodeModel, FailHandlingCode) -->
 	( { CodeModel = model_semi } ->
-		code_info__generate_failure(FailCode),
 		code_info__get_next_label(ContLab),
 		{ FailTestCode = node([
 			if_val(lval(reg(r, 1)), label(ContLab))
 				- "test for success"
 		]) },
-		{ ContLabelCode = node([label(ContLab) - ""]) },
+		code_info__generate_failure(FailCode),
+		{ ContLabelCode = node([
+			label(ContLab)
+				- ""
+		]) },
 		{ FailHandlingCode =
 			tree(FailTestCode,
 			tree(FailCode, 
@@ -508,60 +455,63 @@
 
 %---------------------------------------------------------------------------%
 
-call_gen__generate_det_builtin(PredId, ProcId, Args, Code) -->
+call_gen__generate_builtin(CodeModel, PredId, ProcId, Args, Code) -->
 	code_info__get_module_info(ModuleInfo),
 	{ predicate_module(ModuleInfo, PredId, ModuleName) },
 	{ predicate_name(ModuleInfo, PredId, PredName) },
-	(
-		{ code_util__translate_builtin(ModuleName, PredName, ProcId,
-			Args, no, yes(Var - Rval)) }
+	{
+		code_util__translate_builtin(ModuleName, PredName,
+			ProcId, Args, MaybeTestPrime, MaybeAssignPrime)
 	->
-		code_info__cache_expression(Var, Rval),
-		{ Code = empty }
+		MaybeTest = MaybeTestPrime,
+		MaybeAssign = MaybeAssignPrime
 	;
-		{ error("Unknown builtin predicate") }
-	).
-
-%---------------------------------------------------------------------------%
-
-call_gen__generate_semidet_builtin(PredId, ProcId, Args, Code) -->
-	code_info__get_module_info(ModuleInfo),
-	{ predicate_module(ModuleInfo, PredId, ModuleName) },
-	{ predicate_name(ModuleInfo, PredId, PredName) },
+		error("Unknown builtin predicate")
+	},
 	(
-		{ code_util__translate_builtin(ModuleName, PredName, ProcId,
-			Args, yes(Rval0), Assign) }
-	->
-		( { Rval0 = binop(BinOp, X0, Y0) } ->
-			call_gen__generate_builtin_arg(X0, X, CodeX),
-			call_gen__generate_builtin_arg(Y0, Y, CodeY),
-			{ Rval = binop(BinOp, X, Y) },
-			{ ArgCode = tree(CodeX, CodeY) }
-		; { Rval0 = unop(UnOp, X0) } ->
-			call_gen__generate_builtin_arg(X0, X, ArgCode),
-			{ Rval = unop(UnOp, X) }
+		{ CodeModel = model_det },
+		(
+			{ MaybeTest = no },
+			{ MaybeAssign = yes(Var - Rval) }
+		->
+			code_info__cache_expression(Var, Rval),
+			{ Code = empty }
 		;
-			{ error("Unknown builtin predicate") }
-		),
-		code_info__fail_if_rval_is_false(Rval, TestCode),
-		( { Assign = yes(Var - AssignRval) } ->
-			code_info__cache_expression(Var, AssignRval)
+			{ error("Malformed det builtin predicate") }
+		)
+	;
+		{ CodeModel = model_semi },
+		(
+			{ MaybeTest = yes(Test) }
+		->
+			( { Test = binop(BinOp, X0, Y0) } ->
+				call_gen__generate_builtin_arg(X0, X, CodeX),
+				call_gen__generate_builtin_arg(Y0, Y, CodeY),
+				{ Rval = binop(BinOp, X, Y) },
+				{ ArgCode = tree(CodeX, CodeY) }
+			; { Test = unop(UnOp, X0) } ->
+				call_gen__generate_builtin_arg(X0, X, ArgCode),
+				{ Rval = unop(UnOp, X) }
+			;
+				{ error("Malformed semi builtin predicate") }
+			),
+			code_info__fail_if_rval_is_false(Rval, TestCode),
+			( { MaybeAssign = yes(Var - AssignRval) } ->
+				code_info__cache_expression(Var, AssignRval)
+			;
+				[]
+			),
+			{ Code = tree(ArgCode, TestCode) }
 		;
-			[]
-		),
-		{ Code = tree(ArgCode, TestCode) }
+			{ error("Malformed semi builtin predicate") }
+		)
 	;
-		{ error("Unknown builtin predicate") }
+		{ CodeModel = model_non },
+		{ error("Nondet builtin predicate") }
 	).
 
 %---------------------------------------------------------------------------%
 
-call_gen__generate_nondet_builtin(_PredId, _ProcId, _Args, _Code) -->
-	% there aren't any nondet builtins
-	{ error("Unknown nondet builtin predicate") }.
-
-%---------------------------------------------------------------------------%
-
 :- pred call_gen__generate_builtin_arg(rval, rval, code_tree,
 	code_info, code_info).
 :- mode call_gen__generate_builtin_arg(in, out, out, in, out) is det.
@@ -588,88 +538,6 @@
 		call_gen__partition_args(Rest, Ins, Outs0),
 		Outs = [V | Outs0]
 	).
-
-%---------------------------------------------------------------------------%
-
-/* DEAD CODE
-call_gen__generate_complicated_unify(Var1, Var2, UniMode, CanFail, Code) -->
-	{ determinism_components(Det, CanFail, at_most_one) },
-	{ determinism_to_code_model(Det, CodeModel) },
-	code_info__get_globals(Globals),
-	{ globals__get_args_method(Globals, ArgsMethod) },
-	{ arg_info__unify_arg_info(ArgsMethod, CodeModel, ArgInfo) },
-	{ Arguments = [Var1, Var2] },
-	{ assoc_list__from_corresponding_lists(Arguments, ArgInfo, Args) },
-	{ call_gen__select_out_args(Args, OutArgs) },
-	call_gen__save_variables(OutArgs, CodeA),
-	code_info__setup_call(Args, caller, CodeB),
-	code_info__get_next_label(ReturnLabel),
-	code_info__get_module_info(ModuleInfo),
-	code_info__variable_type(Var1, VarType),
-	( { type_to_type_id(VarType, VarTypeId, _) } ->
-		{ unify_proc__lookup_mode_num(ModuleInfo, VarTypeId, UniMode,
-				Det, ModeNum) },
-		{ call_gen__input_args(ArgInfo, InputArguments) },
-		call_gen__generate_call_livevals(OutArgs, InputArguments,
-			CodeC0),
-		{ call_gen__output_arg_locs(Args, OutputArguments) },
-		call_gen__generate_return_livevals(OutArgs, OutputArguments, 
-				GoalInfo, OutLiveVals),
-		{ code_util__make_uni_label(ModuleInfo, VarTypeId, ModeNum,
-			UniLabel) },
-		{ Address = imported(UniLabel) },
-	/\************
-		% Currently we just conservatively assume the address
-		% of a unification predicate is imported.  For
-		% non-standard modes, we could do better, if
-		% procs_per_c_function is zero (meaning infinity),
-		% or if it is a recursive call.
-		% But the code below doesn't work if procs_per_c_function
-		% is non-zero and it's not a recursive call.
-		{ ModeNum = 0 ->
-			Address = imported(UniLabel)
-		;
-			Address = label(local(UniLabel))
-		},
-	**************\/
-		(
-			{ CanFail = can_fail }
-		->
-			{ CallModel = semidet }
-		;
-			{ CallModel = det }
-		),
-		{ CodeC1 = node([
-			call(Address, label(ReturnLabel),
-				OutLiveVals, CallModel)
-				- "branch to out-of-line unification procedure",
-			label(ReturnLabel) - "Continuation label"
-		]) }
-	;
-		% `type_to_type_id' failed - the type must be a type variable,
-		% i.e. it is a polymorphic unification.
-		% However, these sorts of unifications should have been changed
-		% into calls to unify/2 by polymorphism.m, so if we encounter
-		% any here, it's an internal error.
-		{ error("unexpected polymorphic unification") }
-	),
-	(
-		{ CanFail = can_fail }
-	->
-		code_info__get_next_label(ContLab),
-		call_gen__rebuild_registers(Args),
-		code_info__generate_failure(FailCode),
-		{ CodeD = tree(node([
-			if_val(lval(reg(r(1))), label(ContLab)) -
-				"Test for success"
-			]), tree(FailCode, node([ label(ContLab) - "" ]))) }
-	;
-		call_gen__rebuild_registers(Args),
-		{ CodeD = empty }
-	),
-
-	{ Code = tree(CodeA, tree(CodeB, tree(tree(CodeC0, CodeC1), CodeD))) }.
-*/
 
 %---------------------------------------------------------------------------%
 
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.52
diff -u -r1.52 code_gen.m
--- code_gen.m	1998/06/18 06:05:48	1.52
+++ code_gen.m	1998/07/02 04:19:14
@@ -1,28 +1,29 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1996-1998 The University of Melbourne.
+% Copyright (C) 1994-1998 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %---------------------------------------------------------------------------%
 %
 % Code generation - convert from HLDS to LLDS.
 %
-% Main author: conway.
+% Main authors: conway, zs.
 %
-% Notes:
+% The two main tasks of this module are
 %
-%	code_gen forwards most of the actual construction of intruction
-%	sequences to code_info, and other modules. The generation of
-%	calls is done by call_gen, switches by switch_gen, if-then-elses
-%	by ite_gen, unifications by unify_gen, disjunctions by disj_gen,
-%	and pragma_c_codes by pragma_c_gen.
+% 1	to look after the aspects of generating code for a procedure
+%	that do not involve generating code for a specific goal, and
 %
-%	The general scheme for generating semideterministic code is
-%	to treat it as deterministic code, and have a fall-through
-%	point for failure.  Semideterministic procedures leave a 'true'
-%	in register r(1) to indicate success, and 'false' to indicate
-%	failure.
+% 2	to provide a generic predicate that can be called from anywhere in
+%	the code generator to generate code for a goal.
+%
+% Code_gen forwards most of the actual construction of code for particular
+% goals to other modules. The generation of code for unifications is done
+% by unify_gen, for calls, higher-order calls and method calls by call_gen,
+% for commits by commit_gen, for if-then-elses and negations by ite_gen,
+% for switches by switch_gen and its subsidiary modules, for disjunctions
+% by disj_gen, and for pragma_c_codes by pragma_c_gen. The only kind of goal
+% handled directly by code_gen is the conjunction.
 %
-%---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 
 :- module code_gen.
@@ -31,26 +32,27 @@
 
 :- import_module hlds_module, hlds_pred, hlds_goal, llds, code_info.
 :- import_module continuation_info, globals.
-:- import_module set, list, assoc_list, term, io.
+:- import_module list, io.
 
-		% Translate a HLDS structure into an LLDS
+		% Translate a HLDS module to LLDS.
 
-:- pred generate_code(module_info, module_info, list(c_procedure),
-						io__state, io__state).
-:- mode generate_code(in, out, out, di, uo) is det.
+:- pred generate_code(module_info::in, module_info::out,
+	list(c_procedure)::out, io__state::di, io__state::uo) is det.
 
-:- pred generate_proc_code(proc_info, proc_id, pred_id, module_info, globals,
-	continuation_info, int, continuation_info, int, c_procedure).
-:- mode generate_proc_code(in, in, in, in, in, in, in, out, out, out) is det.
+		% Translate a HLDS procedure to LLDS, threading through
+		% the data structure that records information about layout
+		% structures and the counter for ensuring the uniqueness
+		% of cell numbers.
 
-		% This predicate generates code for a goal.
+:- pred generate_proc_code(proc_info::in, proc_id::in, pred_id::in,
+	module_info::in, globals::in,
+	continuation_info::in, continuation_info::out, int::in, int::out,
+	c_procedure::out) is det.
 
-:- pred code_gen__generate_goal(code_model, hlds_goal, code_tree,
-						code_info, code_info).
-:- mode code_gen__generate_goal(in, in, out, in, out) is det.
+		% Translate a HLDS goal to LLDS.
 
-:- pred code_gen__output_args(assoc_list(var, arg_info), set(lval)).
-:- mode code_gen__output_args(in, out) is det.
+:- pred code_gen__generate_goal(code_model::in, hlds_goal::in, code_tree::out,
+	code_info::in, code_info::out) is det.
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
@@ -58,18 +60,16 @@
 :- implementation.
 
 :- import_module call_gen, unify_gen, ite_gen, switch_gen, disj_gen.
-:- import_module par_conj_gen, pragma_c_gen, trace, options, hlds_out.
+:- import_module par_conj_gen, pragma_c_gen, commit_gen.
+:- import_module trace, options, hlds_out.
 :- import_module code_aux, middle_rec, passes_aux, llds_out.
 :- import_module code_util, type_util, mode_util.
 :- import_module prog_data, prog_out, instmap.
 :- import_module bool, char, int, string.
-:- import_module map, tree, std_util, require, varset.
+:- import_module map, assoc_list, set, term, tree, std_util, require, varset.
 
 %---------------------------------------------------------------------------%
 
-% For a set of high level data structures and associated data, given in
-% ModuleInfo, generate a list of c_procedure structures.
-
 generate_code(ModuleInfo0, ModuleInfo, Procedures) -->
 		% get a list of all the predicate ids
 		% for which we are going to generate code.
@@ -77,12 +77,11 @@
 		% now generate the code for each predicate
 	generate_pred_list_code(ModuleInfo0, ModuleInfo, PredIds, Procedures).
 
-% Generate a list of c_procedure structures for each mode of each
-% predicate given in ModuleInfo
+	% Translate a list of HLDS predicates to LLDS.
 
-:- pred generate_pred_list_code(module_info, module_info, list(pred_id), 
-				list(c_procedure), io__state, io__state).
-:- mode generate_pred_list_code(in, out, in, out, di, uo) is det.
+:- pred generate_pred_list_code(module_info::in, module_info::out,
+	list(pred_id)::in, list(c_procedure)::out,
+	io__state::di, io__state::uo) is det.
 
 generate_pred_list_code(ModuleInfo, ModuleInfo, [], []) --> [].
 generate_pred_list_code(ModuleInfo0, ModuleInfo, [PredId | PredIds],
@@ -104,12 +103,11 @@
 		% and generate the code for the rest of the predicates
 	generate_pred_list_code(ModuleInfo1, ModuleInfo, PredIds, Predicates1).
 
-% For the predicate identified by PredId, with the the associated
-% data in ModuleInfo, generate a code_tree.
+	% Translate a HLDS predicate to LLDS.
 
-:- pred generate_pred_code(module_info, module_info, pred_id, pred_info,
-		list(proc_id), list(c_procedure), io__state, io__state).
-:- mode generate_pred_code(in, out, in, in, in, out, di, uo) is det.
+:- pred generate_pred_code(module_info::in, module_info::out,
+	pred_id::in, pred_info::in, list(proc_id)::in, list(c_procedure)::out,
+	io__state::di, io__state::uo) is det.
 
 generate_pred_code(ModuleInfo0, ModuleInfo, PredId, PredInfo, ProcIds, Code) -->
 	globals__io_lookup_bool_option(very_verbose, VeryVerbose),
@@ -122,7 +120,6 @@
 	;
 		[]
 	),
-		% generate all the procedures for this predicate
 	{ module_info_get_continuation_info(ModuleInfo0, ContInfo0) },
 	{ module_info_get_cell_count(ModuleInfo0, CellCount0) },
 	globals__io_get_globals(Globals),
@@ -133,16 +130,12 @@
 	{ module_info_set_continuation_info(ModuleInfo1, ContInfo, 
 		ModuleInfo) }.
 
-% For all the modes of predicate PredId, generate the appropriate
-% code (deterministic, semideterministic, or nondeterministic).
+	% Translate all the procedures of a HLDS predicate to LLDS.
 
-:- pred generate_proc_list_code(list(proc_id), pred_id, pred_info, module_info,
-	globals, continuation_info, continuation_info, int, int,
-	list(c_procedure), list(c_procedure)).
-% :- mode generate_proc_list_code(in, in, in, in, in, di, uo, di, uo)
-%	is det.
-:- mode generate_proc_list_code(in, in, in, in, in, in, out, in, out, in, out)
-	is det.
+:- pred generate_proc_list_code(list(proc_id)::in, pred_id::in, pred_info::in,
+	module_info::in, globals::in,
+	continuation_info::in, continuation_info::out, int::in, int::out,
+	list(c_procedure)::in, list(c_procedure)::out) is det.
 
 generate_proc_list_code([], _PredId, _PredInfo, _ModuleInfo, _Globals,
 		ContInfo, ContInfo, CellCount, CellCount, Procs, Procs).
@@ -150,10 +143,9 @@
 		Globals, ContInfo0, ContInfo, CellCount0, CellCount,
 		Procs0, Procs) :-
 	pred_info_procedures(PredInfo, ProcInfos),
-		% locate the proc_info structure for this mode of the predicate
 	map__lookup(ProcInfos, ProcId, ProcInfo),
 	generate_proc_code(ProcInfo, ProcId, PredId, ModuleInfo0, Globals,
-		ContInfo0, CellCount0, ContInfo1, CellCount1, Proc),
+		ContInfo0, ContInfo1, CellCount0, CellCount1, Proc),
 	generate_proc_list_code(ProcIds, PredId, PredInfo, ModuleInfo0,
 		Globals, ContInfo1, ContInfo, CellCount1, CellCount,
 		[Proc | Procs0], Procs).
@@ -179,13 +171,10 @@
 %---------------------------------------------------------------------------%
 
 generate_proc_code(ProcInfo, ProcId, PredId, ModuleInfo, Globals,
-		ContInfo0, CellCount0, ContInfo, CellCount, Proc) :-
-		% find out if the proc is deterministic/etc
+		ContInfo0, ContInfo, CellCount0, CellCount, Proc) :-
 	proc_info_interface_determinism(ProcInfo, Detism),
 	proc_info_interface_code_model(ProcInfo, CodeModel),
-		% get the goal for this procedure
 	proc_info_goal(ProcInfo, Goal),
-		% get the information about this procedure that we need.
 	proc_info_varset(ProcInfo, VarSet),
 	proc_info_liveness_info(ProcInfo, Liveness),
 	proc_info_stack_slots(ProcInfo, StackSlots),
@@ -205,39 +194,45 @@
 	;
 		SaveSuccip = no
 	),
-		% initialise the code_info structure 
+		% Initialise the code_info structure. Generate_category_code
+		% below will use the returned OutsideResumePoint as the
+		% entry to the code that handles the failure of the procedure,
+		% if such code is needed. It is never needed for model_det
+		% procedures, always needed for model_semi procedures, and
+		% needed for model_non procedures only if we are doing
+		% execution tracing.
 	code_info__init(VarSet, Liveness, StackSlots, SaveSuccip, Globals,
 		PredId, ProcId, ProcInfo, InitialInst, FollowVars,
-		ModuleInfo, CellCount0, CodeInfo0),
-		% generate code for the procedure
-	globals__get_trace_level(Globals, TraceLevel),
-	code_util__make_proc_label(ModuleInfo, PredId, ProcId, ProcLabel),
-	( trace_level_trace_interface(TraceLevel, yes) ->
-		trace__setup(TraceLevel, CodeInfo0, CodeInfo1)
-	;
-		CodeInfo1 = CodeInfo0
-	),
-	generate_category_code(CodeModel, Goal, ProcInfo, CodeTree,
-		MaybeTraceCallLabel, FrameInfo, CodeInfo1, CodeInfo),
-		% extract the new continuation_info and cell count
-	code_info__get_cell_count(CellCount, CodeInfo, _CodeInfo1),
+		ModuleInfo, CellCount0, OutsideResumePoint, CodeInfo0),
+
+		% Generate code for the procedure.
+	generate_category_code(CodeModel, Goal, OutsideResumePoint,
+		CodeTree, MaybeTraceCallLabel, FrameInfo, CodeInfo0, CodeInfo),
+	code_info__get_cell_count(CellCount, CodeInfo, _),
 
-		% turn the code tree into a list
+		% Turn the code tree into a list.
 	tree__flatten(CodeTree, FragmentList),
-		% now the code is a list of code fragments (== list(instr)),
+		% Now the code is a list of code fragments (== list(instr)),
 		% so we need to do a level of unwinding to get a flat list.
 	list__condense(FragmentList, Instructions0),
 	FrameInfo = frame(TotalSlots, MaybeSuccipSlot, _),
 	(
 		MaybeSuccipSlot = yes(SuccipSlot)
 	->
+			% The set of recorded live values at calls (for value
+			% numbering) and returns (for accurate gc and execution
+			% tracing) do not yet record the stack slot holding the
+			% succip, so add it to those sets.
 		code_gen__add_saved_succip(Instructions0,
 			SuccipSlot, Instructions)
 	;
 		Instructions = Instructions0
 	),
 	( BasicStackLayout = yes ->
-		code_info__get_layout_info(LayoutInfo, CodeInfo, _CodeInfo2),
+			% Create the procedure layout structure.
+		code_util__make_proc_label(ModuleInfo, PredId, ProcId,
+			ProcLabel),
+		code_info__get_layout_info(LayoutInfo, CodeInfo, _),
 		continuation_info__add_proc_info(proc(PredId, ProcId),
 			ProcLabel, TotalSlots, Detism, MaybeSuccipSlot,
 			MaybeTraceCallLabel, LayoutInfo, ContInfo0, ContInfo)
@@ -245,13 +240,13 @@
 		ContInfo = ContInfo0
 	),
 
-		% get the name and arity of this predicate
 	predicate_name(ModuleInfo, PredId, Name),
 	predicate_arity(ModuleInfo, PredId, Arity),
-		% construct a c_procedure structure with all the information
+		% Construct a c_procedure structure with all the information.
 	Proc = c_procedure(Name, Arity, proc(PredId, ProcId), Instructions).
 
 %---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
 
 	% Generate_category_code generates code for an entire procedure.
 	% Its algorithm has three or four main stages:
@@ -296,11 +291,11 @@
 	% continuation needs no code. Only model_semi procedures need code
 	% for the failure continuation at all times.)
 
-:- pred generate_category_code(code_model, hlds_goal, proc_info, code_tree,
-	maybe(label), frame_info, code_info, code_info).
-:- mode generate_category_code(in, in, in, out, out, out, in, out) is det.
+:- pred generate_category_code(code_model::in, hlds_goal::in,
+	resume_point_info::in, code_tree::out, maybe(label)::out,
+	frame_info::out, code_info::in, code_info::out) is det.
 
-generate_category_code(model_det, Goal, ProcInfo, Code,
+generate_category_code(model_det, Goal, ResumePoint, Code,
 		MaybeTraceCallLabel, FrameInfo) -->
 		% generate the code for the body of the clause
 	(
@@ -312,18 +307,8 @@
 		{ MaybeTraceCallLabel = no },
 		{ FrameInfo = frame(0, no, no) }
 	;
-		% make a new failure cont (not model_non);
-		% this continuation is never actually used,
-		% but is a place holder
-		code_info__manufacture_failure_cont(no),
-
 		code_info__get_maybe_trace_info(MaybeTraceInfo),
 		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			code_info__get_module_info(ModuleInfo),
-			{ trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
-				% Protect these vars from being forgotten,
-				% so they will be around for the exit trace.
-			code_info__push_resume_point_vars(ResumeVars),
 			trace__generate_external_event_code(call, TraceInfo,
 				TraceCallLabel, _TypeInfos, TraceCallCode),
 			{ MaybeTraceCallLabel = yes(TraceCallLabel) }
@@ -332,8 +317,8 @@
 			{ MaybeTraceCallLabel = no }
 		),
 		code_gen__generate_goal(model_det, Goal, BodyCode),
-		code_gen__generate_entry(model_det, Goal, FrameInfo,
-			EntryCode),
+		code_gen__generate_entry(model_det, Goal, ResumePoint,
+			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_det, FrameInfo, _, ExitCode),
 		{ Code =
 			tree(EntryCode,
@@ -343,55 +328,49 @@
 		}
 	).
 
-generate_category_code(model_semi, Goal, ProcInfo, Code,
+generate_category_code(model_semi, Goal, ResumePoint, Code,
 		MaybeTraceCallLabel, FrameInfo) -->
-		% make a new failure cont (not model_non)
-	code_info__manufacture_failure_cont(no),
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
 	{ set__singleton_set(FailureLiveRegs, reg(r, 1)) },
 	{ FailCode = node([
 		assign(reg(r, 1), const(false)) - "Fail",
 		livevals(FailureLiveRegs) - "",
 		goto(succip) - "Return from procedure call"
 	]) },
+	code_info__get_maybe_trace_info(MaybeTraceInfo),
 	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		code_info__get_module_info(ModuleInfo),
-		{ trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
-		code_info__make_known_failure_cont(ResumeVars, orig_and_stack,
-			no, SetupCode),
-		code_info__push_resume_point_vars(ResumeVars),
 		trace__generate_external_event_code(call, TraceInfo,
 			TraceCallLabel, _TypeInfos, TraceCallCode),
 		{ MaybeTraceCallLabel = yes(TraceCallLabel) },
 		code_gen__generate_goal(model_semi, Goal, BodyCode),
-		code_gen__generate_entry(model_semi, Goal, FrameInfo,
-			EntryCode),
+		code_gen__generate_entry(model_semi, Goal, ResumePoint,
+			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_semi, FrameInfo,
 			RestoreDeallocCode, ExitCode),
-		code_info__pop_resume_point_vars,
-		code_info__restore_failure_cont(ResumeCode),
+
+		code_info__generate_resume_point(ResumePoint, ResumeCode),
+		{ code_info__resume_point_vars(ResumePoint, ResumeVarList) },
+		{ set__list_to_set(ResumeVarList, ResumeVars) },
 		code_info__set_forward_live_vars(ResumeVars),
 		trace__generate_external_event_code(fail, TraceInfo, _, _,
 			TraceFailCode),
 		{ Code =
 			tree(EntryCode,
-			tree(SetupCode,
 			tree(TraceCallCode,
 			tree(BodyCode,
 			tree(ExitCode,
 			tree(ResumeCode,
 			tree(TraceFailCode,
 			tree(RestoreDeallocCode,
-			     FailCode))))))))
+			     FailCode)))))))
 		}
 	;
 		{ MaybeTraceCallLabel = no },
 		code_gen__generate_goal(model_semi, Goal, BodyCode),
-		code_gen__generate_entry(model_semi, Goal, FrameInfo,
-			EntryCode),
+		code_gen__generate_entry(model_semi, Goal, ResumePoint,
+			FrameInfo, EntryCode),
 		code_gen__generate_exit(model_semi, FrameInfo,
 			RestoreDeallocCode, ExitCode),
-		code_info__restore_failure_cont(ResumeCode),
+		code_info__generate_resume_point(ResumePoint, ResumeCode),
 		{ Code =
 			tree(EntryCode,
 			tree(BodyCode,
@@ -402,52 +381,46 @@
 		}
 	).
 
-generate_category_code(model_non, Goal, ProcInfo, Code,
+generate_category_code(model_non, Goal, ResumePoint, Code,
 		MaybeTraceCallLabel, FrameInfo) -->
-		% make a new failure cont (yes, it is model_non)
-	code_info__manufacture_failure_cont(yes),
-		% we must arrange the tracing of failure out of this proc
 	code_info__get_maybe_trace_info(MaybeTraceInfo),
 	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		code_info__get_module_info(ModuleInfo),
-		{ trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
-		code_info__make_known_failure_cont(ResumeVars, orig_and_stack,
-			yes, SetupCode),
-		code_info__push_resume_point_vars(ResumeVars),
 		trace__generate_external_event_code(call, TraceInfo,
 			TraceCallLabel, _TypeInfos, TraceCallCode),
 		{ MaybeTraceCallLabel = yes(TraceCallLabel) },
 		code_gen__generate_goal(model_non, Goal, BodyCode),
-		code_gen__generate_entry(model_non, Goal, FrameInfo,
-			PrologCode),
-		code_gen__generate_exit(model_non, FrameInfo, _, EpilogCode),
-
-		code_info__pop_resume_point_vars,
-		code_info__restore_failure_cont(RestoreCode),
+		code_gen__generate_entry(model_non, Goal, ResumePoint,
+			FrameInfo, EntryCode),
+		code_gen__generate_exit(model_non, FrameInfo, _, ExitCode),
+
+		code_info__generate_resume_point(ResumePoint, ResumeCode),
+		{ code_info__resume_point_vars(ResumePoint, ResumeVarList) },
+		{ set__list_to_set(ResumeVarList, ResumeVars) },
 		code_info__set_forward_live_vars(ResumeVars),
 		trace__generate_external_event_code(fail, TraceInfo, _, _,
 			TraceFailCode),
-		code_info__generate_failure(FailCode),
+		{ FailCode = node([
+			goto(do_fail) - "fail after fail trace port"
+		]) },
 		{ Code =
-			tree(PrologCode,
-			tree(SetupCode,
+			tree(EntryCode,
 			tree(TraceCallCode,
 			tree(BodyCode,
-			tree(EpilogCode,
-			tree(RestoreCode,
+			tree(ExitCode,
+			tree(ResumeCode,
 			tree(TraceFailCode,
-			     FailCode)))))))
+			     FailCode))))))
 		}
 	;
 		{ MaybeTraceCallLabel = no },
 		code_gen__generate_goal(model_non, Goal, BodyCode),
-		code_gen__generate_entry(model_non, Goal, FrameInfo,
-			PrologCode),
-		code_gen__generate_exit(model_non, FrameInfo, _, EpilogCode),
+		code_gen__generate_entry(model_non, Goal, ResumePoint,
+			FrameInfo, EntryCode),
+		code_gen__generate_exit(model_non, FrameInfo, _, ExitCode),
 		{ Code =
-			tree(PrologCode,
+			tree(EntryCode,
 			tree(BodyCode,
-			     EpilogCode))
+			     ExitCode))
 		}
 	).
 
@@ -472,11 +445,12 @@
 	% need a stack frame, and if the procedure is nondet, then the code
 	% to fill in the succip slot is subsumed by the mkframe.
 
-:- pred code_gen__generate_entry(code_model, hlds_goal, frame_info,
-	code_tree, code_info, code_info).
-:- mode code_gen__generate_entry(in, in, out, out, in, out) is det.
+:- pred code_gen__generate_entry(code_model::in, hlds_goal::in,
+	resume_point_info::in, frame_info::out, code_tree::out,
+	code_info::in, code_info::out) is det.
 
-code_gen__generate_entry(CodeModel, Goal, FrameInfo, PrologCode) -->
+code_gen__generate_entry(CodeModel, Goal, OutsideResumePoint,
+		FrameInfo, EntryCode) -->
 	code_info__get_stack_slots(StackSlots),
 	code_info__get_varset(VarSet),
 	{ code_aux__explain_stack_slots(StackSlots, VarSet, SlotsComment) },
@@ -529,6 +503,8 @@
 	(
 		{ CodeModel = model_non }
 	->
+		{ code_info__resume_point_stack_addr(OutsideResumePoint,
+			OutsideResumeAddress) },
 		(
 			{ Goal = pragma_c_code(_,_,_,_,_,_, PragmaCode) - _},
 			{ PragmaCode = nondet(Fields, FieldsContext,
@@ -541,9 +517,10 @@
 			{ string__format("#define\tMR_ORDINARY_SLOTS\t%d\n",
 				[i(TotalSlots)], DefineStr) },
 			{ DefineComponents = [pragma_c_raw_code(DefineStr)] },
+			{ NondetFrameInfo = ordinary_frame(PushMsg, TotalSlots,
+				yes(Struct)) },
 			{ AllocCode = node([
-				mkframe(PushMsg, TotalSlots, yes(Struct),
-					do_fail)
+				mkframe(NondetFrameInfo, OutsideResumeAddress)
 					- "Allocate stack frame",
 				pragma_c([], DefineComponents,
 					will_not_call_mercury, no, no)
@@ -551,9 +528,11 @@
 			]) },
 			{ NondetPragma = yes }
 		;
+			{ NondetFrameInfo = ordinary_frame(PushMsg, TotalSlots,
+				no) },
 			{ AllocCode = node([
-				mkframe(PushMsg, TotalSlots, no, do_fail) -
-					"Allocate stack frame"
+				mkframe(NondetFrameInfo, OutsideResumeAddress)
+					- "Allocate stack frame"
 			]) },
 			{ NondetPragma = no }
 		)
@@ -573,7 +552,7 @@
 	{ EndComment = node([
 		comment("End of procedure prologue") - ""
 	]) },
-	{ PrologCode =
+	{ EntryCode =
 		tree(StartComment,
 		tree(LabelCode,
 		tree(AllocCode,
@@ -612,12 +591,10 @@
 	% of the epilogue are handled when traversing the pragma C code goal;
 	% we need only #undef a macro defined by the procedure prologue.
 
-:- pred code_gen__generate_exit(code_model, frame_info, code_tree, code_tree,
-	code_info, code_info).
-:- mode code_gen__generate_exit(in, in, out, out, in, out) is det.
+:- pred code_gen__generate_exit(code_model::in, frame_info::in,
+	code_tree::out, code_tree::out, code_info::in, code_info::out) is det.
 
-code_gen__generate_exit(CodeModel, FrameInfo, RestoreDeallocCode, EpilogCode)
-		-->
+code_gen__generate_exit(CodeModel, FrameInfo, RestoreDeallocCode, ExitCode) -->
 	{ StartComment = node([
 		comment("Start of procedure epilogue") - ""
 	]) },
@@ -634,7 +611,7 @@
 				- ""
 		]) },
 		{ RestoreDeallocCode = empty },	% always empty for nondet code
-		{ EpilogCode =
+		{ ExitCode =
 			tree(StartComment,
 			tree(UndefCode,
 			     EndComment))
@@ -727,7 +704,7 @@
 				     SuccessCode)
 			}
 		),
-		{ EpilogCode =
+		{ ExitCode =
 			tree(StartComment,
 			tree(FlushCode,
 			tree(AllSuccessCode,
@@ -754,26 +731,29 @@
 		{ instmap__is_reachable(Instmap) }
 	->
 		{ goal_info_get_code_model(GoalInfo, CodeModel) },
-		(
-			{ CodeModel = model_det },
-			code_gen__generate_det_goal_2(Goal, GoalInfo, Code)
-		;
-			{ CodeModel = model_semi },
-			( { ContextModel \= model_det } ->
-				code_gen__generate_semi_goal_2(Goal, GoalInfo,
-					Code)
+
+			% sanity check: code of some code models
+			% should occur only in limited contexts
+		{
+			CodeModel = model_det
+		;
+			CodeModel = model_semi,
+			( ContextModel \= model_det ->
+				true
 			;
-				{ error("semidet model in det context") }
+				error("semidet model in det context")
 			)
 		;
-			{ CodeModel = model_non },
-			( { ContextModel = model_non } ->
-				code_gen__generate_non_goal_2(Goal, GoalInfo,
-					Code)
+			CodeModel = model_non,
+			( ContextModel = model_non ->
+				true
 			;
-				{ error("nondet model in det/semidet context") }
+				error("nondet model in det/semidet context")
 			)
-		),
+		},
+
+		code_gen__generate_goal_2(Goal, GoalInfo, CodeModel, Code),
+
 			% Make live any variables which subsequent goals
 			% will expect to be live, but were not generated
 		code_info__set_instmap(Instmap),
@@ -785,399 +765,80 @@
 
 %---------------------------------------------------------------------------%
 
-% Generate a conjoined series of goals.
-% Note of course, that with a conjunction, state information
-% flows directly from one conjunct to the next.
-
-:- pred code_gen__generate_goals(hlds_goals, code_model, code_tree,
-							code_info, code_info).
-:- mode code_gen__generate_goals(in, in, out, in, out) is det.
+:- pred code_gen__generate_goal_2(hlds_goal_expr::in, hlds_goal_info::in,
+	code_model::in, code_tree::out, code_info::in, code_info::out) is det.
 
-code_gen__generate_goals([], _, empty) --> [].
-code_gen__generate_goals([Goal | Goals], CodeModel, Instr) -->
-	code_gen__generate_goal(CodeModel, Goal, Instr1),
-	code_info__get_instmap(Instmap),
-	(
-		{ instmap__is_unreachable(Instmap) }
-	->
-		{ Instr = Instr1 }
-	;
-		code_gen__generate_goals(Goals, CodeModel, Instr2),
-		{ Instr = tree(Instr1, Instr2) }
-	).
-
-%---------------------------------------------------------------------------%
-
-:- pred code_gen__generate_det_goal_2(hlds_goal_expr, hlds_goal_info,
-					code_tree, code_info, code_info).
-:- mode code_gen__generate_det_goal_2(in, in, out, in, out) is det.
-
-code_gen__generate_det_goal_2(conj(Goals), _GoalInfo, Instr) -->
-	code_gen__generate_goals(Goals, model_det, Instr).
-code_gen__generate_det_goal_2(par_conj(Goals, _StoreMap), GoalInfo, Instr) -->
-	par_conj_gen__generate_det_par_conj(Goals, GoalInfo, Instr).
-code_gen__generate_det_goal_2(some(_Vars, Goal), _GoalInfo, Instr) -->
-	{ Goal = _ - InnerGoalInfo },
-	{ goal_info_get_code_model(InnerGoalInfo, CodeModel) },
-	(
-		{ CodeModel = model_det },
-		code_gen__generate_goal(model_det, Goal, Instr)
-	;
-		{ CodeModel = model_semi },
-		{ error("semidet model in det context") }
-	;
-		{ CodeModel = model_non },
-		code_info__generate_det_pre_commit(Slots, PreCommit),
-		code_gen__generate_goal(model_non, Goal, GoalCode),
-		code_info__generate_det_commit(Slots, Commit),
-		{ Instr = tree(PreCommit, tree(GoalCode, Commit)) }
-	).
-code_gen__generate_det_goal_2(disj(Goals, StoreMap), _GoalInfo, Instr) -->
-	disj_gen__generate_det_disj(Goals, StoreMap, Instr).
-code_gen__generate_det_goal_2(not(Goal), _GoalInfo, Instr) -->
-	code_gen__generate_negation(model_det, Goal, Instr).
-code_gen__generate_det_goal_2(higher_order_call(PredVar, Args, Types,
-		Modes, Det, _PredOrFunc),
-		GoalInfo, Instr) -->
-	call_gen__generate_higher_order_call(model_det, PredVar, Args,
-		Types, Modes, Det, GoalInfo, Instr).
-code_gen__generate_det_goal_2(class_method_call(TCVar, Num, Args, Types,
-		Modes, Det),
-		GoalInfo, Instr) -->
-	call_gen__generate_class_method_call(model_det, TCVar, Num, Args,
-		Types, Modes, Det, GoalInfo, Instr).
-code_gen__generate_det_goal_2(call(PredId, ProcId, Args, BuiltinState, _, _),
-		GoalInfo, Instr) -->
-	(
-		{ BuiltinState = not_builtin }
-	->
-		code_info__succip_is_used,
-		call_gen__generate_call(model_det, PredId, ProcId, Args,
-			GoalInfo, Instr)
-	;
-		call_gen__generate_det_builtin(PredId, ProcId, Args, Instr)
-	).
-code_gen__generate_det_goal_2(switch(Var, CanFail, CaseList, StoreMap),
-		GoalInfo, Instr) -->
-	switch_gen__generate_switch(model_det, Var, CanFail, CaseList,
-		StoreMap, GoalInfo, Instr).
-code_gen__generate_det_goal_2(
-		if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal, StoreMap),
-							_GoalInfo, Instr) -->
-	ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, StoreMap,
-		Instr).
-code_gen__generate_det_goal_2(unify(_L, _R, _U, Uni, _C), _GoalInfo, Instr) -->
-	(
-		{ Uni = assign(Left, Right) },
-		unify_gen__generate_assignment(Left, Right, Instr)
-	;
-		{ Uni = construct(Var, ConsId, Args, Modes) },
-		unify_gen__generate_construction(Var, ConsId, Args,
-								Modes, Instr)
-	;
-		{ Uni = deconstruct(Var, ConsId, Args, Modes, _Det) },
-		unify_gen__generate_det_deconstruction(Var, ConsId, Args,
-								Modes, Instr)
-	;
-		% These should have been transformed into calls by
-		% polymorphism.m.
-		{ Uni = complicated_unify(_UniMode, _CanFail) },
-		{ error("code_gen__generate_det_goal_2 - complicated unify") }
-	;
-		{ Uni = simple_test(_, _) },
-		{ error("generate_det_goal_2: cannot have det simple_test") }
-	).
-
-code_gen__generate_det_goal_2(pragma_c_code(MayCallMercury,
-		PredId, ModeId, Args, ArgNames, OrigArgTypes, PragmaCode),
-		GoalInfo, Instr) -->
-	pragma_c_gen__generate_pragma_c_code(model_det, MayCallMercury,
-		PredId, ModeId, Args, ArgNames, OrigArgTypes, GoalInfo,
-		PragmaCode, Instr).
-
-%---------------------------------------------------------------------------%
-
-:- pred code_gen__generate_semi_goal_2(hlds_goal_expr, hlds_goal_info,
-					code_tree, code_info, code_info).
-:- mode code_gen__generate_semi_goal_2(in, in, out, in, out) is det.
-
-code_gen__generate_semi_goal_2(conj(Goals), _GoalInfo, Code) -->
-	code_gen__generate_goals(Goals, model_semi, Code).
-code_gen__generate_semi_goal_2(par_conj(_Goals, _SM), _GoalInfo, _Code) -->
-	% Determinism analysis will report a determinism error if the
-	% parallel conj is not det.
-	{ error("sorry, semidet parallel conjunction not implemented") }.
-code_gen__generate_semi_goal_2(some(_Vars, Goal), _GoalInfo, Code) -->
-	{ Goal = _ - InnerGoalInfo },
-	{ goal_info_get_code_model(InnerGoalInfo, CodeModel) },
-	(
-		{ CodeModel = model_det },
-		code_gen__generate_goal(model_det, Goal, Code)
-	;
-		{ CodeModel = model_semi },
-		code_gen__generate_goal(model_semi, Goal, Code)
-	;
-		{ CodeModel = model_non },
-		code_info__generate_semi_pre_commit(Label, Slots, PreCommit),
-		code_gen__generate_goal(model_non, Goal, GoalCode),
-		code_info__generate_semi_commit(Label, Slots, Commit),
-		{ Code = tree(PreCommit, tree(GoalCode, Commit)) }
-	).
-code_gen__generate_semi_goal_2(disj(Goals, StoreMap), _GoalInfo, Code) -->
-	disj_gen__generate_semi_disj(Goals, StoreMap, Code).
-code_gen__generate_semi_goal_2(not(Goal), _GoalInfo, Code) -->
-	code_gen__generate_negation(model_semi, Goal, Code).
-code_gen__generate_semi_goal_2(higher_order_call(PredVar, Args, Types, Modes,
-		Det, _PredOrFunc), GoalInfo, Code) -->
-	call_gen__generate_higher_order_call(model_semi, PredVar, Args,
+code_gen__generate_goal_2(unify(_, _, _, Uni, _), _, CodeModel, Code) -->
+	unify_gen__generate_unification(CodeModel, Uni, Code).
+code_gen__generate_goal_2(conj(Goals), _GoalInfo, CodeModel, Code) -->
+	code_gen__generate_goals(Goals, CodeModel, Code).
+code_gen__generate_goal_2(par_conj(Goals, _SM), GoalInfo, CodeModel, Code) -->
+	par_conj_gen__generate_par_conj(Goals, GoalInfo, CodeModel, Code).
+code_gen__generate_goal_2(disj(Goals, StoreMap), _, CodeModel, Code) -->
+	disj_gen__generate_disj(CodeModel, Goals, StoreMap, Code).
+code_gen__generate_goal_2(not(Goal), _GoalInfo, CodeModel, Code) -->
+	ite_gen__generate_negation(CodeModel, Goal, Code).
+code_gen__generate_goal_2(if_then_else(_Vars, Cond, Then, Else, StoreMap),
+		_GoalInfo, CodeModel, Code) -->
+	ite_gen__generate_ite(CodeModel, Cond, Then, Else, StoreMap, Code).
+code_gen__generate_goal_2(switch(Var, CanFail, CaseList, StoreMap),
+		GoalInfo, CodeModel, Code) -->
+	switch_gen__generate_switch(CodeModel, Var, CanFail, CaseList,
+		StoreMap, GoalInfo, Code).
+code_gen__generate_goal_2(some(_Vars, Goal), _GoalInfo, CodeModel, Code) -->
+	commit_gen__generate_commit(CodeModel, Goal, Code).
+code_gen__generate_goal_2(higher_order_call(PredVar, Args, Types,
+		Modes, Det, _PredOrFunc), GoalInfo, CodeModel, Code) -->
+	call_gen__generate_higher_order_call(CodeModel, PredVar, Args,
 		Types, Modes, Det, GoalInfo, Code).
-code_gen__generate_semi_goal_2(class_method_call(TCVar, Num, Args, Types, Modes,
-		Det), GoalInfo, Code) -->
-	call_gen__generate_class_method_call(model_semi, TCVar, Num, Args,
+code_gen__generate_goal_2(class_method_call(TCVar, Num, Args, Types,
+		Modes, Det), GoalInfo, CodeModel, Code) -->
+	call_gen__generate_class_method_call(CodeModel, TCVar, Num, Args,
 		Types, Modes, Det, GoalInfo, Code).
-code_gen__generate_semi_goal_2(call(PredId, ProcId, Args, BuiltinState, _, _),
-							GoalInfo, Code) -->
+code_gen__generate_goal_2(call(PredId, ProcId, Args, BuiltinState, _, _),
+		GoalInfo, CodeModel, Code) -->
 	(
 		{ BuiltinState = not_builtin }
 	->
-		code_info__succip_is_used,
-		call_gen__generate_call(model_semi, PredId, ProcId, Args,
+		call_gen__generate_call(CodeModel, PredId, ProcId, Args,
 			GoalInfo, Code)
 	;
-		call_gen__generate_semidet_builtin(PredId, ProcId, Args, Code)
-	).
-code_gen__generate_semi_goal_2(switch(Var, CanFail, CaseList, StoreMap),
-		GoalInfo, Instr) -->
-	switch_gen__generate_switch(model_semi, Var, CanFail,
-		CaseList, StoreMap, GoalInfo, Instr).
-code_gen__generate_semi_goal_2(
-		if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal, StoreMap),
-							_GoalInfo, Instr) -->
-	ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, StoreMap,
-		Instr).
-code_gen__generate_semi_goal_2(unify(_L, _R, _U, Uni, _C),
-							_GoalInfo, Code) -->
-	(
-		{ Uni = assign(Left, Right) },
-		unify_gen__generate_assignment(Left, Right, Code)
-	;
-		{ Uni = construct(Var, ConsId, Args, Modes) },
-		unify_gen__generate_construction(Var, ConsId, Args,
-								Modes, Code)
-	;
-		{ Uni = deconstruct(Var, ConsId, Args, Modes, _) },
-		unify_gen__generate_semi_deconstruction(Var, ConsId, Args,
-								Modes, Code)
-	;
-		{ Uni = simple_test(Var1, Var2) },
-		unify_gen__generate_test(Var1, Var2, Code)
-	;
-		{ Uni = complicated_unify(_UniMode, _CanFail) },
-		{ error("code_gen__generate_semi_goal_2 - complicated_unify") }
+		call_gen__generate_builtin(CodeModel, PredId, ProcId, Args,
+			Code)
 	).
+code_gen__generate_goal_2(pragma_c_code(MayCallMercury, PredId, ProcId,
+		Args, ArgNames, OrigArgTypes, PragmaImpl),
+		GoalInfo, CodeModel, Code) -->
+	pragma_c_gen__generate_pragma_c_code(CodeModel, MayCallMercury,
+		PredId, ProcId, Args, ArgNames, OrigArgTypes, GoalInfo,
+		PragmaImpl, Code).
 
-code_gen__generate_semi_goal_2(pragma_c_code(MayCallMercury,
-		PredId, ModeId, Args, ArgNames, OrigArgTypes, PragmaCode),
-		GoalInfo, Instr) -->
-	pragma_c_gen__generate_pragma_c_code(model_semi, MayCallMercury,
-		PredId, ModeId, Args, ArgNames, OrigArgTypes, GoalInfo,
-		PragmaCode, Instr).
-
-%---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 
-:- pred code_gen__generate_negation(code_model, hlds_goal, code_tree,
-	code_info, code_info).
-:- mode code_gen__generate_negation(in, in, out, in, out) is det.
-
-code_gen__generate_negation(CodeModel, Goal0, Code) -->
-	{ Goal0 = GoalExpr - GoalInfo0 },
-	{ goal_info_get_resume_point(GoalInfo0, Resume) },
-	(
-		{ Resume = resume_point(ResumeVarsPrime, ResumeLocsPrime) }
-	->
-		{ ResumeVars = ResumeVarsPrime},
-		{ ResumeLocs = ResumeLocsPrime}
-	;
-		{ error("negated goal has no resume point") }
-	),
-	code_info__push_resume_point_vars(ResumeVars),
-		% The next line is to enable Goal to pass the
-		% pre_goal_update sanity check
-	{ goal_info_set_resume_point(GoalInfo0, no_resume_point, GoalInfo) },
-	{ Goal = GoalExpr - GoalInfo },
-
-		% for a negated simple test, we can generate better code
-		% than the general mechanism, because we don't have to
-		% flush the cache.
-	(
-		{ CodeModel = model_semi },
-		{ GoalExpr = unify(_, _, _, simple_test(L, R), _) },
-		code_info__failure_is_direct_branch(CodeAddr),
-		code_info__get_globals(Globals),
-		{ globals__lookup_bool_option(Globals, simple_neg, yes) }
-	->
-			% Because we're generating a goal
-			% (special-cased, though it may be)
-			% we need to apply the pre- and post-
-			% updates.
-		code_info__pre_goal_update(GoalInfo, yes),
-		code_info__produce_variable(L, CodeL, ValL),
-		code_info__produce_variable(R, CodeR, ValR),
-		code_info__variable_type(L, Type),
-		{ Type = term__functor(term__atom("string"), [], _) ->
-			Op = str_eq
-		; Type = term__functor(term__atom("float"), [], _) ->
-			Op = float_eq
-		;
-			Op = eq
-		},
-		{ TestCode = node([
-			if_val(binop(Op, ValL, ValR), CodeAddr) -
-				"test inequality"
-		]) },
-		code_info__post_goal_update(GoalInfo),
-		{ Code = tree(tree(CodeL, CodeR), TestCode) }
-	;
-		code_gen__generate_negation_general(CodeModel, Goal,
-			ResumeVars, ResumeLocs, Code)
-	),
-	code_info__pop_resume_point_vars.
-
-:- pred code_gen__generate_negation_general(code_model, hlds_goal,
-	set(var), resume_locs, code_tree, code_info, code_info).
-:- mode code_gen__generate_negation_general(in, in, in, in, out, in, out)
-	is det.
-
-code_gen__generate_negation_general(CodeModel, Goal, ResumeVars, ResumeLocs,
-		Code) -->
-		% This code is a cut-down version of the code for semidet
-		% if-then-elses.
-
-	code_info__make_known_failure_cont(ResumeVars, ResumeLocs, no,
-		ModContCode),
-
-		% Maybe save the heap state current before the condition;
-		% this ought to be after we make the failure continuation
-		% because that causes the cache to get flushed
-	code_info__get_globals(Globals),
-	{
-		globals__lookup_bool_option(Globals,
-			reclaim_heap_on_semidet_failure, yes),
-		code_util__goal_may_allocate_heap(Goal)
-	->
-		ReclaimHeap = yes
-	;
-		ReclaimHeap = no
-	},
-	code_info__maybe_save_hp(ReclaimHeap, SaveHpCode, MaybeHpSlot),
-
-	{ globals__lookup_bool_option(Globals, use_trail, UseTrail) },
-	code_info__maybe_save_ticket(UseTrail, SaveTicketCode,
-		MaybeTicketSlot),
-
-		% Generate the condition as a semi-deterministic goal;
-		% it cannot be nondet, since mode correctness requires it
-		% to have no output vars
-	code_gen__generate_goal(model_semi, Goal, GoalCode),
-
-	( { CodeModel = model_det } ->
-		{ DiscardTicketCode = empty },
-		{ FailCode = empty }
-	;
-		code_info__grab_code_info(CodeInfo),
-		code_info__pop_failure_cont,
-		% The call to reset_ticket(..., commit) here is necessary
-		% in order to properly detect floundering.
-		code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot,
-			commit, DiscardTicketCode),
-		code_info__generate_failure(FailCode),
-		code_info__slap_code_info(CodeInfo)
-	),
-	code_info__restore_failure_cont(RestoreContCode),
-	code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot, undo,
-		RestoreTicketCode),
-	code_info__maybe_restore_and_discard_hp(MaybeHpSlot, RestoreHpCode),
-	{ Code = tree(ModContCode,
-		 tree(SaveHpCode,
-		 tree(SaveTicketCode,
-		 tree(GoalCode,
-		 tree(DiscardTicketCode, % is this necessary?
-		 tree(FailCode,
-		 tree(RestoreContCode,
-		 tree(RestoreTicketCode,
-		      RestoreHpCode)))))))) }.
+% Generate a conjoined series of goals.
+% Note of course, that with a conjunction, state information
+% flows directly from one conjunct to the next.
 
-%---------------------------------------------------------------------------%
-%---------------------------------------------------------------------------%
+:- pred code_gen__generate_goals(hlds_goals::in, code_model::in,
+	code_tree::out, code_info::in, code_info::out) is det.
 
-:- pred code_gen__generate_non_goal_2(hlds_goal_expr, hlds_goal_info,
-					code_tree, code_info, code_info).
-:- mode code_gen__generate_non_goal_2(in, in, out, in, out) is det.
-
-code_gen__generate_non_goal_2(conj(Goals), _GoalInfo, Code) -->
-	code_gen__generate_goals(Goals, model_non, Code).
-code_gen__generate_non_goal_2(par_conj(_Goals, _SM), _GoalInfo, _Code) -->
-		% Determinism analysis will report a determinism error if the
-		% parallel conj is not det.
-	{ error("sorry, nondet parallel conjunction not implemented") }.
-code_gen__generate_non_goal_2(some(_Vars, Goal), _GoalInfo, Code) -->
-	{ Goal = _ - InnerGoalInfo },
-	{ goal_info_get_code_model(InnerGoalInfo, CodeModel) },
-	code_gen__generate_goal(CodeModel, Goal, Code).
-code_gen__generate_non_goal_2(disj(Goals, StoreMap), _GoalInfo, Code) -->
-	disj_gen__generate_non_disj(Goals, StoreMap, Code).
-code_gen__generate_non_goal_2(not(_Goal), _GoalInfo, _Code) -->
-	{ error("Cannot have a nondet negation.") }.
-code_gen__generate_non_goal_2(higher_order_call(PredVar, Args, Types, Modes,
-		Det, _PredOrFunc),
-		GoalInfo, Code) -->
-	call_gen__generate_higher_order_call(model_non, PredVar, Args, Types,
-		Modes, Det, GoalInfo, Code).
-code_gen__generate_non_goal_2(class_method_call(TCVar, Num, Args, Types, Modes,
-		Det),
-		GoalInfo, Code) -->
-	call_gen__generate_class_method_call(model_non, TCVar, Num, Args, Types,
-		Modes, Det, GoalInfo, Code).
-code_gen__generate_non_goal_2(call(PredId, ProcId, Args, BuiltinState, _, _),
-							GoalInfo, Code) -->
+code_gen__generate_goals([], _, empty) --> [].
+code_gen__generate_goals([Goal | Goals], CodeModel, Instr) -->
+	code_gen__generate_goal(CodeModel, Goal, Instr1),
+	code_info__get_instmap(Instmap),
 	(
-		{ BuiltinState = not_builtin }
+		{ instmap__is_unreachable(Instmap) }
 	->
-		code_info__succip_is_used,
-		call_gen__generate_call(model_non, PredId, ProcId, Args,
-			GoalInfo, Code)
+		{ Instr = Instr1 }
 	;
-		call_gen__generate_nondet_builtin(PredId, ProcId, Args, Code)
+		code_gen__generate_goals(Goals, CodeModel, Instr2),
+		{ Instr = tree(Instr1, Instr2) }
 	).
-code_gen__generate_non_goal_2(switch(Var, CanFail, CaseList, StoreMap),
-		GoalInfo, Instr) -->
-	switch_gen__generate_switch(model_non, Var, CanFail,
-		CaseList, StoreMap, GoalInfo, Instr).
-code_gen__generate_non_goal_2(
-		if_then_else(_Vars, CondGoal, ThenGoal, ElseGoal, StoreMap),
-							_GoalInfo, Instr) -->
-	ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal,
-		StoreMap, Instr).
-code_gen__generate_non_goal_2(unify(_L, _R, _U, _Uni, _C),
-							_GoalInfo, _Code) -->
-	{ error("Cannot have a nondet unification.") }.
-code_gen__generate_non_goal_2(pragma_c_code(MayCallMercury,
-		PredId, ModeId, Args, ArgNames, OrigArgTypes, PragmaCode),
-		GoalInfo, Instr) -->
-	pragma_c_gen__generate_pragma_c_code(model_non, MayCallMercury,
-		PredId, ModeId, Args, ArgNames, OrigArgTypes, GoalInfo,
-		PragmaCode, Instr).
 
 %---------------------------------------------------------------------------%
 
-code_gen__output_args(Args, Vs) :-
-	code_gen__select_args_with_mode(Args, top_out, _, Lvals),
-	set__list_to_set(Lvals, Vs).
-
-:- pred code_gen__select_args_with_mode(assoc_list(var, arg_info), 
-	arg_mode, list(var), list(lval)).
-:- mode code_gen__select_args_with_mode(in, in, out, out) is det.
+:- pred code_gen__select_args_with_mode(assoc_list(var, arg_info)::in,
+	arg_mode::in, list(var)::out, list(lval)::out) is det.
 
 code_gen__select_args_with_mode([], _, [], []).
 code_gen__select_args_with_mode([Var - ArgInfo | Args], DesiredMode, Vs, Ls) :-
@@ -1194,15 +855,14 @@
 		Ls = Ls0
 	).
 
-
 %---------------------------------------------------------------------------%
 
 % Add the succip to the livevals before and after calls.
 % Traverses the list of instructions looking for livevals and calls,
 % adding succip in the stackvar number given as an argument.
 
-:- pred code_gen__add_saved_succip(list(instruction), int, list(instruction)).
-:- mode code_gen__add_saved_succip(in, in, out) is det.
+:- pred code_gen__add_saved_succip(list(instruction)::in, int::in,
+	list(instruction)::out) is det.
 
 code_gen__add_saved_succip([], _StackLoc, []).
 code_gen__add_saved_succip([Instrn0 - Comment | Instrns0 ], StackLoc, 
@@ -1211,7 +871,7 @@
 		Instrn0 = livevals(LiveVals0),
 		Instrns0 \= [goto(succip) - _ | _]
 		% XXX We should also test for tailcalls
-		% if we ever start generating them directly.
+		% once we start generating them directly.
 	->
 		set__insert(LiveVals0, stackvar(StackLoc), LiveVals1),
 		Instrn = livevals(LiveVals1)
@@ -1226,5 +886,4 @@
 	),
 	code_gen__add_saved_succip(Instrns0, StackLoc, Instrns).
 
-%---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%



More information about the developers mailing list