[m-dev.] for review: update alias branch [2]

Simon Taylor stayl at cs.mu.OZ.AU
Tue May 4 15:55:47 AEST 1999


-----------------------------------------------------------------------------
The diffs for the following modules are relative to the alias branch:
-----------------------------------------------------------------------------

Index: code_info.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/code_info.m,v
retrieving revision 1.211.2.20
diff -u -u -r1.211.2.20 code_info.m
--- code_info.m	1998/11/24 06:27:21	1.211.2.20
+++ code_info.m	1999/05/03 06:32:25
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1994-1998 The University of Melbourne.
+% Copyright (C) 1994-1999 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %---------------------------------------------------------------------------%
@@ -36,10 +36,10 @@
 
 :- implementation.
 
-:- import_module code_util, code_exprn, prog_out, inst_match.
+:- import_module code_util, code_exprn, llds_out, prog_out, inst_match.
 :- import_module arg_info, type_util, mode_util, options.
-:- import_module term, varset.
 
+:- import_module term, varset.
 :- import_module set, stack.
 :- import_module string, require, char, bimap, tree, int.
 
@@ -65,11 +65,10 @@
 		% Create a new code_info structure. Also return the
 		% outermost resumption point, and info about the non-fixed
 		% stack slots used for tracing purposes.
-:- pred code_info__init(prog_varset, set(prog_var), stack_slots, bool, globals,
-	pred_id, proc_id, proc_info, instmap, follow_vars, module_info,
-	int, resume_point_info, trace_slot_info, code_info).
-:- mode code_info__init(in, in, in, in, in, in, in, in, in, in, in, in,
-	out, out, out) is det.
+:- pred code_info__init(bool, globals, pred_id, proc_id, proc_info,
+	follow_vars, module_info, int, resume_point_info,
+	trace_slot_info, code_info).
+:- mode code_info__init(in, in, in, in, in, in, in, in, out, out, out) is det.
 
 		% Get the globals table.
 :- pred code_info__get_globals(globals, code_info, code_info).
@@ -123,14 +122,27 @@
 :- pred code_info__get_cell_count(int, code_info, code_info).
 :- mode code_info__get_cell_count(out, in, out) is det.
 
+:- pred code_info__set_cell_count(int, code_info, code_info).
+:- mode code_info__set_cell_count(in, in, out) is det.
+
 		% Get the flag that indicates whether succip is used or not.
 :- pred code_info__get_succip_used(bool, code_info, code_info).
 :- mode code_info__get_succip_used(out, in, out) is det.
 
+		% Get the label layout information created by tracing
+		% during code generation.
 :- pred code_info__get_layout_info(map(label, internal_layout_info), 
 	code_info, code_info).
 :- mode code_info__get_layout_info(out, in, out) is det.
 
+		% Get the global static data structures that have
+		% been created during code generation and which do
+		% not have to be scanned by llds_common, since they
+		% have no common parts by construction.
+:- pred code_info__get_non_common_static_data(list(comp_gen_c_data),
+	code_info, code_info).
+:- mode code_info__get_non_common_static_data(out, in, out) is det.
+
 %---------------------------------------------------------------------------%
 
 :- implementation.
@@ -172,9 +184,6 @@
 :- pred code_info__set_label_count(int, code_info, code_info).
 :- mode code_info__set_label_count(in, in, out) is det.
 
-:- pred code_info__set_cell_count(int, code_info, code_info).
-:- mode code_info__set_cell_count(in, in, out) is det.
-
 :- pred code_info__set_succip_used(bool, code_info, code_info).
 :- mode code_info__set_succip_used(in, in, out) is det.
 
@@ -196,6 +205,10 @@
 	code_info, code_info).
 :- mode code_info__set_temp_content_map(in, in, out) is det.
 
+:- pred code_info__set_non_common_static_data(list(comp_gen_c_data),
+	code_info, code_info).
+:- mode code_info__set_non_common_static_data(in, in, out) is det.
+
 %---------------------------------------------------------------------------%
 
 	% The code_info structure has three groups of fields.
@@ -263,7 +276,7 @@
 		int,		% The maximum number of extra
 				% temporary stackslots that have been
 				% used during the procedure.
-		map(lval, slot_contents)
+		map(lval, slot_contents),
 				% The temporary locations that have ever been
 				% used on the stack, and what they contain.
 				% Once we have used a stack slot to store
@@ -274,20 +287,27 @@
 				% which would make it impossible to describe
 				% to gc what the slot contains after the end
 				% of the branched control structure.
+		list(comp_gen_c_data)
+				% Static data structures created for this
+				% procedure which do not need to be scanned
+				% by llds_common.
 	).
 
 %---------------------------------------------------------------------------%
 
-code_info__init(Varset, Liveness, StackSlots, SaveSuccip, Globals,
-		PredId, ProcId, ProcInfo, Instmap, FollowVars, ModuleInfo,
-		CellCount, ResumePoint, TraceSlotInfo, CodeInfo) :-
+code_info__init(SaveSuccip, Globals, PredId, ProcId, ProcInfo, FollowVars,
+		ModuleInfo, CellCount, ResumePoint, TraceSlotInfo, CodeInfo) :-
+	proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap),
+	proc_info_liveness_info(ProcInfo, Liveness),
 	proc_info_headvars(ProcInfo, HeadVars),
 	proc_info_arg_info(ProcInfo, ArgInfos),
 	proc_info_interface_code_model(ProcInfo, CodeModel),
 	assoc_list__from_corresponding_lists(HeadVars, ArgInfos, Args),
 	arg_info__build_input_arg_list(Args, ArgList),
 	globals__get_options(Globals, Options),
-	code_exprn__init_state(ArgList, Varset, StackSlots, FollowVars,
+	proc_info_varset(ProcInfo, VarSet),
+	proc_info_stack_slots(ProcInfo, StackSlots),
+	code_exprn__init_state(ArgList, VarSet, StackSlots, FollowVars,
 		Options, ExprnInfo),
 	stack__init(ResumePoints),
 	globals__lookup_bool_option(Globals, allow_hijacks, AllowHijack),
@@ -313,12 +333,12 @@
 		PredId,
 		ProcId,
 		ProcInfo,
-		Varset,
+		VarSet,
 		SlotMax,
 		no,
 
 		Liveness,
-		Instmap,
+		InstMap,
 		Zombies,
 		ExprnInfo,
 		TempsInUse,
@@ -329,7 +349,8 @@
 		SaveSuccip,
 		LayoutMap,
 		0,
-		TempContentMap
+		TempContentMap,
+		[]
 	),
 	code_info__init_maybe_trace_info(Globals, ModuleInfo, ProcInfo,
 		MaybeFailVars, TraceSlotInfo, CodeInfo0, CodeInfo1),
@@ -357,163 +378,173 @@
 
 code_info__get_globals(SA, CI, CI) :-
 	CI  = code_info(SA, _, _, _, _, _, _, _,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_module_info(SB, CI, CI) :-
 	CI  = code_info(_, SB, _, _, _, _, _, _,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_pred_id(SC, CI, CI) :-
 	CI  = code_info(_, _, SC, _, _, _, _, _,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_proc_id(SD, CI, CI) :-
 	CI  = code_info(_, _, _, SD, _, _, _, _,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_proc_info(SE, CI, CI) :-
 	CI  = code_info(_, _, _, _, SE, _, _, _,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_varset(SF, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, SF, _, _,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_var_slot_count(SG, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, SG, _,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_maybe_trace_info(SH, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, SH,
-		_, _, _, _, _, _, _, _, _, _, _, _).
+		_, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_forward_live_vars(LA, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		LA, _, _, _, _, _, _, _, _, _, _, _).
+		LA, _, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_instmap(LB, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, LB, _, _, _, _, _, _, _, _, _, _).
+		_, LB, _, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_zombies(LC, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, LC, _, _, _, _, _, _, _, _, _).
+		_, _, LC, _, _, _, _, _, _, _, _, _, _).
 
 code_info__get_exprn_info(LD, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, LD, _, _, _, _, _, _, _, _).
+		_, _, _, LD, _, _, _, _, _, _, _, _, _).
 
 code_info__get_temps_in_use(LE, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, LE, _, _, _, _, _, _, _).
+		_, _, _, _, LE, _, _, _, _, _, _, _, _).
 
 code_info__get_fail_info(LF, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, _, LF, _, _, _, _, _, _).
+		_, _, _, _, _, LF, _, _, _, _, _, _, _).
 
 code_info__get_label_count(PA, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, _, _, PA, _, _, _, _, _).
+		_, _, _, _, _, _, PA, _, _, _, _, _, _).
 
 code_info__get_cell_count(PB, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, _, _, _, PB, _, _, _, _).
+		_, _, _, _, _, _, _, PB, _, _, _, _, _).
 
 code_info__get_succip_used(PC, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, _, _, _, _, PC, _, _, _).
+		_, _, _, _, _, _, _, _, PC, _, _, _, _).
 
 code_info__get_layout_info(PD, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, _, _, _, _, _, PD, _, _).
+		_, _, _, _, _, _, _, _, _, PD, _, _, _).
 
 code_info__get_max_temp_slot_count(PE, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, _, _, _, _, _, _, PE, _).
+		_, _, _, _, _, _, _, _, _, _, PE, _, _).
 
 code_info__get_temp_content_map(PF, CI, CI) :-
 	CI  = code_info(_, _, _, _, _, _, _, _,
-		_, _, _, _, _, _, _, _, _, _, _, PF).
+		_, _, _, _, _, _, _, _, _, _, _, PF, _).
+
+code_info__get_non_common_static_data(PG, CI, CI) :-
+	CI  = code_info(_, _, _, _, _, _, _, _,
+		_, _, _, _, _, _, _, _, _, _, _, _, PG).
 
 %---------------------------------------------------------------------------%
 
 code_info__set_maybe_trace_info(SH, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, _,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF),
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_forward_live_vars(LA, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		_,  LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF),
+		_,  LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_instmap(LB, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, _,  LC, LD, LE, LF, PA, PB, PC, PD, PE, PF),
+		LA, _,  LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_zombies(LC, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, _,  LD, LE, LF, PA, PB, PC, PD, PE, PF),
+		LA, LB, _,  LD, LE, LF, PA, PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_exprn_info(LD, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, _,  LE, LF, PA, PB, PC, PD, PE, PF),
+		LA, LB, LC, _,  LE, LF, PA, PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_temps_in_use(LE, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, _,  LF, PA, PB, PC, PD, PE, PF),
+		LA, LB, LC, LD, _,  LF, PA, PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_fail_info(LF, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, _,  PA, PB, PC, PD, PE, PF),
+		LA, LB, LC, LD, LE, _,  PA, PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_label_count(PA, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, _,  PB, PC, PD, PE, PF),
+		LA, LB, LC, LD, LE, LF, _,  PB, PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_cell_count(PB, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, _,  PC, PD, PE, PF),
+		LA, LB, LC, LD, LE, LF, PA, _,  PC, PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_succip_used(PC, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, _,  PD, PE, PF),
+		LA, LB, LC, LD, LE, LF, PA, PB, _,  PD, PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_layout_info(PD, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, _,  PE, PF),
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, _,  PE, PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_max_temp_slot_count(PE, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, _,  PF),
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, _,  PF, PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__set_temp_content_map(PF, CI0, CI) :-
 	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, _ ),
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, _ , PG),
 	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
