[m-rev.] diff: remove hlds_llds.m's dependence on ll_backend

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Apr 7 09:09:25 AEST 2004


compiler/hlds_llds.m:
	Remove the dependence of this module on ll_backend.llds by defining
	types using abstract descriptions of LLDS storage locations. These
	have the added advantage that they express the intent of the affected
	data structures more directly. For example, the stack slot type used
	to be able to map a variable to a register or to a field of a cell
	on the heap, which doesn't make sense. This is no longer the case.
	The cost of the conversion operations now required is partly paid for
	by our new ability to avoid some old sanity checks.

compiler/llds.m:
compiler/code_util.m:
	Add some utility predicates to operate on the new data structures.

compiler/code_aux.m:
compiler/code_gen.m:
compiler/code_info.m:
compiler/continuation_info.m:
compiler/follow_vars.m:
compiler/lookup_switch.m:
compiler/par_conj_gen.m:
compiler/stack_alloc.m:
compiler/store_alloc.m:
compiler/var_locn.m:
	Conform to the changes in hlds_llds.m. In some cases, improve the
	style of the affected predicates, e.g. by introducing state variable
	syntax.

compiler/hlds_out.m:
	Conform to the changes in hlds_llds.m, and avoid importing ll_backend.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/code_aux.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_aux.m,v
retrieving revision 1.67
diff -u -b -r1.67 code_aux.m
--- compiler/code_aux.m	27 Oct 2003 05:42:35 -0000	1.67
+++ compiler/code_aux.m	6 Apr 2004 02:43:50 -0000
@@ -30,11 +30,11 @@
 	% conjunction or not.
 
 	% XXX should avoid the dependency on code_info here
-:- pred code_aux__contains_simple_recursive_call(hlds_goal, code_info, bool).
-:- mode code_aux__contains_simple_recursive_call(in, in, out) is semidet.
+:- pred code_aux__contains_simple_recursive_call(hlds_goal::in, code_info::in,
+	bool::out) is semidet.
 
-:- pred code_aux__explain_stack_slots(stack_slots, prog_varset, string).
-:- mode code_aux__explain_stack_slots(in, in, out) is det.
+:- pred code_aux__explain_stack_slots(stack_slots::in, prog_varset::in,
+	string::out) is det.
 
 %---------------------------------------------------------------------------%
 
@@ -72,8 +72,8 @@
 		)
 	).
 
-:- pred code_aux__is_recursive_call(hlds_goal_expr, code_info).
-:- mode code_aux__is_recursive_call(in, in) is semidet.
+:- pred code_aux__is_recursive_call(hlds_goal_expr::in, code_info::in)
+	is semidet.
 
 code_aux__is_recursive_call(Goal, CodeInfo) :-
 	Goal = call(CallPredId, CallProcId, _, BuiltinState, _, _),
@@ -92,20 +92,22 @@
 	string__append("\nStack slot assignments (if any):\n", Explanation1,
 		Explanation).
 
-:- pred code_aux__explain_stack_slots_2(assoc_list(prog_var, lval), prog_varset,
-		string, string).
-:- mode code_aux__explain_stack_slots_2(in, in, in, out) is det.
-
-code_aux__explain_stack_slots_2([], _, String, String).
-code_aux__explain_stack_slots_2([Var - Lval | Rest], VarSet, String0, String) :-
-	code_aux__explain_stack_slots_2(Rest, VarSet, String0, String1),
-	( llds_out__lval_to_string(Lval, LvalString0) ->
-		LvalString = LvalString0
+:- pred code_aux__explain_stack_slots_2(assoc_list(prog_var, stack_slot)::in,
+	prog_varset::in, string::in, string::out) is det.
+
+code_aux__explain_stack_slots_2([], _, !Explanation).
+code_aux__explain_stack_slots_2([Var - Slot | Rest], VarSet, !Explanation) :-
+	code_aux__explain_stack_slots_2(Rest, VarSet, !Explanation),
+	(
+		Slot = det_slot(SlotNum),
+		StackStr = "stackvar"
 	;
-		LvalString = "some lval"
+		Slot = nondet_slot(SlotNum),
+		StackStr = "framevar"
 	),
+	int_to_string(SlotNum, SlotStr),
 	varset__lookup_name(VarSet, Var, VarName),
-	string__append_list([VarName, "\t ->\t", LvalString, "\n", String1],
-		String).
+	string__append_list([VarName, "\t ->\t", StackStr, SlotStr, "\n",
+		!.Explanation], !:Explanation).
 
 %---------------------------------------------------------------------------%
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.122
diff -u -b -r1.122 code_gen.m
--- compiler/code_gen.m	5 Apr 2004 05:06:45 -0000	1.122
+++ compiler/code_gen.m	5 Apr 2004 05:20:36 -0000
@@ -253,7 +253,7 @@
 	;
 		MaybeFollowVars = no,
 		map__init(FollowVarsMap),
-		FollowVars = follow_vars(FollowVarsMap, 1)
+		FollowVars = abs_follow_vars(FollowVarsMap, 1)
 	),
 	module_info_globals(ModuleInfo, Globals),
 	continuation_info__basic_stack_layout_for_proc(PredInfo, Globals,
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.286
diff -u -b -r1.286 code_info.m
--- compiler/code_info.m	23 Mar 2004 10:52:01 -0000	1.286
+++ compiler/code_info.m	1 Apr 2004 18:31:38 -0000
@@ -88,7 +88,7 @@
 		% outermost resumption point, and info about the non-fixed
 		% stack slots used for tracing purposes.
 :- pred code_info__init(bool::in, globals::in, pred_id::in, proc_id::in,
-	pred_info::in, proc_info::in, follow_vars::in, module_info::in,
+	pred_info::in, proc_info::in, abs_follow_vars::in, module_info::in,
 	static_cell_info::in, resume_point_info::out, trace_slot_info::out,
 	code_info::out) is det.
 
@@ -375,8 +375,8 @@
 		MaybeFailVars = no,
 		EffLiveness = Liveness
 	),
