[m-dev.] for review: layouts in all closures

Zoltan Somogyi zs at cs.mu.OZ.AU
Mon Aug 9 17:37:40 AEST 1999


This is for review by Tyson (or Fergus, although that part is always
understood even if omitted :-).

BTW, the previous diffs were required to help me track down the problem
in middle_rec.

Estimated hours taken: 50

Make closures always include layout information, not just in grades in which
typeinfo liveness is turned on. This requires separating two notions,
which were previously combined:

-	Body typeinfo liveness means that when a variable X is live, any
	typeinfo variables describing type variables that occur in the type
	of X must also be live.

-	Interface typeinfo liveness means that when the input arguments
	of a procedure include a polymorphically typed variable (e.g. X),
	typeinfo variables describing type variables that occur in the type
	of X must also be among the arguments.

This change turns on interface typeinfo liveness for procedures that either
have their address taken in the current module, or are exported and thus may
have their address taken in some other module.

compiler/hlds_pred.m:
	Centralize decisions wrt whether procedure interfaces and bodies
	use typeinfo liveness here.

compiler/options.m:
compiler/handle_options.m:
	Rename the typeinfo_liveness option as typeinfo_liveness_hidden,
	to discourage its direct use.

compiler/call_gen.m:
compiler/higher_order.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/unused_args.m:
	Use hlds_pred.m to make decisions about liveness.

compiler/lambda.m:
	Always include the relevant typeinfos in the interfaces of procedures
	created for lambdas.

compiler/continuation_info.m:
compiler/stack_layout.m:
compiler/unify_gen.m:
	Modify the predicates that record and use layout information about
	closures to always do so, since the necessary information is now
	always available about the interfaces of procedures whcih can be
	put into closures. Previously, they only did so if typeinfo_liveness
	was set.

	Also, generate information about the types of the variables in a
	closure from the pred_info's arg types field, not from the proc_info's
	var types field, because unlike the latter, it is valid even for
	imported predicates.

compiler/hlds_out.m:
	Print the non-clause-related information in the clauses_info part
	of a pred_info (e.g. the type parameters) even if the predicate
	has no actual clauses. Simplify the code a bit by getting rid of
	a duplicate test.

compiler/middle_rec.m:
	Require that the code generated for the base case not refer to any
	stack slots if this way of generating code is to be used. This is
	necessary because the base case is executed when the current procedure
	has no stack frame, and thus any references to stack slots would
	refer to and possibly overwrite the data in another procedure's frame.
	In the absence of requiring body typeinfo liveness for exported
	procedures, such references were not generated; in its presence,
	they were. However, we now require only interface liveness for
	exported procedures, so we can still use middle recursion for them.

Zoltan.

cvs diff: Diffing compiler
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.133
diff -u -b -r1.133 call_gen.m
--- call_gen.m	1999/07/13 08:52:41	1.133
+++ call_gen.m	1999/07/16 09:12:48
@@ -437,11 +437,15 @@
 	code_info__get_known_variables(Variables0),
 	{ set__list_to_set(Variables0, Vars0) },
 	{ set__difference(Vars0, Args, Vars1) },
+	code_info__get_module_info(ModuleInfo),
+	code_info__get_pred_id(PredId),
+	code_info__get_proc_id(ProcId),
 	code_info__get_globals(Globals),
-	{ globals__lookup_bool_option(Globals, typeinfo_liveness, 
-		TypeinfoLiveness) },
+	{ module_info_pred_info(ModuleInfo, PredId, PredInfo) },
+	{ proc_should_use_typeinfo_liveness(PredInfo, ProcId, Globals,
+		TypeInfoLiveness) },
 	( 
-		{ TypeinfoLiveness = yes }
+		{ TypeInfoLiveness = yes }
 	->
 		code_info__get_proc_info(ProcInfo),
 		{ proc_info_get_typeinfo_vars_setwise(ProcInfo, Vars1, 
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.24
diff -u -b -r1.24 continuation_info.m
--- continuation_info.m	1999/07/13 08:52:45	1.24
+++ continuation_info.m	1999/07/29 05:07:26
@@ -559,42 +559,49 @@
 
 continuation_info__generate_closure_layout(ModuleInfo, PredId, ProcId,
 		ClosureLayout) :-
-	module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo),
+	module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
+		PredInfo, ProcInfo),
 	proc_info_headvars(ProcInfo, HeadVars),
 	proc_info_arg_info(ProcInfo, ArgInfos),
-	proc_info_vartypes(ProcInfo, VarTypes),
+	pred_info_arg_types(PredInfo, ArgTypes),
 	proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap),
 	map__init(VarLocs0),
 	set__init(TypeVars0),
 	assoc_list__from_corresponding_lists(HeadVars, ArgInfos, VarArgInfos),
-	continuation_info__build_closure_info(VarArgInfos, ArgLayouts,
-		VarTypes, InstMap, VarLocs0, VarLocs, TypeVars0, TypeVars),
+	(
+		continuation_info__build_closure_info(ArgTypes, VarArgInfos,
+			ArgLayouts, InstMap, 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).
+		continuation_info__find_typeinfos_for_tvars(TypeVarsList,
+			VarLocs, ProcInfo, TypeInfoDataMap),
+		ClosureLayout = closure_layout_info(ArgLayouts,
+			TypeInfoDataMap)
+	;
+		error("proc headvars and pred argtypes disagree on arity")
+	).
 
-:- pred continuation_info__build_closure_info(
+:- pred continuation_info__build_closure_info(list(type)::in,
 	assoc_list(prog_var, arg_info)::in,  list(closure_arg_info)::out,
-	map(prog_var, type)::in, instmap::in,
-	map(prog_var, set(rval))::in, map(prog_var, set(rval))::out,
-	set(tvar)::in, set(tvar)::out) is det.
+	instmap::in, map(prog_var, set(rval))::in,
+	map(prog_var, set(rval))::out, set(tvar)::in, set(tvar)::out)
+	is semidet.
 
-continuation_info__build_closure_info([], [], _, _, VarLocs, VarLocs,
+continuation_info__build_closure_info([], [], [], _, VarLocs, VarLocs,
 		TypeVars, TypeVars).
-continuation_info__build_closure_info([Var - ArgInfo | VarArgInfos],
-		[Layout | Layouts], VarTypes, InstMap,
-		VarLocs0, VarLocs, TypeVars0, TypeVars) :-
+continuation_info__build_closure_info([Type | Types],
+		[Var - ArgInfo | VarArgInfos], [Layout | Layouts],
+		InstMap, 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, VarLocs1, VarLocs, TypeVars1, TypeVars).
+	continuation_info__build_closure_info(Types, VarArgInfos, Layouts,
+		InstMap, VarLocs1, VarLocs, TypeVars1, TypeVars).
 
 %---------------------------------------------------------------------------%
 
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.76
diff -u -b -r1.76 handle_options.m
--- handle_options.m	1999/06/01 09:43:45	1.76
+++ handle_options.m	1999/06/01 10:54:19
@@ -351,7 +351,7 @@
 			% The following options cause the info required
 			% by tracing to be generated.
 		globals__io_set_option(trace_stack_layout, bool(yes)),
-		globals__io_set_option(typeinfo_liveness, bool(yes))
+		globals__io_set_option(typeinfo_liveness_hidden, bool(yes))
 	;
 		[]
 	),