+
+code_info__set_non_common_static_data(PG, CI0, CI) :-
+	CI0 = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, _ ),
+	CI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
@@ -560,12 +591,6 @@
 	code_info, code_info).
 :- mode code_info__lookup_type_defn(in, out, in, out) is det.
 
-	% For each type variable in the given list, find out where the
-	% typeinfo var for that type variable is.
-:- pred code_info__find_typeinfos_for_tvars(list(tvar),
-	map(tvar, set(layout_locn)), code_info, code_info).
-:- mode code_info__find_typeinfos_for_tvars(in, out, in, out) is det.
-
 	% Given a constructor id, and a variable (so that we can work out the
 	% type of the constructor), determine correct tag (representation)
 	% of that constructor.
@@ -638,6 +663,14 @@
 	code_info, code_info).
 :- mode code_info__add_trace_layout_for_label(in, in, in, out) is det.
 
+:- pred code_info__add_gc_layout_for_label(label, layout_label_info,
+	code_info, code_info).
+:- mode code_info__add_gc_layout_for_label(in, in, in, out) is det.
+
+:- pred code_info__add_non_common_static_data(comp_gen_c_data,
+	code_info, code_info).
+:- mode code_info__add_non_common_static_data(in, in, out) is det.
+
 %---------------------------------------------------------------------------%
 
 :- implementation.
@@ -664,10 +697,6 @@
 	code_exprn__set_follow_vars(FollowVars, ExprnInfo0, ExprnInfo),
 	code_info__set_exprn_info(ExprnInfo, CI0, CI).
 
-:- pred code_info__get_active_temps_data(assoc_list(lval, slot_contents),
-	code_info, code_info).
-:- mode code_info__get_active_temps_data(out, in, out) is det.
-
 %-----------------------------------------------------------------------------%
 
 	% Update the code info structure to be consistent
@@ -723,9 +752,15 @@
 
 %---------------------------------------------------------------------------%
 
-code_info__variable_type(Var, Type) -->
+:- pred code_info__get_var_types(map(prog_var, type), code_info, code_info).
+:- mode code_info__get_var_types(out, in, out) is det.
+
+code_info__get_var_types(VarTypes) -->
 	code_info__get_proc_info(ProcInfo),
-	{ proc_info_vartypes(ProcInfo, VarTypes) },
+	{ proc_info_vartypes(ProcInfo, VarTypes) }.
+
+code_info__variable_type(Var, Type) -->
+	code_info__get_var_types(VarTypes),
 	{ map__lookup(VarTypes, Var, Type) }.
 
 code_info__lookup_type_defn(Type, TypeDefn) -->
@@ -738,44 +773,6 @@
 	{ module_info_types(ModuleInfo, TypeTable) },
 	{ map__lookup(TypeTable, TypeId, TypeDefn) }.
 
-code_info__find_typeinfos_for_tvars(TypeVars, TypeInfoDataMap) -->
-	code_info__variable_locations(VarLocs),
-	code_info__get_varset(VarSet),
-	code_info__get_proc_info(ProcInfo),
-	{ proc_info_typeinfo_varmap(ProcInfo, TypeInfoMap) },
-	{ map__apply_to_list(TypeVars, TypeInfoMap, TypeInfoLocns) },
-	{ FindLocn = lambda([TypeInfoLocn::in, Locns::out] is det, (
-		type_info_locn_var(TypeInfoLocn, TypeInfoVar),
-		(
-			map__search(VarLocs, TypeInfoVar, TypeInfoRvalSet)
-		->
-			ConvertRval = lambda([Locn::out] is nondet, (
-				set__member(Rval, TypeInfoRvalSet),
-				Rval = lval(Lval),
-				( 
-					TypeInfoLocn = typeclass_info(_,
-						FieldNum),
-					Locn = indirect(Lval, FieldNum)
-				;
-					TypeInfoLocn = type_info(_),
-					Locn = direct(Lval)
-				)
-			)),
-			solutions_set(ConvertRval, Locns)
-		;
-			varset__lookup_name(VarSet, TypeInfoVar,
-				VarString),
-			string__format("%s: %s %s",
-				[s("code_info__find_typeinfos_for_tvars"),
-				s("can't find lval for type_info var"),
-				s(VarString)], ErrStr),
-			error(ErrStr)
-		)
-	)) },
-	{ list__map(FindLocn, TypeInfoLocns, TypeInfoVarLocns) },
-	{ map__from_corresponding_lists(TypeVars, TypeInfoVarLocns,
-		TypeInfoDataMap) }.
-
 code_info__cons_id_to_tag(Var, ConsId, ConsTag) -->
 	code_info__variable_type(Var, Type),
 	code_info__get_module_info(ModuleInfo),
@@ -869,12 +866,38 @@
 	},
 	code_info__set_layout_info(Internals).
 
+code_info__add_gc_layout_for_label(Label, LayoutInfo) -->
+	code_info__get_layout_info(Internals0),
+	{ map__search(Internals0, Label, Internal0) ->
+		Internal0 = internal_layout_info(Exec, Agc0),
+		( Agc0 = no ->
+			true
+		;
+			error("adding gc layout for already known label")
+		),
+		Internal = internal_layout_info(Exec, yes(LayoutInfo)),
+		map__set(Internals0, Label, Internal, Internals)
+	;
+		Internal = internal_layout_info(no, yes(LayoutInfo)),
+		map__det_insert(Internals0, Label, Internal, Internals)
+	},
+	code_info__set_layout_info(Internals).
+
+:- pred code_info__get_active_temps_data(assoc_list(lval, slot_contents),
+	code_info, code_info).
+:- mode code_info__get_active_temps_data(out, in, out) is det.
+
 code_info__get_active_temps_data(Temps) -->
 	code_info__get_temps_in_use(TempsInUse),
 	code_info__get_temp_content_map(TempContentMap),
 	{ map__select(TempContentMap, TempsInUse, TempsInUseContentMap) },
 	{ map__to_assoc_list(TempsInUseContentMap, Temps) }.
 
+code_info__add_non_common_static_data(NonCommonData) -->
+	code_info__get_non_common_static_data(NonCommonDatas0),
+	code_info__set_non_common_static_data(
+		[NonCommonData | NonCommonDatas0]).
+
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 
@@ -901,6 +924,10 @@
 	code_info, code_info).
 :- mode code_info__after_all_branches(in, in, in, out) is det.
 
+:- pred code_info__save_hp_in_branch(code_tree, lval, position_info,
+	position_info).
+:- mode code_info__save_hp_in_branch(out, out, in, out) is det.
+
 :- implementation.
 
 :- type position_info
@@ -919,11 +946,11 @@
 code_info__reset_to_position(position_info(PosCI), CurCI, NextCI) :-
 		% The static fields in PosCI and CurCI should be identical.
 	PosCI  = code_info(_,  _,  _,  _,  _,  _,  _,  _, 
-		LA, LB, LC, LD, LE, LF, _,  _,  _,  _,  _,  _ ),
+		LA, LB, LC, LD, LE, LF, _,  _,  _,  _,  _,  _,  _ ),
 	CurCI  = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		_,  _,  _,  _,  _,  _,  PA, PB, PC, PD, PE, PF),
+		_,  _,  _,  _,  _,  _,  PA, PB, PC, PD, PE, PF, PG),
 	NextCI = code_info(SA, SB, SC, SD, SE, SF, SG, SH,
-		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF).
+		LA, LB, LC, LD, LE, LF, PA, PB, PC, PD, PE, PF, PG).
 
 code_info__generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd, Code) -->
 	code_info__get_exprn_info(Exprn0),
@@ -1022,6 +1049,11 @@
 code_info__fixup_lval(V - store_info(val, L), V - value(lval(L))).
 code_info__fixup_lval(V - store_info(ref, L), V - reference(L)).
 
+code_info__save_hp_in_branch(Code, Slot, Pos0, Pos) :-
+	Pos0 = position_info(CodeInfo0),
+	code_info__save_hp(Code, Slot, CodeInfo0, CodeInfo),
+	Pos  = position_info(CodeInfo).
+
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 
@@ -1213,6 +1245,12 @@
 :- pred code_info__resume_point_stack_addr(resume_point_info::in,
 	code_addr::out) is det.
 
+	% Convert resume_map to map(var, set(rval)),
+	% removing all reference()'s.
+:- pred code_info__resume_map_to_variable_locations(
+	map(prog_var, set(val_or_ref))::in,
+	map(prog_var, set(rval))::out) is det.
+
 %---------------------------------------------------------------------------%
 
 :- implementation.
@@ -1671,8 +1709,10 @@
 
 :- type commit_hijack_info
 	--->	commit_temp_frame(
-			lval		% The stack slot in which we saved
+			lval,		% The stack slot in which we saved
 					% the old value of maxfr.
+			bool		% Do we bracket the goal with
+					% MR_commit_mark and MR_commit_cut?
 		)
 	;	commit_quarter_hijack
 	;	commit_half_hijack(
@@ -1705,14 +1745,45 @@
 		{ Allow = not_allowed ; CondEnv = inside_non_condition }
 	->
 		code_info__acquire_temp_slot(lval(maxfr), MaxfrSlot),
-		{ HijackInfo = commit_temp_frame(MaxfrSlot) },
 		{ MaxfrCode = node([
 			assign(MaxfrSlot, lval(maxfr))
 				- "prepare for temp frame commit"
 		]) },
 		code_info__create_temp_frame(StackLabel,
 			"prepare for temp frame commit", TempFrameCode),
-		{ HijackCode = tree(MaxfrCode, TempFrameCode) }
+		code_info__get_globals(Globals),
+		{ globals__lookup_bool_option(Globals, use_minimal_model,
+			UseMinimalModel) },
+		{ HijackInfo = commit_temp_frame(MaxfrSlot, UseMinimalModel) },
+		{
+			UseMinimalModel = yes,
+			% If the code we are committing across starts but
+			% does not complete the evaluation of a tabled subgoal,
+			% the cut will remove the generator's choice point,
+			% so that the evaluation of the subgoal will never
+			% be completed. We handle such "dangling" generators
+			% by removing them from the subgoal trie of the
+			% tabled procedure. This requires knowing what
+			% tabled subgoals are started inside commits,
+			% which is why we wrap the goal being committed across
+			% inside MR_commit_{mark,cut}.
+			Components = [
+				pragma_c_raw_code(
+					"\tsave_transient_registers();\n"),
+				pragma_c_raw_code(
+					"\tMR_commit_mark();\n"),
+				pragma_c_raw_code(
+					"\trestore_transient_registers();\n")
+			],
+			MarkCode = node([
+				pragma_c([], Components, will_not_call_mercury,
+					no, no) - ""
+			])
+		;
+			UseMinimalModel = no,
+			MarkCode = empty
+		},
+		{ HijackCode = tree(MaxfrCode, tree(TempFrameCode, MarkCode)) }
 	;
 		{ ResumeKnown = resume_point_known },
 		{ CurfrMaxfr = must_be_equal }
@@ -1726,6 +1797,7 @@
 		{ CurfrMaxfr = must_be_equal }
 	->
 		% Here ResumeKnown must be resume_point_unknown.
+
 		code_info__acquire_temp_slot(lval(redoip(lval(curfr))),
 			RedoipSlot),
 		{ HijackInfo = commit_half_hijack(RedoipSlot) },
@@ -1767,13 +1839,30 @@
 		HijackInfo, MaybeTrailSlots) },
 
 	code_info__set_fail_info(FailInfo),