-		var_locn__init_state(ArgList, EffLiveness, VarSet,
-			StackSlots, FollowVars, Options, VarLocnInfo),
+	var_locn__init_state(ArgList, EffLiveness, VarSet, StackSlots,
+		FollowVars, Options, VarLocnInfo),
 	stack__init(ResumePoints),
 	globals__lookup_bool_option(Globals, allow_hijacks, AllowHijack),
 	(
@@ -556,7 +556,7 @@
 
 		% Get the table that contains advice about where
 		% variables should be put.
-:- pred code_info__get_follow_var_map(code_info::in, follow_vars_map::out)
+:- pred code_info__get_follow_var_map(code_info::in, abs_follow_vars_map::out)
 	is det.
 
 		% Get the integer that gives the number of the next
@@ -565,7 +565,7 @@
 
 		% Set the table that contains advice about where
 		% variables should be put.
-:- pred code_info__set_follow_vars(follow_vars::in,
+:- pred code_info__set_follow_vars(abs_follow_vars::in,
 	code_info::in, code_info::out) is det.
 
 	% code_info__pre_goal_update(GoalInfo, Atomic, OldCodeInfo, NewCodeInfo)
@@ -930,10 +930,10 @@
 :- pred code_info__reset_resume_known(position_info::in,
 	code_info::in, code_info::out) is det.
 
-:- pred code_info__generate_branch_end(store_map::in, branch_end::in,
+:- pred code_info__generate_branch_end(abs_store_map::in, branch_end::in,
 	branch_end::out, code_tree::out, code_info::in, code_info::out) is det.
 
-:- pred code_info__after_all_branches(store_map::in, branch_end::in,
+:- pred code_info__after_all_branches(abs_store_map::in, branch_end::in,
 	code_info::in, code_info::out) is det.
 
 :- pred code_info__save_hp_in_branch(code_tree::out, lval::out,
@@ -977,14 +977,16 @@
 		% afterwards, since every goal following a branched
 		% control structure must in any case be annotated with
 		% its own follow_var set.
-	map__to_assoc_list(StoreMap, VarLocs),
-	map__from_assoc_list(VarLocs, FollowVarsMap),
-	assoc_list__values(VarLocs, Locs),
-	code_util__max_mentioned_reg(Locs, MaxMentionedReg),
+	map__to_assoc_list(StoreMap, AbsVarLocs),
+	map__from_assoc_list(AbsVarLocs, FollowVarsMap),
+	assoc_list__values(AbsVarLocs, AbsLocs),
+	code_util__max_mentioned_abs_reg(AbsLocs, MaxMentionedReg),
 	code_info__set_follow_vars(
-		follow_vars(FollowVarsMap, MaxMentionedReg + 1), !CI),
+		abs_follow_vars(FollowVarsMap, MaxMentionedReg + 1), !CI),
 	code_info__get_instmap(!.CI, InstMap),
 	( instmap__is_reachable(InstMap) ->
+		VarLocs = assoc_list__map_values(key_abs_locn_to_lval,
+			AbsVarLocs),
 		code_info__place_vars(VarLocs, Code, !CI)
 	;
 		% With --opt-no-return-call, the variables that we would have
@@ -1074,11 +1076,12 @@
 	% in the store map, and will believe they are where the store map
 	% says they are.
 
-:- pred code_info__remake_with_store_map(store_map::in,
+:- pred code_info__remake_with_store_map(abs_store_map::in,
 	code_info::in, code_info::out) is det.
 
 code_info__remake_with_store_map(StoreMap, !CI) :-
-	map__to_assoc_list(StoreMap, VarLvals),
+	map__to_assoc_list(StoreMap, VarLocns),
+	VarLvals = assoc_list__map_values(key_abs_locn_to_lval, VarLocns),
 	code_info__get_var_locn_info(!.CI, VarLocnInfo0),
 	var_locn__reinit_state(VarLvals, VarLocnInfo0, VarLocnInfo),
 	code_info__set_var_locn_info(VarLocnInfo, !CI).
@@ -2337,8 +2340,10 @@
 	),
 	( MaybeFailVars = yes(FailVars) ->
 		code_info__get_stack_slots(!.CI, StackSlots),
-		map__select(StackSlots, FailVars, StackMap0),
-		map__to_assoc_list(StackMap0, StackList0),
+		map__select(StackSlots, FailVars, AbsStackMap),
+		map__to_assoc_list(AbsStackMap, AbsStackList),
+		StackList0 = assoc_list__map_values(key_stack_slot_to_lval,
+			AbsStackList),
 		code_info__make_singleton_sets(StackList0, StackList),
 		map__from_assoc_list(StackList, StackMap)
 	;
@@ -2366,15 +2371,15 @@
 		ResumePoint = orig_only(OrigMap, OrigAddr)
 	;
 		ResumeLocs = stack_only,
-		code_info__make_stack_resume_map(ResumeVars,
-			StackSlots, StackMap),
+		code_info__make_stack_resume_map(ResumeVars, StackSlots,
+			StackMap),
 		code_info__get_next_label(StackLabel, !CI),
 		StackAddr = label(StackLabel),
 		ResumePoint = stack_only(StackMap, StackAddr)
 	;
 		ResumeLocs = orig_and_stack,
-		code_info__make_stack_resume_map(ResumeVars,
-			StackSlots, StackMap),
+		code_info__make_stack_resume_map(ResumeVars, StackSlots,
+			StackMap),
 		code_info__get_next_label(OrigLabel, !CI),
 		OrigAddr = label(OrigLabel),
 		code_info__get_next_label(StackLabel, !CI),
@@ -2383,8 +2388,8 @@
 			StackMap, StackAddr)
 	;
 		ResumeLocs = stack_and_orig,
-		code_info__make_stack_resume_map(ResumeVars,
-			StackSlots, StackMap),
+		code_info__make_stack_resume_map(ResumeVars, StackSlots,
+			StackMap),
 		code_info__get_next_label(StackLabel, !CI),
 		StackAddr = label(StackLabel),
 		code_info__get_next_label(OrigLabel, !CI),
@@ -2398,7 +2403,9 @@
 
 code_info__make_stack_resume_map(ResumeVars, StackSlots, StackMap) :-
 	map__select(StackSlots, ResumeVars, StackMap0),
-	map__to_assoc_list(StackMap0, StackList0),
+	map__to_assoc_list(StackMap0, AbsStackList),
+	StackList0 = assoc_list__map_values(key_stack_slot_to_lval,
+		AbsStackList),
 	code_info__make_singleton_sets(StackList0, StackList),
 	map__from_assoc_list(StackList, StackMap).
 
@@ -2715,8 +2722,8 @@
 code_info__make_vars_forward_live_2([], _, _, !VarLocnInfo).
 code_info__make_vars_forward_live_2([Var | Vars], StackSlots, N0,
 		!VarLocnInfo) :-
-	( map__search(StackSlots, Var, Lval0) ->
-		Lval = Lval0,
+	( map__search(StackSlots, Var, Slot) ->
+		Lval = stack_slot_to_lval(Slot),
 		N1 = N0
 	;
 		code_info__find_unused_reg(!.VarLocnInfo, N0, N1),
@@ -3246,11 +3253,11 @@
 	code_info__get_next_non_reserved(!.CI, NextNonReserved),
 	code_info__get_var_locn_info(!.CI, VarLocnInfo0),
 	(
-		map__search(FollowVarsMap, Var, PrefLval),
-		PrefLval = reg(PrefRegType, PrefRegNum),
+		map__search(FollowVarsMap, Var, PrefLocn),
+		PrefLocn = abs_reg(PrefRegNum),
+		% ZZZ
 		PrefRegNum >= 1
 	->
-			require(unify(PrefRegType, r), "acquire non-r reg"),
 			var_locn__acquire_reg_prefer_given(PrefRegNum, Lval,
 			VarLocnInfo0, VarLocnInfo)
 	;
@@ -3640,8 +3647,8 @@
 
 code_info__get_variable_slot(CI, Var, Slot) :-
 	code_info__get_stack_slots(CI, StackSlots),
-	( map__search(StackSlots, Var, SlotPrime) ->
-		Slot = SlotPrime
+	( map__search(StackSlots, Var, SlotLocn) ->
+		Slot = stack_slot_to_lval(SlotLocn)
 	;
 		Name = code_info__variable_to_string(CI, Var),
 		term__var_to_int(Var, Num),
@@ -3663,18 +3670,19 @@
 	map__values(StackSlots, StackSlotList),
 	code_info__max_var_slot_2(StackSlotList, 0, SlotCount).
 
-:- pred code_info__max_var_slot_2(list(lval)::in, int::in, int::out) is det.
+:- pred code_info__max_var_slot_2(list(stack_slot)::in, int::in, int::out)
+	is det.
 
-code_info__max_var_slot_2([], Max, Max).
-code_info__max_var_slot_2([L | Ls], Max0, Max) :-
-	( L = stackvar(N) ->
-		int__max(N, Max0, Max1)
-	; L = framevar(N) ->
-		int__max(N, Max0, Max1)
+code_info__max_var_slot_2([], !Max).
+code_info__max_var_slot_2([L | Ls], !Max) :-
+	(
+		L = det_slot(N),
+		int__max(N, !Max)
 	;
-		Max1 = Max0
+		L = nondet_slot(N),
+		int__max(N, !Max)
 	),
-	code_info__max_var_slot_2(Ls, Max1, Max).
+	code_info__max_var_slot_2(Ls, !Max).
 
 :- pred code_info__stack_variable(code_info::in, int::in, lval::out) is det.
 
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.148
diff -u -b -r1.148 code_util.m
--- compiler/code_util.m	23 Mar 2004 10:52:01 -0000	1.148
+++ compiler/code_util.m	1 Apr 2004 14:05:12 -0000
@@ -20,6 +20,7 @@
 :- import_module backend_libs__proc_label.
 :- import_module backend_libs__rtti.
 :- import_module hlds__hlds_goal.
+:- import_module hlds__hlds_llds.
 :- import_module hlds__hlds_module.
 :- import_module hlds__hlds_pred.
 :- import_module ll_backend__llds.
@@ -69,6 +70,7 @@
 :- pred code_util__arg_loc_to_register(arg_loc::in, lval::out) is det.
 
 :- pred code_util__max_mentioned_reg(list(lval)::in, int::out) is det.
+:- pred code_util__max_mentioned_abs_reg(list(abs_locn)::in, int::out) is det.
 
 :- pred code_util__goal_may_alloc_temp_frame(hlds_goal::in) is semidet.
 
@@ -90,6 +92,7 @@
 
 	% Given a procedure that already has its arg_info field filled in,
 	% return a list giving its input variables and their initial locations.
+
 :- pred build_input_arg_list(proc_info::in,
 	assoc_list(prog_var, lval)::out) is det.
 
@@ -104,8 +107,7 @@
 :- import_module libs__options.
 :- import_module parse_tree__prog_util.
 
-:- import_module bool, char, int, string, set, map, term, varset.
-:- import_module require, std_util.
+:- import_module bool, char, int, string, set, term, varset, require.
 
 %---------------------------------------------------------------------------%
 
@@ -222,14 +224,29 @@
 :- pred code_util__max_mentioned_reg_2(list(lval)::in, int::in, int::out)
 	is det.
 
-code_util__max_mentioned_reg_2([], MaxRegNum, MaxRegNum).
-code_util__max_mentioned_reg_2([Lval | Lvals], MaxRegNum0, MaxRegNum) :-
+code_util__max_mentioned_reg_2([], !MaxRegNum).
+code_util__max_mentioned_reg_2([Lval | Lvals], !MaxRegNum) :-
 	( Lval = reg(r, N) ->
-		int__max(MaxRegNum0, N, MaxRegNum1)
+		int__max(N, !MaxRegNum)
+	;
+		true
+	),
+	code_util__max_mentioned_reg_2(Lvals, !MaxRegNum).
+
+code_util__max_mentioned_abs_reg(Lvals, MaxRegNum) :-
+	code_util__max_mentioned_abs_reg_2(Lvals, 0, MaxRegNum).
+
+:- pred code_util__max_mentioned_abs_reg_2(list(abs_locn)::in,
+	int::in, int::out) is det.
+
+code_util__max_mentioned_abs_reg_2([], !MaxRegNum).
+code_util__max_mentioned_abs_reg_2([Lval | Lvals], !MaxRegNum) :-
+	( Lval = abs_reg(N) ->
+		int__max(N, !MaxRegNum)
 	;
-		MaxRegNum1 = MaxRegNum0
+		true
 	),
-	code_util__max_mentioned_reg_2(Lvals, MaxRegNum1, MaxRegNum).
+	code_util__max_mentioned_abs_reg_2(Lvals, !MaxRegNum).
 
 %-----------------------------------------------------------------------------%
 
@@ -449,3 +466,5 @@
 		VarArgs = VarArgs0
 	),
 	build_input_arg_list_2(Rest0, VarArgs0).
+
+%-----------------------------------------------------------------------------%
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.50
diff -u -b -r1.50 continuation_info.m
--- compiler/continuation_info.m	5 Nov 2003 03:17:35 -0000	1.50
+++ compiler/continuation_info.m	1 Apr 2004 15:41:55 -0000
@@ -564,9 +564,9 @@
 		% On return, output arguments are in their registers.
 		code_util__arg_loc_to_register(ArgLoc, Lval),
 		VarLvals = [Var - Lval | TailVarLvals]
-	; map__search(StackSlots, Var, Lval) ->
+	; map__search(StackSlots, Var, Slot) ->
 		% On return, other live variables are in their stack slots.
-		VarLvals = [Var - Lval | TailVarLvals]
+		VarLvals = [Var - stack_slot_to_lval(Slot) | TailVarLvals]
 	; OkToDeleteAny = yes ->
 		VarLvals = TailVarLvals
 	;
Index: compiler/follow_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/follow_vars.m,v
retrieving revision 1.67
diff -u -b -r1.67 follow_vars.m
--- compiler/follow_vars.m	23 Mar 2004 10:52:02 -0000	1.67
+++ compiler/follow_vars.m	1 Apr 2004 14:45:25 -0000
@@ -32,16 +32,14 @@
 :- import_module hlds__hlds_llds.
 :- import_module hlds__hlds_module.
 :- import_module hlds__hlds_pred.
-:- import_module parse_tree__prog_data.
-
-:- import_module map.
 
-:- pred find_final_follow_vars(proc_info::in, follow_vars_map::out, int::out)
-	is det.
+:- pred find_final_follow_vars(proc_info::in, abs_follow_vars_map::out,
+	int::out) is det.
 
-:- pred find_follow_vars_in_goal(hlds_goal::in, map(prog_var, type)::in,
-	module_info::in, follow_vars_map::in, int::in,
-	hlds_goal::out, follow_vars_map::out, int::out) is det.
+:- pred find_follow_vars_in_goal(hlds_goal::in, hlds_goal::out,
+	vartypes::in, module_info::in,
+	abs_follow_vars_map::in, abs_follow_vars_map::out,
+	int::in, int::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -69,93 +67,81 @@
 	assoc_list__from_corresponding_lists(ArgInfo, HeadVars,
 		ArgInfoHeadVars),
 	map__init(FollowVarsMap0),
-	find_final_follow_vars_2(ArgInfoHeadVars, FollowVarsMap0, 1,
-		FollowVarsMap, NextNonReserved).
+	find_final_follow_vars_2(ArgInfoHeadVars,
+		FollowVarsMap0, FollowVarsMap, 1, NextNonReserved).
 
 :- pred find_final_follow_vars_2(assoc_list(arg_info, prog_var)::in,
-	follow_vars_map::in, int::in, follow_vars_map::out, int::out) is det.
+	abs_follow_vars_map::in, abs_follow_vars_map::out, int::in, int::out)
+	is det.
 
-find_final_follow_vars_2([], FollowMap, NextNonReserved,
-		FollowMap, NextNonReserved).
-find_final_follow_vars_2([arg_info(Loc, Mode) - Var | ArgInfoVars],
-		FollowVarsMap0, NextNonReserved0,
-		FollowVarsMap, NextNonReserved) :-
-	code_util__arg_loc_to_register(Loc, Reg),
+find_final_follow_vars_2([], !FollowMap, !NextNonReserved).
+find_final_follow_vars_2([arg_info(RegNum, Mode) - Var | ArgInfoVars],
+		!FollowVarsMap, !NextNonReserved) :-
 	( Mode = top_out ->
-		map__det_insert(FollowVarsMap0, Var, Reg, FollowVarsMap1),
-		int__max(NextNonReserved0, Loc + 1, NextNonReserved1)
+		Locn = abs_reg(RegNum),
+		map__det_insert(!.FollowVarsMap, Var, Locn, !:FollowVarsMap),
+		int__max(RegNum + 1, !NextNonReserved)
 	;
-		FollowVarsMap0 = FollowVarsMap1,
-		NextNonReserved1 = NextNonReserved0
+		true
 	),
-	find_final_follow_vars_2(ArgInfoVars, FollowVarsMap1, NextNonReserved1,
-		FollowVarsMap, NextNonReserved).
+	find_final_follow_vars_2(ArgInfoVars, !FollowVarsMap,
+		!NextNonReserved).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-find_follow_vars_in_goal(Goal0 - GoalInfo0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Goal - GoalInfo, FollowVarsMap, NextNonReserved) :-
-	find_follow_vars_in_goal_expr(Goal0, GoalInfo0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Goal, GoalInfo, FollowVarsMap, NextNonReserved).
+find_follow_vars_in_goal(Goal0 - GoalInfo0, Goal - GoalInfo,
+		VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
+	find_follow_vars_in_goal_expr(Goal0, Goal, GoalInfo0, GoalInfo,
+		VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved).
 
 %-----------------------------------------------------------------------------%
 
-:- 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, hlds_goal_info::out, follow_vars_map::out,
-	int::out) is det.
+:- pred find_follow_vars_in_goal_expr(hlds_goal_expr::in, hlds_goal_expr::out,
+	hlds_goal_info::in, hlds_goal_info::out, vartypes::in, module_info::in,
+	abs_follow_vars_map::in, abs_follow_vars_map::out,
+	int::in, int::out) is det.
+
+find_follow_vars_in_goal_expr(conj(Goals0), conj(Goals), GoalInfo, GoalInfo,
+		VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
+	find_follow_vars_in_conj(Goals0, Goals, VarTypes, ModuleInfo,
+		no, !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), GoalInfo,
-		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
-		par_conj(Goals), GoalInfo, FollowVarsMap, NextNonReserved) :-
+find_follow_vars_in_goal_expr(par_conj(Goals0), par_conj(Goals),
+		GoalInfo, GoalInfo, VarTypes, ModuleInfo,
+		!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.
-	find_follow_vars_in_disj(Goals0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Goals, FollowVarsMap, NextNonReserved).
+	find_follow_vars_in_disj(Goals0, Goals, VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved).
 
 	% We record that at the end of each disjunct, live variables should
 	% be in the locations given by the initial follow_vars, which reflects
 	% the requirements of the code following the disjunction.
 
-find_follow_vars_in_goal_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),
-	goal_info_set_store_map(GoalInfo0, FollowVarsMap0, GoalInfo).
-
-find_follow_vars_in_goal_expr(not(Goal0), GoalInfo, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		not(Goal), GoalInfo, FollowVarsMap, NextNonReserved) :-
-	find_follow_vars_in_goal(Goal0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Goal, FollowVarsMap, NextNonReserved).
+find_follow_vars_in_goal_expr(disj(Goals0), disj(Goals), GoalInfo0, GoalInfo,
+		VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
+	goal_info_set_store_map(GoalInfo0, !.FollowVarsMap, GoalInfo),
+	find_follow_vars_in_disj(Goals0, Goals, VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved).
+
+find_follow_vars_in_goal_expr(not(Goal0), not(Goal), GoalInfo, GoalInfo,
+		VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
+	find_follow_vars_in_goal(Goal0, Goal, VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved).
 
 	% We record that at the end of each arm of the switch, live variables
 	% should be in the locations given by the initial follow_vars, which
 	% reflects the requirements of the code following the switch.
 
-find_follow_vars_in_goal_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),
-	goal_info_set_store_map(GoalInfo0, FollowVarsMap0, GoalInfo).
+find_follow_vars_in_goal_expr(switch(Var, Det, Cases0),
+		switch(Var, Det, Cases), GoalInfo0, GoalInfo,
+		VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved) :-
+	goal_info_set_store_map(GoalInfo0, !.FollowVarsMap, GoalInfo),
+	find_follow_vars_in_cases(Cases0, Cases, VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved).
 
 	% Set the follow_vars field for the condition, the then-part and the
 	% else-part, since in general they have requirements about where
@@ -175,67 +161,67 @@
 	% following the if-then-else.
 
 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), GoalInfo,
-		FollowVarsMapCond, NextNonReservedCond) :-
-	find_follow_vars_in_goal(Then0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Then1, FollowVarsMapThen, NextNonReservedThen),
-	FollowVarsThen = follow_vars(FollowVarsMapThen, NextNonReservedThen),
+		if_then_else(Vars, Cond0, Then0, Else0),
+		if_then_else(Vars, Cond, Then, Else),
+		GoalInfo0, GoalInfo, VarTypes, ModuleInfo,
+		FollowVarsMap0, FollowVarsMapCond,
+		NextNonReserved0, NextNonReservedCond) :-
+	find_follow_vars_in_goal(Then0, Then1, VarTypes, ModuleInfo,
+		FollowVarsMap0, FollowVarsMapThen,
+		NextNonReserved0, NextNonReservedThen),
+	FollowVarsThen =
+		abs_follow_vars(FollowVarsMapThen, NextNonReservedThen),
 	goal_set_follow_vars(Then1, yes(FollowVarsThen), Then),
 
-	find_follow_vars_in_goal(Cond0, VarTypes, ModuleInfo,
-		FollowVarsMapThen, NextNonReservedThen,
-		Cond1, FollowVarsMapCond, NextNonReservedCond),
-	FollowVarsCond = follow_vars(FollowVarsMapCond, NextNonReservedCond),
+	find_follow_vars_in_goal(Cond0, Cond1, VarTypes, ModuleInfo,
+		FollowVarsMapThen, FollowVarsMapCond,
+		NextNonReservedThen, NextNonReservedCond),
+	FollowVarsCond =
+		abs_follow_vars(FollowVarsMapCond, NextNonReservedCond),
 	goal_set_follow_vars(Cond1, yes(FollowVarsCond), Cond),
 
-	find_follow_vars_in_goal(Else0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Else1, FollowVarsMapElse, NextNonReservedElse),
-	FollowVarsElse = follow_vars(FollowVarsMapElse, NextNonReservedElse),
+	find_follow_vars_in_goal(Else0, Else1, VarTypes, ModuleInfo,
+		FollowVarsMap0, FollowVarsMapElse,
+		NextNonReserved0, NextNonReservedElse),
+	FollowVarsElse =
+		abs_follow_vars(FollowVarsMapElse, NextNonReservedElse),
 	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), GoalInfo,
-		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
-		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), GoalInfo,
-		_VarTypes, _ModuleInfo, FollowVarsMap0, NextNonReserved,
-		unify(A,B,C,D,E), GoalInfo, FollowVarsMap, NextNonReserved) :-
+find_follow_vars_in_goal_expr(some(Vars, CanRemove, Goal0),
+		some(Vars, CanRemove, Goal), GoalInfo, GoalInfo,
+		VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
+	find_follow_vars_in_goal(Goal0, Goal, VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved).
+
+find_follow_vars_in_goal_expr(unify(A,B,C,D,E), unify(A,B,C,D,E),
+		GoalInfo, GoalInfo, _VarTypes, _ModuleInfo,
+		!FollowVarsMap, !NextNonReserved) :-
 	(
 		D = assign(LVar, RVar),
-		map__search(FollowVarsMap0, LVar, DesiredLoc)
+		map__search(!.FollowVarsMap, LVar, DesiredLoc)
 	->
-		map__set(FollowVarsMap0, RVar, DesiredLoc, FollowVarsMap)
+		map__set(!.FollowVarsMap, RVar, DesiredLoc, !:FollowVarsMap)
 	;
-		FollowVarsMap = FollowVarsMap0
+		true
 	).
 
-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), GoalInfo,
-		FollowVarsMap, NextNonReserved).
+find_follow_vars_in_goal_expr(foreign_proc(A,B,C,D,E,F,G),
+		foreign_proc(A,B,C,D,E,F,G), GoalInfo, GoalInfo,
+		_, _, !FollowVarsMap, !NextNonReserved).
 
 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(
-		Call @ generic_call(GenericCall, Args, Modes, Det), GoalInfo,
-		VarTypes, ModuleInfo, FollowVarsMap0, NextNonReserved0,
-		Call, GoalInfo, FollowVarsMap, NextNonReserved) :-
+		Call @ generic_call(GenericCall, Args, Modes, Det), Call,
+		GoalInfo, GoalInfo, VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved) :-
 	% unsafe_casts are generated inline.
 	( GenericCall = unsafe_cast ->
-		FollowVarsMap = FollowVarsMap0,
-		NextNonReserved = NextNonReserved0
+		true
 	;
 		determinism_to_code_model(Det, CodeModel),
 		map__apply_to_list(Args, VarTypes, Types),
@@ -247,95 +233,84 @@
 		call_gen__generic_call_info(CodeModel, GenericCall, _,
 			SpecifierArgInfos, FirstInput),
 		find_follow_vars_from_arginfo(SpecifierArgInfos,
-			map__init, 1, FollowVarsMap1, _),
+			map__init, !:FollowVarsMap, 1, _),
 		find_follow_vars_from_sequence(InVars, FirstInput,
-			FollowVarsMap1, FollowVarsMap, NextNonReserved)
+			!FollowVarsMap, !:NextNonReserved)
 	).
 
 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) :-
