for review: an even bigger step towards the debugger (part 2 of 4)

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Apr 1 17:10:32 AEST 1998


Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.10
diff -u -u -r1.10 continuation_info.m
--- continuation_info.m	1998/03/03 17:33:54	1.10
+++ continuation_info.m	1998/04/01 04:12:12
@@ -6,37 +6,39 @@
 %
 % File: continuation_info.m.
 % Main author: trd.
+% Extensive modifications by zs.
 %
-% This file defines the continuation_info data structure, which is used
-% to hold the information we need to output stack_layout tables, 
-% are for
-% accurate garbage collection.
+% 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.
 %
 % Information is collected in several passes. 
-%	- If trace_stack_layouts are needed, 
-%		- during the generation of the procedure's prolog code 
-%		  (in code_gen.m) we add the information about live values
-%		  at entry.
-%		- during the generation of the procedure's epilog code 
-%		  (in code_gen.m) we add the information about live
-%		  values at exit.
 %
-% 	- If basic_stack_layouts are needed, after code for a procedure
-% 	  has been generated, the proc_layout_general_info is added to
-% 	  the continuation_info, and some internal label information
-% 	  is initialized (but not filled in with live values).
+% 	- Before we start generating code for a procedure,
+%	  we initialize the set of internal labels for which we have
+%	  layout information to the empty set. This set is stored in
+%	  the code generator state.
 %
-% 	- If agc_stack_layouts are needed, after the code has been
-% 	  optimized a pass is made over the final LLDS instructions.
-% 	  Information about internal labels, is collected.  The liveness
-% 	  information in call instructions is stored with the
-% 	  corresponding continuation label.
+%	- 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.
+%
+% 	- 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).
+%
+% 	- 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
+%	  in the HLDS.
 %
 % stack_layout.m converts the information collected in this module into
 % stack_layout tables.
-%		
-% The data structures in this module could do with a re-design when it
-% becomes more stable.
 
 %-----------------------------------------------------------------------------%
 
@@ -45,7 +47,7 @@
 :- interface.
 
 :- import_module llds, hlds_pred, prog_data, hlds_data.
-:- import_module set, map, list, assoc_list, term, std_util.
+:- import_module set, map, list, std_util.
 
 	%
 	% Information used by the continuation_info module.
@@ -59,60 +61,50 @@
 	% Information for any procedure, includes information about the
 	% procedure itself, and any internal labels within it.
 	%
-	% The maybe(data) are needed because the data is collected
-	% in a roundabout fashion from various phases of compilation.
-	% In some compilation grades, they are not even needed.
-	% Before data is collected, the field is set to `no'. If
-	% the data is needed (according to various stack_layout
-	% options) it will later be set to a `yes(....)'.
-	% The map is initialized to an empty map, and is later filled
-	% with entries (if required).
-	%
 :- type proc_layout_info
 	--->	proc_layout_info(
-			maybe(proc_layout_general_info),
-					% information on the procedure,
-					% needed for basic_stack_layouts
-			map(label, internal_layout_info),
+			proc_label,	% the proc label
+			determinism,	% determines which stack is used
+			int,		% number of stack slots
+			maybe(int),	% location of succip on stack
+			maybe(label),	% if generate_trace is set,
+					% this contains the label associated
+					% with the call event, whose stack
+					% layout says which variables were
+					% live and where on entry
+			proc_label_layout_info
 					% info for each internal label,
 					% needed for basic_stack_layouts
-			maybe(continuation_label_info),  % entry
-			maybe(continuation_label_info)	 % exit
-					% live data information about
-					% entry and exit points,
-					% needed for trace_stack_layouts
 		).
 
-:- type proc_layout_general_info
-	--->	proc_layout_general_info(
-			proc_label,	% the proc label
-			determinism,	% which stack is used
-			int,		% number of stack slots
-			maybe(int)	% location of succip on stack
-		).
+	%
+	% Information about the labels internal to a procedure.
+	%
+:- type proc_label_layout_info	==	map(label, internal_layout_info).
 
 	%
 	% Information for any internal label.
-	% (Continuation labels are a special case of internal labels).
+	% At some labels, we are interested in the layout of live data;
+	% at others, we are not. The layout_label_info will be present
+	% only for labels of the first kind.
 	%
-:- type internal_layout_info
-	--->	internal_layout_info(
-			maybe(continuation_label_info)
-				% needed for agc_stack_layouts
-		).
+	% XXX From now on, all the maybes will be yes. This layer
+	% will therefore be removed very soon.
+	%
+:- type internal_layout_info	==	maybe(layout_label_info).
 
 	%
-	% Information for a label that is a continuation.
+	% Information about the layout of live data for a label.
 	%
 	% Different calls can assign slightly
 	% different liveness annotations to the labels after the call.
 	% (Two different paths of computation can leave different
 	% information live).
 	% We take the intersection of these annotations.  Intersecting