+	% XXX should release the temp slots in each arm of the switch
 	(
-		{ HijackInfo = commit_temp_frame(MaxfrSlot) },
-		{ SuccessUndoCode = node([
+		{ HijackInfo = commit_temp_frame(MaxfrSlot, UseMinimalModel) },
+		{ MaxfrCode = node([
 			assign(maxfr, lval(MaxfrSlot))
-				- "restore maxfr for full commit hijack"
+				- "restore maxfr for temp frame hijack"
 		]) },
-		{ FailureUndoCode = SuccessUndoCode }
+		{
+			UseMinimalModel = yes,
+			% See the comment in prepare_for_semi_commit above.
+			Components = [
+				pragma_c_raw_code("\tMR_commit_cut();\n")
+			],
+			CutCode = node([
+				pragma_c([], Components,
+					will_not_call_mercury, no, no)
+					- "commit for temp frame hijack"
+			])
+		;
+			UseMinimalModel = no,
+			CutCode = empty
+		},
+		{ SuccessUndoCode = tree(MaxfrCode, CutCode) },
+		{ FailureUndoCode = tree(MaxfrCode, CutCode) }
 	;
 		{ HijackInfo = commit_quarter_hijack },
 		{ FailInfo = fail_info(ResumePoints, _, _, _, _) },
@@ -2094,19 +2183,7 @@
 		map(prog_var, set(rval))::in) is semidet.
 
 code_info__match_resume_loc(Map0, Locations0) :-
-	% Convert resume_map to map(var, set(rval)), removing all reference()'s.
-	map__to_assoc_list(Map0, AL0),
-	Filter = lambda([V::in, R::out] is semidet, (
-		       V = Variable - VVals,
-		       set__to_sorted_list(VVals, Vs),
-		       list__filter_map(code_exprn__value_to_rval, Vs, Rs),
-		       Rs \= [],
-		       set__sorted_list_to_set(Rs, RvalsSet),
-		       R = Variable - RvalsSet
-	       )),
-	list__filter_map(Filter, AL0, AL),
-	map__from_assoc_list(AL, Map),
-
+	code_info__resume_map_to_variable_locations(Map0, Map),
 	map__keys(Map, KeyList),
 	set__list_to_set(KeyList, Keys),
 	map__select(Locations0, Keys, Locations),
@@ -2332,7 +2409,8 @@
 			label(Label1) -
 				"stack only failure continuation"
 		]) },
-		code_info__set_var_locations(Map1)
+		code_info__set_var_locations(Map1),
+		code_info__generate_resume_layout(Label1, Map1)
 	;
 		{ ResumePoint = stack_and_orig(Map1, Addr1, Map2, Addr2) },
 		{ extract_label_from_code_addr(Addr1, Label1) },
@@ -2342,6 +2420,7 @@
 				"stack failure continuation before orig"
 		]) },
 		code_info__set_var_locations(Map1),
+		code_info__generate_resume_layout(Label1, Map1),
 		{ map__to_assoc_list(Map2, AssocList2) },
 		code_info__place_resume_vars(AssocList2, PlaceCode),
 		{ Label2Code = node([
@@ -2366,6 +2445,7 @@
 				"stack failure continuation after orig"
 		]) },
 		code_info__set_var_locations(Map2),
+		code_info__generate_resume_layout(Label2, Map2),
 		{ Code = tree(Label1Code, tree(PlaceCode, Label2Code)) }
 	).
 
@@ -2442,7 +2522,7 @@
 code_info__resume_point_stack_addr(ResumePoint, StackAddr) :-
 	code_info__pick_stack_resume_point(ResumePoint, _, StackAddr).
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred code_info__maybe_save_trail_info(maybe(pair(lval))::out,
 	code_tree::out, code_info::in, code_info::out) is det.
@@ -2525,6 +2605,21 @@
 	).
 
 %---------------------------------------------------------------------------%
+
+code_info__resume_map_to_variable_locations(Map0, Map) :-
+	map__to_assoc_list(Map0, AL0),
+	Filter = lambda([V::in, R::out] is semidet, (
+		       V = Variable - VVals,
+		       set__to_sorted_list(VVals, Vs),
+		       list__filter_map(code_exprn__value_to_rval, Vs, Rs),
+		       Rs \= [],
+		       set__sorted_list_to_set(Rs, RvalsSet),
+		       R = Variable - RvalsSet
+	       )),
+	list__filter_map(Filter, AL0, AL),
+	map__from_assoc_list(AL, Map).
+
+%---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 
 	% Submodule to deal with liveness issues.
@@ -3270,98 +3365,34 @@
 
 code_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
 		LiveLvalues) -->
+	code_info__variable_locations(VarLocs),
 	code_info__get_known_variables(Vars),
-	code_info__get_globals(Globals),
-	{ globals__want_return_var_layouts(Globals, WantReturnVarLayout) },
-	code_info__get_inst_table(InstTable),
-	code_info__find_return_var_lvals(Vars, OutputArgLocs, VarLvals),
-	code_info__generate_var_live_lvalues(VarLvals, InstTable,
-		ReturnInstMap, WantReturnVarLayout, VarLiveLvalues),
-
 	code_info__get_active_temps_data(Temps),
-	{ code_info__generate_temp_live_lvalues(Temps, TempLiveLvalues) },
-
-	{ list__append(VarLiveLvalues, TempLiveLvalues, LiveLvalues) }.
-
-:- pred code_info__find_return_var_lvals(list(prog_var)::in,
-	assoc_list(prog_var, arg_loc)::in, assoc_list(prog_var, lval)::out,
-	code_info::in, code_info::out) is det.
-
-code_info__find_return_var_lvals([], _, []) --> [].
-code_info__find_return_var_lvals([Var | Vars], OutputArgLocs,
-		[Var - Lval | VarLvals]) -->
-	( { assoc_list__search(OutputArgLocs, Var, ArgLoc) } ->
-		% On return, output arguments are in their registers.
-		{ code_util__arg_loc_to_register(ArgLoc, Lval) }
-	;
-		% On return, other live variables are in their stack slots.
-		code_info__get_variable_slot(Var, Lval)
-	),
-	code_info__find_return_var_lvals(Vars, OutputArgLocs, VarLvals).
-
-:- pred code_info__generate_temp_live_lvalues(
-	assoc_list(lval, slot_contents)::in, list(liveinfo)::out) is det.
-
-code_info__generate_temp_live_lvalues([], []).
-code_info__generate_temp_live_lvalues([Temp | Temps], [Live | Lives]) :-
-	Temp = Slot - Contents,
-	code_info__get_live_value_type(Contents, LiveLvalueType),
-	map__init(Empty),
-	Live = live_lvalue(direct(Slot), LiveLvalueType, Empty),
-	code_info__generate_temp_live_lvalues(Temps, Lives).
+	code_info__get_proc_info(ProcInfo),
+	code_info__get_globals(Globals),
+	{ proc_info_inst_table(ProcInfo, InstTable) },
+	{ continuation_info__generate_return_live_lvalues(OutputArgLocs,
+		ReturnInstMap, InstTable, Vars, VarLocs,
+		Temps, ProcInfo, Globals, LiveLvalues) }.
 