+		call(PredId, ProcId, Args, State, E, F), GoalInfo, GoalInfo,
+		_, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
 	( State = inline_builtin ->
-		FollowVarsMap = FollowVarsMap0,
-		NextNonReserved = NextNonReserved0
+		true
 	;
 		find_follow_vars_in_call(PredId, ProcId, Args, ModuleInfo,
-			FollowVarsMap, NextNonReserved)
+			!:FollowVarsMap, !:NextNonReserved)
 	).
 
 %-----------------------------------------------------------------------------%
 
 :- pred find_follow_vars_in_call(pred_id::in, proc_id::in, list(prog_var)::in,
-	module_info::in, follow_vars_map::out, int::out) is det.
+	module_info::in, abs_follow_vars_map::out, int::out) is det.
 
 find_follow_vars_in_call(PredId, ProcId, Args, ModuleInfo,
 		FollowVarsMap, NextNonReserved) :-
 	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),
-	find_follow_vars_from_arginfo(ArgsInfos, FollowVarsMap0, 1,
-		FollowVarsMap, NextNonReserved).
+	find_follow_vars_from_arginfo(ArgsInfos, map__init, FollowVarsMap,
+		1, NextNonReserved).
 
 :- pred find_follow_vars_from_arginfo(assoc_list(prog_var, arg_info)::in,
-	follow_vars_map::in, int::in, follow_vars_map::out, int::out) is det.
+	abs_follow_vars_map::in, abs_follow_vars_map::out,
+	int::in, int::out) is det.
 
-find_follow_vars_from_arginfo([], FollowVarsMap, NextNonReserved,
-		FollowVarsMap, NextNonReserved).
-find_follow_vars_from_arginfo([ArgVar - arg_info(Loc, Mode) | ArgsInfos],
-		FollowVarsMap0, NextNonReserved0,
-		FollowVarsMap, NextNonReserved) :-
-	code_util__arg_loc_to_register(Loc, Lval),
+find_follow_vars_from_arginfo([], !FollowVarsMap, !NextNonReserved).
+find_follow_vars_from_arginfo([ArgVar - arg_info(RegNum, Mode) | ArgsInfos],
+		!FollowVarsMap, !NextNonReserved) :-
 	( Mode = top_in ->
-		( map__insert(FollowVarsMap0, ArgVar, Lval, FollowVarsMap1) ->
-			FollowVarsMap2 = FollowVarsMap1
+		Locn = abs_reg(RegNum),
+		(
+			map__insert(!.FollowVarsMap, ArgVar, Locn,
+				!:FollowVarsMap)
+		->
+			true	% FollowVarsMap is updated
 		;
 			% The call is not in superhomogeneous form: this
 			% argument has appeared before. Since the earlier
 			% appearance will have given the variable a smaller
 			% register number, we prefer that location to the one
 			% we would give to this appearance of the variable.
-			FollowVarsMap2 = FollowVarsMap0
+			true	% FollowVarsMap is not updated
 		),
-		( Lval = reg(r, RegNum) ->
-			int__max(NextNonReserved0, RegNum + 1,
-				NextNonReserved1)
+		int__max(RegNum + 1, !NextNonReserved)
 		;
-			error("arg_info puts arg in non-reg lval")
-		)
-	;
-		FollowVarsMap2 = FollowVarsMap0,
-		NextNonReserved1 = NextNonReserved0
+		true
 	),
 	find_follow_vars_from_arginfo(ArgsInfos,
-		FollowVarsMap2, NextNonReserved1,
-		FollowVarsMap, NextNonReserved).
+		!FollowVarsMap, !NextNonReserved).
 
 %-----------------------------------------------------------------------------%
 
 :- pred find_follow_vars_from_sequence(list(prog_var)::in, int::in,
-	follow_vars_map::in, follow_vars_map::out, int::out) is det.
+	abs_follow_vars_map::in, abs_follow_vars_map::out, int::out) is det.
 
-find_follow_vars_from_sequence([], NextRegNum, FollowVarsMap,
-		FollowVarsMap, NextRegNum).
-find_follow_vars_from_sequence([InVar | InVars], NextRegNum, FollowVarsMap0,
-		FollowVarsMap, NextNonReserved) :-
-	(
-		map__insert(FollowVarsMap0, InVar, reg(r, NextRegNum),
-			FollowVarsMap1)
-	->
-		FollowVarsMap2 = FollowVarsMap1
+find_follow_vars_from_sequence([], NextRegNum, !FollowVarsMap, NextRegNum).
+find_follow_vars_from_sequence([InVar | InVars], NextRegNum, !FollowVarsMap,
+		NextNonReserved) :-
+	Locn = abs_reg(NextRegNum),
+	( map__insert(!.FollowVarsMap, InVar, Locn, !:FollowVarsMap) ->
+		true	% FollowVarsMap is updated
 	;
 		% The call is not in superhomogeneous form: this argument has
 		% appeared before. Since the earlier appearance will have given
 		% the variable a smaller register number, we prefer that
 		% location to the one we would give to this appearance of the
 		% variable.
-		FollowVarsMap2 = FollowVarsMap0
+		true	% FollowVarsMap is not updated
 	),
-	find_follow_vars_from_sequence(InVars, NextRegNum + 1, FollowVarsMap2,
-		FollowVarsMap, NextNonReserved).
+	find_follow_vars_from_sequence(InVars, NextRegNum + 1,
+		!FollowVarsMap, NextNonReserved).
 
 %-----------------------------------------------------------------------------%
 
@@ -359,23 +334,25 @@
 	%
 	% This code is used both for disjunction and parallel conjunction.
 
-:- pred find_follow_vars_in_disj(list(hlds_goal)::in, map(prog_var, type)::in,
-	module_info::in, follow_vars_map::in, int::in,
-	list(hlds_goal)::out, follow_vars_map::out, int::out) is det.
-
-find_follow_vars_in_disj([], _, _ModuleInfo, FollowVarsMap, NextNonReserved,
-		[], FollowVarsMap, NextNonReserved).
-find_follow_vars_in_disj([Goal0 | Goals0], VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		[Goal | Goals], FollowVarsMap, NextNonReserved) :-
-	find_follow_vars_in_goal(Goal0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Goal1, FollowVarsMap, NextNonReserved),
-	FollowVars = follow_vars(FollowVarsMap, NextNonReserved),
+:- pred find_follow_vars_in_disj(list(hlds_goal)::in, list(hlds_goal)::out,
+	vartypes::in, module_info::in,
+	abs_follow_vars_map::in, abs_follow_vars_map::out,
+	int::in, int::out) is det.
+
+find_follow_vars_in_disj([], [], _, _ModuleInfo,
+		FollowVarsMap,  FollowVarsMap,
+		NextNonReserved, NextNonReserved).
+find_follow_vars_in_disj([Goal0 | Goals0], [Goal | Goals],
+		VarTypes, ModuleInfo, FollowVarsMap0, FollowVarsMap,
+		NextNonReserved0, NextNonReserved) :-
+	find_follow_vars_in_goal(Goal0, Goal1, VarTypes, ModuleInfo,
+		FollowVarsMap0, FollowVarsMap,
+		NextNonReserved0, NextNonReserved),
+	FollowVars = abs_follow_vars(FollowVarsMap, NextNonReserved),
 	goal_set_follow_vars(Goal1, yes(FollowVars), Goal),
-	find_follow_vars_in_disj(Goals0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Goals, _FollowVarsMap, _NextNonReserved).
+	find_follow_vars_in_disj(Goals0, Goals, VarTypes, ModuleInfo,
+		FollowVarsMap0, _FollowVarsMap,
+		NextNonReserved0, _NextNonReserved).
 
 %-----------------------------------------------------------------------------%
 
@@ -390,39 +367,40 @@
 	% its follow_vars) and to let different branches "vote" on
 	% what should be in registers.
 