-	% is easy if we represent the live values and type infos as
-	% sets.
-:- type continuation_label_info
-	--->	continuation_label_info(
+	% is easy if we represent the live values and type infos as sets.
+	%
+:- type layout_label_info
+	--->	layout_label_info(
 			set(var_info),
 				% live vars and their locations/names
 			set(pair(tvar, lval))
@@ -128,8 +120,7 @@
 
 	% Return an initialized continuation info structure.
 
-:- pred continuation_info__init(continuation_info).
-:- mode continuation_info__init(out) is det.
+:- pred continuation_info__init(continuation_info::out) is det.
 
 	%
 	% Add the information for a single proc.
@@ -138,44 +129,30 @@
 	% the code model for this proc, and the stack slot of the succip
 	% in this proc (if there is one).
 	%
-:- pred continuation_info__add_proc_layout_info(pred_proc_id, proc_label,
-		int, determinism, maybe(int), continuation_info,
-		continuation_info).
-:- mode continuation_info__add_proc_layout_info(in, in, in, in, in, in,
-		out) is det.
-
-:- pred continuation_info__add_proc_entry_info(pred_proc_id, 
-		list(var_info), assoc_list(var, lval),
-		continuation_info, continuation_info).
-:- mode continuation_info__add_proc_entry_info(in, in, in, in, out) is det.
-
-:- pred continuation_info__add_proc_exit_info(pred_proc_id, 
-		list(var_info), assoc_list(var, lval),
-		continuation_info, continuation_info).
-:- mode continuation_info__add_proc_exit_info(in, in, in, in, out) is det.
-
-:- pred continuation_info__process_llds(list(c_procedure),
-		continuation_info, continuation_info) is det.
-:- mode continuation_info__process_llds(in, in, out) is det.
-
-	%
-	% Add the information for all the labels within a
-	% proc.
-	%
-	% Takes the list of instructions for this proc, the
-	% proc_label, the number of stack slots, the code model for this
-	% proc, and the stack slot of the succip in this proc.
-	%
-:- pred continuation_info__process_instructions(pred_proc_id,
-	list(instruction), continuation_info, continuation_info).
-:- mode continuation_info__process_instructions(in, in, in, out) is det.
+:- pred continuation_info__add_proc_info(pred_proc_id::in, proc_label::in,
+	int::in, determinism::in, maybe(int)::in, maybe(label)::in,
+	proc_label_layout_info::in, continuation_info::in,
+	continuation_info::out) is det.
+
+	%
+	% Call continuation_info__process_instructions on the code
+	% of every procedure in the list.
+	%
+:- pred continuation_info__process_llds(list(c_procedure)::in,
+	continuation_info::in, continuation_info::out) is det.
+
+	%
+	% Add the information for all the continuation labels within a proc.
+	%
+:- pred continuation_info__process_instructions(pred_proc_id::in,
+	list(instruction)::in, continuation_info::in, continuation_info::out)
+	is det.
 
 	%
 	% Get the finished list of proc_layout_infos.
 	%
-:- pred continuation_info__get_all_proc_layouts(list(proc_layout_info),
-		continuation_info, continuation_info).
-:- mode continuation_info__get_all_proc_layouts(out, in, out) is det.
+:- pred continuation_info__get_all_proc_layouts(continuation_info::in,
+	list(proc_layout_info)::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -185,16 +162,7 @@
 :- import_module require.
 
 	% The continuation_info data structure
-
-:- type continuation_info
-	--->	continuation_info(
-			map(pred_proc_id, proc_layout_info),
-				% A proc_layout_info for every procedure
-				% processed
-			map(label, internal_layout_info)
-				% internal labels processed so far
-				% in the current procedure
-			).
+:- type continuation_info	==	map(pred_proc_id, proc_layout_info).
 
 %-----------------------------------------------------------------------------%
 
@@ -205,34 +173,31 @@
 	%
 
 continuation_info__init(ContInfo) :-
-	map__init(LabelMap),
-	map__init(Internals),
-	ContInfo = continuation_info(LabelMap, Internals).
-
-continuation_info__add_proc_entry_info(PredProcId, TypeLvals, TypeInfos) -->
-	continuation_info__get_proc_layout(PredProcId, ProcLayout0),
-	{ ProcLayout0 = proc_layout_info(MaybeProcGeneral, InternalMap, _,
-		ExitInfo) },
-	{ set__list_to_set(TypeLvals, TypeLvalSet) },
-	{ set__list_to_set(TypeInfos, TypeInfoSet) },
-	{ EntryInfo = yes(continuation_label_info(TypeLvalSet, TypeInfoSet)) },
-	{ ProcLayout = proc_layout_info(MaybeProcGeneral, InternalMap, 
-		EntryInfo, ExitInfo) },
-	continuation_info__update_proc_layout(PredProcId, ProcLayout).
-
-continuation_info__add_proc_exit_info(PredProcId, TypeLvals, TypeInfos) -->
-	continuation_info__get_proc_layout(PredProcId, ProcLayout0),
-	{ ProcLayout0 = proc_layout_info(MaybeProcGeneral, InternalMap, 
-		EntryInfo, _) },
-	{ set__list_to_set(TypeLvals, TypeLvalSet) },
-	{ set__list_to_set(TypeInfos, TypeInfoSet) },
-	{ ExitInfo = yes(continuation_label_info(TypeLvalSet, TypeInfoSet)) },
-	{ ProcLayout = proc_layout_info(MaybeProcGeneral, InternalMap, 
-		EntryInfo, ExitInfo) },
-	continuation_info__update_proc_layout(PredProcId, ProcLayout).
-	
+	map__init(ContInfo).
+
+	%
+	% Add the info for this proc (a proc_layout_info) to the
+	% continuation_info. 
+	%
+continuation_info__add_proc_info(PredProcId, ProcLabel, StackSize,
+		Detism, SuccipLocation, MaybeTraceCallLabel, InternalMap,
+		ContInfo0, ContInfo) :-
+	( map__contains(ContInfo0, PredProcId) ->
+		error("duplicate continuation_info for proc.")
+	;
+		LayoutInfo = proc_layout_info(ProcLabel, Detism, StackSize,
+			SuccipLocation, MaybeTraceCallLabel, 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__process_llds([]) --> [].
-continuation_info__process_llds([Proc|Procs]) -->
+continuation_info__process_llds([Proc | Procs]) -->
 	{ Proc = c_procedure(_, _, PredProcId, Instrs) },
 	continuation_info__process_instructions(PredProcId, Instrs),
 	continuation_info__process_llds(Procs).
@@ -241,103 +206,37 @@
 	% Process the list of instructions for this proc, adding
 	% all internal label information to the continuation_info.
 	%
-continuation_info__process_instructions(PredProcId, Instructions) -->
+continuation_info__process_instructions(PredProcId, Instructions,
+		ContInfo0, ContInfo) :-
 
-		% Get all the continuation info from the call instructions
-	continuation_info__initialize_internal_info,
-	{ GetCallLivevals = lambda([Instr::in, Pair::out] is semidet, (
+		% Get all the continuation info from the call instructions.
+	map__lookup(ContInfo0, PredProcId, ProcLayoutInfo0),
+	ProcLayoutInfo0 = proc_layout_info(A, B, C, D, E, Internals0),
+	GetCallLivevals = lambda([Instr::in, Pair::out] is semidet, (
 		Instr = call(_, label(Label), LiveInfo, _) - _Comment,
 		Pair = Label - LiveInfo
-		)) },
-	{ list__filter_map(GetCallLivevals, Instructions, Calls) },
-
-		% Process the continuation label info
-	list__foldl(continuation_info__process_internal_info,
-		Calls),
-
-		% Get all internal labels.
-		% (Some labels are not used as continuations).
-	{ GetAllInternalLabels = lambda([Instr::in, Label::out] is semidet, (
-		Instr = label(Label) - _Comment,
-		Label = local(_, _)
-		)) },
-	{ list__filter_map(GetAllInternalLabels, Instructions, Labels) },
-
-		% Insert all non-continuation internal labels into the
-		% internals, then add the internals to the information
-		% for this proc.
-	continuation_info__add_non_continuation_labels(Labels),
-	continuation_info__get_internal_info(InternalInfo),
-	continuation_info__add_internal_info_to_proc(PredProcId, InternalInfo).
+	)),
+	list__filter_map(GetCallLivevals, Instructions, Calls),
 
-	%
-	% Add the info for this proc (a proc_layout_info) to the
-	% continuation_info. 
-	%
-continuation_info__add_proc_layout_info(PredProcId, ProcLabel, StackSize,
-		Detism, SuccipLocation) -->
-	continuation_info__get_proc_layout(PredProcId, ProcLayoutInfo0),
-	{ 
-		ProcLayoutInfo0 = proc_layout_info(no, InternalMap, 
-			EntryInfo, ExitInfo) 
-	->
-		ProcLayoutInfo = proc_layout_info(yes(proc_layout_general_info(
-			ProcLabel, Detism, StackSize, SuccipLocation)), 
-			InternalMap, EntryInfo, ExitInfo)
-	;
-		error("continuation_info__add_proc_layout_info: general information already done.")
-	},
-	continuation_info__update_proc_layout(PredProcId, ProcLayoutInfo).
+		% Process the continuation label info.
+	list__foldl(continuation_info__process_continuation, Calls,
+		Internals0, Internals),
 
-	%
-	% Get all the proc_layout_infos.
-	%
-continuation_info__get_all_proc_layouts(Entries, ContInfo, ContInfo) :-
-	ContInfo = continuation_info(Map, _),
-	map__values(Map, Entries).
+	ProcLayoutInfo = proc_layout_info(A, B, C, D, E, Internals),
+	map__det_update(ContInfo0, PredProcId, ProcLayoutInfo, ContInfo).
 
 %-----------------------------------------------------------------------------%
 
 	%
-	% Add the list of internal labels to the internal_info
-	% in the continuation_info.
-	%
-:- pred continuation_info__add_non_continuation_labels(list(label),
-		continuation_info, continuation_info).
-:- mode continuation_info__add_non_continuation_labels(in, in, out) is det.
-
-continuation_info__add_non_continuation_labels(Labels) -->
-	continuation_info__get_internal_info(InternalInfo0),
-	{ list__foldl(continuation_info__ensure_label_is_present, Labels,
-		InternalInfo0, InternalInfo) },
-	continuation_info__set_internal_info(InternalInfo).
-
-	%
-	% Add a label to the internals, if it isn't already there.
-	%
-:- pred continuation_info__ensure_label_is_present(label,
-		map(label, internal_layout_info),
-		map(label, internal_layout_info)).
-:- mode continuation_info__ensure_label_is_present(in, in, out) is det.
-continuation_info__ensure_label_is_present(Label, InternalMap0, InternalMap) :-
-	( map__contains(InternalMap0, Label) ->
-		InternalMap = InternalMap0
-	;
-		Internal = internal_layout_info(no),
-		map__det_insert(InternalMap0, Label,
-			Internal, InternalMap)
-	).
-
-	%
 	% Collect the liveness information from a single label and add
 	% it to the internals.
 	%
-:- pred continuation_info__process_internal_info(pair(label,
-		list(liveinfo)), continuation_info, continuation_info).
-:- mode continuation_info__process_internal_info(in, in, out) is det.
+:- pred continuation_info__process_continuation(
+	pair(label, list(liveinfo))::in,
+	proc_label_layout_info::in, proc_label_layout_info::out) is det.
 
-continuation_info__process_internal_info(Label - LiveInfoList, ContInfo0,
-		ContInfo) :-
+continuation_info__process_continuation(Label - LiveInfoList,
+		Internals0, Internals) :-
 	GetVarInfo = lambda([LiveLval::in, VarInfo::out] is det, (
 		LiveLval = live_lvalue(Lval, LiveValueType, Name, _),
 		VarInfo = var_info(Lval, LiveValueType, Name)
@@ -351,10 +250,40 @@
 	list__sort_and_remove_dups(TypeInfoList, SortedTypeInfoList),
 	set__sorted_list_to_set(SortedTypeInfoList, TypeInfoSet),
 	set__list_to_set(VarInfoList, VarInfoSet),
-	NewInternal = internal_layout_info(
-		yes(continuation_label_info(VarInfoSet, TypeInfoSet))),
+	NewInternal = yes(layout_label_info(VarInfoSet, TypeInfoSet)),
 	continuation_info__add_internal_info(Label, NewInternal,
-		ContInfo0, ContInfo).
+		Internals0, Internals).
+
+:- pred continuation_info__ensure_label_is_present(label::in,
+	proc_label_layout_info::in, proc_label_layout_info::out) is det.
+
+continuation_info__ensure_label_is_present(Label, InternalMap0, InternalMap) :-
+	( map__contains(InternalMap0, Label) ->
+		InternalMap = InternalMap0
+	;
+		map__det_insert(InternalMap0, Label, no, InternalMap)
+	).
+
+%-----------------------------------------------------------------------------%
+
+	%
+	% Add an internal info to the list of internal infos.
+	%
+:- pred continuation_info__add_internal_info(label::in,
+	internal_layout_info::in,
+	proc_label_layout_info::in, proc_label_layout_info::out) is det.
+
+continuation_info__add_internal_info(Label, Internal1,
+		Internals0, Internals) :-
+	(
+		map__search(Internals0, Label, Internal0)
+	->
+		continuation_info__merge_internal_labels(Internal0, Internal1,
+			Internal),
+		map__set(Internals0, Label, Internal, Internals)
+	;
+		map__det_insert(Internals0, Label, Internal1, Internals)
+	).
 
 	%
 	% Merge the continuation label information of two labels.
@@ -367,157 +296,24 @@
 	% label is guaranteed not to depend on it.
 	% XXX Is this true for non-det code?
 
-:- pred continuation_info__merge_internal_labels(maybe(continuation_label_info),
-	maybe(continuation_label_info), maybe(continuation_label_info)).
-:- mode continuation_info__merge_internal_labels(in, in, out) is det.
+:- pred continuation_info__merge_internal_labels(
+	maybe(layout_label_info)::in, maybe(layout_label_info)::in,
+	maybe(layout_label_info)::out) is det.
 
 continuation_info__merge_internal_labels(no, no, no).
 continuation_info__merge_internal_labels(no,
-		yes(continuation_label_info(LV0, TV0)),
-		yes(continuation_label_info(LV0, TV0))).
+		yes(layout_label_info(LV0, TV0)),
+		yes(layout_label_info(LV0, TV0))).
 continuation_info__merge_internal_labels(
-		yes(continuation_label_info(LV0, TV0)),
+		yes(layout_label_info(LV0, TV0)),
 		no,
-		yes(continuation_label_info(LV0, TV0))).
+		yes(layout_label_info(LV0, TV0))).
 continuation_info__merge_internal_labels(
-		yes(continuation_label_info(LV0, TV0)),
-		yes(continuation_label_info(LV1, TV1)),
-		yes(continuation_label_info(LV, TV))) :-
+		yes(layout_label_info(LV0, TV0)),
+		yes(layout_label_info(LV1, TV1)),
+		yes(layout_label_info(LV, TV))) :-
 	set__intersect(LV0, LV1, LV),
 	set__intersect(TV0, TV1, TV).
-
-%-----------------------------------------------------------------------------%
-
-	% Procedures to manipulate continuation_info
-
-	%
-	% Add the given proc_layout_info to the continuation_info.
-	%
-:- pred continuation_info__insert_proc_layout(pred_proc_id, proc_layout_info,
-		continuation_info, continuation_info).
-:- mode continuation_info__insert_proc_layout(in, in, in, out) is det.
-
-continuation_info__insert_proc_layout(PredProcId, ProcLayoutInfo,
-		ContInfo0, ContInfo) :-
-	ContInfo0 = continuation_info(ProcLayoutMap0, Internals),
-	map__det_insert(ProcLayoutMap0, PredProcId, ProcLayoutInfo,
-		ProcLayoutMap),
-	ContInfo = continuation_info(ProcLayoutMap, Internals).
-
-	%
-	% Get the proc layout if it exists, otherwise return an 
-	% empty one.
-	%
-:- pred continuation_info__get_proc_layout(pred_proc_id, proc_layout_info,
-		continuation_info, continuation_info).
-:- mode continuation_info__get_proc_layout(in, out, in, out) is det.
-
-continuation_info__get_proc_layout(PredProcId, ProcLayoutInfo,
-		ContInfo, ContInfo) :-
-	ContInfo = continuation_info(ProcLayoutMap, _Internals),
-	( 
-		map__search(ProcLayoutMap, PredProcId, ProcLayoutInfo0)
-	->
-		ProcLayoutInfo = ProcLayoutInfo0
-	;
-		map__init(InternalMap),
-		ProcLayoutInfo = proc_layout_info(no, InternalMap, no, no)
-	).
-
-	%
-	% Update a proc layout.
-	%
-:- pred continuation_info__update_proc_layout(pred_proc_id, proc_layout_info,
-		continuation_info, continuation_info).
-:- mode continuation_info__update_proc_layout(in, in, in, out) is det.
-
-continuation_info__update_proc_layout(PredProcId, ProcLayoutInfo,
-		ContInfo0, ContInfo) :-
-	ContInfo0 = continuation_info(ProcLayoutMap0, Internals),
-	map__set(ProcLayoutMap0, PredProcId, ProcLayoutInfo, ProcLayoutMap),
-	ContInfo = continuation_info(ProcLayoutMap, Internals).
-
-	%
-	% Add the given internal_info to the given procedure in
-	% the continuation_info.
-	%
-	% (The procedure proc_layout_info has already been processed and
-	% added, but at that time the internal_info wasn't available).
-	%
-:- pred continuation_info__add_internal_info_to_proc(pred_proc_id,
-		map(label, internal_layout_info), continuation_info,
-		continuation_info).
-:- mode continuation_info__add_internal_info_to_proc(in, in, in, out) is det.
-
-continuation_info__add_internal_info_to_proc(PredProcId, InternalLayout,
-		ContInfo0, ContInfo) :-
-	ContInfo0 = continuation_info(ProcLayoutMap0, Internals),
-	map__lookup(ProcLayoutMap0, PredProcId, ProcLayoutInfo0),
-	ProcLayoutInfo0 = proc_layout_info(MaybeProcGeneral, _, EntryInfo,
-		ExitInfo),
-	ProcLayoutInfo = proc_layout_info(MaybeProcGeneral, InternalLayout,
-		EntryInfo, ExitInfo),
-	map__set(ProcLayoutMap0, PredProcId, ProcLayoutInfo, ProcLayoutMap),
-	ContInfo = continuation_info(ProcLayoutMap, Internals).
-
-	%
-	% Add an internal info to the list of internal infos.
-	%
-:- pred continuation_info__add_internal_info(label,
-		internal_layout_info, continuation_info, continuation_info).
-:- mode continuation_info__add_internal_info(in, in, in, out) is det.
-
-continuation_info__add_internal_info(Label, Internal, ContInfo0, ContInfo) :-
-	ContInfo0 = continuation_info(ProcLayoutMap, Internals0),
-	Internal = internal_layout_info(ContLabelInfo0),
-	(
-		map__search(Internals0, Label, Existing)
-	->
-		Existing = internal_layout_info(ContLabelInfo1),
-		continuation_info__merge_internal_labels(ContLabelInfo0,
-			ContLabelInfo1, ContLabelInfo),
-		New = internal_layout_info(ContLabelInfo),
-		map__set(Internals0, Label, New, Internals)
-		
-	;
-		map__det_insert(Internals0, Label, Internal, Internals)
-	),
-	ContInfo = continuation_info(ProcLayoutMap, Internals).
-
-	%
-	% Initialize the internal info.
-	%
-:- pred continuation_info__initialize_internal_info(
-	continuation_info, continuation_info).
-:- mode continuation_info__initialize_internal_info(in, out) is det.
-
-continuation_info__initialize_internal_info(ContInfo0, ContInfo) :-
-	ContInfo0 = continuation_info(ProcLayoutMap, _),
-	map__init(Internals),
-	ContInfo = continuation_info(ProcLayoutMap, Internals).
-
-	%
-	% Set the internal info.
-	%
-:- pred continuation_info__set_internal_info(
-	map(label, internal_layout_info), continuation_info,
-	continuation_info).
-:- mode continuation_info__set_internal_info(in, in, out) is det.
-
-continuation_info__set_internal_info(Internals, ContInfo0, ContInfo) :-
-	ContInfo0 = continuation_info(ProcLayoutMap, _),
-	ContInfo = continuation_info(ProcLayoutMap, Internals).
-
-	%
-	% Get the internal_info.
-	%
-:- pred continuation_info__get_internal_info(
-		map(label, internal_layout_info),
-		continuation_info, continuation_info).
-:- mode continuation_info__get_internal_info(out, in, out) is det.
-
-continuation_info__get_internal_info(InternalMap, ContInfo, ContInfo) :-
-	ContInfo = continuation_info(_, InternalMap).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/dense_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dense_switch.m,v
retrieving revision 1.32
diff -u -u -r1.32 dense_switch.m
--- dense_switch.m	1998/03/03 17:33:59	1.32
+++ dense_switch.m	1998/03/28 04:03:46
@@ -236,17 +236,9 @@
 	->
 		{ Comment = "case of dense switch" },
 		% We need to save the expression cache, etc.,
-		% and restore them when we've finished
+		% and restore them when we've finished.
 		code_info__grab_code_info(CodeInfoAtStart),
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ Goal = _ - GoalInfo },
-			{ goal_info_get_goal_path(GoalInfo, Path) },
-			trace__generate_event_code(switch(Path), TraceInfo,
-				TraceCode)
-		;
-			{ TraceCode = empty }
-		),
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 		{ Code =
Index: compiler/disj_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/disj_gen.m,v
retrieving revision 1.62
diff -u -u -r1.62 disj_gen.m
--- disj_gen.m	1998/03/03 17:34:07	1.62
+++ disj_gen.m	1998/03/28 04:02:25
@@ -75,7 +75,7 @@
 		% disjunct that might allocate some heap space.
 	{ MaybeHpSlot = no },
 
-		% Generate all the disjuncts
+		% Generate all the disjuncts.
 	code_info__get_next_label(EndLabel),
 	disj_gen__generate_pruned_disjuncts(Goals, StoreMap, EndLabel,
 		ReclaimHeap, MaybeHpSlot, MaybeTicketSlot, no, GoalsCode),
@@ -125,7 +125,7 @@
 		code_info__make_known_failure_cont(ResumeVars, ResumeLocs, no,
 			ModContCode),
 			% The next line is to enable Goal to pass the
-			% pre_goal_update sanity check
+			% pre_goal_update sanity check.
 		{ goal_info_set_resume_point(GoalInfo0, no_resume_point,
 			GoalInfo) },
 		{ Goal = GoalExpr0 - GoalInfo },
@@ -133,11 +133,11 @@
 		( { First = no } ->
 				% Reset the heap pointer to recover memory
 				% allocated by the previous disjunct(s),
-				% if necessary
+				% if necessary.
 			code_info__maybe_restore_hp(MaybeHpSlot0,
 				RestoreHPCode),
 
-				% Reset the solver state if necessary
+				% Reset the solver state if necessary.
 			code_info__maybe_reset_ticket(MaybeTicketSlot, undo,
 				RestoreTicketCode)
 		;
@@ -146,7 +146,7 @@
 		),
 
 			% Save hp if it needs to be saved and hasn't been
-			% saved previously
+			% saved previously.
 		(
 			{ ReclaimHeap = yes },
 			{ code_util__goal_may_allocate_heap(Goal) },
@@ -161,20 +161,13 @@
 
 		code_info__grab_code_info(CodeInfo),
 
-			% generate the disjunct as a semi-deterministic goal
+			% Generate the disjunct as a semi-deterministic goal.
 		{ CodeModel = model_semi ->
 			true
 		;
 			error("pruned disj non-last goal is not semidet")
 		},
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo, Path) },
-			trace__generate_event_code(disj(Path), TraceInfo,
-				TraceCode)
-		;
-			{ TraceCode = empty }
-		),
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 
@@ -203,25 +196,18 @@
 			      RestCode)))))))))
 		}
 	;