@@ -369,7 +369,7 @@
 	% and needs hijacks and frameopt to be switched off.
 	( { GC_Method = accurate } ->
 		globals__io_set_option(agc_stack_layout, bool(yes)),
-		globals__io_set_option(typeinfo_liveness, bool(yes)),
+		globals__io_set_option(typeinfo_liveness_hidden, bool(yes)),
 		globals__io_set_option(allow_hijacks, bool(no)),
 		globals__io_set_option(optimize_frames, bool(no))
 	;
@@ -382,13 +382,13 @@
 
 	% XXX deforestation does not perform folding on polymorphic
 	% predicates correctly with --typeinfo-liveness.
-	option_implies(typeinfo_liveness, deforestation, bool(no)),
+	option_implies(typeinfo_liveness_hidden, deforestation, bool(no)),
 
 	% XXX middle_rec doesn't work with --typeinfo-liveness,
 	% because --typeinfo-liveness causes the stack to be used
 	% in places where middle_rec is not expecting it and has
 	% hence not set up a stack frame.
-	option_implies(typeinfo_liveness, middle_rec, bool(no)),
+	option_implies(typeinfo_liveness_hidden, middle_rec, bool(no)),
 
 	% XXX value numbering implements the wrong semantics for LLDS
 	% operations involving tickets, which are generated only with
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.53
diff -u -b -r1.53 higher_order.m
--- higher_order.m	1999/07/13 08:52:55	1.53
+++ higher_order.m	1999/07/16 09:35:14
@@ -47,13 +47,19 @@
 	% Iterate collecting requests and processing them until there
 	% are no more requests remaining.
 specialize_higher_order(ModuleInfo0, ModuleInfo) -->
-	globals__io_lookup_bool_option(optimize_higher_order, HigherOrder),
-	globals__io_lookup_bool_option(type_specialization, TypeSpec),
-	globals__io_lookup_bool_option(user_guided_type_specialization,
-		UserTypeSpec),
-	globals__io_lookup_int_option(higher_order_size_limit, SizeLimit),
-	globals__io_lookup_bool_option(typeinfo_liveness,
-		TypeInfoLiveness),
+	globals__io_get_globals(Globals),
+	{ globals__lookup_bool_option(Globals, optimize_higher_order,
+		HigherOrder) },
+	{ globals__lookup_bool_option(Globals, type_specialization,
+		TypeSpec) },
+	{ globals__lookup_bool_option(Globals, user_guided_type_specialization,
+		UserTypeSpec) },
+	{ globals__lookup_int_option(Globals, higher_order_size_limit,
+		SizeLimit) },
+		% A newly created procedure is local and cannot have had
+		% its address taken.
+	{ should_use_typeinfo_liveness(local, address_is_not_taken, Globals,
+		TypeInfoLiveness) },
 	{ Params = ho_params(HigherOrder, TypeSpec,
 		UserTypeSpec, SizeLimit, TypeInfoLiveness) },
 	{ map__init(NewPredMap) },
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.223
diff -u -b -r1.223 hlds_out.m
--- hlds_out.m	1999/07/13 08:52:58	1.223
+++ hlds_out.m	1999/07/21 04:38:35
@@ -699,6 +699,11 @@
 	),
 	{ ClausesInfo = clauses_info(VarSet, _, VarTypes, HeadVars, Clauses,
 		TypeInfoMap, TypeClassInfoMap) },
+	( { string__contains_char(Verbose, 'v') } ->
+		{ AppendVarnums = yes }
+	;
+		{ AppendVarnums = no }
+	),
 	( { string__contains_char(Verbose, 'C') } ->
 		hlds_out__write_indent(Indent),
 		io__write_string("% pred id: "),
@@ -741,18 +746,8 @@
 			io__write_list(Indexes, ", ",
 				mercury_output_index_spec),
 			io__nl
-		)
-	;
-		[]
 	),
 