-:- pred code_info__generate_var_live_lvalues(assoc_list(prog_var, lval)::in,
-	inst_table::in, instmap::in, bool::in, list(liveinfo)::out,
+:- pred code_info__generate_resume_layout(label::in, resume_map::in,
 	code_info::in, code_info::out) is det.
 
-code_info__generate_var_live_lvalues([], _, _, _, []) --> [].
-code_info__generate_var_live_lvalues([Var - Lval | VarLvals], InstTable,
-		InstMap, WantReturnVarLayout, [Live | Lives]) -->
-	(
-		{ WantReturnVarLayout = yes }
-	->
-		code_info__get_varset(VarSet),
-		{ varset__lookup_name(VarSet, Var, Name) },
-		code_info__variable_type(Var, Type),
-		{ instmap__lookup_var(InstMap, Var, Inst) },
-		{ type_util__vars(Type, TypeVars) },
-		code_info__find_typeinfos_for_tvars(TypeVars, TypeParams),
-		{ QualInst = qualified_inst(InstTable, Inst) },
-		{ VarInfo = var(Var, Name, Type, QualInst) },
-		{ Live = live_lvalue(direct(Lval), VarInfo, TypeParams) }
+code_info__generate_resume_layout(Label, ResumeMap) -->
+	code_info__get_globals(Globals),
+	{ globals__lookup_bool_option(Globals, agc_stack_layout,
+		AgcStackLayout) },
+	( { AgcStackLayout = yes } ->
+		code_info__get_active_temps_data(Temps),
+		code_info__get_instmap(InstMap),
+		code_info__get_inst_table(InstTable),
+		code_info__get_proc_info(ProcInfo),
+		{ continuation_info__generate_resume_layout(ResumeMap,
+			Temps, InstMap, InstTable, ProcInfo, Layout) },
+		code_info__add_gc_layout_for_label(Label, Layout)
 	;
-		{ map__init(Empty) },
-		{ Live = live_lvalue(direct(Lval), unwanted, Empty) }
-	),
-	code_info__generate_var_live_lvalues(VarLvals, InstTable, InstMap,
-		WantReturnVarLayout, Lives).
-
-:- pred code_info__get_live_value_type(slot_contents::in, live_value_type::out)
-	is det.
-
-code_info__get_live_value_type(lval(succip), succip).
-code_info__get_live_value_type(lval(hp), hp).
-code_info__get_live_value_type(lval(maxfr), maxfr).
-code_info__get_live_value_type(lval(curfr), curfr).
-code_info__get_live_value_type(lval(succfr(_)), unwanted).
-code_info__get_live_value_type(lval(prevfr(_)), unwanted).
-code_info__get_live_value_type(lval(redofr(_)), unwanted).
-code_info__get_live_value_type(lval(redoip(_)), unwanted).
-code_info__get_live_value_type(lval(succip(_)), unwanted).
-code_info__get_live_value_type(lval(sp), unwanted).
-code_info__get_live_value_type(lval(lvar(_)), unwanted).
-code_info__get_live_value_type(lval(field(_, _, _)), unwanted).
-code_info__get_live_value_type(lval(temp(_, _)), unwanted).
-code_info__get_live_value_type(lval(reg(_, _)), unwanted).
-code_info__get_live_value_type(lval(stackvar(_)), unwanted).
-code_info__get_live_value_type(lval(framevar(_)), unwanted).
-code_info__get_live_value_type(lval(mem_ref(_)), unwanted).		% XXX
-code_info__get_live_value_type(ticket, unwanted). % XXX we may need to
-					% modify this, if the GC is going
-					% to garbage-collect the trail.
-code_info__get_live_value_type(ticket_counter, unwanted).
-code_info__get_live_value_type(sync_term, unwanted).
-code_info__get_live_value_type(trace_data, unwanted).
+		[]
+	).
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
@@ -3396,15 +3427,6 @@
 	% during code generation.
 
 :- interface.
-
-:- type slot_contents 
-	--->	ticket			% a ticket (trail pointer)
-	;	ticket_counter		% a copy of the ticket counter
-	;	trace_data
-	;	sync_term		% a syncronization term used
-					% at the end of par_conjs.
-					% see par_conj_gen.m for details.
-	;	lval(lval).
 
 	% Returns the total stackslot count, but not including space for
 	% succip. This total can change in the future if this call is
Index: continuation_info.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/continuation_info.m,v
retrieving revision 1.3.4.10
diff -u -u -r1.3.4.10 continuation_info.m
--- continuation_info.m	1998/11/24 06:27:33	1.3.4.10
+++ continuation_info.m	1999/04/29 02:45:08
@@ -1,5 +1,5 @@
 %-----------------------------------------------------------------------------%
-% Copyright (C) 1997-1998 The University of Melbourne.
+% Copyright (C) 1997-1999 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
@@ -8,10 +8,10 @@
 % Main author: trd.
 % Extensive modifications by zs.
 %
-% This file defines the continuation_info data structure, which the code
-% generator uses to collect information that will later be converted into
-% stack_layout tables for accurate garbage collection, for stack tracing,
-% execution tracing and perhaps other purposes.
+% This file defines the data structures the code generator uses to collect
+% information that will later be converted into layout tables for accurate
+% garbage collection, for stack tracing, execution tracing and perhaps
+% other purposes.
 %
 % Information is collected in several passes. 
 %
@@ -22,21 +22,27 @@
 %
 %	2 During code generation for the procedure, provided the option
 %	  trace_stack_layouts is set, we add layout information for labels
-%	  that represent trace ports to the code generator state.
+%	  that represent trace ports to the code generator state. If
+%	  agc_stack_layouts is set, we add layout information for the stack
+%	  label in each resumption point. And regardless of option settings,
+%	  we also generate layouts to be attached to any closures we create.
 %
 % 	3 After we finish generating code for a procedure, we record
 %	  all the static information about the procedure (some of which
 %	  is available only after code generation), together with the
 %	  info about internal labels accumulated in the code generator state,
-%	  in the continuation_info structure (which is part of HLDS).
+%	  in the global_data structure (which is part of HLDS).
 %
 % 	4 If agc_stack_layouts is set, we make a pass over the
 % 	  optimized code recorded in the final LLDS instructions.
 %	  In this pass, we collect information from call instructions
 %	  about the internal labels to which calls can return.
-%	  This info will also go straight into the continuation_info
+%	  This info will also go straight into the global_data
 %	  in the HLDS.
 %
+% This module defines the data structures used by all passes. It also
+% implements the whole of pass 4, and various fractions of the other passes.
+%
 % stack_layout.m converts the information collected in this module into
 % stack_layout tables.
 
@@ -47,16 +53,8 @@
 :- interface.
 
 :- import_module llds, hlds_module, hlds_pred, hlds_data, prog_data.
-:- import_module trace, globals.
-:- import_module set, map, list, std_util, bool.
-
-	%
-	% Information used by the continuation_info module.
-	% This is an abstract data type - when processing is finished
-	% use continuation_info__get_all_entries to retrieve the
-	% completed proc_layout_infos.
-	%
-:- type continuation_info.
+:- import_module (inst), instmap, trace, globals.
+:- import_module std_util, bool, list, assoc_list, set, map.
 
 	%
 	% Information for any procedure, includes information about the
@@ -169,103 +167,98 @@
 			live_value_type % info about the variable
 		).
 
-	% Return an initialized continuation info structure.
+:- type closure_layout_info
+	--->	closure_layout_info(
+			list(closure_arg_info),
+				% there is one closure_arg_info for each
+				% argument of the called procedure,
+				% even the args which are not in the closure
+			map(tvar, set(layout_locn))
+				% locations of polymorphic type vars,
+				% encoded so that rN refers to argument N
+		).
 
-:- pred continuation_info__init(continuation_info::out) is det.
+:- type closure_arg_info
+	--->	closure_arg_info(
+			type,	% The type of the argument.
+			(inst)	% The initial inst of the argument.
+
+				% It may be useful in the future to include
+				% info about the final insts and about
+				% the determinism. This would allow us
+				% to implement checked dynamic inst casts,
+				% which may be helpful for dynamic loading.
+				% It may also be useful for printing
+				% closures and for providing user-level
+				% RTTI access.
+		).
 
-	%
-	% Add all the information accumulated by the first three passes
-	% above for a single procedure.
-	%
-	% Takes the pred_proc_id, entry label, the number of stack slots,
-	% the determinism of the proc, the stack slot of the succip
-	% in this proc (if there is one), the label of the call event
-	% (if there is such an event), info about the tracing slots of this
-	% proc, a flag saying whether we definitely need a procedure id
-	% section in the procedure layout, as well as the layouts at all
-	% the trace event labels.
-	%
-:- pred continuation_info__add_proc_info(pred_proc_id::in, label::in,
-	int::in, determinism::in, maybe(int)::in, maybe(label)::in,
-	trace_slot_info::in, bool::in, proc_label_layout_info::in,
-	continuation_info::in, continuation_info::out) is det.
+:- type slot_contents 
+	--->	ticket			% a ticket (trail pointer)
+	;	ticket_counter		% a copy of the ticket counter
+	;	trace_data
+	;	sync_term		% a syncronization term used
+					% at the end of par_conjs.
+					% see par_conj_gen.m for details.
+	;	lval(lval).
 
-	%
 	% Call continuation_info__maybe_process_proc_llds on the code
 	% of every procedure in the list.
-	%
 :- pred continuation_info__maybe_process_llds(list(c_procedure)::in,
-	module_info::in, continuation_info::in, continuation_info::out) is det.
+	module_info::in, global_data::in, global_data::out) is det.
 
-	%
 	% Check whether this procedure ought to have any layout structures
-	% generated for it. If yes, then update the continuation_info to
+	% generated for it. If yes, then update the global_data to
 	% include all the continuation labels within a proc. Whether or not
 	% the information about a continuation label includes the variables
 	% live at that label depends on the values of options.
-	%
 :- pred continuation_info__maybe_process_proc_llds(list(instruction)::in,
 	pred_proc_id::in, module_info::in,
-	continuation_info::in, continuation_info::out) is det.
-
-	%
-	% Get the finished list of proc_layout_infos.
-	%
-:- pred continuation_info__get_all_proc_layouts(continuation_info::in,
-	list(proc_layout_info)::out) is det.
+	global_data::in, global_data::out) is det.
 
-	%
 	% Check whether the given procedure should have at least (a) a basic
 	% stack layout, and (b) a procedure id layout generated for it.
 	% The two bools returned answer these two questions respectively.
-	%
 :- pred continuation_info__basic_stack_layout_for_proc(pred_info::in,
 	globals::in, bool::out, bool::out) is det.
 
+	% Generate the layout information we need for the return point
+	% of a call.
+:- pred continuation_info__generate_return_live_lvalues(
+	assoc_list(prog_var, arg_loc)::in, instmap::in, inst_table::in,
+	list(prog_var)::in, map(prog_var, set(rval))::in,
+	assoc_list(lval, slot_contents)::in, proc_info::in,
+	globals::in, list(liveinfo)::out) is det.
+
+	% Generate the layout information we need for a resumption point,
+	% a label where forward execution can restart after backtracking.
+:- pred continuation_info__generate_resume_layout(
+	map(prog_var, set(val_or_ref))::in,
+	assoc_list(lval, slot_contents)::in, instmap::in, inst_table::in,
+	proc_info::in, layout_label_info::out) is det.
+
+	% Generate the layout information we need to include in a closure.
+:- pred continuation_info__generate_closure_layout(module_info::in,
+	pred_id::in, proc_id::in, closure_layout_info::out) is det.
+
+	% For each type variable in the given list, find out where the
+	% typeinfo var for that type variable is.
+:- pred continuation_info__find_typeinfos_for_tvars(list(tvar)::in,
+	map(prog_var, set(rval))::in, proc_info::in,
+	map(tvar, set(layout_locn))::out) is det.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
 :- implementation.
 
-:- import_module options, type_util.
-:- import_module require.
-
-	% The continuation_info data structure
-:- type continuation_info	==	map(pred_proc_id, proc_layout_info).
+:- import_module hlds_goal, code_info, code_util, type_util, options.
+:- import_module string, require, varset, term.
 
 %-----------------------------------------------------------------------------%
 
 	% Exported predicates.
 
-	%
-	% Initialize the continuation_info
-	%
-
-continuation_info__init(ContInfo) :-
-	map__init(ContInfo).
-
-	%
-	% Add the info for this proc (a proc_layout_info) to the
-	% continuation_info. 
-	%
-continuation_info__add_proc_info(PredProcId, EntryLabel, StackSize,
-		Detism, SuccipLocation, MaybeTraceCallLabel, TraceSlotInfo,
-		ForceProcId, InternalMap, ContInfo0, ContInfo) :-
-	( map__contains(ContInfo0, PredProcId) ->
-		error("duplicate continuation_info for proc.")
-	;
-		LayoutInfo = proc_layout_info(EntryLabel, Detism, StackSize,
-			SuccipLocation, MaybeTraceCallLabel,
-			TraceSlotInfo, ForceProcId, InternalMap),
-		map__det_insert(ContInfo0, PredProcId, LayoutInfo, ContInfo)
-	).
-
-	%
-	% Get all the proc_layout_infos.
-	%
-continuation_info__get_all_proc_layouts(ContInfo, Entries) :-
-	map__values(ContInfo, Entries).
-
 continuation_info__maybe_process_llds([], _) --> [].
 continuation_info__maybe_process_llds([Proc | Procs], ModuleInfo) -->
 	{ Proc = c_procedure(_, _, PredProcId, Instrs) },