-		% Emit code for the last disjunct
+		% Emit code for the last disjunct.
 
-			% Restore the heap pointer if necessary
+			% Restore the heap pointer if necessary.
 		code_info__maybe_restore_and_discard_hp(MaybeHpSlot0,
 			RestoreHPCode),
 
-			% Restore the solver state if necessary
+			% Restore the solver state if necessary.
 		code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot, 
 			undo, RestorePopTicketCode),
 
-			% Generate the goal
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo0, Path) },
-			trace__generate_event_code(disj(Path), TraceInfo,
-				TraceCode)
-		;
-			{ TraceCode = empty }
-		),
+			% Generate the goal.
+		trace__maybe_generate_internal_event_code(Goal0, TraceCode),
 		code_gen__generate_goal(CodeModel, Goal0, GoalCode),
 		code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
 
@@ -307,7 +293,7 @@
 		code_info__make_known_failure_cont(ResumeVars, ResumeLocs, yes,
 			ModContCode),
 			% The next line is to enable Goal to pass the
-			% pre_goal_update sanity check
+			% pre_goal_update sanity check.
 		{ goal_info_set_resume_point(GoalInfo0, no_resume_point,
 			GoalInfo) },
 		{ Goal = GoalExpr0 - GoalInfo },
@@ -315,11 +301,11 @@
 		( { First = no } ->
 				% Reset the heap pointer to recover memory
 				% allocated by the previous disjunct(s),
-				% if necessary
+				% if necessary.
 			code_info__maybe_restore_hp(MaybeHpSlot,
 				RestoreHPCode),
 
-				% Reset the solver state if necessary
+				% Reset the solver state if necessary.
 			code_info__maybe_reset_ticket(MaybeTicketSlot, undo,
 				RestoreTicketCode)
 		;
@@ -329,20 +315,12 @@
 
 		code_info__grab_code_info(CodeInfo),
 
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo, Path) },
-			trace__generate_event_code(disj(Path), TraceInfo,
-				TraceCode)
-		;
-			{ TraceCode = empty }
-		),
-
+		trace__maybe_generate_internal_event_code(Goal, TraceCode),
 		code_gen__generate_goal(model_non, Goal, GoalCode),
 		code_info__generate_branch_end(model_non, StoreMap, SaveCode),
 