-:- pred find_follow_vars_in_cases(list(case)::in, map(prog_var, type)::in,
-	module_info::in, follow_vars_map::in, int::in,
-	list(case)::out, follow_vars_map::out, int::out) is det.
-
-find_follow_vars_in_cases([], _, _ModuleInfo, FollowVarsMap, NextNonReserved,
-		[], FollowVarsMap, NextNonReserved).
-find_follow_vars_in_cases([case(Cons, Goal0) | Goals0], VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		[case(Cons, Goal) | Goals], FollowVarsMap, NextNonReserved) :-
-	find_follow_vars_in_goal(Goal0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved0,
-		Goal1, FollowVarsMap, NextNonReserved),
-	FollowVars = follow_vars(FollowVarsMap, NextNonReserved),
+:- pred find_follow_vars_in_cases(list(case)::in, list(case)::out,
+	vartypes::in, module_info::in,
+	abs_follow_vars_map::in, abs_follow_vars_map::out,
+	int::in, int::out) is det.
+
+find_follow_vars_in_cases([], [], _, _, !FollowVarsMap, !NextNonReserved).
+find_follow_vars_in_cases([case(Cons, Goal0) | Goals0],
+		[case(Cons, Goal) | Goals], VarTypes, ModuleInfo,
+		FollowVarsMap0, FollowVarsMap,
+		NextNonReserved0, NextNonReserved) :-
+	find_follow_vars_in_goal(Goal0, Goal1, VarTypes, ModuleInfo,
+		FollowVarsMap0, FollowVarsMap,
+		NextNonReserved0, NextNonReserved),
+	FollowVars = abs_follow_vars(FollowVarsMap, NextNonReserved),
 	goal_set_follow_vars(Goal1, yes(FollowVars), Goal),
-	find_follow_vars_in_cases(Goals0, VarTypes, ModuleInfo,
-		FollowVarsMap0, NextNonReserved,
-		Goals, _FollowVarsMap, _NextNonReserved).
+	find_follow_vars_in_cases(Goals0, Goals, VarTypes, ModuleInfo,
+		FollowVarsMap0, _FollowVarsMap,
+		NextNonReserved, _NextNonReserved).
 
 %-----------------------------------------------------------------------------%
 
 	% We attach the follow_vars to each goal that follows a goal
 	% that is not cachable by the code generator.
 
-:- pred find_follow_vars_in_conj(list(hlds_goal)::in, map(prog_var, type)::in,
-	module_info::in, bool::in, follow_vars_map::in, int::in,
-	list(hlds_goal)::out, follow_vars_map::out, int::out) is det.
-
-find_follow_vars_in_conj([], _, _ModuleInfo, _AttachToFirst,
-		FollowVarsMap, NextNonReserved,
-		[], FollowVarsMap, NextNonReserved).
-find_follow_vars_in_conj([Goal0 | Goals0], VarTypes, ModuleInfo, AttachToFirst,
-		FollowVarsMap0, NextNonReserved0,
-		[Goal | Goals], FollowVarsMap, NextNonReserved) :-
+:- pred find_follow_vars_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
+	vartypes::in, module_info::in, bool::in,
+	abs_follow_vars_map::in, abs_follow_vars_map::out,
+	int::in, int::out) is det.
+
+find_follow_vars_in_conj([], [], _, _ModuleInfo, _AttachToFirst,
+		!FollowVarsMap, !NextNonReserved).
+find_follow_vars_in_conj([Goal0 | Goals0], [Goal | Goals],
+		VarTypes, ModuleInfo, AttachToFirst,
+		!FollowVarsMap, !NextNonReserved) :-
 	(
 		Goal0 = GoalExpr0 - _,
 		(
@@ -437,15 +415,14 @@
 	;
 		AttachToNext = yes
 	),
-	find_follow_vars_in_conj(Goals0, VarTypes, ModuleInfo, AttachToNext,
-		FollowVarsMap0, NextNonReserved0,
-		Goals, FollowVarsMap1, NextNonReserved1),
-	find_follow_vars_in_goal(Goal0, VarTypes, ModuleInfo,
-		FollowVarsMap1, NextNonReserved1,
-		Goal1, FollowVarsMap, NextNonReserved),
+	find_follow_vars_in_conj(Goals0, Goals, VarTypes, ModuleInfo,
+		AttachToNext, !FollowVarsMap, !NextNonReserved),
+	find_follow_vars_in_goal(Goal0, Goal1, VarTypes, ModuleInfo,
+		!FollowVarsMap, !NextNonReserved),
 	(
 		AttachToFirst = yes,
-		FollowVars = follow_vars(FollowVarsMap, NextNonReserved),
+		FollowVars =
+			abs_follow_vars(!.FollowVarsMap, !.NextNonReserved),
 		goal_set_follow_vars(Goal1, yes(FollowVars), Goal)
 	;
 		AttachToFirst = no,
Index: compiler/hlds_llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_llds.m,v
retrieving revision 1.3
diff -u -b -r1.3 hlds_llds.m
--- compiler/hlds_llds.m	23 Mar 2004 10:52:03 -0000	1.3
+++ compiler/hlds_llds.m	1 Apr 2004 17:20:11 -0000
@@ -14,9 +14,6 @@
 :- interface.
 
 :- import_module hlds__hlds_goal.
-:- import_module ll_backend.		% XXX should make specialized types
-					% to avoid these imports
-:- import_module ll_backend__llds.
 :- import_module parse_tree__prog_data.
 
 :- import_module bool, map, set, std_util.
@@ -26,36 +23,43 @@
 % that are used only by the LLDS back-end.
 %
 
-:- type stack_slots	==	map(prog_var, lval).
+:- type stack_slot
+	--->	det_slot(int)
+	;	nondet_slot(int).
+
+:- type stack_slots	==	map(prog_var, stack_slot).
 				% 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 abs_locn
+	--->	any_reg
+	;	abs_reg(int)
+	;	abs_stackvar(int)
+	;	abs_framevar(int).
+
+:- type abs_follow_vars_map	==	map(prog_var, abs_locn).
 
-:- type follow_vars	--->	follow_vars(follow_vars_map, int).
+:- type abs_follow_vars	--->	abs_follow_vars(abs_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
+				% associated locn 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
+				% or, if the locn is any_reg, it says that it
+				% should be put into any 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).
+:- type abs_store_map	==	map(prog_var, abs_locn).
 				% 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.
+				% The final value is not allowed to map any
+				% variable to any_reg.
 
 	% see compiler/notes/allocation.html for what these alternatives mean
 :- type resume_point	--->	resume_point(set(prog_var), resume_locs)
@@ -137,10 +141,10 @@
 	set(prog_var)::out) is det.
 
 :- pred goal_info_get_follow_vars(hlds_goal_info::in,
-	maybe(follow_vars)::out) is det.
+	maybe(abs_follow_vars)::out) is det.
 
 :- pred goal_info_get_store_map(hlds_goal_info::in,
-	store_map::out) is det.
+	abs_store_map::out) is det.
 
 :- pred goal_info_get_resume_point(hlds_goal_info::in,
 	resume_point::out) is det.
@@ -169,10 +173,10 @@
 	set(prog_var)::out) is semidet.
 
 :- pred goal_info_maybe_get_follow_vars(hlds_goal_info::in,
-	maybe(follow_vars)::out) is semidet.
+	maybe(abs_follow_vars)::out) is semidet.
 
 :- pred goal_info_maybe_get_store_map(hlds_goal_info::in,
-	store_map::out) is semidet.
+	abs_store_map::out) is semidet.
 
 :- pred goal_info_maybe_get_resume_point(hlds_goal_info::in,
 	resume_point::out) is semidet.
@@ -210,10 +214,10 @@
 :- 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_follow_vars(hlds_goal_info::in,
+	maybe(abs_follow_vars)::in, hlds_goal_info::out) is det.
 
