[m-rev.] for review: stack sloty optimization, part 2

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


Index: compiler/det_report.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_report.m,v
retrieving revision 1.70
diff -u -b -r1.70 det_report.m
--- compiler/det_report.m	7 Mar 2002 08:29:46 -0000	1.70
+++ compiler/det_report.m	8 Mar 2002 04:04:18 -0000
@@ -518,11 +518,11 @@
 		Diagnosed) -->
 	det_diagnose_conj(Goals, Desired, Context, DetInfo, Diagnosed).
 
-det_diagnose_goal_2(par_conj(Goals, _SM), _GoalInfo, Desired, _Actual,
+det_diagnose_goal_2(par_conj(Goals), _GoalInfo, Desired, _Actual,
 		Context, DetInfo, Diagnosed) -->
 	det_diagnose_conj(Goals, Desired, Context, DetInfo, Diagnosed).
 
-det_diagnose_goal_2(disj(Goals, _), GoalInfo, Desired, Actual, SwitchContext,
+det_diagnose_goal_2(disj(Goals), GoalInfo, Desired, Actual, SwitchContext,
 		DetInfo, Diagnosed) -->
 	det_diagnose_disj(Goals, Desired, Actual, SwitchContext, DetInfo, 0,
 		ClausesWithSoln, Diagnosed1),
@@ -545,7 +545,7 @@
 	% then it is semideterministic or worse - this is determined
 	% in switch_detection.m and handled via the CanFail field.
 
-det_diagnose_goal_2(switch(Var, SwitchCanFail, Cases, _), GoalInfo,
+det_diagnose_goal_2(switch(Var, SwitchCanFail, Cases), GoalInfo,
 		Desired, _Actual, SwitchContext, DetInfo, Diagnosed) -->
 	(
 		{ SwitchCanFail = can_fail },
@@ -608,7 +608,7 @@
 		det_report_unify_context(First, Last, Context, UnifyContext,
 			DetInfo, LT, RT), Context).
 
-det_diagnose_goal_2(if_then_else(_Vars, Cond, Then, Else, _), _GoalInfo,
+det_diagnose_goal_2(if_then_else(_Vars, Cond, Then, Else), _GoalInfo,
 		Desired, _Actual, SwitchContext, DetInfo, Diagnosed) -->
 	{
 		determinism_components(Desired, _DesiredCanFail, DesiredSolns),
Index: compiler/disj_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/disj_gen.m,v
retrieving revision 1.73
diff -u -b -r1.73 disj_gen.m
--- compiler/disj_gen.m	23 Nov 2000 04:32:34 -0000	1.73
+++ compiler/disj_gen.m	5 Nov 2001 11:21:21 -0000
@@ -21,18 +21,19 @@
 :- import_module list.
 
 :- pred disj_gen__generate_disj(code_model::in, list(hlds_goal)::in,
-	store_map::in, code_tree::out, code_info::in, code_info::out) is det.
+	hlds_goal_info::in, code_tree::out, code_info::in, code_info::out)
+	is det.
 
 %---------------------------------------------------------------------------%
 
 :- implementation.
 
-:- import_module prog_data, hlds_data, code_gen, code_util, trace.
+:- import_module prog_data, hlds_llds, hlds_data, code_gen, code_util, trace.
 :- import_module options, globals, tree.
 
 :- import_module bool, set, tree, map, std_util, term, require.
 
-disj_gen__generate_disj(CodeModel, Goals, StoreMap, Code) -->
+disj_gen__generate_disj(CodeModel, Goals, DisjGoalInfo, Code) -->
 	(
 		{ Goals = [] },
 		( { CodeModel = model_semi } ->
@@ -50,16 +51,18 @@
 			set__init(ResumeVars)
 		},
 		disj_gen__generate_real_disj(CodeModel, ResumeVars,
-			Goals, StoreMap, Code)
+			Goals, DisjGoalInfo, Code)
 	).
 
 %---------------------------------------------------------------------------%
 
 :- pred disj_gen__generate_real_disj(code_model::in, set(prog_var)::in,
-	list(hlds_goal)::in, store_map::in, code_tree::out,
+	list(hlds_goal)::in, hlds_goal_info::in, code_tree::out,
 	code_info::in, code_info::out) is det.
 
-disj_gen__generate_real_disj(CodeModel, ResumeVars, Goals, StoreMap, Code) -->
+disj_gen__generate_real_disj(CodeModel, ResumeVars, Goals, DisjGoalInfo, Code)
+		-->
+
 		% Make sure that the variables whose values will be needed
 		% on backtracking to any disjunct are materialized into
 		% registers or stack slots. Their locations are recorded
@@ -112,10 +115,11 @@
 
 	code_info__remember_position(BranchStart),
 	disj_gen__generate_disjuncts(Goals, CodeModel, ResumeMap, no,
-		HijackInfo, StoreMap, EndLabel,
+		HijackInfo, DisjGoalInfo, EndLabel,
 		ReclaimHeap, MaybeHpSlot, MaybeTicketSlot,
 		BranchStart, no, MaybeEnd, GoalsCode),
 
+	{ goal_info_get_store_map(DisjGoalInfo, StoreMap) },
 	code_info__after_all_branches(StoreMap, MaybeEnd),
 	( { CodeModel = model_non } ->
 		code_info__set_resume_point_to_unknown
@@ -134,7 +138,7 @@
 
 :- pred disj_gen__generate_disjuncts(list(hlds_goal)::in,
 	code_model::in, resume_map::in, maybe(resume_point_info)::in,
-	disj_hijack_info::in, store_map::in, label::in,
+	disj_hijack_info::in, hlds_goal_info::in, label::in,
 	bool::in, maybe(lval)::in, maybe(lval)::in, position_info::in,
 	maybe(branch_end_info)::in, maybe(branch_end_info)::out,
 	code_tree::out, code_info::in, code_info::out) is det.
@@ -142,7 +146,7 @@
 disj_gen__generate_disjuncts([], _, _, _, _, _, _, _, _, _, _, _, _, _) -->
 	{ error("empty disjunction!") }.
 disj_gen__generate_disjuncts([Goal0 | Goals], CodeModel, FullResumeMap,
-		MaybeEntryResumePoint, HijackInfo, StoreMap, EndLabel,
+		MaybeEntryResumePoint, HijackInfo, DisjGoalInfo, EndLabel,
 		ReclaimHeap, MaybeHpSlot0, MaybeTicketSlot,
 		BranchStart0, MaybeEnd0, MaybeEnd, Code) -->
 
@@ -180,7 +184,7 @@
 			{ RestoreTicketCode = empty }
 		),
 
-			% The pre_goal_update sanity check insist on
+			% The pre_goal_update sanity check insists on
 			% no_resume_point, to make sure that all resume
 			% points have been handled by surrounding code.
 		{ goal_info_set_resume_point(GoalInfo0, no_resume_point,
@@ -242,7 +246,7 @@
 			{ ResumeVarsCode = empty },
 
 			code_info__maybe_release_hp(MaybeHpSlot),
-			% we're committing to this disjunct
+			% We're committing to this disjunct if it succeeds.
 			code_info__maybe_reset_prune_and_release_ticket(
 				MaybeTicketSlot, commit, PruneTicketCode),
 
@@ -262,6 +266,7 @@
 			% the disjunction to the place indicated by StoreMap,
 			% and accumulate information about the code_info state
 			% at the ends of the branches so far.
+		{ goal_info_get_store_map(DisjGoalInfo, StoreMap) },
 		code_info__generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd1,
 			SaveCode),
 
@@ -271,8 +276,8 @@
 		]) },
 
 		disj_gen__generate_disjuncts(Goals, CodeModel, FullResumeMap,
-			yes(NextResumePoint), HijackInfo, StoreMap, EndLabel,
-			ReclaimHeap, MaybeHpSlot, MaybeTicketSlot,
+			yes(NextResumePoint), HijackInfo, DisjGoalInfo,
+			EndLabel, ReclaimHeap, MaybeHpSlot, MaybeTicketSlot,
 			BranchStart, MaybeEnd1, MaybeEnd, RestCode),
 
 		{ Code =
@@ -303,6 +308,7 @@
 
 		trace__maybe_generate_internal_event_code(Goal0, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal0, GoalCode),
+		{ goal_info_get_store_map(DisjGoalInfo, StoreMap) },
 		code_info__generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd,
 			SaveCode),
 
Index: compiler/dnf.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dnf.m,v
retrieving revision 1.45
diff -u -b -r1.45 dnf.m
--- compiler/dnf.m	24 May 2001 05:45:37 -0000	1.45
+++ compiler/dnf.m	16 Jul 2001 17:15:39 -0000
@@ -189,7 +189,7 @@
 			Goals, NewPredIds0, NewPredIds),
 		Goal = conj(Goals) - GoalInfo
 	;
-		GoalExpr0 = par_conj(_Goals0, _SM),
+		GoalExpr0 = par_conj(_Goals0),
 		error("sorry, dnf of parallel conjunction not implemented")
 	;
 		GoalExpr0 = some(Vars, CanRemove, SomeGoal0),
@@ -204,24 +204,24 @@
 			DnfInfo, NegGoal, NewPredIds0, NewPredIds),
 		Goal = not(NegGoal) - GoalInfo
 	;
-		GoalExpr0 = disj(Goals0, SM),
+		GoalExpr0 = disj(Goals0),
 		dnf__transform_disj(Goals0, InstMap0, MaybeNonAtomic,
 			ModuleInfo0, ModuleInfo, Base, 0, DnfInfo,
 			Goals, NewPredIds0, NewPredIds),
-		Goal = disj(Goals, SM) - GoalInfo
+		Goal = disj(Goals) - GoalInfo
 	;
-		GoalExpr0 = switch(Var, CanFail, Cases0, SM),
+		GoalExpr0 = switch(Var, CanFail, Cases0),
 		dnf__transform_switch(Cases0, InstMap0, MaybeNonAtomic,
 			ModuleInfo0, ModuleInfo, Base, 0, DnfInfo,
 			Cases, NewPredIds0, NewPredIds),
-		Goal = switch(Var, CanFail, Cases, SM) - GoalInfo
+		Goal = switch(Var, CanFail, Cases) - GoalInfo
 	;
-		GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0, SM),
+		GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
 		% XXX should handle nonempty Vars
 		dnf__transform_ite(Cond0, Then0, Else0, InstMap0,
 			MaybeNonAtomic, ModuleInfo0, ModuleInfo, Base, 0,
 			DnfInfo, Cond, Then, Else, NewPredIds0, NewPredIds),
-		Goal = if_then_else(Vars, Cond, Then, Else, SM) - GoalInfo
+		Goal = if_then_else(Vars, Cond, Then, Else) - GoalInfo
 	;
 		GoalExpr0 = generic_call(_, _, _, _),
 		ModuleInfo = ModuleInfo0,
@@ -450,12 +450,12 @@
 	;
 		IsAtomic = no
 	).
-dnf__is_atomic_expr(_, _, _, par_conj(_, _), no).
+dnf__is_atomic_expr(_, _, _, par_conj(_), no).
 dnf__is_atomic_expr(_, _, _, generic_call(_, _, _, _), yes).
 dnf__is_atomic_expr(_, _, _, call(_, _, _, _, _, _), yes).
-dnf__is_atomic_expr(_, _, _, switch(_, _, _, _), no).
+dnf__is_atomic_expr(_, _, _, switch(_, _, _), no).
 dnf__is_atomic_expr(_, _, _, unify(_, _, _, _, _), yes).
-dnf__is_atomic_expr(_, _, _, disj(_, _), no).
+dnf__is_atomic_expr(_, _, _, disj(_), no).
 dnf__is_atomic_expr(MaybeNonAtomic, InNeg, InSome, not(NegGoalExpr - _),
 		IsAtomic) :-
 	( InNeg = no ->
@@ -472,7 +472,7 @@
 	;
 		IsAtomic = no
 	).
-dnf__is_atomic_expr(_, _, _, if_then_else(_, _, _, _, _), no).
+dnf__is_atomic_expr(_, _, _, if_then_else(_, _, _, _), no).
 dnf__is_atomic_expr(_, _, _, foreign_proc(_, _, _, _, _, _, _), yes).
 dnf__is_atomic_expr(MaybeNonAtomic, InNeg, InSome, shorthand(ShorthandGoal),
 		IsAtomic) :-
@@ -491,11 +491,11 @@
 
 dnf__free_of_nonatomic(conj(Goals) - _, NonAtomic) :-
 	dnf__goals_free_of_nonatomic(Goals, NonAtomic).
-dnf__free_of_nonatomic(par_conj(Goals, _) - _, NonAtomic) :-
+dnf__free_of_nonatomic(par_conj(Goals) - _, NonAtomic) :-
 	dnf__goals_free_of_nonatomic(Goals, NonAtomic).
 dnf__free_of_nonatomic(call(PredId, ProcId, _, _, _, _) - _, NonAtomic) :-
 	\+ set__member(proc(PredId, ProcId), NonAtomic).
-dnf__free_of_nonatomic(switch(_, _, Cases, _) - _, NonAtomic) :-
+dnf__free_of_nonatomic(switch(_, _, Cases) - _, NonAtomic) :-
 	dnf__cases_free_of_nonatomic(Cases, NonAtomic).
 dnf__free_of_nonatomic(unify(_, _, _, Uni, _) - _, NonAtomic) :-
 	\+ (
@@ -503,7 +503,7 @@
 			_, _, _, _, _),
 		set__member(proc(PredId, ProcId), NonAtomic)
 	).