-			% make sure every variable in the resume set is in its
-			% stack slot
+			% Make sure every variable in the resume set is in its
+			% stack slot.
 		code_info__flush_resume_vars_to_stack(FlushResumeVarsCode),
 
 		{ BranchCode = node([
@@ -353,9 +331,9 @@
 		code_info__slap_code_info(CodeInfo),
 		code_info__pop_resume_point_vars,
 
-			% make sure that the redoip of the top nondet frame
+			% Make sure that the redoip of the top nondet frame
 			% points to the right label, and set up the start of
-			% the next disjunct
+			% the next disjunct.
 		code_info__restore_failure_cont(RestoreContCode),
 
 		disj_gen__generate_non_disjuncts(Goals, StoreMap, EndLabel,
@@ -373,7 +351,7 @@
 			      RestCode)))))))))
 		}
 	;
-		% Emit code for the last disjunct
+		% Emit code for the last disjunct.
 
 		{ Goals = [] ->
 			true
@@ -381,23 +359,15 @@
 			error("disj_gen__generate_non_disjuncts: last disjunct followed by others")
 		},
 
-			% Restore the heap pointer if necessary
+			% Restore the heap pointer if necessary.
 		code_info__maybe_restore_and_discard_hp(MaybeHpSlot,
 			RestoreHPCode),
 
-			% Restore the solver state if necessary
+			% Restore the solver state if necessary.
 		code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot,
 			undo, RestorePopTicketCode),
 
-		code_info__get_maybe_trace_info(MaybeTraceInfo),
-		( { MaybeTraceInfo = yes(TraceInfo) } ->
-			{ goal_info_get_goal_path(GoalInfo0, Path) },
-			trace__generate_event_code(disj(Path), TraceInfo,
-				TraceCode)
-		;
-			{ TraceCode = empty }
-		),
-
+		trace__maybe_generate_internal_event_code(Goal0, TraceCode),
 		code_gen__generate_goal(model_non, Goal0, GoalCode),
 		code_info__generate_branch_end(model_non, StoreMap, SaveCode),
 
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.43
diff -u -u -r1.43 goal_util.m
--- goal_util.m	1998/03/03 17:34:19	1.43
+++ goal_util.m	1998/03/31 09:47:17
@@ -61,6 +61,21 @@
 :- pred goal_util__goal_vars(hlds_goal, set(var)).
 :- mode goal_util__goal_vars(in, out) is det.
 
+	%
+	% A type-info variable may be non-local to a goal if any of 
+	% the ordinary non-local variables for that goal are
+	% polymorphically typed with a type that depends on that
+	% type-info variable.
+	%
+	% In addition, a typeclass-info may be non-local to a goal if
+	% any of the non-local variables for that goal are
+	% polymorphically typed and are constrained by the typeclass
+	% constraints for that typeclass-info variable.
+	%
+:- pred goal_util__extra_nonlocal_typeinfos(map(var, type_info_locn),
+		map(var, type), hlds_goal, set(var)).
+:- mode goal_util__extra_nonlocal_typeinfos(in, in, in, out) is det.
+
 	% See whether the goal is a branched structure.
 :- pred goal_util__goal_is_branched(hlds_goal_expr).
 :- mode goal_util__goal_is_branched(in) is semidet.
@@ -485,6 +500,23 @@
 	set__insert_list(Set0, NonLocals, Set1),
 	set__insert_list(Set1, LambdaVars, Set2),
 	goal_util__goal_vars_2(Goal, Set2, Set).
+
+%-----------------------------------------------------------------------------%
+
+goal_util__extra_nonlocal_typeinfos(TypeVarMap, VarTypes,
+		Goal0, NonLocalTypeInfos) :-
+	Goal0 = _ - GoalInfo0,
+	goal_info_get_nonlocals(GoalInfo0, NonLocals),
+	set__to_sorted_list(NonLocals, NonLocalsList),
+	map__apply_to_list(NonLocalsList, VarTypes, NonLocalsTypes),
+	term__vars_list(NonLocalsTypes, NonLocalTypeVars),
+		% Find all the type-infos and typeclass-infos that are
+		% non-local
+	solutions_set(lambda([Var::out] is nondet, (
+			list__member(TheVar, NonLocalTypeVars),
+			map__search(TypeVarMap, TheVar, Location),
+			type_info_locn_var(Location, Var)
+		)), NonLocalTypeInfos).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.45
diff -u -u -r1.45 handle_options.m
--- handle_options.m	1998/03/03 17:34:21	1.45
+++ handle_options.m	1998/03/31 06:50:37
@@ -262,12 +262,16 @@
 	% --generate-trace requires 
 	% 	- disabling optimizations that would change 
 	% 	  the trace being generated
-	%	- enabling excess_assign to exclude junk vars from the trace
-	%	  (and to ensure consistent paths across optimization levels)
+	%	- enabling some low level optimizations to ensure consistent
+	%	  paths across optimization levels)
 	% 	- enabling stack layouts
 	% 	- enabling typeinfo liveness
 	globals__io_lookup_bool_option(generate_trace, Trace),
 	( { Trace = yes } ->
+			% The following options modify the structure
+			% of the program, which makes it difficult to
+			% relate the trace to the source code (although
+			% it can be easily related to the transformed HLDS).
 		globals__io_set_option(inline_simple, bool(no)),
 		globals__io_set_option(inline_single_use, bool(no)),
 		globals__io_set_option(inline_compound_threshold, int(0)),
@@ -276,7 +280,29 @@
 		globals__io_set_option(optimize_duplicate_calls, bool(no)),
 		globals__io_set_option(optimize_constructor_last_call,
 			bool(no)),
+
+			% The following option prevents useless variables
+			% from cluttering the trace. Its explicit setting
+			% removes a source of variability in the goal paths
+			% reported by tracing.
 		globals__io_set_option(excess_assign, bool(yes)),
+			% The explicit setting of the following option
+			% removes a source of variability in the goal paths
+			% reported by tracing.
+		globals__io_set_option(follow_code, bool(yes)),
+			% The following option selects a special-case
+			% code generator that cannot (yet) implement tracing.
+		globals__io_set_option(middle_rec, bool(no)),
+			% Tracing inserts C code into the generated LLDS.
+			% Value numbering cannot optimize such LLDS code.
+			% (If it tried, it would get it wrong due to the
+			% absence of liveness annotations on the introduced
+			% labels.) We turn value numbering off now so that
+			% we don't have to discover this fact anew
+			% for each procedure.
+		globals__io_set_option(optimize_value_number, bool(no)),
+			% 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))
 	;