@@ -290,17 +283,17 @@
 
 	%
 	% Process the list of instructions for this proc, adding
-	% all internal label information to the continuation_info.
+	% all internal label information to global_data.
 	%
 :- pred continuation_info__process_proc_llds(pred_proc_id::in,
 	list(instruction)::in, bool::in,
-	continuation_info::in, continuation_info::out) is det.
+	global_data::in, global_data::out) is det.
 
 continuation_info__process_proc_llds(PredProcId, Instructions,
-		WantReturnInfo, ContInfo0, ContInfo) :-
+		WantReturnInfo, GlobalData0, GlobalData) :-
 
 		% Get all the continuation info from the call instructions.
-	map__lookup(ContInfo0, PredProcId, ProcLayoutInfo0),
+	global_data_get_proc_layout(GlobalData0, PredProcId, ProcLayoutInfo0),
 	ProcLayoutInfo0 = proc_layout_info(A, B, C, D, E, F, G, Internals0),
 	GetCallLivevals = lambda([Instr::in, Pair::out] is semidet, (
 		Instr = call(_, label(Label), LiveInfo, _) - _Comment,
@@ -313,7 +306,8 @@
 		Calls, Internals0, Internals),
 
 	ProcLayoutInfo = proc_layout_info(A, B, C, D, E, F, G, Internals),
-	map__det_update(ContInfo0, PredProcId, ProcLayoutInfo, ContInfo).
+	global_data_update_proc_layout(GlobalData0, PredProcId, ProcLayoutInfo,
+		GlobalData).
 
 %-----------------------------------------------------------------------------%
 
@@ -421,5 +415,270 @@
 		list__member(Type, ArgTypes),
 		type_is_higher_order(Type, _, _)
 	)).
+
+%-----------------------------------------------------------------------------%
+
+continuation_info__generate_return_live_lvalues(OutputArgLocs, InstTable,
+		ReturnInstMap, Vars, VarLocs, Temps, ProcInfo,
+		Globals, LiveLvalues) :-
+	globals__want_return_var_layouts(Globals, WantReturnVarLayout),
+	proc_info_stack_slots(ProcInfo, StackSlots),
+	continuation_info__find_return_var_lvals(Vars, StackSlots,
+		OutputArgLocs, VarLvals),
+	continuation_info__generate_var_live_lvalues(VarLvals, InstTable,
+		ReturnInstMap, VarLocs, ProcInfo,
+		WantReturnVarLayout, VarLiveLvalues),
+	continuation_info__generate_temp_live_lvalues(Temps, TempLiveLvalues),
+	list__append(VarLiveLvalues, TempLiveLvalues, LiveLvalues).
+
+:- pred continuation_info__find_return_var_lvals(list(prog_var)::in,
+	stack_slots::in, assoc_list(prog_var, arg_loc)::in,
+	assoc_list(prog_var, lval)::out) is det.
+
+continuation_info__find_return_var_lvals([], _, _, []).
+continuation_info__find_return_var_lvals([Var | Vars], StackSlots,
+		OutputArgLocs, [Var - Lval | VarLvals]) :-
+	( assoc_list__search(OutputArgLocs, Var, ArgLoc) ->
+		% On return, output arguments are in their registers.
+		code_util__arg_loc_to_register(ArgLoc, Lval)
+	;
+		% On return, other live variables are in their stack slots.
+		map__lookup(StackSlots, Var, Lval)
+	),
+	continuation_info__find_return_var_lvals(Vars, StackSlots,
+		OutputArgLocs, VarLvals).
+
+:- pred continuation_info__generate_temp_live_lvalues(
+	assoc_list(lval, slot_contents)::in, list(liveinfo)::out) is det.
+
+continuation_info__generate_temp_live_lvalues([], []).
+continuation_info__generate_temp_live_lvalues([Temp | Temps], [Live | Lives]) :-
+	Temp = Slot - Contents,
+	continuation_info__live_value_type(Contents, LiveLvalueType),
+	map__init(Empty),
+	Live = live_lvalue(direct(Slot), LiveLvalueType, Empty),
+	continuation_info__generate_temp_live_lvalues(Temps, Lives).
+
+:- pred continuation_info__generate_var_live_lvalues(
+	assoc_list(prog_var, lval)::in, instmap::in, inst_table::in,
+	map(prog_var, set(rval))::in, proc_info::in,
+	bool::in, list(liveinfo)::out) is det.
+
+continuation_info__generate_var_live_lvalues([], _, _, _, _, _, []).
+continuation_info__generate_var_live_lvalues([Var - Lval | VarLvals],
+		InstMap, InstTable, VarLocs, ProcInfo,
+		WantReturnVarLayout, [Live | Lives]) :-
+	( WantReturnVarLayout = yes ->
+		continuation_info__generate_layout_for_var(Var, InstMap,
+			InstTable, ProcInfo, LiveValueType, TypeVars),
+		continuation_info__find_typeinfos_for_tvars(TypeVars,
+			VarLocs, ProcInfo, TypeParams),
+		Live = live_lvalue(direct(Lval), LiveValueType, TypeParams)
+	;
+		map__init(Empty),
+		Live = live_lvalue(direct(Lval), unwanted, Empty)
+	),
+	continuation_info__generate_var_live_lvalues(VarLvals, InstMap,
+		InstTable, VarLocs, ProcInfo, WantReturnVarLayout, Lives).
+
+%---------------------------------------------------------------------------%
+
+continuation_info__generate_resume_layout(ResumeMap, Temps,
+		InstMap, InstTable, ProcInfo, Layout) :-
+	map__to_assoc_list(ResumeMap, ResumeList),
+	set__init(TVars0),
+	continuation_info__generate_resume_layout_for_vars(ResumeList,
+		InstMap, InstTable, ProcInfo, VarInfos, TVars0, TVars),
+	set__list_to_set(VarInfos, VarInfoSet),
+	set__to_sorted_list(TVars, TVarList),
+
+	% Typeinfos should never be passed by reference.
+	code_info__resume_map_to_variable_locations(ResumeMap, ResumeVarLocs),
+	continuation_info__find_typeinfos_for_tvars(TVarList, ResumeVarLocs,
+		ProcInfo, TVarInfoMap),
+	continuation_info__generate_temp_var_infos(Temps, TempInfos),
+	set__list_to_set(TempInfos, TempInfoSet),
+	set__union(VarInfoSet, TempInfoSet, AllInfoSet),
+	Layout = layout_label_info(AllInfoSet, TVarInfoMap).
+
+:- pred continuation_info__generate_resume_layout_for_vars(
+	assoc_list(prog_var, set(val_or_ref))::in, instmap::in, inst_table::in,
+	proc_info::in, list(var_info)::out,
+	set(tvar)::in, set(tvar)::out) is det.
+
+continuation_info__generate_resume_layout_for_vars([], _, _, _,
+		[], TVars, TVars).
+continuation_info__generate_resume_layout_for_vars([Var - RvalSet | VarRvals],
+		InstMap, InstTable, ProcInfo, [VarInfo | VarInfos],
+		TVars0, TVars) :-
+	continuation_info__generate_resume_layout_for_var(Var, RvalSet,
+		InstMap, InstTable, ProcInfo, VarInfo, TypeVars),
+	set__insert_list(TVars0, TypeVars, TVars1),
+	continuation_info__generate_resume_layout_for_vars(VarRvals,
+		InstMap, InstTable, ProcInfo, VarInfos, TVars1, TVars).
+
+:- pred continuation_info__generate_resume_layout_for_var(prog_var::in,
+	set(val_or_ref)::in, instmap::in, inst_table::in, proc_info::in,
+	var_info::out, list(tvar)::out) is det.
+
+continuation_info__generate_resume_layout_for_var(Var, ValOrRefSet, InstMap,
+		InstTable, ProcInfo, VarInfo, TypeVars) :-
+	set__to_sorted_list(ValOrRefSet, VarOrRefList),
+	( VarOrRefList = [ValOrRefPrime] ->
+		ValOrRef = ValOrRefPrime
+	;
+		error("var has more than one rval in stack resume map")
+	),
+	(
+		ValOrRef = value(Rval),
+		( Rval = lval(LvalPrime) ->
+			Lval = LvalPrime
+		;
+			error("var rval is not lval in stack resume map")
+		)
+	;
+		ValOrRef = reference(Lval)
+	),
+	continuation_info__generate_layout_for_var(Var, InstMap, InstTable,
+		ProcInfo, LiveValueType, TypeVars),
+	VarInfo = var_info(direct(Lval), LiveValueType).
+
+:- pred continuation_info__generate_temp_var_infos(
+	assoc_list(lval, slot_contents)::in, list(var_info)::out) is det.
+
+continuation_info__generate_temp_var_infos([], []).
+continuation_info__generate_temp_var_infos([Temp | Temps], [Live | Lives]) :-
+	Temp = Slot - Contents,
+	continuation_info__live_value_type(Contents, LiveLvalueType),
+	Live = var_info(direct(Slot), LiveLvalueType),
+	continuation_info__generate_temp_var_infos(Temps, Lives).
+
+%---------------------------------------------------------------------------%
+
+:- pred continuation_info__generate_layout_for_var(prog_var::in,
+	instmap::in, inst_table::in, proc_info::in,
+	live_value_type::out, list(tvar)::out) is det.
+
+continuation_info__generate_layout_for_var(Var, InstMap, InstTable, ProcInfo,
+		LiveValueType, TypeVars) :-
+	proc_info_varset(ProcInfo, VarSet),
+	proc_info_vartypes(ProcInfo, VarTypes),
+	varset__lookup_name(VarSet, Var, "V_", Name),
+	instmap__lookup_var(InstMap, Var, Inst),
+	map__lookup(VarTypes, Var, Type),
+	LiveValueType = var(Var, Name, Type, qualified_inst(InstTable, Inst)),
+	type_util__vars(Type, TypeVars).
+
+%---------------------------------------------------------------------------%
+
+continuation_info__generate_closure_layout(ModuleInfo, PredId, ProcId,
+		ClosureLayout) :-
+	module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo),
+	proc_info_headvars(ProcInfo, HeadVars),
+	proc_info_arg_info(ProcInfo, ArgInfos),
+	proc_info_vartypes(ProcInfo, VarTypes),
+	proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap),
+	proc_info_inst_table(ProcInfo, InstTable),
+	map__init(VarLocs0),
+	set__init(TypeVars0),
+	assoc_list__from_corresponding_lists(HeadVars, ArgInfos, VarArgInfos),
+	continuation_info__build_closure_info(VarArgInfos, ArgLayouts,
+		VarTypes, InstMap, InstTable, VarLocs0, VarLocs,
+		TypeVars0, TypeVars),
+	set__to_sorted_list(TypeVars, TypeVarsList),
+	continuation_info__find_typeinfos_for_tvars(TypeVarsList, VarLocs,
+		ProcInfo, TypeInfoDataMap),
+	ClosureLayout = closure_layout_info(ArgLayouts, TypeInfoDataMap).
+
+:- pred continuation_info__build_closure_info(
+	assoc_list(prog_var, arg_info)::in,  list(closure_arg_info)::out,
+	map(prog_var, type)::in, instmap::in, inst_table::in,
+	map(prog_var, set(rval))::in, map(prog_var, set(rval))::out,
+	set(tvar)::in, set(tvar)::out) is det.
+
+continuation_info__build_closure_info([], [], _, _, _, VarLocs, VarLocs,
+		TypeVars, TypeVars).
+continuation_info__build_closure_info([Var - ArgInfo | VarArgInfos],
+		[Layout | Layouts], VarTypes, InstMap, InstTable,
+		VarLocs0, VarLocs, TypeVars0, TypeVars) :-
+	ArgInfo = arg_info(ArgLoc, _ArgMode),
+	map__lookup(VarTypes, Var, Type),
+	instmap__lookup_var(InstMap, Var, Inst),
+	Layout = closure_arg_info(Type, Inst),
+	set__singleton_set(Locations, lval(reg(r, ArgLoc))),
+	map__det_insert(VarLocs0, Var, Locations, VarLocs1),
+	type_util__vars(Type, VarTypeVars),
+	set__insert_list(TypeVars0, VarTypeVars, TypeVars1),
+	continuation_info__build_closure_info(VarArgInfos, Layouts,
+		VarTypes, InstMap, InstTable, VarLocs1, VarLocs,
+		TypeVars1, TypeVars).
+
+%---------------------------------------------------------------------------%
+
+continuation_info__find_typeinfos_for_tvars(TypeVars, VarLocs, ProcInfo,
+		TypeInfoDataMap) :-
+	proc_info_varset(ProcInfo, VarSet),
+	proc_info_typeinfo_varmap(ProcInfo, TypeInfoMap),
+	map__apply_to_list(TypeVars, TypeInfoMap, TypeInfoLocns),
+	FindLocn = lambda([TypeInfoLocn::in, Locns::out] is det, (
+		type_info_locn_var(TypeInfoLocn, TypeInfoVar),
+		(
+			map__search(VarLocs, TypeInfoVar, TypeInfoRvalSet)
+		->
+			ConvertRval = lambda([Locn::out] is nondet, (
+				set__member(Rval, TypeInfoRvalSet),
+				Rval = lval(Lval),
+				( 
+					TypeInfoLocn = typeclass_info(_,
+						FieldNum),
+					Locn = indirect(Lval, FieldNum)
+				;
+					TypeInfoLocn = type_info(_),
+					Locn = direct(Lval)
+				)
+			)),
+			solutions_set(ConvertRval, Locns)
+		;
+			varset__lookup_name(VarSet, TypeInfoVar,
+				VarString),
+			string__format("%s: %s %s",
+				[s("code_info__find_typeinfos_for_tvars"),
+				s("can't find lval for type_info var"),
+				s(VarString)], ErrStr),
+			error(ErrStr)
+		)
+	)),
+	list__map(FindLocn, TypeInfoLocns, TypeInfoVarLocns),
+	map__from_corresponding_lists(TypeVars, TypeInfoVarLocns,
+		TypeInfoDataMap).
+
+%-----------------------------------------------------------------------------%
+
+:- pred continuation_info__live_value_type(slot_contents::in,
+	live_value_type::out) is det.
+
+continuation_info__live_value_type(lval(succip), succip).
+continuation_info__live_value_type(lval(hp), hp).
+continuation_info__live_value_type(lval(maxfr), maxfr).
+continuation_info__live_value_type(lval(curfr), curfr).
+continuation_info__live_value_type(lval(succfr(_)), unwanted).
+continuation_info__live_value_type(lval(prevfr(_)), unwanted).
+continuation_info__live_value_type(lval(redofr(_)), unwanted).
+continuation_info__live_value_type(lval(redoip(_)), unwanted).
+continuation_info__live_value_type(lval(succip(_)), unwanted).
+continuation_info__live_value_type(lval(sp), unwanted).
+continuation_info__live_value_type(lval(lvar(_)), unwanted).
+continuation_info__live_value_type(lval(field(_, _, _)), unwanted).
+continuation_info__live_value_type(lval(temp(_, _)), unwanted).
+continuation_info__live_value_type(lval(reg(_, _)), unwanted).
+continuation_info__live_value_type(lval(stackvar(_)), unwanted).
+continuation_info__live_value_type(lval(framevar(_)), unwanted).
+continuation_info__live_value_type(lval(mem_ref(_)), unwanted).	% XXX
+continuation_info__live_value_type(ticket, unwanted). % XXX we may need to
+					% modify this, if the GC is going
+					% to garbage-collect the trail.
+continuation_info__live_value_type(ticket_counter, unwanted).
+continuation_info__live_value_type(sync_term, unwanted).
+continuation_info__live_value_type(trace_data, unwanted).
 
 %-----------------------------------------------------------------------------%