-dnf__free_of_nonatomic(disj(Goals, _) - GoalInfo, NonAtomic) :-
+dnf__free_of_nonatomic(disj(Goals) - GoalInfo, NonAtomic) :-
 		% For Aditi, nondet disjunctions are non-atomic, 
 		% no matter what they contain.
 	goal_info_get_determinism(GoalInfo, Detism),
@@ -513,7 +513,7 @@
 	dnf__free_of_nonatomic(Goal, NonAtomic).
 dnf__free_of_nonatomic(some(_, _, Goal) - _, NonAtomic) :-
 	dnf__free_of_nonatomic(Goal, NonAtomic).
-dnf__free_of_nonatomic(if_then_else(_, Cond, Then, Else, _) - GoalInfo, 
+dnf__free_of_nonatomic(if_then_else(_, Cond, Then, Else) - GoalInfo, 
 		NonAtomic) :-
 		% For Aditi, nondet if-then-elses are non-atomic, 
 		% no matter what they contain.
Index: compiler/follow_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/follow_code.m,v
retrieving revision 1.62
diff -u -b -r1.62 follow_code.m
--- compiler/follow_code.m	7 Apr 2001 14:04:36 -0000	1.62
+++ compiler/follow_code.m	19 Dec 2001 00:47:29 -0000
@@ -88,25 +88,25 @@
 move_follow_code_in_goal_2(conj(Goals0), conj(Goals), Flags, R0, R) :-
 	move_follow_code_in_conj(Goals0, Goals, Flags, R0, R).
 
-move_follow_code_in_goal_2(par_conj(Goals0, SM), par_conj(Goals, SM),
+move_follow_code_in_goal_2(par_conj(Goals0), par_conj(Goals),
 		Flags, R0, R) :-
 		% move_follow_code_in_disj treats its list of goals as
 		% independent goals, so we can use it to process the
 		% independent parallel conjuncts.
 	move_follow_code_in_disj(Goals0, Goals, Flags, R0, R).
 
-move_follow_code_in_goal_2(disj(Goals0, SM), disj(Goals, SM), Flags, R0, R) :-
+move_follow_code_in_goal_2(disj(Goals0), disj(Goals), Flags, R0, R) :-
 	move_follow_code_in_disj(Goals0, Goals, Flags, R0, R).
 
 move_follow_code_in_goal_2(not(Goal0), not(Goal), Flags, R0, R) :-
 	move_follow_code_in_goal(Goal0, Goal, Flags, R0, R).
 
-move_follow_code_in_goal_2(switch(Var, Det, Cases0, SM),
-		switch(Var, Det, Cases, SM), Flags, R0, R) :-
+move_follow_code_in_goal_2(switch(Var, Det, Cases0),
+		switch(Var, Det, Cases), Flags, R0, R) :-
 	move_follow_code_in_cases(Cases0, Cases, Flags, R0, R).
 
-move_follow_code_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0, SM),
-		if_then_else(Vars, Cond, Then, Else, SM), Flags, R0, R) :-
+move_follow_code_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
+		if_then_else(Vars, Cond, Then, Else), Flags, R0, R) :-
 	move_follow_code_in_goal(Cond0, Cond, Flags, R0, R1),
 	move_follow_code_in_goal(Then0, Then, Flags, R1, R2),
 	move_follow_code_in_goal(Else0, Else, Flags, R2, R).
@@ -211,15 +211,15 @@
 %-----------------------------------------------------------------------------%
 
 move_follow_code_select([], [], []).