Index: compiler/ite_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ite_gen.m,v
retrieving revision 1.53
diff -u -u -r1.53 ite_gen.m
--- ite_gen.m	1998/01/23 12:56:38	1.53
+++ ite_gen.m	1998/03/28 04:36:29
@@ -115,15 +115,7 @@
 	code_info__maybe_discard_hp(MaybeHpSlot),
 
 		% Generate the then branch
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfoThen) } ->
-		{ ThenGoal = _ - ThenGoalInfo },
-		{ goal_info_get_goal_path(ThenGoalInfo, ThenPath) },
-		trace__generate_event_code(ite_then(ThenPath), TraceInfoThen,
-			ThenTraceCode)
-	;
-		{ ThenTraceCode = empty }
-	),
+	trace__maybe_generate_internal_event_code(ThenGoal, ThenTraceCode),
 	code_gen__generate_goal(CodeModel, ThenGoal, ThenCode),
 	code_info__generate_branch_end(CodeModel, StoreMap, ThenSaveCode),
 
@@ -135,14 +127,7 @@
 	code_info__maybe_restore_and_discard_hp(MaybeHpSlot, RestoreHPCode),
 
 		% Generate the else branch
-	( { MaybeTraceInfo = yes(TraceInfoElse) } ->
-		{ ElseGoal = _ - ElseGoalInfo },
-		{ goal_info_get_goal_path(ElseGoalInfo, ElsePath) },
-		trace__generate_event_code(ite_else(ElsePath), TraceInfoElse,
-			ElseTraceCode)
-	;
-		{ ElseTraceCode = empty }
-	),
+	trace__maybe_generate_internal_event_code(ElseGoal, ElseTraceCode),
 	code_gen__generate_goal(CodeModel, ElseGoal, ElseCode),
 	code_info__generate_branch_end(CodeModel, StoreMap, ElseSaveCode),
 
@@ -272,15 +257,7 @@
 	),
 
 		% Generate the then branch
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfoThen) } ->
-		{ ThenGoal = _ - ThenGoalInfo },
-		{ goal_info_get_goal_path(ThenGoalInfo, ThenPath) },
-		trace__generate_event_code(ite_then(ThenPath), TraceInfoThen,
-			ThenTraceCode)
-	;
-		{ ThenTraceCode = empty }
-	),
+	trace__maybe_generate_internal_event_code(ThenGoal, ThenTraceCode),
 	code_gen__generate_goal(model_non, ThenGoal, ThenCode),
 	code_info__generate_branch_end(model_non, StoreMap, ThenSaveCode),
 
@@ -292,14 +269,7 @@
 		RestoreTicketCode),
 
 		% Generate the else branch
-	( { MaybeTraceInfo = yes(TraceInfoElse) } ->
-		{ ElseGoal = _ - ElseGoalInfo },
-		{ goal_info_get_goal_path(ElseGoalInfo, ElsePath) },
-		trace__generate_event_code(ite_else(ElsePath), TraceInfoElse,
-			ElseTraceCode)
-	;
-		{ ElseTraceCode = empty }
-	),
+	trace__maybe_generate_internal_event_code(ElseGoal, ElseTraceCode),
 	code_gen__generate_goal(model_non, ElseGoal, ElseCode),
 	code_info__generate_branch_end(model_non, StoreMap, ElseSaveCode),
 
Index: compiler/lambda.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lambda.m,v
retrieving revision 1.40
diff -u -u -r1.40 lambda.m
--- lambda.m	1998/03/03 17:34:45	1.40
+++ lambda.m	1998/03/18 07:12:16
@@ -41,28 +41,28 @@
 :- interface. 
 
 :- import_module hlds_module, hlds_pred, hlds_goal, hlds_data, prog_data.
-:- import_module list, map, term, varset.
+:- import_module list, map, set, term, varset.
 
 :- pred lambda__process_pred(pred_id, module_info, module_info).
 :- mode lambda__process_pred(in, in, out) is det.
 
 :- pred lambda__transform_lambda(pred_or_func, string, list(var), list(mode), 
-		determinism, list(var), hlds_goal, unification,
+		determinism, list(var), set(var), hlds_goal, unification,
 		varset, map(var, type), list(class_constraint), tvarset,
 		map(tvar, type_info_locn), map(class_constraint, var),
 		module_info, unify_rhs, unification, module_info).
-:- mode lambda__transform_lambda(in, in, in, in, in, in, in, in, in, in, in, in,
-		in, in, in, out, out, out) is det.
+:- mode lambda__transform_lambda(in, in, in, in, in, in, in, in, in, in, in,
+		in, in, in, in, in, out, out, out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
 :- implementation.
 
-:- import_module make_hlds.
-:- import_module prog_util, mode_util, inst_match, llds, arg_info.
+:- import_module make_hlds, globals, options.
+:- import_module goal_util, prog_util, mode_util, inst_match, llds, arg_info.
 
-:- import_module bool, set, string, std_util, require.
+:- import_module bool, string, std_util, require.
 
 :- type lambda_info --->
 		lambda_info(
@@ -238,17 +238,19 @@
 		Unification0, Functor, Unification, LambdaInfo0, LambdaInfo) :-
 	LambdaInfo0 = lambda_info(VarSet, VarTypes, Constraints, TVarSet,
 			TVarMap, TCVarMap, POF, PredName, ModuleInfo0),
+	goal_util__extra_nonlocal_typeinfos(TVarMap, VarTypes,
+		LambdaGoal, ExtraTypeInfos),
 	lambda__transform_lambda(PredOrFunc, PredName, Vars, Modes, Det,
-		OrigNonLocals0, LambdaGoal, Unification0, VarSet, VarTypes,
-		Constraints, TVarSet, TVarMap, TCVarMap, ModuleInfo0, Functor,
-		Unification, ModuleInfo),
+		OrigNonLocals0, ExtraTypeInfos, LambdaGoal, Unification0,
+		VarSet, VarTypes, Constraints, TVarSet, TVarMap, TCVarMap,
+		ModuleInfo0, Functor, Unification, ModuleInfo),
 	LambdaInfo = lambda_info(VarSet, VarTypes, Constraints, TVarSet,
 			TVarMap, TCVarMap, POF, PredName, ModuleInfo).
 
 lambda__transform_lambda(PredOrFunc, OrigPredName, Vars, Modes, Detism,
-		OrigVars, LambdaGoal, Unification0, VarSet, VarTypes,
-		Constraints, TVarSet, TVarMap, TCVarMap, ModuleInfo0, Functor,
-		Unification, ModuleInfo) :-
+		OrigVars, ExtraTypeInfos, LambdaGoal, Unification0,
+		VarSet, VarTypes, Constraints, TVarSet, TVarMap, TCVarMap,
+		ModuleInfo0, Functor, Unification, ModuleInfo) :-
 	(
 		Unification0 = construct(Var0, _, _, UniModes0)
 	->
@@ -270,7 +272,20 @@
 
 	LambdaGoal = _ - LambdaGoalInfo,
 	goal_info_get_nonlocals(LambdaGoalInfo, NonLocals0),
-	set__delete_list(NonLocals0, Vars, NonLocals),
+	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
+	),
+
 	set__to_sorted_list(NonLocals, ArgVars1),
 	( 
 		LambdaGoal = call(PredId0, ProcId0, CallVars,
@@ -376,7 +391,6 @@
 		% inputs came before outputs, but that resulted in the
 		% HLDS not being type or mode correct which caused problems
 		% for some transformations and for rerunning mode analysis.
-		module_info_globals(ModuleInfo1, Globals),
 		arg_info__ho_call_args_method(Globals, ArgsMethod),
 
 		% Now construct the proc_info and pred_info for the new
Index: compiler/live_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.72
diff -u -u -r1.72 live_vars.m
--- live_vars.m	1998/02/03 08:18:22	1.72
+++ live_vars.m	1998/03/31 10:06:05
@@ -36,6 +36,7 @@
 
 :- import_module llds, arg_info, prog_data, hlds_goal, hlds_data, mode_util.
 :- import_module liveness, code_aux, globals, graph_colour, instmap, options.
+:- import_module trace.
 :- import_module list, map, set, std_util, assoc_list, bool.
 :- import_module int, term, require.
 
@@ -47,8 +48,16 @@
 
 	initial_liveness(ProcInfo0, ModuleInfo, Liveness0),
 	set__init(LiveSets0),
-	set__init(ResumeVars0),
-	build_live_sets_in_goal(Goal0, Liveness0, ResumeVars0, LiveSets0,
+	module_info_globals(ModuleInfo, Globals),
+	globals__lookup_bool_option(Globals, generate_trace, Trace),
+	( Trace = yes ->
+		trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0),
+		set__insert(LiveSets0, ResumeVars0, LiveSets1)
+	;
+		set__init(ResumeVars0),
+		LiveSets1 = LiveSets0
+	),
+	build_live_sets_in_goal(Goal0, Liveness0, ResumeVars0, LiveSets1,
 		ModuleInfo, ProcInfo0, _Liveness, _ResumeVars, LiveSets),
 	graph_colour__group_elements(LiveSets, ColourSets),
 	set__to_sorted_list(ColourSets, ColourList),
Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.91
diff -u -u -r1.91 liveness.m
--- liveness.m	1998/03/03 17:34:49	1.91
+++ liveness.m	1998/03/31 10:06:13
@@ -145,7 +145,7 @@
 
 :- import_module hlds_goal, hlds_data, llds, quantification, (inst), instmap.
 :- import_module hlds_out, mode_util, code_util, quantification, options.
-:- import_module prog_data, globals, passes_aux.
+:- import_module prog_data, trace, globals, passes_aux.
 
 :- import_module bool, map, std_util, list, assoc_list, require.
 :- import_module varset, string.
@@ -164,7 +164,13 @@
 	initial_deadness(ProcInfo1, ModuleInfo, Deadness0),
 	detect_deadness_in_goal(Goal1, Deadness0, LiveInfo, _, Goal2),
 
-	set__init(ResumeVars0),
+	module_info_globals(ModuleInfo, Globals),
+	globals__lookup_bool_option(Globals, generate_trace, Trace),
+	( Trace = yes ->
+		trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0)
+	;
+		set__init(ResumeVars0)
+	),
 	detect_resume_points_in_goal(Goal2, Liveness0, LiveInfo,
 		ResumeVars0, Goal, _),
 
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.77
diff -u -u -r1.77 llds_out.m
--- llds_out.m	1998/03/18 08:07:38	1.77
+++ llds_out.m	1998/03/31 01:33:58
@@ -18,13 +18,13 @@
 :- interface.
 
 :- import_module llds, prog_data, hlds_data.
-:- import_module bool, io.
+:- import_module set_bbbtree, bool, io.
 
 	% Given a 'c_file' structure, open the appropriate .c file
 	% and output the code into that file.
 
-:- pred output_c_file(c_file, io__state, io__state).
-:- mode output_c_file(in, di, uo) is det.
+:- pred output_c_file(c_file, set_bbbtree(label), io__state, io__state).
+:- mode output_c_file(in, in, di, uo) is det.
 
 	% Convert an lval to a string description of that lval.
 
@@ -135,16 +135,17 @@
 		;	data_addr(data_addr)
 		;	pragma_c_struct(string).
 
-output_c_file(C_File) -->
+output_c_file(C_File, StackLayoutLabels) -->
 	globals__io_lookup_bool_option(split_c_files, SplitFiles),
 	( { SplitFiles = yes } ->
 		{ C_File = c_file(ModuleName, C_HeaderInfo, C_Modules) },
 		module_name_to_file_name(ModuleName, ".dir", yes, ObjDirName),
 		make_directory(ObjDirName),
 		output_c_file_init(ModuleName, C_Modules),
-		output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo)
+		output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo,
+			StackLayoutLabels)
 	;