-	( { string__contains_char(Verbose, 'v') } ->
-		{ AppendVarnums = yes }
-	;
-		{ AppendVarnums = no }
-	),
-
-	( { string__contains_char(Verbose, 'C'), Clauses \= [] } ->
 		( { HeadTypeParams \= [] } ->
 			io__write_string(
 				"% head_type_params:\n"),
@@ -766,13 +761,19 @@
 		hlds_out__write_var_types(Indent, VarSet, AppendVarnums,
 			VarTypes, TVarSet),
 
+		( { Clauses \= [] } ->
 		% Never write the clauses out verbosely -
-		% disable the dump_hlds_options option before writing them,
-		% and restore its initial value afterwards
+			% disable the dump_hlds_options option before writing
+			% them, and restore its initial value afterwards
 		globals__io_set_option(dump_hlds_options, string("")),
-		hlds_out__write_clauses(Indent, ModuleInfo, PredId, VarSet,
-			AppendVarnums, HeadVars, PredOrFunc, Clauses, no),
-		globals__io_set_option(dump_hlds_options, string(Verbose))
+			hlds_out__write_clauses(Indent, ModuleInfo, PredId,
+				VarSet, AppendVarnums, HeadVars, PredOrFunc,
+				Clauses, no),
+			globals__io_set_option(dump_hlds_options,
+				string(Verbose))
+		;
+			[]
+		)
 	;
 		[]
 	),
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.63
diff -u -b -r1.63 hlds_pred.m
--- hlds_pred.m	1999/07/14 04:17:11	1.63
+++ hlds_pred.m	1999/07/16 09:54:46
@@ -14,13 +14,13 @@
 :- interface.
 
 :- import_module hlds_data, hlds_goal, hlds_module, llds, prog_data, instmap.
-:- import_module term_util.
+:- import_module globals, term_util.
 :- import_module bool, list, set, map, std_util, term, varset.
 
 :- implementation.
 
 :- import_module code_aux, goal_util, make_hlds, prog_util.
-:- import_module mode_util, type_util, globals, options.
+:- import_module mode_util, type_util, options.
 :- import_module int, string, require, assoc_list.
 
 %-----------------------------------------------------------------------------%
@@ -1225,7 +1225,8 @@
 	% Similarly if the address of a procedure of this predicate is taken,
 	% so that we can copy the closure.
 	module_info_globals(ModuleInfo0, Globals),
-	globals__lookup_bool_option(Globals, typeinfo_liveness,
+	ExportStatus = local,
+	should_use_typeinfo_liveness(ExportStatus, IsAddressTaken, Globals,
 		TypeInfoLiveness),
 	( TypeInfoLiveness = yes ->
 		goal_info_get_nonlocals(GoalInfo, NonLocals),
@@ -1268,7 +1269,7 @@
 	set__init(Assertions),
 
 	pred_info_create(ModuleName, SymName, TVarSet, ExistQVars, ArgTypes,
-		true, Context, local, Markers, predicate, ClassContext, 
+		true, Context, ExportStatus, Markers, predicate, ClassContext, 
 		Owner, Assertions, ProcInfo, ProcId, PredInfo),
 
 	module_info_get_predicate_table(ModuleInfo0, PredTable0),
@@ -1494,6 +1495,17 @@
 		list(type), list(prog_var), proc_info).
 :- mode proc_info_create_vars_from_types(in, in, out, out) is det.
 
+	% Return true if the given procedure should use typeinfo liveness.
+:- pred proc_should_use_typeinfo_liveness(pred_info, proc_id, globals, bool).
+:- mode proc_should_use_typeinfo_liveness(in, in, in, out) is det.
+
+	% Return true if a procedure should use typeinfo liveness,
+	% based on the options, whether the procedure has its address taken,
+	% and whether the procedure is exported.
+:- pred should_use_typeinfo_liveness(import_status, is_address_taken,
+		globals, bool).
+:- mode should_use_typeinfo_liveness(in, in, in, out) is det.
+
 :- implementation.
 
 :- type proc_info
@@ -1552,6 +1564,11 @@
 					% typeinfo liveness for them, so that
 					% deep_copy and accurate gc have the
 					% RTTI they need for copying closures.
+					%
+					% Note that any exported procedure
+					% must be considered as having its
+					% address taken, since it is possible
+					% that some other module may do so.
 			maybe(rl_exprn_id)
 					% For predicates with an
 					% `aditi_top_down' marker, which are
@@ -1999,6 +2016,35 @@
 		NewVars, Types, VarTypes),
 	proc_info_set_varset(ProcInfo0, VarSet, ProcInfo1),
 	proc_info_set_vartypes(ProcInfo1, VarTypes, ProcInfo).
+
+proc_should_use_typeinfo_liveness(PredInfo, ProcId, Globals,
+		TypeInfoLiveness) :-
+	pred_info_import_status(PredInfo, Status),
+	pred_info_procedures(PredInfo, ProcTable),
+	map__lookup(ProcTable, ProcId, ProcInfo),
+	proc_info_is_address_taken(ProcInfo, IsAddressTaken),
+	should_use_typeinfo_liveness(Status, IsAddressTaken, Globals,
+		TypeInfoLiveness).
+
+should_use_typeinfo_liveness(Status, IsAddressTaken, Globals,
+		TypeInfoLiveness) :-
+	(
+		(
+			IsAddressTaken = address_is_taken
+		;
+			% If the predicate is exported, its address may have
+			% been taken elsewhere. If it is imported, then it
+			% follows that it must be exported somewhere.
+			Status \= local
+		;
+			globals__lookup_bool_option(Globals,
+				typeinfo_liveness_hidden, yes)
+		)
+	->
+		TypeInfoLiveness = yes
+	;
+		TypeInfoLiveness = no
+	).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/lambda.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lambda.m,v
retrieving revision 1.54
diff -u -b -r1.54 lambda.m
--- lambda.m	1999/07/30 05:17:34	1.54
+++ lambda.m	1999/08/03 09:45:24
@@ -363,18 +363,10 @@
 	LambdaGoal = _ - LambdaGoalInfo,
 	goal_info_get_nonlocals(LambdaGoalInfo, NonLocals0),
 	set__delete_list(NonLocals0, Vars, NonLocals1),
-	module_info_globals(ModuleInfo0, Globals),
 
-	% If typeinfo_liveness is set, all type_infos for the
-	% arguments should be included, not just the ones
-	% that are used.
-	globals__lookup_bool_option(Globals,
-		typeinfo_liveness, TypeInfoLiveness),
-	( TypeInfoLiveness = yes ->
-		set__union(NonLocals1, ExtraTypeInfos, NonLocals)
-	;
-		NonLocals = NonLocals1
-	),
+	% We need all the typeinfos, including the ones that are not used,
+	% for the layout structure describing the closure.
+	set__union(NonLocals1, ExtraTypeInfos, NonLocals),
 
 	set__to_sorted_list(NonLocals, ArgVars1),
 	( 
Index: compiler/live_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.83
diff -u -b -r1.83 live_vars.m
--- live_vars.m	1999/07/13 08:53:03	1.83
+++ live_vars.m	1999/07/16 09:38:41
@@ -25,9 +25,9 @@
 
 :- import_module hlds_module, hlds_pred.
 
-:- pred allocate_stack_slots_in_proc(proc_info, pred_id, module_info,
+:- pred allocate_stack_slots_in_proc(proc_info, pred_id, proc_id, module_info,
 	proc_info).
-:- mode allocate_stack_slots_in_proc(in, in, in, out) is det.
+:- mode allocate_stack_slots_in_proc(in, in, in, in, out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -42,11 +42,12 @@
 
 %-----------------------------------------------------------------------------%
 
-allocate_stack_slots_in_proc(ProcInfo0, PredId, ModuleInfo, ProcInfo) :-
+allocate_stack_slots_in_proc(ProcInfo0, PredId, ProcId, ModuleInfo, ProcInfo)
+		:-
 	proc_info_goal(ProcInfo0, Goal0),
 	proc_info_interface_code_model(ProcInfo0, CodeModel),
 
-	initial_liveness(ProcInfo0, PredId, ModuleInfo, Liveness0),
+	initial_liveness(ProcInfo0, PredId, ProcId, ModuleInfo, Liveness0),
 	set__init(LiveSets0),
 	module_info_globals(ModuleInfo, Globals),
 	globals__get_trace_level(Globals, TraceLevel),
@@ -58,8 +59,12 @@
 		LiveSets1 = LiveSets0
 	),
 	trace__reserved_slots(ProcInfo0, Globals, NumReservedSlots),
+	module_info_pred_info(ModuleInfo, PredId, PredInfo),
+	proc_should_use_typeinfo_liveness(PredInfo, ProcId, Globals,
+		TypeInfoLiveness),
 	build_live_sets_in_goal(Goal0, Liveness0, ResumeVars0, LiveSets1,
-		ModuleInfo, ProcInfo0, _Liveness, _ResumeVars, LiveSets),
+		ModuleInfo, ProcInfo0, TypeInfoLiveness,
+		_Liveness, _ResumeVars, LiveSets),
 	graph_colour__group_elements(LiveSets, ColourSets),
 	set__to_sorted_list(ColourSets, ColourList),
 	allocate_stack_slots(ColourList, CodeModel, NumReservedSlots,
@@ -75,12 +80,14 @@
 % delta annotations.
 
 :- pred build_live_sets_in_goal(hlds_goal, set(prog_var), set(prog_var),
-	set(set(prog_var)), module_info, proc_info, set(prog_var),
-	set(prog_var), set(set(prog_var))).
-:- mode build_live_sets_in_goal(in, in, in, in, in, in, out, out, out) is det.
+	set(set(prog_var)), module_info, proc_info, bool,
+	set(prog_var), set(prog_var), set(set(prog_var))).
+:- mode build_live_sets_in_goal(in, in, in, in, in, in, in, out, out, out)
+	is det.
 
 build_live_sets_in_goal(Goal0 - GoalInfo, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets) :-
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets) :-
 	% note: we must be careful to apply deaths before births
 	goal_info_get_pre_deaths(GoalInfo, PreDeaths),
 	goal_info_get_pre_births(GoalInfo, PreBirths),
@@ -129,7 +136,7 @@
 	),
 
 	build_live_sets_in_goal_2(Goal0, Liveness3, ResumeVars1, LiveSets1,
-		GoalInfo, ModuleInfo, ProcInfo,
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness4, ResumeVars, LiveSets2),
 
 	(
@@ -172,19 +179,21 @@
 	% of variables which need to be on the stack at the same time.
 
 :- pred build_live_sets_in_goal_2(hlds_goal_expr, set(prog_var), set(prog_var),
-	set(set(prog_var)), hlds_goal_info, module_info, proc_info,
+	set(set(prog_var)), hlds_goal_info, module_info, proc_info, bool,
 	set(prog_var), set(prog_var), set(set(prog_var))).
-:- mode build_live_sets_in_goal_2(in, in, in, in, in, in, in, out, out, out)
-	is det.
+:- mode build_live_sets_in_goal_2(in, in, in, in, in, in, in, in,
+	out, out, out) is det.
 
 build_live_sets_in_goal_2(conj(Goals0), Liveness0, ResumeVars0, LiveSets0,
-		_, ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets) :-
+		_, ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets) :-
 	build_live_sets_in_conj(Goals0, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets).
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets).
 
 build_live_sets_in_goal_2(par_conj(Goals0, _SM), Liveness0, ResumeVars0,
-		LiveSets0, GoalInfo, ModuleInfo, ProcInfo, Liveness,
-		ResumeVars, LiveSets) :-
+		LiveSets0, GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets) :-
 	goal_info_get_nonlocals(GoalInfo, NonLocals),
 	set__union(NonLocals, Liveness0, LiveSet),
 		% We insert all the union of the live vars and the nonlocals.
@@ -199,41 +208,52 @@
 		% of independent goals, so we can use it for parallel conj's
 		% too.
 	build_live_sets_in_disj(Goals0, Liveness0, ResumeVars0, LiveSets1,
-		GoalInfo, ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets).
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets).
 
 build_live_sets_in_goal_2(disj(Goals0, _), Liveness0, ResumeVars0, LiveSets0,
-		GoalInfo, ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets)
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets)
 		:-
 	build_live_sets_in_disj(Goals0, Liveness0, ResumeVars0, LiveSets0,
-		GoalInfo, ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets).
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets).
 
-build_live_sets_in_goal_2(switch(_, _, Cases0, _), Liveness0,
-		ResumeVars0, LiveSets0, _, ModuleInfo, ProcInfo, Liveness,
-		ResumeVars, LiveSets) :-
+build_live_sets_in_goal_2(switch(_, _, Cases0, _),
+		Liveness0, ResumeVars0, LiveSets0, _,
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets) :-
 	build_live_sets_in_cases(Cases0, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets).
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets).
 
 build_live_sets_in_goal_2(if_then_else(_Vars, Cond0, Then0, Else0, _),
-		Liveness0, ResumeVars0, LiveSets0, _, ModuleInfo, ProcInfo,
+		Liveness0, ResumeVars0, LiveSets0, _,
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness, ResumeVars, LiveSets) :-
 	build_live_sets_in_goal(Cond0, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness1, ResumeVars1, LiveSets1),
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness1, ResumeVars1, LiveSets1),
 	build_live_sets_in_goal(Then0, Liveness1, ResumeVars1, LiveSets1,
-		ModuleInfo, ProcInfo, _Liveness2, ResumeVars2, LiveSets2),
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		_Liveness2, ResumeVars2, LiveSets2),
 	build_live_sets_in_goal(Else0, Liveness0, ResumeVars0, LiveSets2,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars3, LiveSets),
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars3, LiveSets),
 	set__union(ResumeVars2, ResumeVars3, ResumeVars).
 
 build_live_sets_in_goal_2(not(Goal0), Liveness0, ResumeVars0, LiveSets0,
-		_, ModuleInfo, ProcInfo, Liveness, ResumeVars0, LiveSets) :-
+		_, ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars0, LiveSets) :-
 	build_live_sets_in_goal(Goal0, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, _, LiveSets).
+		ModuleInfo, ProcInfo, TypeInfoLiveness, Liveness, _, LiveSets).
 
 build_live_sets_in_goal_2(some(_Vs, _, Goal0), Liveness0, ResumeVars0,
-		LiveSets0, GoalInfo, ModuleInfo, ProcInfo,
+		LiveSets0, GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness, ResumeVars, LiveSets) :-
 	build_live_sets_in_goal(Goal0, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars1, LiveSets),
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars1, LiveSets),
 
 	% If the "some" goal cannot succeed more than once,
 	% then execution cannot backtrack into the inner goal once control
@@ -250,7 +270,7 @@
 build_live_sets_in_goal_2(
 		generic_call(_GenericCall, ArgVars, Modes, Det),
 		Liveness, ResumeVars0, LiveSets0,
-		GoalInfo, ModuleInfo, ProcInfo,
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness, ResumeVars, LiveSets) :-
 	% The variables which need to be saved onto the stack
 	% before the call are all the variables that are live
@@ -269,7 +289,7 @@
 	% Might need to add more live variables with alternate liveness
 	% calculation.
 
-	maybe_add_alternate_liveness_typeinfos(ModuleInfo, ProcInfo,
+	maybe_add_alternate_liveness_typeinfos(ProcInfo, TypeInfoLiveness,
 		OutVars, StackVars0, StackVars),
 
 	set__insert(LiveSets0, StackVars, LiveSets),
@@ -286,7 +306,7 @@
 
 build_live_sets_in_goal_2(call(PredId, ProcId, ArgVars, BuiltinState, _, _),
 		Liveness, ResumeVars0, LiveSets0,
-		GoalInfo, ModuleInfo, ProcInfo,
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness, ResumeVars, LiveSets) :-
 	(
 		BuiltinState = inline_builtin
@@ -304,11 +324,11 @@
 		set__difference(Liveness, OutVars, InputLiveness),
 		set__union(InputLiveness, ResumeVars0, StackVars0),
 
-		% Might need to add more live variables with alternate
-		% liveness calculation.
+		% Might need to add more live variables
+		% if this procedure uses typeinfo liveness.
 
-		maybe_add_alternate_liveness_typeinfos(ModuleInfo,
-			ProcInfo, OutVars, StackVars0, StackVars),
+		maybe_add_alternate_liveness_typeinfos(ProcInfo,
+			TypeInfoLiveness, OutVars, StackVars0, StackVars),
 
 		set__insert(LiveSets0, StackVars, LiveSets),
 
@@ -324,7 +344,7 @@
 	).
 
 build_live_sets_in_goal_2(unify(_,_,_,D,_), Liveness, ResumeVars0, LiveSets0,
-		_, _, _, Liveness, ResumeVars0, LiveSets) :-
+		_, _, _, _, Liveness, ResumeVars0, LiveSets) :-
 	(
 		D = complicated_unify(_, _, _)
 	->
@@ -338,7 +358,7 @@
 
 build_live_sets_in_goal_2(pragma_c_code(Attributes, PredId, ProcId,
 		Args, _, _, _), Liveness, ResumeVars0, LiveSets0,
-		GoalInfo, ModuleInfo, ProcInfo,
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness, ResumeVars, LiveSets) :-
 
 	goal_info_get_code_model(GoalInfo, CodeModel),
@@ -365,11 +385,11 @@
 		set__difference(Liveness, OutVars, InputLiveness),
 		set__union(InputLiveness, ResumeVars0, StackVars0),
 
-		% Might need to add more live variables with alternate
-		% liveness calculation.
+		% Might need to add more live variables
+		% if this procedure uses typeinfo liveness.
 
-		maybe_add_alternate_liveness_typeinfos(ModuleInfo,
-			ProcInfo, OutVars, StackVars0, StackVars),
+		maybe_add_alternate_liveness_typeinfos(ProcInfo,
+			TypeInfoLiveness, OutVars, StackVars0, StackVars),
 
 		set__insert(LiveSets0, StackVars, LiveSets),
 
@@ -383,28 +403,33 @@
 %-----------------------------------------------------------------------------%
 
 :- pred build_live_sets_in_conj(list(hlds_goal), set(prog_var), set(prog_var),
-	set(set(prog_var)), module_info, proc_info, set(prog_var),
+	set(set(prog_var)), module_info, proc_info, bool, set(prog_var),
 	set(prog_var), set(set(prog_var))).
-:- mode build_live_sets_in_conj(in, in, in, in, in, in, out, out, out) is det.
+:- mode build_live_sets_in_conj(in, in, in, in, in, in, in, out, out, out)
+	is det.
 
 build_live_sets_in_conj([], Liveness, ResumeVars, LiveSets,
-		_ModuleInfo, _ProcInfo, Liveness, ResumeVars, LiveSets).
+		_, _, _, Liveness, ResumeVars, LiveSets).
 build_live_sets_in_conj([Goal0 | Goals0], Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets) :-
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars, LiveSets) :-
 	(
 		Goal0 = _ - GoalInfo,
 		goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
 		instmap_delta_is_unreachable(InstMapDelta)
 	->
 		build_live_sets_in_goal(Goal0,
-			Liveness0, ResumeVars0, LiveSets0, ModuleInfo, ProcInfo,
+			Liveness0, ResumeVars0, LiveSets0,
+			ModuleInfo, ProcInfo, TypeInfoLiveness,
 			Liveness, ResumeVars, LiveSets)
 	;
 		build_live_sets_in_goal(Goal0,
-			Liveness0, ResumeVars0, LiveSets0, ModuleInfo, ProcInfo,
+			Liveness0, ResumeVars0, LiveSets0,
+			ModuleInfo, ProcInfo, TypeInfoLiveness,
 			Liveness1, ResumeVars1, LiveSets1),
 		build_live_sets_in_conj(Goals0,
-			Liveness1, ResumeVars1, LiveSets1, ModuleInfo, ProcInfo,
+			Liveness1, ResumeVars1, LiveSets1,
+			ModuleInfo, ProcInfo, TypeInfoLiveness,
 			Liveness, ResumeVars, LiveSets)
 	).
 
@@ -414,20 +439,21 @@
 	% parallel conjunctions.
 
 :- pred build_live_sets_in_disj(list(hlds_goal), set(prog_var), set(prog_var),
-	set(set(prog_var)), hlds_goal_info, module_info, proc_info,
+	set(set(prog_var)), hlds_goal_info, module_info, proc_info, bool,
 	set(prog_var), set(prog_var), set(set(prog_var))).
-:- mode build_live_sets_in_disj(in, in, in, in, in, in, in, out, out, out)
+:- mode build_live_sets_in_disj(in, in, in, in, in, in, in, in, out, out, out)
 	is det.
 
-build_live_sets_in_disj([], Liveness, ResumeVars, LiveSets, _, _, _,
+build_live_sets_in_disj([], Liveness, ResumeVars, LiveSets, _, _, _, _,
 		Liveness, ResumeVars, LiveSets).
 build_live_sets_in_disj([Goal0 | Goals0], Liveness0, ResumeVars0, LiveSets0,
-		GoalInfo, ModuleInfo, ProcInfo,
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness, ResumeVars, LiveSets) :-
 	build_live_sets_in_goal(Goal0, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars1, LiveSets1),
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars1, LiveSets1),
 	build_live_sets_in_disj(Goals0, Liveness0, ResumeVars0, LiveSets1,
-		GoalInfo, ModuleInfo, ProcInfo,
+		GoalInfo, ModuleInfo, ProcInfo, TypeInfoLiveness,
 		_Liveness2, ResumeVars2, LiveSets),
 	goal_info_get_code_model(GoalInfo, CodeModel),
 	( CodeModel = model_non ->
@@ -447,19 +473,23 @@
 %-----------------------------------------------------------------------------%
 
 :- pred build_live_sets_in_cases(list(case), set(prog_var), set(prog_var),
-	set(set(prog_var)), module_info, proc_info, set(prog_var),
-	set(prog_var), set(set(prog_var))).
-:- mode build_live_sets_in_cases(in, in, in, in, in, in, out, out, out) is det.
+	set(set(prog_var)), module_info, proc_info, bool,
+	set(prog_var), set(prog_var), set(set(prog_var))).
+:- mode build_live_sets_in_cases(in, in, in, in, in, in, in, out, out, out)
+	is det.
 
-build_live_sets_in_cases([], Liveness, ResumeVars, LiveSets, _, _,
+build_live_sets_in_cases([], Liveness, ResumeVars, LiveSets, _, _, _,
 		Liveness, ResumeVars, LiveSets).
 build_live_sets_in_cases([case(_Cons, Goal0) | Goals0],
-		Liveness0, ResumeVars0, LiveSets0, ModuleInfo, ProcInfo,
+		Liveness0, ResumeVars0, LiveSets0,
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
 		Liveness, ResumeVars, LiveSets) :-
 	build_live_sets_in_goal(Goal0, Liveness0, ResumeVars0, LiveSets0,
-		ModuleInfo, ProcInfo, Liveness, ResumeVars1, LiveSets1),
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		Liveness, ResumeVars1, LiveSets1),
 	build_live_sets_in_cases(Goals0, Liveness0, ResumeVars0, LiveSets1,
-		ModuleInfo, ProcInfo, _Liveness2, ResumeVars2, LiveSets),
+		ModuleInfo, ProcInfo, TypeInfoLiveness,
+		_Liveness2, ResumeVars2, LiveSets),
 	set__union(ResumeVars1, ResumeVars2, ResumeVars).
 
 %-----------------------------------------------------------------------------%
@@ -485,17 +515,14 @@
 	% Make sure you get the output vars first, and the live vars second,
 	% since this makes a significant difference to the output set of vars.
 
-:- pred maybe_add_alternate_liveness_typeinfos(module_info, proc_info,
+:- pred maybe_add_alternate_liveness_typeinfos(proc_info, bool,
 	set(prog_var), set(prog_var), set(prog_var)).
 :- mode maybe_add_alternate_liveness_typeinfos(in, in, in, in, out) is det.
 
-maybe_add_alternate_liveness_typeinfos(ModuleInfo, ProcInfo, OutVars,
+maybe_add_alternate_liveness_typeinfos(ProcInfo, TypeInfoLiveness, OutVars,
 		LiveVars1, LiveVars) :-
-	module_info_globals(ModuleInfo, Globals),
-	globals__lookup_bool_option(Globals, typeinfo_liveness,
-		TypeinfoLiveness),
 	(
-		TypeinfoLiveness = yes
+		TypeInfoLiveness = yes
 	->
 		proc_info_get_typeinfo_vars_setwise(ProcInfo, LiveVars1,
 			TypeInfoVarsLive),
Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.100
diff -u -b -r1.100 liveness.m
--- liveness.m	1999/07/13 08:53:05	1.100
+++ liveness.m	1999/07/16 09:01:45
@@ -130,13 +130,15 @@
 	% This consists of the {pre,post}{birth,death} sets and
 	% resume point information.
 
-:- pred detect_liveness_proc(proc_info, pred_id, module_info, proc_info).
-:- mode detect_liveness_proc(in, in, in, out) is det.
+:- pred detect_liveness_proc(proc_info, pred_id, proc_id, module_info,
+	proc_info).
+:- mode detect_liveness_proc(in, in, in, in, out) is det.
 
 	% Return the set of variables live at the start of the procedure.
 
-:- pred initial_liveness(proc_info, pred_id, module_info, set(prog_var)).
-:- mode initial_liveness(in, in, in, out) is det.
+:- pred initial_liveness(proc_info, pred_id, proc_id, module_info,
+	set(prog_var)).
+:- mode initial_liveness(in, in, in, in, out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -151,14 +153,12 @@
 :- import_module bool, map, std_util, list, assoc_list, require.
 :- import_module string.
 
-detect_liveness_proc(ProcInfo0, PredId, ModuleInfo, ProcInfo) :-
+detect_liveness_proc(ProcInfo0, PredId, ProcId, ModuleInfo, ProcInfo) :-
 	requantify_proc(ProcInfo0, ProcInfo1),
 	proc_info_goal(ProcInfo1, Goal0),
 	proc_info_varset(ProcInfo1, Varset),
 	proc_info_vartypes(ProcInfo1, VarTypes),
 	module_info_globals(ModuleInfo, Globals),
-	globals__lookup_bool_option(Globals, typeinfo_liveness,
-		TypeInfoLiveness0),
 
 	module_info_pred_info(ModuleInfo, PredId, PredInfo),
 	pred_info_module(PredInfo, PredModule),
@@ -170,12 +170,13 @@
 	->
 		TypeInfoLiveness = no
 	;
-		TypeInfoLiveness = TypeInfoLiveness0
+		proc_should_use_typeinfo_liveness(PredInfo, ProcId, Globals,
+			TypeInfoLiveness)
 	),
 	live_info_init(ModuleInfo, ProcInfo1, TypeInfoLiveness,
 		VarTypes, Varset, LiveInfo),
 
-	initial_liveness(ProcInfo1, PredId, ModuleInfo, Liveness0),
+	initial_liveness(ProcInfo1, PredId, ProcId, ModuleInfo, Liveness0),
 	detect_liveness_in_goal(Goal0, Liveness0, LiveInfo,
 		_, Goal1),
 
@@ -947,7 +948,7 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-initial_liveness(ProcInfo, PredId, ModuleInfo, Liveness) :-
+initial_liveness(ProcInfo, PredId, ProcId, ModuleInfo, Liveness) :-
 	proc_info_headvars(ProcInfo, Vars),
 	proc_info_argmodes(ProcInfo, Modes),
 	proc_info_vartypes(ProcInfo, VarTypes),
@@ -972,9 +973,9 @@
 	module_info_globals(ModuleInfo, Globals),
 	proc_info_goal(ProcInfo, _Goal - GoalInfo),
 	goal_info_get_nonlocals(GoalInfo, NonLocals0),
-	globals__lookup_bool_option(Globals, typeinfo_liveness, 
-		TypeinfoLiveness),
 	module_info_pred_info(ModuleInfo, PredId, PredInfo),
+	proc_should_use_typeinfo_liveness(PredInfo, ProcId, Globals,
+		TypeinfoLiveness),
 	pred_info_module(PredInfo, PredModule),
 	pred_info_name(PredInfo, PredName),
 	pred_info_arity(PredInfo, PredArity),
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.135
diff -u -b -r1.135 mercury_compile.m
--- mercury_compile.m	1999/07/16 08:06:07	1.135
+++ mercury_compile.m	1999/07/17 07:18:54
@@ -1235,15 +1235,17 @@
 	),
 	write_proc_progress_message("% Computing liveness in ", PredId, ProcId,
 		ModuleInfo3),
-	{ detect_liveness_proc(ProcInfo3, PredId, ModuleInfo3, ProcInfo4) },
+	{ detect_liveness_proc(ProcInfo3, PredId, ProcId, ModuleInfo3,
+		ProcInfo4) },
 	write_proc_progress_message("% Allocating stack slots in ", PredId,
 		                ProcId, ModuleInfo3),
-	{ allocate_stack_slots_in_proc(ProcInfo4, PredId, ModuleInfo3,
+	{ allocate_stack_slots_in_proc(ProcInfo4, PredId, ProcId, ModuleInfo3,
 		ProcInfo5) },
 	write_proc_progress_message(
 		"% Allocating storage locations for live vars in ",
 				PredId, ProcId, ModuleInfo3),
-	{ store_alloc_in_proc(ProcInfo5, PredId, ModuleInfo3, ProcInfo6) },
+	{ store_alloc_in_proc(ProcInfo5, PredId, ProcId, ModuleInfo3,
+		ProcInfo6) },
 	globals__io_get_trace_level(TraceLevel),
 	( { TraceLevel \= none } ->
 		write_proc_progress_message(
@@ -1921,7 +1923,7 @@
 	maybe_write_string(Verbose, "% Computing liveness...\n"),
 	maybe_flush_output(Verbose),
 	process_all_nonimported_nonaditi_procs(
-		update_proc_predid(detect_liveness_proc),
+		update_proc_predprocid(detect_liveness_proc),
 		HLDS0, HLDS),
 	maybe_write_string(Verbose, "% done.\n"),
 	maybe_report_stats(Stats).
@@ -1934,7 +1936,7 @@
 	maybe_write_string(Verbose, "% Computing stack vars..."),
 	maybe_flush_output(Verbose),
 	process_all_nonimported_nonaditi_procs(
-		update_proc_predid(allocate_stack_slots_in_proc),
+		update_proc_predprocid(allocate_stack_slots_in_proc),
 		HLDS0, HLDS),
 	maybe_write_string(Verbose, " done.\n"),
 	maybe_report_stats(Stats).
@@ -1947,7 +1949,7 @@
 	maybe_write_string(Verbose, "% Allocating store map..."),
 	maybe_flush_output(Verbose),
 	process_all_nonimported_nonaditi_procs(
-		update_proc_predid(store_alloc_in_proc),
+		update_proc_predprocid(store_alloc_in_proc),
 		HLDS0, HLDS),
 	maybe_write_string(Verbose, " done.\n"),
 	maybe_report_stats(Stats).
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/middle_rec.m,v
retrieving revision 1.77
diff -u -b -r1.77 middle_rec.m
--- middle_rec.m	1999/07/10 07:19:52	1.77
+++ middle_rec.m	1999/08/06 09:01:57
@@ -153,6 +153,12 @@
 	{ tree__flatten(RecCode, RecListList) },
 	{ list__condense(RecListList, RecList) },
 
+	% In the code we generate, the base instruction sequence is executed
+	% in situations where this procedure has no stack frame. If this
+	% sequence refers to stackvars, it will be to some other procedure's
+	% variables, which is obviously incorrect.
+	{ opt_util__block_refers_stackvars(BaseList, no) },
+
 	{ list__append(BaseList, RecList, AvoidList) },
 	{ middle_rec__find_unused_register(AvoidList, AuxReg) },
 
@@ -160,12 +166,12 @@
 	{ middle_rec__add_counter_to_livevals(BeforeList0, AuxReg,
 		BeforeList) },
 
-	{ middle_rec__generate_downloop_test(EntryTestList,
-		Loop1Label, Loop1Test) },
-
 	code_info__get_next_label(Loop1Label),
 	code_info__get_next_label(Loop2Label),
 	code_info__get_total_stackslot_count(FrameSize),
+
+	{ middle_rec__generate_downloop_test(EntryTestList,
+		Loop1Label, Loop1Test) },
 
 	{ FrameSize = 0 ->
 		MaybeIncrSp = [],
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.266
diff -u -b -r1.266 options.m
--- options.m	1999/06/15 07:09:56	1.266
+++ options.m	1999/07/06 01:21:55
@@ -180,7 +180,21 @@
 				% Use an alternate calculation of liveness
 				% where typeinfos are live for any live data
 				% the includes that type variable.
-		;	typeinfo_liveness
+				%
+				% This option is hidden because we must not
+				% pay attention to it for any procedure whose
+				% address is taken; those must always be
+				% treated with typeinfo liveness (otherwise,
+				% the layout structure we include in closures
+				% using that procedure may not have all the
+				% information required to reconstruct the
+				% types of all the values inside the closure).
+				%
+				% The only place in the compiler that should
+				% look at this option is the predicate
+				% should_use_typeinfo_liveness in hlds_pred.m;
+				% everything else should go through there.
+		;	typeinfo_liveness_hidden
 				% Generate unify and compare preds.  For
 				% measurement only. Code generated with
 				% this set to `no' is unlikely to
@@ -503,7 +517,7 @@
 	agc_stack_layout	-	bool(no),
 	procid_stack_layout	-	bool(no),
 	trace_stack_layout	-	bool(no),
-	typeinfo_liveness	-	bool(no),
+	typeinfo_liveness_hidden	-	bool(no),
 	special_preds		-	bool(yes),
 	type_ctor_info		-	bool(yes),
 	type_ctor_layout	-	bool(yes),
@@ -850,7 +864,7 @@
 long_option("basic-stack-layout",	basic_stack_layout).
 long_option("procid-stack-layout",	procid_stack_layout).
 long_option("trace-stack-layout",	trace_stack_layout).
-long_option("typeinfo-liveness",	typeinfo_liveness).
+long_option("typeinfo-liveness",	typeinfo_liveness_hidden).
 long_option("special-preds",		special_preds).
 long_option("type-ctor-info",		type_ctor_info).
 long_option("type-ctor-layout",		type_ctor_layout).
Index: compiler/passes_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/passes_aux.m,v
retrieving revision 1.33
diff -u -b -r1.33 passes_aux.m
--- passes_aux.m	1999/07/13 08:03:00	1.33
+++ passes_aux.m	1999/07/16 08:55:40
@@ -22,6 +22,9 @@
 				proc_info, module_info, proc_info))
 		;	update_proc_predid(pred(
 				proc_info, pred_id, module_info, proc_info))