Index: hlds_pred.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_pred.m,v
retrieving revision 1.35.4.19
diff -u -u -r1.35.4.19 hlds_pred.m
--- hlds_pred.m	1998/11/24 06:28:44	1.35.4.19
+++ hlds_pred.m	1998/12/15 01:44:31
<< snip >>
@@ -319,7 +365,8 @@
 
 	% hlds_pred__define_new_pred(Goal, CallGoal, Args, ExtraArgs, InstMap,
 	% 	PredName, TVarSet, VarTypes, ClassContext, TVarMap, TCVarMap, 
-	%	VarSet, Markers, InstTable, ModuleInfo0, ModuleInfo, PredProcId)
+	%	VarSet, Markers, Owner, InstTable, ModuleInfo0, ModuleInfo,
+	%	PredProcId)
 	%
 	% Create a new predicate for the given goal, returning a goal to 
 	% call the created predicate. ExtraArgs is the list of extra
@@ -330,8 +377,22 @@
 		list(prog_var), instmap, string, tvarset, map(prog_var, type),
 		class_constraints, map(tvar, type_info_locn),
 		map(class_constraint, prog_var), prog_varset, pred_markers,
-		inst_table, module_info, module_info, pred_proc_id).
-:- mode hlds_pred__define_new_pred(in, out, in, out, in, in, in, in,
+		aditi_owner, inst_table, module_info, module_info,
+		pred_proc_id).
+:- mode hlds_pred__define_new_pred(in, out, in, out, in, in, in, in, in, in,
+		in, in, in, in, in, in, out, out) is det.
+
+	% Same as above, except that the argument modes are given explicitly
+	% rather than computed from the goal's instmap_delta. This is useful
+	% when the instmap_delta for the procedure is out of date and
+	% needs to be recomputed.
+:- pred hlds_pred__define_new_pred(hlds_goal, hlds_goal, list(prog_var),
+		list(prog_var), instmap, list(mode), string, tvarset,
+		map(prog_var, type), class_constraints,
+		map(tvar, type_info_locn), map(class_constraint, prog_var),
+		prog_varset, pred_markers, aditi_owner, inst_table,
+		module_info, module_info, pred_proc_id).
+:- mode hlds_pred__define_new_pred(in, out, in, out, in, in, in, in, in, in,
 		in, in, in, in, in, in, in, out, out) is det.
 
 	% Various predicates for accessing the information stored in the
<< snip >>
@@ -973,22 +1089,39 @@
 
 add_marker(Markers, Marker, [Marker | Markers]).
 
+remove_marker(Markers0, Marker, Markers) :-
+	list__delete_all(Markers0, Marker, Markers).
+
 markers_to_marker_list(Markers, Markers).
 
+marker_list_to_markers(Markers, Markers).
+
 %-----------------------------------------------------------------------------%
 
 hlds_pred__define_new_pred(Goal0, Goal, ArgVars0, ExtraTypeInfos, InstMap0,
 		PredName, TVarSet, VarTypes0, ClassContext, TVarMap, TCVarMap,
-		VarSet0, Markers, InstTable, ModuleInfo0, ModuleInfo,
+		VarSet0, Markers, Owner, InstTable, ModuleInfo0, ModuleInfo,
 		PredProcId) :-
 	Goal0 = _GoalExpr - GoalInfo,
 	goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
 	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap),
-
+	
+	compute_arg_modes(ArgVars0, InstMap0, InstMap, ArgModes),
+	hlds_pred__define_new_pred(Goal0, Goal, ArgVars0, ExtraTypeInfos,
+		InstMap0, ArgModes, PredName, TVarSet, VarTypes0,
+		ClassContext, TVarMap, TCVarMap, VarSet0, Markers,
+		Owner, InstTable, ModuleInfo0, ModuleInfo, PredProcId).
+
+hlds_pred__define_new_pred(Goal0, Goal, ArgVars0, ExtraTypeInfos, _InstMap0,
+		ArgModes, PredName, TVarSet, VarTypes0, ClassContext, TVarMap,
+		TCVarMap, VarSet0, Markers, Owner, InstTable,
+		ModuleInfo0, ModuleInfo, PredProcId) :-
 	% XXX The set of existentially quantified type variables
 	% here might not be correct.
 	ExistQVars = [],
 
+	Goal0 = _ - GoalInfo,
+
 	% If typeinfo_liveness is set, all type_infos for the argument
 	% variables need to be passed in, not just the ones that are used.
 	module_info_globals(ModuleInfo0, Globals),
@@ -1008,12 +1141,15 @@
 
 	goal_info_get_context(GoalInfo, Context),
 	goal_info_get_determinism(GoalInfo, Detism),
-	compute_arg_types_modes(ArgVars, VarTypes0, InstMap0, InstMap,
-		ArgTypes, ArgModes),
+
+	list__length(ExtraTypeInfos, NumExtraTypeInfos),
+	in_mode(InMode),
+	list__duplicate(NumExtraTypeInfos, InMode, InModes),
+	list__append(InModes, ArgModes, AllArgModes),
 
 	module_info_name(ModuleInfo0, ModuleName),
 	SymName = qualified(ModuleName, PredName),
-	Modes = argument_modes(InstTable, ArgModes),	% YYY
+	Modes = argument_modes(InstTable, AllArgModes),	% YYY
 
 		% Remove unneeded variables from the vartypes and varset.
 	goal_util__goal_vars(Goal0, GoalVars0), 
