[m-rev.] for review: stack slot optimization, part 3

Zoltan Somogyi zs at cs.mu.OZ.AU
Sat Mar 9 20:21:42 AEDT 2002


Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.277
diff -u -b -r1.277 hlds_out.m
--- compiler/hlds_out.m	7 Mar 2002 08:29:51 -0000	1.277
+++ compiler/hlds_out.m	8 Mar 2002 04:04:23 -0000
@@ -261,6 +261,7 @@
 % HLDS modules.
 :- import_module mercury_to_mercury, purity, special_pred, instmap.
 :- import_module termination, term_errors, check_typeclass, rtti.
+:- import_module hlds_llds.
 
 % RL back-end modules (XXX should avoid using those here).
 :- import_module rl.
@@ -1195,9 +1196,12 @@
 		[]
 	),
 	( { string__contains_char(Verbose, 'p') } ->
-		{ goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
+		(
+			{ goal_info_maybe_get_pre_deaths(GoalInfo,
+				PreDeaths) },
 		{ set__to_sorted_list(PreDeaths, PreDeathList) },
-		( { PreDeathList \= [] } ->
+			{ PreDeathList \= [] }
+		->
 			hlds_out__write_indent(Indent),
 			io__write_string("% pre-deaths: "),
 			mercury_output_vars(PreDeathList, VarSet,
@@ -1206,9 +1210,12 @@
 		;
 			[]
 		),
-		{ goal_info_get_pre_births(GoalInfo, PreBirths) },
+		(
+			{ goal_info_maybe_get_pre_births(GoalInfo,
+				PreBirths) },
 		{ set__to_sorted_list(PreBirths, PreBirthList) },
-		( { PreBirthList \= [] } ->
+			{ PreBirthList \= [] }
+		->
 			hlds_out__write_indent(Indent),
 			io__write_string("% pre-births: "),
 			mercury_output_vars(PreBirthList, VarSet,
@@ -1220,25 +1227,6 @@
 	;
 		[]
 	),
-	( { string__contains_char(Verbose, 'f') } ->
-		{ goal_info_get_follow_vars(GoalInfo, MaybeFollowVars) },
-		(
-			{ MaybeFollowVars = yes(FollowVars) }
-		->
-			{ FollowVars = follow_vars(FollowVarsMap, NextReg) },
-			{ map__to_assoc_list(FollowVarsMap, FVlist) },
-			hlds_out__write_indent(Indent),
-			io__write_string("% follow vars: "),
-			io__write_int(NextReg),
-			io__write_string("\n"),
-			hlds_out__write_var_to_lvals(FVlist,
-				VarSet, AppendVarnums, Indent)
-		;
-			[]
-		)
-	;
-		[]
-	),
 	( { string__contains_char(Verbose, 'd') } ->
 		hlds_out__write_indent(Indent),
 		io__write_string("% determinism: "),
@@ -1269,9 +1257,12 @@
 		[]
 	),
 	( { string__contains_char(Verbose, 'p') } ->
-		{ goal_info_get_post_deaths(GoalInfo, PostDeaths) },
+		(
+			{ goal_info_maybe_get_post_deaths(GoalInfo,
+				PostDeaths) },
 		{ set__to_sorted_list(PostDeaths, PostDeathList) },
-		( { PostDeathList \= [] } ->
+			{ PostDeathList \= [] }
+		->
 			hlds_out__write_indent(Indent),
 			io__write_string("% post-deaths: "),
 			mercury_output_vars(PostDeathList, VarSet,
@@ -1280,9 +1271,12 @@
 		;
 			[]
 		),
-		{ goal_info_get_post_births(GoalInfo, PostBirths) },
+		(
+			{ goal_info_maybe_get_post_births(GoalInfo,
+				PostBirths) },
 		{ set__to_sorted_list(PostBirths, PostBirthList) },
-		( { PostBirthList \= [] } ->
+			{ PostBirthList \= [] }
+		->
 			hlds_out__write_indent(Indent),
 			io__write_string("% post-births: "),
 			mercury_output_vars(PostBirthList, VarSet,
@@ -1294,50 +1288,13 @@
 	;
 		[]
 	),
-	( { string__contains_char(Verbose, 'r') } ->
-		{ goal_info_get_resume_point(GoalInfo, Resume) },
+	{ goal_info_get_code_gen_info(GoalInfo, CodeGenInfo) },
 		(
-			{ Resume = no_resume_point }
-		;
-			{ Resume = resume_point(ResumeVars, Locs) },
-			{ set__to_sorted_list(ResumeVars, ResumeVarList) },
-			hlds_out__write_indent(Indent),
-			io__write_string("% resume point "),
-			(
-				{ Locs = orig_only },
-				io__write_string("orig only ")
+		{ CodeGenInfo = no_code_gen_info }
 			;
-				{ Locs = stack_only },
-				io__write_string("stack only ")
-			;
-				{ Locs = orig_and_stack },
-				io__write_string("orig and stack ")
-			;
-				{ Locs = stack_and_orig },
-				io__write_string("stack and orig ")
-			),
-			mercury_output_vars(ResumeVarList, VarSet,
-				AppendVarnums),
-			io__write_string("\n")
-		)
-	;
-		[]
-	),
-	(
-		{ string__contains_char(Verbose, 's') },
-		( { Goal = disj(_, SM) }
-		; { Goal = switch(_, _, _, SM) }
-		; { Goal = if_then_else(_, _, _, _, SM) }
-		),
-		{ map__to_assoc_list(SM, SMlist) },
-		{ SMlist \= [] }
-	->
-		hlds_out__write_indent(Indent),
-		io__write_string("% store map:\n"),
-		hlds_out__write_var_to_lvals(SMlist, VarSet, AppendVarnums,
-			Indent)
-	;
-		[]
+		{ CodeGenInfo = llds_code_gen_info(_CodeGenDetails) },
+		hlds_out__write_llds_code_gen_info(GoalInfo,
+			VarSet, AppendVarnums, Indent, Verbose)
 	),
 	( { string__contains_char(Verbose, 'g') } ->
 		{ goal_info_get_features(GoalInfo, Features) },
@@ -1358,7 +1315,7 @@
 	int, string, maybe_vartypes, io__state, io__state).
 :- mode hlds_out__write_goal_2(in, in, in, in, in, in, in, di, uo) is det.
 
-hlds_out__write_goal_2(switch(Var, CanFail, CasesList, _), ModuleInfo, VarSet,
+hlds_out__write_goal_2(switch(Var, CanFail, CasesList), ModuleInfo, VarSet,
 		AppendVarnums, Indent, Follow, TypeQual) -->
 	hlds_out__write_indent(Indent),
 	io__write_string("( % "),
@@ -1399,7 +1356,7 @@
 	io__write_string(")"),
 	io__write_string(Follow).
 
-hlds_out__write_goal_2(if_then_else(Vars, Cond, Then, Else, _), ModuleInfo,
+hlds_out__write_goal_2(if_then_else(Vars, Cond, Then, Else), ModuleInfo,
 		VarSet, AppendVarnums, Indent, Follow, TypeQual) -->
 	hlds_out__write_indent(Indent),
 	io__write_string("(if"),
@@ -1417,7 +1374,7 @@
 	globals__io_lookup_string_option(dump_hlds_options, Verbose),
 	(
 		{ Verbose \= "" },
-		{ Else = if_then_else(_, _, _, _, _) - _ }
+		{ Else = if_then_else(_, _, _, _) - _ }
 	->
 		hlds_out__write_goal_a(Else, ModuleInfo, VarSet, AppendVarnums,
 			Indent, "\n", TypeQual)
@@ -1465,7 +1422,7 @@
 		io__write_string(Follow)
 	).
 
-hlds_out__write_goal_2(par_conj(List, _), ModuleInfo, VarSet, AppendVarnums,
+hlds_out__write_goal_2(par_conj(List), ModuleInfo, VarSet, AppendVarnums,
 		Indent, Follow, TypeQual) -->
 	hlds_out__write_indent(Indent),
 	( { List = [Goal | Goals] } ->
@@ -1484,7 +1441,7 @@
 		io__write_string(Follow)
 	).
 
-hlds_out__write_goal_2(disj(List, _), ModuleInfo, VarSet, AppendVarnums,
+hlds_out__write_goal_2(disj(List), ModuleInfo, VarSet, AppendVarnums,
 		Indent, Follow, TypeQual) -->
 	hlds_out__write_indent(Indent),
 	( { List = [Goal | Goals] } ->
@@ -1758,7 +1715,199 @@
 	io__write_string(")"),
 	io__write_string(Follow).
 
+:- pred hlds_out__write_llds_code_gen_info(hlds_goal_info::in, prog_varset::in,
+	bool::in, int::in, string::in, io__state::di, io__state::uo) is det.
 
+hlds_out__write_llds_code_gen_info(GoalInfo, VarSet, AppendVarnums,
+		Indent, Verbose) -->
+	( { string__contains_char(Verbose, 'f') } ->
+		{ goal_info_get_follow_vars(GoalInfo, MaybeFollowVars) },
+		(
+			{ MaybeFollowVars = yes(FollowVars) }
+		->
+			{ FollowVars = follow_vars(FollowVarsMap, NextReg) },
+			{ map__to_assoc_list(FollowVarsMap, FVlist) },
+			hlds_out__write_indent(Indent),
+			io__write_string("% follow vars: "),
+			io__write_int(NextReg),
+			io__write_string("\n"),
+			hlds_out__write_var_to_lvals(FVlist,
+				VarSet, AppendVarnums, Indent)
+		;
+			[]
+		)
+	;
+		[]
+	),
+	( { string__contains_char(Verbose, 'r') } ->
+		{ goal_info_get_resume_point(GoalInfo, Resume) },
+		(
+			{ Resume = no_resume_point }
+		;
+			{ Resume = resume_point(ResumeVars, Locs) },
+			{ set__to_sorted_list(ResumeVars, ResumeVarList) },
+			hlds_out__write_indent(Indent),
+			io__write_string("% resume point "),
+			(
+				{ Locs = orig_only },
+				io__write_string("orig only ")
+			;
+				{ Locs = stack_only },
+				io__write_string("stack only ")
+			;
+				{ Locs = orig_and_stack },
+				io__write_string("orig and stack ")
+			;
+				{ Locs = stack_and_orig },
+				io__write_string("stack and orig ")
+			),
+			mercury_output_vars(ResumeVarList, VarSet,
+				AppendVarnums),
+			io__write_string("\n")
+		)
+	;
+		[]
+	),
+	(
+		{ string__contains_char(Verbose, 's') },
+		{ goal_info_get_store_map(GoalInfo, StoreMap) },
+		{ map__to_assoc_list(StoreMap, StoreMaplist) },
+		{ StoreMaplist \= [] }
+	->
+		hlds_out__write_indent(Indent),
+		io__write_string("% store map:\n"),
+		hlds_out__write_var_to_lvals(StoreMaplist, VarSet,
+			AppendVarnums, Indent)
+	;
+		[]
+	),
+	(
+		{ string__contains_char(Verbose, 's') },
+		{ goal_info_get_maybe_need_across_call(GoalInfo,
+			MaybeNeedAcrossCall) },
+		{ MaybeNeedAcrossCall = yes(NeedAcrossCall) }
+	->
+		{ NeedAcrossCall = need_across_call(CallForwardSet,
+			CallResumeSet, CallNondetSet) },
+		{ set__to_sorted_list(CallForwardSet, CallForwardList) },
+		{ set__to_sorted_list(CallResumeSet, CallResumeList) },
+		{ set__to_sorted_list(CallNondetSet, CallNondetList) },
+		hlds_out__write_indent(Indent),
+		io__write_string("% need across call forward vars:"),
+		( { CallForwardList = [] } ->
+			io__write_string(" none\n")
+		;
+			io__write_string("\n"),
+			hlds_out__write_indent(Indent),
+			io__write_string("% "),
+			hlds_out__write_vars(CallForwardList, VarSet,
+				AppendVarnums),
+			io__write_string("\n")
+		),
+
+		hlds_out__write_indent(Indent),
+		io__write_string("% need across call resume vars:"),
+		( { CallResumeList = [] } ->
+			io__write_string(" none\n")
+		;
+			io__write_string("\n"),
+			hlds_out__write_indent(Indent),
+			io__write_string("% "),
+			hlds_out__write_vars(CallResumeList, VarSet,
+				AppendVarnums),
+			io__write_string("\n")
+		),
+
+		hlds_out__write_indent(Indent),
+		io__write_string("% need across call nondet vars:"),
+		( { CallNondetList = [] } ->
+			io__write_string(" none\n")
+		;
+			io__write_string("\n"),
+			hlds_out__write_indent(Indent),
+			io__write_string("% "),
+			hlds_out__write_vars(CallNondetList, VarSet,
+				AppendVarnums),
+			io__write_string("\n")
+		)
+	;
+		[]
+	),
+	(
+		{ string__contains_char(Verbose, 's') },
+		{ goal_info_get_maybe_need_in_resume(GoalInfo,
+			MaybeNeedInResume) },
+		{ MaybeNeedInResume = yes(NeedInResume) }
+	->
+		{ NeedInResume = need_in_resume(ResumeOnStack, ResumeResumeSet,
+			ResumeNondetSet) },
+		{ set__to_sorted_list(ResumeResumeSet, ResumeResumeList) },
+		{ set__to_sorted_list(ResumeNondetSet, ResumeNondetList) },
+
+		hlds_out__write_indent(Indent),
+		(
+			{ ResumeOnStack = yes },
+			io__write_string("% resume point has stack label\n")
+		;
+			{ ResumeOnStack = no },
+			io__write_string("% resume point has no stack label\n")
+		),
+		hlds_out__write_indent(Indent),
+		io__write_string("% need in resume resume vars:"),
+		( { ResumeResumeList = [] } ->
+			io__write_string(" none\n")
+		;
+			io__write_string("\n"),
+			hlds_out__write_indent(Indent),
+			io__write_string("% "),
+			hlds_out__write_vars(ResumeResumeList, VarSet,
+				AppendVarnums),
+			io__write_string("\n")
+		),
+
+		hlds_out__write_indent(Indent),
+		io__write_string("% need in resume nondet vars:"),
+		( { ResumeNondetList = [] } ->
+			io__write_string(" none\n")
+		;
+			io__write_string("\n"),
+			hlds_out__write_indent(Indent),
+			io__write_string("% "),
+			hlds_out__write_vars(ResumeNondetList, VarSet,
+				AppendVarnums),
+			io__write_string("\n")
+		)
+	;
+		[]
+	),
+	(
+		{ string__contains_char(Verbose, 's') },
+		{ goal_info_get_maybe_need_in_par_conj(GoalInfo,
+			MaybeNeedInParConj) },
+		{ MaybeNeedInParConj = yes(NeedInParConj) }
+	->
+		{ NeedInParConj = need_in_par_conj(ParConjSet) },
+		{ set__to_sorted_list(ParConjSet, ParConjList) },
+		hlds_out__write_indent(Indent),
+		io__write_string("% need in par_conj vars:\n"),
+		hlds_out__write_indent(Indent),
+		io__write_string("% "),
+		hlds_out__write_vars(ParConjList, VarSet, AppendVarnums),
+		io__write_string("\n")
+	;
+		[]
+	).
+
+:- pred hlds_out__write_vars(list(prog_var)::in, prog_varset::in, bool::in,
+	io__state::di, io__state::uo) is det.
+
+hlds_out__write_vars([], _, _) --> [].
+hlds_out__write_vars([Var], VarSet, AppendVarnums) -->
+	mercury_output_var(Var, VarSet, AppendVarnums).
+hlds_out__write_vars([Var1, Var2 | Vars], VarSet, AppendVarnums) -->
+	mercury_output_var(Var1, VarSet, AppendVarnums),
+	io__write_string(", "),
+	hlds_out__write_vars([Var2 | Vars], VarSet, AppendVarnums).
 
 :- pred hlds_out__write_varnum_list(list(prog_var), io__state, io__state).
 :- mode hlds_out__write_varnum_list(in, di, uo) is det.
@@ -1943,10 +2092,15 @@
 hlds_out__write_unification(deconstruct(Var, ConsId, ArgVars, ArgModes,
 		CanFail, CanCGC),
 		ModuleInfo, ProgVarSet, InstVarSet, AppendVarnums, Indent) -->
+	globals__io_lookup_string_option(dump_hlds_options, Verbose),
+	( { string__contains_char(Verbose, 'G') } ->
 	hlds_out__write_indent(Indent),
 	io__write_string("% Compile time garbage collect: "),
 	io__write(CanCGC),
-	io__nl,
+		io__nl
+	;
+		[]
+	),
 	hlds_out__write_indent(Indent),
 	io__write_string("% "),
 	mercury_output_var(Var, ProgVarSet, AppendVarnums),
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.104
diff -u -b -r1.104 hlds_pred.m
--- compiler/hlds_pred.m	5 Mar 2002 10:59:16 -0000	1.104
+++ compiler/hlds_pred.m	8 Mar 2002 04:04:23 -0000
@@ -14,7 +14,8 @@
 :- interface.
 
 :- import_module prog_data.
-:- import_module hlds_data, hlds_goal, hlds_module, instmap, term_util.
+:- import_module hlds_data, hlds_goal, hlds_module, hlds_llds.
+:- import_module instmap, term_util.
 :- import_module mode_errors.
 :- import_module globals.
 
Index: compiler/inlining.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/inlining.m,v
retrieving revision 1.104
diff -u -b -r1.104 inlining.m
--- compiler/inlining.m	16 Dec 2001 08:11:08 -0000	1.104
+++ compiler/inlining.m	17 Dec 2001 02:08:47 -0000
@@ -516,21 +516,20 @@
 inlining__inlining_in_goal(conj(Goals0) - GoalInfo, conj(Goals) - GoalInfo) -->
 	inlining__inlining_in_conj(Goals0, Goals).
 
-inlining__inlining_in_goal(par_conj(Goals0, SM) - GoalInfo,
-		par_conj(Goals, SM) - GoalInfo) -->
+inlining__inlining_in_goal(par_conj(Goals0) - GoalInfo,
+		par_conj(Goals) - GoalInfo) -->
 	inlining__inlining_in_disj(Goals0, Goals).
 
-inlining__inlining_in_goal(disj(Goals0, SM) - GoalInfo,
-		disj(Goals, SM) - GoalInfo) -->
+inlining__inlining_in_goal(disj(Goals0) - GoalInfo, disj(Goals) - GoalInfo) -->
 	inlining__inlining_in_disj(Goals0, Goals).
 
-inlining__inlining_in_goal(switch(Var, Det, Cases0, SM) - GoalInfo,
-		switch(Var, Det, Cases, SM) - GoalInfo) -->
+inlining__inlining_in_goal(switch(Var, Det, Cases0) - GoalInfo,
+		switch(Var, Det, Cases) - GoalInfo) -->
 	inlining__inlining_in_cases(Cases0, Cases).
 
 inlining__inlining_in_goal(
-		if_then_else(Vars, Cond0, Then0, Else0, SM) - GoalInfo,
-		if_then_else(Vars, Cond, Then, Else, SM) - GoalInfo) -->
+		if_then_else(Vars, Cond0, Then0, Else0) - GoalInfo,
+		if_then_else(Vars, Cond, Then, Else) - GoalInfo) -->
 	inlining__inlining_in_goal(Cond0, Cond),
 	inlining__inlining_in_goal(Then0, Then),
 	inlining__inlining_in_goal(Else0, Else).
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.114
diff -u -b -r1.114 intermod.m
--- compiler/intermod.m	7 Mar 2002 08:29:53 -0000	1.114
+++ compiler/intermod.m	8 Mar 2002 04:04:25 -0000
@@ -455,12 +455,11 @@
 intermod__traverse_goal(conj(Goals0) - Info, conj(Goals) - Info, DoWrite) -->
 	intermod__traverse_list_of_goals(Goals0, Goals, DoWrite).
 
-intermod__traverse_goal(par_conj(Goals0, SM) - Info, par_conj(Goals, SM) - Info,
+intermod__traverse_goal(par_conj(Goals0) - Info, par_conj(Goals) - Info,
 		DoWrite) -->
 	intermod__traverse_list_of_goals(Goals0, Goals, DoWrite).
 
-intermod__traverse_goal(disj(Goals0, SM) - Info, disj(Goals, SM) - Info,
-		DoWrite) -->
+intermod__traverse_goal(disj(Goals0) - Info, disj(Goals) - Info, DoWrite) -->
 	intermod__traverse_list_of_goals(Goals0, Goals, DoWrite).
 
 intermod__traverse_goal(Goal, Goal, DoWrite) -->
@@ -474,8 +473,8 @@
 intermod__traverse_goal(generic_call(A,B,C,D) - Info,
 			generic_call(A,B,C,D) - Info, yes) --> [].
 
-intermod__traverse_goal(switch(A, B, Cases0, D) - Info,
-		switch(A, B, Cases, D) - Info, DoWrite) -->
+intermod__traverse_goal(switch(A, B, Cases0) - Info,
+		switch(A, B, Cases) - Info, DoWrite) -->
 	intermod__traverse_cases(Cases0, Cases, DoWrite).
 
 	% Export declarations for preds used in higher order pred constants
@@ -491,8 +490,8 @@
 		some(Vars, CanRemove, Goal) - Info, DoWrite) -->
 	intermod__traverse_goal(Goal0, Goal, DoWrite).
 
-intermod__traverse_goal(if_then_else(Vars, Cond0, Then0, Else0, SM) - Info,
-		if_then_else(Vars, Cond, Then, Else, SM) - Info, DoWrite) -->
+intermod__traverse_goal(if_then_else(Vars, Cond0, Then0, Else0) - Info,
+		if_then_else(Vars, Cond, Then, Else) - Info, DoWrite) -->
 	intermod__traverse_goal(Cond0, Cond, DoWrite1),
 	intermod__traverse_goal(Then0, Then, DoWrite2),
 	intermod__traverse_goal(Else0, Else, DoWrite3),
Index: compiler/ite_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ite_gen.m,v
retrieving revision 1.65
diff -u -b -r1.65 ite_gen.m
--- compiler/ite_gen.m	23 Nov 2000 04:32:37 -0000	1.65
+++ compiler/ite_gen.m	5 Nov 2001 11:45:25 -0000
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1994-2000 The University of Melbourne.
+% Copyright (C) 1994-2001 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.
 %---------------------------------------------------------------------------%
@@ -21,7 +21,7 @@
 :- import_module hlds_goal, code_model, llds, code_info.
 
 :- pred ite_gen__generate_ite(code_model::in, hlds_goal::in, hlds_goal::in,
-	hlds_goal::in, store_map::in, code_tree::out,
+	hlds_goal::in, hlds_goal_info::in, code_tree::out,
 	code_info::in, code_info::out) is det.
 
 :- pred ite_gen__generate_negation(code_model::in, hlds_goal::in,
@@ -31,13 +31,13 @@
 
 :- implementation.
 
-:- import_module prog_data, tree, builtin_ops.
+:- import_module hlds_llds, prog_data, tree, builtin_ops.
 :- import_module code_gen, code_util, trace, options, globals, instmap.
 
 :- import_module bool, set, term, list, map, std_util, require.
 
-ite_gen__generate_ite(CodeModel, CondGoal0, ThenGoal, ElseGoal, StoreMap, Code)
-		-->
+ite_gen__generate_ite(CodeModel, CondGoal0, ThenGoal, ElseGoal, IteGoalInfo,
+		Code) -->
 	{ CondGoal0 = CondExpr - CondInfo0 },
 	{ goal_info_get_code_model(CondInfo0, CondCodeModel) },
 	{
@@ -126,6 +126,7 @@
 			MaybeTicketSlot, commit, ResetTicketCode)
 	),
 
+	{ goal_info_get_store_map(IteGoalInfo, StoreMap) },
 	code_info__get_instmap(EndCondInstMap),
 	( { instmap__is_unreachable(EndCondInstMap) } ->
 		% If the instmap indicates we cannot reach the then part,
Index: compiler/lambda.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lambda.m,v
retrieving revision 1.75
diff -u -b -r1.75 lambda.m
--- compiler/lambda.m	5 Mar 2002 10:59:18 -0000	1.75
+++ compiler/lambda.m	8 Mar 2002 04:04:26 -0000
@@ -251,22 +251,22 @@
 
 lambda__process_goal_2(conj(Goals0), GoalInfo, conj(Goals) - GoalInfo) -->
 	lambda__process_goal_list(Goals0, Goals).
-lambda__process_goal_2(par_conj(Goals0, SM), GoalInfo,
-		par_conj(Goals, SM) - GoalInfo) -->
+lambda__process_goal_2(par_conj(Goals0), GoalInfo,
+		par_conj(Goals) - GoalInfo) -->
 	lambda__process_goal_list(Goals0, Goals).
-lambda__process_goal_2(disj(Goals0, SM), GoalInfo, disj(Goals, SM) - GoalInfo)
+lambda__process_goal_2(disj(Goals0), GoalInfo, disj(Goals) - GoalInfo)
 		-->
 	lambda__process_goal_list(Goals0, Goals).
 lambda__process_goal_2(not(Goal0), GoalInfo, not(Goal) - GoalInfo) -->
 	lambda__process_goal(Goal0, Goal).
-lambda__process_goal_2(switch(Var, CanFail, Cases0, SM), GoalInfo, 
-			switch(Var, CanFail, Cases, SM) - GoalInfo) -->
+lambda__process_goal_2(switch(Var, CanFail, Cases0), GoalInfo, 
+			switch(Var, CanFail, Cases) - GoalInfo) -->
 	lambda__process_cases(Cases0, Cases).
 lambda__process_goal_2(some(Vars, CanRemove, Goal0), GoalInfo,
 			some(Vars, CanRemove, Goal) - GoalInfo) -->
 	lambda__process_goal(Goal0, Goal).
-lambda__process_goal_2(if_then_else(Vars, A0, B0, C0, SM), GoalInfo,
-			if_then_else(Vars, A, B, C, SM) - GoalInfo) -->
+lambda__process_goal_2(if_then_else(Vars, A0, B0, C0), GoalInfo,
+			if_then_else(Vars, A, B, C) - GoalInfo) -->
 	lambda__process_goal(A0, A),
 	lambda__process_goal(B0, B),
 	lambda__process_goal(C0, C).
Index: compiler/lco.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lco.m,v
retrieving revision 1.17
diff -u -b -r1.17 lco.m
--- compiler/lco.m	7 Apr 2001 14:04:43 -0000	1.17
+++ compiler/lco.m	16 Jul 2001 17:17:36 -0000
@@ -64,18 +64,18 @@
 	lco_in_conj(RevGoals0, [], ModuleInfo, Goals).
 
 	% XXX Some execution algorithm issues here.
-lco_in_goal_2(par_conj(_Goals0, SM), _ModuleInfo, par_conj(_Goals, SM)) :-
+lco_in_goal_2(par_conj(_Goals0), _ModuleInfo, par_conj(_Goals)) :-
 	error("sorry: lco of parallel conjunction not implemented").
 
-lco_in_goal_2(disj(Goals0, SM), ModuleInfo, disj(Goals, SM)) :-
+lco_in_goal_2(disj(Goals0), ModuleInfo, disj(Goals)) :-
 	lco_in_disj(Goals0, ModuleInfo, Goals).
 
-lco_in_goal_2(switch(Var, Det, Cases0, SM), ModuleInfo,
-		switch(Var, Det, Cases, SM)) :-
+lco_in_goal_2(switch(Var, Det, Cases0), ModuleInfo,
+		switch(Var, Det, Cases)) :-
 	lco_in_cases(Cases0, ModuleInfo, Cases).
 
-lco_in_goal_2(if_then_else(Vars, Cond, Then0, Else0, SM), ModuleInfo,
-		if_then_else(Vars, Cond, Then, Else, SM)) :-
+lco_in_goal_2(if_then_else(Vars, Cond, Then0, Else0), ModuleInfo,
+		if_then_else(Vars, Cond, Then, Else)) :-
 	lco_in_goal(Then0, ModuleInfo, Then),
 	lco_in_goal(Else0, ModuleInfo, Else).
 
Index: compiler/live_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.98
diff -u -b -r1.98 live_vars.m
--- compiler/live_vars.m	7 Apr 2001 14:04:43 -0000	1.98
+++ compiler/live_vars.m	9 Jan 2002 09:36:23 -0000
@@ -8,152 +8,117 @@
 %
 % Main authors: conway, zs.
 %
-% This module allocates stack slots to the variables that need to be saved
-% either across a call or across a goal that may fail.
+% This module finds out what variables need to be saved across calls,
+% across goals that may fail, and in parallel conjunctions. It then does those
+% things with that information. First, it attaches that information to the
+% relevant goal as a LLDS-backend-specific annotation. Second, it invokes
+% the relevant type class method of the allocator-specific data structure
+% it is passed; the basic stack slot allocator and the optimizing stack slot
+% allocator pass different instances of this type class.
 %
-% The jobs is done in two steps. First we traverse the predicate definition
-% looking for sets of variables that must be saved on the stack at the same
-% time. Then we use a graph colouring algorithm to find an allocation of
-% stack slots (colours) to variables such that in each set of variables
-% that must be saved at the same time, each variable has a different colour.
-
 %-----------------------------------------------------------------------------%
 
 :- module live_vars.
 
 :- interface.
 
-:- import_module hlds_module, hlds_pred.
-
-:- pred allocate_stack_slots_in_proc(proc_info::in, pred_id::in,
-	module_info::in, proc_info::out) is det.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
 % Parse tree modules
 :- import_module prog_data.
 
 % HLDS modules
-:- import_module hlds_goal, hlds_data, mode_util, instmap, code_aux.
-:- import_module liveness.
-
-% Modules shared between different back-ends.
-:- import_module code_model.
-
-% LLDS modules
-:- import_module llds, arg_info, trace_params, trace.
-
-% Misc
-:- import_module globals, options, graph_colour.
-
+:- import_module hlds_goal, hlds_pred, hlds_module, hlds_llds.
 
 % Standard library modules
-:- import_module list, map, set, std_util, assoc_list, bool.
-:- import_module int, require.
-
-%-----------------------------------------------------------------------------%
+:- import_module bool, set.
 
 :- type alloc_data
 	--->	alloc_data(
 			module_info		::	module_info,
 			proc_info		::	proc_info,
-			typeinfo_liveness	::	bool
+			typeinfo_liveness	::	bool,
+			opt_no_return_calls	::	bool
 		).
 
-allocate_stack_slots_in_proc(ProcInfo0, PredId, ModuleInfo, ProcInfo) :-
-	proc_info_goal(ProcInfo0, Goal0),
-	proc_info_interface_code_model(ProcInfo0, CodeModel),
-
-	initial_liveness(ProcInfo0, PredId, ModuleInfo, Liveness0),
-	set__init(LiveSets0),
-	module_info_globals(ModuleInfo, Globals),
-	globals__get_trace_level(Globals, TraceLevel),
-	( trace_level_is_none(TraceLevel) = no ->
-		trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0),
-		set__insert(LiveSets0, ResumeVars0, LiveSets1)
-	;
-		set__init(ResumeVars0),
-		LiveSets1 = LiveSets0
-	),
-	trace__do_we_need_maxfr_slot(Globals, ProcInfo0, ProcInfo1),
-	trace__reserved_slots(ModuleInfo, ProcInfo1, Globals, NumReservedSlots,
-		MaybeReservedVarInfo),
-	( MaybeReservedVarInfo = yes(ResVar - _) ->
-		set__singleton_set(ResVarSet, ResVar),
-		set__insert(LiveSets1, ResVarSet, LiveSets2)
-	;
-		LiveSets2 = LiveSets1
-	),
-	module_info_pred_info(ModuleInfo, PredId, PredInfo),
-	body_should_use_typeinfo_liveness(PredInfo, Globals, TypeInfoLiveness),
-	AllocData = alloc_data(ModuleInfo, ProcInfo1, TypeInfoLiveness),
-	set__init(NondetLiveness0),
-	build_live_sets_in_goal(Goal0, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets2, AllocData,
-		_Liveness, _NondetLiveness, LiveSets),
-	graph_colour__group_elements(LiveSets, ColourSets),
-	set__to_sorted_list(ColourSets, ColourList),
-	allocate_stack_slots(ColourList, CodeModel, NumReservedSlots,
-		MaybeReservedVarInfo, StackSlots),
-
-	proc_info_set_stack_slots(ProcInfo1, StackSlots, ProcInfo).
+:- typeclass stack_alloc_info(T) where [
+	pred at_call_site(need_across_call::in, hlds_goal_info::in,
+		T::in, T::out) is det,
+	pred at_resume_site(need_in_resume::in, hlds_goal_info::in,
+		T::in, T::out) is det,
+	pred at_par_conj(need_in_par_conj::in, hlds_goal_info::in,
+		T::in, T::out) is det
+].
+
+:- pred build_live_sets_in_goal(hlds_goal::in, T::in,
+	set(prog_var)::in, set(prog_var)::in,
+	set(prog_var)::in, alloc_data::in,
+	hlds_goal::out, T::out, set(prog_var)::out, set(prog_var)::out)
+	is det <= stack_alloc_info(T).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
+:- implementation.
+
+:- import_module llds, arg_info, prog_data.
+:- import_module hlds_goal, hlds_llds, hlds_data, mode_util.
+:- import_module code_model, liveness, code_aux, instmap.
+:- import_module int, list, assoc_list, map, std_util, require.
+
+%-----------------------------------------------------------------------------%
+
 % The stack_slots structure (map(prog_var, lval)) is threaded through the
 % traversal of the goal. The liveness information is computed from the liveness
 % delta annotations.
 
-:- pred build_live_sets_in_goal(hlds_goal::in,
-	set(prog_var)::in, set(prog_var)::in, set(prog_var)::in,
-	set(set(prog_var))::in, alloc_data::in,
-	set(prog_var)::out, set(prog_var)::out, set(set(prog_var))::out) is det.
-
-build_live_sets_in_goal(Goal - GoalInfo, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	goal_info_get_pre_deaths(GoalInfo, PreDeaths),
-	goal_info_get_pre_births(GoalInfo, PreBirths),
-	goal_info_get_post_deaths(GoalInfo, PostDeaths),
-	goal_info_get_post_births(GoalInfo, PostBirths),
+build_live_sets_in_goal(Goal0 - GoalInfo0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goal - GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
+	goal_info_get_pre_deaths(GoalInfo0, PreDeaths),
+	goal_info_get_pre_births(GoalInfo0, PreBirths),
+	goal_info_get_post_deaths(GoalInfo0, PostDeaths),
+	goal_info_get_post_births(GoalInfo0, PostBirths),
 
 	% note: we must be careful to apply deaths before births
 	set__difference(Liveness0, PreDeaths, Liveness1),
 	set__union(Liveness1, PreBirths, Liveness2),
 
 	%
-	% if the goal is atomic, we want to apply the postdeaths
+	% If the goal is atomic, we want to apply the postdeaths
 	% before processing the goal, but if the goal is a compound
-	% goal, then we want to apply them after processing it
+	% goal, then we want to apply them after processing it.
 	%
-	( goal_is_atomic(Goal) ->
+	( goal_is_atomic(Goal0) ->
 		set__difference(Liveness2, PostDeaths, Liveness3)
 	;
 		Liveness3 = Liveness2
 	),
 
-	goal_info_get_resume_point(GoalInfo, ResumePoint),
+	goal_info_get_resume_point(GoalInfo0, ResumePoint),
 	(
+		ResumePoint = no_resume_point,
+		ResumeVars1 = ResumeVars0,
+		GoalInfo1 = GoalInfo0,
+		StackAlloc1 = StackAlloc0
+	;
 		ResumePoint = resume_point(ResumePointVars, Locs),
-		resume_locs_include_stack(Locs, yes)
-	->
+		( resume_locs_include_stack(Locs, yes) ->
 		set__union(ResumeVars0, ResumePointVars, ResumeVars1),
-		set__union(ResumeVars1, NondetLiveness0, InterferingVars),
-		set__insert(LiveSets0, InterferingVars, LiveSets1)
+			ResumeOnStack = yes
 	;
 		ResumeVars1 = ResumeVars0,
-		LiveSets1 = LiveSets0
+			ResumeOnStack = no
+		),
+		NeedInResume = need_in_resume(ResumeOnStack,
+			ResumeVars1, NondetLiveness0),
+		record_resume_site(NeedInResume, GoalInfo0, GoalInfo1,
+			StackAlloc0, StackAlloc1)
 	),
 
-	build_live_sets_in_goal_2(Goal, Liveness3,
-		NondetLiveness0, ResumeVars1, LiveSets1, GoalInfo, AllocData,
-		Liveness4, NondetLiveness, LiveSets),
+	build_live_sets_in_goal_2(Goal0, GoalInfo1, StackAlloc1,
+		Liveness3, NondetLiveness0, ResumeVars1, AllocData,
+		Goal, GoalInfo, StackAlloc, Liveness4, NondetLiveness),
 
-	( goal_is_atomic(Goal) ->
+	( goal_is_atomic(Goal0) ->
 		Liveness5 = Liveness4
 	;
 		set__difference(Liveness4, PostDeaths, Liveness5)
@@ -177,68 +142,79 @@
 	% `ResumeVars' is the set of variables that may or may not be
 	% `live' during the current forward execution but will become
 	% live again on backtracking.
-	% `LiveSets' is the interference graph, i.e. the set of sets
+	% `SaveInfo' is the interference graph, i.e. the set of sets
 	% of variables which need to be on the stack at the same time.
 
-:- pred build_live_sets_in_goal_2(hlds_goal_expr::in,
-	set(prog_var)::in, set(prog_var)::in, set(prog_var)::in,
-	set(set(prog_var))::in, hlds_goal_info::in, alloc_data::in,
-	set(prog_var)::out,
-	set(prog_var)::out, set(set(prog_var))::out) is det.
-
-build_live_sets_in_goal_2(conj(Goals), Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, _, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_conj(Goals, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness, LiveSets).
-
-build_live_sets_in_goal_2(par_conj(Goals, _SM),
-		Liveness0, NondetLiveness0, ResumeVars0, LiveSets0,
-		GoalInfo, AllocData, Liveness, NondetLiveness, LiveSets) :-
-	goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals),
+:- pred build_live_sets_in_goal_2(hlds_goal_expr::in, hlds_goal_info::in,
+	T::in, set(prog_var)::in, set(prog_var)::in,
+	set(prog_var)::in, alloc_data::in,
+	hlds_goal_expr::out, hlds_goal_info::out, T::out,
+	set(prog_var)::out, set(prog_var)::out)
+	is det <= stack_alloc_info(T).
+
+build_live_sets_in_goal_2(conj(Goals0), GoalInfo, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		conj(Goals), GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
+	build_live_sets_in_conj(Goals0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goals, StackAlloc, Liveness, NondetLiveness).
+
+build_live_sets_in_goal_2(par_conj(Goals0), GoalInfo0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		par_conj(Goals), GoalInfo, StackAlloc,
+		Liveness, NondetLiveness) :-
+	goal_info_get_code_gen_nonlocals(GoalInfo0, NonLocals),
 	set__union(NonLocals, Liveness0, LiveSet),
-		% We insert all the union of the live vars and the nonlocals.
 		% Since each parallel conjunct may be run on a different
 		% Mercury engine to the current engine, we must save all
 		% the variables that are live or nonlocal to the parallel
 		% conjunction. Nonlocal variables that are currently free, but
 		% are bound inside one of the conjuncts need a stackslot
 		% because they are passed out by reference to that stackslot.
-	set__insert(LiveSets0, LiveSet, LiveSets1),
-		% build_live_sets_in_disj treats its list of goals as a list
-		% of independent goals, so we can use it for parallel conj's
-		% too. XXX No, it doesn't.
-	build_live_sets_in_disj(Goals, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets1, GoalInfo, AllocData,
-		Liveness, NondetLiveness, LiveSets).
-
-build_live_sets_in_goal_2(disj(Goals, _SM), Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, GoalInfo, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_disj(Goals, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, GoalInfo, AllocData,
-		Liveness, NondetLiveness1, LiveSets),
+	NeedInParConj = need_in_par_conj(LiveSet),
+	record_par_conj(NeedInParConj, GoalInfo0, GoalInfo,
+		StackAlloc0, StackAlloc1),
+	build_live_sets_in_par_conj(Goals0, StackAlloc1,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goals, StackAlloc, Liveness, NondetLiveness).
+
+build_live_sets_in_goal_2(disj(Goals0), GoalInfo, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		disj(Goals), GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
+	build_live_sets_in_disj(Goals0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, GoalInfo, AllocData,
+		Goals, StackAlloc, Liveness, NondetLiveness1),
 	(
 		Goals = [First | _],
 		First = _ - FirstGoalInfo,
 		goal_info_get_resume_point(FirstGoalInfo, ResumePoint),
 		(
-			ResumePoint = resume_point(ResumeVars, Locs),
+			ResumePoint = resume_point(ResumeVars, _Locs),
 				% If we can backtrack into the disjunction,
 				% we must protect the stack slots needed by
 				% any of its resumption points from being
 				% reused in the following code. The first
 				% resumption point's vars include all the
 				% vars needed by all the resumption points.
-				%
+				% However, the first disjunct can be orig_only
+				% while later disjuncts are include the stack.
+				
 				% Note that we must check the disjunction's
 				% code model, not any disjuncts'; the
 				% disjunction as a whole can be model_non
 				% without any disjunct being model_non.
 			(
-				resume_locs_include_stack(Locs, yes),
-				goal_info_get_code_model(GoalInfo, model_non)
+				goal_info_get_code_model(GoalInfo, model_non),
+				some [Disjunct] (
+					list__member(Disjunct, Goals),
+					Disjunct = _ - DisjunctGoalInfo,
+					goal_info_get_resume_point(
+						DisjunctGoalInfo,
+						DisjunctResumePoint),
+					DisjunctResumePoint =
+						resume_point(_, Locs),
+					resume_locs_include_stack(Locs, yes)
+				)
 			->
 				set__union(NondetLiveness1, ResumeVars,
 					NondetLiveness)
@@ -262,40 +238,44 @@
 		NondetLiveness = NondetLiveness1
 	).
 
-build_live_sets_in_goal_2(switch(_Var, _CanFail, Cases, _SM), Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, _, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_cases(Cases, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness, LiveSets).
-
-build_live_sets_in_goal_2(if_then_else(_Vars, Cond, Then, Else, _SM),
-		Liveness0, NondetLiveness0, ResumeVars0, LiveSets0,
-		_, AllocData, Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_goal(Cond, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness1, NondetLivenessCond, LiveSets1),
-	build_live_sets_in_goal(Then, Liveness1,
-		NondetLivenessCond, ResumeVars0, LiveSets1, AllocData,
-		_Liveness2, NondetLivenessThen, LiveSets2),
-	build_live_sets_in_goal(Else, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets2, AllocData,
-		Liveness, NondetLivenessElse, LiveSets),
+build_live_sets_in_goal_2(switch(Var, CanFail, Cases0), GoalInfo, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		switch(Var, CanFail, Cases), GoalInfo, StackAlloc,
+		Liveness, NondetLiveness) :-
+	build_live_sets_in_cases(Cases0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Cases, StackAlloc, Liveness, NondetLiveness).
+
+build_live_sets_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), GoalInfo,
+		StackAlloc0, Liveness0, NondetLiveness0,
+		ResumeVars0, AllocData,
+		if_then_else(Vars, Cond, Then, Else), GoalInfo, StackAlloc,
+		Liveness, NondetLiveness) :-
+	build_live_sets_in_goal(Cond0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Cond, StackAlloc1, LivenessCond, NondetLivenessCond),
+	build_live_sets_in_goal(Then0, StackAlloc1,
+		LivenessCond, NondetLivenessCond, ResumeVars0, AllocData,
+		Then, StackAlloc2, _LivenessThen, NondetLivenessThen),
+	build_live_sets_in_goal(Else0, StackAlloc2,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Else, StackAlloc, Liveness, NondetLivenessElse),
 	set__union(NondetLivenessThen, NondetLivenessElse, NondetLiveness).
 
-build_live_sets_in_goal_2(not(Goal), Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, _, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_goal(Goal, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness, LiveSets).
-
-build_live_sets_in_goal_2(some(_Vars, _CR, Goal), Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, GoalInfo, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_goal(Goal, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness1, LiveSets),
+build_live_sets_in_goal_2(not(Goal0), GoalInfo, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		not(Goal), GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
+	build_live_sets_in_goal(Goal0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, StackAlloc, Liveness, NondetLiveness).
+
+build_live_sets_in_goal_2(some(Vars, CR, Goal0), GoalInfo, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		some(Vars, CR, Goal), GoalInfo, StackAlloc,
+		Liveness, NondetLiveness) :-
+	build_live_sets_in_goal(Goal0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, StackAlloc, Liveness, NondetLiveness1),
 
 	% If the "some" goal cannot succeed more than once,
 	% then execution cannot backtrack into the inner goal once control
@@ -309,39 +289,45 @@
 		NondetLiveness = NondetLiveness0
 	).
 
-build_live_sets_in_goal_2(generic_call(_GenericCall, ArgVars, Modes, Det),
-		Liveness, NondetLiveness0, ResumeVars0, LiveSets0,
-		GoalInfo, AllocData, Liveness, NondetLiveness, LiveSets) :-
-
-	determinism_to_code_model(Det, CallModel),
-	ProcInfo = AllocData^proc_info,
+build_live_sets_in_goal_2(Goal, GoalInfo0, StackAlloc0,
+		Liveness, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
+	Goal = generic_call(_GenericCall, ArgVars, Modes, _Det),
+	ProcInfo = AllocData ^ proc_info,
 	proc_info_vartypes(ProcInfo, VarTypes),
 	map__apply_to_list(ArgVars, VarTypes, Types),
-	ModuleInfo = AllocData^module_info,
-	make_arg_infos(Types, Modes, CallModel, ModuleInfo, ArgInfos),
-	find_output_vars_from_arg_info(ArgVars, ArgInfos, OutVars),
-
-	build_live_sets_in_call(Liveness, NondetLiveness0, ResumeVars0,
-		LiveSets0, OutVars, GoalInfo, AllocData, NondetLiveness,
-		LiveSets).
-
-build_live_sets_in_goal_2(call(PredId, ProcId, ArgVars, Builtin, _, _),
-		Liveness, NondetLiveness0, ResumeVars0, LiveSets0,
-		GoalInfo, AllocData, Liveness, NondetLiveness, LiveSets) :-
+	ModuleInfo = AllocData ^ module_info,
+	arg_info__partition_generic_call_args(ModuleInfo, ArgVars,
+		Types, Modes, _InVars, OutVars, _UnusedVars),
+
+	build_live_sets_in_call(OutVars, GoalInfo0, StackAlloc0,
+		Liveness, NondetLiveness0, ResumeVars0, AllocData,
+		GoalInfo, StackAlloc, NondetLiveness).
+
+build_live_sets_in_goal_2(Goal, GoalInfo0, StackAlloc0,
+		Liveness, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
+	Goal = call(PredId, ProcId, ArgVars, Builtin, _, _),
+	ModuleInfo = AllocData ^ module_info,
+	CallerProcInfo = AllocData ^ proc_info,
+	proc_info_vartypes(CallerProcInfo, VarTypes),
+	module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
+		_PredInfo, ProcInfo),
+	arg_info__partition_proc_call_args(ProcInfo, VarTypes, ModuleInfo,
+		ArgVars, _InVars, OutVars, _UnusedVars),
 	( Builtin = inline_builtin ->
 		NondetLiveness = NondetLiveness0,
-		LiveSets = LiveSets0
+		GoalInfo = GoalInfo0,
+		StackAlloc = StackAlloc0
 	;
-		ModuleInfo = AllocData^module_info,
-		find_output_vars(PredId, ProcId, ArgVars, ModuleInfo, OutVars),
-		build_live_sets_in_call(Liveness, NondetLiveness0,
-			ResumeVars0, LiveSets0, OutVars, GoalInfo, AllocData,
-			NondetLiveness, LiveSets)
+		build_live_sets_in_call(OutVars, GoalInfo0, StackAlloc0,
+			Liveness, NondetLiveness0, ResumeVars0, AllocData,
+			GoalInfo, StackAlloc, NondetLiveness)
 	).
 
-build_live_sets_in_goal_2(Goal, Liveness, NondetLiveness,
-		_ResumeVars0, LiveSets, _GoalInfo, _,
-		Liveness, NondetLiveness, LiveSets) :-
+build_live_sets_in_goal_2(Goal, GoalInfo, StackAlloc,
+		Liveness, NondetLiveness, _ResumeVars0, _AllocData,
+		Goal, GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
 	Goal = unify(_, _, _, Unification, _),
 	( Unification = complicated_unify(_, _, _) ->
 		error("build_live_sets_in_goal_2: complicated_unify")
@@ -349,12 +335,14 @@
 		true
 	).
 
-build_live_sets_in_goal_2(foreign_proc(Attributes,
-		PredId, ProcId, Args, _, _, _),
-		Liveness, NondetLiveness0, ResumeVars0, LiveSets0,
-		GoalInfo, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	goal_info_get_code_model(GoalInfo, CodeModel),
+build_live_sets_in_goal_2(Goal, GoalInfo0, StackAlloc0,
+		Liveness, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, GoalInfo, StackAlloc, Liveness, NondetLiveness) :-
+	Goal = foreign_proc(Attributes, PredId, ProcId, Args, _, _, _),
+	ModuleInfo = AllocData ^ module_info,
+	find_input_output_vars(PredId, ProcId, Args, ModuleInfo,
+		_InVars, OutVars),
+	goal_info_get_code_model(GoalInfo0, CodeModel),
 	(
 		% We don't need to save any variables onto the stack
 		% before a pragma_c_code if we know that it can't
@@ -366,7 +354,8 @@
 		may_call_mercury(Attributes, will_not_call_mercury)
 	->
 		NondetLiveness = NondetLiveness0,
-		LiveSets = LiveSets0
+		GoalInfo = GoalInfo0,
+		StackAlloc = StackAlloc0
 	;
 		% The variables which need to be saved onto the stack
 		% before the call are all the variables that are live
@@ -374,15 +363,12 @@
 		% by the call), plus all the variables that may be needed
 		% at an enclosing resumption point.
 
-		ModuleInfo = AllocData^module_info,
-		find_output_vars(PredId, ProcId, Args, ModuleInfo, OutVars),
-		build_live_sets_in_call(Liveness, NondetLiveness0,
-			ResumeVars0, LiveSets0, OutVars, GoalInfo, AllocData,
-			NondetLiveness, LiveSets)
+		build_live_sets_in_call(OutVars, GoalInfo0, StackAlloc0,
+			Liveness, NondetLiveness0, ResumeVars0, AllocData,
+			GoalInfo, StackAlloc, NondetLiveness)
 	).
 
-build_live_sets_in_goal_2(shorthand(_), _, _, _, _, _, _, _, _, _)
-		:-
+build_live_sets_in_goal_2(shorthand(_), _,_,_,_,_,_,_,_,_,_,_) :-
 	% these should have been expanded out by now
 	error("build_live_sets_in_goal_2: unexpected shorthand").
 
@@ -394,91 +380,129 @@
 	% except for the output arguments produced by the goal, plus all the
 	% variables that may be needed at an enclosing resumption point.
 
-:- pred build_live_sets_in_call(set(prog_var)::in, set(prog_var)::in,
-	set(prog_var)::in, set(set(prog_var))::in, set(prog_var)::in,
-	hlds_goal_info::in, alloc_data::in, set(prog_var)::out,
-	set(set(prog_var))::out) is det.
-
-build_live_sets_in_call(Liveness, NondetLiveness0, ResumeVars0, LiveSets0,
-		OutVars, GoalInfo, AllocData, NondetLiveness, LiveSets) :-
+:- pred build_live_sets_in_call(set(prog_var)::in, hlds_goal_info::in,
+	T::in, set(prog_var)::in, set(prog_var)::in,
+	set(prog_var)::in, alloc_data::in,
+	hlds_goal_info::out, T::out, set(prog_var)::out)
+	is det <= stack_alloc_info(T).
+
+build_live_sets_in_call(OutVars, GoalInfo0, StackAlloc0,
+		Liveness, NondetLiveness0, ResumeVars0, AllocData,
+		GoalInfo, StackAlloc, NondetLiveness) :-
 
-	set__difference(Liveness, OutVars, StackVars0),
+	set__difference(Liveness, OutVars, ForwardVars0),
 
-	% Might need to add more live variables with alternate liveness
+	% Might need to add more live variables with typeinfo liveness
 	% calculation.
 
-	maybe_add_alternate_liveness_typeinfos(AllocData^proc_info,
-		AllocData^typeinfo_liveness, OutVars, StackVars0, StackVars),
+	maybe_add_typeinfo_liveness(AllocData ^ proc_info,
+		AllocData ^ typeinfo_liveness, OutVars,
+		ForwardVars0, ForwardVars),
+
+	goal_info_get_determinism(GoalInfo0, Detism),
+	(
+		Detism = erroneous,
+		AllocData ^ opt_no_return_calls = yes
+	->
+		NeedAcrossCall = need_across_call(set__init, set__init,
+			set__init)
+	;
+		NeedAcrossCall = need_across_call(ForwardVars, ResumeVars0,
+			NondetLiveness0)
+	),
 
-	set__union(ResumeVars0, NondetLiveness0, OtherStackDemands),
-	set__union(StackVars, OtherStackDemands, InterferingVars),
-	set__insert(LiveSets0, InterferingVars, LiveSets),
+	record_call_site(NeedAcrossCall, GoalInfo0, GoalInfo,
+		StackAlloc0, StackAlloc),
 
 	% If this is a nondet call, then all the stack slots we need
 	% must be protected against reuse in following code.
 
 	goal_info_get_code_model(GoalInfo, CodeModel),
 	( CodeModel = model_non ->
-		set__union(NondetLiveness0, StackVars, NondetLiveness)
+		set__union(NondetLiveness0, ForwardVars, NondetLiveness)
 	;
 		NondetLiveness = NondetLiveness0
 	).
 
 %-----------------------------------------------------------------------------%
 
-:- pred build_live_sets_in_conj(list(hlds_goal)::in,
-	set(prog_var)::in, set(prog_var)::in, set(prog_var)::in,
-	set(set(prog_var))::in, alloc_data::in, set(prog_var)::out,
-	set(prog_var)::out, set(set(prog_var))::out) is det.
-
-build_live_sets_in_conj([], Liveness, NondetLiveness, _, LiveSets, _,
-		Liveness, NondetLiveness, LiveSets).
-build_live_sets_in_conj([Goal | Goals], Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
+:- pred build_live_sets_in_conj(list(hlds_goal)::in, T::in,
+	set(prog_var)::in, set(prog_var)::in,
+	set(prog_var)::in, alloc_data::in,
+	list(hlds_goal)::out, T::out, set(prog_var)::out, set(prog_var)::out)
+	is det <= stack_alloc_info(T).
+
+build_live_sets_in_conj([], StackAlloc, Liveness, NondetLiveness, _, _,
+		[], StackAlloc, Liveness, NondetLiveness).
+build_live_sets_in_conj([Goal0 | Goals0], StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		[Goal | Goals], StackAlloc, Liveness, NondetLiveness) :-
 	(
-		Goal = _ - GoalInfo,
+		Goal0 = _ - GoalInfo,
 		goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
 		instmap_delta_is_unreachable(InstMapDelta)
 	->
-		build_live_sets_in_goal(Goal, Liveness0,
-			NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-			Liveness, NondetLiveness, LiveSets)
-	;
-		build_live_sets_in_goal(Goal, Liveness0,
-			NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-			Liveness1, NondetLiveness1, LiveSets1),
-		build_live_sets_in_conj(Goals, Liveness1,
-			NondetLiveness1, ResumeVars0, LiveSets1, AllocData,
-			Liveness, NondetLiveness, LiveSets)
+		build_live_sets_in_goal(Goal0, StackAlloc0,
+			Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+			Goal, StackAlloc, Liveness, NondetLiveness),
+		Goals = Goals0 % XXX
+	;
+		build_live_sets_in_goal(Goal0, StackAlloc0,
+			Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+			Goal, StackAlloc1, Liveness1, NondetLiveness1),
+		build_live_sets_in_conj(Goals0, StackAlloc1,
+			Liveness1, NondetLiveness1, ResumeVars0, AllocData,
+			Goals, StackAlloc, Liveness, NondetLiveness)
 	).
 
 %-----------------------------------------------------------------------------%
 
-	% build_live_sets_in_disj is used for both disjunctions and
-	% parallel conjunctions.
+:- pred build_live_sets_in_par_conj(list(hlds_goal)::in, T::in,
+	set(prog_var)::in, set(prog_var)::in,
+	set(prog_var)::in, alloc_data::in,
+	list(hlds_goal)::out, T::out, set(prog_var)::out, set(prog_var)::out)
+	is det <= stack_alloc_info(T).
+
+build_live_sets_in_par_conj([], StackAlloc,
+		Liveness, NondetLiveness, _, _,
+		[], StackAlloc, Liveness, NondetLiveness).
+build_live_sets_in_par_conj([Goal0 | Goals0], StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		[Goal | Goals], StackAlloc, Liveness, NondetLiveness) :-
+	build_live_sets_in_goal(Goal0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, StackAlloc1, Liveness1, NondetLiveness1),
+	build_live_sets_in_par_conj(Goals0, StackAlloc1,
+		Liveness1, NondetLiveness1, ResumeVars0, AllocData,
+		Goals, StackAlloc, Liveness, NondetLiveness).
 
-:- pred build_live_sets_in_disj(list(hlds_goal)::in,
+%-----------------------------------------------------------------------------%
+
+:- pred build_live_sets_in_disj(list(hlds_goal)::in, T::in,
 	set(prog_var)::in, set(prog_var)::in, set(prog_var)::in,
-	set(set(prog_var))::in, hlds_goal_info::in, alloc_data::in,
-	set(prog_var)::out, set(prog_var)::out,
-	set(set(prog_var))::out) is det.
-
-build_live_sets_in_disj([], Liveness, NondetLiveness, _, LiveSets, _, _,
-		Liveness, NondetLiveness, LiveSets).
-build_live_sets_in_disj([Goal | Goals], Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, GoalInfo, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_goal(Goal, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness1, LiveSets1),
-	build_live_sets_in_disj(Goals, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets1, GoalInfo, AllocData,
-		_Liveness2, NondetLiveness2, LiveSets),
-	goal_info_get_code_model(GoalInfo, CodeModel),
-	( CodeModel = model_non ->
+	hlds_goal_info::in, alloc_data::in,
+	list(hlds_goal)::out, T::out,
+	set(prog_var)::out, set(prog_var)::out)
+	is det <= stack_alloc_info(T).
+
+build_live_sets_in_disj([], StackAlloc, Liveness, NondetLiveness, _, _, _,
+		[], StackAlloc, Liveness, NondetLiveness).
+build_live_sets_in_disj([Goal0 | Goals0], StackAlloc0,
+		Liveness0, NondetLiveness0,
+		ResumeVars0, DisjGoalInfo, AllocData,
+		[Goal | Goals], StackAlloc, Liveness, NondetLiveness) :-
+	Goal = _ - GoalInfo,
+	build_live_sets_in_goal(Goal0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, StackAlloc1, Liveness, NondetLiveness1),
+	build_live_sets_in_disj(Goals0, StackAlloc1,
+		Liveness0, NondetLiveness0,
+		ResumeVars0, DisjGoalInfo, AllocData,
+		Goals, StackAlloc, _Liveness2, NondetLiveness2),
+	goal_info_get_code_model(DisjGoalInfo, DisjCodeModel),
+	( DisjCodeModel = model_non ->
 			% NondetLiveness should be a set of prog_var sets.
-			% Insteading of taking the union of the NondetLive sets
+			% Instead of taking the union of the NondetLive sets
 			% at the ends of disjuncts, we should just keep them
 			% in this set of sets.
 		set__union(NondetLiveness1, NondetLiveness2, NondetLiveness3),
@@ -498,28 +522,30 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred build_live_sets_in_cases(list(case)::in,
-	set(prog_var)::in, set(prog_var)::in, set(prog_var)::in,
-	set(set(prog_var))::in, alloc_data::in, set(prog_var)::out,
-	set(prog_var)::out, set(set(prog_var))::out) is det.
-
-build_live_sets_in_cases([], Liveness, NondetLiveness, _, LiveSets,
-		_, Liveness, NondetLiveness, LiveSets).
-build_live_sets_in_cases([case(_Cons, Goal) | Cases],
-		Liveness0, NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness, LiveSets) :-
-	build_live_sets_in_goal(Goal, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets0, AllocData,
-		Liveness, NondetLiveness1, LiveSets1),
-	build_live_sets_in_cases(Cases, Liveness0,
-		NondetLiveness0, ResumeVars0, LiveSets1, AllocData,
-		_Liveness2, NondetLiveness2, LiveSets),
+:- pred build_live_sets_in_cases(list(case)::in, T::in,
+	set(prog_var)::in, set(prog_var)::in,
+	set(prog_var)::in, alloc_data::in,
+	list(case)::out, T::out, set(prog_var)::out, set(prog_var)::out)
+	is det <= stack_alloc_info(T).
+
+build_live_sets_in_cases([], StackAlloc, Liveness, NondetLiveness, _, _,
+		[], StackAlloc, Liveness, NondetLiveness).
+build_live_sets_in_cases([case(Cons, Goal0) | Cases0], StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		[case(Cons, Goal) | Cases], StackAlloc,
+		Liveness, NondetLiveness) :-
+	build_live_sets_in_goal(Goal0, StackAlloc0,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Goal, StackAlloc1, Liveness, NondetLiveness1),
+	build_live_sets_in_cases(Cases0, StackAlloc1,
+		Liveness0, NondetLiveness0, ResumeVars0, AllocData,
+		Cases, StackAlloc, _Liveness2, NondetLiveness2),
 	set__union(NondetLiveness1, NondetLiveness2, NondetLiveness).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-	% If doing alternate liveness calculation, any typeinfos for
+	% If doing typeinfo liveness calculation, any typeinfos for
 	% output variables or live variables are also live.
 	% This is because if you want to examine the live data, you need to
 	% know what shape the polymorphic args of the variables
@@ -530,23 +556,20 @@
 	% saved (otherwise we would throw out typeinfos and might
 	% need one at a continuation point just after a call).
 
-	% maybe_add_alternate_liveness_typeinfos takes a set of vars
-	% (output vars) and a set of live vars and if we
-	% are doing alternate liveness, adds the appropriate typeinfo
-	% variables to the set of variables. If not, it returns the live
-	% vars unchanged.
+	% maybe_add_typeinfo_liveness takes a set of vars (output vars) and
+	% a set of live vars and if we are doing typeinfo liveness, adds the
+	% appropriate typeinfo variables to the set of variables. If not,
+	% it returns the live vars unchanged.
 
 	% Make sure you get the output vars first, and the live vars second,
 	% since this makes a significant difference to the output set of vars.
 
-:- pred maybe_add_alternate_liveness_typeinfos(proc_info::in, bool::in,
+:- pred maybe_add_typeinfo_liveness(proc_info::in, bool::in,
 	set(prog_var)::in, set(prog_var)::in, set(prog_var)::out) is det.
 
-maybe_add_alternate_liveness_typeinfos(ProcInfo, TypeInfoLiveness, OutVars,
+maybe_add_typeinfo_liveness(ProcInfo, TypeInfoLiveness, OutVars,
 		LiveVars1, LiveVars) :-
-	(
-		TypeInfoLiveness = yes
-	->
+	( TypeInfoLiveness = yes ->
 		proc_info_vartypes(ProcInfo, VarTypes),
 		proc_info_typeinfo_varmap(ProcInfo, TVarMap),
 		proc_info_get_typeinfo_vars(LiveVars1, VarTypes, TVarMap,
@@ -561,85 +584,71 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred find_output_vars(pred_id::in, proc_id::in, list(prog_var)::in,
-	module_info::in, set(prog_var)::out) is det.
+:- pred find_input_output_vars(pred_id::in, proc_id::in, list(prog_var)::in,
+	module_info::in, set(prog_var)::out, set(prog_var)::out) is det.
 
-find_output_vars(PredId, ProcId, ArgVars, ModuleInfo, OutVars) :-
+find_input_output_vars(PredId, ProcId, ArgVars, ModuleInfo, InVars, OutVars) :-
 	module_info_preds(ModuleInfo, Preds),
 	map__lookup(Preds, PredId, PredInfo),
 	pred_info_procedures(PredInfo, Procs),
 	map__lookup(Procs, ProcId, ProcInfo),
 	proc_info_arg_info(ProcInfo, ArgInfo),
-	find_output_vars_from_arg_info(ArgVars, ArgInfo, OutVars).
+	find_input_output_vars_from_arg_info(ArgVars, ArgInfo,
+		InVars, OutVars).
 
-:- pred find_output_vars_from_arg_info(list(prog_var)::in, list(arg_info)::in,
-	set(prog_var)::out) is det.
+:- pred find_input_output_vars_from_arg_info(list(prog_var)::in,
+	list(arg_info)::in, set(prog_var)::out, set(prog_var)::out) is det.
 
-find_output_vars_from_arg_info(ArgVars, ArgInfo, OutVars) :-
+find_input_output_vars_from_arg_info(ArgVars, ArgInfo, InVars, OutVars) :-
 	assoc_list__from_corresponding_lists(ArgVars, ArgInfo, ArgPairs),
+	set__init(InVars0),
 	set__init(OutVars0),
-	find_output_vars_2(ArgPairs, OutVars0, OutVars).
+	find_input_output_vars_2(ArgPairs, InVars0, InVars, OutVars0, OutVars).
 
-:- pred find_output_vars_2(assoc_list(prog_var, arg_info)::in,
+:- pred find_input_output_vars_2(assoc_list(prog_var, arg_info)::in,
+	set(prog_var)::in, set(prog_var)::out,
 	set(prog_var)::in, set(prog_var)::out) is det.
 
-find_output_vars_2([], OutVars, OutVars).
-find_output_vars_2([Var - arg_info(_, Mode) | Rest], OutVars0, OutVars) :-
-	( Mode = top_out ->
+find_input_output_vars_2([], InVars, InVars, OutVars, OutVars).
+find_input_output_vars_2([Var - arg_info(_, Mode) | Rest],
+		InVars0, InVars, OutVars0, OutVars) :-
+	(
+		Mode = top_out,
+		InVars1 = InVars0,
 		set__insert(OutVars0, Var, OutVars1)
 	;
+		Mode = top_in,
+		set__insert(InVars0, Var, InVars1),
+		OutVars1 = OutVars0
+	;
+		Mode = top_unused,
+		InVars1 = InVars0,
 		OutVars1 = OutVars0
 	),
-	find_output_vars_2(Rest, OutVars1, OutVars).
+	find_input_output_vars_2(Rest, InVars1, InVars, OutVars1, OutVars).
 
 %-----------------------------------------------------------------------------%
 
-:- pred allocate_stack_slots(list(set(prog_var))::in, code_model::in, int::in,
-	maybe(pair(prog_var, int))::in, stack_slots::out) is det.
+:- pred record_call_site(need_across_call::in, hlds_goal_info::in,
+	hlds_goal_info::out, T::in, T::out) is det <= stack_alloc_info(T).
 
-allocate_stack_slots(ColourList, CodeModel, NumReservedSlots,
-		MaybeReservedVarInfo, StackSlots) :-
-	map__init(StackSlots0),
-		% The reserved slots are referred to by fixed number
-		% (e.g. framevar(1)) in trace__setup.
-	FirstVarSlot is 1 + NumReservedSlots,
-	allocate_stack_slots_2(ColourList, CodeModel, FirstVarSlot,
-		MaybeReservedVarInfo, StackSlots0, StackSlots).
+record_call_site(NeedAcrossCall, GoalInfo0, GoalInfo,
+		StackAlloc0, StackAlloc) :-
+	goal_info_set_need_across_call(GoalInfo0, NeedAcrossCall, GoalInfo),
+	at_call_site(NeedAcrossCall, GoalInfo, StackAlloc0, StackAlloc).
 
-:- pred allocate_stack_slots_2(list(set(prog_var))::in, code_model::in,
-	int::in, maybe(pair(prog_var, int))::in,
-	stack_slots::in, stack_slots::out) is det.
+:- pred record_resume_site(need_in_resume::in, hlds_goal_info::in,
+	hlds_goal_info::out, T::in, T::out) is det <= stack_alloc_info(T).
 
-allocate_stack_slots_2([], _, _, _, StackSlots, StackSlots).
-allocate_stack_slots_2([Vars | VarSets], CodeModel, N0, MaybeReservedVarInfo,
-		StackSlots0, StackSlots) :-
-	(
-		MaybeReservedVarInfo = yes(ResVar - ResSlotNum),
-		set__member(ResVar, Vars)
-	->
-		SlotNum = ResSlotNum,
-		N1 = N0
-	;
-		SlotNum = N0,
-		N1 = N0 + 1
-	),
-	( CodeModel = model_non ->
-		Slot = framevar(SlotNum)
-	;
-		Slot = stackvar(SlotNum)
-	),
-	set__to_sorted_list(Vars, VarList),
-	allocate_same_stack_slot(VarList, Slot, StackSlots0, StackSlots1),
-	allocate_stack_slots_2(VarSets, CodeModel, N1, MaybeReservedVarInfo,
-		StackSlots1, StackSlots).
-
-:- pred allocate_same_stack_slot(list(prog_var)::in, lval::in, stack_slots::in,
-	stack_slots::out) is det.
-
-allocate_same_stack_slot([], _Slot, StackSlots, StackSlots).
-allocate_same_stack_slot([Var | Vars], Slot, StackSlots0, StackSlots) :-
-	map__det_insert(StackSlots0, Var, Slot, StackSlots1),
-	allocate_same_stack_slot(Vars, Slot, StackSlots1, StackSlots).
+record_resume_site(NeedInResume, GoalInfo0, GoalInfo,
+		StackAlloc0, StackAlloc) :-
+	goal_info_set_need_in_resume(GoalInfo0, NeedInResume, GoalInfo),
+	at_resume_site(NeedInResume, GoalInfo, StackAlloc0, StackAlloc).
 
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
+:- pred record_par_conj(need_in_par_conj::in, hlds_goal_info::in,
+	hlds_goal_info::out, T::in, T::out) is det <= stack_alloc_info(T).
+
+record_par_conj(NeedInParConj, GoalInfo0, GoalInfo,
+		StackAlloc0, StackAlloc) :-
+	goal_info_set_need_in_par_conj(GoalInfo0, NeedInParConj, GoalInfo),
+	at_par_conj(NeedInParConj, GoalInfo, StackAlloc0, StackAlloc).
Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.118
diff -u -b -r1.118 liveness.m
--- compiler/liveness.m	7 Apr 2001 14:04:44 -0000	1.118
+++ compiler/liveness.m	12 Jan 2002 06:11:27 -0000
@@ -13,9 +13,9 @@
 % These annotations are the pre-birth set, the post-birth set,
 % the pre-death set, the post-death set, and the resume_point field.
 %
-% Because it recomputes each of these annotations from scratch,
-% it should be safe to call this module multiple times
-% (although this has not been tested yet).
+% Because it recomputes each of these annotations from scratch, it is safe
+% to call this module multiple times, and in fact we do so if stack slot
+% optimization is enabled.
 %
 % Note - the concept of `liveness' here is different to that used in
 % mode analysis. Mode analysis is concerned with the liveness of what
@@ -178,12 +178,12 @@
 % Parse tree modules
 :- import_module prog_util, (inst).
 % HLDS modules
-:- import_module hlds_goal, hlds_data, hlds_out, instmap, mode_util.
+:- import_module hlds_goal, hlds_llds, hlds_data, hlds_out, instmap, mode_util.
 :- import_module quantification, polymorphism.
 % Modules shared between different back-ends.
 :- import_module code_model, passes_aux.
 % LLDS modules
-:- import_module llds, code_util, trace_params, trace.
+:- import_module llds, arg_info, code_util, trace_params, trace.
 % Misc
 :- import_module globals, options.
 
@@ -310,11 +310,8 @@
 	),
 		% We initialize all the fields in order to obliterate any
 		% annotations left by a previous invocation of this module.
-	goal_info_set_pre_deaths(GoalInfo0, PreDeaths, GoalInfo1),
-	goal_info_set_pre_births(GoalInfo1, PreBirths, GoalInfo2),
-	goal_info_set_post_deaths(GoalInfo2, PostDeaths, GoalInfo3),
-	goal_info_set_post_births(GoalInfo3, PostBirths, GoalInfo4),
-	goal_info_set_resume_point(GoalInfo4, no_resume_point, GoalInfo).
+	goal_info_initialize_liveness_info(GoalInfo0, PreBirths, PostBirths,
+		PreDeaths, PostDeaths, no_resume_point, GoalInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -328,22 +325,22 @@
 		Liveness, conj(Goals)) :-
 	detect_liveness_in_conj(Goals0, Liveness0, LiveInfo, Liveness, Goals).
 
-detect_liveness_in_goal_2(par_conj(Goals0, SM), Liveness0, NonLocals, LiveInfo,
-		Liveness, par_conj(Goals, SM)) :-
+detect_liveness_in_goal_2(par_conj(Goals0), Liveness0, NonLocals, LiveInfo,
+		Liveness, par_conj(Goals)) :-
 	set__init(Union0),
 	detect_liveness_in_par_conj(Goals0, Liveness0, NonLocals, LiveInfo,
 		Union0, Union, Goals),
 	set__union(Liveness0, Union, Liveness).
 
-detect_liveness_in_goal_2(disj(Goals0, SM), Liveness0, NonLocals, LiveInfo,
-		Liveness, disj(Goals, SM)) :-
+detect_liveness_in_goal_2(disj(Goals0), Liveness0, NonLocals, LiveInfo,
+		Liveness, disj(Goals)) :-
 	set__init(Union0),
 	detect_liveness_in_disj(Goals0, Liveness0, NonLocals, LiveInfo,
 		Union0, Union, Goals),
 	set__union(Liveness0, Union, Liveness).
 
-detect_liveness_in_goal_2(switch(Var, Det, Cases0, SM), Liveness0, NonLocals,
-		LiveInfo, Liveness, switch(Var, Det, Cases, SM)) :-
+detect_liveness_in_goal_2(switch(Var, Det, Cases0), Liveness0, NonLocals,
+		LiveInfo, Liveness, switch(Var, Det, Cases)) :-
 	detect_liveness_in_cases(Cases0, Liveness0, NonLocals, LiveInfo,
 		Liveness0, Liveness, Cases).
 
@@ -351,9 +348,9 @@
 		Liveness, not(Goal)) :-
 	detect_liveness_in_goal(Goal0, Liveness0, LiveInfo, Liveness, Goal).
 
-detect_liveness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM),
+detect_liveness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
 		Liveness0, NonLocals, LiveInfo, Liveness,
-		if_then_else(Vars, Cond, Then, Else, SM)) :-
+		if_then_else(Vars, Cond, Then, Else)) :-
 	detect_liveness_in_goal(Cond0, Liveness0, LiveInfo, LivenessCond, Cond),
 
 	%
@@ -417,7 +414,12 @@
 		goal_info_get_instmap_delta(GoalInfo, InstmapDelta),
 		instmap_delta_is_unreachable(InstmapDelta)
 	->
-		Goals = Goals0,
+		% If we continued processing goals, the final value of Liveness
+		% would not reflect reality. If we stopped processing goals but
+		% included the original Goals0 in Goals, then the liveness
+		% fields in Goals would remain uninitialized. Removing goals
+		% following a goal that cannot succeed works.
+		Goals = [],
 		Liveness = Liveness1
 	;
 		detect_liveness_in_conj(Goals0, Liveness1, LiveInfo,
@@ -528,8 +530,8 @@
 	detect_deadness_in_conj(Goals0, Deadness0, Liveness0, LiveInfo,
 		Goals, Deadness).
 
-detect_deadness_in_goal_2(par_conj(Goals0, SM), GoalInfo, Deadness0, Liveness0,
-		LiveInfo, Deadness, par_conj(Goals, SM)) :-
+detect_deadness_in_goal_2(par_conj(Goals0), GoalInfo, Deadness0, Liveness0,
+		LiveInfo, Deadness, par_conj(Goals)) :-
 	set__init(Union0),
 	liveness__get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
 		_, CompletedNonLocals),
@@ -537,16 +539,16 @@
 		CompletedNonLocals, LiveInfo, Union0, Union, Goals),
 	set__union(Union, Deadness0, Deadness).
 
-detect_deadness_in_goal_2(disj(Goals0, SM), GoalInfo, Deadness0, Liveness0,
-		LiveInfo, Deadness, disj(Goals, SM)) :-
+detect_deadness_in_goal_2(disj(Goals0), GoalInfo, Deadness0, Liveness0,
+		LiveInfo, Deadness, disj(Goals)) :-
 	set__init(Union0),
 	liveness__get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
 		_, CompletedNonLocals),
 	detect_deadness_in_disj(Goals0, Deadness0, Liveness0,
 		CompletedNonLocals, LiveInfo, Union0, Deadness, Goals, _).
 
-detect_deadness_in_goal_2(switch(Var, Det, Cases0, SM), GoalInfo, Deadness0,
-		Liveness0, LiveInfo, Deadness, switch(Var, Det, Cases, SM)) :-
+detect_deadness_in_goal_2(switch(Var, Det, Cases0), GoalInfo, Deadness0,
+		Liveness0, LiveInfo, Deadness, switch(Var, Det, Cases)) :-
 	set__init(Union0),
 	liveness__get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
 		_, CompletedNonLocals),
@@ -558,9 +560,9 @@
 	detect_deadness_in_goal(Goal0, Deadness0, Liveness0,
 		LiveInfo, Deadness, Goal).
 
-detect_deadness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM),
+detect_deadness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
 		GoalInfo, Deadness0, Liveness0, LiveInfo, Deadness,
-		if_then_else(Vars, Cond, Then, Else, SM)) :-
+		if_then_else(Vars, Cond, Then, Else)) :-
 	update_liveness_goal(Cond0, LiveInfo, Liveness0, LivenessCond),
 
 	detect_deadness_in_goal(Else0, Deadness0, Liveness0, LiveInfo,
@@ -844,24 +846,24 @@
 		Liveness, Liveness).
 update_liveness_expr(conj(Goals), _, LiveInfo, Liveness0, Liveness) :-
 	update_liveness_conj(Goals, LiveInfo, Liveness0, Liveness).
-update_liveness_expr(par_conj(Goals, _), _, LiveInfo, Liveness0, Liveness) :-
+update_liveness_expr(par_conj(Goals), _, LiveInfo, Liveness0, Liveness) :-
 		% XXX do these need special treatment?
 	update_liveness_conj(Goals, LiveInfo, Liveness0, Liveness).
-update_liveness_expr(disj(Goals, _), _GoalInfo, LiveInfo,
+update_liveness_expr(disj(Goals), _GoalInfo, LiveInfo,
 		Liveness0, Liveness) :-
 	( find_reachable_goal(Goals, Goal) ->
 		update_liveness_goal(Goal, LiveInfo, Liveness0, Liveness)
 	;
 		Liveness = Liveness0
 	).
-update_liveness_expr(switch(_, _, Cases, _), _GoalInfo, LiveInfo,
+update_liveness_expr(switch(_, _, Cases), _GoalInfo, LiveInfo,
 		Liveness0, Liveness) :-
 	( find_reachable_case(Cases, Goal) ->
 		update_liveness_goal(Goal, LiveInfo, Liveness0, Liveness)
 	;
 		Liveness = Liveness0
 	).
-update_liveness_expr(if_then_else(_, Cond, Then, Else, _), _GoalInfo, LiveInfo,
+update_liveness_expr(if_then_else(_, Cond, Then, Else), _GoalInfo, LiveInfo,
 		Liveness0, Liveness) :-
 	Else = _ - ElseGoalInfo,
 	goal_info_get_instmap_delta(ElseGoalInfo, ElseInstmapDelta),
@@ -1025,13 +1027,13 @@
 		GoalExpr = conj(Goals),
 		GoalInfo = GoalInfo0
 	;
-		GoalExpr0 = par_conj(Goals0, SM),
+		GoalExpr0 = par_conj(Goals0),
 		delay_death_conj(Goals0, BornVars0, DelayedDead0, VarSet,
 			Goals, BornVars, DelayedDead),
-		GoalExpr = par_conj(Goals, SM),
+		GoalExpr = par_conj(Goals),
 		GoalInfo = GoalInfo0
 	;
-		GoalExpr0 = disj(Goals0, SM),
+		GoalExpr0 = disj(Goals0),
 		delay_death_disj(Goals0, BornVars0, DelayedDead0, VarSet,
 			GoalDeaths, MaybeBornVarsDelayedDead),
 		(
@@ -1039,7 +1041,7 @@
 			Goals = list__map(
 				kill_excess_delayed_dead_goal(DelayedDead),
 				GoalDeaths),
-			GoalExpr = disj(Goals, SM),
+			GoalExpr = disj(Goals),
 			GoalInfo = GoalInfo0
 		;
 			MaybeBornVarsDelayedDead = no,
@@ -1051,7 +1053,7 @@
 			DelayedDead = DelayedDead0
 		)
 	;
-		GoalExpr0 = switch(Var, CanFail, Cases0, SM),
+		GoalExpr0 = switch(Var, CanFail, Cases0),
 		delay_death_cases(Cases0, BornVars0, DelayedDead0, VarSet,
 			CaseDeaths, MaybeBornVarsDelayedDead),
 		(
@@ -1059,7 +1061,7 @@
 			Cases = list__map(
 				kill_excess_delayed_dead_case(DelayedDead),
 				CaseDeaths),
-			GoalExpr = switch(Var, CanFail, Cases, SM),
+			GoalExpr = switch(Var, CanFail, Cases),
 			GoalInfo = GoalInfo0
 		;
 			MaybeBornVarsDelayedDead = no,
@@ -1073,7 +1075,7 @@
 		GoalInfo = GoalInfo0,
 		BornVars = BornVars0
 	;
-		GoalExpr0 = if_then_else(QuantVars, Cond0, Then0, Else0, SM),
+		GoalExpr0 = if_then_else(QuantVars, Cond0, Then0, Else0),
 		delay_death_goal(Cond0, BornVars0, DelayedDead0, VarSet,
 			Cond, BornVarsCond, DelayedDeadCond),
 		delay_death_goal(Then0, BornVarsCond, DelayedDeadCond, VarSet,
@@ -1086,7 +1088,7 @@
 			Then1 - DelayedDeadThen),
 		Else = kill_excess_delayed_dead_goal(DelayedDead,
 			Else1 - DelayedDeadElse),
-		GoalExpr = if_then_else(QuantVars, Cond, Then, Else, SM),
+		GoalExpr = if_then_else(QuantVars, Cond, Then, Else),
 		GoalInfo = GoalInfo0
 	;
 		GoalExpr0 = some(QuantVars, CanRemove, Goal0),
@@ -1233,13 +1235,13 @@
 	detect_resume_points_in_conj(Goals0, Liveness0, LiveInfo, ResumeVars0,
 		Goals, Liveness).
 
-detect_resume_points_in_goal_2(par_conj(Goals0, SM), _, Liveness0, LiveInfo,
-		ResumeVars0, par_conj(Goals, SM), Liveness) :-
+detect_resume_points_in_goal_2(par_conj(Goals0), _, Liveness0, LiveInfo,
+		ResumeVars0, par_conj(Goals), Liveness) :-
 	detect_resume_points_in_par_conj(Goals0, Liveness0, LiveInfo,
 		ResumeVars0, Goals, Liveness).
 
-detect_resume_points_in_goal_2(disj(Goals0, SM), GoalInfo, Liveness0, LiveInfo,
-		ResumeVars0, disj(Goals, SM), Liveness) :-
+detect_resume_points_in_goal_2(disj(Goals0), GoalInfo, Liveness0, LiveInfo,
+		ResumeVars0, disj(Goals), Liveness) :-
 	goal_info_get_code_model(GoalInfo, CodeModel),
 	( CodeModel = model_non ->
 		detect_resume_points_in_non_disj(Goals0, Liveness0, LiveInfo,
@@ -1249,14 +1251,14 @@
 			ResumeVars0, Goals, Liveness, _)
 	).
 
-detect_resume_points_in_goal_2(switch(Var, CF, Cases0, SM), _, Liveness0,
-		LiveInfo, ResumeVars0, switch(Var, CF, Cases, SM), Liveness) :-
+detect_resume_points_in_goal_2(switch(Var, CF, Cases0), _, Liveness0,
+		LiveInfo, ResumeVars0, switch(Var, CF, Cases), Liveness) :-
 	detect_resume_points_in_cases(Cases0, Liveness0, LiveInfo, ResumeVars0,
 		Cases, Liveness).
 
-detect_resume_points_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM),
+detect_resume_points_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
 		GoalInfo0, Liveness0, LiveInfo, ResumeVars0,
-		if_then_else(Vars, Cond, Then, Else, SM), LivenessThen) :-
+		if_then_else(Vars, Cond, Then, Else), LivenessThen) :-
 
 	% compute the set of variables that may be needed at the start
 	% of the else part and attach this set to the condition
@@ -1285,6 +1287,14 @@
 	->
 		CondResumeLocs = orig_only
 	;
+		set__empty(CondResumeVars)
+	->
+		% There is no difference between orig_only and stack_only when
+		% there are no resume variables, but some parts of code_info
+		% insist on a stack label if e.g. the condition contains
+		% commits, which is why we choose to use stack_only here.
+		CondResumeLocs = stack_only
+	;
 		code_util__cannot_fail_before_stack_flush(Cond1)
 	->
 		CondResumeLocs = stack_only
@@ -1601,45 +1611,22 @@
 
 %-----------------------------------------------------------------------------%
 
+	% Return the set of variables whose values are needed beyond the end
+	% of the procedure (i.e. its output arguments).
+
 :- pred initial_deadness(proc_info::in, live_info::in, module_info::in,
 	set(prog_var)::out) is det.
 
 initial_deadness(ProcInfo, LiveInfo, ModuleInfo, Deadness) :-
-	proc_info_headvars(ProcInfo, Vars),
-	proc_info_argmodes(ProcInfo, Modes),
-	proc_info_vartypes(ProcInfo, VarTypes),
-	map__apply_to_list(Vars, VarTypes, Types),
-	set__init(Deadness0),
-		% All output arguments are in the initial deadness.
-	(
-		initial_deadness_2(Vars, Modes, Types, ModuleInfo,
-			Deadness0, Deadness1)
-	->
-		Deadness2 = Deadness1
-	;
-		error("initial_deadness: list length mis-match")
-	),
+		% The output arguments are all in the initial deadness.
+	arg_info__partition_proc_args(ProcInfo, ModuleInfo, _, Deadness0, _),
 
-		% If doing alternate liveness, the corresponding
+		% If doing typeinfo liveness, the corresponding
 		% typeinfos need to be added to these.
+	proc_info_vartypes(ProcInfo, VarTypes),
 	proc_info_typeinfo_varmap(ProcInfo, TVarMap),
-	proc_info_maybe_complete_with_typeinfo_vars(Deadness2,
+	proc_info_maybe_complete_with_typeinfo_vars(Deadness0,
 		LiveInfo ^ typeinfo_liveness, VarTypes, TVarMap, Deadness).
-
-:- pred initial_deadness_2(list(prog_var)::in, list(mode)::in, list(type)::in,
-	module_info::in, set(prog_var)::in, set(prog_var)::out) is semidet.
-
-initial_deadness_2([], [], [], _ModuleInfo, Deadness, Deadness).
-initial_deadness_2([V | Vs], [M | Ms], [T | Ts], ModuleInfo,
-		Deadness0, Deadness) :-
-	(
-		mode_to_arg_mode(ModuleInfo, M, T, top_out)
-	->
-		set__insert(Deadness0, V, Deadness1)
-	;
-		Deadness1 = Deadness0
-	),
-	initial_deadness_2(Vs, Ms, Ts, ModuleInfo, Deadness1, Deadness).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/lookup_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lookup_switch.m,v
retrieving revision 1.42
diff -u -b -r1.42 lookup_switch.m
--- compiler/lookup_switch.m	20 Jan 2001 15:42:46 -0000	1.42
+++ compiler/lookup_switch.m	18 Jul 2001 12:12:18 -0000
@@ -42,7 +42,7 @@
 :- interface.
 
 :- import_module prog_data.
-:- import_module hlds_goal, hlds_data, switch_util.
+:- import_module hlds_goal, hlds_llds, hlds_data, switch_util.
 :- import_module code_model.
 :- import_module llds, code_info.
 
Index: compiler/magic.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/magic.m,v
retrieving revision 1.28
diff -u -b -r1.28 magic.m
--- compiler/magic.m	20 Feb 2002 03:14:10 -0000	1.28
+++ compiler/magic.m	20 Feb 2002 04:26:45 -0000
@@ -268,7 +268,7 @@
 		ProcInfo0, ProcInfo, ModuleInfo0, ModuleInfo) -->
 	{ proc_info_goal(ProcInfo0, Goal0) },
 
-	{ Goal0 = if_then_else(_Vars, Cond, Then, Else, _SM) - GoalInfo ->
+	{ Goal0 = if_then_else(_Vars, Cond, Then, Else) - GoalInfo ->
 		goal_util__if_then_else_to_disjunction(Cond, Then, Else, 
 			GoalInfo, Disj),
 		Goal1 = Disj - GoalInfo,
@@ -278,7 +278,7 @@
 		% in the copies of the condition.
 		requantify_proc(ProcInfo1, ProcInfo3),
 		ModuleInfo1 = ModuleInfo0
-	; Goal0 = switch(Var, _Canfail, Cases, _SM) - GoalInfo ->
+	; Goal0 = switch(Var, _Canfail, Cases) - GoalInfo ->
 		proc_info_varset(ProcInfo0, VarSet0),
 		proc_info_vartypes(ProcInfo0, VarTypes0),
 		proc_info_get_initial_instmap(ProcInfo0, 
@@ -290,8 +290,7 @@
 			VarTypes0, VarTypes1, ModuleInfo0, ModuleInfo1),
 		proc_info_set_varset(ProcInfo0, VarSet1, ProcInfo1),
 		proc_info_set_vartypes(ProcInfo1, VarTypes1, ProcInfo2),
-		map__init(SM),
-		Goal1 = disj(Disjuncts, SM) - GoalInfo,
+		Goal1 = disj(Disjuncts) - GoalInfo,
 		proc_info_set_goal(ProcInfo2, Goal1, ProcInfo3)
 	;
 		ProcInfo3 = ProcInfo0,
@@ -1501,12 +1500,12 @@
 	% Switches, if-then-elses and disjunctions involving database calls
 	% should have been transformed into separate procedures by dnf.m.
 magic__preprocess_goal_2(Goal, [Goal], HOMap, HOMap) -->
-	{ Goal = disj(_, _) - _ }.
+	{ Goal = disj(_) - _ }.
 magic__preprocess_goal_2(Goal, [Goal], HOMap, HOMap) -->
-	{ Goal = switch(_, _, _, _) - _ }.
+	{ Goal = switch(_, _, _) - _ }.
 magic__preprocess_goal_2(Goal, [Goal], HOMap, HOMap) --> 
-	{ Goal = if_then_else(_, _, _, _, _) - _ }.
-magic__preprocess_goal_2(par_conj(_, _) - _, _, _, _) -->
+	{ Goal = if_then_else(_, _, _, _) - _ }.
+magic__preprocess_goal_2(par_conj(_) - _, _, _, _) -->
 	{ error("Sorry, not yet implemented: parallel conjunction in Aditi procedures") }.
 magic__preprocess_goal_2(generic_call(_, _, _, _) - _, _, _, _) -->
 	{ error("Sorry, not yet implemented: higher-order or class-method calls in Aditi procedures") }.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.402
diff -u -b -r1.402 make_hlds.m
--- compiler/make_hlds.m	7 Mar 2002 08:29:58 -0000	1.402
+++ compiler/make_hlds.m	8 Mar 2002 04:04:30 -0000
@@ -4764,15 +4764,15 @@
 		PredCallId, MI) -->
 	warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId, MI).
 
-warn_singletons_in_goal_2(par_conj(Goals, _SM), _GoalInfo, QuantVars, VarSet,
+warn_singletons_in_goal_2(par_conj(Goals), _GoalInfo, QuantVars, VarSet,
 		PredCallId, MI) -->
 	warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId, MI).
 
-warn_singletons_in_goal_2(disj(Goals, _), _GoalInfo, QuantVars, VarSet,
+warn_singletons_in_goal_2(disj(Goals), _GoalInfo, QuantVars, VarSet,
 		PredCallId, MI) -->
 	warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId, MI).
 
-warn_singletons_in_goal_2(switch(_Var, _CanFail, Cases, _),
+warn_singletons_in_goal_2(switch(_Var, _CanFail, Cases),
 			_GoalInfo, QuantVars, VarSet, PredCallId, MI) -->
 	warn_singletons_in_cases(Cases, QuantVars, VarSet, PredCallId, MI).
 
@@ -4797,7 +4797,7 @@
 	{ set__insert_list(QuantVars, Vars, QuantVars1) },
 	warn_singletons_in_goal(SubGoal, QuantVars1, VarSet, PredCallId, MI).
 
-warn_singletons_in_goal_2(if_then_else(Vars, Cond, Then, Else, _), GoalInfo,
+warn_singletons_in_goal_2(if_then_else(Vars, Cond, Then, Else), GoalInfo,
 				QuantVars, VarSet, PredCallId, MI) -->
 	%
 	% warn if any quantified variables do not occur in the condition
@@ -5637,9 +5637,8 @@
 		transform_info, transform_info, io__state, io__state).
 :- mode transform_goal_2(in, in, in, in, out, out, in, out, di, uo) is det.
 
-transform_goal_2(fail, _, VarSet, _, disj([], Empty) - GoalInfo, VarSet,
+transform_goal_2(fail, _, VarSet, _, disj([]) - GoalInfo, VarSet,
 		Info, Info) -->
-	{ map__init(Empty) },
 	{ goal_info_init(GoalInfo) }.
 
 transform_goal_2(true, _, VarSet, _, conj([]) - GoalInfo, VarSet,
@@ -5662,13 +5661,12 @@
 
 
 transform_goal_2(if_then_else(Vars0, A0, B0, C0), _, VarSet0, Subst,
-	if_then_else(Vars, A, B, C, Empty) - GoalInfo, VarSet, Info0, Info)
-		-->
+		if_then_else(Vars, A, B, C) - GoalInfo, VarSet,
+		Info0, Info) -->
 	{ substitute_vars(Vars0, Subst, Vars) },
 	transform_goal(A0, VarSet0, Subst, A, VarSet1, Info0, Info1),
 	transform_goal(B0, VarSet1, Subst, B, VarSet2, Info1, Info2),
 	transform_goal(C0, VarSet2, Subst, C, VarSet, Info2, Info),
-	{ map__init(Empty) },
 	{ goal_info_init(GoalInfo) }.
 
 transform_goal_2(if_then(Vars0, A0, B0), Context, Subst, VarSet0,
@@ -7269,9 +7267,8 @@
 		unravel_unification(term__variable(X), ElseTerm,
 			Context, MainContext, SubContext, VarSet33, pure,
 			ElseGoal, VarSet, Info3, Info),
-		{ map__init(Empty) },
-		{ IfThenElse = if_then_else(Vars, IfGoal, ThenGoal, ElseGoal,
-			Empty) },
+		{ IfThenElse = if_then_else(Vars, IfGoal,
+			ThenGoal, ElseGoal) },
 		{ goal_info_init(Context, GoalInfo) },
 		{ Goal = IfThenElse - GoalInfo }
 	;
Index: compiler/mark_static_terms.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mark_static_terms.m,v
retrieving revision 1.7
diff -u -b -r1.7 mark_static_terms.m
--- compiler/mark_static_terms.m	7 Apr 2001 14:04:49 -0000	1.7
+++ compiler/mark_static_terms.m	16 Jul 2001 17:19:51 -0000
@@ -58,7 +58,7 @@
 goal_expr_mark_static_terms(conj(Goals0), conj(Goals), SI0, SI) :-
 	conj_mark_static_terms(Goals0, Goals, SI0, SI).
 
-goal_expr_mark_static_terms(par_conj(Goals0, SM), par_conj(Goals, SM),
+goal_expr_mark_static_terms(par_conj(Goals0), par_conj(Goals),
 		SI0, SI) :-
 	% it's OK to treat parallel conjunctions as if they were
 	% sequential here, since if we mark any variables as
@@ -66,11 +66,11 @@
 	% done at compile time.
 	conj_mark_static_terms(Goals0, Goals, SI0, SI).
 
-goal_expr_mark_static_terms(disj(Goals0, B), disj(Goals, B), SI0, SI0) :-
+goal_expr_mark_static_terms(disj(Goals0), disj(Goals), SI0, SI0) :-
 	% we revert to the original static_info at the end of branched goals
 	disj_mark_static_terms(Goals0, Goals, SI0).
 
-goal_expr_mark_static_terms(switch(A, B, Cases0, D), switch(A, B, Cases, D),
+goal_expr_mark_static_terms(switch(A, B, Cases0), switch(A, B, Cases),
 		SI0, SI0) :-
 	% we revert to the original static_info at the end of branched goals
 	cases_mark_static_terms(Cases0, Cases, SI0).
@@ -82,8 +82,8 @@
 goal_expr_mark_static_terms(some(A, B, Goal0), some(A, B, Goal), SI0, SI) :-
 	goal_mark_static_terms(Goal0, Goal, SI0, SI).
 
-goal_expr_mark_static_terms(if_then_else(A, Cond0, Then0, Else0, E),
-		if_then_else(A, Cond, Then, Else, E), SI0, SI0) :-
+goal_expr_mark_static_terms(if_then_else(A, Cond0, Then0, Else0),
+		if_then_else(A, Cond, Then, Else), SI0, SI0) :-
 	% we run the Cond and the Then in sequence,
 	% and we run the Else in parallel with that,
 	% and then we throw away the static_infos we computed
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list