-		output_single_c_file(C_File, no)
+		output_single_c_file(C_File, no, StackLayoutLabels)
 	).
 
 :- pred make_directory(string, io__state, io__state).
@@ -156,15 +157,17 @@
 	io__call_system(Command, _Result).
 
 :- pred output_c_file_list(list(c_module), int, module_name,
-			list(c_header_code), io__state, io__state).
-:- mode output_c_file_list(in, in, in, in, di, uo) is det.
+	list(c_header_code), set_bbbtree(label), io__state, io__state).
+:- mode output_c_file_list(in, in, in, in, in, di, uo) is det.
 
-output_c_file_list([], _, _, _) --> [].
-output_c_file_list([Module|Modules], Num, ModuleName, C_HeaderLines) -->
+output_c_file_list([], _, _, _, _) --> [].
+output_c_file_list([Module|Modules], Num, ModuleName, C_HeaderLines,
+		StackLayoutLabels) -->
 	output_single_c_file(c_file(ModuleName, C_HeaderLines, [Module]),
-		yes(Num)),
+		yes(Num), StackLayoutLabels),
 	{ Num1 is Num + 1 },
-	output_c_file_list(Modules, Num1, ModuleName, C_HeaderLines).
+	output_c_file_list(Modules, Num1, ModuleName, C_HeaderLines,
+		StackLayoutLabels).
 
 :- pred output_c_file_init(module_name, list(c_module), io__state, io__state).
 :- mode output_c_file_init(in, in, di, uo) is det.
@@ -205,11 +208,12 @@
 		io__set_exit_status(1)
 	).
 
-:- pred output_single_c_file(c_file, maybe(int), io__state, io__state).
-:- mode output_single_c_file(in, in, di, uo) is det.
+:- pred output_single_c_file(c_file, maybe(int), set_bbbtree(label),
+	io__state, io__state).
+:- mode output_single_c_file(in, in, in, di, uo) is det.
 
-output_single_c_file(c_file(ModuleName, C_HeaderLines, Modules), SplitFiles) 
-		-->
+output_single_c_file(c_file(ModuleName, C_HeaderLines, Modules), SplitFiles,
+		StackLayoutLabels) -->
 	( { SplitFiles = yes(Num) } ->
 		module_name_to_split_c_file_name(ModuleName, Num, ".c",
 			FileName)
@@ -245,7 +249,7 @@
 		{ gather_c_file_labels(Modules, Labels) },
 		{ set__init(DeclSet0) },
 		output_c_label_decl_list(Labels, DeclSet0, DeclSet),
-		output_c_module_list(Modules, DeclSet),
+		output_c_module_list(Modules, StackLayoutLabels, DeclSet),
 		( { SplitFiles = yes(_) } ->
 			[]
 		;
@@ -424,18 +428,21 @@
 	io__write_string("_bunch_"),
 	io__write_int(Number).
 
-:- pred output_c_module_list(list(c_module), decl_set, io__state, io__state).
-:- mode output_c_module_list(in, in, di, uo) is det.
+:- pred output_c_module_list(list(c_module), set_bbbtree(label), decl_set,
+	io__state, io__state).
+:- mode output_c_module_list(in, in, in, di, uo) is det.
 
-output_c_module_list([], _) --> [].
-output_c_module_list([M | Ms], DeclSet0) -->
-	output_c_module(M, DeclSet0, DeclSet),
-	output_c_module_list(Ms, DeclSet).
+output_c_module_list([], _, _) --> [].
+output_c_module_list([M | Ms], StackLayoutLabels, DeclSet0) -->
+	output_c_module(M, StackLayoutLabels, DeclSet0, DeclSet),
+	output_c_module_list(Ms, StackLayoutLabels, DeclSet).
 
-:- pred output_c_module(c_module, decl_set, decl_set, io__state, io__state).
-:- mode output_c_module(in, in, out, di, uo) is det.
+:- pred output_c_module(c_module, set_bbbtree(label), decl_set, decl_set,
+	io__state, io__state).
+:- mode output_c_module(in, in, in, out, di, uo) is det.
 
-output_c_module(c_module(ModuleName, Procedures), DeclSet0, DeclSet) -->
+output_c_module(c_module(ModuleName, Procedures), StackLayoutLabels,
+		DeclSet0, DeclSet) -->
 	io__write_string("\n"),
 	output_c_procedure_list_decls(Procedures, DeclSet0, DeclSet),
 	io__write_string("\n"),
@@ -443,7 +450,7 @@
 	io__write_string(ModuleName),
 	io__write_string(")\n"),
 	{ gather_c_module_labels(Procedures, Labels) },
-	output_c_label_init_list(Labels),
+	output_c_label_init_list(Labels, StackLayoutLabels),
 	io__write_string("BEGIN_CODE\n"),
 	io__write_string("\n"),
 	globals__io_lookup_bool_option(auto_comments, PrintComments),
@@ -452,7 +459,7 @@
 	io__write_string("END_MODULE\n").
 
 output_c_module(c_data(ModuleName, VarName, ExportedFromModule, ArgVals,
-		_Refs), DeclSet0, DeclSet) -->
+		_Refs), _, DeclSet0, DeclSet) -->
 	io__write_string("\n"),
 	{ DataAddr = data_addr(data_addr(ModuleName, VarName)) },
 	output_cons_arg_decls(ArgVals, "", "", 0, _, DeclSet0, DeclSet1),
@@ -471,7 +478,7 @@
 		0, _),
 	{ set__insert(DeclSet1, DataAddr, DeclSet) }.
 