@@ -1036,9 +1172,10 @@
 		ProcInfo0),
 	proc_info_set_maybe_termination_info(ProcInfo0, TermInfo, ProcInfo),
 
+	map__apply_to_list(ArgVars, VarTypes, ArgTypes),
 	pred_info_create(ModuleName, SymName, TVarSet, ExistQVars, ArgTypes,
 		true, Context, local, Markers, predicate, ClassContext, 
-		ProcInfo, ProcId, PredInfo),
+		Owner, ProcInfo, ProcId, PredInfo),
 
 	module_info_get_predicate_table(ModuleInfo0, PredTable0),
 	predicate_table_insert(PredTable0, PredInfo, PredId,
@@ -1050,18 +1187,15 @@
 	Goal = GoalExpr - GoalInfo,
 	PredProcId = proc(PredId, ProcId).
 
-:- pred compute_arg_types_modes(list(prog_var)::in, map(prog_var, type)::in,
-	instmap::in, instmap::in, list(type)::out, list(mode)::out) is det.
+:- pred compute_arg_modes(list(prog_var)::in, instmap::in, instmap::in,
+		list(mode)::out) is det.
 
-compute_arg_types_modes([], _, _, _, [], []).
-compute_arg_types_modes([Var | Vars], VarTypes, InstMap0, InstMap,
-		[Type | Types], [Mode | Modes]) :-
-	map__lookup(VarTypes, Var, Type),
+compute_arg_modes([], _, _, []).
+compute_arg_modes([Var | Vars], InstMap0, InstMap, [Mode | Modes]) :-
 	instmap__lookup_var(InstMap0, Var, Inst0),
 	instmap__lookup_var(InstMap, Var, Inst),
 	Mode = (Inst0 -> Inst),
-	compute_arg_types_modes(Vars, VarTypes, InstMap0, InstMap,
-		Types, Modes).
+	compute_arg_modes(Vars, InstMap0, InstMap, Modes).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
<< snip >>
Index: unify_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/unify_gen.m,v
retrieving revision 1.83.2.11
diff -u -u -r1.83.2.11 unify_gen.m
--- unify_gen.m	1998/11/24 06:32:38	1.83.2.11
+++ unify_gen.m	1999/05/03 06:36:04
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1994-1998 The University of Melbourne.
+% Copyright (C) 1994-1999 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %---------------------------------------------------------------------------%
@@ -39,8 +39,8 @@
 
 :- import_module hlds_module, hlds_pred, prog_data, prog_out, code_util.
 :- import_module mode_util, type_util, code_aux, hlds_out, tree, arg_info.
-:- import_module inst_match.
-:- import_module term, bool, string, list, int, map, require, std_util.
+:- import_module globals, options, continuation_info, stack_layout, inst_match.
+:- import_module term, bool, string, int, list, map, require, std_util.
 
 :- type uni_val		--->	ref(prog_var)
 			;	lval(lval).
@@ -231,25 +231,28 @@
 unify_gen__generate_tag_rval_2(code_addr_constant(_, _), _Rval, _TestRval) :-
 	% This should never happen
 	error("Attempted code_addr unification").
-unify_gen__generate_tag_rval_2(base_type_info_constant(_, _, _), _, _) :-
+unify_gen__generate_tag_rval_2(type_ctor_info_constant(_, _, _), _, _) :-
 	% This should never happen
-	error("Attempted base_type_info unification").
+	error("Attempted type_ctor_info unification").
 unify_gen__generate_tag_rval_2(base_typeclass_info_constant(_, _, _), _, _) :-
 	% This should never happen
 	error("Attempted base_typeclass_info unification").
+unify_gen__generate_tag_rval_2(tabling_pointer_constant(_, _), _, _) :-
+	% This should never happen
+	error("Attempted tabling_pointer unification").
 unify_gen__generate_tag_rval_2(no_tag, _Rval, TestRval) :-
 	TestRval = const(true).
-unify_gen__generate_tag_rval_2(simple_tag(SimpleTag), Rval, TestRval) :-
+unify_gen__generate_tag_rval_2(unshared_tag(UnsharedTag), Rval, TestRval) :-
 	TestRval = binop(eq,	unop(tag, Rval),
-				unop(mktag, const(int_const(SimpleTag)))).
-unify_gen__generate_tag_rval_2(complicated_tag(Bits, Num), Rval, TestRval) :-
+				unop(mktag, const(int_const(UnsharedTag)))).
+unify_gen__generate_tag_rval_2(shared_remote_tag(Bits, Num), Rval, TestRval) :-
 	TestRval = binop(and,
 			binop(eq,	unop(tag, Rval),
 					unop(mktag, const(int_const(Bits)))), 
 			binop(eq,	lval(field(yes(Bits), Rval,
 						const(int_const(0)))),
 					const(int_const(Num)))).
-unify_gen__generate_tag_rval_2(complicated_constant_tag(Bits, Num), Rval,
+unify_gen__generate_tag_rval_2(shared_local_tag(Bits, Num), Rval,
 		TestRval) :-
 	TestRval = binop(eq,	Rval,
 			mkword(Bits, unop(mkbody, const(int_const(Num))))).
@@ -295,7 +298,7 @@
 		{ error(
 		"unify_gen__generate_construction_2: no_tag: arity != 1") }
 	).
-unify_gen__generate_construction_2(simple_tag(SimpleTag),
+unify_gen__generate_construction_2(unshared_tag(UnsharedTag),
 		Var, Args, Modes, IMDelta, Code) -->
 	code_info__get_module_info(ModuleInfo),
 	code_info__get_inst_table(InstTable),
@@ -309,14 +312,15 @@
 	{ unify_gen__var_type_msg(VarType, VarTypeMsg) },
 	% XXX Later we will need to worry about
 	% whether the cell must be unique or not.
-	{ Expr = create(SimpleTag, RVals, no, CellNo, VarTypeMsg) },
+	{ Expr = create(UnsharedTag, RVals, uniform(no), can_be_either,
+		CellNo, VarTypeMsg) },
 	code_info__cache_expression(Var, Expr),
 	unify_gen__aliased_vars_set_location(Args, ArgTypes, Modes,
-		InstMap0, InstMap, InstTable, ModuleInfo, Var, SimpleTag,
+		InstMap0, InstMap, InstTable, ModuleInfo, Var, UnsharedTag,
 		0, Code0),
 	unify_gen__maybe_place_refs(Var, Code1),
 	{ Code = tree(Code0, Code1) }.
-unify_gen__generate_construction_2(complicated_tag(Bits0, Num0),
+unify_gen__generate_construction_2(shared_remote_tag(Bits0, Num0),
 		Var, Args, Modes, IMDelta, Code) -->
 	code_info__get_module_info(ModuleInfo),
 	code_info__get_inst_table(InstTable),
@@ -332,17 +336,19 @@
 	{ unify_gen__var_type_msg(VarType, VarTypeMsg) },
 	% XXX Later we will need to worry about
 	% whether the cell must be unique or not.
-	{ Expr = create(Bits0, RVals, no, CellNo, VarTypeMsg) },
+	{ Expr = create(Bits0, RVals, uniform(no), can_be_either,
+		CellNo, VarTypeMsg) },
 	code_info__cache_expression(Var, Expr),
 	unify_gen__aliased_vars_set_location(Args, ArgTypes, Modes, InstMap0,
 		InstMap, InstTable, ModuleInfo, Var, Bits0, 1, Code0),
 	unify_gen__maybe_place_refs(Var, Code1),
 	{ Code = tree(Code0, Code1) }.
-unify_gen__generate_construction_2(complicated_constant_tag(Bits1, Num1),
+unify_gen__generate_construction_2(shared_local_tag(Bits1, Num1),
 		Var, _Args, _Modes, _IMDelta, Code) -->
-	unify_gen__cache_unification(Var,
-		mkword(Bits1, unop(mkbody, const(int_const(Num1)))), Code).
-unify_gen__generate_construction_2(base_type_info_constant(ModuleName,
+	{ Code = empty },
+	code_info__cache_expression(Var,
+		mkword(Bits1, unop(mkbody, const(int_const(Num1))))).
+unify_gen__generate_construction_2(type_ctor_info_constant(ModuleName,
 		TypeName, TypeArity), Var, Args, _Modes, _IMDelta, Code) -->
 	( { Args = [] } ->
 		[]
@@ -350,7 +356,7 @@
 		{ error("unify_gen: type-info constant has args") }
 	),
 	unify_gen__cache_unification(Var, const(data_addr_const(data_addr(
-		ModuleName, base_type(info, TypeName, TypeArity)))), Code).
+		ModuleName, type_ctor(info, TypeName, TypeArity)))), Code).
 unify_gen__generate_construction_2(base_typeclass_info_constant(ModuleName,
 		ClassId, Instance), Var, Args, _Modes, _IMDelta, Code) -->
 	( { Args = [] } ->
@@ -358,8 +364,22 @@
 	;
 		{ error("unify_gen: typeclass-info constant has args") }
 	),
-	unify_gen__cache_unification(Var, const(data_addr_const(data_addr(
-		ModuleName, base_typeclass_info(ClassId, Instance)))), Code).
+	{ Code = empty },
+	code_info__cache_expression(Var, const(data_addr_const(data_addr(
+		ModuleName, base_typeclass_info(ClassId, Instance))))).
+unify_gen__generate_construction_2(tabling_pointer_constant(PredId, ProcId),
+		Var, Args, _Modes, _IMDelta, Code) -->
+	( { Args = [] } ->
+		[]
+	;
+		{ error("unify_gen: tabling pointer constant has args") }
+	),
+	{ Code = empty },
+	code_info__get_module_info(ModuleInfo),
+	{ code_util__make_proc_label(ModuleInfo, PredId, ProcId, ProcLabel) },
+	{ module_info_name(ModuleInfo, ModuleName) },
+	{ DataAddr = data_addr(ModuleName, tabling_pointer(ProcLabel)) },
+	code_info__cache_expression(Var, const(data_addr_const(DataAddr))).
 unify_gen__generate_construction_2(code_addr_constant(PredId, ProcId),
 		Var, Args, _Modes, _IMDelta, Code) -->
 	( { Args = [] } ->
@@ -373,6 +393,9 @@
 		Code).
 unify_gen__generate_construction_2(pred_closure_tag(PredId, ProcId),
 		Var, Args, Modes, IMDelta, Code) -->
+	% This code constructs or extends a closure.
+	% The structure of closures is defined in runtime/mercury_ho_call.h.
+
 	code_info__get_module_info(ModuleInfo),
 	{ module_info_preds(ModuleInfo, Preds) },
 	{ map__lookup(Preds, PredId, PredInfo) },
@@ -402,8 +425,16 @@
 % new closure P from the old closure P0 by appending the args X, Y, Z.
 % The advantage of this optimization is that when P is called, we
 % will only need to do one indirect call rather than two.
-% (Hmm... is this optimization really worth it?  It probably
-% doesn't happen very often, and it's not guaranteed to be a win.)
+% Its disadvantage is that the cost of creating the closure P is greater.
+% Whether this is a net win depend on the number of times P is called.
+%
+% The pattern that this optimization looks for happens rarely at the moment.
+% The reason is that although we allow the creation of closures with a simple
+% syntax (e.g. P0 = append4([1])), we don't allow their extension with a
+% similarly simple syntax (e.g. P = call(P0, [2])). In fact, typecheck.m
+% contains code to detect such constructs, because it does not have code
+% to typecheck them (you get a message about call/2 should be used as a goal,
+% not an expression).
 %
 	{ proc_info_goal(ProcInfo, ProcInfoGoal) },
 	{ proc_info_interface_code_model(ProcInfo, CodeModel) },
@@ -428,46 +459,63 @@
 		% closure
 		code_info__produce_variable(CallPred, Code98, Value)
 	    ;
-		code_info__get_next_label(LoopEnd),
 		code_info__get_next_label(LoopStart),
+		code_info__get_next_label(LoopTest),
 		code_info__acquire_reg(r, LoopCounter),
 		code_info__acquire_reg(r, NumOldArgs),
 		code_info__acquire_reg(r, NewClosure),
 		{ Zero = const(int_const(0)) },
 		{ One = const(int_const(1)) },
+		{ Two = const(int_const(2)) },
+		{ Three = const(int_const(3)) },
 		{ list__length(CallArgs, NumNewArgs) },
 		{ NumNewArgs_Rval = const(int_const(NumNewArgs)) },
-		{ NumNewArgsPlusTwo is NumNewArgs + 2 },
-		{ NumNewArgsPlusTwo_Rval =
-			const(int_const(NumNewArgsPlusTwo)) },
+		{ NumNewArgsPlusThree is NumNewArgs + 3 },
+		{ NumNewArgsPlusThree_Rval =
+			const(int_const(NumNewArgsPlusThree)) },
 		code_info__produce_variable(CallPred, Code1, OldClosure),
 		{ Code2 = node([
 			comment("build new closure from old closure") - "",
 			assign(NumOldArgs,
-				lval(field(yes(0), OldClosure, Zero)))
+				lval(field(yes(0), OldClosure, Two)))
 				- "get number of arguments",
 			incr_hp(NewClosure, no,
 				binop(+, lval(NumOldArgs),
-				NumNewArgsPlusTwo_Rval), "closure")
+				NumNewArgsPlusThree_Rval), "closure")
 				- "allocate new closure",
 			assign(field(yes(0), lval(NewClosure), Zero),
+				lval(field(yes(0), OldClosure, Zero)))
+				- "set closure layout structure",
+			assign(field(yes(0), lval(NewClosure), One),
+				lval(field(yes(0), OldClosure, One)))
+				- "set closure code pointer",
+			assign(field(yes(0), lval(NewClosure), Two),
 				binop(+, lval(NumOldArgs), NumNewArgs_Rval))
 				- "set new number of arguments",
-			assign(LoopCounter, Zero)
+			assign(NumOldArgs, binop(+, lval(NumOldArgs), Three))
+				- "set up loop limit",
+			assign(LoopCounter, Three)
 				- "initialize loop counter",
+			% It is possible for the number of hidden arguments
+			% to be zero, in which case the body of this loop
+			% should not be executed at all. This is why we
+			% jump to the loop condition test.
+			goto(label(LoopTest))
+				- "enter the copy loop at the conceptual top",
 			label(LoopStart) - "start of loop",
-			assign(LoopCounter,
-				binop(+, lval(LoopCounter), One))
-				- "increment loop counter",
 			assign(field(yes(0), lval(NewClosure),
 					lval(LoopCounter)),
 				lval(field(yes(0), OldClosure,
 					lval(LoopCounter))))
-				- "copy old field",
-			if_val(binop(<=, lval(LoopCounter),
-				lval(NumOldArgs)), label(LoopStart))
-				- "repeat the loop?",
-			label(LoopEnd) - "end of loop"
+				- "copy old hidden argument",
+			assign(LoopCounter,
+				binop(+, lval(LoopCounter), One))
+				- "increment loop counter",
+			label(LoopTest)
+				- "do we have more old arguments to copy?",
+			if_val(binop(<, lval(LoopCounter), lval(NumOldArgs)),
+				label(LoopStart))
+				- "repeat the loop?"
 		]) },
 		unify_gen__generate_extra_closure_args(CallArgs,
 			LoopCounter, NewClosure, Code3),