-move_follow_code_select([Goal|Goals], FollowGoals, RestGoals) :-
-	(
-		move_follow_code_is_builtin(Goal)
-	->
+move_follow_code_select([Goal | Goals], FollowGoals, RestGoals) :-
+	% Goal = _ - GoalInfo,
+	% \+ goal_info_has_feature(GoalInfo, (impure))
+	( move_follow_code_is_builtin(Goal) ->
 		move_follow_code_select(Goals, FollowGoals0, RestGoals),
-		FollowGoals = [Goal|FollowGoals0]
+		FollowGoals = [Goal | FollowGoals0]
 	;
 		FollowGoals = [],
-		RestGoals = [Goal|Goals]
+		RestGoals = [Goal | Goals]
 	).
 
 %-----------------------------------------------------------------------------%
@@ -229,20 +229,20 @@
 
 move_follow_code_move_goals(Goal0 - GoalInfo, FollowGoals, Goal - GoalInfo) :-
 	(
-		Goal0 = switch(Var, Det, Cases0, SM),
+		Goal0 = switch(Var, Det, Cases0),
 		move_follow_code_move_goals_cases(Cases0, FollowGoals, Cases),
-		Goal = switch(Var, Det, Cases, SM)
+		Goal = switch(Var, Det, Cases)
 	;
-		Goal0 = disj(Goals0, SM),
+		Goal0 = disj(Goals0),
 		move_follow_code_move_goals_disj(Goals0, FollowGoals, Goals),
-		Goal = disj(Goals, SM)
+		Goal = disj(Goals)
 	;
-		Goal0 = if_then_else(Vars, Cond, Then0, Else0, SM),
+		Goal0 = if_then_else(Vars, Cond, Then0, Else0),
 		follow_code__conjoin_goal_and_goal_list(Then0,
 			FollowGoals, Then),
 		follow_code__conjoin_goal_and_goal_list(Else0,
 			FollowGoals, Else),
-		Goal = if_then_else(Vars, Cond, Then, Else, SM)
+		Goal = if_then_else(Vars, Cond, Then, Else)
 	).
 
 %-----------------------------------------------------------------------------%
Index: compiler/follow_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/follow_vars.m,v
retrieving revision 1.62
diff -u -b -r1.62 follow_vars.m
--- compiler/follow_vars.m	7 Apr 2001 14:04:37 -0000	1.62
+++ compiler/follow_vars.m	22 Jul 2001 13:31:13 -0000
@@ -28,7 +28,7 @@
 
 :- interface.
 
-:- import_module hlds_module, hlds_pred, hlds_goal, prog_data.
+:- import_module hlds_module, hlds_pred, hlds_goal, hlds_llds, prog_data.
 :- import_module map.
 
 :- pred find_final_follow_vars(proc_info::in, follow_vars_map::out, int::out)
@@ -84,29 +84,30 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-find_follow_vars_in_goal(Goal0 - GoalInfo, VarTypes, ModuleInfo,
+find_follow_vars_in_goal(Goal0 - GoalInfo0, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
 		Goal - GoalInfo, FollowVarsMap, NextNonReserved) :-
-	find_follow_vars_in_goal_expr(Goal0, VarTypes, ModuleInfo,
+	find_follow_vars_in_goal_expr(Goal0, GoalInfo0, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
-		Goal, FollowVarsMap, NextNonReserved).
+		Goal, GoalInfo, FollowVarsMap, NextNonReserved).
 
 %-----------------------------------------------------------------------------%
 
-:- pred find_follow_vars_in_goal_expr(hlds_goal_expr::in,
+:- pred find_follow_vars_in_goal_expr(hlds_goal_expr::in, hlds_goal_info::in,
 	map(prog_var, type)::in, module_info::in, follow_vars_map::in, int::in,
-	hlds_goal_expr::out, follow_vars_map::out, int::out) is det.
+	hlds_goal_expr::out, hlds_goal_info::out, follow_vars_map::out,
+	int::out) is det.
 
-find_follow_vars_in_goal_expr(conj(Goals0), VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		conj(Goals), FollowVarsMap, NextNonReserved) :-
+find_follow_vars_in_goal_expr(conj(Goals0), GoalInfo,
+		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
+		conj(Goals), GoalInfo, FollowVarsMap, NextNonReserved) :-
 	find_follow_vars_in_conj(Goals0, VarTypes, ModuleInfo,
 		no, FollowVarsMap0, NextNonReserved0,
 		Goals, FollowVarsMap, NextNonReserved).
 
-find_follow_vars_in_goal_expr(par_conj(Goals0, SM), VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		par_conj(Goals, SM), FollowVarsMap, NextNonReserved) :-
+find_follow_vars_in_goal_expr(par_conj(Goals0), GoalInfo,
+		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
+		par_conj(Goals), GoalInfo, FollowVarsMap, NextNonReserved) :-
 		% find_follow_vars_in_disj treats its list of goals as a
 		% series of independent goals, so we can use it to process
 		% independent parallel conjunction.
@@ -118,16 +119,17 @@
 	% be in the locations given by the initial follow_vars, which reflects
 	% the requirements of the code following the disjunction.
 
-find_follow_vars_in_goal_expr(disj(Goals0, _), VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		disj(Goals, FollowVarsMap0), FollowVarsMap, NextNonReserved) :-
+find_follow_vars_in_goal_expr(disj(Goals0), GoalInfo0,
+		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
+		disj(Goals), GoalInfo, FollowVarsMap, NextNonReserved) :-
 	find_follow_vars_in_disj(Goals0, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
-		Goals, FollowVarsMap, NextNonReserved).
+		Goals, FollowVarsMap, NextNonReserved),
+	goal_info_set_store_map(GoalInfo0, FollowVarsMap0, GoalInfo).
 
-find_follow_vars_in_goal_expr(not(Goal0), VarTypes, ModuleInfo,
+find_follow_vars_in_goal_expr(not(Goal0), GoalInfo, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
-		not(Goal), FollowVarsMap, NextNonReserved) :-
+		not(Goal), GoalInfo, FollowVarsMap, NextNonReserved) :-
 	find_follow_vars_in_goal(Goal0, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
 		Goal, FollowVarsMap, NextNonReserved).
@@ -136,13 +138,14 @@
 	% should be in the locations given by the initial follow_vars, which
 	% reflects the requirements of the code following the switch.
 
-find_follow_vars_in_goal_expr(switch(Var, Det, Cases0, _), VarTypes,
-		ModuleInfo, FollowVarsMap0, NextNonReserved0,
-		switch(Var, Det, Cases, FollowVarsMap0),
+find_follow_vars_in_goal_expr(switch(Var, Det, Cases0), GoalInfo0,
+		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
+		switch(Var, Det, Cases), GoalInfo,
 		FollowVarsMap, NextNonReserved) :-
 	find_follow_vars_in_cases(Cases0, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
-		Cases, FollowVarsMap, NextNonReserved).
+		Cases, FollowVarsMap, NextNonReserved),
+	goal_info_set_store_map(GoalInfo0, FollowVarsMap0, GoalInfo).
 
 	% Set the follow_vars field for the condition, the then-part and the
 	% else-part, since in general they have requirements about where
@@ -161,9 +164,10 @@
 	% follow_vars, which reflects the requirements of the code
 	% following the if-then-else.
 
-find_follow_vars_in_goal_expr(if_then_else(Vars, Cond0, Then0, Else0, _),
+find_follow_vars_in_goal_expr(
+		if_then_else(Vars, Cond0, Then0, Else0), GoalInfo0,
 		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
-		if_then_else(Vars, Cond, Then, Else, FollowVarsMap0),
+		if_then_else(Vars, Cond, Then, Else), GoalInfo,
 		FollowVarsMapCond, NextNonReservedCond) :-
 	find_follow_vars_in_goal(Then0, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
@@ -181,18 +185,21 @@
 		FollowVarsMap0, NextNonReserved0,
 		Else1, FollowVarsMapElse, NextNonReservedElse),
 	FollowVarsElse = follow_vars(FollowVarsMapElse, NextNonReservedElse),
-	goal_set_follow_vars(Else1, yes(FollowVarsElse), Else).
+	goal_set_follow_vars(Else1, yes(FollowVarsElse), Else),
+
+	goal_info_set_store_map(GoalInfo0, FollowVarsMap0, GoalInfo).
 
-find_follow_vars_in_goal_expr(some(Vars, CanRemove, Goal0),
+find_follow_vars_in_goal_expr(some(Vars, CanRemove, Goal0), GoalInfo,
 		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
-		some(Vars, CanRemove, Goal), FollowVarsMap, NextNonReserved) :-
+		some(Vars, CanRemove, Goal), GoalInfo,
+		FollowVarsMap, NextNonReserved) :-
 	find_follow_vars_in_goal(Goal0, VarTypes, ModuleInfo,
 		FollowVarsMap0, NextNonReserved0,
 		Goal, FollowVarsMap, NextNonReserved).
 
-find_follow_vars_in_goal_expr(unify(A,B,C,D,E), _, _ModuleInfo,
-		FollowVarsMap0, NextNonReserved,
-		unify(A,B,C,D,E), FollowVarsMap, NextNonReserved) :-
+find_follow_vars_in_goal_expr(unify(A,B,C,D,E), GoalInfo,
+		_VarTypes, _ModuleInfo, FollowVarsMap0, NextNonReserved,
+		unify(A,B,C,D,E), GoalInfo, FollowVarsMap, NextNonReserved) :-
 	(
 		D = assign(LVar, RVar),
 		map__search(FollowVarsMap0, LVar, DesiredLoc)
@@ -202,26 +209,26 @@
 		FollowVarsMap = FollowVarsMap0
 	).
 
-find_follow_vars_in_goal_expr(foreign_proc(A,B,C,D,E,F,G),
+find_follow_vars_in_goal_expr(foreign_proc(A,B,C,D,E,F,G), GoalInfo,
 		_, _ModuleInfo, FollowVarsMap, NextNonReserved,
-		foreign_proc(A,B,C,D,E,F,G),
+		foreign_proc(A,B,C,D,E,F,G), GoalInfo,
 		FollowVarsMap, NextNonReserved).
 
-find_follow_vars_in_goal_expr(shorthand(_), _, _, _, _, _, _, _) :-
+find_follow_vars_in_goal_expr(shorthand(_), _, _, _, _, _, _, _, _, _) :-
 	% these should have been expanded out by now
 	error("find_follow_vars_in_goal_2: unexpected shorthand").
 
 find_follow_vars_in_goal_expr(
-		generic_call(GenericCall, Args, Modes, Det),
+		generic_call(GenericCall, Args, Modes, Det), GoalInfo,
 		VarTypes, ModuleInfo, _FollowVarsMap0, _NextNonReserved0,
-		generic_call(GenericCall, Args, Modes, Det),
+		generic_call(GenericCall, Args, Modes, Det), GoalInfo,
 		FollowVarsMap, NextNonReserved) :-
 	determinism_to_code_model(Det, CodeModel),
 	map__apply_to_list(Args, VarTypes, Types),
 	call_gen__maybe_remove_aditi_state_args(GenericCall,
 		Args, Types, Modes, EffArgs, EffTypes, EffModes),
-	make_arg_infos(EffTypes, EffModes, CodeModel, ModuleInfo, EffArgInfo),
-	assoc_list__from_corresponding_lists(EffArgs, EffArgInfo,
+	make_arg_infos(EffTypes, EffModes, CodeModel, ModuleInfo, EffArgInfos),
+	assoc_list__from_corresponding_lists(EffArgs, EffArgInfos,
 		EffArgsInfos),
 	arg_info__partition_args(EffArgsInfos, EffInVarInfos, _),
 	assoc_list__keys(EffInVarInfos, EffInVars),
@@ -233,9 +240,9 @@
 	find_follow_vars_from_sequence(EffInVars, FirstInput, FollowVarsMap1,
 		FollowVarsMap, NextNonReserved).
 
-find_follow_vars_in_goal_expr(call(PredId, ProcId, Args, State, E,F),
-		_, ModuleInfo, FollowVarsMap0, NextNonReserved0,
-		call(PredId, ProcId, Args, State, E,F),
+find_follow_vars_in_goal_expr(call(PredId, ProcId, Args, State, E, F),
+		GoalInfo, _, ModuleInfo, FollowVarsMap0, NextNonReserved0,
+		call(PredId, ProcId, Args, State, E, F), GoalInfo,
 		FollowVarsMap, NextNonReserved) :-
 	( State = inline_builtin ->
 		FollowVarsMap = FollowVarsMap0,
@@ -252,10 +259,7 @@
 
 find_follow_vars_in_call(PredId, ProcId, Args, ModuleInfo,
 		FollowVarsMap, NextNonReserved) :-
-	module_info_preds(ModuleInfo, PredTable),
-	map__lookup(PredTable, PredId, PredInfo),
-	pred_info_procedures(PredInfo, ProcTable),
-	map__lookup(ProcTable, ProcId, ProcInfo),
+	module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo),
 	proc_info_arg_info(ProcInfo, ArgInfo),
 	assoc_list__from_corresponding_lists(Args, ArgInfo, ArgsInfos),
 	map__init(FollowVarsMap0),
Index: compiler/goal_path.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_path.m,v
retrieving revision 1.14
diff -u -b -r1.14 goal_path.m
--- compiler/goal_path.m	7 Apr 2001 14:04:37 -0000	1.14
+++ compiler/goal_path.m	16 Jul 2001 17:09:34 -0000
@@ -49,13 +49,13 @@
 
 fill_expr_slots(conj(Goals0), _, Path0, SlotInfo, conj(Goals)) :-
 	fill_conj_slots(Goals0, Path0, 0, SlotInfo, Goals).
-fill_expr_slots(par_conj(Goals0, SM), _, Path0, SlotInfo,
-		par_conj(Goals, SM)) :-
+fill_expr_slots(par_conj(Goals0), _, Path0, SlotInfo,
+		par_conj(Goals)) :-
 	fill_conj_slots(Goals0, Path0, 0, SlotInfo, Goals).
-fill_expr_slots(disj(Goals0, B), _, Path0, SlotInfo, disj(Goals, B)) :-
+fill_expr_slots(disj(Goals0), _, Path0, SlotInfo, disj(Goals)) :-
 	fill_disj_slots(Goals0, Path0, 0, SlotInfo, Goals).
-fill_expr_slots(switch(Var, B, Cases0, D), _, Path0, SlotInfo,
-		switch(Var, B, Cases, D)) :-
+fill_expr_slots(switch(Var, B, Cases0), _, Path0, SlotInfo,
+		switch(Var, B, Cases)) :-
 	SlotInfo = slot_info(VarTypes, ModuleInfo),
 	map__lookup(VarTypes, Var, Type),
 	(
@@ -80,8 +80,8 @@
 		MaybeCut = cut
 	),
 	fill_goal_slots(Goal0, [exist(MaybeCut) | Path0], SlotInfo, Goal).
-fill_expr_slots(if_then_else(A, Cond0, Then0, Else0, E), _, Path0, SlotInfo,
-		if_then_else(A, Cond, Then, Else, E)) :-
+fill_expr_slots(if_then_else(A, Cond0, Then0, Else0), _, Path0, SlotInfo,
+		if_then_else(A, Cond, Then, Else)) :-
 	fill_goal_slots(Cond0, [ite_cond | Path0], SlotInfo, Cond),
 	fill_goal_slots(Then0, [ite_then | Path0], SlotInfo, Then),
 	fill_goal_slots(Else0, [ite_else | Path0], SlotInfo, Else).
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.73
diff -u -b -r1.73 goal_util.m
--- compiler/goal_util.m	22 Feb 2002 01:20:40 -0000	1.73
+++ compiler/goal_util.m	22 Feb 2002 05:17:54 -0000
@@ -6,8 +6,19 @@
 
 % Main author: conway.
 %
-% This module provides various utility procedures for manipulating HLDS goals,
-% e.g. some functionality for renaming variables in goals.
+% This module provides some functionality for renaming variables in goals.
+% The predicates rename_var* take a structure and a mapping from var -> var
+% and apply that translation. If a var in the input structure does not
+% occur as a key in the mapping, then the variable is left unsubstituted.
+
+% goal_util__create_variables takes a list of variables, a varset an
+% initial translation mapping and an initial mapping from variable to
+% type, and creates new instances of each of the source variables in the
+% translation mapping, adding the new variable to the type mapping and
+% updating the varset. The type for each new variable is found by looking
+% in the type map given in the 5th argument - the last input.
+% (This interface will not easily admit uniqueness in the type map for this
+% reason - such is the sacrifice for generality.)
 
 %-----------------------------------------------------------------------------%
 
@@ -36,10 +47,17 @@
 		map(prog_var, prog_var), hlds_goal).
 :- mode goal_util__must_rename_vars_in_goal(in, in, out) is det.
 
+:- pred goal_util__rename_vars_in_var_set(set(prog_var), bool,
+	map(prog_var, prog_var), set(prog_var)).
+:- mode goal_util__rename_vars_in_var_set(in, in, in, out) is det.
+
 :- pred goal_util__rename_var_list(list(var(T)), bool,
 		map(var(T), var(T)), list(var(T))).
 :- mode goal_util__rename_var_list(in, in, in, out) is det.
 
+:- pred goal_util__rename_var(var(V), bool, map(var(V), var(V)), var(V)).
+:- mode goal_util__rename_var(in, in, in, out) is det.
+
 % goal_util__create_variables takes a list of variables, a varset an
 % initial translation mapping and an initial mapping from variable to
 % type, and creates new instances of each of the source variables in the
@@ -228,7 +246,7 @@
 
 :- implementation.
 
-:- import_module hlds_data, mode_util, code_aux, prog_data, purity.
+:- import_module hlds_data, hlds_llds, mode_util, code_aux, prog_data, purity.
 :- import_module code_aux, det_analysis, inst_match, type_util, (inst).
 
 :- import_module int, string, require, varset.
@@ -293,10 +311,6 @@
 	goal_util__rename_var(V, Must, Subn, N),
 	goal_util__rename_var_list(Vs, Must, Subn, Ns).
 
-:- pred goal_util__rename_var(var(V), bool, map(var(V), var(V)),
-		var(V)).
-:- mode goal_util__rename_var(in, in, in, out) is det.
-
 goal_util__rename_var(V, Must, Subn, N) :-
 	(
 		map__search(Subn, V, N0)
@@ -337,109 +351,93 @@
 
 goal_util__rename_vars_in_goal(Goal0 - GoalInfo0, Must, Subn, Goal - GoalInfo)
 		:-
-	goal_util__name_apart_2(Goal0, Must, Subn, Goal),
-	goal_util__name_apart_goalinfo(GoalInfo0, Must, Subn, GoalInfo).
+	goal_util__rename_vars_in_goal_expr(Goal0, Must, Subn, Goal),
+	goal_util__rename_vars_in_goal_info(GoalInfo0, Must, Subn, GoalInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__name_apart_2(hlds_goal_expr, bool, map(prog_var, prog_var),
-		hlds_goal_expr).
-:- mode goal_util__name_apart_2(in, in, in, out) is det.
+:- pred goal_util__rename_vars_in_goal_expr(hlds_goal_expr, bool,
+	map(prog_var, prog_var), hlds_goal_expr).
+:- mode goal_util__rename_vars_in_goal_expr(in, in, in, out) is det.
 
-goal_util__name_apart_2(conj(Goals0), Must, Subn, conj(Goals)) :-
-	goal_util__name_apart_list(Goals0, Must, Subn, Goals).
+goal_util__rename_vars_in_goal_expr(conj(Goals0), Must, Subn, conj(Goals)) :-
+	goal_util__rename_vars_in_goals(Goals0, Must, Subn, Goals).
 
-goal_util__name_apart_2(par_conj(Goals0, SM0), Must, Subn,
-		par_conj(Goals, SM)) :-
-	goal_util__name_apart_list(Goals0, Must, Subn, Goals),
-	goal_util__rename_var_maps(SM0, Must, Subn, SM).
+goal_util__rename_vars_in_goal_expr(par_conj(Goals0), Must, Subn,
+		par_conj(Goals)) :-
+	goal_util__rename_vars_in_goals(Goals0, Must, Subn, Goals).
 
-goal_util__name_apart_2(disj(Goals0, SM0), Must, Subn, disj(Goals, SM)) :-
-	goal_util__name_apart_list(Goals0, Must, Subn, Goals),
-	goal_util__rename_var_maps(SM0, Must, Subn, SM).
+goal_util__rename_vars_in_goal_expr(disj(Goals0), Must, Subn, disj(Goals)) :-
+	goal_util__rename_vars_in_goals(Goals0, Must, Subn, Goals).
 
-goal_util__name_apart_2(switch(Var0, Det, Cases0, SM0), Must, Subn,
-		switch(Var, Det, Cases, SM)) :-
+goal_util__rename_vars_in_goal_expr(switch(Var0, Det, Cases0), Must, Subn,
+		switch(Var, Det, Cases)) :-
 	goal_util__rename_var(Var0, Must, Subn, Var),
-	goal_util__name_apart_cases(Cases0, Must, Subn, Cases),
-	goal_util__rename_var_maps(SM0, Must, Subn, SM).
+	goal_util__rename_vars_in_cases(Cases0, Must, Subn, Cases).
 
-goal_util__name_apart_2(if_then_else(Vars0, Cond0, Then0, Else0, SM0),
-		Must, Subn, if_then_else(Vars, Cond, Then, Else, SM)) :-
+goal_util__rename_vars_in_goal_expr(if_then_else(Vars0, Cond0, Then0, Else0),
+		Must, Subn, if_then_else(Vars, Cond, Then, Else)) :-
 	goal_util__rename_var_list(Vars0, Must, Subn, Vars),
 	goal_util__rename_vars_in_goal(Cond0, Must, Subn, Cond),
 	goal_util__rename_vars_in_goal(Then0, Must, Subn, Then),
-	goal_util__rename_vars_in_goal(Else0, Must, Subn, Else),
-	goal_util__rename_var_maps(SM0, Must, Subn, SM).
+	goal_util__rename_vars_in_goal(Else0, Must, Subn, Else).
 
-goal_util__name_apart_2(not(Goal0), Must, Subn, not(Goal)) :-
+goal_util__rename_vars_in_goal_expr(not(Goal0), Must, Subn, not(Goal)) :-
 	goal_util__rename_vars_in_goal(Goal0, Must, Subn, Goal).
 
-goal_util__name_apart_2(some(Vars0, CanRemove, Goal0), Must, Subn,
+goal_util__rename_vars_in_goal_expr(some(Vars0, CanRemove, Goal0), Must, Subn,
 		some(Vars, CanRemove, Goal)) :-
 	goal_util__rename_var_list(Vars0, Must, Subn, Vars),
 	goal_util__rename_vars_in_goal(Goal0, Must, Subn, Goal).
 
-goal_util__name_apart_2(
+goal_util__rename_vars_in_goal_expr(
 		generic_call(GenericCall0, Args0, Modes, Det),
 		Must, Subn,
 		generic_call(GenericCall, Args, Modes, Det)) :-
 	goal_util__rename_generic_call(GenericCall0, Must, Subn, GenericCall),
 	goal_util__rename_var_list(Args0, Must, Subn, Args).
 
-goal_util__name_apart_2(
+goal_util__rename_vars_in_goal_expr(
 		call(PredId, ProcId, Args0, Builtin, Context, Sym),
 		Must, Subn,
 		call(PredId, ProcId, Args, Builtin, Context, Sym)) :-
 	goal_util__rename_var_list(Args0, Must, Subn, Args).
 
-goal_util__name_apart_2(unify(TermL0,TermR0,Mode,Unify0,Context), Must, Subn,
-		unify(TermL,TermR,Mode,Unify,Context)) :-
+goal_util__rename_vars_in_goal_expr(unify(TermL0,TermR0,Mode,Unify0,Context),
+		Must, Subn, unify(TermL,TermR,Mode,Unify,Context)) :-
 	goal_util__rename_var(TermL0, Must, Subn, TermL),
 	goal_util__rename_unify_rhs(TermR0, Must, Subn, TermR),
 	goal_util__rename_unify(Unify0, Must, Subn, Unify).
 
-goal_util__name_apart_2(foreign_proc(A,B,C,Vars0,E,F,G), Must, Subn,
-		foreign_proc(A,B,C,Vars,E,F,G)) :-
+goal_util__rename_vars_in_goal_expr(foreign_proc(A,B,C,Vars0,E,F,G),
+		Must, Subn, foreign_proc(A,B,C,Vars,E,F,G)) :-
 	goal_util__rename_var_list(Vars0, Must, Subn, Vars).
 
-goal_util__name_apart_2(shorthand(ShorthandGoal0), Must, Subn,
+goal_util__rename_vars_in_goal_expr(shorthand(ShorthandGoal0), Must, Subn,
 		shorthand(ShrothandGoal)) :-
-	goal_util__name_apart_2_shorthand(ShorthandGoal0, Must, Subn,
+	goal_util__rename_vars_in_shorthand(ShorthandGoal0, Must, Subn,
 		ShrothandGoal).
 
-
-:- pred goal_util__name_apart_2_shorthand(shorthand_goal_expr, bool,
+:- pred goal_util__rename_vars_in_shorthand(shorthand_goal_expr, bool,
 		map(prog_var, prog_var), shorthand_goal_expr).
-:- mode goal_util__name_apart_2_shorthand(in, in, in, out) is det.
+:- mode goal_util__rename_vars_in_shorthand(in, in, in, out) is det.
 
-goal_util__name_apart_2_shorthand(bi_implication(LHS0, RHS0), Must, Subn,
+goal_util__rename_vars_in_shorthand(bi_implication(LHS0, RHS0), Must, Subn,
 		bi_implication(LHS, RHS)) :-
 	goal_util__rename_vars_in_goal(LHS0, Must, Subn, LHS),
 	goal_util__rename_vars_in_goal(RHS0, Must, Subn, RHS).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__name_apart_list(list(hlds_goal), bool,
-		map(prog_var, prog_var), list(hlds_goal)).
-:- mode goal_util__name_apart_list(in, in, in, out) is det.
-
-goal_util__name_apart_list([], _Must, _Subn, []).
-goal_util__name_apart_list([G0 | Gs0], Must, Subn, [G | Gs]) :-
-	goal_util__rename_vars_in_goal(G0, Must, Subn, G),
-	goal_util__name_apart_list(Gs0, Must, Subn, Gs).
-
-%-----------------------------------------------------------------------------%
-
-:- pred goal_util__name_apart_cases(list(case), bool, map(prog_var, prog_var),
+:- pred goal_util__rename_vars_in_cases(list(case), bool, map(prog_var, prog_var),
 		list(case)).
-:- mode goal_util__name_apart_cases(in, in, in, out) is det.
+:- mode goal_util__rename_vars_in_cases(in, in, in, out) is det.
 
-goal_util__name_apart_cases([], _Must, _Subn, []).
-goal_util__name_apart_cases([case(Cons, G0) | Gs0], Must, Subn,
+goal_util__rename_vars_in_cases([], _Must, _Subn, []).
+goal_util__rename_vars_in_cases([case(Cons, G0) | Gs0], Must, Subn,
 		[case(Cons, G) | Gs]) :-
 	goal_util__rename_vars_in_goal(G0, Must, Subn, G),
-	goal_util__name_apart_cases(Gs0, Must, Subn, Gs).
+	goal_util__rename_vars_in_cases(Gs0, Must, Subn, Gs).
 
 %-----------------------------------------------------------------------------%
 
@@ -535,60 +533,47 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__name_apart_goalinfo(hlds_goal_info,
+:- pred goal_util__rename_vars_in_goal_info(hlds_goal_info,
 		bool, map(prog_var, prog_var), hlds_goal_info).
-:- mode goal_util__name_apart_goalinfo(in, in, in, out) is det.
+:- mode goal_util__rename_vars_in_goal_info(in, in, in, out) is det.
 
-goal_util__name_apart_goalinfo(GoalInfo0, Must, Subn, GoalInfo) :-
-	goal_info_get_pre_births(GoalInfo0, PreBirths0),
-	goal_util__name_apart_set(PreBirths0, Must, Subn, PreBirths),
-	goal_info_set_pre_births(GoalInfo0, PreBirths, GoalInfo1),
-
-	goal_info_get_pre_deaths(GoalInfo1, PreDeaths0),
-	goal_util__name_apart_set(PreDeaths0, Must, Subn, PreDeaths),
-	goal_info_set_pre_deaths(GoalInfo1, PreDeaths, GoalInfo2),
-
-	goal_info_get_post_births(GoalInfo2, PostBirths0),
-	goal_util__name_apart_set(PostBirths0, Must, Subn, PostBirths),
-	goal_info_set_post_births(GoalInfo2, PostBirths, GoalInfo3),
-
-	goal_info_get_post_deaths(GoalInfo3, PostDeaths0),
-	goal_util__name_apart_set(PostDeaths0, Must, Subn, PostDeaths),
-	goal_info_set_post_deaths(GoalInfo3, PostDeaths, GoalInfo4),
-
-	goal_info_get_nonlocals(GoalInfo4, NonLocals0),
-	goal_util__name_apart_set(NonLocals0, Must, Subn, NonLocals),
-	goal_info_set_nonlocals(GoalInfo4, NonLocals, GoalInfo5),
+goal_util__rename_vars_in_goal_info(GoalInfo0, Must, Subn, GoalInfo) :-
+	goal_info_get_nonlocals(GoalInfo0, NonLocals0),
+	goal_util__rename_vars_in_var_set(NonLocals0, Must, Subn, NonLocals),
+	goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo1),
 
-	goal_info_get_instmap_delta(GoalInfo5, InstMap0),
+	goal_info_get_instmap_delta(GoalInfo1, InstMap0),
 	instmap_delta_apply_sub(InstMap0, Must, Subn, InstMap),
-	goal_info_set_instmap_delta(GoalInfo5, InstMap, GoalInfo6),
+	goal_info_set_instmap_delta(GoalInfo1, InstMap, GoalInfo2),
 
-	goal_info_get_follow_vars(GoalInfo6, MaybeFollowVars0),
-	(
-		MaybeFollowVars0 = no,
-		MaybeFollowVars = no
-	;
-		MaybeFollowVars0 = yes(FollowVars0),
-		FollowVars0 = follow_vars(FollowVarsMap0, NextReserved),
-		goal_util__rename_var_maps(FollowVarsMap0, Must, Subn,
-			FollowVarsMap),
-		FollowVars = follow_vars(FollowVarsMap, NextReserved),
-		MaybeFollowVars = yes(FollowVars)
-	),
-	goal_info_set_follow_vars(GoalInfo6, MaybeFollowVars, GoalInfo).
+	goal_info_get_code_gen_info(GoalInfo2, CodeGenInfo0),
+	goal_util__rename_vars_in_code_gen_info(CodeGenInfo0, Must, Subn,
+		CodeGenInfo),
+	goal_info_set_code_gen_info(GoalInfo2, CodeGenInfo, GoalInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_util__name_apart_set(set(prog_var), bool, map(prog_var, prog_var),
-		set(prog_var)).
-:- mode goal_util__name_apart_set(in, in, in, out) is det.
-
-goal_util__name_apart_set(Vars0, Must, Subn, Vars) :-
+goal_util__rename_vars_in_var_set(Vars0, Must, Subn, Vars) :-
 	set__to_sorted_list(Vars0, VarsList0),
 	goal_util__rename_var_list(VarsList0, Must, Subn, VarsList),
 	set__list_to_set(VarsList, Vars).
 
+:- pred goal_util__rename_vars_in_code_gen_info(hlds_goal_code_gen_info::in,
+	bool::in, map(prog_var, prog_var)::in, hlds_goal_code_gen_info::out)
+	is det.
+
+goal_util__rename_vars_in_code_gen_info(CodeGenInfo0, Must, Subn,
+		CodeGenInfo) :-
+	(
+		CodeGenInfo0 = no_code_gen_info,
+		CodeGenInfo = no_code_gen_info
+	;
+		CodeGenInfo0 = llds_code_gen_info(LldsInfo0),
+		rename_vars_in_llds_code_gen_info(LldsInfo0, Must, Subn,
+			LldsInfo),
+		CodeGenInfo = llds_code_gen_info(LldsInfo)
+	).
+
 %-----------------------------------------------------------------------------%
 
 goal_util__goal_vars(Goal - _GoalInfo, Set) :-
@@ -623,13 +608,13 @@
 goal_util__goal_vars_2(conj(Goals), Set0, Set) :-
 	goal_util__goals_goal_vars(Goals, Set0, Set).
 
-goal_util__goal_vars_2(par_conj(Goals, _SM), Set0, Set) :-
+goal_util__goal_vars_2(par_conj(Goals), Set0, Set) :-
 	goal_util__goals_goal_vars(Goals, Set0, Set).
 
-goal_util__goal_vars_2(disj(Goals, _), Set0, Set) :-
+goal_util__goal_vars_2(disj(Goals), Set0, Set) :-
 	goal_util__goals_goal_vars(Goals, Set0, Set).
 
-goal_util__goal_vars_2(switch(Var, _Det, Cases, _), Set0, Set) :-
+goal_util__goal_vars_2(switch(Var, _Det, Cases), Set0, Set) :-
 	set__insert(Set0, Var, Set1),
 	goal_util__cases_goal_vars(Cases, Set1, Set).
 
@@ -640,7 +625,7 @@
 goal_util__goal_vars_2(not(Goal - _GoalInfo), Set0, Set) :-
 	goal_util__goal_vars_2(Goal, Set0, Set).
 
-goal_util__goal_vars_2(if_then_else(Vars, A - _, B - _, C - _, _), Set0, Set) :-
+goal_util__goal_vars_2(if_then_else(Vars, A - _, B - _, C - _), Set0, Set) :-
 	set__insert_list(Set0, Vars, Set1),
 	goal_util__goal_vars_2(A, Set1, Set2),
 	goal_util__goal_vars_2(B, Set2, Set3),
@@ -734,9 +719,9 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_util__goal_is_branched(if_then_else(_, _, _, _, _)).
-goal_util__goal_is_branched(switch(_, _, _, _)).
-goal_util__goal_is_branched(disj(_, _)).
+goal_util__goal_is_branched(if_then_else(_, _, _, _)).
+goal_util__goal_is_branched(switch(_, _, _)).
+goal_util__goal_is_branched(disj(_)).
 
 %-----------------------------------------------------------------------------%
 
@@ -778,16 +763,16 @@
 
 goal_expr_size(conj(Goals), Size) :-
 	goals_size(Goals, Size).
-goal_expr_size(par_conj(Goals, _SM), Size) :-
+goal_expr_size(par_conj(Goals), Size) :-
 	goals_size(Goals, Size1),
 	Size is Size1 + 1.
-goal_expr_size(disj(Goals, _), Size) :-
+goal_expr_size(disj(Goals), Size) :-
 	goals_size(Goals, Size1),
 	Size is Size1 + 1.
-goal_expr_size(switch(_, _, Goals, _), Size) :-
+goal_expr_size(switch(_, _, Goals), Size) :-
 	cases_size(Goals, Size1),
 	Size is Size1 + 1.
-goal_expr_size(if_then_else(_, Cond, Then, Else, _), Size) :-
+goal_expr_size(if_then_else(_, Cond, Then, Else), Size) :-
 	goal_size(Cond, Size1),
 	goal_size(Then, Size2),
 	goal_size(Else, Size3),
@@ -853,13 +838,13 @@
 
 goal_expr_calls(conj(Goals), PredProcId) :-
 	goals_calls(Goals, PredProcId).
-goal_expr_calls(par_conj(Goals, _), PredProcId) :-
+goal_expr_calls(par_conj(Goals), PredProcId) :-
 	goals_calls(Goals, PredProcId).
-goal_expr_calls(disj(Goals, _), PredProcId) :-
+goal_expr_calls(disj(Goals), PredProcId) :-
 	goals_calls(Goals, PredProcId).
-goal_expr_calls(switch(_, _, Goals, _), PredProcId) :-
+goal_expr_calls(switch(_, _, Goals), PredProcId) :-
 	cases_calls(Goals, PredProcId).
-goal_expr_calls(if_then_else(_, Cond, Then, Else, _), PredProcId) :-
+goal_expr_calls(if_then_else(_, Cond, Then, Else), PredProcId) :-
 	(
 		goal_calls(Cond, PredProcId)
 	;
@@ -913,13 +898,13 @@
 
 goal_expr_calls_pred_id(conj(Goals), PredId) :-
 	goals_calls_pred_id(Goals, PredId).
-goal_expr_calls_pred_id(par_conj(Goals, _), PredId) :-
+goal_expr_calls_pred_id(par_conj(Goals), PredId) :-
 	goals_calls_pred_id(Goals, PredId).
-goal_expr_calls_pred_id(disj(Goals, _), PredId) :-
+goal_expr_calls_pred_id(disj(Goals), PredId) :-
 	goals_calls_pred_id(Goals, PredId).
-goal_expr_calls_pred_id(switch(_, _, Goals, _), PredId) :-
+goal_expr_calls_pred_id(switch(_, _, Goals), PredId) :-
 	cases_calls_pred_id(Goals, PredId).
-goal_expr_calls_pred_id(if_then_else(_, Cond, Then, Else, _), PredId) :-
+goal_expr_calls_pred_id(if_then_else(_, Cond, Then, Else), PredId) :-
 	(
 		goal_calls_pred_id(Cond, PredId)
 	;
@@ -945,15 +930,15 @@
 
 goal_expr_contains_reconstruction(conj(Goals)) :-
 	goals_contain_reconstruction(Goals).
-goal_expr_contains_reconstruction(disj(Goals, _)) :-
+goal_expr_contains_reconstruction(disj(Goals)) :-
 	goals_contain_reconstruction(Goals).
-goal_expr_contains_reconstruction(par_conj(Goals, _)) :-
+goal_expr_contains_reconstruction(par_conj(Goals)) :-
 	goals_contain_reconstruction(Goals).
-goal_expr_contains_reconstruction(switch(_, _, Cases, _)) :-
+goal_expr_contains_reconstruction(switch(_, _, Cases)) :-
 	list__member(Case, Cases),
 	Case = case(_, Goal),
  	goal_contains_reconstruction(Goal).
-goal_expr_contains_reconstruction(if_then_else(_, Cond, Then, Else, _)) :-
+goal_expr_contains_reconstruction(if_then_else(_, Cond, Then, Else)) :-
  	goals_contain_reconstruction([Cond, Then, Else]).
 goal_expr_contains_reconstruction(not(Goal)) :-
 	goal_contains_reconstruction(Goal).
@@ -986,18 +971,18 @@
 	%
 direct_subgoal(some(_, _, Goal), Goal).
 direct_subgoal(not(Goal), Goal).
-direct_subgoal(if_then_else(_, If, Then, Else, _), Goal) :-
+direct_subgoal(if_then_else(_, If, Then, Else), Goal) :-
 	( Goal = If
 	; Goal = Then
 	; Goal = Else
 	).
 direct_subgoal(conj(ConjList), Goal) :-
 	list__member(Goal, ConjList).
-direct_subgoal(par_conj(ConjList, _), Goal) :-
+direct_subgoal(par_conj(ConjList), Goal) :-
 	list__member(Goal, ConjList).
-direct_subgoal(disj(DisjList, _), Goal) :-
+direct_subgoal(disj(DisjList), Goal) :-
 	list__member(Goal, DisjList).
-direct_subgoal(switch(_, _, CaseList, _), Goal) :-
+direct_subgoal(switch(_, _, CaseList), Goal) :-
 	list__member(Case, CaseList),
 	Case = case(_, Goal).
 
@@ -1110,10 +1095,7 @@
 		GoalInfo, NegCondElseInfo),
 	conj_list_to_goal([not(Cond) - NegCondInfo, Else], 
 		NegCondElseInfo, NegCondElse),
-
-	map__init(SM),
-	Goal = disj([CondThen, NegCondElse], SM).
-
+	Goal = disj([CondThen, NegCondElse]).
 
 	% Compute a hlds_goal_info for a pair of conjoined goals.
 :- pred goal_util__compute_disjunct_goal_info(hlds_goal::in, hlds_goal::in, 
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.134
diff -u -b -r1.134 handle_options.m
--- compiler/handle_options.m	23 Feb 2002 07:30:45 -0000	1.134
+++ compiler/handle_options.m	8 Mar 2002 04:05:36 -0000
@@ -578,6 +578,8 @@
 			globals__io_set_option(optimize_duplicate_calls,
 				bool(no)),
 			globals__io_set_option(optimize_constructor_last_call,
+				bool(no)),
+			globals__io_set_option(optimize_saved_vars_cell,
 				bool(no))
 		;
 			[]
@@ -622,7 +624,11 @@
 			% The following options cause the info required
 			% by tracing to be generated.
 		globals__io_set_option(trace_stack_layout, bool(yes)),
-		globals__io_set_option(body_typeinfo_liveness, bool(yes))
+		globals__io_set_option(body_typeinfo_liveness, bool(yes)),
+			% To support up-level printing, we need to save
+			% variables across a call even if the call cannot
+			% succeed.
+		globals__io_set_option(opt_no_return_calls, bool(no))
 	;
 		[]
 	),
@@ -1422,6 +1428,7 @@
 :- pred convert_dump_alias(string, string).
 :- mode convert_dump_alias(in, out) is semidet.
 
+convert_dump_alias("osv", "bcdglmnpruvP").
 convert_dump_alias("ALL", "abcdfgilmnprstuvCIMPTU").
 convert_dump_alias("all", "abcdfgilmnprstuvCMPT").
 convert_dump_alias("codegen", "dfnprsu").
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.94
diff -u -b -r1.94 higher_order.m
--- compiler/higher_order.m	7 Mar 2002 08:29:48 -0000	1.94
+++ compiler/higher_order.m	8 Mar 2002 04:04:21 -0000
@@ -422,18 +422,18 @@
 traverse_goal_2(conj(Goals0) - Info, conj(Goals) - Info) -->
 	list__map_foldl(traverse_goal_2, Goals0, Goals).
 
-traverse_goal_2(par_conj(Goals0, SM) - Info, par_conj(Goals, SM) - Info) -->
+traverse_goal_2(par_conj(Goals0) - Info, par_conj(Goals) - Info) -->
 		% traverse_disj treats its list of goals as independent
 		% rather than specifically disjoint, so we can use it
 		% to process a list of independent parallel conjuncts.
 	traverse_disj(Goals0, Goals).
 
-traverse_goal_2(disj(Goals0, SM) - Info, disj(Goals, SM) - Info) -->
+traverse_goal_2(disj(Goals0) - Info, disj(Goals) - Info) -->
 	traverse_disj(Goals0, Goals).
 
 		% a switch is treated as a disjunction
-traverse_goal_2(switch(Var, CanFail, Cases0, SM) - Info,
-		switch(Var, CanFail, Cases, SM) - Info) -->
+traverse_goal_2(switch(Var, CanFail, Cases0) - Info,
+		switch(Var, CanFail, Cases) - Info) -->
 	traverse_cases(Cases0, Cases).
 
 		% check whether this call could be specialized
@@ -462,7 +462,7 @@
 
 		% if-then-elses are handled as disjunctions
 traverse_goal_2(Goal0, Goal) -->
-	{ Goal0 = if_then_else(Vars, Cond0, Then0, Else0, SM) - GoalInfo },
+	{ Goal0 = if_then_else(Vars, Cond0, Then0, Else0) - GoalInfo },
 	get_pre_branch_info(PreInfo),
 	traverse_goal_2(Cond0, Cond),
 	traverse_goal_2(Then0, Then),
@@ -470,7 +470,7 @@
 	set_pre_branch_info(PreInfo),
 	traverse_goal_2(Else0, Else),
 	get_post_branch_info(PostElseInfo),
-	{ Goal = if_then_else(Vars, Cond, Then, Else, SM) - GoalInfo },
+	{ Goal = if_then_else(Vars, Cond, Then, Else) - GoalInfo },
 	{ merge_post_branch_infos(PostThenInfo, PostElseInfo, PostInfo) },
 	set_post_branch_info(PostInfo).
 
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.93
diff -u -b -r1.93 hlds_goal.m
--- compiler/hlds_goal.m	26 Feb 2002 02:52:26 -0000	1.93
+++ compiler/hlds_goal.m	1 Mar 2002 17:11:45 -0000
@@ -13,7 +13,7 @@
 :- interface.
 
 :- import_module hlds_data, hlds_pred, prog_data, (inst), instmap.
-:- import_module llds.	% XXX needed for `lval'
+:- import_module hlds_llds.
 :- import_module bool, char, list, set, map, std_util.
 
 %-----------------------------------------------------------------------------%
@@ -89,15 +89,7 @@
 					% whether or not the switch test itself
 					% can fail (i.e. whether or not it
 					% covers all the possible cases)
-			switch_cases	:: list(case),
-			switch_store_map :: store_map
-					% a map saying where each live variable
-					% should be at the end of each arm of
-					% the switch. This field is filled in
-					% with advisory information by the
-					% follow_vars pass, while store_alloc
-					% fills it with authoritative
-					% information.
+			switch_cases	:: list(case)
 		)
 
 		% A unification.
@@ -126,16 +118,7 @@
 		% A disjunction.
 		% Note: disjunctions should be fully flattened.
 
-	;	disj(
-			hlds_goals,
-			store_map	% a map saying where each live variable
-					% should be at the end of each arm of
-					% the disj. This field is filled in
-					% with advisory information by the
-					% follow_vars pass, while store_alloc
-					% fills it with authoritative
-					% information.
-		)
+	;	disj(hlds_goals)
 
 		% A negation
 	;	not(hlds_goal)
@@ -171,15 +154,7 @@
 					% variables <Vars>.
 			ite_cond	:: hlds_goal,	% The <Condition>
 			ite_then	:: hlds_goal,	% The <Then> part
-			ite_else	:: hlds_goal,	% The <Else> part
-			ite_store_map	:: store_map
-					% a map saying where each live variable
-					% should be at the end of each arm of
-					% the disj. This field is filled in
-					% with advisory information by the
-					% follow_vars pass, while store_alloc
-					% fills it with authoritative
-					% information.
+			ite_else	:: hlds_goal	% The <Else> part
 		)
 
 		% Foreign code from a pragma foreign_proc(...) decl.
@@ -211,11 +186,7 @@
 		)
 
 		% parallel conjunction
-	;	par_conj(hlds_goals, store_map)
-					% The store_map specifies the locations
-					% in which live variables should be
-					% stored at the start of the parallel
-					% conjunction.
+	;	par_conj(hlds_goals)
 
 		% shorthand goals
 		%
@@ -604,6 +575,7 @@
 %
 
 :- type hlds_goal_info.
+:- type hlds_goal_code_gen_info.
 
 :- pred goal_info_init(hlds_goal_info).
 :- mode goal_info_init(out) is det.
@@ -626,30 +598,6 @@
 % variable can occur in both the post-death and post-birth sets,
 % or in both the pre-death and pre-birth sets.
 
-:- pred goal_info_get_pre_births(hlds_goal_info, set(prog_var)).
-:- mode goal_info_get_pre_births(in, out) is det.
-
-:- pred goal_info_set_pre_births(hlds_goal_info, set(prog_var), hlds_goal_info).
-:- mode goal_info_set_pre_births(in, in, out) is det.
-
-:- pred goal_info_get_post_births(hlds_goal_info, set(prog_var)).
-:- mode goal_info_get_post_births(in, out) is det.
-
-:- pred goal_info_set_post_births(hlds_goal_info, set(prog_var), hlds_goal_info).
-:- mode goal_info_set_post_births(in, in, out) is det.
-
-:- pred goal_info_get_pre_deaths(hlds_goal_info, set(prog_var)).
-:- mode goal_info_get_pre_deaths(in, out) is det.
-
-:- pred goal_info_set_pre_deaths(hlds_goal_info, set(prog_var), hlds_goal_info).
-:- mode goal_info_set_pre_deaths(in, in, out) is det.
-
-:- pred goal_info_get_post_deaths(hlds_goal_info, set(prog_var)).
-:- mode goal_info_get_post_deaths(in, out) is det.
-
-:- pred goal_info_set_post_deaths(hlds_goal_info, set(prog_var), hlds_goal_info).
-:- mode goal_info_set_post_deaths(in, in, out) is det.
-
 	% see also goal_info_get_code_model in code_model.m
 :- pred goal_info_get_determinism(hlds_goal_info, determinism).
 :- mode goal_info_get_determinism(in, out) is det.
@@ -701,37 +649,21 @@
 :- pred goal_info_set_context(hlds_goal_info, prog_context, hlds_goal_info).
 :- mode goal_info_set_context(in, in, out) is det.
 
-:- pred goal_info_get_follow_vars(hlds_goal_info, maybe(follow_vars)).
-:- mode goal_info_get_follow_vars(in, out) is det.
-
-:- pred goal_info_set_follow_vars(hlds_goal_info, maybe(follow_vars),
-	hlds_goal_info).
-:- mode goal_info_set_follow_vars(in, in, out) is det.
-
-:- pred goal_info_get_resume_point(hlds_goal_info, resume_point).
-:- mode goal_info_get_resume_point(in, out) is det.
-
-:- pred goal_info_set_resume_point(hlds_goal_info, resume_point,
-	hlds_goal_info).
-:- mode goal_info_set_resume_point(in, in, out) is det.
-
 :- pred goal_info_get_goal_path(hlds_goal_info, goal_path).
 :- mode goal_info_get_goal_path(in, out) is det.
 
 :- pred goal_info_set_goal_path(hlds_goal_info, goal_path, hlds_goal_info).
 :- mode goal_info_set_goal_path(in, in, out) is det.
 
-:- pred goal_get_nonlocals(hlds_goal, set(prog_var)).
-:- mode goal_get_nonlocals(in, out) is det.
+:- pred goal_info_get_code_gen_info(hlds_goal_info, hlds_goal_code_gen_info).
+:- mode goal_info_get_code_gen_info(in, out) is det.
 
-:- pred goal_set_follow_vars(hlds_goal, maybe(follow_vars), hlds_goal).
-:- mode goal_set_follow_vars(in, in, out) is det.
-
-:- pred goal_set_resume_point(hlds_goal, resume_point, hlds_goal).
-:- mode goal_set_resume_point(in, in, out) is det.
+:- pred goal_info_set_code_gen_info(hlds_goal_info, hlds_goal_code_gen_info,
+	hlds_goal_info).
+:- mode goal_info_set_code_gen_info(in, in, out) is det.
 
-:- pred goal_info_resume_vars_and_loc(resume_point, set(prog_var), resume_locs).
-:- mode goal_info_resume_vars_and_loc(in, out, out) is det.
+:- pred goal_get_nonlocals(hlds_goal, set(prog_var)).
+:- mode goal_get_nonlocals(in, out) is det.
 
 :- type goal_feature
 	--->	constraint	% This is included if the goal is
@@ -739,6 +671,12 @@
 				% for the definition of this.
 	;	(impure)	% This goal is impure.  See hlds_pred.m.
 	;	(semipure)	% This goal is semipure.  See hlds_pred.m.
+	;	stack_opt	% This goal was created by stack slot
+				% optimization. Other optimizations should
+				% assume that it is there for a reason, and
+				% therefore should refrain from "optimizing"
+				% it away, even though it is a copy of another,
+				% previous goal.
 	;	call_table_gen	% This goal generates the variable that
 				% represents the call table tip. If debugging
 				% is enabled, the code generator needs to save
@@ -1105,56 +1043,15 @@
 
 %-----------------------------------------------------------------------------%
 %
-% Stuff specific to the LLDS back-end.
-%
-
-%
-% The following types are annotations on the HLDS
-% that are used only by the LLDS back-end.
+% Stuff specific to a back-end. At the moment, only the LLDS back-end
+% annotates the HLDS.
 %
 
-:- type stack_slots	==	map(prog_var, lval).
-				% Maps variables to their stack slots.
-				% The only legal lvals in the range are
-				% stackvars and framevars.
-
-:- type follow_vars_map	==	map(prog_var, lval).
-
-:- type follow_vars	--->	follow_vars(follow_vars_map, int).
-				% Advisory information about where variables
-				% ought to be put next. Variables may or may
-				% not appear in the map. If they do, then the
-				% associated lval says where the value of that
-				% variable ought to be put when it is computed,
-				% or, if the lval refers to the nonexistent
-				% register r(-1), it says that it should be
-				% put into an available register. The integer
-				% in the second half of the pair gives the
-				% number of the first register that is
-				% not reserved for other purposes, and is
-				% free to hold such variables.
-
-:- type store_map	==	map(prog_var, lval).
-				% Authoritative information about where
-				% variables must be put at the ends of
-				% branches of branched control structures.
-				% However, between the follow_vars and
-				% and store_alloc passes, these fields
-				% temporarily hold follow_vars information.
-				% Apart from this, the legal range is
-				% the set of legal lvals.
-
-	% see compiler/notes/allocation.html for what these alternatives mean
-:- type resume_point	--->	resume_point(set(prog_var), resume_locs)
-			;	no_resume_point.
-
-:- type resume_locs	--->	orig_only
-			;	stack_only
-			;	orig_and_stack
-			;	stack_and_orig.
+:- type hlds_goal_code_gen_info
+	--->	no_code_gen_info
+	;	llds_code_gen_info(llds_code_gen :: llds_code_gen_details).
 
 %-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
 
 :- implementation.
 
@@ -1192,14 +1089,6 @@
 	% if this structure is modified.
 :- type hlds_goal_info
 	---> goal_info(
-		pre_births :: set(prog_var),	% the pre-birth set
-		post_births :: set(prog_var),	% the post-birth set
-		pre_deaths :: set(prog_var),	% the pre-death set
-		post_deaths :: set(prog_var),	% the post-death set
-				% (all four are computed by liveness.m)
-				% NB for atomic goals, the post-deadness
-				% should be applied _before_ the goal
-
 		determinism :: determinism, 
 				% the overall determinism of the goal
 				% (computed during determinism analysis)
@@ -1261,42 +1150,26 @@
 				% contain any reconstructions.
 		*/
 
-		follow_vars :: maybe(follow_vars),
-				% advisory information about where variables
-				% ought to be put next. The legal range
-				% includes the nonexistent register r(-1),
-				% which indicates any available register.
-
 		features :: set(goal_feature),
 				% The set of used-defined "features" of
 				% this goal, which optimisers may wish
 				% to know about.
 
-		resume_point :: resume_point,
-				% If this goal establishes a resumption point,
-				% state what variables need to be saved for
-				% that resumption point, and which entry
-				% labels of the resumption point will be
-				% needed. (See compiler/notes/allocation.html)
-
-		goal_path :: goal_path
+		goal_path :: goal_path,
 				% The path to this goal from the root in
 				% reverse order.
+
+		code_gen_info :: hlds_goal_code_gen_info
 	).
 
 goal_info_init(GoalInfo) :-
 	Detism = erroneous,
-	set__init(PreBirths),
-	set__init(PostBirths),
-	set__init(PreDeaths),
-	set__init(PostDeaths),
 	instmap_delta_init_unreachable(InstMapDelta),
 	set__init(NonLocals),
 	term__context_init(Context),
 	set__init(Features),
-	GoalInfo = goal_info(PreBirths, PostBirths, PreDeaths, PostDeaths,
-		Detism, InstMapDelta, Context, NonLocals, no, Features,
-		no_resume_point, []).
+	GoalInfo = goal_info(Detism, InstMapDelta, Context, NonLocals,
+		Features, [], no_code_gen_info).
 
 goal_info_init(Context, GoalInfo) :-
 	goal_info_init(GoalInfo0),
@@ -1315,14 +1188,6 @@
 	goal_info_set_determinism(GoalInfo2, Detism, GoalInfo3),
 	goal_info_set_context(GoalInfo3, Context, GoalInfo).
 
-goal_info_get_pre_births(GoalInfo, GoalInfo ^ pre_births).
-
-goal_info_get_post_births(GoalInfo, GoalInfo ^ post_births).
-
-goal_info_get_pre_deaths(GoalInfo, GoalInfo ^ pre_deaths).
-
-goal_info_get_post_deaths(GoalInfo, GoalInfo ^ post_deaths).
-
 goal_info_get_determinism(GoalInfo, GoalInfo ^ determinism).
 
 goal_info_get_instmap_delta(GoalInfo, GoalInfo ^ instmap_delta).
@@ -1336,25 +1201,11 @@
 goal_info_get_code_gen_nonlocals(GoalInfo, NonLocals) :-
 	goal_info_get_nonlocals(GoalInfo, NonLocals).
 
-goal_info_get_follow_vars(GoalInfo, GoalInfo ^ follow_vars).
-
 goal_info_get_features(GoalInfo, GoalInfo ^ features).
 
-goal_info_get_resume_point(GoalInfo, GoalInfo ^ resume_point).
-
 goal_info_get_goal_path(GoalInfo, GoalInfo ^ goal_path).
 
-goal_info_set_pre_births(GoalInfo0, PreBirths,
-		GoalInfo0 ^ pre_births := PreBirths).
-
-goal_info_set_post_births(GoalInfo0, PostBirths,
-		GoalInfo0 ^ post_births := PostBirths).
-
-goal_info_set_pre_deaths(GoalInfo0, PreDeaths,
-		GoalInfo0 ^ pre_deaths := PreDeaths).
-
-goal_info_set_post_deaths(GoalInfo0, PostDeaths,
-		GoalInfo0 ^ post_deaths := PostDeaths).
+goal_info_get_code_gen_info(GoalInfo, GoalInfo ^ code_gen_info).
 
 goal_info_set_determinism(GoalInfo0, Determinism,
 		GoalInfo0 ^ determinism := Determinism).
@@ -1372,17 +1223,16 @@
 goal_info_set_code_gen_nonlocals(GoalInfo0, NonLocals, GoalInfo) :-
 	goal_info_set_nonlocals(GoalInfo0, NonLocals, GoalInfo).
 
-goal_info_set_follow_vars(GoalInfo0, FollowVars,
-		GoalInfo0 ^ follow_vars := FollowVars).
-
 goal_info_set_features(GoalInfo0, Features, GoalInfo0 ^ features := Features).
 
-goal_info_set_resume_point(GoalInfo0, ResumePoint,
-		GoalInfo0 ^ resume_point := ResumePoint).
-
 goal_info_set_goal_path(GoalInfo0, GoalPath,
 		GoalInfo0 ^ goal_path := GoalPath).
 
+goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo,
+		GoalInfo0 ^ code_gen_info := CodeGenInfo).
+
+%-----------------------------------------------------------------------------%
+
 goal_info_add_feature(GoalInfo0, Feature, GoalInfo) :-
 	goal_info_get_features(GoalInfo0, Features0),
 	set__insert(Features0, Feature, Features),
@@ -1397,23 +1247,11 @@
 	goal_info_get_features(GoalInfo, Features),
 	set__member(Feature, Features).
 
+%-----------------------------------------------------------------------------%
+
 goal_get_nonlocals(_Goal - GoalInfo, NonLocals) :-
 	goal_info_get_nonlocals(GoalInfo, NonLocals).
 
-goal_set_follow_vars(Goal - GoalInfo0, FollowVars, Goal - GoalInfo) :-
-	goal_info_set_follow_vars(GoalInfo0, FollowVars, GoalInfo).
-
-goal_set_resume_point(Goal - GoalInfo0, ResumePoint, Goal - GoalInfo) :-
-	goal_info_set_resume_point(GoalInfo0, ResumePoint, GoalInfo).
-
-goal_info_resume_vars_and_loc(Resume, Vars, Locs) :-
-	(
-		Resume = resume_point(Vars, Locs)
-	;
-		Resume = no_resume_point,
-		error("goal_info__get_resume_vars_and_loc: no resume point")
-	).
-
 %-----------------------------------------------------------------------------%
 %
 % Miscellaneous utility procedures for dealing with HLDS goals
@@ -1435,7 +1273,7 @@
 	% otherwise return the goal as a singleton list.
 
 goal_to_par_conj_list(Goal, ConjList) :-
-	( Goal = (par_conj(List, _) - _) ->
+	( Goal = par_conj(List) - _ ->
 		ConjList = List
 	;
 		ConjList = [Goal]
@@ -1446,7 +1284,7 @@
 	% otherwise return the goal as a singleton list.
 
 goal_to_disj_list(Goal, DisjList) :-
-	( Goal = (disj(List, _) - _) ->
+	( Goal = disj(List) - _ ->
 		DisjList = List
 	;
 		DisjList = [Goal]
@@ -1473,8 +1311,7 @@
 	( ConjList = [Goal0] ->
 		Goal = Goal0
 	;
-		map__init(StoreMap),
-		Goal = par_conj(ConjList, StoreMap) - GoalInfo
+		Goal = par_conj(ConjList) - GoalInfo
 	).
 
 	% Convert a list of disjuncts to a goal.
@@ -1486,8 +1323,7 @@
 	( DisjList = [Goal0] ->
 		Goal = Goal0
 	;
-		map__init(Empty),
-		Goal = disj(DisjList, Empty) - GoalInfo
+		Goal = disj(DisjList) - GoalInfo
 	).
 
 conjoin_goal_and_goal_list(Goal0, Goals, Goal) :-
@@ -1522,8 +1358,7 @@
 		Goal = conj(NegatedGoals) - _,
 		all_negated(NegatedGoals, UnnegatedGoals)
 	->
-		map__init(StoreMap),
-		NegatedGoal = disj(UnnegatedGoals, StoreMap) - GoalInfo
+		NegatedGoal = disj(UnnegatedGoals) - GoalInfo
 	;
 		NegatedGoal = not(Goal) - GoalInfo
 	).
@@ -1554,13 +1389,13 @@
 		GoalExpr = generic_call(_, _, _, _),
 		HasForeign = no
 	;
-		GoalExpr = switch(_, _, _, _),
+		GoalExpr = switch(_, _, _),
 		HasForeign = no
 	;
 		GoalExpr = unify(_, _, _, _, _),
 		HasForeign = no
 	;
-		GoalExpr = disj(Goals, _),
+		GoalExpr = disj(Goals),
 		HasForeign = goal_list_has_foreign(Goals)
 	;
 		GoalExpr = not(Goal2),
@@ -1569,7 +1404,7 @@
 		GoalExpr = some(_, _, Goal2),
 		HasForeign = goal_has_foreign(Goal2)
 	;
-		GoalExpr = if_then_else(_, Goal2, Goal3, Goal4, _),
+		GoalExpr = if_then_else(_, Goal2, Goal3, Goal4),
 		HasForeign =
 		(	goal_has_foreign(Goal2) = yes 
 		->	yes
@@ -1583,7 +1418,7 @@
 		GoalExpr = foreign_proc(_, _, _, _, _, _, _),
 		HasForeign = yes
 	;
-		GoalExpr = par_conj(Goals, _),
+		GoalExpr = par_conj(Goals),
 		HasForeign = goal_list_has_foreign(Goals)
 	;
 		GoalExpr = shorthand(ShorthandGoal),
@@ -1613,7 +1448,7 @@
 %-----------------------------------------------------------------------------%
 
 goal_is_atomic(conj([])).
-goal_is_atomic(disj([], _)).
+goal_is_atomic(disj([])).
 goal_is_atomic(generic_call(_,_,_,_)).
 goal_is_atomic(call(_,_,_,_,_,_)).
 goal_is_atomic(unify(_,_,_,_,_)).
@@ -1631,8 +1466,7 @@
 	true_goal(Goal - GoalInfo0),
 	goal_info_set_context(GoalInfo0, Context, GoalInfo).
 
-fail_goal(disj([], SM) - GoalInfo) :-
-	map__init(SM),
+fail_goal(disj([]) - GoalInfo) :-
 	goal_info_init(GoalInfo0),
 	goal_info_set_determinism(GoalInfo0, failure, GoalInfo1), 
 	instmap_delta_init_unreachable(InstMapDelta),
@@ -1685,17 +1519,17 @@
 
 set_goal_contexts_2(Context, conj(Goals0), conj(Goals)) :-
 	list__map(set_goal_contexts(Context), Goals0, Goals).
-set_goal_contexts_2(Context, disj(Goals0, SM), disj(Goals, SM)) :-
+set_goal_contexts_2(Context, disj(Goals0), disj(Goals)) :-
 	list__map(set_goal_contexts(Context), Goals0, Goals).
-set_goal_contexts_2(Context, par_conj(Goals0, SM), par_conj(Goals, SM)) :-
+set_goal_contexts_2(Context, par_conj(Goals0), par_conj(Goals)) :-
 	list__map(set_goal_contexts(Context), Goals0, Goals).
-set_goal_contexts_2(Context, if_then_else(Vars, Cond0, Then0, Else0, SM),
-		if_then_else(Vars, Cond, Then, Else, SM)) :-
+set_goal_contexts_2(Context, if_then_else(Vars, Cond0, Then0, Else0),
+		if_then_else(Vars, Cond, Then, Else)) :-
 	set_goal_contexts(Context, Cond0, Cond),
 	set_goal_contexts(Context, Then0, Then),
 	set_goal_contexts(Context, Else0, Else).
-set_goal_contexts_2(Context, switch(Var, CanFail, Cases0, SM),
-		switch(Var, CanFail, Cases, SM)) :-
+set_goal_contexts_2(Context, switch(Var, CanFail, Cases0),
+		switch(Var, CanFail, Cases)) :-
 	list__map(
 	    (pred(case(ConsId, Goal0)::in, case(ConsId, Goal)::out) is det :-
 		set_goal_contexts(Context, Goal0, Goal)
Index: compiler/hlds_llds.m
===================================================================
RCS file: compiler/hlds_llds.m
diff -N compiler/hlds_llds.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/hlds_llds.m	9 Jan 2002 07:52:34 -0000
@@ -0,0 +1,660 @@
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2002 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.
+%-----------------------------------------------------------------------------%
+
+% This module defines annotations on HLDS goals that are used by the LLDS
+% back end.
+
+% Author: zs.
+
+:- module hlds_llds.
+
+:- interface.
+
+:- import_module hlds_goal, prog_data, llds.
+:- import_module bool, map, set, std_util.
+
+%
+% The following types are annotations on the HLDS
+% that are used only by the LLDS back-end.
+%
+
+:- type stack_slots	==	map(prog_var, lval).
+				% Maps variables to their stack slots.
+				% The only legal lvals in the range are
+				% stackvars and framevars.
+
+:- type follow_vars_map	==	map(prog_var, lval).
+
+:- type follow_vars	--->	follow_vars(follow_vars_map, int).
+				% Advisory information about where variables
+				% ought to be put next. Variables may or may
+				% not appear in the map. If they do, then the
+				% associated lval says where the value of that
+				% variable ought to be put when it is computed,
+				% or, if the lval refers to the nonexistent
+				% register r(-1), it says that it should be
+				% put into an available register. The integer
+				% in the second half of the pair gives the
+				% number of the first register that is
+				% not reserved for other purposes, and is
+				% free to hold such variables.
+
+:- type store_map	==	map(prog_var, lval).
+				% Authoritative information about where
+				% variables must be put at the ends of
+				% branches of branched control structures.
+				% However, between the follow_vars and
+				% and store_alloc passes, these fields
+				% temporarily hold follow_vars information.
+				% Apart from this, the legal range is
+				% the set of legal lvals.
+
+	% see compiler/notes/allocation.html for what these alternatives mean
+:- type resume_point	--->	resume_point(set(prog_var), resume_locs)
+			;	no_resume_point.
+
+:- type resume_locs	--->	orig_only
+			;	stack_only
+			;	orig_and_stack
+			;	stack_and_orig.
+
+:- type need_across_call
+	--->	need_across_call(
+	 		call_forward_vars	:: set(prog_var),
+	 		call_resume_vars	:: set(prog_var),
+	 		call_nondet_vars	:: set(prog_var)
+		).
+
+:- type need_in_resume
+	--->	need_in_resume(
+			resume_vars_on_stack	:: bool,
+	 		resume_resume_vars	:: set(prog_var),
+	 		resume_nondet_vars	:: set(prog_var)
+		).
+
+:- type need_in_par_conj
+	--->	need_in_par_conj(
+	 		par_conj_engine_vars	:: set(prog_var)
+		).
+
+:- type llds_code_gen_details.
+
+%-----------------------------------------------------------------------------%
+
+% Instead of recording the liveness of every variable at every
+% part of the goal, we just keep track of the initial liveness
+% and the changes in liveness.  Note that when traversing forwards
+% through a goal, deaths must be applied before births;
+% this is necessary to handle certain circumstances where a
+% variable can occur in both the post-death and post-birth sets,
+% or in both the pre-death and pre-birth sets.
+
+:- pred goal_info_get_pre_births(hlds_goal_info::in,
+	set(prog_var)::out) is det.
+
+:- pred goal_info_get_post_births(hlds_goal_info::in,
+	set(prog_var)::out) is det.
+
+:- pred goal_info_get_pre_deaths(hlds_goal_info::in,
+	set(prog_var)::out) is det.
+
+:- pred goal_info_get_post_deaths(hlds_goal_info::in,
+	set(prog_var)::out) is det.
+
+:- pred goal_info_get_follow_vars(hlds_goal_info::in,
+	maybe(follow_vars)::out) is det.
+
+:- pred goal_info_get_store_map(hlds_goal_info::in,
+	store_map::out) is det.
+
+:- pred goal_info_get_resume_point(hlds_goal_info::in,
+	resume_point::out) is det.
+
+:- pred goal_info_get_maybe_need_across_call(hlds_goal_info::in,
+	maybe(need_across_call)::out) is det.
+
+:- pred goal_info_get_maybe_need_in_resume(hlds_goal_info::in,
+	maybe(need_in_resume)::out) is det.
+
+:- pred goal_info_get_maybe_need_in_par_conj(hlds_goal_info::in,
+	maybe(need_in_par_conj)::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- pred goal_info_maybe_get_pre_births(hlds_goal_info::in,
+	set(prog_var)::out) is semidet.
+
+:- pred goal_info_maybe_get_post_births(hlds_goal_info::in,
+	set(prog_var)::out) is semidet.
+
+:- pred goal_info_maybe_get_pre_deaths(hlds_goal_info::in,
+	set(prog_var)::out) is semidet.
+
+:- pred goal_info_maybe_get_post_deaths(hlds_goal_info::in,
+	set(prog_var)::out) is semidet.
+
+:- pred goal_info_maybe_get_follow_vars(hlds_goal_info::in,
+	maybe(follow_vars)::out) is semidet.
+
+:- pred goal_info_maybe_get_store_map(hlds_goal_info::in,
+	store_map::out) is semidet.
+
+:- pred goal_info_maybe_get_resume_point(hlds_goal_info::in,
+	resume_point::out) is semidet.
+
+:- pred goal_info_maybe_get_maybe_need_across_call(hlds_goal_info::in,
+	maybe(need_across_call)::out) is semidet.
+
+:- pred goal_info_maybe_get_maybe_need_in_resume(hlds_goal_info::in,
+	maybe(need_in_resume)::out) is semidet.
+
+:- pred goal_info_maybe_get_maybe_need_in_par_conj(hlds_goal_info::in,
+	maybe(need_in_par_conj)::out) is semidet.
+
+%-----------------------------------------------------------------------------%
+
+:- pred goal_info_initialize_liveness_info(hlds_goal_info::in,
+	set(prog_var)::in, set(prog_var)::in, set(prog_var)::in,
+	set(prog_var)::in, resume_point::in, hlds_goal_info::out) is det.
+
+:- pred goal_info_set_pre_births(hlds_goal_info::in, set(prog_var)::in,
+	hlds_goal_info::out) is det.
+
+:- pred goal_info_set_post_births(hlds_goal_info::in, set(prog_var)::in,
+	hlds_goal_info::out) is det.
+
+:- pred goal_info_set_pre_deaths(hlds_goal_info::in, set(prog_var)::in,
+	hlds_goal_info::out) is det.
+
+:- pred goal_info_set_post_deaths(hlds_goal_info::in, set(prog_var)::in,
+	hlds_goal_info::out) is det.
+
+:- pred goal_info_set_follow_vars(hlds_goal_info::in, maybe(follow_vars)::in,
+	hlds_goal_info::out) is det.
+
+:- pred goal_info_set_store_map(hlds_goal_info::in, store_map::in,
+	hlds_goal_info::out) is det.
+
+:- pred goal_info_set_resume_point(hlds_goal_info::in, resume_point::in,
+	hlds_goal_info::out) is det.
+
+:- pred goal_info_set_need_across_call(hlds_goal_info::in,
+	need_across_call::in, hlds_goal_info::out) is det.
+
+:- pred goal_info_set_need_in_resume(hlds_goal_info::in,
+	need_in_resume::in, hlds_goal_info::out) is det.
+
+:- pred goal_info_set_need_in_par_conj(hlds_goal_info::in,
+	need_in_par_conj::in, hlds_goal_info::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- pred goal_set_follow_vars(hlds_goal::in, maybe(follow_vars)::in,
+	hlds_goal::out) is det.
+
+:- pred goal_set_resume_point(hlds_goal::in, resume_point::in,
+	hlds_goal::out) is det.
+
+:- pred goal_info_resume_vars_and_loc(resume_point::in,
+	set(prog_var)::out, resume_locs::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- pred rename_vars_in_llds_code_gen_info(llds_code_gen_details::in,
+	bool::in, map(prog_var, prog_var)::in, llds_code_gen_details::out)
+	is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module goal_util.
+:- import_module list, assoc_list, require.
+
+:- type maybe_need
+	--->	no_need
+	;	need_call(need_across_call)
+	;	need_resume(need_in_resume)
+	;	need_par_conj(need_in_par_conj).
+
+:- type llds_code_gen_details --->
+	llds_code_gen_details(
+		pre_births		:: set(prog_var),
+		post_births		:: set(prog_var),
+		pre_deaths		:: set(prog_var),
+		post_deaths		:: set(prog_var),
+			% All four of these fields are computed by liveness.m.
+			% For atomic goals, the post-deadness should be applied
+			% _before_ the goal.
+
+		follow_vars		:: maybe(follow_vars),
+			% Advisory information about where variables
+			% ought to be put next. The legal range
+			% includes the nonexistent register r(-1),
+			% which indicates any available register.
+			%
+			% Initially set to `no' for all goals, which
+			% means the absence of the advisory
+			% information. Can be set to `yes' by the
+			% follow_vars pass, if it is invoked. Can be
+			% set to `yes' for any kind of goal.
+
+		store_map		:: store_map,
+			% This annotation is meaningful only after the
+			% store_alloc pass, and even then only if
+			% attached to a goal representing a branched
+			% control structure, i.e. an if_then_else,
+			% switch or disj goal. For those goals, the map
+			% will have an entry for every variable that is
+			% forward live after the goal, and will map
+			% each of those variables to the location where
+			% all the branches will leave the value of the
+			% variable. The code after the branched goal
+			% can therefore pick it up from there.
+			%
+			% This field should contain an empty map if its
+			% contents are not meaningful.
+
+		resume_point		:: resume_point,
+			% If this goal establishes a resumption point,
+			% i.e. it is the second or later disjunct of a
+			% disjunction or if it is the condition of an
+			% if-then-else, this field will state what variables
+			% need to be saved for that resumption point, and
+			% which entry labels of the resumption point will be
+			% needed. (See compiler/notes/allocation.html)
+			%
+			% This field is filled in during the liveness
+			% pass. Before then, and after then if the goal
+			% does not establish a resumption point, it
+			% should contain no_resume_point.
+
+		maybe_need		:: maybe_need
+			% These three fields are filled in during the
+			% stackvars pass. They are not meaningful before then,
+			% and should therefore contain `no'.
+			%
+			% During the stack_vars pass, live_vars.m will set the
+			% maybe_need_across_call field to `yes' for calls,
+			% generic calls, and for foreign_proc goals that may
+			% call back to Mercury. The argument of the `yes' will
+			% state what variables need to be on the stack across
+			% that call.
+			%
+			% During the stack_vars pass, live_vars.m will set the
+			% maybe_need_in_resume field to `yes' for disjunctions,
+			% if-then-elses and negations. The argument of the
+			% `yes' will state what variables need to be on the
+			% stack at the resume point.
+			%
+			% During the stack_vars pass, live_vars.m will set the
+			% maybe_need_in_par_conj field to `yes' for par_conj
+			% goals. The argument of the `yes' will state what
+			% variables are required to be on the stack by the
+			% parallel execution engine.
+	).
+
+%-----------------------------------------------------------------------------%
+
+goal_info_get_pre_births(GoalInfo, PreBirths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( PreBirthsPrime = CodeGenInfo ^ llds_code_gen ^ pre_births ->
+		PreBirths = PreBirthsPrime
+	;
+		error("goal_info_get_pre_births: no code_gen_info")
+	).
+
+goal_info_get_post_births(GoalInfo, PostBirths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( PostBirthsPrime = CodeGenInfo ^ llds_code_gen ^ post_births ->
+		PostBirths = PostBirthsPrime
+	;
+		error("goal_info_get_post_births: no code_gen_info")
+	).
+
+goal_info_get_pre_deaths(GoalInfo, PreDeaths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( PreDeathsPrime = CodeGenInfo ^ llds_code_gen ^ pre_deaths ->
+		PreDeaths = PreDeathsPrime
+	;
+		error("goal_info_get_pre_deaths: no code_gen_info")
+	).
+
+goal_info_get_post_deaths(GoalInfo, PostDeaths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( PostDeathsPrime = CodeGenInfo ^ llds_code_gen ^ post_deaths ->
+		PostDeaths = PostDeathsPrime
+	;
+		error("goal_info_get_post_deaths: no code_gen_info")
+	).
+
+goal_info_get_follow_vars(GoalInfo, FollowVars) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( FollowVarsPrime = CodeGenInfo ^ llds_code_gen ^ follow_vars ->
+		FollowVars = FollowVarsPrime
+	;
+		error("goal_info_get_follow_vars: no code_gen_info")
+	).
+
+goal_info_get_store_map(GoalInfo, StoreMap) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( StoreMapPrime = CodeGenInfo ^ llds_code_gen ^ store_map ->
+		StoreMap = StoreMapPrime
+	;
+		error("goal_info_get_store_map: no code_gen_info")
+	).
+
+goal_info_get_resume_point(GoalInfo, ResumePoint) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( ResumePointPrime = CodeGenInfo ^ llds_code_gen ^ resume_point ->
+		ResumePoint = ResumePointPrime
+	;
+		error("goal_info_get_resume_point: no code_gen_info")
+	).
+
+goal_info_get_maybe_need_across_call(GoalInfo, MaybeNeedAtCall) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( MaybeNeed = CodeGenInfo ^ llds_code_gen ^ maybe_need ->
+		( MaybeNeed = need_call(NeedAtCall) ->
+			MaybeNeedAtCall = yes(NeedAtCall)
+		;
+			MaybeNeedAtCall = no
+		)
+	;
+		error("goal_info_get_need_at_call: no code_gen_info")
+	).
+
+goal_info_get_maybe_need_in_resume(GoalInfo, MaybeNeedInResume) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( MaybeNeed = CodeGenInfo ^ llds_code_gen ^ maybe_need ->
+		( MaybeNeed = need_resume(NeedInResume) ->
+			MaybeNeedInResume = yes(NeedInResume)
+		;
+			MaybeNeedInResume = no
+		)
+	;
+		error("goal_info_get_need_in_resume: no code_gen_info")
+	).
+
+goal_info_get_maybe_need_in_par_conj(GoalInfo, MaybeNeedInParConj) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	( MaybeNeed = CodeGenInfo ^ llds_code_gen ^ maybe_need ->
+		( MaybeNeed = need_par_conj(NeedInParConj) ->
+			MaybeNeedInParConj = yes(NeedInParConj)
+		;
+			MaybeNeedInParConj = no
+		)
+	;
+		error("goal_info_get_need_in_par_conj: no code_gen_info")
+	).
+
+%-----------------------------------------------------------------------------%
+
+goal_info_maybe_get_pre_births(GoalInfo, PreBirths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	PreBirths = CodeGenInfo ^ llds_code_gen ^ pre_births.
+
+goal_info_maybe_get_post_births(GoalInfo, PostBirths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	PostBirths = CodeGenInfo ^ llds_code_gen ^ post_births.
+
+goal_info_maybe_get_pre_deaths(GoalInfo, PreDeaths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	PreDeaths = CodeGenInfo ^ llds_code_gen ^ pre_deaths.
+
+goal_info_maybe_get_post_deaths(GoalInfo, PostDeaths) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	PostDeaths = CodeGenInfo ^ llds_code_gen ^ post_deaths.
+
+goal_info_maybe_get_follow_vars(GoalInfo, FollowVars) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	FollowVars = CodeGenInfo ^ llds_code_gen ^ follow_vars.
+
+goal_info_maybe_get_store_map(GoalInfo, StoreMap) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	StoreMap = CodeGenInfo ^ llds_code_gen ^ store_map.
+
+goal_info_maybe_get_resume_point(GoalInfo, ResumePoint) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	ResumePoint = CodeGenInfo ^ llds_code_gen ^ resume_point.
+
+goal_info_maybe_get_maybe_need_across_call(GoalInfo, MaybeNeedAcrossCall) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	MaybeNeed = CodeGenInfo ^ llds_code_gen ^ maybe_need,
+	MaybeNeed = need_call(NeedAcrossCall),
+	MaybeNeedAcrossCall = yes(NeedAcrossCall).
+
+goal_info_maybe_get_maybe_need_in_resume(GoalInfo, MaybeNeedInResume) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	MaybeNeed = CodeGenInfo ^ llds_code_gen ^ maybe_need,
+	MaybeNeed = need_resume(NeedInResume),
+	MaybeNeedInResume = yes(NeedInResume).
+
+goal_info_maybe_get_maybe_need_in_par_conj(GoalInfo, MaybeNeedInParConj) :-
+	goal_info_get_code_gen_info(GoalInfo, CodeGenInfo),
+	MaybeNeed = CodeGenInfo ^ llds_code_gen ^ maybe_need,
+	MaybeNeed = need_par_conj(NeedInParConj),
+	MaybeNeedInParConj = yes(NeedInParConj).
+
+%-----------------------------------------------------------------------------%
+
+goal_info_initialize_liveness_info(GoalInfo0, PreBirths, PostBirths,
+		PreDeaths, PostDeaths, ResumePoint, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = (((((LLDSInfo0
+		^ pre_births := PreBirths)
+		^ post_births := PostBirths)
+		^ pre_deaths := PreDeaths)
+		^ post_deaths := PostDeaths)
+		^ resume_point := ResumePoint),
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_pre_births(GoalInfo0, PreBirths, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ pre_births := PreBirths,
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_post_births(GoalInfo0, PostBirths, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ post_births := PostBirths,
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_pre_deaths(GoalInfo0, PreDeaths, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ pre_deaths := PreDeaths,
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_post_deaths(GoalInfo0, PostDeaths, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ post_deaths := PostDeaths,
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_follow_vars(GoalInfo0, FollowVars, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ follow_vars := FollowVars,
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_store_map(GoalInfo0, StoreMap, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ store_map := StoreMap,
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_resume_point(GoalInfo0, ResumePoint, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ resume_point := ResumePoint,
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_need_across_call(GoalInfo0, NeedAcrossCall, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ maybe_need := need_call(NeedAcrossCall),
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_need_in_resume(GoalInfo0, NeedInResume, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ maybe_need := need_resume(NeedInResume),
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+goal_info_set_need_in_par_conj(GoalInfo0, NeedInParConj, GoalInfo) :-
+	goal_info_get_code_gen_info(GoalInfo0, CodeGenInfo0),
+	LLDSInfo0 = get_details(CodeGenInfo0),
+	LLDSInfo = LLDSInfo0 ^ maybe_need := need_par_conj(NeedInParConj),
+	CodeGenInfo = llds_code_gen_info(LLDSInfo),
+	goal_info_set_code_gen_info(GoalInfo0, CodeGenInfo, GoalInfo).
+
+%-----------------------------------------------------------------------------%
+
+goal_set_follow_vars(Goal - GoalInfo0, FollowVars, Goal - GoalInfo) :-
+	goal_info_set_follow_vars(GoalInfo0, FollowVars, GoalInfo).
+
+goal_set_resume_point(Goal - GoalInfo0, ResumePoint, Goal - GoalInfo) :-
+	goal_info_set_resume_point(GoalInfo0, ResumePoint, GoalInfo).
+
+goal_info_resume_vars_and_loc(Resume, Vars, Locs) :-
+	(
+		Resume = resume_point(Vars, Locs)
+	;
+		Resume = no_resume_point,
+		error("goal_info__get_resume_vars_and_loc: no resume point")
+	).
+
+%-----------------------------------------------------------------------------%
+
+:- func get_details(hlds_goal_code_gen_info) = llds_code_gen_details.
+
+get_details(no_code_gen_info) = init_llds_code_gen_details.
+get_details(llds_code_gen_info(LLDSInfo)) = LLDSInfo.
+
+:- func init_llds_code_gen_details = llds_code_gen_details.
+
+init_llds_code_gen_details =
+	llds_code_gen_details(set__init, set__init, set__init, set__init,
+	no, map__init, no_resume_point, no_need).
+
+%-----------------------------------------------------------------------------%
+
+rename_vars_in_llds_code_gen_info(Details0, Must, Subn, Details) :-
+	Details0 = llds_code_gen_details(PreBirths0, PostBirths0,
+		PreDeaths0, PostDeaths0, MaybeFollowVars0, StoreMap0,
+		ResumePoint0, MaybeNeed0),
+	rename_vars_in_var_set(PreBirths0, Must, Subn, PreBirths),
+	rename_vars_in_var_set(PostBirths0, Must, Subn, PostBirths),
+	rename_vars_in_var_set(PreDeaths0, Must, Subn, PreDeaths),
+	rename_vars_in_var_set(PostDeaths0, Must, Subn, PostDeaths),
+	(
+		MaybeFollowVars0 = no,
+		MaybeFollowVars = no
+	;
+		MaybeFollowVars0 = yes(FollowVars0),
+		FollowVars0 = follow_vars(FollowVarsMap0, FirstFreeReg),
+		rename_vars_in_var_lval_map(FollowVarsMap0, Must, Subn,
+			FollowVarsMap),
+		FollowVars = follow_vars(FollowVarsMap, FirstFreeReg),
+		MaybeFollowVars = yes(FollowVars)
+	),
+	rename_vars_in_var_lval_map(StoreMap0, Must, Subn, StoreMap),
+	(
+		ResumePoint0 = no_resume_point,
+		ResumePoint = no_resume_point
+	;
+		ResumePoint0 = resume_point(ResumePointVars0, ResumeLocs),
+		rename_vars_in_var_set(ResumePointVars0, Must, Subn,
+			ResumePointVars),
+		ResumePoint = resume_point(ResumePointVars, ResumeLocs)
+	),
+	(
+		MaybeNeed0 = no_need,
+		MaybeNeed = no_need
+	;
+		MaybeNeed0 = need_call(NeedAcrossCall0),
+		NeedAcrossCall0 = need_across_call(ForwardVars0,
+			CallResumeVars0, CallNondetLiveVars0),
+		rename_vars_in_var_set(ForwardVars0, Must, Subn,
+			ForwardVars),
+		rename_vars_in_var_set(CallResumeVars0, Must, Subn,
+			CallResumeVars),
+		rename_vars_in_var_set(CallNondetLiveVars0, Must, Subn,
+			CallNondetLiveVars),
+		NeedAcrossCall = need_across_call(ForwardVars,
+			CallResumeVars, CallNondetLiveVars),
+		MaybeNeed = need_call(NeedAcrossCall)
+	;
+		MaybeNeed0 = need_resume(NeedInResume0),
+		NeedInResume0 = need_in_resume(OnStack, ResumeVars0,
+			NondetLiveVars0),
+		rename_vars_in_var_set(ResumeVars0, Must, Subn,
+			ResumeVars),
+		rename_vars_in_var_set(NondetLiveVars0, Must, Subn,
+			NondetLiveVars),
+		NeedInResume = need_in_resume(OnStack, ResumeVars,
+			NondetLiveVars),
+		MaybeNeed = need_resume(NeedInResume)
+	;
+		MaybeNeed0 = need_par_conj(NeedInParConj0),
+		NeedInParConj0 = need_in_par_conj(ParConjVars0),
+		rename_vars_in_var_set(ParConjVars0, Must, Subn, ParConjVars),
+		NeedInParConj = need_in_par_conj(ParConjVars),
+		MaybeNeed = need_par_conj(NeedInParConj)
+	),
+	Details = llds_code_gen_details(PreBirths, PostBirths,
+		PreDeaths, PostDeaths, MaybeFollowVars, StoreMap,
+		ResumePoint, MaybeNeed).
+
+:- pred rename_vars_in_var_lval_map(map(prog_var, lval)::in,
+	bool::in, map(prog_var, prog_var)::in, map(prog_var, lval)::out)
+	is det.
+
+rename_vars_in_var_lval_map(VarLvalMap0, Must, Subn, VarLvalMap) :-
+	map__to_assoc_list(VarLvalMap0, VarLvalList0),
+	rename_vars_in_var_lval_list(VarLvalList0, Must, Subn, VarLvalList),
+	map__from_assoc_list(VarLvalList, VarLvalMap).
+
+:- pred rename_vars_in_var_lval_list(assoc_list(prog_var, lval)::in,
+	bool::in, map(prog_var, prog_var)::in, assoc_list(prog_var, lval)::out)
+	is det.
+
+rename_vars_in_var_lval_list([], _Must, _Subn, []).
+rename_vars_in_var_lval_list([Var0 - Lval0 | VarLvals0], Must, Subn,
+		[Var - Lval | VarLvals]) :-
+	rename_var(Var0, Must, Subn, Var),
+	rename_vars_in_lval(Lval0, Must, Subn, Lval),
+	rename_vars_in_var_lval_list(VarLvals0, Must, Subn, VarLvals).
+
+:- pred rename_vars_in_lval(lval::in, bool::in, map(prog_var, prog_var)::in,
+	lval::out) is det.
+
+rename_vars_in_lval(Lval0, _Must, _Subn, Lval) :-
+	(
+		( Lval0 = stackvar(_)
+		; Lval0 = framevar(_)
+		; Lval0 = reg(_, _)
+		)
+	->
+		Lval = Lval0
+	;
+		error("rename_vars_in_lval: unexpected lval")
+	).
+
+%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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