+		;	update_proc_predprocid(pred(
+				proc_info, pred_id, proc_id,
+				module_info, proc_info))
 		;	update_proc_io(pred(
 				pred_id, proc_id, module_info,
 				proc_info, proc_info, io__state, io__state))
@@ -82,7 +85,10 @@
 
 :- inst task =	bound(( update_proc(pred(in, in, out) is det)
 		;	update_proc_predid(pred(in, in, in, out) is det)
-		;	update_proc_io(pred(in, in, in, in, out, di, uo) is det)
+		;	update_proc_predprocid(pred(in, in, in, in, out)
+				is det)
+		;	update_proc_io(pred(in, in, in, in, out, di, uo)
+				is det)
 		;	update_proc_error(pred(in, in, in, out, in, out,
 				out, out, di, uo) is det)
 		;	update_pred_error(pred(in, in, out, in, out,
@@ -285,6 +291,12 @@
 	;
 		Task0 = update_proc_predid(Closure),
 		call(Closure, Proc0, PredId, ModuleInfo0, Proc),
+		ModuleInfo8 = ModuleInfo0,
+		Task1 = Task0,
+		State9 = State0
+	;
+		Task0 = update_proc_predprocid(Closure),
+		call(Closure, Proc0, PredId, ProcId, ModuleInfo0, Proc),
 		ModuleInfo8 = ModuleInfo0,
 		Task1 = Task0,
 		State9 = State0
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.32
diff -u -b -r1.32 stack_layout.m
--- stack_layout.m	1999/07/12 06:21:22	1.32
+++ stack_layout.m	1999/07/14 04:11:51
@@ -235,7 +235,7 @@
 	set_bbbtree(label)::out) is det.
 
 :- pred stack_layout__construct_closure_layout(proc_label::in,
-	maybe(closure_layout_info)::in, list(maybe(rval))::out,
+	closure_layout_info::in, list(maybe(rval))::out,
 	create_arg_types::out, int::in, int::out) is det.
 
 :- implementation.
@@ -936,26 +936,20 @@
 	% with runtime/mercury_ho_call.h, which contains macros to access
 	% the data structures we build here.
 
-stack_layout__construct_closure_layout(ProcLabel, MaybeClosureLayoutInfo,
+stack_layout__construct_closure_layout(ProcLabel, ClosureLayoutInfo,
 		Rvals, ArgTypes, CNum0, CNum) :-
 	stack_layout__construct_procid_rvals(ProcLabel, ProcIdRvals,
 		ProcIdTypes),
-	( MaybeClosureLayoutInfo = yes(ClosureLayoutInfo) ->
 		ClosureLayoutInfo = closure_layout_info(ClosureArgs,
 			TVarLocnMap),
 		stack_layout__construct_closure_arg_rvals(ClosureArgs,
 			ClosureArgRvals, ClosureArgTypes, CNum0, CNum),
 		stack_layout__construct_tvar_rvals(TVarLocnMap, TVarRvals,
-			TvarRvalTypes),
+		TVarRvalTypes),
 		list__append(ClosureArgRvals, TVarRvals, LayoutRvals),
-		LayoutTypes = initial(ClosureArgTypes, TvarRvalTypes)
-	;
-		LayoutRvals = [yes(const(int_const(-1)))],
-		LayoutTypes = initial([1 - yes(integer)], none),
-		CNum = CNum0
-	),
 	list__append(ProcIdRvals, LayoutRvals, Rvals),
-	ArgTypes = initial(ProcIdTypes, LayoutTypes).
+	ArgTypes = initial(ProcIdTypes, initial(ClosureArgTypes,
+		TVarRvalTypes)).
 
 :- pred stack_layout__construct_closure_arg_rvals(list(closure_arg_info)::in,
 	list(maybe(rval))::out, initial_arg_types::out, int::in, int::out)
Index: compiler/store_alloc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/store_alloc.m,v
retrieving revision 1.69
diff -u -b -r1.69 store_alloc.m
--- store_alloc.m	1999/07/13 08:53:31	1.69
+++ store_alloc.m	1999/07/16 09:44:28
@@ -28,8 +28,9 @@
 
 :- import_module hlds_module, hlds_pred.
 
-:- pred store_alloc_in_proc(proc_info, pred_id, module_info, proc_info).
-:- mode store_alloc_in_proc(in, in, in, out) is det.
+:- pred store_alloc_in_proc(proc_info, pred_id, proc_id, module_info,
+	proc_info).
+:- mode store_alloc_in_proc(in, in, in, in, out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -51,7 +52,7 @@
 
 %-----------------------------------------------------------------------------%
 
-store_alloc_in_proc(ProcInfo0, PredId, ModuleInfo, ProcInfo) :-
+store_alloc_in_proc(ProcInfo0, PredId, ProcId, ModuleInfo, ProcInfo) :-
 	module_info_globals(ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, follow_vars, ApplyFollowVars),
 	( ApplyFollowVars = yes ->
@@ -68,7 +69,7 @@
 	;
 		proc_info_goal(ProcInfo0, Goal2)
 	),
-	initial_liveness(ProcInfo0, PredId, ModuleInfo, Liveness0),
+	initial_liveness(ProcInfo0, PredId, ProcId, ModuleInfo, Liveness0),
 	globals__get_trace_level(Globals, TraceLevel),
 	( TraceLevel \= none ->
 		trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0)
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.101
diff -u -b -r1.101 unify_gen.m
--- unify_gen.m	1999/07/13 08:53:38	1.101
+++ unify_gen.m	1999/07/14 08:52:22
@@ -506,10 +506,6 @@
 	    )
 	;
 		{ Code = empty },
-		code_info__make_entry_label(ModuleInfo, PredId, ProcId, no,
-			CodeAddr),
-		{ code_util__extract_proc_label_from_code_addr(CodeAddr,
-			ProcLabel) },
 		(
 			{ EvalMethod = normal }
 		;
@@ -525,29 +521,15 @@
 			{ error(
 			"Sorry, not implemented: `aditi_top_down' closures") }
 		),
-		{ module_info_globals(ModuleInfo, Globals) },
-		{ 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
-		},
+		{ continuation_info__generate_closure_layout(
+			ModuleInfo, PredId, ProcId, ClosureInfo) },
+		code_info__make_entry_label(ModuleInfo, PredId, ProcId, no,
+			CodeAddr),
+		{ code_util__extract_proc_label_from_code_addr(CodeAddr,
+			ProcLabel) },
 		code_info__get_cell_count(CNum0),
 		{ stack_layout__construct_closure_layout(ProcLabel,
-			MaybeClosureInfo, ClosureLayoutMaybeRvals,
+			ClosureInfo, ClosureLayoutMaybeRvals,
 			ClosureLayoutArgTypes, CNum0, CNum) },
 		code_info__set_cell_count(CNum),
 		code_info__get_next_cell_number(ClosureLayoutCellNo),
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.59
diff -u -b -r1.59 unused_args.m
--- unused_args.m	1999/07/13 08:53:41	1.59
+++ unused_args.m	1999/07/16 09:03:08
@@ -256,10 +256,10 @@
 			ArgModes, VarDep1, VarDep2),
 		
 		module_info_globals(ModuleInfo, Globals),
-		globals__lookup_bool_option(Globals, typeinfo_liveness, 
-			TypeinfoLiveness),
+		proc_should_use_typeinfo_liveness(PredInfo, ProcId, Globals,
+			TypeInfoLiveness),
 		( 
-			TypeinfoLiveness = yes,
+			TypeInfoLiveness = yes,
 			pred_info_module(PredInfo, PredModule),
 			pred_info_name(PredInfo, PredName),
 			pred_info_arity(PredInfo, PredArity),
--------------------------------------------------------------------------
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