@@ -481,15 +529,50 @@
 	    { SkipFirstArg = yes }
 	;
 		{ Code98 = empty },
-		{ proc_info_arg_info(ProcInfo, ArgInfo) },
 		code_info__make_entry_label(ModuleInfo, PredId, ProcId, no,
-				CodeAddress),
-		code_info__get_next_cell_number(CellNo),
+			CodeAddr),
+		{ code_util__extract_proc_label_from_code_addr(CodeAddr,
+			ProcLabel) },
+		{ globals__lookup_bool_option(Globals, typeinfo_liveness,
+			TypeInfoLiveness) },
+		{
+			TypeInfoLiveness = yes,
+			continuation_info__generate_closure_layout(
+				ModuleInfo, PredId, ProcId, ClosureInfo),
+			MaybeClosureInfo = yes(ClosureInfo)
+		;
+			TypeInfoLiveness = no,
+			% In the absence of typeinfo liveness, procedures
+			% are not guaranteed to have typeinfos for all the
+			% type variables in their signatures. Such a missing
+			% typeinfo would cause a compile-time abort in
+			% continuation_info__generate_closure_layout,
+			% and even if that predicate was modified,
+			% we still couldn't generate a usable layout
+			% structure.
+			MaybeClosureInfo = no
+		},
+		code_info__get_cell_count(CNum0),
+		{ stack_layout__construct_closure_layout(ProcLabel,
+			MaybeClosureInfo, ClosureLayoutMaybeRvals,
+			ClosureLayoutArgTypes, CNum0, CNum) },
+		code_info__set_cell_count(CNum),
+		code_info__get_next_cell_number(ClosureLayoutCellNo),
+		{ ClosureLayout = create(0, ClosureLayoutMaybeRvals,
+			ClosureLayoutArgTypes, must_be_static,
+			ClosureLayoutCellNo, "closure_layout") },
 		{ list__length(Args, NumArgs) },
+		{ proc_info_arg_info(ProcInfo, ArgInfo) },
 		{ unify_gen__generate_pred_args(Args, ArgInfo, PredArgs) },
-		{ Vector = [yes(const(int_const(NumArgs))),
-			yes(const(code_addr_const(CodeAddress))) | PredArgs] },
-		{ Value = create(0, Vector, no, CellNo, "closure") },
+		{ Vector = [
+			yes(ClosureLayout),
+			yes(const(code_addr_const(CodeAddr))),
+			yes(const(int_const(NumArgs)))
+			| PredArgs
+		] },
+		code_info__get_next_cell_number(ClosureCellNo),
+		{ Value = create(0, Vector, uniform(no), can_be_either,
+			ClosureCellNo, "closure") },
 		{ NumExtraProcArgs = 0 },
 		{ SkipFirstArg = no }
 	),
@@ -552,25 +635,26 @@
 	code_info__produce_variable(Var, Code0, Value),
 	{ One = const(int_const(1)) },
 	{ Code1 = node([
-		assign(LoopCounter,
-			binop(+, lval(LoopCounter), One))
-			- "increment argument counter",
 		assign(field(yes(0), lval(NewClosure), lval(LoopCounter)),
 			Value)
-			- "set new argument field"
+			- "set new argument field",
+		assign(LoopCounter,
+			binop(+, lval(LoopCounter), One))
+			- "increment argument counter"
 	]) },
 	{ Code = tree(tree(Code0, Code1), Code2) },
 	unify_gen__generate_extra_closure_args(Vars, LoopCounter,
 		NewClosure, Code2).
 
 :- pred unify_gen__generate_pred_args(list(prog_var), list(arg_info),
-					list(maybe(rval))).
+	list(maybe(rval))).
 :- mode unify_gen__generate_pred_args(in, in, out) is det.
 
 unify_gen__generate_pred_args([], _, []).
 unify_gen__generate_pred_args([_|_], [], _) :-
 	error("unify_gen__generate_pred_args: insufficient args").
-unify_gen__generate_pred_args([Var|Vars], [ArgInfo|ArgInfos], [Rval|Rvals]) :-
+unify_gen__generate_pred_args([Var | Vars], [ArgInfo | ArgInfos],
+		[Rval | Rvals]) :-
 	ArgInfo = arg_info(_, ArgMode),
 	( ArgMode = top_in ->
 		Rval = yes(var(Var))
@@ -738,12 +822,15 @@
 		{ Tag = code_addr_constant(_, _) },
 		{ Code = empty }
 	;
-		{ Tag = base_type_info_constant(_, _, _) },
+		{ Tag = type_ctor_info_constant(_, _, _) },
 		{ Code = empty }
 	;
 		{ Tag = base_typeclass_info_constant(_, _, _) },
 		{ Code = empty }
 	;
+		{ Tag = tabling_pointer_constant(_, _) },
+		{ Code = empty }
+	;
 		{ Tag = no_tag },
 		( { Args = [Arg], Modes = [Mode] } ->
 			code_info__variable_type(Arg, Type),
@@ -753,15 +840,15 @@
 			{ error("unify_gen__generate_det_deconstruction: no_tag: arity != 1") }
 		)
 	;
-		{ Tag = simple_tag(SimpleTag) },
+		{ Tag = unshared_tag(UnsharedTag) },
 		{ Rval = var(Var) },
 		{ unify_gen__make_fields_and_argvars(Args, Rval, 0,
-			SimpleTag, Fields, ArgVars) },
+			UnsharedTag, Fields, ArgVars) },
 		unify_gen__var_types(Args, ArgTypes),
 		unify_gen__generate_unify_args(Fields, ArgVars,
 			Modes, ArgTypes, IMDelta, Code)
 	;
-		{ Tag = complicated_tag(Bits0, _Num0) },
+		{ Tag = shared_remote_tag(Bits0, _Num0) },
 		{ Rval = var(Var) },
 		{ unify_gen__make_fields_and_argvars(Args, Rval, 1,
 			Bits0, Fields, ArgVars) },
@@ -769,7 +856,7 @@
 		unify_gen__generate_unify_args(Fields, ArgVars,
 			Modes, ArgTypes, IMDelta, Code)
 	;
-		{ Tag = complicated_constant_tag(_Bits1, _Num1) },
+		{ Tag = shared_local_tag(_Bits1, _Num1) },
 		{ Code = empty } % if this is det, then nothing happens
 	).
 
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list