-:- pred goal_info_set_store_map(hlds_goal_info::in, store_map::in,
+:- pred goal_info_set_store_map(hlds_goal_info::in, abs_store_map::in,
 	hlds_goal_info::out) is det.
 
 :- pred goal_info_set_resume_point(hlds_goal_info::in, resume_point::in,
@@ -230,7 +234,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred goal_set_follow_vars(hlds_goal::in, maybe(follow_vars)::in,
+:- pred goal_set_follow_vars(hlds_goal::in, maybe(abs_follow_vars)::in,
 	hlds_goal::out) is det.
 
 :- pred goal_set_resume_point(hlds_goal::in, resume_point::in,
@@ -253,11 +257,18 @@
 
 %-----------------------------------------------------------------------------%
 
+:- func stack_slot_to_abs_locn(stack_slot) = abs_locn.
+:- func key_stack_slot_to_abs_locn(_, stack_slot) = abs_locn.
+
+:- func abs_locn_to_string(abs_locn) = string.
+
+%-----------------------------------------------------------------------------%
+
 :- implementation.
 
 :- import_module hlds__goal_util.
 
-:- import_module list, assoc_list, require.
+:- import_module string, list, assoc_list, require.
 
 	% For the meaning of this type, see the documentation of the
 	% maybe_need field of llds_code_gen_details below.
@@ -277,7 +288,7 @@
 			% For atomic goals, the post-deadness should be applied
 			% _before_ the goal.
 
-		follow_vars		:: maybe(follow_vars),
+		follow_vars		:: maybe(abs_follow_vars),
 			% Initially set to `no' for all goals, which
 			% means the absence of the advisory
 			% information. Can be set to `yes' by the
@@ -287,7 +298,7 @@
 			% For the semantics of the value inside a `yes',
 			% see the documentation of the follow_vars type.
 
-		store_map		:: store_map,
+		store_map		:: abs_store_map,
 			% This annotation is meaningful only after the
 			% store_alloc pass, and even then only if
 			% attached to a goal representing a branched
@@ -581,7 +592,7 @@
 		Resume = resume_point(Vars, Locs)
 	;
 		Resume = no_resume_point,
-		error("goal_info__get_resume_vars_and_loc: no resume point")
+		error("goal_info_resume_vars_and_loc: no resume point")
 	).
 
 %-----------------------------------------------------------------------------%
@@ -612,13 +623,13 @@
 		MaybeFollowVars = no
 	;
 		MaybeFollowVars0 = yes(FollowVars0),
-		FollowVars0 = follow_vars(FollowVarsMap0, FirstFreeReg),
-		rename_vars_in_var_lval_map(FollowVarsMap0, Must, Subn,
+		FollowVars0 = abs_follow_vars(FollowVarsMap0, FirstFreeReg),
+		rename_vars_in_var_locn_map(FollowVarsMap0, Must, Subn,
 			FollowVarsMap),
-		FollowVars = follow_vars(FollowVarsMap, FirstFreeReg),
+		FollowVars = abs_follow_vars(FollowVarsMap, FirstFreeReg),
 		MaybeFollowVars = yes(FollowVars)
 	),
-	rename_vars_in_var_lval_map(StoreMap0, Must, Subn, StoreMap),
+	rename_vars_in_var_locn_map(StoreMap0, Must, Subn, StoreMap),
 	(
 		ResumePoint0 = no_resume_point,
 		ResumePoint = no_resume_point
@@ -666,39 +677,36 @@
 		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)
+:- pred rename_vars_in_var_locn_map(map(prog_var, abs_locn)::in,
+	bool::in, map(prog_var, prog_var)::in, map(prog_var, abs_locn)::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).
+rename_vars_in_var_locn_map(VarLocnMap0, Must, Subn, VarLocnMap) :-
+	map__to_assoc_list(VarLocnMap0, VarLocnList0),
+	rename_vars_in_var_locn_list(VarLocnList0, Must, Subn, VarLocnList),
+	map__from_assoc_list(VarLocnList, VarLocnMap).
+
+:- pred rename_vars_in_var_locn_list(assoc_list(prog_var, abs_locn)::in,
+	bool::in, map(prog_var, prog_var)::in,
+	assoc_list(prog_var, abs_locn)::out) is det.
+
+rename_vars_in_var_locn_list([], _Must, _Subn, []).
+rename_vars_in_var_locn_list([Var0 - Locn | VarLocns0], Must, Subn,
+		[Var - Locn | VarLocns]) :-
+	rename_var(Var0, Must, Subn, Var),
+	rename_vars_in_var_locn_list(VarLocns0, Must, Subn, VarLocns).
 
-:- 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).
+stack_slot_to_abs_locn(det_slot(N)) = abs_stackvar(N).
+stack_slot_to_abs_locn(nondet_slot(N)) = abs_framevar(N).
 
-:- pred rename_vars_in_lval(lval::in, bool::in, map(prog_var, prog_var)::in,
-	lval::out) is det.
+key_stack_slot_to_abs_locn(_, Slot) =
+	stack_slot_to_abs_locn(Slot).
 
-rename_vars_in_lval(Lval0, _Must, _Subn, Lval) :-
-	(
-		( Lval0 = stackvar(_)
-		; Lval0 = framevar(_)
-		; Lval0 = reg(_, _)
-		)
-	->
-		Lval = Lval0
-	;
-		error("rename_vars_in_lval: unexpected lval")
-	).
+abs_locn_to_string(any_reg) = "any_reg".
+abs_locn_to_string(abs_reg(N)) = "r" ++ int_to_string(N).
+abs_locn_to_string(abs_stackvar(N)) = "stackvar" ++ int_to_string(N).
+abs_locn_to_string(abs_framevar(N)) = "framevar" ++ int_to_string(N).
 
 %-----------------------------------------------------------------------------%
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.327
diff -u -b -r1.327 hlds_out.m
--- compiler/hlds_out.m	5 Apr 2004 05:06:48 -0000	1.327
+++ compiler/hlds_out.m	5 Apr 2004 05:20:36 -0000
@@ -257,12 +257,6 @@
 :- import_module aditi_backend.
 :- import_module aditi_backend__rl.
 
-% LLDS back-end modules (XXX should avoid using those here).
-:- import_module ll_backend.
-:- import_module ll_backend__code_util.
-:- import_module ll_backend__llds.
-:- import_module ll_backend__llds_out.
-
 % Misc
 :- import_module backend_libs.
 :- import_module backend_libs__foreign.
@@ -1828,13 +1822,13 @@
 		goal_info_get_follow_vars(GoalInfo, MaybeFollowVars),
 		(
 			MaybeFollowVars = yes(FollowVars),
-			FollowVars = follow_vars(FollowVarsMap, NextReg),
+			FollowVars = abs_follow_vars(FollowVarsMap, NextReg),
 			map__to_assoc_list(FollowVarsMap, FVlist),
 			hlds_out__write_indent(Indent, !IO),
 			io__write_string("% follow vars: ", !IO),
 			io__write_int(NextReg, !IO),
 			io__write_string("\n", !IO),
-			hlds_out__write_var_to_lvals(FVlist, VarSet,
+			hlds_out__write_var_to_abs_locns(FVlist, VarSet,
 				AppendVarnums, Indent, !IO)
 		;
 			MaybeFollowVars = no
@@ -1874,12 +1868,12 @@
 	(
 		string__contains_char(Verbose, 's'),
 		goal_info_get_store_map(GoalInfo, StoreMap),
-		map__to_assoc_list(StoreMap, StoreMaplist),
-		StoreMaplist \= []
+		map__to_assoc_list(StoreMap, StoreMapList),
+		StoreMapList \= []
 	->
 		hlds_out__write_indent(Indent, !IO),
 		io__write_string("% store map:\n", !IO),
-		hlds_out__write_var_to_lvals(StoreMaplist, VarSet,
+		hlds_out__write_var_to_abs_locns(StoreMapList, VarSet,
 			AppendVarnums, Indent, !IO)
 	;
 		true
@@ -2853,28 +2847,25 @@
 	bool::in, io::di, io::uo) is det.
 
 hlds_out__write_stack_slots(Indent, StackSlots, VarSet, AppendVarnums, !IO) :-
-	map__to_assoc_list(StackSlots, VarSlotList),
-	hlds_out__write_var_to_lvals(VarSlotList, VarSet, AppendVarnums,
+	map__to_assoc_list(StackSlots, VarSlotList0),
+	VarSlotList = assoc_list__map_values(key_stack_slot_to_abs_locn,
+		VarSlotList0),
+	hlds_out__write_var_to_abs_locns(VarSlotList, VarSet, AppendVarnums,
 		Indent, !IO).
 
-:- pred hlds_out__write_var_to_lvals(assoc_list(prog_var, lval)::in,
+:- pred hlds_out__write_var_to_abs_locns(assoc_list(prog_var, abs_locn)::in,
 	prog_varset::in, bool::in, int::in, io::di, io::uo) is det.
 
-hlds_out__write_var_to_lvals([], _, _, _, !IO).
-hlds_out__write_var_to_lvals([Var - Loc | VarLocs], VarSet, AppendVarnums,
+hlds_out__write_var_to_abs_locns([], _, _, _, !IO).
+hlds_out__write_var_to_abs_locns([Var - Loc | VarLocs], VarSet, AppendVarnums,
 		Indent, !IO) :-
 	hlds_out__write_indent(Indent, !IO),
 	io__write_string("%\t", !IO),
 	mercury_output_var(Var, VarSet, AppendVarnums, !IO),
 	io__write_string("\t-> ", !IO),
-	( llds_out__lval_to_string(Loc, LocStrPrime) ->
-		LocStr = LocStrPrime
-	;
-		LocStr = "unknown location"
-	),
-	io__write_string(LocStr, !IO),
+	io__write_string(abs_locn_to_string(Loc), !IO),
 	io__write_string("\n", !IO),
-	hlds_out__write_var_to_lvals(VarLocs, VarSet, AppendVarnums, Indent,
+	hlds_out__write_var_to_abs_locns(VarLocs, VarSet, AppendVarnums, Indent,
 		!IO).
 
 %-----------------------------------------------------------------------------%
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.299
diff -u -b -r1.299 llds.m
--- compiler/llds.m	5 Apr 2004 05:07:39 -0000	1.299
+++ compiler/llds.m	6 Apr 2004 02:44:11 -0000
@@ -22,6 +22,7 @@
 :- import_module backend_libs__rtti.
 :- import_module hlds__code_model.
 :- import_module hlds__hlds_goal.
+:- import_module hlds__hlds_llds.
 :- import_module hlds__hlds_pred.
 :- import_module libs__tree.
 :- import_module ll_backend__layout.
@@ -651,6 +652,19 @@
 	--->	ground
 	;	partial((inst)).
 
+:- func stack_slot_to_lval(stack_slot) = lval.
+:- func key_stack_slot_to_lval(_, stack_slot) = lval.
+
+:- type lval_or_any_reg
+	--->	lval(lval)
+	;	any_reg.
+
+:- func abs_locn_to_lval_or_any_reg(abs_locn) = lval_or_any_reg.
+
+:- func abs_locn_to_lval(abs_locn) = lval.
+
+:- func key_abs_locn_to_lval(_, abs_locn) = lval.
+
 	% An lval represents a data location or register that can be used
 	% as the target of an assignment.
 :- type lval --->
@@ -947,6 +961,26 @@
 :- implementation.
 
 :- import_module require.
+
+stack_slot_to_lval(det_slot(N)) = stackvar(N).
+stack_slot_to_lval(nondet_slot(N)) = framevar(N).
+
+key_stack_slot_to_lval(_, Slot) =
+	stack_slot_to_lval(Slot).
+
+abs_locn_to_lval_or_any_reg(any_reg) = any_reg.
+abs_locn_to_lval_or_any_reg(abs_reg(N)) = lval(reg(r, N)).
+abs_locn_to_lval_or_any_reg(abs_stackvar(N)) = lval(stackvar(N)).
+abs_locn_to_lval_or_any_reg(abs_framevar(N)) = lval(framevar(N)).
+
+abs_locn_to_lval(any_reg) = _ :-
+	error("abs_locn_to_lval: any_reg").
+abs_locn_to_lval(abs_reg(N)) = reg(r, N).
+abs_locn_to_lval(abs_stackvar(N)) = stackvar(N).
+abs_locn_to_lval(abs_framevar(N)) = framevar(N).
+
+key_abs_locn_to_lval(_, AbsLocn) =
+	abs_locn_to_lval(AbsLocn).
 
 llds__stack_slot_num_to_lval(CodeModel, SlotNum) =
 	(if CodeModel = model_non then
Index: compiler/lookup_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_switch.m,v
retrieving revision 1.52
diff -u -b -r1.52 lookup_switch.m
--- compiler/lookup_switch.m	23 Mar 2004 10:52:05 -0000	1.52
+++ compiler/lookup_switch.m	1 Apr 2004 16:58:58 -0000
@@ -57,7 +57,7 @@
 :- type rval_map == map(prog_var, list(pair(int, rval))).
 
 :- pred lookup_switch__is_lookup_switch(prog_var::in, cases_list::in,
-	hlds_goal_info::in, can_fail::in, int::in, store_map::in,
+	hlds_goal_info::in, can_fail::in, int::in, abs_store_map::in,
 	branch_end::in, branch_end::out, code_model::in, int::out, int::out,
 	can_fail::out, can_fail::out, list(prog_var)::out, case_consts::out,
 	maybe(set(prog_var))::out, code_info::in, code_info::out) is semidet.
@@ -66,7 +66,7 @@
 
 :- pred lookup_switch__generate(prog_var::in, list(prog_var)::in,
 	case_consts::in, int::in, int::in, can_fail::in, can_fail::in,
-	maybe(set(prog_var))::in, store_map::in, branch_end::in,
+	maybe(set(prog_var))::in, abs_store_map::in, branch_end::in,
 	code_tree::out, code_info::in, code_info::out) is det.
 
 %-----------------------------------------------------------------------------%
@@ -205,7 +205,7 @@
 %---------------------------------------------------------------------------%
 
 :- pred lookup_switch__generate_constants(cases_list::in, list(prog_var)::in,
-	store_map::in, branch_end::in, branch_end::out, code_model::in,
+	abs_store_map::in, branch_end::in, branch_end::out, code_model::in,
 	case_consts::out, maybe(set(prog_var))::out,
 	code_info::in, code_info::out) is semidet.
 
Index: compiler/par_conj_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/par_conj_gen.m,v
retrieving revision 1.15
diff -u -b -r1.15 par_conj_gen.m
--- compiler/par_conj_gen.m	23 Mar 2004 10:52:10 -0000	1.15
+++ compiler/par_conj_gen.m	1 Apr 2004 17:15:24 -0000
@@ -113,6 +113,7 @@
 
 :- import_module check_hlds__mode_util.
 :- import_module hlds__hlds_data.
+:- import_module hlds__hlds_llds.
 :- import_module hlds__hlds_module.
 :- import_module hlds__instmap.
 :- import_module libs__globals.
@@ -191,7 +192,8 @@
 	code_info__get_stack_slots(!.CI, AllSlots),
 	code_info__get_known_variables(!.CI, Variables),
 	set__list_to_set(Variables, LiveVars),
-	map__select(AllSlots, LiveVars, StoreMap),
+	map__select(AllSlots, LiveVars, StoreMap0),
+	StoreMap = map__map_values(key_stack_slot_to_abs_locn, StoreMap0),
 	code_info__generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd,
 		SaveCode, !CI),
 	Goal = _GoalExpr - GoalInfo,
Index: compiler/stack_alloc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_alloc.m,v
retrieving revision 1.6
diff -u -b -r1.6 stack_alloc.m
--- compiler/stack_alloc.m	23 Mar 2004 10:52:12 -0000	1.6
+++ compiler/stack_alloc.m	1 Apr 2004 15:46:05 -0000
@@ -163,20 +163,19 @@
 
 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 = NumReservedSlots + 1,
 	allocate_stack_slots_2(ColourList, CodeModel, FirstVarSlot,
-		MaybeReservedVarInfo, StackSlots0, StackSlots).
+		MaybeReservedVarInfo, map__init, StackSlots).
 
 :- 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.
 
-allocate_stack_slots_2([], _, _, _, StackSlots, StackSlots).
+allocate_stack_slots_2([], _, _, _, !StackSlots).
 allocate_stack_slots_2([Vars | VarSets], CodeModel, N0, MaybeReservedVarInfo,
-		StackSlots0, StackSlots) :-
+		!StackSlots) :-
 	(
 		MaybeReservedVarInfo = yes(ResVar - ResSlotNum),
 		set__member(ResVar, Vars)
@@ -187,22 +186,22 @@
 		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_same_stack_slot(VarList, CodeModel, SlotNum, !StackSlots),
 	allocate_stack_slots_2(VarSets, CodeModel, N1, MaybeReservedVarInfo,
-		StackSlots1, StackSlots).
+		!StackSlots).
 
-:- pred allocate_same_stack_slot(list(prog_var)::in, lval::in, stack_slots::in,
-	stack_slots::out) is det.
+:- pred allocate_same_stack_slot(list(prog_var)::in, code_model::in, int::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).
+allocate_same_stack_slot([], _CodeModel, _Slot, !StackSlots).
+allocate_same_stack_slot([Var | Vars], CodeModel, Slot, !StackSlots) :-
+	( CodeModel = model_non ->
+		Locn = nondet_slot(Slot)
+	;
+		Locn = det_slot(Slot)
+	),
+	map__det_insert(!.StackSlots, Var, Locn, !:StackSlots),
+	allocate_same_stack_slot(Vars, CodeModel, Slot, !StackSlots).
 
 %-----------------------------------------------------------------------------%
Index: compiler/store_alloc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/store_alloc.m,v
retrieving revision 1.85
diff -u -b -r1.85 store_alloc.m
--- compiler/store_alloc.m	23 Mar 2004 10:52:12 -0000	1.85
+++ compiler/store_alloc.m	4 Apr 2004 15:42:54 -0000
@@ -69,11 +69,11 @@
 		find_final_follow_vars(!.ProcInfo,
 			FollowVarsMap0, NextNonReserved0),
 		proc_info_vartypes(!.ProcInfo, VarTypes),
-		find_follow_vars_in_goal(Goal0, VarTypes, ModuleInfo,
-			FollowVarsMap0, NextNonReserved0,
-			Goal1, FollowVarsMap, NextNonReserved),
+		find_follow_vars_in_goal(Goal0, Goal1, VarTypes, ModuleInfo,
+			FollowVarsMap0, FollowVarsMap,
+			NextNonReserved0, NextNonReserved),
 		Goal1 = GoalExpr1 - GoalInfo1,
-		FollowVars = follow_vars(FollowVarsMap, NextNonReserved),
+		FollowVars = abs_follow_vars(FollowVarsMap, NextNonReserved),
 		goal_info_set_follow_vars(GoalInfo1, yes(FollowVars),
 			GoalInfo2),
 		Goal2 = GoalExpr1 - GoalInfo2
@@ -92,8 +92,8 @@
 	LastLocns0 = initial_last_locns(InputArgLvals),
 	proc_info_stack_slots(!.ProcInfo, StackSlots),
 	StoreAllocInfo = store_alloc_info(ModuleInfo, StackSlots),
-	store_alloc_in_goal(Goal2, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goal, _, _),
+	store_alloc_in_goal(Goal2, Goal, Liveness0, _, LastLocns0, _,
+		ResumeVars0, StoreAllocInfo),
 	proc_info_set_goal(Goal, !ProcInfo).
 
 :- func initial_last_locns(assoc_list(prog_var, lval)) = last_locns.
@@ -117,12 +117,12 @@
 
 :- type last_locns	== map(prog_var, where_stored).
 
-:- pred store_alloc_in_goal(hlds_goal::in, liveness_info::in, set(prog_var)::in,
-	last_locns::in, store_alloc_info::in, hlds_goal::out,
-	liveness_info::out, last_locns::out) is det.
+:- pred store_alloc_in_goal(hlds_goal::in, hlds_goal::out,
+	liveness_info::in, liveness_info::out, last_locns::in, last_locns::out,
+	set(prog_var)::in, store_alloc_info::in) is det.
 
-store_alloc_in_goal(Goal0 - GoalInfo0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goal - GoalInfo, Liveness, LastLocns) :-
+store_alloc_in_goal(Goal0 - GoalInfo0, Goal - GoalInfo, Liveness0, Liveness,
+		!LastLocns, ResumeVars0, StoreAllocInfo) :-
 	% note: we must be careful to apply deaths before births
 	goal_info_get_pre_deaths(GoalInfo0, PreDeaths),
 	goal_info_get_pre_births(GoalInfo0, PreBirths),
@@ -131,17 +131,17 @@
 
 	set__difference(Liveness0,  PreDeaths, Liveness1),
 	set__union(Liveness1, PreBirths, Liveness2),
-	store_alloc_in_goal_2(Goal0, Liveness2, ResumeVars0, LastLocns0,
-		PostDeaths, StoreAllocInfo, Goal, Liveness3, LastLocns),
+	store_alloc_in_goal_2(Goal0, Goal, Liveness2, Liveness3,
+		!LastLocns, ResumeVars0, PostDeaths, StoreAllocInfo),
 	set__difference(Liveness3, PostDeaths, Liveness4),
 	% If any variables magically become live in the PostBirths,
 	% then they have to mundanely become live in a parallel goal,
 	% so we don't need to allocate anything for them here.
-	%
-	% Any variables that become magically live at the end of the goal
-	% should not be included in the store map.
 	set__union(Liveness4, PostBirths, Liveness),
 	( goal_util__goal_is_branched(Goal) ->
+		% Any variables that become magically live at the
+		% end of the goal should not be included in the store map.
+		% That is why we use Liveness4 instead of Liveness here.
 		set__union(Liveness4, ResumeVars0, MappedSet),
 		set__to_sorted_list(MappedSet, MappedVars),
 		( goal_info_maybe_get_store_map(GoalInfo0, StoreMapPrime) ->
@@ -149,8 +149,8 @@
 		;
 			AdvisoryStoreMap = map__init
 		),
-		store_alloc_allocate_storage(MappedVars, AdvisoryStoreMap,
-			StoreAllocInfo, StoreMap),
+		store_alloc_allocate_storage(MappedVars, StoreAllocInfo,
+			AdvisoryStoreMap, StoreMap),
 		goal_info_set_store_map(GoalInfo0, StoreMap, GoalInfo)
 	;
 		GoalInfo = GoalInfo0
@@ -160,74 +160,74 @@
 
 	% Here we process each of the different sorts of goals.
 
-:- pred store_alloc_in_goal_2(hlds_goal_expr::in, liveness_info::in,
-	set(prog_var)::in, last_locns::in, set(prog_var)::in,
-	store_alloc_info::in, hlds_goal_expr::out, liveness_info::out,
-	last_locns::out) is det.
-
-store_alloc_in_goal_2(conj(Goals0), Liveness0, ResumeVars0, LastLocns0,
-		_, StoreAllocInfo, conj(Goals), Liveness, LastLocns) :-
-	store_alloc_in_conj(Goals0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goals, Liveness, LastLocns).
-
-store_alloc_in_goal_2(par_conj(Goals0), Liveness0, ResumeVars0, LastLocns0,
-		_, StoreAllocInfo, par_conj(Goals), Liveness, LastLocns) :-
-	store_alloc_in_par_conj(Goals0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goals, Liveness, LastLocns).
-
-store_alloc_in_goal_2(disj(Goals0), Liveness0, ResumeVars0, LastLocns0,
-		_, StoreAllocInfo, disj(Goals), Liveness, LastLocns) :-
-	store_alloc_in_disj(Goals0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goals, Liveness, LastLocnsList),
-	merge_last_locations(LastLocnsList, LastLocns).
+:- pred store_alloc_in_goal_2(hlds_goal_expr::in, hlds_goal_expr::out,
+	liveness_info::in, liveness_info::out,
+	last_locns::in, last_locns::out, set(prog_var)::in, set(prog_var)::in,
+	store_alloc_info::in) is det.
+
+store_alloc_in_goal_2(conj(Goals0), conj(Goals), !Liveness, !LastLocns,
+		ResumeVars0, _, StoreAllocInfo) :-
+	store_alloc_in_conj(Goals0, Goals, !Liveness, !LastLocns,
+		ResumeVars0, StoreAllocInfo).
+
+store_alloc_in_goal_2(par_conj(Goals0), par_conj(Goals),
+		!Liveness, !LastLocns, ResumeVars0, _, StoreAllocInfo) :-
+	store_alloc_in_par_conj(Goals0, Goals, !Liveness, !LastLocns,
+		ResumeVars0, StoreAllocInfo).
+
+store_alloc_in_goal_2(disj(Goals0), disj(Goals), !Liveness, !LastLocns,
+		ResumeVars0, _, StoreAllocInfo) :-
+	store_alloc_in_disj(Goals0, Goals, !Liveness,
+		!.LastLocns, LastLocnsList, ResumeVars0, StoreAllocInfo),
+	merge_last_locations(LastLocnsList, !:LastLocns).
 
-store_alloc_in_goal_2(not(Goal0), Liveness0, _ResumeVars0, LastLocns0,
-		_, StoreAllocInfo, not(Goal), Liveness, LastLocns0) :-
+store_alloc_in_goal_2(not(Goal0), not(Goal), !Liveness, !LastLocns,
+		_ResumeVars0, _, StoreAllocInfo) :-
 	Goal0 = _ - GoalInfo0,
 	goal_info_get_resume_point(GoalInfo0, ResumeNot),
 	goal_info_resume_vars_and_loc(ResumeNot, ResumeNotVars, _),
-	store_alloc_in_goal(Goal0, Liveness0, ResumeNotVars, LastLocns0,
-		StoreAllocInfo, Goal, Liveness, _).
+	store_alloc_in_goal(Goal0, Goal, !Liveness, !.LastLocns, _,
+		ResumeNotVars, StoreAllocInfo).
 
-store_alloc_in_goal_2(switch(Var, Det, Cases0), Liveness0, ResumeVars0,
-		LastLocns0, _, StoreAllocInfo,
-		switch(Var, Det, Cases), Liveness, LastLocns) :-
-	store_alloc_in_cases(Cases0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Cases, Liveness, LastLocnsList),
-	merge_last_locations(LastLocnsList, LastLocns).
+store_alloc_in_goal_2(switch(Var, Det, Cases0), switch(Var, Det, Cases),
+		!Liveness, !LastLocns, ResumeVars0, _, StoreAllocInfo) :-
+	store_alloc_in_cases(Cases0, Cases, !Liveness,
+		!.LastLocns, LastLocnsList, ResumeVars0, StoreAllocInfo),
+	merge_last_locations(LastLocnsList, !:LastLocns).
 
 store_alloc_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
-		Liveness0, ResumeVars0, LastLocns0, _, StoreAllocInfo,
-		if_then_else(Vars, Cond, Then, Else), Liveness, LastLocns) :-
+		if_then_else(Vars, Cond, Then, Else),
+		Liveness0, Liveness, LastLocns0, LastLocns,
+		ResumeVars0, _, StoreAllocInfo) :-
 	Cond0 = _ - CondGoalInfo0,
 	goal_info_get_resume_point(CondGoalInfo0, ResumeCond),
 	goal_info_resume_vars_and_loc(ResumeCond, ResumeCondVars, _),
-	store_alloc_in_goal(Cond0, Liveness0, ResumeCondVars, LastLocns0,
-		StoreAllocInfo, Cond, Liveness1, LastLocnsCond),
-	store_alloc_in_goal(Then0, Liveness1, ResumeVars0, LastLocnsCond,
-		StoreAllocInfo, Then, Liveness, LastLocnsThen),
-	store_alloc_in_goal(Else0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Else, _Liveness2, LastLocnsElse),
+	store_alloc_in_goal(Cond0, Cond, Liveness0, Liveness1,
+		LastLocns0, LastLocnsCond, ResumeCondVars, StoreAllocInfo),
+	store_alloc_in_goal(Then0, Then, Liveness1, Liveness,
+		LastLocnsCond, LastLocnsThen, ResumeVars0, StoreAllocInfo),
+	store_alloc_in_goal(Else0, Else, Liveness0, _Liveness2,
+		LastLocns0, LastLocnsElse, ResumeVars0, StoreAllocInfo),
 	merge_last_locations([LastLocnsThen, LastLocnsElse], LastLocns).
 
-store_alloc_in_goal_2(some(Vars, CanRemove, Goal0), Liveness0, ResumeVars0,
-		LastLocns0, _, StoreAllocInfo,
-		some(Vars, CanRemove, Goal), Liveness, LastLocns) :-
-	store_alloc_in_goal(Goal0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goal, Liveness, LastLocns).
-
-store_alloc_in_goal_2(generic_call(A, B, C, D), Liveness, _, LastLocns,
-		_, _, generic_call(A, B, C, D), Liveness, LastLocns).
-
-store_alloc_in_goal_2(call(A, B, C, D, E, F), Liveness, _, LastLocns,
-		_, _, call(A, B, C, D, E, F), Liveness, LastLocns).
-
-store_alloc_in_goal_2(unify(A,B,C,D,E), Liveness, _, LastLocns,
-		_, _, unify(A,B,C,D,E), Liveness, LastLocns).
-
-store_alloc_in_goal_2(foreign_proc(A, B, C, D, E, F, G), Liveness, _,
-		LastLocns, _, _, foreign_proc(A, B, C, D, E, F, G),
-		Liveness, LastLocns).
+store_alloc_in_goal_2(some(Vars, CanRemove, Goal0),
+		some(Vars, CanRemove, Goal), !Liveness, !LastLocns,
+		ResumeVars0, _, StoreAllocInfo) :-
+	store_alloc_in_goal(Goal0, Goal, !Liveness, !LastLocns,
+		ResumeVars0, StoreAllocInfo).
+
+store_alloc_in_goal_2(generic_call(A, B, C, D), generic_call(A, B, C, D),
+		!Liveness, !LastLocns, _, _, _).
+
+store_alloc_in_goal_2(call(A, B, C, D, E, F), call(A, B, C, D, E, F),
+		!Liveness, !LastLocns, _, _, _).
+
+store_alloc_in_goal_2(unify(A, B, C, D, E), unify(A, B, C, D, E),
+		!Liveness, !LastLocns, _, _, _).
+
+store_alloc_in_goal_2(foreign_proc(A, B, C, D, E, F, G),
+		foreign_proc(A, B, C, D, E, F, G), !Liveness, !LastLocns,
+		_, _, _).
 
 store_alloc_in_goal_2(shorthand(_), _, _, _, _, _, _, _, _) :-
 	% these should have been expanded out by now
@@ -235,56 +235,55 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred store_alloc_in_conj(list(hlds_goal)::in, liveness_info::in,
-	set(prog_var)::in, last_locns::in, store_alloc_info::in,
-	list(hlds_goal)::out, liveness_info::out, last_locns::out) is det.
-
-store_alloc_in_conj([], Liveness, _, LastLocns, _, [], Liveness, LastLocns).
-store_alloc_in_conj([Goal0 | Goals0], Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, [Goal | Goals], Liveness, LastLocns) :-
+:- pred store_alloc_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
+	liveness_info::in, liveness_info::out, last_locns::in, last_locns::out,
+	set(prog_var)::in, store_alloc_info::in) is det.
+
+store_alloc_in_conj([], [], !Liveness, !LastLocns, _, _).
+store_alloc_in_conj([Goal0 | Goals0], [Goal | Goals], !Liveness, !LastLocns,
+		ResumeVars0, StoreAllocInfo) :-
 	(
 			% XXX should be threading the instmap
 		Goal0 = _ - GoalInfo,
 		goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
 		instmap_delta_is_unreachable(InstMapDelta)
 	->
-		store_alloc_in_goal(Goal0, Liveness0, ResumeVars0, LastLocns0,
-			StoreAllocInfo, Goal, Liveness, LastLocns),
+		store_alloc_in_goal(Goal0, Goal, !Liveness, !LastLocns,
+			ResumeVars0, StoreAllocInfo),
 		Goals = Goals0
 	;
-		store_alloc_in_goal(Goal0, Liveness0, ResumeVars0, LastLocns0,
-			StoreAllocInfo, Goal, Liveness1, LastLocns1),
-		store_alloc_in_conj(Goals0, Liveness1, ResumeVars0, LastLocns1,
-			StoreAllocInfo, Goals, Liveness, LastLocns)
+		store_alloc_in_goal(Goal0, Goal, !Liveness, !LastLocns,
+			ResumeVars0, StoreAllocInfo),
+		store_alloc_in_conj(Goals0, Goals, !Liveness, !LastLocns,
+			ResumeVars0, StoreAllocInfo)
 	).
 
 %-----------------------------------------------------------------------------%
 
-:- pred store_alloc_in_par_conj(list(hlds_goal)::in, liveness_info::in,
-	set(prog_var)::in, last_locns::in, store_alloc_info::in,
-	list(hlds_goal)::out, liveness_info::out, last_locns::out) is det.
-
-store_alloc_in_par_conj([], Liveness, _, LastLocns, _,
-		[], Liveness, LastLocns).
-store_alloc_in_par_conj([Goal0 | Goals0], Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, [Goal | Goals], Liveness, LastLocns) :-
+:- pred store_alloc_in_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
+	liveness_info::in, liveness_info::out, last_locns::in, last_locns::out,
+	set(prog_var)::in, store_alloc_info::in) is det.
+
+store_alloc_in_par_conj([], [], !Liveness, !LastLocns, _, _).
+store_alloc_in_par_conj([Goal0 | Goals0], [Goal | Goals], Liveness0, Liveness,
+		!LastLocns, ResumeVars0, StoreAllocInfo) :-
 	% XXX ignoring _Liveness1 looks fishy
-	store_alloc_in_goal(Goal0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goal, Liveness, LastLocns1),
-	store_alloc_in_par_conj(Goals0, Liveness0, ResumeVars0, LastLocns1,
-		StoreAllocInfo, Goals, _Liveness1, LastLocns).
+	store_alloc_in_goal(Goal0, Goal, Liveness0, Liveness,
+		!LastLocns, ResumeVars0, StoreAllocInfo),
+	store_alloc_in_par_conj(Goals0, Goals, Liveness0, _Liveness1,
+		!LastLocns, ResumeVars0, StoreAllocInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred store_alloc_in_disj(list(hlds_goal)::in, liveness_info::in,
-	set(prog_var)::in, last_locns::in, store_alloc_info::in,
-	list(hlds_goal)::out, liveness_info::out, list(last_locns)::out)
-	is det.
-
-store_alloc_in_disj([], Liveness, _, _, _, [], Liveness, []).
-store_alloc_in_disj([Goal0 | Goals0], Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, [Goal | Goals], Liveness,
-		[LastLocnsGoal | LastLocnsDisj]) :-
+:- pred store_alloc_in_disj(list(hlds_goal)::in, list(hlds_goal)::out,
+	liveness_info::in, liveness_info::out,
+	last_locns::in, list(last_locns)::out,
+	set(prog_var)::in, store_alloc_info::in) is det.
+
+store_alloc_in_disj([], [], !Liveness, _, [], _, _).
+store_alloc_in_disj([Goal0 | Goals0], [Goal | Goals], Liveness0, Liveness,
+		LastLocns0, [LastLocnsGoal | LastLocnsDisj],
+		ResumeVars0, StoreAllocInfo) :-
 	Goal0 = _ - GoalInfo0,
 	goal_info_get_resume_point(GoalInfo0, ResumeGoal),
 	(
@@ -293,25 +292,27 @@
 	;
 		ResumeGoal = resume_point(ResumeGoalVars, _)
 	),
-	store_alloc_in_goal(Goal0, Liveness0, ResumeGoalVars, LastLocns0,
-		StoreAllocInfo, Goal, Liveness, LastLocnsGoal),
-	store_alloc_in_disj(Goals0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goals, _Liveness1, LastLocnsDisj).
+	store_alloc_in_goal(Goal0, Goal, Liveness0, Liveness,
+		LastLocns0, LastLocnsGoal, ResumeGoalVars, StoreAllocInfo),
+	store_alloc_in_disj(Goals0, Goals, Liveness0, _Liveness1,
+		LastLocns0, LastLocnsDisj, ResumeVars0, StoreAllocInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- pred store_alloc_in_cases(list(case)::in, liveness_info::in,
-	set(prog_var)::in, last_locns::in, store_alloc_info::in,
-	list(case)::out, liveness_info::out, list(last_locns)::out) is det.
-
-store_alloc_in_cases([], Liveness, _, _, _, [], Liveness, []).
-store_alloc_in_cases([case(Cons, Goal0) | Goals0], Liveness0, ResumeVars0,
-		LastLocns0, StoreAllocInfo, [case(Cons, Goal) | Goals],
-		Liveness, [LastLocnsGoal | LastLocnsCases]) :-
-	store_alloc_in_goal(Goal0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goal, Liveness, LastLocnsGoal),
-	store_alloc_in_cases(Goals0, Liveness0, ResumeVars0, LastLocns0,
-		StoreAllocInfo, Goals, _Liveness1, LastLocnsCases).
+:- pred store_alloc_in_cases(list(case)::in, list(case)::out,
+	liveness_info::in, liveness_info::out,
+	last_locns::in, list(last_locns)::out,
+	set(prog_var)::in, store_alloc_info::in) is det.
+
+store_alloc_in_cases([], [], !Liveness, _, [], _, _). 
+store_alloc_in_cases([case(Cons, Goal0) | Goals0], [case(Cons, Goal) | Goals],
+		Liveness0, Liveness,
+		LastLocns0, [LastLocnsGoal | LastLocnsCases],
+		ResumeVars0, StoreAllocInfo) :-
+	store_alloc_in_goal(Goal0, Goal, Liveness0, Liveness,
+		LastLocns0, LastLocnsGoal, ResumeVars0, StoreAllocInfo),
+	store_alloc_in_cases(Goals0, Goals, Liveness0, _Liveness1,
+		LastLocns0, LastLocnsCases, ResumeVars0, StoreAllocInfo).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -341,14 +342,15 @@
 	% generate a store map that maps every live variable to its own
 	% real location.
 
-:- pred store_alloc_allocate_storage(list(prog_var)::in, store_map::in,
-	store_alloc_info::in, store_map::out) is det.
+:- pred store_alloc_allocate_storage(list(prog_var)::in, store_alloc_info::in,
+	abs_store_map::in, abs_store_map::out) is det.
 
-store_alloc_allocate_storage(LiveVars, FollowVars, StoreAllocInfo, StoreMap) :-
+store_alloc_allocate_storage(LiveVars, StoreAllocInfo, FollowVars, StoreMap) :-
 
 	% This addresses point 1
 	map__keys(FollowVars, FollowKeys),
-	store_alloc_remove_nonlive(FollowKeys, LiveVars, FollowVars, StoreMap0),
+	store_alloc_remove_nonlive(FollowKeys, LiveVars, FollowVars,
+		StoreMap0),
 
 	% This addresses points 3 and 4
 	map__keys(StoreMap0, StoreVars),
@@ -360,107 +362,83 @@
 	store_alloc_allocate_extras(LiveVars, N, SeenLvals, StoreAllocInfo,
 		StoreMap1, StoreMap).
 
-:- pred store_alloc_remove_nonlive(list(prog_var), list(prog_var),
-		store_map, store_map).
-:- mode store_alloc_remove_nonlive(in, in, in, out) is det.
+:- pred store_alloc_remove_nonlive(list(prog_var)::in, list(prog_var)::in,
+	abs_store_map::in, abs_store_map::out) is det.
 
-store_alloc_remove_nonlive([], _LiveVars, StoreMap, StoreMap).
-store_alloc_remove_nonlive([Var | Vars], LiveVars, StoreMap0, StoreMap) :-
+store_alloc_remove_nonlive([], _LiveVars, !StoreMap).
+store_alloc_remove_nonlive([Var | Vars], LiveVars, !StoreMap) :-
 	( list__member(Var, LiveVars) ->
-		StoreMap1 = StoreMap0
+		true
 	;
-		map__delete(StoreMap0, Var, StoreMap1)
+		map__delete(!.StoreMap, Var, !:StoreMap)
 	),
-	store_alloc_remove_nonlive(Vars, LiveVars, StoreMap1, StoreMap).
+	store_alloc_remove_nonlive(Vars, LiveVars, !StoreMap).
 
-:- pred store_alloc_handle_conflicts_and_nonreal(list(prog_var),
-	int, int, set(lval), set(lval), store_map, store_map).
-:- mode store_alloc_handle_conflicts_and_nonreal(in, in, out, in, out, in, out)
-	is det.
-
-store_alloc_handle_conflicts_and_nonreal([], N, N, SeenLvals, SeenLvals,
-		StoreMap, StoreMap).
-store_alloc_handle_conflicts_and_nonreal([Var | Vars], N0, N,
-		SeenLvals0, SeenLvals, StoreMap0, StoreMap) :-
-	map__lookup(StoreMap0, Var, Lval),
+:- pred store_alloc_handle_conflicts_and_nonreal(list(prog_var)::in,
+	int::in, int::out, set(abs_locn)::in, set(abs_locn)::out,
+	abs_store_map::in, abs_store_map::out) is det.
+
+store_alloc_handle_conflicts_and_nonreal([], !N, !SeenLocns, !StoreMap).
+store_alloc_handle_conflicts_and_nonreal([Var | Vars], !N, !SeenLocns,
+		!StoreMap) :-
+	map__lookup(!.StoreMap, Var, Locn),
 	(
-		( artificial_lval(Lval)
-		; set__member(Lval, SeenLvals0)
+		( Locn = any_reg
+		; set__member(Locn, !.SeenLocns)
 		)
 	->
-		next_free_reg(N0, SeenLvals0, N1),
-		FinalLval = reg(r, N1),
-		map__det_update(StoreMap0, Var, FinalLval, StoreMap1)
-	;
-		N1 = N0,
-		FinalLval = Lval,
-		StoreMap1 = StoreMap0
+		next_free_reg(!.SeenLocns, !N),
+		FinalLocn = abs_reg(!.N),
+		map__det_update(!.StoreMap, Var, FinalLocn, !:StoreMap)
+	;
+		FinalLocn = Locn
 	),
-	set__insert(SeenLvals0, FinalLval, SeenLvals1),
-	store_alloc_handle_conflicts_and_nonreal(Vars, N1, N,
-		SeenLvals1, SeenLvals, StoreMap1, StoreMap).
-
-:- pred store_alloc_allocate_extras(list(prog_var), int, set(lval),
-		store_alloc_info, store_map, store_map).
-:- mode store_alloc_allocate_extras(in, in, in, in, in, out) is det.
-
-store_alloc_allocate_extras([], _, _, _, StoreMap, StoreMap).
-store_alloc_allocate_extras([Var | Vars], N0, SeenLvals0, StoreAllocInfo,
-		StoreMap0, StoreMap) :-
-	(
-		map__contains(StoreMap0, Var)
-	->
+	set__insert(!.SeenLocns, FinalLocn, !:SeenLocns),
+	store_alloc_handle_conflicts_and_nonreal(Vars, !N, !SeenLocns,
+		!StoreMap).
+
+:- pred store_alloc_allocate_extras(list(prog_var)::in, int::in,
+	set(abs_locn)::in, store_alloc_info::in,
+	abs_store_map::in, abs_store_map::out) is det.
+
+store_alloc_allocate_extras([], _, _, _, !StoreMap).
+store_alloc_allocate_extras([Var | Vars], !.N, !.SeenLocns, StoreAllocInfo,
+		!StoreMap) :-
+	( map__contains(!.StoreMap, Var) ->
 		% We have already allocated a slot for this variable.
-		N1 = N0,
-		StoreMap1 = StoreMap0,
-		SeenLvals1 = SeenLvals0
+		true
 	;
 		% We have not yet allocated a slot for this variable,
 		% which means it is not in the follow vars (if any).
 		StoreAllocInfo = store_alloc_info(_, StackSlots),
 		(
 			map__search(StackSlots, Var, StackSlot),
-			\+ set__member(StackSlot, SeenLvals0)
+			StackSlotLocn = stack_slot_to_abs_locn(StackSlot),
+			\+ set__member(StackSlotLocn, !.SeenLocns)
 			% Follow_vars was run, so the only
 			% reason why a var would not be in the
 			% follow_vars set is if it was supposed to
 			% be in its stack slot.
 		->
-			Locn = StackSlot,
-			N1 = N0
+			Locn = StackSlotLocn
 		;
-			next_free_reg(N0, SeenLvals0, N1),
-			Locn = reg(r, N1)
+			next_free_reg(!.SeenLocns, !N),
+			Locn = abs_reg(!.N)
 		),
-		map__det_insert(StoreMap0, Var, Locn, StoreMap1),
-		set__insert(SeenLvals0, Locn, SeenLvals1)
+		map__det_insert(!.StoreMap, Var, Locn, !:StoreMap),
+		set__insert(!.SeenLocns, Locn, !:SeenLocns)
 	),
-	store_alloc_allocate_extras(Vars, N1, SeenLvals1, StoreAllocInfo,
-		StoreMap1, StoreMap).
-
-%-----------------------------------------------------------------------------%
-
-	% The follow_vars pass maps some variables r(-1) as a hint to the
-	% code generator to put them in any free register. Since store maps
-	% require real locations, we can't use such hints directly.
-
-	% For robustness, we check for N < 1 instead of N = -1.
-
-:- pred artificial_lval(lval).
-:- mode artificial_lval(in) is semidet.
-
-artificial_lval(reg(_Type, Num)) :-
-	Num < 1.
+	store_alloc_allocate_extras(Vars, !.N, !.SeenLocns, StoreAllocInfo,
+		!StoreMap).
 
 %-----------------------------------------------------------------------------%
 
-:- pred next_free_reg(int, set(lval), int).
-:- mode next_free_reg(in, in, out) is det.
+:- pred next_free_reg(set(abs_locn)::in, int::in, int::out) is det.
 
-next_free_reg(N0, Values, N) :-
-	( set__member(reg(r, N0), Values) ->
+next_free_reg(Values, N0, N) :-
+	( set__member(abs_reg(N0), Values) ->
 		N1 = N0 + 1,
-		next_free_reg(N1, Values, N)
+		next_free_reg(Values, N1, N)
 	;
 		N = N0
 	).
Index: compiler/var_locn.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/var_locn.m,v
retrieving revision 1.17
diff -u -b -r1.17 var_locn.m
--- compiler/var_locn.m	19 Mar 2004 10:19:27 -0000	1.17
+++ compiler/var_locn.m	1 Apr 2004 17:46:50 -0000
@@ -30,8 +30,9 @@
 
 :- type var_locn_info.
 
-%	var_locn__init_state(Arguments, Liveness, Varset,
-%			StackSlots, FollowVars, Opts, VarLocnInfo)
+%	var_locn__init_state(Arguments, Liveness, Varset, StackSlots,
+%		FollowVars, Opts, VarLocnInfo)
+%
 %		Produces an initial state of the VarLocnInfo given
 %		an association list of variables and lvalues. The initial
 %		state places the given variables at their corresponding
@@ -47,8 +48,8 @@
 %		are considered constants.
 
 :- pred var_locn__init_state(assoc_list(prog_var, lval)::in, set(prog_var)::in,
-	prog_varset::in, stack_slots::in, follow_vars::in, option_table::in,
-	var_locn_info::out) is det.
+	prog_varset::in, stack_slots::in, abs_follow_vars::in,
+	option_table::in, var_locn_info::out) is det.
 
 %	var_locn__reinit_state(VarLocs, VarLocnInfo0, VarLocnInfo)
 %		Produces a new state of the VarLocnInfo in which the static
@@ -311,8 +312,8 @@
 %		Returns the table mapping each variable to the lval (if any)
 %		where it is desired next.
 
-:- pred var_locn__get_follow_var_map(var_locn_info::in, follow_vars_map::out)
-	is det.
+:- pred var_locn__get_follow_var_map(var_locn_info::in,
+	abs_follow_vars_map::out) is det.
 
 %	var_locn__get_next_non_reserved(VarLocnInfo, NonRes)
 %		Returns the number of the first register which is free for
@@ -325,7 +326,7 @@
 %		where it is desired next, and the number of the first
 %		non-reserved register.
 
-:- pred var_locn__set_follow_vars(follow_vars::in,
+:- pred var_locn__set_follow_vars(abs_follow_vars::in,
 	var_locn_info::in, var_locn_info::out) is det.
 
 %	var_locn__max_reg_in_use(MaxReg)
@@ -420,7 +421,7 @@
 						% that are relevant to
 						% decisions about which rvals
 						% are constants.
-		follow_vars_map	:: follow_vars_map,
+		follow_vars_map	:: abs_follow_vars_map,
 						% Where vars are needed next.
 		next_non_res	:: int,		% Next register that is not
 						% reserved in follow_vars_map.
@@ -452,14 +453,14 @@
 
 %----------------------------------------------------------------------------%
 
-var_locn__init_state(VarLocs, Liveness, Varset, StackSlots, FollowVars,
-		Options, VarLocnInfo) :-
+var_locn__init_state(VarLocs, Liveness, Varset, StackSlots,
+		FollowVars, Options, VarLocnInfo) :-
 	map__init(VarStateMap0),
 	map__init(LocVarMap0),
 	var_locn__init_state_2(VarLocs, yes(Liveness),
 		VarStateMap0, VarStateMap, LocVarMap0, LocVarMap),
 	exprn_aux__init_exprn_opts(Options, ExprnOpts),
-	FollowVars = follow_vars(FollowVarMap, NextNonReserved),
+	FollowVars = abs_follow_vars(FollowVarMap, NextNonReserved),
 	set__init(AcquiredRegs),
 	VarLocnInfo = var_locn_info(Varset, StackSlots, ExprnOpts,
 		FollowVarMap, NextNonReserved, VarStateMap, LocVarMap,
@@ -1651,11 +1652,14 @@
 var_locn__select_preferred_reg(VLI, Var, CheckInUse, Avoid, Lval) :-
 	var_locn__get_follow_var_map(VLI, FollowVarMap),
 	(
-		map__search(FollowVarMap, Var, PrefLval),
-		PrefLval = reg(_, _)
+		map__search(FollowVarMap, Var, PrefLocn),
+		( PrefLocn = abs_reg(_)
+		; PrefLocn = any_reg
+		)
 	->
 		(
-			real_lval(PrefLval),
+			PrefLocn = abs_reg(N),
+			PrefLval = reg(r, N),
 			( CheckInUse = yes ->
 				\+ var_locn__lval_in_use(VLI, PrefLval)
 			;
@@ -1693,11 +1697,14 @@
 var_locn__select_preferred_reg_or_stack(VLI, Var, Lval, CheckInUse) :-
 	var_locn__get_follow_var_map(VLI, FollowVarMap),
 	(
-		map__search(FollowVarMap, Var, PrefLval),
-		PrefLval = reg(_, _)
+		map__search(FollowVarMap, Var, PrefLocn),
+		( PrefLocn = abs_reg(_)
+		; PrefLocn = any_reg
+		)
 	->
 		(
-			real_lval(PrefLval),
+			PrefLocn = abs_reg(N),
+			PrefLval = reg(r, N),
 			( CheckInUse = yes ->
 				\+ var_locn__lval_in_use(VLI, PrefLval)
 			;
@@ -1711,7 +1718,8 @@
 	;
 		(
 			var_locn__get_stack_slots(VLI, StackSlots),
-			map__search(StackSlots, Var, StackSlot),
+			map__search(StackSlots, Var, StackSlotLocn),
+			StackSlot = stack_slot_to_lval(StackSlotLocn),
 			( CheckInUse = yes ->
 				\+ var_locn__lval_in_use(VLI, StackSlot)
 			;
@@ -2242,7 +2250,8 @@
 
 %----------------------------------------------------------------------------%
 
-var_locn__set_follow_vars(follow_vars(FollowVarMap, NextNonReserved), !VLI) :-
+var_locn__set_follow_vars(FollowVars, !VLI) :-
+	FollowVars = abs_follow_vars(FollowVarMap, NextNonReserved),
 	var_locn__set_follow_var_map(FollowVarMap, !VLI),
 	var_locn__set_next_non_reserved(NextNonReserved, !VLI).
 
@@ -2281,7 +2290,7 @@
 :- pred var_locn__set_varset(prog_varset::in,
 	var_locn_info::in, var_locn_info::out) is det.
 
-:- pred var_locn__set_follow_var_map(follow_vars_map::in,
+:- pred var_locn__set_follow_var_map(abs_follow_vars_map::in,
 	var_locn_info::in, var_locn_info::out) is det.
 
 :- pred var_locn__set_next_non_reserved(int::in,
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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