-output_c_module(c_code(C_Code, Context), DeclSet, DeclSet) -->
+output_c_module(c_code(C_Code, Context), _, DeclSet, DeclSet) -->
 	globals__io_lookup_bool_option(auto_comments, PrintComments),
 	( { PrintComments = yes } ->
 		io__write_string("/* "),
@@ -485,7 +492,7 @@
 	io__write_string("\n"),
 	output_reset_line_num.
 
-output_c_module(c_export(PragmaExports), DeclSet, DeclSet) -->
+output_c_module(c_export(PragmaExports), _, DeclSet, DeclSet) -->
 	output_exported_c_functions(PragmaExports).
 
 	% output_c_header_include_lines reverses the list of c header lines
@@ -522,6 +529,7 @@
 
 :- pred output_exported_c_functions(list(string), io__state, io__state).
 :- mode output_exported_c_functions(in, di, uo) is det.
+
 output_exported_c_functions([]) --> [].
 output_exported_c_functions([F | Fs]) -->
 	io__write_string(F),
@@ -568,36 +576,53 @@
 	output_label(Label),
 	io__write_string(");\n").
 
-:- pred output_c_label_init_list(list(label), io__state, io__state).
-:- mode output_c_label_init_list(in, di, uo) is det.
+:- pred output_c_label_init_list(list(label), set_bbbtree(label),
+	io__state, io__state).
+:- mode output_c_label_init_list(in, in, di, uo) is det.
 
-output_c_label_init_list([]) --> [].
-output_c_label_init_list([Label | Labels]) -->
-	output_c_label_init(Label),
-	output_c_label_init_list(Labels).
+output_c_label_init_list([], _) --> [].
+output_c_label_init_list([Label | Labels], StackLayoutLabels) -->
+	output_c_label_init(Label, StackLayoutLabels),
+	output_c_label_init_list(Labels, StackLayoutLabels).
 
-:- pred output_c_label_init(label, io__state, io__state).
-:- mode output_c_label_init(in, di, uo) is det.
+:- pred output_c_label_init(label, set_bbbtree(label), io__state, io__state).
+:- mode output_c_label_init(in, in, di, uo) is det.
 
-output_c_label_init(Label) -->
+output_c_label_init(Label, StackLayoutLabels) -->
 	(
 		{ Label = exported(_) },
-		io__write_string("\tinit_entry("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_entry_sl(")
+		;
+			io__write_string("\tinit_entry(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	;
 		{ Label = local(_) },
-		io__write_string("\tinit_entry("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_entry_sl(")
+		;
+			io__write_string("\tinit_entry(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	;
 		{ Label = c_local(_) },
-		io__write_string("\tinit_local("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_local_sl(")
+		;
+			io__write_string("\tinit_local(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	;
 		{ Label = local(_, _) },
-		io__write_string("\tinit_label("),
+		( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+			io__write_string("\tinit_label_sl(")
+		;
+			io__write_string("\tinit_label(")
+		),
 		output_label(Label),
 		io__write_string(");\n")
 	).
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.81
diff -u -u -r1.81 mercury_compile.m
--- mercury_compile.m	1998/03/30 13:30:57	1.81
+++ mercury_compile.m	1998/03/31 01:33:18
@@ -26,7 +26,7 @@
 
 	% library modules
 :- import_module int, list, map, set, std_util, dir, require, string, bool.
-:- import_module library, getopt, term, varset.
+:- import_module library, getopt, term, set_bbbtree, varset.
 
 	% the main compiler passes (in order of execution)
 :- import_module handle_options, prog_io, prog_out, modules, module_qual.
@@ -997,13 +997,13 @@
 	;
 		{ Proc = Proc0 }
 	),
-	{ globals__lookup_bool_option(Globals, basic_stack_layout,
-		BasicStackLayout) },
-	( { BasicStackLayout = yes } ->
+	{ globals__lookup_bool_option(Globals, agc_stack_layout,
+		AgcStackLayout) },
+	( { AgcStackLayout = yes } ->
 		{ Proc = c_procedure(_, _, PredProcId, Instructions) },
 		{ module_info_get_continuation_info(ModuleInfo5, ContInfo2) },
 		write_proc_progress_message(
-		   "% Generating stack layout continuation information for ",
+			"% Generating call continuation information for ",
 				PredId, ProcId, ModuleInfo5),
 		{ continuation_info__process_instructions(PredProcId,
 			Instructions, ContInfo2, ContInfo3) },
@@ -1631,14 +1631,14 @@
 
 mercury_compile__maybe_generate_stack_layouts(ModuleInfo0, LLDS0, Verbose, 
 		Stats, ModuleInfo) -->
-	globals__io_lookup_bool_option(agc_stack_layout, StackLayout),
-	( { StackLayout = yes } ->
+	globals__io_lookup_bool_option(agc_stack_layout, AgcStackLayout),
+	( { AgcStackLayout = yes } ->
 		maybe_write_string(Verbose,
-			"% Generating stack layout continuation information..."),
+			"% Generating call continuation information..."),
 		maybe_flush_output(Verbose),
 		{ module_info_get_continuation_info(ModuleInfo0, ContInfo0) },
-		{ continuation_info__process_llds(LLDS0, ContInfo0,
-			ContInfo) },
+		{ continuation_info__process_llds(LLDS0,
+			ContInfo0, ContInfo) },
 		{ module_info_set_continuation_info(ModuleInfo0, ContInfo,
 			ModuleInfo) },
 		maybe_write_string(Verbose, " done.\n"),
@@ -1664,10 +1664,12 @@
 	{ base_type_info__generate_llds(HLDS0, BaseTypeInfos) },
 	{ base_type_layout__generate_llds(HLDS0, HLDS1, BaseTypeLayouts) },
 	{ BasicStackLayout = yes ->
-		stack_layout__generate_llds(HLDS1, HLDS, StackLayouts),
+		stack_layout__generate_llds(HLDS1, HLDS,
+			StackLayouts, StackLayoutLabelMap),
 		list__append(StackLayouts, BaseTypeLayouts, StaticData0)
 	;
 		HLDS = HLDS1,
+		set_bbbtree__init(StackLayoutLabelMap),
 		StaticData0 = BaseTypeLayouts
 	},
 
@@ -1677,7 +1679,8 @@
 	{ list__append(BaseTypeInfos, StaticData, AllData) },
 	mercury_compile__chunk_llds(HLDS, LLDS1, AllData, CommonData,
 		LLDS2, NumChunks),
-	mercury_compile__output_llds(ModuleName, LLDS2, Verbose, Stats),
+	mercury_compile__output_llds(ModuleName, LLDS2, StackLayoutLabelMap,
+		Verbose, Stats),
 
 	export__produce_header_file(HLDS, ModuleName),
 
@@ -1791,18 +1794,19 @@
 	Num1 is Num + 1,
 	mercury_compile__combine_chunks_2(Chunks, ModName, Num1, Modules).
 
-:- pred mercury_compile__output_llds(module_name, c_file, bool, bool,
-	io__state, io__state).
-:- mode mercury_compile__output_llds(in, in, in, in, di, uo) is det.
+:- pred mercury_compile__output_llds(module_name, c_file, set_bbbtree(label),
+	bool, bool, io__state, io__state).
+:- mode mercury_compile__output_llds(in, in, in, in, in, di, uo) is det.
 
-mercury_compile__output_llds(ModuleName, LLDS, Verbose, Stats) -->
+mercury_compile__output_llds(ModuleName, LLDS, StackLayoutLabels,
+		Verbose, Stats) -->
 	maybe_write_string(Verbose,
 		"% Writing output to `"),
 	module_name_to_file_name(ModuleName, ".c", yes, FileName),
 	maybe_write_string(Verbose, FileName),
 	maybe_write_string(Verbose, "'..."),
 	maybe_flush_output(Verbose),
-	output_c_file(LLDS),
+	output_c_file(LLDS, StackLayoutLabels),
 	maybe_write_string(Verbose, " done.\n"),
 	maybe_flush_output(Verbose),
 	maybe_report_stats(Stats).
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.90
diff -u -u -r1.90 opt_util.m
--- opt_util.m	1998/03/03 17:35:30	1.90
+++ opt_util.m	1998/03/16 04:26:50
@@ -282,16 +282,6 @@
 :- pred opt_util__rvals_free_of_lval(list(rval), lval).
 :- mode opt_util__rvals_free_of_lval(in, in) is semidet.
 
-	% Return the set of lvals referenced in an rval.
-
-:- pred opt_util__lvals_in_rval(rval, list(lval)).
-:- mode opt_util__lvals_in_rval(in, out) is det.
-
-	% Return the set of lvals referenced in an lval.
-
-:- pred opt_util__lvals_in_lval(lval, list(lval)).
-:- mode opt_util__lvals_in_lval(in, out) is det.
-
 	% Count the number of hp increments in a block of code.
 
 :- pred opt_util__count_incr_hp(list(instruction), int).
@@ -1544,59 +1534,6 @@
 opt_util__rval_free_of_lval(binop(_, Rval1, Rval2), Forbidden) :-
 	opt_util__rval_free_of_lval(Rval1, Forbidden),
 	opt_util__rval_free_of_lval(Rval2, Forbidden).
-
-%-----------------------------------------------------------------------------%
-
-opt_util__lvals_in_lval(reg(_, _), []).
-opt_util__lvals_in_lval(stackvar(_), []).
-opt_util__lvals_in_lval(framevar(_), []).
-opt_util__lvals_in_lval(succip, []).
-opt_util__lvals_in_lval(maxfr, []).
-opt_util__lvals_in_lval(curfr, []).
-opt_util__lvals_in_lval(succip(Rval), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
-opt_util__lvals_in_lval(redoip(Rval), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
-opt_util__lvals_in_lval(succfr(Rval), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
-opt_util__lvals_in_lval(prevfr(Rval), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
-opt_util__lvals_in_lval(hp, []).
-opt_util__lvals_in_lval(sp, []).
-opt_util__lvals_in_lval(field(_, Rval1, Rval2), Lvals) :-
-	opt_util__lvals_in_rval(Rval1, Lvals1),
-	opt_util__lvals_in_rval(Rval2, Lvals2),
-	list__append(Lvals1, Lvals2, Lvals).
-opt_util__lvals_in_lval(lvar(_), []).
-opt_util__lvals_in_lval(temp(_, _), []).
-opt_util__lvals_in_lval(mem_ref(Rval), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
-
-opt_util__lvals_in_rval(lval(Lval), [Lval | Lvals]) :-
-	opt_util__lvals_in_lval(Lval, Lvals).
-opt_util__lvals_in_rval(var(_), _) :-
-	error("found var in opt_util__lvals_in_rval").
-opt_util__lvals_in_rval(create(_, _, _, _, _), []).
-opt_util__lvals_in_rval(mkword(_, Rval), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
-opt_util__lvals_in_rval(const(_), []).
-opt_util__lvals_in_rval(unop(_, Rval), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
-opt_util__lvals_in_rval(binop(_, Rval1, Rval2), Lvals) :-
-	opt_util__lvals_in_rval(Rval1, Lvals1),
-	opt_util__lvals_in_rval(Rval2, Lvals2),
-	list__append(Lvals1, Lvals2, Lvals).
-opt_util__lvals_in_rval(mem_addr(MemRef), Lvals) :-
-	opt_util__lvals_in_mem_ref(MemRef, Lvals).
-
-	% XXX
-:- pred opt_util__lvals_in_mem_ref(mem_ref, list(lval)).
-:- mode opt_util__lvals_in_mem_ref(in, out) is det.
-
-opt_util__lvals_in_mem_ref(stackvar_ref(_), []).
-opt_util__lvals_in_mem_ref(framevar_ref(_), []).
-opt_util__lvals_in_mem_ref(heap_ref(Rval, _, _), Lvals) :-
-	opt_util__lvals_in_rval(Rval, Lvals).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.131
diff -u -u -r1.131 polymorphism.m
--- polymorphism.m	1998/03/30 03:09:06	1.131
+++ polymorphism.m	1998/03/30 10:24:18
@@ -295,7 +295,7 @@
 :- import_module hlds_pred, hlds_goal, hlds_data, llds, (lambda).
 :- import_module prog_data, type_util, mode_util, quantification, instmap.
 :- import_module code_util, unify_proc, special_pred, prog_util, make_hlds.
-:- import_module (inst), hlds_out, base_typeclass_info, passes_aux.
+:- import_module (inst), hlds_out, base_typeclass_info, goal_util, passes_aux.
 
 :- import_module bool, int, string, list, set, map.
 :- import_module term, varset, std_util, require, assoc_list.
@@ -554,7 +554,7 @@
 
 	% process any polymorphic calls inside the goal
 	polymorphism__process_goal(Goal0, Goal1, Info0, Info1),
-	polymorphism__fixup_quantification(Goal1, Goal, Info1, Info),
+	polymorphism__fixup_quantification(Goal1, Goal, _, Info1, Info),
 	Info = poly_info(VarSet, VarTypes, TypeVarSet,
 				TypeInfoMap, TypeclassInfoLocations,
 				_Proofs, _PredName, ModuleInfo),
@@ -752,10 +752,11 @@
 		% lambda goal and then convert the lambda expression
 		% into a new predicate
 		polymorphism__process_goal(LambdaGoal0, LambdaGoal1),
-		polymorphism__fixup_quantification(LambdaGoal1, LambdaGoal),
+		polymorphism__fixup_quantification(LambdaGoal1,
+				LambdaGoal, NonLocalTypeInfos),
 		polymorphism__process_lambda(PredOrFunc, Vars, Modes,
-				Det, ArgVars, LambdaGoal, Unification,
-				Y1, Unification1),
+				Det, ArgVars, NonLocalTypeInfos, LambdaGoal,
+				Unification, Y1, Unification1),
 		{ Goal = unify(XVar, Y1, Mode, Unification1, Context)
 				- GoalInfo }
 	;
@@ -961,8 +962,8 @@
 	).
 
 :- pred polymorphism__fixup_quantification(hlds_goal, hlds_goal,
-		poly_info, poly_info).
-:- mode polymorphism__fixup_quantification(in, out, in, out) is det.
+		set(var), poly_info, poly_info).
+:- mode polymorphism__fixup_quantification(in, out, out, in, out) is det.
 
 %
 % If the predicate we are processing is a polymorphic predicate,
@@ -971,36 +972,18 @@
 % so that it includes the type-info variables in the non-locals set.
 %
 
-polymorphism__fixup_quantification(Goal0, Goal, Info0, Info) :-
+polymorphism__fixup_quantification(Goal0, Goal, NewOutsideVars, Info0, Info) :-
 	Info0 = poly_info(VarSet0, VarTypes0, TypeVarSet, TypeVarMap,
 			TypeClassVarMap, Proofs, PredName, ModuleInfo),
 	( map__is_empty(TypeVarMap) ->
+		set__init(NewOutsideVars),
 		Info = Info0,
 		Goal = Goal0
 	;
-		%
-		% A type-info variable may be non-local to a goal if any of 
-		% the ordinary non-local variables for that goal are
-		% polymorphically typed with a type that depends on that
-		% type-info variable.
-		%
-		% In addition, a typeclass-info may be non-local to a goal if
-		% any of the non-local variables for that goal are
-		% polymorphically typed and are constrained by the typeclass
-		% constraints for that typeclass-info variable
-		%
+		goal_util__extra_nonlocal_typeinfos(TypeVarMap,
+			VarTypes0, Goal0, NewOutsideVars),
 		Goal0 = _ - GoalInfo0,
 		goal_info_get_nonlocals(GoalInfo0, NonLocals),
-		set__to_sorted_list(NonLocals, NonLocalsList),
-		map__apply_to_list(NonLocalsList, VarTypes0, NonLocalsTypes),
-		term__vars_list(NonLocalsTypes, NonLocalTypeVars),
-			% Find all the type-infos and typeclass-infos that are
-			% non-local
-		solutions_set(lambda([Var::out] is nondet, (
-				list__member(TheVar, NonLocalTypeVars),
-				map__search(TypeVarMap, TheVar, Location),
-				type_info_locn_var(Location, Var)
-			)), NewOutsideVars),
 		set__union(NewOutsideVars, NonLocals, OutsideVars),
 		implicitly_quantify_goal(Goal0, VarSet0, VarTypes0,
 			OutsideVars, Goal, VarSet, VarTypes, _Warnings),
@@ -1009,14 +992,15 @@
 	).
 
 :- pred polymorphism__process_lambda(pred_or_func, list(var),
-		list(mode), determinism, list(var), hlds_goal, unification,
-		unify_rhs, unification, poly_info, poly_info).
-:- mode polymorphism__process_lambda(in, in, in, in, in, in, in, out, out,
+		list(mode), determinism, list(var), set(var),
+		hlds_goal, unification, unify_rhs, unification,
+		poly_info, poly_info).
+:- mode polymorphism__process_lambda(in, in, in, in, in, in, in, in, out, out,
 		in, out) is det.
 
 polymorphism__process_lambda(PredOrFunc, Vars, Modes, Det, OrigNonLocals,
-		LambdaGoal, Unification0, Functor, Unification,
-		PolyInfo0, PolyInfo) :-
+		NonLocalTypeInfos, LambdaGoal, Unification0, Functor,
+		Unification, PolyInfo0, PolyInfo) :-
 	PolyInfo0 = poly_info(VarSet, VarTypes, TVarSet, TVarMap, 
 			TCVarMap, Proofs, PredName, ModuleInfo0),
 
@@ -1030,9 +1014,9 @@
 		AllConstraints, Constraints),
 
 	lambda__transform_lambda(PredOrFunc, PredName, Vars, Modes, Det,
-		OrigNonLocals, LambdaGoal, Unification0, VarSet, VarTypes,
-		Constraints, TVarSet, TVarMap, TCVarMap, ModuleInfo0, Functor,
-		Unification, ModuleInfo),
+		OrigNonLocals, NonLocalTypeInfos, LambdaGoal, Unification0,
+		VarSet, VarTypes, Constraints, TVarSet, TVarMap, TCVarMap,
+		ModuleInfo0, Functor, Unification, ModuleInfo),
 	PolyInfo = poly_info(VarSet, VarTypes, TVarSet, TVarMap, 
 			TCVarMap, Proofs, PredName, ModuleInfo).
 
Index: compiler/pragma_c_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/pragma_c_gen.m,v
retrieving revision 1.14
diff -u -u -r1.14 pragma_c_gen.m
--- pragma_c_gen.m	1998/03/03 17:35:38	1.14
+++ pragma_c_gen.m	1998/03/28 04:23:48
@@ -532,16 +532,10 @@
 	code_info__maybe_save_ticket(UseTrail, SaveTicketCode, MaybeTicketSlot),
 	code_info__maybe_reset_ticket(MaybeTicketSlot, undo, RestoreTicketCode),
 
-	code_info__get_maybe_trace_info(MaybeTraceInfo),
-	( { MaybeTraceInfo = yes(TraceInfo) } ->
-		trace__generate_event_code(disj([disj(1)]), TraceInfo,
-			FirstTraceCode),
-		trace__generate_event_code(disj([disj(2)]), TraceInfo,
-			LaterTraceCode)
-	;
-		{ FirstTraceCode = empty },
-		{ LaterTraceCode = empty }
-	),
+	trace__maybe_generate_pragma_event_code(nondet_pragma_first,
+		FirstTraceCode),
+	trace__maybe_generate_pragma_event_code(nondet_pragma_later,
+		LaterTraceCode),
 
 	{ FirstDisjunctCode =
 		tree(SaveHeapCode,



More information about the developers mailing list