[m-rev.] for post-commit review: fix deep profiling (part 1 of 2)

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed May 19 15:32:52 AEST 2004


The following change is only 98% complete, not 100%. I am committing it in
this state because (1) we pass many more test cases in deep profiling grade
with it than without it, and (2) the double maintanance involved in fixing
CVS conflicts is preventing from doing the last 2%.

Get the deep profiler to work for code that sets up to catch exceptions,
which for the last year or more has included the compiler, and to get it
almost working for code that actually catching exceptions.

The basic problem is that code that throws exceptions will in general cause
several calls to "return" without executing the exit or fail port codes that
the deep profiling transformation inserted into their bodies, and this leaves
the data structure being built by the deep profiling inconsistent. The solution
uses the same approach as we have adopted for the debugger: have the code that
handles the throwing of exceptions simulate a return from each call between
the throw and the catch, updating the deep profiling data structures as needed.

This requires us to be able to walk the stack at runtime not just in debugging
grades but also in deep profiling grades. Since the debugger already has the
mechanisms required for this, we reuse them. The procedure layouts used by the
debugger were designed to have three segments: the procedure stack walk
information, the procedure id, and the execution tracing information. We now
modify this design to make the third segment contain two pointers: to the
execution tracing information (for use by the debugger), and to the procedure's
proc_static structure (for use by deep profiling). Each pointer will be null
unless the pointed-to structure is required by compile-time options.

This common use by the debugger and by deep profiling of the stack-walk
structure and the procedure id structure (which deep profiling used to
generate independently and possibly redundantly) required some rearrangement
of the compiler's version of these data structures.

To make this rearrangement simpler, this diff removes a capability that
we theoretically supported but never used: turning on stack traces without
turning on execution tracing and vice versa. After this diff, stack tracing
is enabled if and only if either execution tracing or deep profiling is
enabled.

The diff also includes improvements in the debugging infrastructure for
debugging deep profiling, which were necessary for the implementation of the
rest of the changes.

compiler/deep_profiling.m:
	The code in exception.m needs to know the locations of the variables
	that we would pass to the exit or fail port code, so it can simulate
	leaving the procedure invocation through the exception port. Without
	this information, throwing an exception leaves the deep profiling
	data structures of the procedure invocations between throw and catch
	in an inconsistent state.

	Deep_profiling.m creates these variables, but it doesn't know where
	they will be at runtime, so it records their identities; the code
	generator will allocate them stack slots and record the numbers of
	these stack slots for placement in the now expanded proc layout
	structures. Deep profiling used to generate static data structures
	separately from the HLDS, but since the code generator now needs
	access to them, we store their information in proc_infos in the HLDS.

	Instead of passing the addresses of proc_static structures to the deep
	profiling port procedures, pass the address of proc_layout structures,
	since the information about the identities of procedures are now stored
	not in the proc_static structure, but in the proc_layout structure
	that points to the proc_static structure.

compiler/hlds_pred.m:
compiler/layout.m:
	Move the definitions of the static data structures generated by deep
	profiling from layout.m to hlds_pred.m, to allow deep_profiling.m
	to store them in proc_infos.

compiler/hlds_pred.m:
compiler/rtti.m:
	Move the definition of rtti_proc_label from rtti.m to hlds_pred.m,
	since some of the new data structures in hlds_pred.m need it. Despite
	its name, the rtti_proc_label type doesn't contain any info that
	doesn't belong in the HLDS.

	Add some information to the rtti_proc_label type that is now needed
	by deep profiling, e.g. record determinisms instead of just code
	models. Record explicitly the outcome of some tests that used to be
	duplicated in more than one place in the compiler, e.g. for whether
	the procedure (as opposed to the predicate) is imported. Change some
	of the field names to be more precise about the field's meaning.

compiler/code_gen.m:
	Transmit the contents of the deep profiling data structures stored in
	the proc_info by deep_profiling.m to continuation_info.m, together
	with the layout structures created for execution tracing and the
	identities of the variables needed for handling exceptions,
	when code generation for a procedure is complete.

	After the goal that generates these variables, save them to stack
	for use by the exception handler.

compiler/hlds_goal.m:
	Add a feature to mark the goal that generates the deep profiling
	variables needed by the exception handler.

compiler/hlds_llds.m:
	Add a utility predicate for new code in code_gen.m

compiler/continuation_info.m:
	Hold the deep profiling information computed by code_gen.m for use by
	stack_layout.m.

compiler/layout.m:
compiler/layout_out.m:
	Update the definitions of the data structures describing procedure
	layouts, and the code writing them out, to reflect the use of some
	parts of procedure layouts by deep profiling as well as debugging.

	Change the layout structures generated by deep profiling to use
	rtti_proc_labels, which are backend independent, instead of
	proc_labels, which are specific to the LLDS backend.

	Conform to the changes in runtime/mercury_stack_layout.h.

compiler/stack_layout.m:
	Generate the updated version of proc_layout structures.

compiler/mercury_compile.m:
compiler/global_data.m:
	Conform to the fact that deep profiling no longer generates layout
	structures separate from proc_infos.

compiler/llds_out.m:
	Register proc_layout structures instead of proc_static structures
	for use by runtime/mercury_deep_profiling.c.

compiler/options.m:
compiler/handle_options.m:
	Rename the require_tracing option as exec_trace, since this more
	directly reflects its meaning.

	Instead of having --debug set both require_tracing and stack_trace,
	make it set (be the user-visible name of) just exec_trace;
	the value of stack_trace is implied.

	Turn off the specialization of deep profiling for self-tail-recursive
	procedures for now. Due to the changes made by this diff in the data
	structures involved in debugging, it cannot be debugged until this
	change has been installed. Handling the full language is more important
	than a specialization that reduces only stack space overheads, not
	runtime overheads.

compiler/compile_target_code.m:
	Conform to the changes in options.m and runtime/mercury_grade.h.

compiler/hlds_data.m:
	Replace the deep_profiling_proc_static cons_id, and its associated tag,
	to deep_profiling_proc_layout, since we now generate addresses of proc
	layout structures, not of proc_static structures.

compiler/code_util.m:
	Simplify some code based on the new info in rtti_proc_labels.

compiler/bytecode_gen.m:
compiler/dependency_graph.m:
compiler/higher_order.m:
compiler/hlds_out.m:
compiler/mercury_to_mercury.m:
compiler/ml_code_util.m:
compiler/ml_unify_gen.m:
compiler/opt_debug.m:
compiler/proc_label.m:
compiler/prog_rep.m:
compiler/rl_exprn.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
compiler/switch_util.m:
compiler/unify_gen.m:
	Minor changes to conform to the change from deep_profiling_proc_static
	to deep_profiling_proc_layout, to the change in the structure of
	rtti_proc_labels, to the changes in types of layout.m, and/or to the
	new goal feature.

deep_profiler/measurements.m:
	Reserve space for exception counts.

deep_profiler/html_format.m:
	Add a column for exception counts.

deep_profiler/profile.m:
deep_profiler/read_profile.m:
	Rename the data structures referring to compiler generated unify,
	compare and index predicates to avoid misleading names: they are
	not the only compiler generated predicates.

deep_profiler/read_profile.m:
runtime/mercury_deep_profiling.c:
	Update the string that identifies deep profiling data files.
	This is necessary because the format has changed: it now includes
	information about exception port counts.

library/exception.m:
	In deep profiling grades, execute the exception port code for every
	procedure invocation between a throw and a catch, using the procedure
	layout structures now generated by the compiler for every procedure.
	Rename the function involved to reflect its new, more general purpose.

	Update the definitions of the hand-written proc_static and proc_layout
	structures for the procedures implemented via hand-written C code.

	Indent C preprocessor directives and foreign_procs according to our
	coding standards.

library/profiling_builtin.m:
	Change the parameters of the call port code procedures from proc_static
	to proc_layout. Reach the proc_static structure from the proc_layout
	structure when needed. Include the proc_layout structure in any
	messages from assertion failures.

	Add some conditionally compiled debugging code.

	Give some variables better names.

runtime/mercury_type_info.h:
runtime/mercury_builtin_types.c:
	Move the macros required to create the proc_static structures
	of unify and compare predicates from mercury_type_info.h
	to mercury_builtin_types.c, since the latter is the only file
	that needs them.

	Use the same macros for creating the proc_static structures
	of hand-written unify, compare and compare_reprentation predicates
	as for user defined predicates. This required changing their naming
	scheme.

runtime/mercury_unify_compare_body.h:
	Conform to the new naming scheme.

runtime/mercury_ho_call.c:
	Provide the mechanism for mercury_unify_compare_body.h to conform
	to the new naming scheme.

	Remove the definitions of the proc_static structures for
	hand-written unify, compare and compare_reprentation predicates,
	since these now have to be defined together with the corresponding
	proc_layout structures in mercury_builtin_types.c.

runtime/mercury_builtin_types.[ch]:
	Update the definitions of the hand-written proc_static and proc_layout
	structures for the procedures implemented via hand-written C code,
	and add the required declarations first.

	Handle deep profiling of compare_representation as well as unify
	and compare predicates on builtin types.

	Handle deep profiling of compare_representation on user-defined types,
	since this is done entirely in the runtime, not by compiler generated
	predicates.

runtime/mercury_builtin_types_proc_layouts.h:
	New header file containing the declarations of the proc layout
	structures of the unify, compare and index predicates of builtin types.
	Logically, these declarations belong in mercury_builtin_types.h,
	but putting them there causes problems for the linker; the details
	are explained in the file itself.

runtime/Mmakefile:
	Add the new header file.

runtime/mercury_minimal_model.[ch]:
	Update the definitions of the hand-written proc_static and proc_layout
	structures for the procedures implemented via hand-written C code,
	and add the required declarations first.

runtime/mercury_grade.h:
	Replace the MR_REQUIRE_TRACING grade option with MR_EXEC_TRACING.
	Besides being better named, the MR_EXEC_TRACING option implies
	MR_STACK_TRACE.

	Besides the overall binary compatibility version number, add subsidiary
	version numbers for binary compatibility in deep profiling and
	debugging grades. These will make it easier to bootstrap changes
	(such as this) that affect binary compatibility only in such grades.

runtime/mercury_trace_base.c:
trace/mercury_trace.c:
	Conform to the new names of the configuration parameters.

runtime/mercury_hand_compare_body.h:
runtime/mercury_hand_unify_body.h:
runtime/mercury_hand_unify_compare_body.h:
runtime/mercury_ho_call.c:
tools/make_port_code:
	Pass proc_layout structures instead of proc_static structures
	to deep profiling port routines.

runtime/mercury_conf_param.h:
	Make MR_DEEP_PROFILING as well as MR_EXEC_TRACING imply MR_STACK_TRACE,
	since deep profiling now needs stack tracing. (MR_STACK_TRACE needs
	to be set in this file, because tests in this file depend on knowing
	its value, and this file is among the first files included (in this
	case indirectly) in mercury_imp.h.)

	Document the macros controlling the debugging of deep profiling.

	Enable printing of label names when the relevant deep profiling
	debugging macro is set.

runtime/mercury_debug.c:
runtime/mercury_deep_rec_depth_actions.h:
runtime/mercury_deep_rec_depth_body.h:
runtime/mercury_exception_catch_body.h:
	Get to proc_statics via proc_layouts.

runtime/mercury_deep_call_port_body.c:
runtime/mercury_deep_leave_port_body.c:
	Get to proc_statics via proc_layouts.

	Allow the debugger to disable deep profiling in Mercury code that is
	part of the debugger, not of the user program being executed.

	Add some more assertions.

runtime/mercury_engine.[ch]:
	Add a new debugging flag that controls at runtime whether we generate
	a human readable Deep.debug equivalent to the binary Deep.data files.
	(We already had a mechanism for controlling this at compile time,
	but this isn't flexible enough.)

runtime/mercury_wrapper.c:
	Allow this new debugging flag to be set from MERCURY_OPTIONS.

runtime/mercury_deep_profiling.[ch]:
	Respect this new debugging flag.

	Update the hand-written proc_static structures representing the runtime
	system.

	Print out addresses of proc_layout as well as proc_static structures
	when assertions fail.

	Add a field to the measurement structure for exception port counts,
	and write out this field with the other port counts.

	Remove procedure id information from proc_static structures,
	deep profiling now uses the procedure id in the proc_layout structure.

	Add to proc_static structures fields that specify where, if anywhere,
	the variables needed by exception.m to executed the exception port code
	are in the procedure's stack frame.

	Define a global flag that allows the debugger to disable deep
	profiling in Mercury code that is part of the debugger, not of the
	user program being executed.

	Increase type safety by providing two versions of the function
	for registering proc_layouts, one for the proc_layout structures
	of user-defined predicates and one for unify, compare and index
	predicates.

	Fix a bug that occurs only if MR_DEEP_PROFILING_EXPLICIT_CALL_COUNTS is
	defined (which it usually isn't): the initial call count was wrong.

runtime/mercury_deep_profiling_hand.h:
	Fix a bug: the handwritten code saving deep profiling variables was
	saving them in slots that didn't belong to the relevant stack frame.

	Update to conform to the modified definitions of proc_static structures
	and the fact that we now reach them via proc_layout structures.

runtime/mercury_exception_catch_body.h:
runtime/mercury_stacks.h:
	Fix the other side of the bug in mercury_deep_profiling_hand.h
	by reserving the right number of stack slots in the stack frames
	of the various modes of exception__catch. Make it harder to make
	the same bug in the future by getting the needed info from the
	place in mercury_stacks.h that defines the structure of the relevant
	stack frame.

runtime/mercury_proc_id.h:
	Rename the procedure id structure fields referring to compiler
	generated unify, compare and index predicates: they are not the only
	compiler-generated predicates.

runtime/mercury_stack_layout.h:
	Change procedure layout structures to allow them to be used for deep
	profiling as well as for debugging, as described in the prologue above.

	We don't need the capability to support label layout structures with
	links to misnamed proc layout structures, and supporting it is
	inconvenient, so delete the capability.

runtime/mercury_debug.c:
runtime/mercury_deep_profiling_hand.h:
runtime/mercury_layout_util.c:
runtime/mercury_ml_expand_body.h:
runtime/mercury_stack_trace.c:
runtime/mercury_types.h:
trace/mercury_trace_external.c:
	Conform to the new names of the procedure id structure fields.

runtime/mercury_std.h:
	Add some more arities for MR_PASTE for use in some of the modified
	modules in the runtime.

trace/mercury_trace_internal.c:
	Disable deep profiling actions in Mercury code that is part of the
	debugger, not of the program being debugged.

scripts/init_grade_options.sh-subr:
scripts/parse_grade_options.sh-subr:
	Make changes parallel to the ones in runtime/mercury_grade.h: delete
	--stack-trace as an independent option, and make --debug set its
	own option, not --require-tracing.

scripts/canonical_grade.sh-subr:
scripts/final_grade_options.sh-subr:
scripts/c2init.in:
scripts/mgnuc.in:
scripts/ml.in:
	Conform to the changes in grade options for debugging and for deep
	profiling.

tools/bootcheck:
	If Mmake.stage.{browser,deep,library,runtime,trace}.params exist,
	copy them to become the file Mmake.$dir.params in stage2/$dir
	(where dir is derived from the name of the original file in the obvious
	way). This allows more flexibility in the creation of the stage2;
	for example, it allows some directories (e.g. runtime or library)
	to be compiled with more debugging than other directories (e.g.
	compiler). This may be required because compiling all directories
	with lots of debugging may cause the linker to thrash.

	Add an option, --disable-debug-libs, that clobbers the libraries
	that should be linked in only in debugging grades.

	To conserve disk space, remove Deep.data files created by the bootcheck
	by default. Add an option, --keep-deep-data, to preserve these files.

	Use a consistent mechanism (test -f) for testing the existence of
	all files whose existence is tested.

	When recording modification times, record the modification times
	of some more files.

tests/hard_coded/Mmakefile:
	In deep profiling grades, disable the test cases that we don't now
	pass in such grades, and document the reasons for their failure.

	Fix the misclassification of the write_binary test case.

Zoltan.

cvs server: Diffing .
cvs server: Diffing analysis
cvs server: Diffing bindist
cvs server: Diffing boehm_gc
cvs server: Diffing boehm_gc/Mac_files
cvs server: Diffing boehm_gc/cord
cvs server: Diffing boehm_gc/cord/private
cvs server: Diffing boehm_gc/doc
cvs server: Diffing boehm_gc/include
cvs server: Diffing boehm_gc/include/private
cvs server: Diffing boehm_gc/tests
cvs server: Diffing browser
cvs server: Diffing bytecode
cvs server: Diffing compiler
Index: compiler/bytecode_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.80
diff -u -b -r1.80 bytecode_gen.m
--- compiler/bytecode_gen.m	23 Mar 2004 10:52:01 -0000	1.80
+++ compiler/bytecode_gen.m	19 May 2004 03:54:28 -0000
@@ -772,7 +772,7 @@
 		ConsId = table_io_decl(_),
 		sorry(this_file, "bytecode cannot implement table io decl")
 	;
-		ConsId = deep_profiling_proc_static(_),
+		ConsId = deep_profiling_proc_layout(_),
 		sorry(this_file, "bytecode cannot implement deep profiling")
 	).
 
@@ -788,32 +788,40 @@
 bytecode_gen__map_cons_tag(shared_local_tag(Primary, Secondary),
 	shared_local_tag(Primary, Secondary)).
 bytecode_gen__map_cons_tag(string_constant(_), _) :-
-	unexpected(this_file, "string_constant cons tag for non-string_constant cons id").
+	unexpected(this_file, "string_constant cons tag " ++
+		"for non-string_constant cons id").
 bytecode_gen__map_cons_tag(int_constant(IntVal), enum_tag(IntVal)).
 bytecode_gen__map_cons_tag(float_constant(_), _) :-
-	unexpected(this_file, "float_constant cons tag for non-float_constant cons id").
+	unexpected(this_file, "float_constant cons tag " ++
+		"for non-float_constant cons id").
 bytecode_gen__map_cons_tag(pred_closure_tag(_, _, _), _) :-
-	unexpected(this_file, "pred_closure_tag cons tag for non-pred_const cons id").
+	unexpected(this_file, "pred_closure_tag cons tag " ++
+		"for non-pred_const cons id").
 bytecode_gen__map_cons_tag(type_ctor_info_constant(_, _, _), _) :-
-	unexpected(this_file, "type_ctor_info_constant cons tag for non-type_ctor_info_constant cons id").
+	unexpected(this_file, "type_ctor_info_constant cons tag " ++
+		"for non-type_ctor_info_constant cons id").
 bytecode_gen__map_cons_tag(base_typeclass_info_constant(_, _, _), _) :-
-	unexpected(this_file, "base_typeclass_info_constant cons tag for non-base_typeclass_info_constant cons id").
+	unexpected(this_file, "base_typeclass_info_constant cons tag " ++
+		"for non-base_typeclass_info_constant cons id").
 bytecode_gen__map_cons_tag(tabling_pointer_constant(_, _), _) :-
-	unexpected(this_file, "tabling_pointer_constant cons tag for non-tabling_pointer_constant cons id").
-bytecode_gen__map_cons_tag(deep_profiling_proc_static_tag(_), _) :-
-	unexpected(this_file, "deep_profiling_proc_static_tag cons tag for non-deep_profiling_proc_static cons id").
+	unexpected(this_file, "tabling_pointer_constant cons tag " ++
+		"for non-tabling_pointer_constant cons id").
+bytecode_gen__map_cons_tag(deep_profiling_proc_layout_tag(_), _) :-
+	unexpected(this_file, "deep_profiling_proc_layout_tag cons tag " ++
+		"for non-deep_profiling_proc_static cons id").
 bytecode_gen__map_cons_tag(table_io_decl_tag(_), _) :-
-	unexpected(this_file, "table_io_decl_tag cons tag for non-table_io_decl cons id").
+	unexpected(this_file, "table_io_decl_tag cons tag " ++
+		"for non-table_io_decl cons id").
 bytecode_gen__map_cons_tag(reserved_address(_), _) :-
 	% These should only be generated if the --num-reserved-addresses
 	% or --num-reserved-objects options are used.
-	sorry(this_file,
-	   "bytecode with --num-reserved-addresses or --num-reserved-objects").
+	sorry(this_file, "bytecode with --num-reserved-addresses " ++
+		"or --num-reserved-objects").
 bytecode_gen__map_cons_tag(shared_with_reserved_addresses(_, _), _) :-
 	% These should only be generated if the --num-reserved-addresses
 	% or --num-reserved-objects options are used.
-	sorry(this_file,
-	   "bytecode with --num-reserved-addresses or --num-reserved-objects").
+	sorry(this_file, "bytecode with --num-reserved-addresses " ++
+		"or --num-reserved-objects").
 
 %---------------------------------------------------------------------------%
 
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.123
diff -u -b -r1.123 code_gen.m
--- compiler/code_gen.m	10 Apr 2004 10:33:00 -0000	1.123
+++ compiler/code_gen.m	19 May 2004 03:54:28 -0000
@@ -90,6 +90,7 @@
 :- import_module ll_backend__continuation_info.
 :- import_module ll_backend__disj_gen.
 :- import_module ll_backend__ite_gen.
+:- import_module ll_backend__layout.
 :- import_module ll_backend__llds_out.
 :- import_module ll_backend__middle_rec.
 :- import_module ll_backend__par_conj_gen.
@@ -356,12 +357,23 @@
 		IsBeingTraced = bool__not(EffTraceIsNone),
 		NeedsAllNames = eff_trace_needs_all_var_names(PredInfo,
 			ProcInfo, TraceLevel, TraceSuppress),
+		proc_info_get_maybe_deep_profile_info(ProcInfo,
+			MaybeHLDSDeepInfo),
+		(
+			MaybeHLDSDeepInfo = yes(HLDSDeepInfo),
+			DeepProfInfo = generate_deep_prof_info(ProcInfo,
+				HLDSDeepInfo),
+			MaybeDeepProfInfo = yes(DeepProfInfo)
+		;
+			MaybeHLDSDeepInfo = no,
+			MaybeDeepProfInfo = no
+		),
 		ProcLayout = proc_layout_info(RttiProcLabel, EntryLabel,
 			Detism, TotalSlots, MaybeSuccipSlot, EvalMethod,
 			MaybeTraceCallLabel, MaxTraceReg, HeadVars, MaybeGoal,
 			InstMap0, TraceSlotInfo, ForceProcId, VarSet, VarTypes,
 			InternalMap, MaybeTableInfo, IsBeingTraced,
-			NeedsAllNames),
+			NeedsAllNames, MaybeDeepProfInfo),
 		global_data_add_new_proc_layout(proc(PredId, ProcId),
 			ProcLayout, !GlobalData)
 	;
@@ -413,6 +425,44 @@
 			MayAlterRtti)
 	).
 
+:- func generate_deep_prof_info(proc_info, deep_profile_proc_info)
+	= proc_layout_proc_static.
+
+generate_deep_prof_info(ProcInfo, HLDSDeepInfo) = DeepProfInfo :-
+	HLDSDeepInfo ^ deep_layout = MaybeHLDSDeepLayout,
+	(
+		MaybeHLDSDeepLayout = yes(HLDSDeepLayout)
+	;
+		MaybeHLDSDeepLayout = no,
+		error("generate_deep_prof_info: " ++
+			"no HLDS deep profiling layout info")
+	),
+	HLDSDeepLayout = hlds_deep_layout(HLDSProcStatic, HLDSExcpVars),
+	HLDSExcpVars = hlds_deep_excp_vars(TopCSDVar, MiddleCSDVar,
+		MaybeOldOutermostVar),
+	proc_info_stack_slots(ProcInfo, StackSlots),
+	( map__search(StackSlots, TopCSDVar, TopCSDSlot) ->
+		TopCSDSlotNum = stack_slot_num(TopCSDSlot),
+		map__lookup(StackSlots, MiddleCSDVar, MiddleCSDSlot),
+		MiddleCSDSlotNum = stack_slot_num(MiddleCSDSlot),
+		(
+			MaybeOldOutermostVar = yes(OldOutermostVar),
+			map__lookup(StackSlots, OldOutermostVar,
+				OldOutermostSlot),
+			OldOutermostSlotNum = stack_slot_num(OldOutermostSlot)
+		;
+			MaybeOldOutermostVar = no,
+			OldOutermostSlotNum = -1
+		)
+	;
+		TopCSDSlotNum = -1,
+		MiddleCSDSlotNum = -1,
+		OldOutermostSlotNum = -1
+	),
+	DeepExcpSlots = deep_excp_slots(TopCSDSlotNum, MiddleCSDSlotNum,
+		OldOutermostSlotNum),
+	DeepProfInfo = proc_layout_proc_static(HLDSProcStatic, DeepExcpSlots).
+
 :- pred maybe_add_tabling_pointer_var(module_info::in,
 	pred_id::in, proc_id::in, proc_info::in, proc_label::in,
 	global_data::in, global_data::out) is det.
@@ -1084,6 +1134,8 @@
 
 		code_gen__generate_goal_2(Goal, GoalInfo, CodeModel, GoalCode,
 			!CI),
+		goal_info_get_features(GoalInfo, Features),
+		code_info__get_proc_info(!.CI, ProcInfo),
 
 			% If the predicate's evaluation method is memo,
 			% loopcheck or minimal model, the goal generated
@@ -1097,7 +1149,6 @@
 			% If tracing is not enabled, then CallTableVar isn't
 			% guaranteed to have a stack slot.
 		(
-			goal_info_get_features(GoalInfo, Features),
 			set__member(call_table_gen, Features),
 			code_info__get_proc_info(!.CI, ProcInfo),
 			proc_info_get_call_table_tip(ProcInfo,
@@ -1106,10 +1157,39 @@
 			code_info__get_maybe_trace_info(!.CI, yes(_))
 		->
 			code_info__save_variables_on_stack([CallTableVar],
-				SaveCode, !CI),
-			Code = tree(GoalCode, SaveCode)
+				TipSaveCode, !CI),
+			CodeUptoTip = tree(GoalCode, TipSaveCode)
 		;
-			Code = GoalCode
+			CodeUptoTip = GoalCode
+		),
+			% After the goal that generates the variables needed
+			% at the exception port, on which deep_profiling.m puts
+			% the save_deep_excp_vars feature, save those variables
+			% in their stack slots. The procedure layout structure
+			% gives the identity of their slots, and exception.m
+			% expects to find the variables in their stack slots.
+			%
+			% These variables are computed by the call port code
+			% and are needed by the exit and fail port codes, so
+			% their lifetime is the entire procedure invocation.
+			% If the procedure makes any calls other than the ones
+			% inserted by deep profiling, then all the variables
+			% will have stack slots, and we save them all on the
+			% stack. If the procedure doesn't make any such calls,
+			% then the variables won't have stack slots, but they
+			% won't *need* stack slots either, since there is no
+			% way for such a leaf procedure to throw an exception.
+			% (Throwing requires calling exception__throw, directly
+			% or indirectly.)
+		(
+			set__member(save_deep_excp_vars, Features)
+		->
+			DeepSaveVars = compute_deep_save_excp_vars(ProcInfo),
+			code_info__save_variables_on_stack(DeepSaveVars,
+				DeepSaveCode, !CI),
+			Code = tree(CodeUptoTip, DeepSaveCode)
+		;
+			Code = CodeUptoTip
 		),
 
 			% Make live any variables which subsequent goals
@@ -1118,6 +1198,37 @@
 		code_info__post_goal_update(GoalInfo, !CI)
 	;
 		Code = empty
+	).
+
+:- func compute_deep_save_excp_vars(proc_info) = list(prog_var).
+
+compute_deep_save_excp_vars(ProcInfo) = DeepSaveVars :-
+	proc_info_get_maybe_deep_profile_info(ProcInfo, MaybeDeepProfInfo),
+	(
+		MaybeDeepProfInfo = yes(DeepProfInfo),
+		MaybeDeepLayout = DeepProfInfo ^ deep_layout,
+		MaybeDeepLayout = yes(DeepLayout)
+	->
+		ExcpVars = DeepLayout ^ deep_layout_excp,
+		ExcpVars = hlds_deep_excp_vars(TopCSDVar, MiddleCSDVar,
+			MaybeOldOutermostVar),
+		proc_info_stack_slots(ProcInfo, StackSlots),
+		( map__search(StackSlots, TopCSDVar, _) ->
+			% If one of these variables has a stack
+			% slot, the others must have one too.
+			(
+				MaybeOldOutermostVar = yes(OldOutermostVar),
+				DeepSaveVars = [TopCSDVar, MiddleCSDVar,
+					OldOutermostVar]
+			;
+				MaybeOldOutermostVar = no,
+				DeepSaveVars = [TopCSDVar, MiddleCSDVar]
+			)
+		;
+			DeepSaveVars = []
+		)
+	;
+		error("compute_deep_save_excp_vars: inconsistent proc_info")
 	).
 
 %---------------------------------------------------------------------------%
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.149
diff -u -b -r1.149 code_util.m
--- compiler/code_util.m	10 Apr 2004 10:33:00 -0000	1.149
+++ compiler/code_util.m	19 May 2004 03:54:28 -0000
@@ -18,7 +18,6 @@
 :- interface.
 
 :- import_module backend_libs__proc_label.
-:- import_module backend_libs__rtti.
 :- import_module hlds__hlds_goal.
 :- import_module hlds__hlds_llds.
 :- import_module hlds__hlds_module.
@@ -101,6 +100,7 @@
 :- implementation.
 
 :- import_module backend_libs__builtin_ops.
+:- import_module backend_libs__rtti.
 :- import_module hlds__code_model.
 :- import_module hlds__special_pred.
 :- import_module libs__globals.
@@ -116,16 +116,7 @@
 	code_util__make_entry_label_from_rtti(RttiProcLabel, Immed, ProcAddr).
 
 code_util__make_entry_label_from_rtti(RttiProcLabel, Immed, ProcAddr) :-
-	(
-		(
-			RttiProcLabel ^ is_imported = yes
-		;
-			RttiProcLabel ^ is_pseudo_imported = yes,
-			% only the (in, in) mode of unification is imported
-			hlds_pred__in_in_unification_proc_id(
-				RttiProcLabel^proc_id)
-		)
-	->
+	( RttiProcLabel ^ proc_is_imported = yes ->
 		ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
 		ProcAddr = imported(ProcLabel)
 	;
@@ -149,7 +140,7 @@
 		% If we want to define the label or use it to put it
 		% into a data structure, a label that is usable only
 		% within the current C module won't do.
-		( RttiProcLabel ^ is_exported = yes ->
+		( RttiProcLabel ^ proc_is_exported = yes ->
 			Label = exported(ProcLabel)
 		;
 			Label = local(ProcLabel)
Index: compiler/compile_target_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/compile_target_code.m,v
retrieving revision 1.58
diff -u -b -r1.58 compile_target_code.m
--- compiler/compile_target_code.m	1 Apr 2004 04:48:23 -0000	1.58
+++ compiler/compile_target_code.m	19 May 2004 03:54:28 -0000
@@ -546,17 +546,11 @@
 	;
 		DeclDebugOpt = ""
 	),
-	globals__io_lookup_bool_option(require_tracing, RequireTracing, !IO),
-	( RequireTracing = yes ->
-		RequireTracingOpt = "-DMR_REQUIRE_TRACING "
+	globals__io_lookup_bool_option(exec_trace, ExecTrace, !IO),
+	( ExecTrace = yes ->
+		ExecTraceOpt = "-DMR_EXEC_TRACE "
 	;
-		RequireTracingOpt = ""
-	),
-	globals__io_lookup_bool_option(stack_trace, StackTrace, !IO),
-	( StackTrace = yes ->
-		StackTraceOpt = "-DMR_STACK_TRACE "
-	;
-		StackTraceOpt = ""
+		ExecTraceOpt = ""
 	),
 	globals__io_lookup_bool_option(target_debug, Target_Debug, !IO),
 	( Target_Debug = yes ->
@@ -636,7 +630,7 @@
 		GC_Opt, ProfileCallsOpt, ProfileTimeOpt, ProfileMemoryOpt,
 		ProfileDeepOpt, RecordTermSizesOpt, PIC_Reg_Opt, TagsOpt,
 		NumTagBitsOpt, Target_DebugOpt, LL_DebugOpt,
-		DeclDebugOpt, RequireTracingOpt, StackTraceOpt,
+		DeclDebugOpt, ExecTraceOpt,
 		UseTrailOpt, ReserveTagOpt, MinimalModelOpt, TypeLayoutOpt,
 		InlineAllocOpt, " ", AnsiOpt, " ", WarningOpt, " ", CFLAGS,
 		" -c ", C_File, " ", NameObjectFile, O_File], Command),
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.51
diff -u -b -r1.51 continuation_info.m
--- compiler/continuation_info.m	10 Apr 2004 10:33:00 -0000	1.51
+++ compiler/continuation_info.m	19 May 2004 03:54:28 -0000
@@ -10,8 +10,8 @@
 %
 % This file defines the data structures the code generator uses to collect
 % information that will later be converted into layout tables for accurate
-% garbage collection, for stack tracing, execution tracing and perhaps
-% other purposes.
+% garbage collection, stack tracing, execution tracing, deep profiling and
+% perhaps other purposes.
 %
 % Information is collected in several passes.
 %
@@ -51,7 +51,6 @@
 
 :- interface.
 
-:- import_module backend_libs__rtti.
 :- import_module hlds__hlds_goal.
 :- import_module hlds__hlds_module.
 :- import_module hlds__hlds_pred.
@@ -59,6 +58,7 @@
 :- import_module libs__globals.
 :- import_module libs__trace_params.
 :- import_module ll_backend__global_data.
+:- import_module ll_backend__layout.
 :- import_module ll_backend__llds.
 :- import_module ll_backend__trace.
 :- import_module parse_tree__inst.
@@ -129,9 +129,10 @@
 			is_being_traced :: bool,
 					% True if the effective trace level
 					% of the procedure is not none.
-			need_all_names	:: bool
+			need_all_names	:: bool,
 					% True iff we need the names of all the
 					% variables.
+			deep_prof	:: maybe(proc_layout_proc_static)
 		).
 
 	%
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.23
diff -u -b -r1.23 deep_profiling.m
--- compiler/deep_profiling.m	23 Mar 2004 10:52:02 -0000	1.23
+++ compiler/deep_profiling.m	19 May 2004 03:54:28 -0000
@@ -17,12 +17,9 @@
 :- interface.
 
 :- import_module hlds__hlds_module.
-:- import_module ll_backend__layout.
 
-:- import_module io, list.
-
-:- pred apply_deep_profiling_transformation(module_info::in, module_info::out,
-	list(layout_data)::out, io__state::di, io__state::uo) is det.
+:- pred apply_deep_profiling_transformation(module_info::in, module_info::out)
+	is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -50,7 +47,7 @@
 :- import_module bool, int, list, assoc_list, map, require, set.
 :- import_module std_util, string, term, varset, counter.
 
-apply_deep_profiling_transformation(!ModuleInfo, ProcStatics, !IO) :-
+apply_deep_profiling_transformation(!ModuleInfo) :-
 	module_info_globals(!.ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, deep_profile_tail_recursion,
 		TailRecursion),
@@ -63,14 +60,8 @@
 	module_info_predids(!.ModuleInfo, PredIds),
 	module_info_get_predicate_table(!.ModuleInfo, PredTable0),
 	predicate_table_get_preds(PredTable0, PredMap0),
-	list__foldl2(transform_predicate(!.ModuleInfo),
-		PredIds, PredMap0, PredMap, [], MaybeProcStatics),
-		% Remove any duplicates that resulted from
-		% references in inner tail recursive procedures
-	list__filter_map(
-		(pred(MaybeProcStatic::in, ProcStatic::out) is semidet :-
-			MaybeProcStatic = yes(ProcStatic)
-	), MaybeProcStatics, ProcStatics),
+	list__foldl(transform_predicate(!.ModuleInfo), PredIds,
+		PredMap0, PredMap),
 	predicate_table_set_preds(PredMap, PredTable0, PredTable),
 	module_info_set_predicate_table(PredTable, !ModuleInfo).
 
@@ -123,14 +114,18 @@
 	->
 		proc_info_set_goal(Goal, ProcInfo0, ProcInfo1),
 		figure_out_rec_call_numbers(Goal, 0, _N, [], TailCallSites),
-		OrigDeepProfileInfo = deep_profile_proc_info(
+		OrigDeepRecInfo = yes(deep_recursion_info(
 			outer_proc(ClonePredProcId),
 			[visible_scc_data(PredProcId, ClonePredProcId,
-				TailCallSites)]),
-		CloneDeepProfileInfo = deep_profile_proc_info(
+				TailCallSites)])),
+		OrigDeepProfileInfo = deep_profile_proc_info(
+			OrigDeepRecInfo, no),
+		CloneDeepRecInfo = yes(deep_recursion_info(
 			inner_proc(PredProcId),
 			[visible_scc_data(PredProcId, ClonePredProcId,
-				TailCallSites)]),
+				TailCallSites)])),
+		CloneDeepProfileInfo = deep_profile_proc_info(
+			CloneDeepRecInfo, no),
 		proc_info_set_maybe_deep_profile_info(
 			yes(OrigDeepProfileInfo), ProcInfo1, ProcInfo),
 		proc_info_set_maybe_deep_profile_info(
@@ -456,25 +451,21 @@
 %-----------------------------------------------------------------------------%
 
 :- pred transform_predicate(module_info::in, pred_id::in,
-	pred_table::in, pred_table::out,
-	list(maybe(layout_data))::in, list(maybe(layout_data))::out) is det.
+	pred_table::in, pred_table::out) is det.
 
-transform_predicate(ModuleInfo, PredId, PredMap0, PredMap,
-		ProcStatics0, ProcStatics) :-
+transform_predicate(ModuleInfo, PredId, PredMap0, PredMap) :-
 	map__lookup(PredMap0, PredId, PredInfo0),
 	ProcIds = pred_info_non_imported_procids(PredInfo0),
 	pred_info_procedures(PredInfo0, ProcTable0),
-	list__foldl2(maybe_transform_procedure(ModuleInfo, PredId),
-		ProcIds, ProcTable0, ProcTable, ProcStatics0, ProcStatics),
+	list__foldl(maybe_transform_procedure(ModuleInfo, PredId),
+		ProcIds, ProcTable0, ProcTable),
 	pred_info_set_procedures(ProcTable, PredInfo0, PredInfo),
 	map__det_update(PredMap0, PredId, PredInfo, PredMap).
 
 :- pred maybe_transform_procedure(module_info::in, pred_id::in, proc_id::in,
-	proc_table::in, proc_table::out,
-	list(maybe(layout_data))::in, list(maybe(layout_data))::out) is det.
+	proc_table::in, proc_table::out) is det.
 
-maybe_transform_procedure(ModuleInfo, PredId, ProcId, ProcTable0, ProcTable,
-		ProcStatics0, ProcStatics) :-
+maybe_transform_procedure(ModuleInfo, PredId, ProcId, ProcTable0, ProcTable) :-
 	map__lookup(ProcTable0, ProcId, ProcInfo0),
 	proc_info_goal(ProcInfo0, Goal0),
 	predicate_module(ModuleInfo, PredId, PredModuleName),
@@ -490,52 +481,51 @@
 		% infinite recursion.
 		mercury_profiling_builtin_module(PredModuleName)
 	->
-		ProcTable = ProcTable0,
-		ProcStatics = ProcStatics0
+		ProcTable = ProcTable0
 	;
 		transform_procedure2(ModuleInfo, proc(PredId, ProcId),
-			ProcInfo0, ProcInfo, ProcStatics0, ProcStatics),
+			ProcInfo0, ProcInfo),
 		map__det_update(ProcTable0, ProcId, ProcInfo, ProcTable)
 	).
 
 :- pred transform_procedure2(module_info::in, pred_proc_id::in,
-	proc_info::in, proc_info::out,
-	list(maybe(layout_data))::in, list(maybe(layout_data))::out) is det.
+	proc_info::in, proc_info::out) is det.
 
-transform_procedure2(ModuleInfo, PredProcId, Proc0, Proc,
-		ProcStaticList0, ProcStaticList) :-
-	proc_info_get_maybe_deep_profile_info(Proc0, MaybeRecInfo),
+transform_procedure2(ModuleInfo, PredProcId, Proc0, Proc) :-
+	proc_info_get_maybe_deep_profile_info(Proc0, MaybeDeepInfo),
 	proc_info_interface_code_model(Proc0, CodeModel),
 	(
 		CodeModel = model_det,
 		(
-			MaybeRecInfo = yes(RecInfo),
+			MaybeDeepInfo = yes(DeepInfo),
+			DeepInfo = deep_profile_proc_info(MaybeDeepRecInfo, _),
+			MaybeDeepRecInfo = yes(RecInfo),
 			RecInfo ^ role = inner_proc(_)
 		->
 			transform_inner_proc(ModuleInfo, PredProcId, Proc0,
-				Proc, MaybeProcStatic)
+				Proc)
 		;
 			transform_det_proc(ModuleInfo, PredProcId, Proc0,
-				Proc, MaybeProcStatic)
+				Proc)
 		)
 	;
 		CodeModel = model_semi,
 		(
-			MaybeRecInfo = yes(RecInfo),
+			MaybeDeepInfo = yes(DeepInfo),
+			DeepInfo = deep_profile_proc_info(MaybeDeepRecInfo, _),
+			MaybeDeepRecInfo = yes(RecInfo),
 			RecInfo ^ role = inner_proc(_)
 		->
 			transform_inner_proc(ModuleInfo, PredProcId, Proc0,
-				Proc, MaybeProcStatic)
+				Proc)
 		;
 			transform_semi_proc(ModuleInfo, PredProcId, Proc0,
-				Proc, MaybeProcStatic)
+				Proc)
 		)
 	;
 		CodeModel = model_non,
-		transform_non_proc(ModuleInfo, PredProcId, Proc0,
-			Proc, MaybeProcStatic)
-	),
-	ProcStaticList = [MaybeProcStatic | ProcStaticList0].
+		transform_non_proc(ModuleInfo, PredProcId, Proc0, Proc)
+	).
 
 %-----------------------------------------------------------------------------%
 
@@ -549,13 +539,13 @@
 		vars			:: prog_varset,
 		var_types		:: vartypes,
 		proc_filename		:: string,
-		maybe_rec_info		:: maybe(deep_profile_proc_info)
+		maybe_rec_info		:: maybe(deep_recursion_info)
 	).
 
 :- pred transform_det_proc(module_info::in, pred_proc_id::in,
-	proc_info::in, proc_info::out, maybe(layout_data)::out) is det.
+	proc_info::in, proc_info::out) is det.
 
-transform_det_proc(ModuleInfo, PredProcId, !Proc, yes(ProcStatic)) :-
+transform_det_proc(ModuleInfo, PredProcId, !Proc) :-
 	proc_info_goal(!.Proc, Goal0),
 	Goal0 = _ - GoalInfo0,
 	proc_info_varset(!.Proc, Vars0),
@@ -565,7 +555,7 @@
 	map__set(VarTypes0, TopCSD, CPointerType, VarTypes1),
 	varset__new_named_var(Vars1, "MiddleCSD", MiddleCSD, Vars2),
 	map__set(VarTypes1, MiddleCSD, CPointerType, VarTypes2),
-	varset__new_named_var(Vars2, "ProcStatic", ProcStaticVar, Vars3),
+	varset__new_named_var(Vars2, "ProcStaticLayout", ProcStaticVar, Vars3),
 	map__set(VarTypes2, ProcStaticVar, CPointerType, VarTypes3),
 	module_info_globals(ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, use_activation_counts,
@@ -582,11 +572,13 @@
 		VarTypes5 = VarTypes3,
 		MaybeActivationPtr = no
 	),
+	ExcpVars = hlds_deep_excp_vars(TopCSD, MiddleCSD, MaybeActivationPtr),
 	proc_info_context(!.Proc, Context),
 	FileName = term__context_file(Context),
 	LineNumber = term__context_line(Context),
 
-	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeRecInfo),
+	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeDeepProfInfo),
+	extract_deep_rec_info(MaybeDeepProfInfo, MaybeRecInfo),
 	DeepInfo0 = deep_info(ModuleInfo, PredProcId, MiddleCSD,
 		counter__init(0), [], Vars5, VarTypes5,
 		FileName, MaybeRecInfo),
@@ -608,23 +600,27 @@
 
 	RttiProcLabel = rtti__make_rtti_proc_label(ModuleInfo, PredId, ProcId),
 	IsInInterface = is_proc_in_interface(ModuleInfo, PredId, ProcId),
-	ProcStatic = proc_static_data(RttiProcLabel, FileName, LineNumber,
-		IsInInterface, CallSites),
-	ProcStaticConsId = deep_profiling_proc_static(RttiProcLabel),
+	ProcStatic = hlds_proc_static(FileName, LineNumber, IsInInterface,
+		CallSites),
+	ProcStaticConsId = deep_profiling_proc_layout(RttiProcLabel),
 	generate_unify(ProcStaticConsId, ProcStaticVar, BindProcStaticVarGoal),
 
 	(
 		MaybeActivationPtr = yes(ActivationPtr1),
 		generate_call(ModuleInfo, "det_call_port_code_sr", 4,
 			[ProcStaticVar, TopCSD, MiddleCSD, ActivationPtr1],
-			[TopCSD, MiddleCSD, ActivationPtr1], CallPortCode),
+			[TopCSD, MiddleCSD, ActivationPtr1], CallPortCode0),
+		goal_add_feature(CallPortCode0, save_deep_excp_vars,
+			CallPortCode),
 		generate_call(ModuleInfo, "det_exit_port_code_sr", 3,
 			[TopCSD, MiddleCSD, ActivationPtr1], [], ExitPortCode)
 	;
 		MaybeActivationPtr = no,
 		generate_call(ModuleInfo, "det_call_port_code_ac", 3,
 			[ProcStaticVar, TopCSD, MiddleCSD],
-			[TopCSD, MiddleCSD], CallPortCode),
+			[TopCSD, MiddleCSD], CallPortCode0),
+		goal_add_feature(CallPortCode0, save_deep_excp_vars,
+			CallPortCode),
 		generate_call(ModuleInfo, "det_exit_port_code_ac", 2,
 			[TopCSD, MiddleCSD], [], ExitPortCode)
 	),
@@ -638,12 +634,13 @@
 	]) - GoalInfo,
 	proc_info_set_varset(Vars, !Proc),
 	proc_info_set_vartypes(VarTypes, !Proc),
-	proc_info_set_goal(Goal, !Proc).
+	proc_info_set_goal(Goal, !Proc),
+	record_hlds_proc_static(ProcStatic, ExcpVars, !Proc).
 
 :- pred transform_semi_proc(module_info::in, pred_proc_id::in,
-	proc_info::in, proc_info::out, maybe(layout_data)::out) is det.
+	proc_info::in, proc_info::out) is det.
 
-transform_semi_proc(ModuleInfo, PredProcId, !Proc, yes(ProcStatic)) :-
+transform_semi_proc(ModuleInfo, PredProcId, !Proc) :-
 	proc_info_goal(!.Proc, Goal0),
 	Goal0 = _ - GoalInfo0,
 	proc_info_varset(!.Proc, Vars0),
@@ -653,7 +650,7 @@
 	map__set(VarTypes0, TopCSD, CPointerType, VarTypes1),
 	varset__new_named_var(Vars1, "MiddleCSD", MiddleCSD, Vars2),
 	map__set(VarTypes1, MiddleCSD, CPointerType, VarTypes2),
-	varset__new_named_var(Vars2, "ProcStatic", ProcStaticVar, Vars3),
+	varset__new_named_var(Vars2, "ProcStaticLayout", ProcStaticVar, Vars3),
 	map__set(VarTypes2, ProcStaticVar, CPointerType, VarTypes3),
 	module_info_globals(ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, use_activation_counts,
@@ -670,11 +667,13 @@
 		VarTypes5 = VarTypes3,
 		MaybeActivationPtr = no
 	),
+	ExcpVars = hlds_deep_excp_vars(TopCSD, MiddleCSD, MaybeActivationPtr),
 	proc_info_context(!.Proc, Context),
 	FileName = term__context_file(Context),
 	LineNumber = term__context_line(Context),
 
-	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeRecInfo),
+	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeDeepProfInfo),
+	extract_deep_rec_info(MaybeDeepProfInfo, MaybeRecInfo),
 	DeepInfo0 = deep_info(ModuleInfo, PredProcId, MiddleCSD,
 		counter__init(0), [], Vars5, VarTypes5,
 		FileName, MaybeRecInfo),
@@ -696,16 +695,18 @@
 
 	RttiProcLabel = rtti__make_rtti_proc_label(ModuleInfo, PredId, ProcId),
 	IsInInterface = is_proc_in_interface(ModuleInfo, PredId, ProcId),
-	ProcStatic = proc_static_data(RttiProcLabel, FileName, LineNumber,
+	ProcStatic = hlds_proc_static(FileName, LineNumber,
 		IsInInterface, CallSites),
-	ProcStaticConsId = deep_profiling_proc_static(RttiProcLabel),
+	ProcStaticConsId = deep_profiling_proc_layout(RttiProcLabel),
 	generate_unify(ProcStaticConsId, ProcStaticVar, BindProcStaticVarGoal),
 
 	(
 		MaybeActivationPtr = yes(ActivationPtr1),
 		generate_call(ModuleInfo, "semi_call_port_code_sr", 4,
 			[ProcStaticVar, TopCSD, MiddleCSD, ActivationPtr1],
-			[TopCSD, MiddleCSD, ActivationPtr1], CallPortCode),
+			[TopCSD, MiddleCSD, ActivationPtr1], CallPortCode0),
+		goal_add_feature(CallPortCode0, save_deep_excp_vars,
+			CallPortCode),
 		generate_call(ModuleInfo, "semi_exit_port_code_sr", 3,
 			[TopCSD, MiddleCSD, ActivationPtr1], [], ExitPortCode),
 		generate_call(ModuleInfo, "semi_fail_port_code_sr", 3,
@@ -716,7 +717,9 @@
 		MaybeActivationPtr = no,
 		generate_call(ModuleInfo, "semi_call_port_code_ac", 3,
 			[ProcStaticVar, TopCSD, MiddleCSD],
-			[TopCSD, MiddleCSD], CallPortCode),
+			[TopCSD, MiddleCSD], CallPortCode0),
+		goal_add_feature(CallPortCode0, save_deep_excp_vars,
+			CallPortCode),
 		generate_call(ModuleInfo, "semi_exit_port_code_ac", 2,
 			[TopCSD, MiddleCSD], [], ExitPortCode),
 		generate_call(ModuleInfo, "semi_fail_port_code_ac", 2,
@@ -741,12 +744,13 @@
 	]) - GoalInfo,
 	proc_info_set_varset(Vars, !Proc),
 	proc_info_set_vartypes(VarTypes, !Proc),
-	proc_info_set_goal(Goal, !Proc).
+	proc_info_set_goal(Goal, !Proc),
+	record_hlds_proc_static(ProcStatic, ExcpVars, !Proc).
 
 :- pred transform_non_proc(module_info::in, pred_proc_id::in,
-	proc_info::in, proc_info::out, maybe(layout_data)::out) is det.
+	proc_info::in, proc_info::out) is det.
 
-transform_non_proc(ModuleInfo, PredProcId, !Proc, yes(ProcStatic)) :-
+transform_non_proc(ModuleInfo, PredProcId, !Proc) :-
 	proc_info_goal(!.Proc, Goal0),
 	Goal0 = _ - GoalInfo0,
 	proc_info_varset(!.Proc, Vars0),
@@ -756,7 +760,7 @@
 	map__set(VarTypes0, TopCSD, CPointerType, VarTypes1),
 	varset__new_named_var(Vars1, "MiddleCSD", MiddleCSD, Vars2),
 	map__set(VarTypes1, MiddleCSD, CPointerType, VarTypes2),
-	varset__new_named_var(Vars2, "ProcStatic", ProcStaticVar, Vars3),
+	varset__new_named_var(Vars2, "ProcStaticLayout", ProcStaticVar, Vars3),
 	map__set(VarTypes2, ProcStaticVar, CPointerType, VarTypes3),
 	module_info_globals(ModuleInfo, Globals),
 	globals__lookup_bool_option(Globals, use_activation_counts,
@@ -767,24 +771,24 @@
 			OldOutermostProcDyn0, Vars4),
 		map__set(VarTypes3, OldOutermostProcDyn0, CPointerType,
 			VarTypes4),
-		varset__new_named_var(Vars4, "NewOutermost",
-			NewOutermostProcDyn, Vars5),
-		map__set(VarTypes4, NewOutermostProcDyn, CPointerType,
-			VarTypes5),
 		MaybeOldActivationPtr = yes(OldOutermostProcDyn0)
 	;
 		UseActivationCounts = yes,
-		varset__new_named_var(Vars3, "NewOutermost",
-			NewOutermostProcDyn, Vars5),
-		map__set(VarTypes3, NewOutermostProcDyn, CPointerType,
-			VarTypes5),
+		Vars4 = Vars3,
+		VarTypes4 = VarTypes3,
 		MaybeOldActivationPtr = no
 	),
+	ExcpVars = hlds_deep_excp_vars(TopCSD, MiddleCSD,
+		MaybeOldActivationPtr),
+	varset__new_named_var(Vars4, "NewOutermost", NewOutermostProcDyn,
+		Vars5),
+	map__set(VarTypes4, NewOutermostProcDyn, CPointerType, VarTypes5),
 	proc_info_context(!.Proc, Context),
 	FileName = term__context_file(Context),
 	LineNumber = term__context_line(Context),
 
-	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeRecInfo),
+	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeDeepProfInfo),
+	extract_deep_rec_info(MaybeDeepProfInfo, MaybeRecInfo),
 	DeepInfo0 = deep_info(ModuleInfo, PredProcId, MiddleCSD,
 		counter__init(0), [], Vars5, VarTypes5,
 		FileName, MaybeRecInfo),
@@ -798,9 +802,9 @@
 	PredProcId = proc(PredId, ProcId),
 	RttiProcLabel = rtti__make_rtti_proc_label(ModuleInfo, PredId, ProcId),
 	IsInInterface = is_proc_in_interface(ModuleInfo, PredId, ProcId),
-	ProcStatic = proc_static_data(RttiProcLabel, FileName, LineNumber,
+	ProcStatic = hlds_proc_static(FileName, LineNumber,
 		IsInInterface, CallSites),
-	ProcStaticConsId = deep_profiling_proc_static(RttiProcLabel),
+	ProcStaticConsId = deep_profiling_proc_layout(RttiProcLabel),
 	generate_unify(ProcStaticConsId, ProcStaticVar, BindProcStaticVarGoal),
 
 	(
@@ -810,6 +814,8 @@
 			OldOutermostProcDyn2, NewOutermostProcDyn],
 			[TopCSD, MiddleCSD,
 				OldOutermostProcDyn2, NewOutermostProcDyn],
+			CallPortCode0),
+		goal_add_feature(CallPortCode0, save_deep_excp_vars,
 			CallPortCode),
 		generate_call(ModuleInfo, "non_exit_port_code_sr", 3,
 			[TopCSD, MiddleCSD, OldOutermostProcDyn2], [],
@@ -827,6 +833,8 @@
 		generate_call(ModuleInfo, "non_call_port_code_ac", 4,
 			[ProcStaticVar, TopCSD, MiddleCSD, NewOutermostProcDyn],
 			[TopCSD, MiddleCSD, NewOutermostProcDyn],
+			CallPortCode0),
+		goal_add_feature(CallPortCode0, save_deep_excp_vars,
 			CallPortCode),
 		generate_call(ModuleInfo, "non_exit_port_code_ac", 2,
 			[TopCSD, MiddleCSD], [], ExitPortCode),
@@ -879,12 +887,13 @@
 	]) - GoalInfo,
 	proc_info_set_varset(Vars, !Proc),
 	proc_info_set_vartypes(VarTypes, !Proc),
-	proc_info_set_goal(Goal, !Proc).
+	proc_info_set_goal(Goal, !Proc),
+	record_hlds_proc_static(ProcStatic, ExcpVars, !Proc).
 
 :- pred transform_inner_proc(module_info::in, pred_proc_id::in,
-	proc_info::in, proc_info::out, maybe(layout_data)::out) is det.
+	proc_info::in, proc_info::out) is det.
 
-transform_inner_proc(ModuleInfo, PredProcId, !Proc, no) :-
+transform_inner_proc(ModuleInfo, PredProcId, !Proc) :-
 	proc_info_goal(!.Proc, Goal0),
 	Goal0 = _ - GoalInfo0,
 	proc_info_varset(!.Proc, Vars0),
@@ -897,7 +906,8 @@
 	goal_info_get_context(GoalInfo0, Context),
 	FileName = term__context_file(Context),
 
-	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeRecInfo),
+	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeDeepProfInfo),
+	extract_deep_rec_info(MaybeDeepProfInfo, MaybeRecInfo),
 	DeepInfo0 = deep_info(ModuleInfo, PredProcId, MiddleCSD,
 		counter__init(0), [], Vars1, VarTypes1,
 		FileName, MaybeRecInfo),
@@ -1777,5 +1787,35 @@
 fail_goal_info = GoalInfo :-
 	instmap_delta_init_unreachable(InstMapDelta),
 	goal_info_init(set__init, InstMapDelta, failure, pure, GoalInfo).
+
+%-----------------------------------------------------------------------------%
+
+:- pred extract_deep_rec_info(maybe(deep_profile_proc_info)::in,
+	maybe(deep_recursion_info)::out) is det.
+
+extract_deep_rec_info(MaybeDeepProfInfo, MaybeRecInfo) :-
+	(
+		MaybeDeepProfInfo = yes(DeepProfInfo),
+		DeepProfInfo = deep_profile_proc_info(MaybeRecInfo, _)
+	;
+		MaybeDeepProfInfo = no,
+		MaybeRecInfo = no
+	).
+
+:- pred record_hlds_proc_static(hlds_proc_static::in, hlds_deep_excp_vars::in,
+	proc_info::in, proc_info::out) is det.
+
+record_hlds_proc_static(ProcStatic, ExcpVars, !Proc) :-
+	proc_info_get_maybe_deep_profile_info(!.Proc, MaybeDeepInfo0),
+	MaybeDeepLayoutInfo = yes(hlds_deep_layout(ProcStatic, ExcpVars)),
+	(
+		MaybeDeepInfo0 = yes(DeepInfo0),
+		DeepInfo = DeepInfo0 ^ deep_layout := MaybeDeepLayoutInfo
+	;
+		MaybeDeepInfo0 = no,
+		DeepInfo = deep_profile_proc_info(no, MaybeDeepLayoutInfo)
+	),
+	MaybeDeepInfo = yes(DeepInfo),
+	proc_info_set_maybe_deep_profile_info(MaybeDeepInfo, !Proc).
 
 %-----------------------------------------------------------------------------%
Index: compiler/dependency_graph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.69
diff -u -b -r1.69 dependency_graph.m
--- compiler/dependency_graph.m	5 Apr 2004 05:06:46 -0000	1.69
+++ compiler/dependency_graph.m	19 May 2004 03:54:28 -0000
@@ -506,7 +506,7 @@
 		_Caller, !DepGraph).
 dependency_graph__add_arcs_in_cons(tabling_pointer_const(_, _),
 		_Caller, !DepGraph).
-dependency_graph__add_arcs_in_cons(deep_profiling_proc_static(_),
+dependency_graph__add_arcs_in_cons(deep_profiling_proc_layout(_),
 		_Caller, !DepGraph).
 dependency_graph__add_arcs_in_cons(table_io_decl(_),
 		_Caller, !DepGraph).
Index: compiler/global_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/global_data.m,v
retrieving revision 1.3
diff -u -b -r1.3 global_data.m
--- compiler/global_data.m	8 Apr 2004 05:35:02 -0000	1.3
+++ compiler/global_data.m	19 May 2004 03:54:28 -0000
@@ -18,15 +18,13 @@
 :- import_module ll_backend__continuation_info.
 :- import_module ll_backend__exprn_aux.
 :- import_module ll_backend__llds.
-:- import_module ll_backend__layout.
 :- import_module parse_tree__prog_data. % for module_name
 
 :- import_module bool, list.
 
 :- type global_data.
 
-:- pred global_data_init(list(layout_data)::in, static_cell_info::in,
-	global_data::out) is det.
+:- pred global_data_init(static_cell_info::in, global_data::out) is det.
 
 :- pred global_data_add_new_proc_var( pred_proc_id::in, comp_gen_c_var::in,
 	global_data::in, global_data::out) is det.
@@ -55,9 +53,6 @@
 :- pred global_data_get_all_closure_layouts(global_data::in,
 	list(comp_gen_c_data)::out) is det.
 
-:- pred global_data_get_all_deep_prof_data(global_data::in,
-	list(comp_gen_c_data)::out) is det.
-
 :- pred global_data_get_static_cell_info(global_data::in,
 	static_cell_info::out) is det.
 
@@ -119,11 +114,6 @@
 						% it is possible, although
 						% unlikely, for two closures
 						% to have the same layout.
-			deep_prof_data		:: list(comp_gen_c_data),
-						% The list of global data
-						% structures created by the
-						% deep profiling
-						% transformation.
 			static_cell_info	:: static_cell_info
 						% Information about all the
 						% statically allocated cells
@@ -134,12 +124,11 @@
 
 wrap_layout_data(LayoutData) = layout_data(LayoutData).
 
-global_data_init(LayoutData, StaticCellInfo, GlobalData) :-
+global_data_init(StaticCellInfo, GlobalData) :-
 	map__init(EmptyDataMap),
 	map__init(EmptyLayoutMap),
-	WrappedLayoutData = list__map(wrap_layout_data, LayoutData),
 	GlobalData = global_data(EmptyDataMap, EmptyLayoutMap, [],
-		WrappedLayoutData, StaticCellInfo).
+		StaticCellInfo).
 
 global_data_add_new_proc_var(PredProcId, ProcVar, GlobalData0, GlobalData) :-
 	ProcVarMap0 = GlobalData0 ^ proc_var_map,
@@ -182,9 +171,6 @@
 
 global_data_get_all_closure_layouts(GlobalData, ClosureLayouts) :-
 	ClosureLayouts = GlobalData ^ closure_layouts.
-
-global_data_get_all_deep_prof_data(GlobalData, LayoutData) :-
-	LayoutData = GlobalData ^ deep_prof_data.
 
 global_data_get_static_cell_info(GlobalData, StaticCellInfo) :-
 	StaticCellInfo = GlobalData ^ static_cell_info.
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.203
diff -u -b -r1.203 handle_options.m
--- compiler/handle_options.m	14 May 2004 08:40:22 -0000	1.203
+++ compiler/handle_options.m	19 May 2004 03:54:28 -0000
@@ -228,13 +228,13 @@
 			"`simple', `total' or  `num-data-elems').", !Errors)
 	),
 	map__lookup(OptionTable0, trace, Trace),
-	map__lookup(OptionTable0, require_tracing, RequireTracingOpt),
+	map__lookup(OptionTable0, exec_trace, ExecTraceOpt),
 	map__lookup(OptionTable0, decl_debug, DeclDebugOpt),
 	(
 		Trace = string(TraceStr),
-		RequireTracingOpt = bool(RequireTracing),
+		ExecTraceOpt = bool(ExecTrace),
 		DeclDebugOpt = bool(DeclDebug),
-		convert_trace_level(TraceStr, RequireTracing, DeclDebug,
+		convert_trace_level(TraceStr, ExecTrace, DeclDebug,
 			MaybeTraceLevel)
 	->
 		(
@@ -732,12 +732,16 @@
 	option_implies(target_debug, strip, bool(no)),
 
 	% --decl-debug is an extension of --debug
-	option_implies(decl_debug, require_tracing, bool(yes)),
-	option_implies(decl_debug, stack_trace, bool(yes)),
+	option_implies(decl_debug, exec_trace, bool(yes)),
 
-	% The `.debug' grade (i.e. --stack-trace plus --require-tracing)
-	% implies --use-trail, except with --use-minimal-model, which is
-	% not compatible with --use-trail.
+	% We need to be able to simulate exits for calls between where an
+	% exception is thrown to where it is caught both in the debugger and
+	% for deep profiling.
+	option_implies(exec_trace, stack_trace, bool(yes)),
+	option_implies(profile_deep, stack_trace, bool(yes)),
+
+	% The `.debug' grade implies --use-trail, except with
+	% --use-minimal-model, which is not compatible with --use-trail.
 	%
 	% The reason for this is to avoid unnecessary proliferation in
 	% the number of different grades.  If you're using --debug,
@@ -745,9 +749,8 @@
 	% be able to afford the minor performance hit caused by
 	% --use-trail.
 
-	globals__io_lookup_bool_option(stack_trace, StackTrace),
-	globals__io_lookup_bool_option(require_tracing, RequireTracing),
-	( { StackTrace = yes, RequireTracing = yes, UseMinimalModel = no } ->
+	globals__io_lookup_bool_option(exec_trace, ExecTrace),
+	( { ExecTrace = yes, UseMinimalModel = no } ->
 		globals__io_set_option(use_trail, bool(yes))
 	;
 		[]
@@ -755,7 +758,7 @@
 
 	% In debugging grades, we want to generate executables in which
 	% one can do retries across I/O safely.
-	option_implies(require_tracing, trace_table_io_all, bool(yes)),
+	option_implies(exec_trace, trace_table_io_all, bool(yes)),
 
 	% --trace-table-io-all is compulsory application of --trace-table-io
 	option_implies(trace_table_io_all, trace_table_io, bool(yes)),
@@ -860,9 +863,7 @@
 		[]
 	),
 
-	% Deep profiling will eventually use `procid' stack layouts,
-	% but for now, we use a separate copy of each MR_Proc_Id structure.
-	% option_implies(profile_deep, procid_stack_layout, bool(yes)),
+	option_implies(profile_deep, procid_stack_layout, bool(yes)),
 	globals__io_lookup_bool_option(profile_deep, ProfileDeep),
 	globals__io_lookup_bool_option(highlevel_code, HighLevel),
 	( { ProfileDeep = yes } ->
@@ -1844,17 +1845,9 @@
 
 	% Debugging/Tracing components
 grade_component_table("decldebug", trace,
-	[stack_trace - bool(yes), require_tracing - bool(yes),
-	decl_debug - bool(yes)], no).
+	[exec_trace - bool(yes), decl_debug - bool(yes)], no).
 grade_component_table("debug", trace,
-	[stack_trace - bool(yes), require_tracing - bool(yes),
-	decl_debug - bool(no)], no).
-grade_component_table("trace", trace,
-	[stack_trace - bool(no), require_tracing - bool(yes),
-	decl_debug - bool(no)], no).
-grade_component_table("strce", trace,
-	[stack_trace - bool(yes), require_tracing - bool(no),
-	decl_debug - bool(no)], no).
+	[exec_trace - bool(yes), decl_debug - bool(no)], no).
 
 :- pred reset_grade_options(option_table::in, option_table::out) is det.
 
@@ -1884,8 +1877,7 @@
 grade_start_values(reserve_tag - bool(no)).
 grade_start_values(use_minimal_model - bool(no)).
 grade_start_values(pic_reg - bool(no)).
-grade_start_values(stack_trace - bool(no)).
-grade_start_values(require_tracing - bool(no)).
+grade_start_values(exec_trace - bool(no)).
 grade_start_values(decl_debug - bool(no)).
 
 :- pred split_grade_string(string, list(string)).
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.115
diff -u -b -r1.115 higher_order.m
--- compiler/higher_order.m	21 Dec 2003 05:04:33 -0000	1.115
+++ compiler/higher_order.m	19 May 2004 03:54:28 -0000
@@ -718,7 +718,7 @@
 is_interesting_cons_id(Params, typeclass_info_cell_constructor) =
 	Params ^ user_type_spec.
 is_interesting_cons_id(_Params, tabling_pointer_const(_, _)) = no.
-is_interesting_cons_id(_Params, deep_profiling_proc_static(_)) = no.
+is_interesting_cons_id(_Params, deep_profiling_proc_layout(_)) = no.
 is_interesting_cons_id(_Params, table_io_decl(_)) = no.
 
 	% Process a higher-order call or class_method_call to see if it
Index: compiler/hlds_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_code_util.m,v
retrieving revision 1.10
diff -u -b -r1.10 hlds_code_util.m
--- compiler/hlds_code_util.m	23 Mar 2004 10:52:03 -0000	1.10
+++ compiler/hlds_code_util.m	19 May 2004 03:54:28 -0000
@@ -70,8 +70,8 @@
 cons_id_to_tag(typeclass_info_cell_constructor, _, _) = unshared_tag(0).
 cons_id_to_tag(tabling_pointer_const(PredId,ProcId), _, _) =
 		tabling_pointer_constant(PredId,ProcId).
-cons_id_to_tag(deep_profiling_proc_static(PPId), _, _) =
-		deep_profiling_proc_static_tag(PPId).
+cons_id_to_tag(deep_profiling_proc_layout(PPId), _, _) =
+		deep_profiling_proc_layout_tag(PPId).
 cons_id_to_tag(table_io_decl(PPId), _, _) = table_io_decl_tag(PPId).
 cons_id_to_tag(cons(Name, Arity), Type, ModuleInfo) = Tag :-
 	(
Index: compiler/hlds_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_data.m,v
retrieving revision 1.85
diff -u -b -r1.85 hlds_data.m
--- compiler/hlds_data.m	12 May 2004 14:24:18 -0000	1.85
+++ compiler/hlds_data.m	19 May 2004 03:54:28 -0000
@@ -13,8 +13,6 @@
 
 :- interface.
 
-:- import_module backend_libs.
-:- import_module backend_libs__rtti.
 :- import_module hlds__hlds_pred.
 :- import_module parse_tree__inst.
 :- import_module parse_tree__prog_data.
@@ -59,9 +57,10 @@
 		% that points to the table that implements
 		% memoization, loop checking or the minimal
 		% model semantics for the given procedure.
-	;	deep_profiling_proc_static(rtti_proc_label)
-		% The ProcStatic structure of a procedure,
-		% as documented in the deep profiling paper.
+	;	deep_profiling_proc_layout(rtti_proc_label)
+		% The Proc_Layout structure of a procedure. Its proc_static
+		% field is used by deep profiling, as documented in the deep
+		% profiling paper.
 	;	table_io_decl(rtti_proc_label).
 		% The address of a structure that describes
 		% the layout of the answer block used by
@@ -206,9 +205,9 @@
 		"can't get arity of typeclass_info_cell_constructor").
 cons_id_arity(tabling_pointer_const(_, _)) =
 	func_error("cons_id_arity: can't get arity of tabling_pointer_const").
-cons_id_arity(deep_profiling_proc_static(_)) =
+cons_id_arity(deep_profiling_proc_layout(_)) =
 	func_error("cons_id_arity: " ++
-		"can't get arity of deep_profiling_proc_static").
+		"can't get arity of deep_profiling_proc_layout").
 cons_id_arity(table_io_decl(_)) =
 	func_error("cons_id_arity: can't get arity of table_io_decl").
 
@@ -222,7 +221,7 @@
 cons_id_maybe_arity(type_info_cell_constructor(_)) = no.
 cons_id_maybe_arity(typeclass_info_cell_constructor) = no.
 cons_id_maybe_arity(tabling_pointer_const(_, _)) = no.
-cons_id_maybe_arity(deep_profiling_proc_static(_)) = no.
+cons_id_maybe_arity(deep_profiling_proc_layout(_)) = no.
 cons_id_maybe_arity(table_io_decl(_)) = no.
 
 make_functor_cons_id(term__atom(Name), Arity) = cons(unqualified(Name), Arity).
@@ -401,7 +400,7 @@
 			% represented as global data. The word just contains
 			% the address of the tabling pointer of the
 			% specified procedure.
-	;	deep_profiling_proc_static_tag(rtti_proc_label)
+	;	deep_profiling_proc_layout_tag(rtti_proc_label)
 			% This is for constants representing procedure
 			% descriptions for deep profiling.
 	;	table_io_decl_tag(rtti_proc_label)
@@ -511,7 +510,7 @@
 get_primary_tag(type_ctor_info_constant(_, _, _)) = no.
 get_primary_tag(base_typeclass_info_constant(_, _, _)) = no.
 get_primary_tag(tabling_pointer_constant(_, _)) = no.
-get_primary_tag(deep_profiling_proc_static_tag(_)) = no.
+get_primary_tag(deep_profiling_proc_layout_tag(_)) = no.
 get_primary_tag(table_io_decl_tag(_)) = no.
 get_primary_tag(single_functor) = yes(0).
 get_primary_tag(unshared_tag(PrimaryTag)) = yes(PrimaryTag).
@@ -530,7 +529,7 @@
 get_secondary_tag(type_ctor_info_constant(_, _, _)) = no.
 get_secondary_tag(base_typeclass_info_constant(_, _, _)) = no.
 get_secondary_tag(tabling_pointer_constant(_, _)) = no.
-get_secondary_tag(deep_profiling_proc_static_tag(_)) = no.
+get_secondary_tag(deep_profiling_proc_layout_tag(_)) = no.
 get_secondary_tag(table_io_decl_tag(_)) = no.
 get_secondary_tag(single_functor) = no.
 get_secondary_tag(unshared_tag(_)) = no.
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.114
diff -u -b -r1.114 hlds_goal.m
--- compiler/hlds_goal.m	31 Mar 2004 12:32:28 -0000	1.114
+++ compiler/hlds_goal.m	19 May 2004 03:54:28 -0000
@@ -737,6 +737,10 @@
 				% feature, even if their determinism puts an
 				% at_most_zero upper bound on the number of
 				% solutions they have.
+	;	save_deep_excp_vars
+				% This goal generates the deep profiling
+				% variables that the exception handler needs
+				% to execute the exception port code.
 	;	hide_debug_event
 				% The events associated with this goal should
 				% be hidden. This is used e.g. by the tabling
Index: compiler/hlds_llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_llds.m,v
retrieving revision 1.4
diff -u -b -r1.4 hlds_llds.m
--- compiler/hlds_llds.m	10 Apr 2004 10:33:01 -0000	1.4
+++ compiler/hlds_llds.m	19 May 2004 03:54:28 -0000
@@ -257,6 +257,8 @@
 
 %-----------------------------------------------------------------------------%
 
+:- func stack_slot_num(stack_slot) = int.
+
 :- func stack_slot_to_abs_locn(stack_slot) = abs_locn.
 :- func key_stack_slot_to_abs_locn(_, stack_slot) = abs_locn.
 
@@ -697,6 +699,9 @@
 	rename_vars_in_var_locn_list(VarLocns0, Must, Subn, VarLocns).
 
 %-----------------------------------------------------------------------------%
+
+stack_slot_num(det_slot(N)) = N.
+stack_slot_num(nondet_slot(N)) = N.
 
 stack_slot_to_abs_locn(det_slot(N)) = abs_stackvar(N).
 stack_slot_to_abs_locn(nondet_slot(N)) = abs_framevar(N).
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.329
diff -u -b -r1.329 hlds_out.m
--- compiler/hlds_out.m	14 May 2004 08:40:23 -0000	1.329
+++ compiler/hlds_out.m	19 May 2004 03:54:28 -0000
@@ -322,8 +322,8 @@
 	"<typeclass_info_cell_constructor>".
 hlds_out__cons_id_to_string(tabling_pointer_const(_, _)) =
 	"<tabling_pointer>".
-hlds_out__cons_id_to_string(deep_profiling_proc_static(_)) =
-	"<deep_profiling_proc_static>".
+hlds_out__cons_id_to_string(deep_profiling_proc_layout(_)) =
+	"<deep_profiling_proc_layout>".
 hlds_out__cons_id_to_string(table_io_decl(_)) = "<table_io_decl>".
 
 hlds_out__write_cons_id(cons(SymName, Arity)) -->
@@ -346,8 +346,8 @@
 	io__write_string("<typeclass_info_cell_constructor>").
 hlds_out__write_cons_id(tabling_pointer_const(_, _)) -->
 	io__write_string("<tabling_pointer>").
-hlds_out__write_cons_id(deep_profiling_proc_static(_)) -->
-	io__write_string("<deep_profiling_proc_static>").
+hlds_out__write_cons_id(deep_profiling_proc_layout(_)) -->
+	io__write_string("<deep_profiling_proc_layout>").
 hlds_out__write_cons_id(table_io_decl(_)) -->
 	io__write_string("<table_io_decl>").
 
@@ -2590,9 +2590,9 @@
 		io__write_int(ProcIdInt, !IO),
 		io__write_string(")", !IO)
 	;
-		ConsId = deep_profiling_proc_static(RttiProcLabel),
+		ConsId = deep_profiling_proc_layout(RttiProcLabel),
 		rtti__proc_label_pred_proc_id(RttiProcLabel, PredId, ProcId),
-		io__write_string("deep_profiling_proc_static(", !IO),
+		io__write_string("deep_profiling_proc_layout(", !IO),
 		hlds_out__write_pred_id(ModuleInfo, PredId, !IO),
 		proc_id_to_int(ProcId, ProcIdInt),
 		io__write_string(" (mode ", !IO),
@@ -3524,8 +3524,12 @@
 
 	(
 		MaybeDeepProfileInfo = yes(DeepProfileInfo),
-		DeepProfileInfo = deep_profile_proc_info(Role, _SCC),
-		io__write_string("% deep profile info: ", !IO),
+		DeepProfileInfo = deep_profile_proc_info(MaybeRecInfo,
+			MaybeDeepLayout),
+		(
+			MaybeRecInfo = yes(DeepRecInfo),
+			DeepRecInfo = deep_recursion_info(Role, _),
+			io__write_string("% deep recursion info: ", !IO),
 		(
 			Role = inner_proc(DeepPredProcId),
 			io__write_string("inner, outer is ", !IO)
@@ -3540,6 +3544,32 @@
 		io__write_string("/", !IO),
 		io__write_int(DeepProcInt, !IO),
 		io__write_string("\n", !IO)
+	;
+			MaybeRecInfo = no
+		),
+		(
+			MaybeDeepLayout = yes(DeepLayout),
+			DeepLayout = hlds_deep_layout(_, ExcpVars),
+			ExcpVars = hlds_deep_excp_vars(TopCSD, MiddleCSD,
+				MaybeOldOutermost),
+			io__write_string("% deep layout info: ", !IO),
+			io__write_string("TopCSD is ", !IO),
+			mercury_output_var(TopCSD, VarSet, AppendVarnums, !IO),
+			io__write_string(", MiddleCSD is ", !IO),
+			mercury_output_var(MiddleCSD, VarSet, AppendVarnums,
+				!IO),
+			(
+				MaybeOldOutermost = yes(OldOutermost),
+				io__write_string(", OldOutermost is ", !IO),
+				mercury_output_var(OldOutermost, VarSet,
+					AppendVarnums, !IO)
+			;
+				MaybeOldOutermost = no
+			),
+			io__write_string("\n", !IO)
+		;
+			MaybeDeepLayout = no
+		)
 	;
 		MaybeDeepProfileInfo = no
 	),
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.141
diff -u -b -r1.141 hlds_pred.m
--- compiler/hlds_pred.m	24 Mar 2004 00:39:28 -0000	1.141
+++ compiler/hlds_pred.m	19 May 2004 03:54:28 -0000
@@ -24,7 +24,7 @@
 :- import_module parse_tree__prog_data.
 :- import_module transform_hlds__term_util.
 
-:- import_module bool, list, set, map, std_util, term, varset.
+:- import_module bool, list, assoc_list, set, map, std_util, term, varset.
 
 :- implementation.
 
@@ -43,7 +43,7 @@
 :- import_module libs__options.
 
 % Standard library modules.
-:- import_module int, string, require, assoc_list.
+:- import_module int, string, require.
 
 %-----------------------------------------------------------------------------%
 
@@ -104,6 +104,58 @@
 :- type pred_proc_id	--->	proc(pred_id, proc_id).
 :- type pred_proc_list	==	list(pred_proc_id).
 
+:- type prog_var_name == string.
+
+	% The rtti_proc_label type holds all the information about a procedure
+	% that we need to compute the entry label for that procedure
+	% in the target language (the llds__code_addr or mlds__code_addr).
+:- type rtti_proc_label --->
+	rtti_proc_label(
+		pred_or_func		::	pred_or_func,
+		this_module		::	module_name,
+		proc_module		::	module_name,
+		proc_name		::	string,
+		proc_arity		::	arity,
+		proc_arg_types		::	list(type),
+		pred_id			::	pred_id,
+		proc_id			::	proc_id,
+		proc_headvars		::	assoc_list(prog_var,
+							prog_var_name),
+		proc_arg_modes		::	list(arg_mode),
+		proc_interface_detism	::	determinism,
+
+		% The following booleans hold values computed from the
+		% pred_info, using procedures
+		%	pred_info_is_imported/1,
+		%	pred_info_is_pseudo_imported/1,
+		%	pred_info_get_maybe_special_pred_info/1
+		% respectively.
+		% We store booleans here, rather than storing the
+		% pred_info, to avoid retaining a reference to the
+		% parts of the pred_info that we aren't interested in,
+		% so that those parts can be garbage collected.
+		% We use booleans rather than an import_status
+		% so that we can continue to use the above-mentioned
+		% abstract interfaces rather than hard-coding tests
+		% on the import_status.
+
+		pred_is_imported	::	bool,
+		pred_is_pseudo_imported	::	bool,
+		pred_is_special_pred	::	maybe(special_pred),
+
+		% The following boolean holds a value computed from the
+		% proc_info, using procedure_is_exported/2
+
+		proc_is_exported	::	bool,
+
+		% The following bool is true if the procedure was
+		% imported, either because the containing predicate
+		% was imported, or because it was pseudoimported
+		% and the procedure is an in-in unify procedure.
+
+		proc_is_imported	::	bool
+	).
+
 %-----------------------------------------------------------------------------%
 
 	% The clauses_info structure contains the clauses for a predicate
@@ -1556,8 +1608,8 @@
 			inner_proc	:: pred_proc_id
 		).
 
-:- type deep_profile_proc_info
-	--->	deep_profile_proc_info(
+:- type deep_recursion_info
+	--->	deep_recursion_info(
 			role		:: deep_profile_role,
 			visible_scc	:: list(visible_scc_data)
 					% If the procedure is not tail
@@ -1579,6 +1631,79 @@
 					% left-to-right, from zero.)
 		).
 
+:- type call_site_static_data			% defines MR_CallSiteStatic
+	--->	normal_call(
+			normal_callee		:: rtti_proc_label,
+			normal_type_subst	:: string,
+			normal_file_name	:: string,
+			normal_line_number	:: int,
+			normal_goal_path	:: goal_path
+		)
+	;	special_call(
+			special_file_name	:: string,
+			special_line_number	:: int,
+			special_goal_path	:: goal_path
+		)
+	;	higher_order_call(
+			higher_order_file_name	:: string,
+			ho_line_number		:: int,
+			ho_goal_path		:: goal_path
+		)
+	;	method_call(
+			method_file_name	:: string,
+			method_line_number	:: int,
+			method_goal_path	:: goal_path
+		)
+	;	callback(
+			callback_file_name	:: string,
+			callback_line_number	:: int,
+			callback_goal_path	:: goal_path
+		).
+
+:- type hlds_proc_static
+	--->	hlds_proc_static(	% defines part of MR_ProcStatic
+			proc_static_file_name	:: string,
+			proc_static_line_number :: int,
+			proc_is_in_interface	:: bool,
+			call_site_statics	:: list(call_site_static_data)
+		).
+
+	% The hlds_deep_excp_vars gives the variables that hold
+	% the values returned by the call port code, which are needed to let
+	% exception.throw perform the work we need to do at the excp port.
+:- type hlds_deep_excp_vars
+	--->	hlds_deep_excp_vars(
+			top_csd		:: prog_var,
+			middle_csd	:: prog_var,
+			old_outermost	:: maybe(prog_var)
+					% Needed only with the save/restore
+					% approach, not the activation counting
+					% approach.
+		).
+
+:- type hlds_deep_layout
+	--->	hlds_deep_layout(
+			deep_layout_static :: hlds_proc_static,
+			deep_layout_excp   :: hlds_deep_excp_vars
+		).
+
+:- type deep_profile_proc_info
+	--->	deep_profile_proc_info(
+			deep_rec	:: maybe(deep_recursion_info),
+			deep_layout	:: maybe(hlds_deep_layout)
+					% The first field is set during
+					% the first, tail recursion
+					% part of the deep profiling
+					% transformation, if that is enabled.
+					% The deep_layout field is set during
+					% the second part; it will be bound
+					% to `no' before and during the first
+					% part, and to `yes' after the second.
+					% The contents of this field govern
+					% what will go into MR_ProcStatic
+					% structures.
+		).
+
 :- type table_arg_info
 	--->	table_arg_info(
 			headvar		:: prog_var,
@@ -2741,8 +2866,7 @@
 		( InlineBuiltins = yes
 		; CallerPredId = PredId
 		),
-		is_inline_builtin(ModuleName, PredName,
-			ProcId, Arity)
+		is_inline_builtin(ModuleName, PredName, ProcId, Arity)
 	->
 		BuiltinState = inline_builtin
 	;
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.12
diff -u -b -r1.12 layout.m
--- compiler/layout.m	14 Mar 2003 08:10:06 -0000	1.12
+++ compiler/layout.m	19 May 2004 03:54:28 -0000
@@ -33,8 +33,6 @@
 :- interface.
 
 :- import_module backend_libs__proc_label.
-:- import_module backend_libs__rtti.
-:- import_module hlds__hlds_goal.
 :- import_module hlds__hlds_pred.
 :- import_module libs__trace_params.
 :- import_module ll_backend__llds.
@@ -55,9 +53,9 @@
 			maybe_var_info		:: maybe(label_var_info)
 		)
 	;	proc_layout_data(		% defines MR_Proc_Layout
-			proc_label,
-			proc_layout_stack_traversal,
-			maybe_proc_id_and_exec_trace
+			proc_layout_label	:: rtti_proc_label,
+			proc_layout_trav	:: proc_layout_stack_traversal,
+			proc_layout_more	:: maybe_proc_id_and_more
 		)
 	;	module_layout_data(		% defines MR_Module_Layout
 			module_name		:: module_name,
@@ -77,13 +75,6 @@
 			closure_line_number	:: int,
 			closure_goal_path	:: string
 		)
-	;	proc_static_data(		% defines MR_ProcStatic
-			proc_static_id		:: rtti_proc_label,
-			proc_static_file_name	:: string,
-			proc_static_line_number :: int,
-			proc_is_in_interface	:: bool,
-			call_site_statics	:: list(call_site_static_data)
-		)
 	;	table_io_decl_data(
 			table_io_decl_proc_ptr	:: rtti_proc_label,
 			table_io_decl_kind	:: proc_layout_kind,
@@ -102,35 +93,6 @@
 			table_gen_type_params	:: rval
 		).
 
-:- type call_site_static_data			% defines MR_CallSiteStatic
-	--->	normal_call(
-			normal_callee		:: rtti_proc_label,
-			normal_type_subst	:: string,
-			normal_file_name	:: string,
-			normal_line_number	:: int,
-			normal_goal_path	:: goal_path
-		)
-	;	special_call(
-			special_file_name	:: string,
-			special_line_number	:: int,
-			special_goal_path	:: goal_path
-		)
-	;	higher_order_call(
-			higher_order_file_name	:: string,
-			ho_line_number		:: int,
-			ho_goal_path		:: goal_path
-		)
-	;	method_call(
-			method_file_name	:: string,
-			method_line_number	:: int,
-			method_goal_path	:: goal_path
-		)
-	;	callback(
-			callback_file_name	:: string,
-			callback_line_number	:: int,
-			callback_goal_path	:: goal_path
-		).
-
 :- type label_var_info
 	--->	label_var_info(			% part of MR_Label_Layout
 			encoded_var_count	:: int,
@@ -150,10 +112,34 @@
 			detism			:: determinism
 		).
 
-:- type maybe_proc_id_and_exec_trace
+	% The deep_slot_info gives the stack slot numbers that hold
+	% the values returned by the call port code, which are needed to let
+	% exception.throw perform the work we need to do at the excp port.
+	% The old_outermost slot is needed only with the save/restore approach;
+	% the old_outermost field contain -1 otherwise. All fields will contain
+	% -1 if the variables are never saved on the stack because the
+	% predicate makes no calls (in which case it cannot throw exceptions,
+	% because to do that it would need to call exception.throw, directly or
+	% indirectly.)
+:- type deep_excp_slots
+	--->	deep_excp_slots(
+			top_csd		:: int,
+			middle_csd	:: int,
+			old_outermost	:: int
+		).
+
+:- type proc_layout_proc_static
+	--->	proc_layout_proc_static(
+			hlds_proc_static	:: hlds_proc_static,
+			deep_excp_slots		:: deep_excp_slots
+		).
+
+:- type maybe_proc_id_and_more
 	--->	no_proc_id
-	;	proc_id_only
-	;	proc_id_and_exec_trace(proc_layout_exec_trace).
+	;	proc_id(
+			maybe(proc_layout_proc_static),
+			maybe(proc_layout_exec_trace)
+		).
 
 :- type proc_layout_exec_trace			% defines MR_Exec_Trace
 	--->	proc_layout_exec_trace(
@@ -191,14 +177,15 @@
 
 :- type layout_name
 	--->	label_layout(label, label_vars)
-	;	proc_layout(proc_label, proc_layout_kind)
-		% A proc layout structure for stack tracing, accurate gc
-		% and/or execution tracing.
-	;	proc_layout_head_var_nums(proc_label)
+	;	proc_layout(rtti_proc_label, proc_layout_kind)
+		% A proc layout structure for stack tracing, accurate gc,
+		% deep profiling and/or execution tracing.
+	;	proc_layout_exec_trace(rtti_proc_label)
+	;	proc_layout_head_var_nums(rtti_proc_label)
 		% A vector of variable numbers, containing the numbers of the
 		% procedure's head variables, including the ones generated by
 		% the compiler.
-	;	proc_layout_var_names(proc_label)
+	;	proc_layout_var_names(rtti_proc_label)
 		% A vector of variable names (represented as offsets into
 		% the string table) for a procedure layout structure.
 	;	table_io_decl(rtti_proc_label)
@@ -222,11 +209,10 @@
 
 :- type proc_layout_kind
 	--->	proc_layout_traversal
-	;	proc_layout_proc_id(proc_layout_user_or_compiler)
-	;	proc_layout_exec_trace(proc_layout_user_or_compiler).
+	;	proc_layout_proc_id(proc_layout_user_or_uci).
 
-:- type proc_layout_user_or_compiler
+:- type proc_layout_user_or_uci
 	--->	user
-	;	compiler.
+	;	uci.
 
 %-----------------------------------------------------------------------------%
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.31
diff -u -b -r1.31 layout_out.m
--- compiler/layout_out.m	3 May 2004 08:47:24 -0000	1.31
+++ compiler/layout_out.m	19 May 2004 03:54:28 -0000
@@ -73,8 +73,9 @@
 :- func make_label_layout_name(label) = string.
 
 	% For a given procedure label, return whether the procedure is
-	% user-defined or compiler-generated.
-:- func proc_label_user_or_compiler(proc_label) = proc_layout_user_or_compiler.
+	% user-defined or part of a compiler-generated unify, compare or index
+	% predicate.
+:- func proc_label_user_or_uci(proc_label) = proc_layout_user_or_uci.
 
 	% Output a value of C type MR_PredFunc corrresponding to the argument.
 :- pred output_pred_or_func(pred_or_func::in, io::di, io::uo) is det.
@@ -118,10 +119,6 @@
 	output_module_layout_data_defn(ModuleName, StringTableSize,
 		StringTable, ProcLayoutNames, FileLayouts, TraceLevel,
 		SuppressedEvents, !DeclSet, !IO).
-output_layout_data_defn(proc_static_data(RttiProcLabel, FileName, LineNumber,
-		IsInInterface, CallSites), !DeclSet, !IO) :-
-	output_proc_static_data_defn(RttiProcLabel, FileName, LineNumber,
-		IsInInterface, CallSites, !DeclSet, !IO).
 output_layout_data_defn(table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
 		PTIVectorRval, TypeParamsRval), !DeclSet, !IO) :-
 	output_table_io_decl(RttiProcLabel, Kind, NumPTIs,
@@ -155,16 +152,16 @@
 	LayoutName = label_layout(Label, label_has_var_info).
 extract_layout_name(label_layout_data(Label, _, _, _, _, no), LayoutName) :-
 	LayoutName = label_layout(Label, label_has_no_var_info).
-extract_layout_name(proc_layout_data(ProcLabel, _, MaybeRest), LayoutName) :-
-	Kind = maybe_proc_layout_and_exec_trace_kind(MaybeRest, ProcLabel),
-	LayoutName = proc_layout(ProcLabel, Kind).
+extract_layout_name(proc_layout_data(RttiProcLabel, _, MaybeRest),
+		LayoutName) :-
+	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
+	Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
+	LayoutName = proc_layout(RttiProcLabel, Kind).
 extract_layout_name(closure_proc_id_data(CallerProcLabel, SeqNo,
 		ClosureProcLabel, _, _, _, _),
 		closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel)).
 extract_layout_name(module_layout_data(ModuleName, _,_,_,_,_,_), LayoutName) :-
 	LayoutName = module_layout(ModuleName).
-extract_layout_name(proc_static_data(RttiProcLabel, _, _, _, _), LayoutName) :-
-	LayoutName = proc_static(RttiProcLabel).
 extract_layout_name(table_io_decl_data(RttiProcLabel, _, _, _, _),
 		LayoutName) :-
 	LayoutName = table_io_decl(RttiProcLabel).
@@ -202,22 +199,26 @@
 	io__write_string(mercury_data_prefix),
 	io__write_string("_label_layout__"),
 	io__write_string(label_to_c_string(Label, yes)).
-output_layout_name(proc_layout(ProcLabel, _)) -->
+output_layout_name(proc_layout(RttiProcLabel, _)) -->
 	io__write_string(mercury_data_prefix),
 	io__write_string("_proc_layout__"),
 	% We can't omit the mercury_ prefix on ProcLabel, even though the
 	% mercury_data_prefix duplicates it, because there is no simply way
 	% to make the MR_init_entryl_sl macro delete that prefix from the
 	% entry label's name to get the name of its layout structure.
-	output_proc_label(ProcLabel, yes).
-output_layout_name(proc_layout_head_var_nums(ProcLabel)) -->
+	output_proc_label(make_proc_label_from_rtti(RttiProcLabel), yes).
+output_layout_name(proc_layout_exec_trace(RttiProcLabel)) -->
+	io__write_string(mercury_data_prefix),
+	io__write_string("_proc_layout_exec_trace__"),
+	output_proc_label(make_proc_label_from_rtti(RttiProcLabel), no).
+output_layout_name(proc_layout_head_var_nums(RttiProcLabel)) -->
 	io__write_string(mercury_data_prefix),
 	io__write_string("_head_var_nums__"),
-	output_proc_label(ProcLabel, no).
-output_layout_name(proc_layout_var_names(ProcLabel)) -->
+	output_proc_label(make_proc_label_from_rtti(RttiProcLabel), no).
+output_layout_name(proc_layout_var_names(RttiProcLabel)) -->
 	io__write_string(mercury_data_prefix),
 	io__write_string("_var_names__"),
-	output_proc_label(ProcLabel, no).
+	output_proc_label(make_proc_label_from_rtti(RttiProcLabel), no).
 output_layout_name(closure_proc_id(CallerProcLabel, SeqNo, _)) -->
 	io__write_string(mercury_data_prefix),
 	io__write_string("_closure_layout__"),
@@ -303,11 +304,30 @@
 	io__write_string(" "),
 	output_layout_name(label_layout(Label, LabelVars)).
 output_layout_name_storage_type_name(proc_layout(ProcLabel, Kind),
-		_BeingDefined) -->
-	io__write_string("static MR_STATIC_CODE_CONST "),
-	io__write_string(kind_to_type(Kind)),
+		BeingDefined) -->
+	{ ProcIsImported = ProcLabel ^ proc_is_imported },
+	{ ProcIsExported = ProcLabel ^ proc_is_exported },
+	(
+		{ ProcIsImported = no },
+		{ ProcIsExported = no }
+	->
+		io__write_string("static ")
+	;
+		(
+			{ BeingDefined = yes }
+		;
+			{ BeingDefined = no },
+			io__write_string("extern ")
+		)
+	),
+	io__write_string("const "),
+	io__write_string(proc_layout_kind_to_type(Kind)),
 	io__write_string(" "),
 	output_layout_name(proc_layout(ProcLabel, Kind)).
+output_layout_name_storage_type_name(proc_layout_exec_trace(ProcLabel),
+		_BeingDefined) -->
+	io__write_string("static MR_STATIC_CODE_CONST MR_Exec_Trace\n\t"),
+	output_layout_name(proc_layout_exec_trace(ProcLabel)).
 output_layout_name_storage_type_name(proc_layout_head_var_nums(ProcLabel),
 		_BeingDefined) -->
 	io__write_string("static const "),
@@ -328,7 +348,7 @@
 		io__write_string("MR_User_Closure_Id\n")
 	;
 		{ ClosureProcLabel = special_proc(_, _, _, _, _, _) },
-		io__write_string("MR_Compiler_Closure_Id\n")
+		io__write_string("MR_UCI_Closure_Id\n")
 	),
 	output_layout_name(closure_proc_id(CallerProcLabel, SeqNo,
 		ClosureProcLabel)).
@@ -368,20 +388,8 @@
 	io__write_string("static const MR_Module_Layout "),
 	output_layout_name(module_layout(ModuleName)).
 output_layout_name_storage_type_name(proc_static(RttiProcLabel),
-		BeingDefined) -->
-	(
-		{ BeingDefined = no },
-		io__write_string("extern ")
-	;
-		{ BeingDefined = yes }
-	),
-	(
-		{ RttiProcLabel ^ maybe_special_pred = yes(_) },
-		io__write_string("MR_Compiler_ProcStatic ")
-	;
-		{ RttiProcLabel ^ maybe_special_pred = no },
-		io__write_string("MR_User_ProcStatic ")
-	),
+		_BeingDefined) -->
+	io__write_string("static MR_ProcStatic "),
 	output_layout_name(proc_static(RttiProcLabel)).
 output_layout_name_storage_type_name(proc_static_call_sites(RttiProcLabel),
 		_BeingDefined) -->
@@ -408,7 +416,8 @@
 	io__write_string("[]").
 
 layout_name_would_include_code_addr(label_layout(_, _)) = no.
-layout_name_would_include_code_addr(proc_layout(_, _)) = yes.
+layout_name_would_include_code_addr(proc_layout(_, _)) = no.
+layout_name_would_include_code_addr(proc_layout_exec_trace(_)) = yes.
 layout_name_would_include_code_addr(proc_layout_head_var_nums(_)) = no.
 layout_name_would_include_code_addr(proc_layout_var_names(_)) = no.
 layout_name_would_include_code_addr(closure_proc_id(_, _, _)) = no.
@@ -431,13 +440,14 @@
 label_vars_to_type(label_has_var_info) =    "MR_Label_Layout".
 label_vars_to_type(label_has_no_var_info) = "MR_Label_Layout_No_Var_Info".
 
-:- func kind_to_type(proc_layout_kind) = string.
+:- func proc_layout_kind_to_type(proc_layout_kind) = string.
 
-kind_to_type(proc_layout_traversal) =            "MR_Proc_Layout_Traversal".
-kind_to_type(proc_layout_proc_id(user)) =        "MR_Proc_Layout_User".
-kind_to_type(proc_layout_proc_id(compiler)) =    "MR_Proc_Layout_Compiler".
-kind_to_type(proc_layout_exec_trace(user)) =     "MR_Proc_Layout_User_Exec".
-kind_to_type(proc_layout_exec_trace(compiler)) = "MR_Proc_Layout_Compiler_Exec".
+proc_layout_kind_to_type(proc_layout_traversal) =
+	"MR_Proc_Layout_Traversal".
+proc_layout_kind_to_type(proc_layout_proc_id(user)) =
+	"MR_Proc_Layout_User".
+proc_layout_kind_to_type(proc_layout_proc_id(uci)) =
+	"MR_Proc_Layout_UCI".
 
 %-----------------------------------------------------------------------------%
 
@@ -607,76 +617,96 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_proc_layout_data_defn(proc_label::in,
-	proc_layout_stack_traversal::in, maybe_proc_id_and_exec_trace::in,
+:- pred output_proc_layout_data_defn(rtti_proc_label::in,
+	proc_layout_stack_traversal::in, maybe_proc_id_and_more::in,
 	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_proc_layout_data_defn(ProcLabel, Traversal, MaybeRest, !DeclSet, !IO) :-
-	Kind = maybe_proc_layout_and_exec_trace_kind(MaybeRest, ProcLabel),
+output_proc_layout_data_defn(RttiProcLabel, Traversal, MaybeRest,
+		!DeclSet, !IO) :-
+	output_layout_traversal_decls(Traversal, !DeclSet, !IO),
+	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
+	Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
 	(
 		MaybeRest = no_proc_id,
-		output_layout_traversal_decls(Traversal, !DeclSet, !IO),
-		output_proc_layout_data_defn_start(ProcLabel, Kind, Traversal,
-			!IO),
+		output_proc_layout_data_defn_start(RttiProcLabel, Kind,
+			Traversal, !IO),
 		output_layout_no_proc_id_group(!IO),
 		output_proc_layout_data_defn_end(!IO)
 	;
-		MaybeRest = proc_id_only,
-		output_layout_traversal_decls(Traversal, !DeclSet, !IO),
-		output_proc_layout_data_defn_start(ProcLabel, Kind, Traversal,
-			!IO),
-		output_layout_proc_id_group(ProcLabel, !IO),
-		output_layout_no_exec_trace_group(!IO),
-		output_proc_layout_data_defn_end(!IO)
+		MaybeRest = proc_id(MaybeProcStatic, MaybeExecTrace),
+		(
+			MaybeProcStatic = yes(ProcStatic),
+			output_proc_static_data_defn(RttiProcLabel, ProcStatic,
+				!DeclSet, !IO)
 	;
-		MaybeRest = proc_id_and_exec_trace(ExecTrace),
+			MaybeProcStatic = no
+		),
+		(
+			MaybeExecTrace = yes(ExecTrace),
 		HeadVarNums = ExecTrace ^ head_var_nums,
-		output_proc_layout_head_var_nums(ProcLabel, HeadVarNums,
-			!DeclSet, !IO),
+			output_proc_layout_head_var_nums(RttiProcLabel,
+				HeadVarNums, !DeclSet, !IO),
 		VarNames = ExecTrace ^ var_names,
 		MaxVarNum = ExecTrace ^ max_var_num,
-		output_proc_layout_var_names(ProcLabel, VarNames, MaxVarNum,
-			!DeclSet, !IO),
-		output_layout_traversal_decls(Traversal, !DeclSet, !IO),
-		output_layout_exec_trace_decls(ProcLabel, ExecTrace, !DeclSet,
-			!IO),
+			output_proc_layout_var_names(RttiProcLabel, VarNames,
+				MaxVarNum, !DeclSet, !IO),
+			output_layout_exec_trace_decls(RttiProcLabel,
+				ExecTrace, !DeclSet, !IO),
+			output_layout_exec_trace(RttiProcLabel, ExecTrace,
+				!DeclSet, !IO)
+		;
+			MaybeExecTrace = no
+		),
 
-		output_proc_layout_data_defn_start(ProcLabel, Kind, Traversal,
-			!IO),
+		output_proc_layout_data_defn_start(RttiProcLabel, Kind,
+			Traversal, !IO),
 		output_layout_proc_id_group(ProcLabel, !IO),
-		output_layout_exec_trace_group(ProcLabel, ExecTrace, !IO),
+		(
+			MaybeExecTrace = no,
+			io__write_string("NULL,\n", !IO)
+		;
+			MaybeExecTrace = yes(_),
+			io__write_string("&", !IO),
+			output_layout_name(
+				proc_layout_exec_trace(RttiProcLabel), !IO),
+			io__write_string(",\n", !IO)
+		),
+		(
+			MaybeProcStatic = no,
+			io__write_string("NULL\n", !IO)
+		;
+			MaybeProcStatic = yes(_),
+			io__write_string("&", !IO),
+			output_layout_name(proc_static(RttiProcLabel), !IO),
+			io__write_string("\n", !IO)
+		),
 		output_proc_layout_data_defn_end(!IO)
 	),
-	decl_set_insert(data_addr(layout_addr(proc_layout(ProcLabel, Kind))),
-		!DeclSet).
+	decl_set_insert(data_addr(
+		layout_addr(proc_layout(RttiProcLabel, Kind))), !DeclSet).
 
-:- func maybe_proc_layout_and_exec_trace_kind(maybe_proc_id_and_exec_trace,
+:- func maybe_proc_layout_and_more_kind(maybe_proc_id_and_more,
 	proc_label) = proc_layout_kind.
 
-maybe_proc_layout_and_exec_trace_kind(MaybeRest, ProcLabel) = Kind :-
+maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel) = Kind :-
 	(
 		MaybeRest = no_proc_id,
 		Kind = proc_layout_traversal
 	;
-		MaybeRest = proc_id_only,
-		Kind = proc_layout_proc_id(
-			proc_label_user_or_compiler(ProcLabel))
-	;
-		MaybeRest = proc_id_and_exec_trace(_),
-		Kind = proc_layout_exec_trace(
-			proc_label_user_or_compiler(ProcLabel))
+		MaybeRest = proc_id(_, _),
+		Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel))
 	).
 
-proc_label_user_or_compiler(proc(_, _, _, _, _, _)) = user.
-proc_label_user_or_compiler(special_proc(_, _, _, _, _, _)) = compiler.
+proc_label_user_or_uci(proc(_, _, _, _, _, _)) = user.
+proc_label_user_or_uci(special_proc(_, _, _, _, _, _)) = uci.
 
-:- pred output_proc_layout_data_defn_start(proc_label::in,
+:- pred output_proc_layout_data_defn_start(rtti_proc_label::in,
 	proc_layout_kind::in, proc_layout_stack_traversal::in,
 	io::di, io::uo) is det.
 
-output_proc_layout_data_defn_start(ProcLabel, Kind, Traversal) -->
+output_proc_layout_data_defn_start(RttiProcLabel, Kind, Traversal) -->
 	io__write_string("\n"),
-	output_layout_name_storage_type_name(proc_layout(ProcLabel, Kind),
+	output_layout_name_storage_type_name(proc_layout(RttiProcLabel, Kind),
 		yes),
 	io__write_string(" = {\n"),
 	output_layout_traversal_group(Traversal).
@@ -752,17 +782,18 @@
 output_layout_no_proc_id_group -->
 	io__write_string("-1\n").
 
-:- pred output_layout_exec_trace_decls(proc_label::in,
+:- pred output_layout_exec_trace_decls(rtti_proc_label::in,
 	proc_layout_exec_trace::in, decl_set::in, decl_set::out,
 	io::di, io::uo) is det.
 
-output_layout_exec_trace_decls(ProcLabel, ExecTrace, !DeclSet, !IO) :-
+output_layout_exec_trace_decls(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
 	ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
 		MaybeTableInfo, _HeadVarNums, _VarNames, _MaxVarNum,
 		_MaxRegNum, _MaybeFromFullSlot, _MaybeIoSeqSlot,
 		_MaybeTrailSlot, _MaybeMaxfrSlot, _EvalMethod,
 		_MaybeCallTableSlot),
-	ModuleName = get_defining_module_name(ProcLabel),
+	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
+	ModuleName = get_defining_module_name(ProcLabel) ,
 	output_layout_decl(CallLabelLayout, !DeclSet, !IO),
 	output_layout_decl(module_layout(ModuleName), !DeclSet, !IO),
 	(
@@ -778,72 +809,77 @@
 		MaybeTableInfo = no
 	).
 
-:- pred output_layout_exec_trace_group(proc_label::in,
-	proc_layout_exec_trace::in, io::di, io::uo) is det.
+:- pred output_layout_exec_trace(rtti_proc_label::in,
+	proc_layout_exec_trace::in, decl_set::in, decl_set::out,
+	io::di, io::uo) is det.
 
-output_layout_exec_trace_group(ProcLabel, ExecTrace) -->
-	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
+output_layout_exec_trace(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
+	ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
 		MaybeTableInfo, HeadVarNums, _VarNames, MaxVarNum,
 		MaxRegNum, MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
-		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot) },
-	io__write_string("{\nMR_LABEL_LAYOUT_REF("),
-	( { CallLabelLayout = label_layout(CallLabel, _) } ->
-		output_label(CallLabel, no)
-	;
-		{ error("output_layout_exec_trace_group: bad call layout") }
-	),
-	io__write_string("),\n(const MR_Module_Layout *) &"),
-	{ ModuleName = get_defining_module_name(ProcLabel) },
-	output_layout_name(module_layout(ModuleName)),
-	io__write_string(",\n"),
+		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot),
+	io__write_string("\n", !IO),
+	output_layout_name_storage_type_name(
+		proc_layout_exec_trace(RttiProcLabel), yes, !IO),
+	io__write_string(" = {\nMR_LABEL_LAYOUT_REF(", !IO),
+	( CallLabelLayout = label_layout(CallLabel, _) ->
+		output_label(CallLabel, no, !IO)
+	;
+		error("output_layout_exec_trace: bad call layout")
+	),
+	io__write_string("),\n(const MR_Module_Layout *) &", !IO),
+	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
+	ModuleName = get_defining_module_name(ProcLabel),
+	output_layout_name(module_layout(ModuleName), !IO),
+	io__write_string(",\n", !IO),
 	(
-		{ MaybeProcBody = yes(ProcBody) },
-		output_rval(ProcBody)
+		MaybeProcBody = yes(ProcBody),
+		output_rval(ProcBody, !IO)
 	;
-		{ MaybeProcBody = no },
-		io__write_int(0)
+		MaybeProcBody = no,
+		io__write_int(0, !IO)
 	),
-	io__write_string(",\n"),
+	io__write_string(",\n", !IO),
 	(
-		{ MaybeCallTableSlot = yes(_) },
-		io__write_string("&"),
-		output_tabling_pointer_var_name(ProcLabel)
+		MaybeCallTableSlot = yes(_),
+		io__write_string("&", !IO),
+		output_tabling_pointer_var_name(ProcLabel, !IO)
 	;
-		{ MaybeCallTableSlot = no },
-		io__write_string("NULL")
+		MaybeCallTableSlot = no,
+		io__write_string("NULL", !IO)
 	),
-	io__write_string(",\n{ "),
+	io__write_string(",\n{ ", !IO),
 	(
-		{ MaybeTableInfo = yes(TableInfo) },
-		io__write_string("(const void *) &"),
-		output_layout_name(TableInfo)
+		MaybeTableInfo = yes(TableInfo),
+		io__write_string("(const void *) &", !IO),
+		output_layout_name(TableInfo, !IO)
 	;
-		{ MaybeTableInfo = no },
-		io__write_string("NULL")
+		MaybeTableInfo = no,
+		io__write_string("NULL", !IO)
 	),
-	io__write_string(" },\n"),
-	output_layout_name(proc_layout_head_var_nums(ProcLabel)),
-	io__write_string(",\n"),
-	output_layout_name(proc_layout_var_names(ProcLabel)),
-	io__write_string(",\n"),
-	io__write_int(list__length(HeadVarNums)),
-	io__write_string(",\n"),
-	io__write_int(MaxVarNum),
-	io__write_string(",\n"),
-	io__write_int(MaxRegNum),
-	io__write_string(",\n"),
-	write_maybe_slot_num(MaybeFromFullSlot),
-	io__write_string(",\n"),
-	write_maybe_slot_num(MaybeIoSeqSlot),
-	io__write_string(",\n"),
-	write_maybe_slot_num(MaybeTrailSlot),
-	io__write_string(",\n"),
-	write_maybe_slot_num(MaybeMaxfrSlot),
-	io__write_string(",\n"),
-	io__write_string(eval_method_to_c_string(EvalMethod)),
-	io__write_string(",\n"),
-	write_maybe_slot_num(MaybeCallTableSlot),
-	io__write_string("\n}\n").
+	io__write_string(" },\n", !IO),
+	output_layout_name(proc_layout_head_var_nums(RttiProcLabel), !IO),
+	io__write_string(",\n", !IO),
+	output_layout_name(proc_layout_var_names(RttiProcLabel), !IO),
+	io__write_string(",\n", !IO),
+	io__write_int(list__length(HeadVarNums), !IO),
+	io__write_string(",\n", !IO),
+	io__write_int(MaxVarNum, !IO),
+	io__write_string(",\n", !IO),
+	io__write_int(MaxRegNum, !IO),
+	io__write_string(",\n", !IO),
+	write_maybe_slot_num(MaybeFromFullSlot, !IO),
+	io__write_string(",\n", !IO),
+	write_maybe_slot_num(MaybeIoSeqSlot, !IO),
+	io__write_string(",\n", !IO),
+	write_maybe_slot_num(MaybeTrailSlot, !IO),
+	io__write_string(",\n", !IO),
+	write_maybe_slot_num(MaybeMaxfrSlot, !IO),
+	io__write_string(",\n", !IO),
+	io__write_string(eval_method_to_c_string(EvalMethod), !IO),
+	io__write_string(",\n", !IO),
+	write_maybe_slot_num(MaybeCallTableSlot, !IO),
+	io__write_string("\n};\n", !IO).
 
 :- pred write_maybe_slot_num(maybe(int)::in, io::di, io::uo) is det.
 
@@ -877,54 +913,50 @@
 		Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL"
 	).
 
-:- pred output_proc_layout_head_var_nums(proc_label::in, list(int)::in,
+:- pred output_proc_layout_head_var_nums(rtti_proc_label::in, list(int)::in,
 	decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_proc_layout_head_var_nums(ProcLabel, HeadVarNums, !DeclSet) -->
-	io__write_string("\n"),
+output_proc_layout_head_var_nums(ProcLabel, HeadVarNums, !DeclSet, !IO) :-
+	io__write_string("\n", !IO),
 	output_layout_name_storage_type_name(
-		proc_layout_head_var_nums(ProcLabel), yes),
-	io__write_string(" = {\n"),
-	( { HeadVarNums = [] } ->
+		proc_layout_head_var_nums(ProcLabel), yes, !IO),
+	io__write_string(" = {\n", !IO),
+	(
+		HeadVarNums = [],
 			% ANSI/ISO C doesn't allow empty arrays, so
 			% place a dummy value in the array.
-		io__write_string("0\n")
+		io__write_string("0\n", !IO)
 	;
-		list__foldl(output_number_in_vector, HeadVarNums)
+		HeadVarNums = [_ | _],
+		list__foldl(output_number_in_vector, HeadVarNums, !IO)
 	),
-	io__write_string("};\n"),
-	{ decl_set_insert(data_addr(
-		layout_addr(proc_layout_head_var_nums(ProcLabel))),
-		!DeclSet) }.
+	io__write_string("};\n", !IO),
+	decl_set_insert(data_addr(
+		layout_addr(proc_layout_head_var_nums(ProcLabel))), !DeclSet).
 
-:- pred output_proc_layout_var_names(proc_label::in, list(int)::in, int::in,
-	decl_set::in, decl_set::out, io::di, io::uo) is det.
+:- pred output_proc_layout_var_names(rtti_proc_label::in, list(int)::in,
+	int::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_proc_layout_var_names(ProcLabel, VarNames, MaxVarNum,
-		!DeclSet) -->
-	{ list__length(VarNames, VarNameCount) },
-	{ require(unify(VarNameCount, MaxVarNum),
-		"output_proc_layout_var_names: VarNameCount != MaxVarNum") },
-	io__write_string("\n"),
+output_proc_layout_var_names(ProcLabel, VarNames, MaxVarNum, !DeclSet, !IO) :-
+	list__length(VarNames, VarNameCount),
+	require(unify(VarNameCount, MaxVarNum),
+		"output_proc_layout_var_names: VarNameCount != MaxVarNum"),
+	io__write_string("\n", !IO),
 	output_layout_name_storage_type_name(proc_layout_var_names(ProcLabel),
-		yes),
-	io__write_string(" = {\n"),
-	( { VarNames = [] } ->
+		yes, !IO),
+	io__write_string(" = {\n", !IO),
+	(
+		VarNames = [],
 			% ANSI/ISO C doesn't allow empty arrays, so
 			% place a dummy value in the array.
-		io__write_string("0\n")
+		io__write_string("0\n", !IO)
 	;
-		list__foldl(output_number_in_vector, VarNames)
+		VarNames = [_ | _],
+		list__foldl(output_number_in_vector, VarNames, !IO)
 	),
-	io__write_string("};\n"),
-	{ decl_set_insert(data_addr(
-		layout_addr(proc_layout_var_names(ProcLabel))),
-		!DeclSet) }.
-
-:- pred output_layout_no_exec_trace_group(io::di, io::uo) is det.
-
-output_layout_no_exec_trace_group -->
-	io__write_string("0\n").
+	io__write_string("};\n", !IO),
+	decl_set_insert(data_addr(
+		layout_addr(proc_layout_var_names(ProcLabel))), !DeclSet).
 
 %-----------------------------------------------------------------------------%
 
@@ -1073,9 +1105,10 @@
 	is det.
 
 output_proc_layout_name_in_vector(LayoutName, !IO) :-
-	( LayoutName = proc_layout(Label, _) ->
+	( LayoutName = proc_layout(RttiProcLabel, _) ->
+		ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
 		io__write_string("MR_PROC_LAYOUT1(", !IO),
-		output_proc_label(Label, no, !IO),
+		output_proc_label(ProcLabel, no, !IO),
 		io__write_string(")\n", !IO)
 	;
 		error("output_proc_layout_name_in_vector: not proc layout")
@@ -1350,20 +1383,22 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_proc_static_data_defn(rtti_proc_label::in, string::in,
-	int::in, bool::in, list(call_site_static_data)::in,
-	decl_set::in, decl_set::out, io::di, io::uo) is det.
+:- pred output_proc_static_data_defn(rtti_proc_label::in,
+	proc_layout_proc_static::in, decl_set::in, decl_set::out,
+	io::di, io::uo) is det.
 
-output_proc_static_data_defn(RttiProcLabel, FileName, LineNumber,
-		IsInInterface, CallSites, !DeclSet, !IO) :-
+output_proc_static_data_defn(RttiProcLabel, ProcLayoutProcStatic,
+		!DeclSet, !IO) :-
+	ProcLayoutProcStatic = proc_layout_proc_static(HLDSProcStatic,
+		DeepExcpVars),
+	HLDSProcStatic = hlds_proc_static(FileName, LineNumber, IsInInterface,
+		CallSites),
 	list__foldl2(output_call_site_static_decl, CallSites, !DeclSet, !IO),
 	output_call_site_static_array(RttiProcLabel, CallSites, !DeclSet, !IO),
 	LayoutName = proc_static(RttiProcLabel),
 	io__write_string("\n", !IO),
 	output_layout_name_storage_type_name(LayoutName, yes, !IO),
 	io__write_string(" = {\n", !IO),
-	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-	output_layout_proc_id_group(ProcLabel, !IO),
 	quote_and_write_string(FileName, !IO),
 	io__write_string(",\n", !IO),
 	io__write_int(LineNumber, !IO),
@@ -1383,7 +1418,15 @@
 	io__write_string(",\n#ifdef MR_USE_ACTIVATION_COUNTS\n", !IO),
 	io__write_string("0,\n", !IO),
 	io__write_string("#endif\n", !IO),
-	io__write_string("NULL\n};\n", !IO),
+	io__write_string("NULL,\n", !IO),
+	DeepExcpVars = deep_excp_slots(TopCSDSlot, MiddleCSDSlot,
+		OldOutermostSlot),
+	io__write_int(TopCSDSlot, !IO),
+	io__write_string(",\n\t", !IO),
+	io__write_int(MiddleCSDSlot, !IO),
+	io__write_string(",\n\t", !IO),
+	io__write_int(OldOutermostSlot, !IO),
+	io__write_string("\n};\n", !IO),
 	decl_set_insert(data_addr(layout_addr(LayoutName)), !DeclSet).
 
 :- pred output_call_site_static_array(rtti_proc_label::in,
@@ -1409,9 +1452,12 @@
 	(
 		CallSiteStatic = normal_call(Callee, TypeSubst,
 			FileName, LineNumber, GoalPath),
-		io__write_string("MR_normal_call, (MR_ProcStatic *)\n&",
+		io__write_string("MR_normal_call, (MR_Proc_Layout *)\n&",
 			!IO),
-		output_layout_name(proc_static(Callee), !IO),
+		CalleeProcLabel = make_proc_label_from_rtti(Callee),
+		CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
+		output_layout_name(proc_layout(Callee,
+			proc_layout_proc_id(CalleeUserOrUci)), !IO),
 		( TypeSubst = "" ->
 			io__write_string(", NULL, ", !IO)
 		;
@@ -1449,7 +1495,10 @@
 output_call_site_static_decl(CallSiteStatic, !DeclSet, !IO) :-
 	(
 		CallSiteStatic = normal_call(Callee, _, _, _, _),
-		output_maybe_layout_name_decl(proc_static(Callee),
+		CalleeProcLabel = make_proc_label_from_rtti(Callee),
+		CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
+		output_maybe_layout_name_decl(proc_layout(Callee,
+			proc_layout_proc_id(CalleeUserOrUci)),
 			!DeclSet, !IO)
 	;
 		CallSiteStatic = special_call(_, _, _)
@@ -1471,8 +1520,7 @@
 		PTIVectorRval, TypeParamsRval, !DeclSet, !IO) :-
 	output_rval_decls(PTIVectorRval, !DeclSet, !IO),
 	LayoutName = table_io_decl(RttiProcLabel),
-	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-	ProcLayoutName = proc_layout(ProcLabel, ProcLayoutKind),
+	ProcLayoutName = proc_layout(RttiProcLabel, ProcLayoutKind),
 	output_layout_decl(ProcLayoutName, !DeclSet, !IO),
 
 	io__write_string("\n", !IO),
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.230
diff -u -b -r1.230 llds_out.m
--- compiler/llds_out.m	16 May 2004 03:54:31 -0000	1.230
+++ compiler/llds_out.m	19 May 2004 03:54:28 -0000
@@ -713,7 +713,8 @@
 		Data = layout_data(LayoutData),
 		LayoutData = module_layout_data(ModuleName, _,_,_,_,_,_)
 	->
-		io__write_string("\tif (MR_register_module_layout != NULL) {\n",
+		io__write_string(
+			"\tif (MR_register_module_layout != NULL) {\n",
 			!IO),
 		io__write_string("\t\t(*MR_register_module_layout)(", !IO),
 		io__write_string("\n\t\t\t&", !IO),
@@ -731,7 +732,8 @@
 output_write_proc_static_list_decls([Data | Datas], !DeclSet, !IO) :-
 	(
 		Data = layout_data(LayoutData),
-		LayoutData = proc_static_data(_, _, _, _, _)
+		LayoutData = proc_layout_data(_, _, MaybeRest),
+		MaybeRest = proc_id(yes(_), _)
 	->
 		output_maybe_layout_data_decl(LayoutData, !DeclSet, !IO)
 	;
@@ -746,11 +748,24 @@
 output_write_proc_static_list([Data | Datas], !IO) :-
 	(
 		Data = layout_data(LayoutData),
-		LayoutData = proc_static_data(RttiProcLabel, _, _, _, _)
+		LayoutData = proc_layout_data(RttiProcLabel, _, MaybeRest),
+		MaybeRest = proc_id(yes(_), _)
 	->
-		io__write_string("\tMR_write_out_proc_static(fp, ", !IO),
-		io__write_string("(MR_ProcStatic *)\n\t\t&", !IO),
-		output_layout_name(proc_static(RttiProcLabel), !IO),
+		ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
+		UserOrUCI = proc_label_user_or_uci(ProcLabel),
+		Kind = proc_layout_proc_id(UserOrUCI),
+		(
+			UserOrUCI = user,
+			io__write_string(
+				"\tMR_write_out_user_proc_static(fp,\n\t\t&",
+				!IO)
+		;
+			UserOrUCI = uci,
+			io__write_string(
+				"\tMR_write_out_uci_proc_static(fp,\n\t\t&",
+				!IO)
+		),
+		output_layout_name(proc_layout(RttiProcLabel, Kind), !IO),
 		io__write_string(");\n", !IO)
 	;
 		true
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.306
diff -u -b -r1.306 mercury_compile.m
--- compiler/mercury_compile.m	14 May 2004 08:40:25 -0000	1.306
+++ compiler/mercury_compile.m	19 May 2004 03:54:28 -0000
@@ -1484,8 +1484,7 @@
 	globals__io_lookup_bool_option(statistics, Stats, !IO),
 	mercury_compile__maybe_output_prof_call_graph(Verbose, Stats,
 		HLDS21, HLDS25, !IO),
-	mercury_compile__middle_pass(ModuleName, HLDS25, HLDS50,
-		DeepProfilingStructures, !IO),
+	mercury_compile__middle_pass(ModuleName, HLDS25, HLDS50, !IO),
 	globals__io_lookup_bool_option(highlevel_code, HighLevelCode, !IO),
 	globals__io_lookup_bool_option(aditi_only, AditiOnly, !IO),
 	globals__io_get_target(Target, !IO),
@@ -1617,8 +1616,7 @@
 			FactTableBaseFiles = []
 		;
 			mercury_compile__backend_pass(HLDS50, HLDS,
-				DeepProfilingStructures, GlobalData, LLDS,
-				!IO),
+				GlobalData, LLDS, !IO),
 			mercury_compile__output_pass(HLDS, GlobalData, LLDS,
 				MaybeRLFile, ModuleName, _CompileErrors,
 				FactTableBaseFiles, !IO)
@@ -2241,9 +2239,9 @@
 %-----------------------------------------------------------------------------%
 
 :- pred mercury_compile__middle_pass(module_name::in, module_info::in,
-	module_info::out, list(layout_data)::out, io::di, io::uo) is det.
+	module_info::out, io::di, io::uo) is det.
 
-mercury_compile__middle_pass(ModuleName, !HLDS, DeepProfilingStructs, !IO) :-
+mercury_compile__middle_pass(ModuleName, !HLDS, !IO) :-
 	globals__io_lookup_bool_option(verbose, Verbose, !IO),
 	globals__io_lookup_bool_option(statistics, Stats, !IO),
 
@@ -2350,8 +2348,7 @@
 	% Deep profiling transformation should be done late in the piece
 	% since it munges the code a fair amount and introduces strange
 	% disjunctions that might confuse other hlds->hlds transformations.
-	mercury_compile__maybe_deep_profiling(Verbose, Stats, !HLDS,
-		DeepProfilingStructs, !IO),
+	mercury_compile__maybe_deep_profiling(Verbose, Stats, !HLDS, !IO),
 	mercury_compile__maybe_dump_hlds(!.HLDS, "50", "deep_profiling", !IO),
 
 	mercury_compile__maybe_dump_hlds(!.HLDS, "51", "middle_pass", !IO).
@@ -2419,18 +2416,16 @@
 %-----------------------------------------------------------------------------%
 
 :- pred mercury_compile__backend_pass(module_info::in, module_info::out,
-	list(layout_data)::in, global_data::out, list(c_procedure)::out,
+	global_data::out, list(c_procedure)::out,
 	io::di, io::uo) is det.
 
-mercury_compile__backend_pass(!HLDS, DeepProfilingStructures,
-		GlobalData, LLDS, !IO) :-
+mercury_compile__backend_pass(!HLDS, GlobalData, LLDS, !IO) :-
 	module_info_name(!.HLDS, ModuleName),
 	globals__io_lookup_bool_option(unboxed_float, UnboxFloat, !IO),
 	globals__io_lookup_bool_option(common_data, DoCommonData, !IO),
 	StaticCellInfo0 = init_static_cell_info(ModuleName, UnboxFloat,
 		DoCommonData),
-	global_data_init(DeepProfilingStructures, StaticCellInfo0,
-		GlobalData0),
+	global_data_init(StaticCellInfo0, GlobalData0),
 
 	globals__io_lookup_bool_option(verbose, Verbose, !IO),
 	globals__io_lookup_bool_option(statistics, Stats, !IO),
@@ -3447,22 +3442,19 @@
 	).
 
 :- pred mercury_compile__maybe_deep_profiling(bool::in, bool::in,
-	module_info::in, module_info::out, list(layout_data)::out,
-	io::di, io::uo) is det.
+	module_info::in, module_info::out, io::di, io::uo) is det.
 
-mercury_compile__maybe_deep_profiling(Verbose, Stats, !HLDS,
-		DeepProfStructs, !IO) :-
-	globals__io_lookup_bool_option(profile_deep, Dead, !IO),
-	( Dead = yes ->
+mercury_compile__maybe_deep_profiling(Verbose, Stats, !HLDS, !IO) :-
+	globals__io_lookup_bool_option(profile_deep, ProfileDeep, !IO),
+	( ProfileDeep = yes ->
 		maybe_write_string(Verbose,
 			"% Applying deep profiling transformation...\n", !IO),
 		maybe_flush_output(Verbose, !IO),
-		apply_deep_profiling_transformation(!HLDS, DeepProfStructs,
-			!IO),
+		apply_deep_profiling_transformation(!HLDS),
 		maybe_write_string(Verbose, "% done.\n", !IO),
 		maybe_report_stats(Stats, !IO)
 	;
-		DeepProfStructs = []
+		true
 	).
 
 :- pred mercury_compile__maybe_introduce_accumulators(bool::in, bool::in,
@@ -3757,7 +3749,6 @@
 	% XXX We assume that the foreign language we use is C
 	get_c_interface_info(HLDS, c, C_InterfaceInfo),
 	global_data_get_all_proc_vars(GlobalData, GlobalVars),
-	global_data_get_all_deep_prof_data(GlobalData, DeepProfData),
 	global_data_get_all_closure_layouts(GlobalData, ClosureLayouts),
 	global_data_get_static_cell_info(GlobalData, StaticCellInfo),
 	StaticCells = get_static_cells(StaticCellInfo),
@@ -3766,7 +3757,7 @@
 	% Next we put it all together and output it to one or more C files.
 	%
 	list__condense([StaticCells, ClosureLayouts, StackLayouts,
-		DeepProfData, TypeCtorTables, TypeClassInfos], AllData),
+		TypeCtorTables, TypeClassInfos], AllData),
 	mercury_compile__construct_c_file(HLDS, C_InterfaceInfo,
 		Procs, GlobalVars, AllData, CFile, NumChunks, !IO),
 	mercury_compile__output_llds(ModuleName, CFile, LayoutLabels,
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.239
diff -u -b -r1.239 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	12 May 2004 14:24:27 -0000	1.239
+++ compiler/mercury_to_mercury.m	19 May 2004 03:54:28 -0000
@@ -1577,8 +1577,8 @@
 	add_string("<typeclass_info_cell_constructor>").
 mercury_format_cons_id(tabling_pointer_const(_, _), _) -->
 	add_string("<tabling pointer>").
-mercury_format_cons_id(deep_profiling_proc_static(_), _) -->
-	add_string("<deep_profiling_proc_static>").
+mercury_format_cons_id(deep_profiling_proc_layout(_), _) -->
+	add_string("<deep_profiling_proc_layout>").
 mercury_format_cons_id(table_io_decl(_), _) -->
 	add_string("<table_io_decl>").
 
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.80
diff -u -b -r1.80 ml_code_util.m
--- compiler/ml_code_util.m	23 Mar 2004 10:52:08 -0000	1.80
+++ compiler/ml_code_util.m	19 May 2004 03:54:28 -0000
@@ -16,7 +16,6 @@
 :- interface.
 
 :- import_module backend_libs__builtin_ops.
-:- import_module backend_libs__rtti.
 :- import_module hlds__code_model.
 :- import_module hlds__hlds_module.
 :- import_module hlds__hlds_pred.
@@ -742,6 +741,7 @@
 :- implementation.
 
 :- import_module backend_libs__foreign.
+:- import_module backend_libs__rtti.
 :- import_module check_hlds__mode_util.
 :- import_module check_hlds__polymorphism.
 :- import_module check_hlds__type_util.
@@ -1090,10 +1090,11 @@
 	%
 ml_gen_proc_params_from_rtti(ModuleInfo, RttiProcId) = FuncParams :-
 	HeadVars = RttiProcId ^ proc_headvars,
-	ArgTypes = RttiProcId ^ arg_types,
+	ArgTypes = RttiProcId ^ proc_arg_types,
 	ArgModes = RttiProcId ^ proc_arg_modes,
-	PredOrFunc = RttiProcId ^ pred_or_func,
-	CodeModel = RttiProcId ^ proc_interface_code_model,
+	PredOrFunc = RttiProcId^pred_or_func,
+	Detism = RttiProcId^proc_interface_detism,
+	determinism_to_code_model(Detism, CodeModel),
 	HeadVarNames = list__map((func(Var - Name) = Result :-
 			term__var_to_int(Var, N),
 			Result = mlds__var_name(Name, yes(N))
@@ -1380,12 +1381,10 @@
 		MLDS_Module) :-
 	RttiProcLabel = rtti_proc_label(PredOrFunc, ThisModule, PredModule,
 		PredName, PredArity, _ArgTypes, PredId, ProcId,
-		_HeadVarsWithNames, _ArgModes, CodeModel,
-		IsImported, _IsPseudoImported, _IsExported,
-		IsSpecialPredInstance),
-	(
-		IsSpecialPredInstance = yes(SpecialPred - TypeCtor)
-	->
+		_HeadVarsWithNames, _ArgModes, Detism,
+		PredIsImported, _PredIsPseudoImported,
+		IsSpecialPred, _ProcIsExported, _ProcIsImported),
+	( IsSpecialPred = yes(SpecialPred - TypeCtor) ->
 		(
 			% All type_ctors other than tuples here should be
 			% module qualified, since builtin types are handled
@@ -1428,7 +1427,7 @@
 			% Work out which module supplies the code for
 			% the predicate.
 			ThisModule \= PredModule,
-			IsImported = no
+			PredIsImported = no
 		->
 			% This predicate is a specialized version of
 			% a pred from a `.opt' file.
@@ -1449,6 +1448,7 @@
 		;
 			NonOutputFunc = no
 		),
+		determinism_to_code_model(Detism, CodeModel),
 		MLDS_PredLabel = pred(PredOrFunc, MaybeDeclaringModule,
 			PredName, PredArity, CodeModel, NonOutputFunc)
 	),
Index: compiler/ml_unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.74
diff -u -b -r1.74 ml_unify_gen.m
--- compiler/ml_unify_gen.m	5 Apr 2004 05:07:41 -0000	1.74
+++ compiler/ml_unify_gen.m	19 May 2004 03:54:28 -0000
@@ -431,9 +431,9 @@
 	DataAddr = data_addr(PredModule, tabling_pointer(PredLabel - ProcId)),
 	Rval = unop(cast(MLDS_VarType), const(data_addr_const(DataAddr))).
 
-ml_gen_constant(deep_profiling_proc_static_tag(_), _, _, !Info) :-
+ml_gen_constant(deep_profiling_proc_layout_tag(_), _, _, !Info) :-
 	error("ml_gen_constant: " ++
-		"deep_profiling_proc_static_tag not yet supported").
+		"deep_profiling_proc_layout_tag not yet supported").
 
 ml_gen_constant(table_io_decl_tag(_), _, _, !Info) :-
 	error("ml_gen_constant: table_io_decl_tag not yet supported").
@@ -1325,7 +1325,7 @@
 		Tag = tabling_pointer_constant(_, _),
 		Statements = []
 	;
-		Tag = deep_profiling_proc_static_tag(_),
+		Tag = deep_profiling_proc_layout_tag(_),
 		Statements = []
 	;
 		Tag = table_io_decl_tag(_),
@@ -1443,7 +1443,7 @@
 		Tag = tabling_pointer_constant(_, _),
 		error("ml_tag_offset_and_argnum")
 	;
-		Tag = deep_profiling_proc_static_tag(_),
+		Tag = deep_profiling_proc_layout_tag(_),
 		error("ml_tag_offset_and_argnum")
 	;
 		Tag = table_io_decl_tag(_),
@@ -1761,9 +1761,9 @@
 ml_gen_tag_test_rval(tabling_pointer_constant(_, _), _, _, _) = _ :-
 	% This should never happen
 	error("Attempted tabling_pointer unification").
-ml_gen_tag_test_rval(deep_profiling_proc_static_tag(_), _, _, _) = _ :-
+ml_gen_tag_test_rval(deep_profiling_proc_layout_tag(_), _, _, _) = _ :-
 	% This should never happen
-	error("Attempted deep_profiling_proc_static unification").
+	error("Attempted deep_profiling_proc_layout unification").
 ml_gen_tag_test_rval(table_io_decl_tag(_), _, _, _) = _ :-
 	% This should never happen
 	error("Attempted table_io_decl unification").
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.139
diff -u -b -r1.139 opt_debug.m
--- compiler/opt_debug.m	24 Mar 2004 02:57:12 -0000	1.139
+++ compiler/opt_debug.m	19 May 2004 03:54:28 -0000
@@ -514,15 +514,19 @@
 	),
 	string__append_list(["label_layout(", LabelStr, ", ",
 		LabelVarsStr, ")"], Str).
-opt_debug__dump_layout_name(proc_layout(ProcLabel, _), Str) :-
-	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
+opt_debug__dump_layout_name(proc_layout(RttiProcLabel, _), Str) :-
+	opt_debug__dump_rttiproclabel(RttiProcLabel, ProcLabelStr),
 	string__append_list(["proc_layout(", ProcLabelStr, ")"], Str).
-opt_debug__dump_layout_name(proc_layout_head_var_nums(ProcLabel), Str) :-
-	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
+opt_debug__dump_layout_name(proc_layout_exec_trace(RttiProcLabel), Str) :-
+	opt_debug__dump_rttiproclabel(RttiProcLabel, ProcLabelStr),
+	string__append_list(["proc_layout_exec_trace(", ProcLabelStr, ")"],
+		Str).
+opt_debug__dump_layout_name(proc_layout_head_var_nums(RttiProcLabel), Str) :-
+	opt_debug__dump_rttiproclabel(RttiProcLabel, ProcLabelStr),
 	string__append_list(["proc_layout_head_var_nums(", ProcLabelStr, ")"],
 		Str).
-opt_debug__dump_layout_name(proc_layout_var_names(ProcLabel), Str) :-
-	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
+opt_debug__dump_layout_name(proc_layout_var_names(RttiProcLabel), Str) :-
+	opt_debug__dump_rttiproclabel(RttiProcLabel, ProcLabelStr),
 	string__append_list(["proc_layout_var_names(", ProcLabelStr, ")"],
 		Str).
 opt_debug__dump_layout_name(closure_proc_id(ProcLabel, SeqNo, _), Str) :-
@@ -667,6 +671,12 @@
 	opt_debug__dump_label(L2, L2_str),
 	opt_debug__dump_label_pairs(Labels, L_str),
 	string__append_list([" ", L1_str, "-", L2_str, L_str], Str).
+
+:- pred opt_debug__dump_rttiproclabel(rtti_proc_label::in, string::out) is det.
+
+opt_debug__dump_rttiproclabel(RttiProcLabel, Str) :-
+	ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
+	opt_debug__dump_proclabel(ProcLabel, Str).
 
 opt_debug__dump_proclabel(proc(Module, _PredOrFunc, PredModule,
 		PredName, Arity, ProcId), Str) :-
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.423
diff -u -b -r1.423 options.m
--- compiler/options.m	10 Feb 2004 12:43:31 -0000	1.423
+++ compiler/options.m	19 May 2004 03:54:28 -0000
@@ -197,15 +197,10 @@
 		% Compilation model options for optional features:
 
 		%   (a) Debugging
-		%	For documentation of the stack_trace, require_tracing,
-		%	and decl_debug options, see the documentation for
-		%	MR_STACK_TRACE, MR_REQUIRE_TRACING, and MR_DECL_DEBUG
-		%	in runtime/mercury_conf_param.h.
-		%	The debug option just means both stack_trace and
-		%	require_tracing.
-		;	debug
-		;	stack_trace
-		;	require_tracing
+		%	For documentation of the exec_trace and decl_debug
+		%	options, see the documentation for MR_EXEC_TRACE
+		%	and MR_DECL_DEBUG in runtime/mercury_conf_param.h.
+		;	exec_trace
 		;	decl_debug
 
 		%   (b) Profiling
@@ -299,6 +294,7 @@
 				% The foreign programming languages that this
 				% backend can interface to.
 		; 	backend_foreign_languages
+		;	stack_trace
 				% Stack layout information required to do
 				% a stack trace.
 		;       basic_stack_layout
@@ -865,9 +861,7 @@
 
 		% Optional feature compilation model options:
 		% (a) Debuggging
-	debug			-	bool_special,
-	stack_trace		-	bool(no),
-	require_tracing		-	bool(no),
+	exec_trace		-	bool(no),
 	decl_debug		-	bool(no),
 		% (b) Profiling
 	profiling		-	bool_special,
@@ -884,7 +878,7 @@
 	use_lots_of_ho_specialization
 				-	bool(no),
 	deep_profile_tail_recursion
-				-	bool(yes),
+				-	bool(no),
 	record_term_sizes_as_words -	bool(no),
 	record_term_sizes_as_cells -	bool(no),
 		% (c) Miscellaneous optional features
@@ -948,6 +942,7 @@
 					% The backend_foreign_languages option
 					% depends on the target and is set in
 					% handle_options.
+	stack_trace		-	bool(no),
 	basic_stack_layout	-	bool(no),
 	agc_stack_layout	-	bool(no),
 	procid_stack_layout	-	bool(no),
@@ -1505,11 +1500,7 @@
 long_option("Java-only",                java_only).
 	% Optional features compilation model options:
 	% (a) debugging
-long_option("debug",			debug).
-% The following options are not allowed, because they're
-% not very useful and would probably only confuse people.
-% long_option("stack-trace",		stack_trace).
-% long_option("require-tracing",	require_tracing).
+long_option("debug",			exec_trace).
 long_option("decl-debug",       	decl_debug).
 	% (b) profiling
 long_option("profiling",		profiling).
@@ -2018,9 +2009,6 @@
 	map__set(OptionTable1, profile_calls, bool(no), OptionTable2),
         map__set(OptionTable2, profile_memory, bool(no), OptionTable3),
         map__set(OptionTable3, profile_deep, bool(yes), OptionTable).
-special_handler(debug, bool(Value), OptionTable0, ok(OptionTable)) :-
-	map__set(OptionTable0, stack_trace, bool(Value), OptionTable1),
-	map__set(OptionTable1, require_tracing, bool(Value), OptionTable).
 special_handler(inlining, bool(Value), OptionTable0, ok(OptionTable)) :-
 	map__set(OptionTable0, inline_simple, bool(Value), OptionTable1),
 	map__set(OptionTable1, inline_builtins, bool(Value), OptionTable2),
Index: compiler/proc_label.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/proc_label.m,v
retrieving revision 1.3
diff -u -b -r1.3 proc_label.m
--- compiler/proc_label.m	27 May 2003 05:57:18 -0000	1.3
+++ compiler/proc_label.m	19 May 2004 03:54:28 -0000
@@ -18,7 +18,6 @@
 
 :- interface. 
 
-:- import_module backend_libs__rtti.
 :- import_module hlds__hlds_module.
 :- import_module hlds__hlds_pred.
 :- import_module hlds__special_pred.
@@ -89,9 +88,9 @@
 	RttiProcLabel = rtti_proc_label(PredOrFunc, ThisModule,
 		PredModule, PredName, PredArity, _ArgTypes, _PredId, ProcId,
 		_ProcHeadVarsWithNames, _ArgModes, _CodeModel,
-		IsImported, _IsPseudoImported, _IsExported,
-		IsSpecialPredInstance),
-	( IsSpecialPredInstance = yes(SpecialPred - TypeCtor) ->
+		PredIsImported, _PredIsPseudoImported, IsSpecialPred,
+		_ProcIsExported, _ProcIsImported),
+	( IsSpecialPred = yes(SpecialPred - TypeCtor) ->
 		(
 			% All type_ctors other than tuples here should be
 			% module qualified, since builtin types are
@@ -123,7 +122,7 @@
 			error(ErrorMessage)
 		)
 	;
-		ProcLabel = make_user_proc_label(ThisModule, IsImported,
+		ProcLabel = make_user_proc_label(ThisModule, PredIsImported,
 			PredOrFunc, PredModule, PredName, PredArity, ProcId)
 	).
 
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.23
diff -u -b -r1.23 prog_rep.m
--- compiler/prog_rep.m	1 Dec 2003 15:55:47 -0000	1.23
+++ compiler/prog_rep.m	19 May 2004 03:54:28 -0000
@@ -111,7 +111,7 @@
 	Rep = "$typeclass_info_cell_constructor".
 prog_rep__represent_cons_id(tabling_pointer_const(_, _), Rep) :-
 	Rep = "$tabling_pointer_const".
-prog_rep__represent_cons_id(deep_profiling_proc_static(_), Rep) :-
+prog_rep__represent_cons_id(deep_profiling_proc_layout(_), Rep) :-
 	Rep = "$deep_profiling_procedure_data".
 prog_rep__represent_cons_id(table_io_decl(_), Rep) :-
 	Rep = "$table_io_decl".
Index: compiler/rl_exprn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_exprn.m,v
retrieving revision 1.39
diff -u -b -r1.39 rl_exprn.m
--- compiler/rl_exprn.m	14 May 2004 08:40:27 -0000	1.39
+++ compiler/rl_exprn.m	19 May 2004 03:54:28 -0000
@@ -524,7 +524,7 @@
 rl_exprn__set_term_arg_cons_id_code(tabling_pointer_const(_, _),
 		_, _, _, _, _, _) -->
 	{ error("rl_exprn__set_term_arg_cons_id_code") }.
-rl_exprn__set_term_arg_cons_id_code(deep_profiling_proc_static(_),
+rl_exprn__set_term_arg_cons_id_code(deep_profiling_proc_layout(_),
 		_, _, _, _, _, _) -->
 	{ error("rl_exprn__set_term_arg_cons_id_code") }.
 rl_exprn__set_term_arg_cons_id_code(table_io_decl(_),
@@ -1166,23 +1166,28 @@
 		{ Code = empty }
 	; 
 		{ ConsId = base_typeclass_info_const(_, _, _, _) },
-		{ error("rl_exprn__unify: unsupported cons_id - base_typeclass_info_const") }
+		{ error("rl_exprn__unify: unsupported cons_id - " ++
+			"base_typeclass_info_const") }
 	; 
 		{ ConsId = type_info_cell_constructor(_) },
 		% XXX for now we ignore these and hope it doesn't matter.
 		{ Code = empty }
 	; 
 		{ ConsId = typeclass_info_cell_constructor },
-		{ error("rl_exprn__unify: unsupported cons_id - typeclass_info_cell_constructor") }
+		{ error("rl_exprn__unify: unsupported cons_id - " ++
+			"typeclass_info_cell_constructor") }
 	; 
 		{ ConsId = tabling_pointer_const(_, _) },
-		{ error("rl_exprn__unify: unsupported cons_id - tabling_pointer_const") }
+		{ error("rl_exprn__unify: unsupported cons_id - " ++
+			"tabling_pointer_const") }
 	; 
-		{ ConsId = deep_profiling_proc_static(_) },
-		{ error("rl_exprn__unify: unsupported cons_id - deep_profiling_proc_static") }
+		{ ConsId = deep_profiling_proc_layout(_) },
+		{ error("rl_exprn__unify: unsupported cons_id - " ++
+			"deep_profiling_proc_layout") }
 	; 
 		{ ConsId = table_io_decl(_) },
-		{ error("rl_exprn__unify: unsupported cons_id - table_io_decl") }
+		{ error("rl_exprn__unify: unsupported cons_id - " ++
+			"table_io_decl") }
 	).
 		
 rl_exprn__unify(deconstruct(Var, ConsId, Args, UniModes, CanFail, _CanCGC),
Index: compiler/rtti.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti.m,v
retrieving revision 1.47
diff -u -b -r1.47 rtti.m
--- compiler/rtti.m	8 Apr 2004 05:35:08 -0000	1.47
+++ compiler/rtti.m	19 May 2004 03:54:28 -0000
@@ -24,14 +24,12 @@
 
 :- interface.
 
-:- import_module hlds__code_model.
 :- import_module hlds__hlds_data.
 :- import_module hlds__hlds_module.
 :- import_module hlds__hlds_pred.
-:- import_module hlds__special_pred.
 :- import_module parse_tree__prog_data.
 
-:- import_module assoc_list, bool, list, set, map, std_util.
+:- import_module bool, list, set, map, std_util.
 
 %-----------------------------------------------------------------------------%
 %
@@ -506,50 +504,6 @@
 		).
 
 %-----------------------------------------------------------------------------%
-
-:- type prog_var_name == string.
-
-	% The rtti_proc_label type holds all the information about a procedure
-	% that we need to compute the entry label for that procedure
-	% in the target language (the llds__code_addr or mlds__code_addr).
-:- type rtti_proc_label --->
-	rtti_proc_label(
-		pred_or_func		::	pred_or_func,
-		this_module		::	module_name,
-		pred_module		::	module_name,
-		pred_name		::	string,
-		arity			::	arity,
-		arg_types		::	list(type),
-		pred_id			::	pred_id,
-		proc_id			::	proc_id,
-		proc_headvars		::	assoc_list(prog_var,
-							prog_var_name),
-		proc_arg_modes		::	list(arg_mode),
-		proc_interface_code_model ::	code_model,
-		%
-		% The following booleans hold values computed from the
-		% pred_info, using procedures
-		%	pred_info_is_imported/1,
-		%	pred_info_is_pseudo_imported/1,
-		%	procedure_is_exported/2, and
-		%	pred_info_get_maybe_special_pred/1
-		% respectively.
-		% We store booleans here, rather than storing the
-		% pred_info, to avoid retaining a reference to the
-		% parts of the pred_info that we aren't interested in,
-		% so that those parts can be garbage collected.
-		% We use booleans rather than an import_status
-		% so that we can continue to use the above-mentioned
-		% abstract interfaces rather than hard-coding tests
-		% on the import_status.
-		%
-		is_imported		::	bool,
-		is_pseudo_imported	::	bool,
-		is_exported		::	bool,
-		maybe_special_pred	::	maybe(special_pred)
-	).
-
-%-----------------------------------------------------------------------------%
 %
 % The data structures representing the top-level global data structures
 % generated by the Mercury compiler. Usually readonly, with one exception:
@@ -983,24 +937,37 @@
 	proc_info_varset(ProcInfo, ProcVarSet),
 	proc_info_headvars(ProcInfo, ProcHeadVars),
 	proc_info_argmodes(ProcInfo, ProcModes),
-	proc_info_interface_code_model(ProcInfo, ProcCodeModel),
+	proc_info_interface_determinism(ProcInfo, ProcDetism),
 	modes_to_arg_modes(ModuleInfo, ProcModes, ArgTypes, ProcArgModes),
-	IsImported = (pred_info_is_imported(PredInfo) -> yes ; no),
-	IsPseudoImp = (pred_info_is_pseudo_imported(PredInfo) -> yes ; no),
-	IsExported = (procedure_is_exported(ModuleInfo, PredInfo, ProcId)
+	PredIsImported = (pred_info_is_imported(PredInfo) -> yes ; no),
+	PredIsPseudoImp = (pred_info_is_pseudo_imported(PredInfo) -> yes ; no),
+	ProcIsExported = (procedure_is_exported(ModuleInfo, PredInfo, ProcId)
 		-> yes ; no),
-	pred_info_get_maybe_special_pred(PredInfo, MaybeSpecial),
+	pred_info_get_maybe_special_pred(PredInfo, PredMaybeSpecial),
 	ProcHeadVarsWithNames = list__map((func(Var) = Var - Name :-
 			Name = varset__lookup_name(ProcVarSet, Var)
 		), ProcHeadVars),
+	(
+		(
+			PredIsImported = yes
+		;
+			PredIsPseudoImp = yes,
+			hlds_pred__in_in_unification_proc_id(ProcId)
+		)
+	->
+		ProcIsImported = yes
+	;
+		ProcIsImported = no
+	),
 	ProcLabel = rtti_proc_label(PredOrFunc, ThisModule, PredModule,
 		PredName, Arity, ArgTypes, PredId, ProcId,
-		ProcHeadVarsWithNames, ProcArgModes, ProcCodeModel,
-		IsImported, IsPseudoImp, IsExported, MaybeSpecial).
+		ProcHeadVarsWithNames, ProcArgModes, ProcDetism,
+		PredIsImported, PredIsPseudoImp, PredMaybeSpecial,
+		ProcIsExported, ProcIsImported).
 
 rtti__proc_label_pred_proc_id(ProcLabel, PredId, ProcId) :-
-	ProcLabel = rtti_proc_label(_, _, _, _, _, _, PredId, ProcId,
-		_, _, _, _, _, _, _).
+	PredId = ProcLabel ^ pred_id,
+	ProcId = ProcLabel ^ proc_id.
 
 rtti__id_to_c_identifier(ctor_rtti_id(RttiTypeCtor, RttiName), Str) :-
 	rtti__name_to_string(RttiTypeCtor, RttiName, Str).
Index: compiler/rtti_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_out.m,v
retrieving revision 1.45
diff -u -b -r1.45 rtti_out.m
--- compiler/rtti_out.m	8 Apr 2004 05:35:09 -0000	1.45
+++ compiler/rtti_out.m	19 May 2004 03:54:28 -0000
@@ -86,6 +86,7 @@
 :- import_module backend_libs__pseudo_type_info.
 :- import_module backend_libs__type_ctor_info.
 :- import_module hlds__hlds_data.
+:- import_module hlds__hlds_pred.
 :- import_module libs__globals.
 :- import_module libs__options.
 :- import_module ll_backend__code_util.
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_to_mlds.m,v
retrieving revision 1.50
diff -u -b -r1.50 rtti_to_mlds.m
--- compiler/rtti_to_mlds.m	24 Mar 2004 02:57:13 -0000	1.50
+++ compiler/rtti_to_mlds.m	19 May 2004 03:54:28 -0000
@@ -53,6 +53,7 @@
 :- import_module backend_libs__type_ctor_info.
 :- import_module check_hlds__type_util.
 :- import_module hlds__hlds_data.
+:- import_module hlds__hlds_pred.
 :- import_module ml_backend__ml_closure_gen.
 :- import_module ml_backend__ml_code_util.
 :- import_module ml_backend__ml_unify_gen.
@@ -1371,7 +1372,7 @@
 	% which unboxes the arguments if necessary.
 	%
 	( univ_to_type(RttiProcIdUniv, RttiProcId) ->
-		( RttiProcId ^ arity = 0 ->
+		( RttiProcId ^ proc_arity = 0 ->
 			% If there are no arguments, then there's no unboxing
 			% to do, so we don't need a wrapper.
 			% (This case can occur with --no-special-preds, where
Index: compiler/saved_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/saved_vars.m,v
retrieving revision 1.38
diff -u -b -r1.38 saved_vars.m
--- compiler/saved_vars.m	31 Mar 2004 12:32:29 -0000	1.38
+++ compiler/saved_vars.m	19 May 2004 03:54:29 -0000
@@ -209,6 +209,7 @@
 ok_to_duplicate(hide_debug_event) = no.
 ok_to_duplicate(tailcall) = no.
 ok_to_duplicate(keep_constant_binding) = no.
+ok_to_duplicate(save_deep_excp_vars) = no.
 
 % Divide a list of goals into an initial subsequence of goals that
 % construct constants, and all other goals.
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.87
diff -u -b -r1.87 stack_layout.m
--- compiler/stack_layout.m	4 May 2004 07:23:20 -0000	1.87
+++ compiler/stack_layout.m	19 May 2004 03:54:29 -0000
@@ -82,10 +82,7 @@
 	% converting it into LLDS data structures.
 
 stack_layout__generate_llds(ModuleInfo0, !GlobalData, Layouts, LayoutLabels) :-
-	global_data_get_all_proc_layouts(!.GlobalData, ProcLayoutList0),
-	list__filter(stack_layout__valid_proc_layout, ProcLayoutList0,
-		ProcLayoutList),
-
+	global_data_get_all_proc_layouts(!.GlobalData, ProcLayoutList),
 	module_info_globals(ModuleInfo0, Globals),
 	globals__lookup_bool_option(Globals, agc_stack_layout, AgcLayout),
 	globals__lookup_bool_option(Globals, trace_stack_layout, TraceLayout),
@@ -286,56 +283,51 @@
 :- pred stack_layout__construct_layouts(proc_layout_info::in,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_layouts(ProcLayoutInfo) -->
-	{ ProcLayoutInfo = proc_layout_info(RttiProcLabel, EntryLabel, Detism,
-		StackSlots, SuccipLoc, EvalMethod, MaybeCallLabel, MaxTraceReg,
-		HeadVars, MaybeGoal, InstMap, TraceSlotInfo, ForceProcIdLayout,
-		VarSet, VarTypes, InternalMap, MaybeTableIoDecl, IsBeingTraced,
-		NeedsAllNames) },
-	{ map__to_assoc_list(InternalMap, Internals) },
-	{ compute_var_number_map(HeadVars, VarSet, Internals, MaybeGoal,
-		VarNumMap) },
-
-	{ code_util__extract_proc_label_from_label(EntryLabel, ProcLabel) },
-	stack_layout__get_procid_stack_layout(ProcIdLayout0),
-	{ bool__or(ProcIdLayout0, ForceProcIdLayout, ProcIdLayout) },
+stack_layout__construct_layouts(ProcLayoutInfo, !Info) :-
+	ProcLayoutInfo = proc_layout_info(RttiProcLabel, EntryLabel, _Detism,
+		_StackSlots, _SuccipLoc, _EvalMethod, _MaybeCallLabel,
+		_MaxTraceReg, HeadVars, MaybeGoal, _InstMap, _TraceSlotInfo,
+		ForceProcIdLayout, VarSet, _VarTypes, InternalMap,
+		MaybeTableIoDecl, _IsBeingTraced, _NeedsAllNames,
+		_MaybeDeepProfInfo),
+	map__to_assoc_list(InternalMap, Internals),
+	compute_var_number_map(HeadVars, VarSet, Internals, MaybeGoal,
+		VarNumMap),
+
+	code_util__extract_proc_label_from_label(EntryLabel, ProcLabel),
+	stack_layout__get_procid_stack_layout(ProcIdLayout0, !Info),
+	bool__or(ProcIdLayout0, ForceProcIdLayout, ProcIdLayout),
 	(
-		{ ProcIdLayout = yes
+		( ProcIdLayout = yes
 		; MaybeTableIoDecl = yes(_)
-		}
-	->
-		{ UserOrCompiler = proc_label_user_or_compiler(ProcLabel) },
-		stack_layout__get_trace_stack_layout(TraceLayout),
-		{
-			TraceLayout = yes,
-			(
-				IsBeingTraced = no,
-				Kind = proc_layout_proc_id(UserOrCompiler)
-			;
-				IsBeingTraced = yes,
-				Kind = proc_layout_exec_trace(UserOrCompiler)
 			)
+	->
+		Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel))
 		;
-			TraceLayout = no,
-			Kind = proc_layout_proc_id(UserOrCompiler)
-		}
-	;
-		{ Kind = proc_layout_traversal }
+		Kind = proc_layout_traversal
 	),
 
-	{ ProcLayoutName = proc_layout(ProcLabel, Kind) },
+	ProcLayoutName = proc_layout(RttiProcLabel, Kind),
+
+	(
+		( !.Info ^ agc_stack_layout = yes
+		; !.Info ^ trace_stack_layout = yes
+		),
+		valid_proc_layout(ProcLayoutInfo)
+	->
+		list__map_foldl(stack_layout__construct_internal_layout(
+			ProcLayoutName, VarNumMap), Internals, InternalLayouts,
+			!Info)
+	;
+		InternalLayouts = []
+	),
 
-	list__map_foldl(stack_layout__construct_internal_layout(ProcLayoutName,
-		VarNumMap), Internals, InternalLayouts),
-	stack_layout__get_label_tables(LabelTables0),
-	{ list__foldl(stack_layout__update_label_table, InternalLayouts,
-		LabelTables0, LabelTables) },
-	stack_layout__set_label_tables(LabelTables),
-	stack_layout__construct_proc_layout(RttiProcLabel, EntryLabel,
-		ProcLabel, Detism, StackSlots, SuccipLoc, EvalMethod,
-		MaybeCallLabel, MaxTraceReg, HeadVars, MaybeGoal, InstMap,
-		TraceSlotInfo, VarSet, VarTypes, MaybeTableIoDecl,
-		Kind, NeedsAllNames, VarNumMap).
+	stack_layout__get_label_tables(LabelTables0, !Info),
+	list__foldl(stack_layout__update_label_table, InternalLayouts,
+		LabelTables0, LabelTables),
+	stack_layout__set_label_tables(LabelTables, !Info),
+	stack_layout__construct_proc_layout(ProcLayoutInfo, Kind, VarNumMap,
+		!Info).
 
 %---------------------------------------------------------------------------%
 
@@ -431,22 +423,13 @@
 
 %---------------------------------------------------------------------------%
 
-	% Construct a procedure-specific layout.
-
-:- pred stack_layout__construct_proc_layout(rtti_proc_label::in, label::in,
-	proc_label::in, determinism::in, int::in, maybe(int)::in,
-	eval_method::in, maybe(label)::in, int::in, list(prog_var)::in,
-	maybe(hlds_goal)::in, instmap::in, trace_slot_info::in, prog_varset::in,
-	vartypes::in, maybe(proc_table_info)::in,
-	proc_layout_kind::in, bool::in, var_num_map::in,
+:- pred stack_layout__construct_proc_traversal(label::in, determinism::in,
+	int::in, maybe(int)::in, proc_layout_stack_traversal::out, 
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_proc_layout(RttiProcLabel, EntryLabel, ProcLabel,
-		Detism, StackSlots, MaybeSuccipLoc, EvalMethod, MaybeCallLabel,
-		MaxTraceReg, HeadVars, MaybeGoal, InstMap, TraceSlotInfo,
-		VarSet, VarTypes, MaybeTableInfo, Kind,
-		NeedsAllNames, VarNumMap) -->
-	{
+stack_layout__construct_proc_traversal(EntryLabel, Detism, NumStackSlots,
+		MaybeSuccipLoc, Traversal, !Info) :-
+	(
 		MaybeSuccipLoc = yes(Location)
 	->
 		( determinism_components(Detism, _, at_most_many) ->
@@ -458,7 +441,7 @@
 			SuccipInt),
 		MaybeSuccipInt = yes(SuccipInt)
 	;
-			% Use a dummy location 1 if there is no succip slot
+			% Use a dummy location if there is no succip slot
 			% on the stack.
 			%
 			% This case can arise in two circumstances.
@@ -485,45 +468,70 @@
 			% Future uses of stack layouts will have to have
 			% similar constraints.
 		MaybeSuccipInt = no
-	},
-	stack_layout__get_static_code_addresses(StaticCodeAddr),
-	{ StaticCodeAddr = yes ->
+	),
+	stack_layout__get_static_code_addresses(StaticCodeAddr, !Info),
+	(
+		StaticCodeAddr = yes,
 		MaybeEntryLabel = yes(EntryLabel)
 	;
+		StaticCodeAddr = no,
 		MaybeEntryLabel = no
-	},
-	{ TraversalGroup = proc_layout_stack_traversal(MaybeEntryLabel,
-		MaybeSuccipInt, StackSlots, Detism) },
+	),
+	Traversal = proc_layout_stack_traversal(MaybeEntryLabel,
+		MaybeSuccipInt, NumStackSlots, Detism).
+
+	% Construct a procedure-specific layout.
+
+:- pred stack_layout__construct_proc_layout(proc_layout_info::in,
+	proc_layout_kind::in, var_num_map::in,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__construct_proc_layout(ProcLayoutInfo, Kind, VarNumMap, !Info) :-
+	ProcLayoutInfo = proc_layout_info(RttiProcLabel, EntryLabel, Detism,
+		StackSlots, SuccipLoc, EvalMethod, MaybeCallLabel, MaxTraceReg,
+		HeadVars, MaybeGoal, InstMap, TraceSlotInfo,
+		_ForceProcIdLayout, VarSet, VarTypes, _InternalMap,
+		MaybeTableInfo, IsBeingTraced, NeedsAllNames,
+		MaybeProcStatic),
+	stack_layout__construct_proc_traversal(EntryLabel, Detism, StackSlots,
+		SuccipLoc, Traversal, !Info),
 	(
-		{ Kind = proc_layout_traversal },
-		{ MaybeRest = no_proc_id }
+		Kind = proc_layout_traversal,
+		More = no_proc_id
 	;
-		{ Kind = proc_layout_proc_id(_) },
-		{ MaybeRest = proc_id_only }
+		Kind = proc_layout_proc_id(_),
+		stack_layout__get_trace_stack_layout(TraceStackLayout, !Info),
+		(
+			TraceStackLayout = yes,
+			IsBeingTraced = yes,
+			valid_proc_layout(ProcLayoutInfo)
+		->
+			stack_layout__construct_trace_layout(RttiProcLabel,
+				EvalMethod, MaybeCallLabel, MaxTraceReg,
+				HeadVars, MaybeGoal, InstMap, TraceSlotInfo,
+				VarSet, VarTypes, MaybeTableInfo,
+				NeedsAllNames, VarNumMap, ExecTrace, !Info),
+			MaybeExecTrace = yes(ExecTrace)
 	;
-		{ Kind = proc_layout_exec_trace(_) },
-		stack_layout__construct_trace_layout(RttiProcLabel, EvalMethod,
-			MaybeCallLabel, MaxTraceReg, HeadVars, MaybeGoal,
-			InstMap, TraceSlotInfo, VarSet, VarTypes,
-			MaybeTableInfo, NeedsAllNames, VarNumMap, ExecTrace),
-		{ MaybeRest = proc_id_and_exec_trace(ExecTrace) }
+			MaybeExecTrace = no
 	),
-
-	{ ProcLayout = proc_layout_data(ProcLabel, TraversalGroup, MaybeRest) },
-	{ Data = layout_data(ProcLayout) },
-	{ LayoutName = proc_layout(ProcLabel, Kind) },
-	stack_layout__add_proc_layout_data(Data, LayoutName, EntryLabel),
-
+		More = proc_id(MaybeProcStatic, MaybeExecTrace)
+	),
+	ProcLayout = proc_layout_data(RttiProcLabel, Traversal, More),
+	Data = layout_data(ProcLayout),
+	LayoutName = proc_layout(RttiProcLabel, Kind),
+	stack_layout__add_proc_layout_data(Data, LayoutName, EntryLabel,
+		!Info),
 	(
-		{ MaybeTableInfo = no }
+		MaybeTableInfo = no
 	;
-		{ MaybeTableInfo = yes(TableInfo) },
-		stack_layout__get_static_cell_info(StaticCellInfo0),
-		{ stack_layout__make_table_data(RttiProcLabel, Kind,
+		MaybeTableInfo = yes(TableInfo),
+		stack_layout__get_static_cell_info(StaticCellInfo0, !Info),
+		stack_layout__make_table_data(RttiProcLabel, Kind,
 			TableInfo, TableData,
-			StaticCellInfo0, StaticCellInfo) },
-		stack_layout__set_static_cell_info(StaticCellInfo),
-		stack_layout__add_table_data(TableData)
+			StaticCellInfo0, StaticCellInfo),
+		stack_layout__set_static_cell_info(StaticCellInfo, !Info),
+		stack_layout__add_table_data(TableData, !Info)
 	).
 
 :- pred stack_layout__construct_trace_layout(rtti_proc_label::in,
Index: compiler/switch_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/switch_util.m,v
retrieving revision 1.17
diff -u -b -r1.17 switch_util.m
--- compiler/switch_util.m	5 Apr 2004 05:07:42 -0000	1.17
+++ compiler/switch_util.m	19 May 2004 03:54:29 -0000
@@ -291,7 +291,7 @@
 switch_util__switch_priority(type_ctor_info_constant(_, _, _)) = 6.
 switch_util__switch_priority(base_typeclass_info_constant(_, _, _)) = 6.
 switch_util__switch_priority(tabling_pointer_constant(_, _)) = 6.
-switch_util__switch_priority(deep_profiling_proc_static_tag(_)) = 6.
+switch_util__switch_priority(deep_profiling_proc_layout_tag(_)) = 6.
 switch_util__switch_priority(table_io_decl_tag(_)) = 6.
 
 	% Determine the range of an atomic type.
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.141
diff -u -b -r1.141 unify_gen.m
--- compiler/unify_gen.m	8 Apr 2004 03:54:49 -0000	1.141
+++ compiler/unify_gen.m	19 May 2004 03:54:29 -0000
@@ -263,9 +263,9 @@
 unify_gen__generate_tag_test_rval_2(tabling_pointer_constant(_, _), _, _) :-
 	% This should never happen
 	error("Attempted tabling_pointer unification").
-unify_gen__generate_tag_test_rval_2(deep_profiling_proc_static_tag(_), _, _) :-
+unify_gen__generate_tag_test_rval_2(deep_profiling_proc_layout_tag(_), _, _) :-
 	% This should never happen
-	error("Attempted deep_profiling_proc_static_tag unification").
+	error("Attempted deep_profiling_proc_layout_tag unification").
 unify_gen__generate_tag_test_rval_2(table_io_decl_tag(_), _, _) :-
 	% This should never happen
 	error("Attempted table_io_decl_tag unification").
@@ -425,14 +425,23 @@
 	code_info__assign_const_to_var(Var,
 		const(data_addr_const(DataAddr, no)), !CI).
 unify_gen__generate_construction_2(
-		deep_profiling_proc_static_tag(RttiProcLabel),
+		deep_profiling_proc_layout_tag(RttiProcLabel),
 		Var, Args, _Modes, _, _, empty, !CI) :-
 	( Args = [] ->
 		true
 	;
 		error("unify_gen: deep_profiling_proc_static has args")
 	),
-	DataAddr = layout_addr(proc_static(RttiProcLabel)),
+	IsSpecial = RttiProcLabel ^ pred_is_special_pred,
+	(
+		IsSpecial = yes(_),
+		UserOrUCI = uci
+	;
+		IsSpecial = no,
+		UserOrUCI = user
+	),
+	ProcKind = proc_layout_proc_id(UserOrUCI),
+	DataAddr = layout_addr(proc_layout(RttiProcLabel, ProcKind)),
 	code_info__assign_const_to_var(Var,
 		const(data_addr_const(DataAddr, no)), !CI).
 unify_gen__generate_construction_2(table_io_decl_tag(RttiProcLabel),
@@ -842,7 +851,7 @@
 		Tag = tabling_pointer_constant(_, _),
 		Code = empty
 	;
-		Tag = deep_profiling_proc_static_tag(_),
+		Tag = deep_profiling_proc_layout_tag(_),
 		Code = empty
 	;
 		Tag = table_io_decl_tag(_),
cvs server: Diffing compiler/notes
cvs server: Diffing debian
cvs server: Diffing deep_profiler
Index: deep_profiler/html_format.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/html_format.m,v
retrieving revision 1.2
diff -u -b -r1.2 html_format.m
--- deep_profiler/html_format.m	2 Dec 2002 11:24:33 -0000	1.2
+++ deep_profiler/html_format.m	19 May 2004 03:54:29 -0000
@@ -907,13 +907,13 @@
 	( show_port_counts(Fields) = yes ->
 		Calls = WrapFunc("Calls", by_cost(calls, self, overall)),
 		FirstRow1 = FirstRow0 ++
-			"<TH COLSPAN=4>Port counts\n",
+			"<TH COLSPAN=5>Port counts\n",
 		SecondRow1 = SecondRow0 ++
-			string__format("<TH ALIGN=RIGHT>%s\n",
-				[s(Calls)]) ++
+			string__format("<TH ALIGN=RIGHT>%s\n", [s(Calls)]) ++
 			"<TH ALIGN=RIGHT>Exits\n" ++
 			"<TH ALIGN=RIGHT>Fails\n" ++
-			"<TH ALIGN=RIGHT>Redos\n"
+			"<TH ALIGN=RIGHT>Redos\n" ++
+			"<TH ALIGN=RIGHT>Excps\n"
 	;
 		FirstRow1 = FirstRow0,
 		SecondRow1 = SecondRow0
@@ -1346,6 +1346,7 @@
 	Exits = exits(Own),
 	Fails = fails(Own),
 	Redos = redos(Own),
+	Excps = excps(Own),
 
 	OwnQuanta = quanta(Own),
 	TotalQuanta = inherit_quanta(OwnPlusDesc),
@@ -1392,7 +1393,9 @@
 			string__format("<TD CLASS=port ALIGN=RIGHT>%s</TD>\n",
 				[s(commas(Fails))]) ++
 			string__format("<TD CLASS=port ALIGN=RIGHT>%s</TD>\n",
-				[s(commas(Redos))])
+				[s(commas(Redos))]) ++
+			string__format("<TD CLASS=port ALIGN=RIGHT>%s</TD>\n",
+				[s(commas(Excps))])
 	;
 		PortHTML = ""
 	),
Index: deep_profiler/measurements.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/measurements.m,v
retrieving revision 1.3
diff -u -b -r1.3 measurements.m
--- deep_profiler/measurements.m	3 Jul 2001 08:16:18 -0000	1.3
+++ deep_profiler/measurements.m	19 May 2004 03:54:29 -0000
@@ -22,6 +22,7 @@
 :- func exits(own_prof_info) = int.
 :- func fails(own_prof_info) = int.
 :- func redos(own_prof_info) = int.
+:- func excps(own_prof_info) = int.
 :- func quanta(own_prof_info) = int.
 :- func allocs(own_prof_info) = int.
 :- func words(own_prof_info) = int.
@@ -48,7 +49,7 @@
 :- func sum_own_infos(list(own_prof_info)) = own_prof_info.
 :- func sum_inherit_infos(list(inherit_prof_info)) = inherit_prof_info.
 
-:- func compress_profile(int, int, int, int, int, int) = own_prof_info.
+:- func compress_profile(int, int, int, int, int, int, int) = own_prof_info.
 :- func compress_profile(own_prof_info) = own_prof_info.
 
 :- func own_to_string(own_prof_info) = string.
@@ -61,21 +62,21 @@
 :- import_module string.
 
 :- type own_prof_info
-	--->	all(int, int, int, int, int, int)
-			% exits, fails, redos, quanta, allocs, words
+	--->	all(int, int, int, int, int, int, int)
+			% exits, fails, redos, excps, quanta, allocs, words
 			% implicit calls = exits + fails - redos
 	;	det(int, int, int, int)
 			% exits, quanta, allocs, words;
-			% implicit fails == redos == 0
+			% implicit fails == redos == excps == 0
 			% implicit calls == exits
 	;	fast_det(int, int, int)
 			% exits, allocs, words;
-			% implicit fails == redos == 0
+			% implicit fails == redos == excps == 0
 			% implicit calls == exits
 			% implicit quanta == 0
 	;	fast_nomem_semi(int, int).
 			% exits, fails
-			% implicit redos == 0
+			% implicit redos == excps == 0
 			% implicit calls == exits + fails
 			% implicit quanta == 0
 			% implicit allocs == words == 0
@@ -91,6 +92,7 @@
 exits(fast_nomem_semi(Exits, _)) = Exits.
 fails(fast_nomem_semi(_, Fails)) = Fails.
 redos(fast_nomem_semi(_, _)) = 0.
+excps(fast_nomem_semi(_, _)) = 0.
 quanta(fast_nomem_semi(_, _)) = 0.
 allocs(fast_nomem_semi(_, _)) = 0.
 words(fast_nomem_semi(_, _)) = 0.
@@ -99,6 +101,7 @@
 exits(fast_det(Exits, _, _)) = Exits.
 fails(fast_det(_, _, _)) = 0.
 redos(fast_det(_, _, _)) = 0.
+excps(fast_det(_, _, _)) = 0.
 quanta(fast_det(_, _, _)) = 0.
 allocs(fast_det(_, Allocs, _)) = Allocs.
 words(fast_det(_, _, Words)) = Words.
@@ -107,17 +110,19 @@
 exits(det(Exits, _, _, _)) = Exits.
 fails(det(_, _, _, _)) = 0.
 redos(det(_, _, _, _)) = 0.
+excps(det(_, _, _, _)) = 0.
 quanta(det(_, Quanta, _, _)) = Quanta.
 allocs(det(_, _, Allocs, _)) = Allocs.
 words(det(_, _, _, Words)) = Words.
 
-calls(all(Exits, Fails, Redos, _, _, _)) = Exits + Fails - Redos.
-exits(all(Exits, _, _, _, _, _)) = Exits.
-fails(all(_, Fails, _, _, _, _)) = Fails.
-redos(all(_, _, Redos, _, _, _)) = Redos.
-quanta(all(_, _, _, Quanta, _, _)) = Quanta.
-allocs(all(_, _, _, _, Allocs, _)) = Allocs.
-words(all(_, _, _, _, _, Words)) = Words.
+calls(all(Exits, Fails, Redos, Excps, _, _, _)) = Exits + Fails + Excps - Redos.
+exits(all(Exits, _, _, _, _, _, _)) = Exits.
+fails(all(_, Fails, _, _, _, _, _)) = Fails.
+redos(all(_, _, Redos, _, _, _, _)) = Redos.
+excps(all(_, _, _, Excps, _, _, _)) = Excps.
+quanta(all(_, _, _, _, Quanta, _, _)) = Quanta.
+allocs(all(_, _, _, _, _, Allocs, _)) = Allocs.
+words(all(_, _, _, _, _, _, Words)) = Words.
 
 zero_own_prof_info = fast_nomem_semi(0, 0).
 
@@ -155,20 +160,22 @@
 	Exits = exits(PI2),
 	Fails = fails(PI2),
 	Redos = redos(PI2),
+	Excps = excps(PI2),
 	Quanta = inherit_quanta(PI1) + quanta(PI2),
 	Allocs = inherit_allocs(PI1) + allocs(PI2),
 	Words = inherit_words(PI1) + words(PI2),
-	SumPI = compress_profile(Exits, Fails, Redos,
+	SumPI = compress_profile(Exits, Fails, Redos, Excps,
 		Quanta, Allocs, Words).
 
 add_own_to_own(PI1, PI2) = SumPI :-
 	Exits = exits(PI1) + exits(PI2),
 	Fails = fails(PI1) + fails(PI2),
 	Redos = redos(PI1) + redos(PI2),
+	Excps = excps(PI1) + excps(PI2),
 	Quanta = quanta(PI1) + quanta(PI2),
 	Allocs = allocs(PI1) + allocs(PI2),
 	Words = words(PI1) + words(PI2),
-	SumPI = compress_profile(Exits, Fails, Redos,
+	SumPI = compress_profile(Exits, Fails, Redos, Excps,
 		Quanta, Allocs, Words).
 
 sum_own_infos(Owns) =
@@ -177,9 +184,10 @@
 sum_inherit_infos(Inherits) =
 	list__foldl(add_inherit_to_inherit, Inherits, zero_inherit_prof_info).
 
-compress_profile(Exits, Fails, Redos, Quanta, Allocs, Words) = PI :-
+compress_profile(Exits, Fails, Redos, Excps, Quanta, Allocs, Words) = PI :-
 	(
 		Redos = 0,
+		Excps = 0,
 		Quanta = 0,
 		Allocs = 0,
 		Words = 0
@@ -187,7 +195,8 @@
 		PI = fast_nomem_semi(Exits, Fails)
 	;
 		Fails = 0,
-		Redos = 0
+		Redos = 0,
+		Excps = 0
 	->
 		( Quanta = 0 ->
 			PI = fast_det(Exits, Allocs, Words)
@@ -195,14 +204,15 @@
 			PI = det(Exits, Quanta, Allocs, Words)
 		)
 	;
-		PI = all(Exits, Fails, Redos, Quanta, Allocs, Words)
+		PI = all(Exits, Fails, Redos, Excps, Quanta, Allocs, Words)
 	).
 
 compress_profile(PI0) = PI :-
 	(
-		PI0 = all(Exits, Fails, Redos, Quanta, Allocs, Words),
+		PI0 = all(Exits, Fails, Redos, Excps, Quanta, Allocs, Words),
 		(
 			Redos = 0,
+			Excps = 0,
 			Quanta = 0,
 			Allocs = 0,
 			Words = 0
@@ -210,7 +220,8 @@
 			PI = fast_nomem_semi(Exits, Fails)
 		;
 			Fails = 0,
-			Redos = 0
+			Redos = 0,
+			Excps = 0
 		->
 			( Quanta = 0 ->
 				PI = fast_det(Exits, Allocs, Words)
@@ -243,11 +254,12 @@
 
 %-----------------------------------------------------------------------------%
 
-own_to_string(all(Exits, Fails, Redos, Quanta, Allocs, Words)) =
+own_to_string(all(Exits, Fails, Redos, Excps, Quanta, Allocs, Words)) =
 	"all(" ++
 	string__int_to_string(Exits) ++ ", " ++
 	string__int_to_string(Fails) ++ ", " ++
 	string__int_to_string(Redos) ++ ", " ++
+	string__int_to_string(Excps) ++ ", " ++
 	string__int_to_string(Quanta) ++ ", " ++
 	string__int_to_string(Allocs) ++ ", " ++
 	string__int_to_string(Words) ++
Index: deep_profiler/profile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/profile.m,v
retrieving revision 1.4
diff -u -b -r1.4 profile.m
--- deep_profiler/profile.m	18 Jul 2001 04:38:04 -0000	1.4
+++ deep_profiler/profile.m	19 May 2004 03:54:29 -0000
@@ -182,13 +182,13 @@
 			user_arity		:: int,
 			user_mode		:: int
 		)
-	;	compiler_generated(
-			comp_gen_type_name	:: string,
-			comp_gen_type_module	:: string,
-			comp_gen_def_module	:: string,
-			comp_gen_pred_name	:: string,
-			comp_gen_arity		:: int,
-			comp_gen_mode		:: int
+	;	uci_pred(
+			uci_type_name		:: string,
+			uci_type_module		:: string,
+			uci_def_module		:: string,
+			uci_pred_name		:: string,
+			uci_arity		:: int,
+			uci_mode		:: int
 		).
 
 :- type call_site_array_slot
@@ -434,7 +434,7 @@
 	(
 		ProcId = user_defined(_, DeclModule, _, _, _, _)
 	;
-		ProcId = compiler_generated(_, DeclModule, _, _, _, _)
+		ProcId = uci_pred(_, DeclModule, _, _, _, _)
 	).
 
 dummy_proc_id = user_defined(predicate, "unknown", "unknown", "unknown",
Index: deep_profiler/read_profile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/read_profile.m,v
retrieving revision 1.5
diff -u -b -r1.5 read_profile.m
--- deep_profiler/read_profile.m	12 Jan 2004 04:29:23 -0000	1.5
+++ deep_profiler/read_profile.m	19 May 2004 03:54:29 -0000
@@ -107,7 +107,10 @@
 
 :- func id_string = string.
 
-id_string = "Mercury deep profiler data".
+% This must the same string as the one written by MR_write_out_id_string
+% in runtime/mercury_deep_profiling.c.
+
+id_string = "Mercury deep profiler data version 1\n".
 
 :- func init_deep(int, int, int, int, int, int, int, int, int, int)
 	= initial_deep.
@@ -315,8 +318,8 @@
 	read_deep_byte(Res0, !IO),
 	(
 		Res0 = ok(Byte),
-		( Byte = token_isa_compiler_generated ->
-			read_proc_id_compiler_generated(Res, !IO)
+		( Byte = token_isa_uci_pred ->
+			read_proc_id_uci_pred(Res, !IO)
 		; Byte = token_isa_predicate ->
 			read_proc_id_user_defined(predicate, Res, !IO)
 		; Byte = token_isa_function ->
@@ -331,10 +334,10 @@
 		Res = error(Err)
 	).
 
-:- pred read_proc_id_compiler_generated(maybe_error(proc_id)::out,
+:- pred read_proc_id_uci_pred(maybe_error(proc_id)::out,
 	io__state::di, io__state::uo) is det.
 
-read_proc_id_compiler_generated(Res, !IO) :-
+read_proc_id_uci_pred(Res, !IO) :-
 	io_combinator__maybe_error_sequence_6(
 		read_string,
 		read_string,
@@ -345,7 +348,7 @@
 		(pred(TypeName::in, TypeModule::in, DefModule::in,
 			PredName::in, Arity::in, Mode::in, ProcId::out)
 			is det :-
-			ProcId = ok(compiler_generated(TypeName, TypeModule,
+			ProcId = ok(uci_pred(TypeName, TypeModule,
 				DefModule, PredName, Arity, Mode))
 		),
 		Res, !IO).
@@ -370,7 +373,7 @@
 
 :- func raw_proc_id_to_string(proc_id) = string.
 
-raw_proc_id_to_string(compiler_generated(TypeName, TypeModule, _DefModule,
+raw_proc_id_to_string(uci_pred(TypeName, TypeModule, _DefModule,
 		PredName, Arity, Mode)) =
 	string__append_list(
 		[PredName, " for ", TypeModule, ":", TypeName,
@@ -385,7 +388,7 @@
 
 :- func refined_proc_id_to_string(proc_id) = string.
 
-refined_proc_id_to_string(compiler_generated(TypeName, TypeModule, _DefModule,
+refined_proc_id_to_string(uci_pred(TypeName, TypeModule, _DefModule,
 		RawPredName, Arity, Mode)) = Name :-
 	( RawPredName = "__Unify__" ->
 		PredName = "Unify"
@@ -596,10 +599,17 @@
 	read_num(Res0, !IO),
 	(
 		Res0 = ok(Mask),
+
+		% The masks here must correspond exactly with the masks in
+		% MR_write_out_call_site_dynamic in mercury_deep_profiling.c
+		% in the runtime.
 		some [!MaybeError] (
 			!:MaybeError = no,
-			% Calls are computed from the other counts in
-			% measurements.m.
+			% We normally assume that the configuration macro
+			% MR_DEEP_PROFILING_EXPLICIT_CALL_COUNTS is not
+			% defined, and thus mercury_deep_profiling.m never
+			% writes out call counts (instead, call counts are
+			% computed from other port counts in measurements.m).
 			% maybe_read_num_handle_error(Mask, 0x0001, Calls,
 			% 	!MaybeError, !IO),
 			maybe_read_num_handle_error(Mask, 0x0002, Exits,
@@ -608,11 +618,13 @@
 				!MaybeError, !IO),
 			maybe_read_num_handle_error(Mask, 0x0008, Redos,
 				!MaybeError, !IO),
-			maybe_read_num_handle_error(Mask, 0x0010, Quanta,
+			maybe_read_num_handle_error(Mask, 0x0010, Excps,
+				!MaybeError, !IO),
+			maybe_read_num_handle_error(Mask, 0x0020, Quanta,
 				!MaybeError, !IO),
-			maybe_read_num_handle_error(Mask, 0x0020, Mallocs,
+			maybe_read_num_handle_error(Mask, 0x0040, Mallocs,
 				!MaybeError, !IO),
-			maybe_read_num_handle_error(Mask, 0x0040, Words,
+			maybe_read_num_handle_error(Mask, 0x0080, Words,
 				!MaybeError, !IO),
 			LastMaybeError = !.MaybeError
 		),
@@ -621,7 +633,7 @@
 			Res = error(Error)
 		;
 			LastMaybeError = no,
-			Res = ok(compress_profile(Exits, Fails, Redos, 
+			Res = ok(compress_profile(Exits, Fails, Redos, Excps,
 				Quanta, Mallocs, Words))
 		)
 	;
@@ -1129,10 +1141,10 @@
 	[will_not_call_mercury, thread_safe],
 	"X = MR_deep_token_isa_function;").
 
-:- func token_isa_compiler_generated = int.
-:- pragma c_code(token_isa_compiler_generated = (X::out),
+:- func token_isa_uci_pred = int.
+:- pragma c_code(token_isa_uci_pred = (X::out),
 	[will_not_call_mercury, thread_safe],
-	"X = MR_deep_token_isa_compiler_generated;").
+	"X = MR_deep_token_isa_uci_pred;").
 
 %------------------------------------------------------------------------------%
 %------------------------------------------------------------------------------%
cvs server: Diffing deep_profiler/notes
cvs server: Diffing doc
cvs server: Diffing extras
cvs server: Diffing extras/aditi
cvs server: Diffing extras/cgi
cvs server: Diffing extras/complex_numbers
cvs server: Diffing extras/complex_numbers/samples
cvs server: Diffing extras/complex_numbers/tests
cvs server: Diffing extras/concurrency
cvs server: Diffing extras/curs
cvs server: Diffing extras/curs/samples
cvs server: Diffing extras/curses
cvs server: Diffing extras/curses/sample
cvs server: Diffing extras/dynamic_linking
cvs server: Diffing extras/error
cvs server: Diffing extras/graphics
cvs server: Diffing extras/graphics/mercury_glut
cvs server: Diffing extras/graphics/mercury_opengl
cvs server: Diffing extras/graphics/mercury_tcltk
cvs server: Diffing extras/graphics/samples
cvs server: Diffing extras/graphics/samples/calc
cvs server: Diffing extras/graphics/samples/maze
cvs server: Diffing extras/graphics/samples/pent
cvs server: Diffing extras/lazy_evaluation
cvs server: Diffing extras/lex
cvs server: Diffing extras/lex/samples
cvs server: Diffing extras/lex/tests
cvs server: Diffing extras/logged_output
cvs server: Diffing extras/moose
cvs server: Diffing extras/moose/samples
cvs server: Diffing extras/moose/tests
cvs server: Diffing extras/morphine
cvs server: Diffing extras/morphine/non-regression-tests
cvs server: Diffing extras/morphine/scripts
cvs server: Diffing extras/morphine/source
cvs server: Diffing extras/odbc
cvs server: Diffing extras/posix
cvs server: Diffing extras/quickcheck
cvs server: Diffing extras/quickcheck/tutes
cvs server: Diffing extras/references
cvs server: Diffing extras/references/samples
cvs server: Diffing extras/references/tests
cvs server: Diffing extras/stream
cvs server: Diffing extras/trailed_update
cvs server: Diffing extras/trailed_update/samples
cvs server: Diffing extras/trailed_update/tests
cvs server: Diffing extras/xml
cvs server: Diffing extras/xml/samples
cvs server: Diffing java
cvs server: Diffing java/runtime
cvs server: Diffing library
Index: library/exception.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/exception.m,v
retrieving revision 1.86
diff -u -b -r1.86 exception.m
--- library/exception.m	15 Mar 2004 06:50:15 -0000	1.86
+++ library/exception.m	19 May 2004 03:54:29 -0000
@@ -646,7 +646,7 @@
 #ifndef ML_HLC_EXCEPTION_GUARD
 #define ML_HLC_EXCEPTION_GUARD
 
-#ifdef MR_HIGHLEVEL_CODE
+  #ifdef MR_HIGHLEVEL_CODE
 
   #ifdef MR_USE_GCC_NESTED_FUNCTIONS
   	#define MR_CONT_PARAMS		MR_NestedCont cont
@@ -731,7 +731,7 @@
 		MR_Pred handler_pred, MR_Box *output,
 		MR_CONT_PARAMS);
 
-#endif /* MR_HIGHLEVEL_CODE */
+  #endif /* MR_HIGHLEVEL_CODE */
 
 #endif /* ML_HLC_EXCEPTION_GUARD */
 ").
@@ -866,18 +866,19 @@
 	MR_Univ		exception;
 } ML_ExceptionHandler;
 
-#ifndef MR_THREAD_SAFE
+  #ifndef MR_THREAD_SAFE
   ML_ExceptionHandler	*ML_exception_handler;
-#endif
+  #endif
 
-#ifdef MR_THREAD_SAFE
-  #define ML_GET_EXCEPTION_HANDLER()	MR_GETSPECIFIC(MR_exception_handler_key)
+  #ifdef MR_THREAD_SAFE
+    #define ML_GET_EXCEPTION_HANDLER()		\
+    	MR_GETSPECIFIC(MR_exception_handler_key)
   #define ML_SET_EXCEPTION_HANDLER(val)	\
   	pthread_setspecific(MR_exception_handler_key, (val))
-#else  /* !MR_THREAD_SAFE */
+  #else  /* !MR_THREAD_SAFE */
   #define ML_GET_EXCEPTION_HANDLER()	ML_exception_handler
   #define ML_SET_EXCEPTION_HANDLER(val)	ML_exception_handler = (val)
-#endif /* !MR_THREAD_SAFE */
+  #endif /* !MR_THREAD_SAFE */
 
 void MR_CALL
 mercury__exception__builtin_throw_1_p_0(MR_Univ exception)
@@ -888,16 +889,16 @@
 		ML_report_uncaught_exception((MR_Word) exception);
 		exit(EXIT_FAILURE);
 	} else {
-#ifdef	MR_DEBUG_JMPBUFS
+  #ifdef MR_DEBUG_JMPBUFS
 		fprintf(stderr, ""throw longjmp %p\\n"",
 			exception_handler->handler);
-#endif
+  #endif
 		exception_handler->exception = exception;
 		longjmp(exception_handler->handler, 1);
 	}
 }
 
-#ifdef MR_NATIVE_GC
+  #ifdef MR_NATIVE_GC
 
 /*
 ** The following code is needed to trace the local variables
@@ -961,7 +962,7 @@
 
   #define ML_AGC_LOCAL(NAME) (agc_locals.NAME)
 
-#else /* !MR_NATIVE_GC */
+  #else /* !MR_NATIVE_GC */
 
   /* If accurate GC is not enabled, we define all of these as NOPs. */
   #define ML_DECLARE_AGC_HANDLER
@@ -969,7 +970,7 @@
   #define ML_UNINSTALL_AGC_HANDLER()
   #define ML_AGC_LOCAL(name) (name)
 
-#endif /* !MR_NATIVE_GC */
+  #endif /* !MR_NATIVE_GC */
 
 void MR_CALL
 mercury__exception__builtin_catch_model_det(MR_Mercury_Type_Info type_info,
@@ -983,19 +984,19 @@
 
 	ML_INSTALL_AGC_HANDLER(type_info, handler_pred);
 
-#ifdef	MR_DEBUG_JMPBUFS
+  #ifdef MR_DEBUG_JMPBUFS
 	fprintf(stderr, ""detcatch setjmp %p\\n"", this_handler.handler);
-#endif
+  #endif
 
 	if (setjmp(this_handler.handler) == 0) {
 		ML_call_goal_det_handcoded(type_info, pred, output);
 		ML_SET_EXCEPTION_HANDLER(this_handler.prev);
 		ML_UNINSTALL_AGC_HANDLER();
 	} else {
-#ifdef	MR_DEBUG_JMPBUFS
+  #ifdef MR_DEBUG_JMPBUFS
 		fprintf(stderr, ""detcatch caught jmp %p\\n"",
 			this_handler.handler);
-#endif
+  #endif
 
 		ML_SET_EXCEPTION_HANDLER(this_handler.prev);
 		ML_UNINSTALL_AGC_HANDLER();
@@ -1017,9 +1018,9 @@
 
 	ML_INSTALL_AGC_HANDLER(type_info, handler_pred);
 
-#ifdef	MR_DEBUG_JMPBUFS
+  #ifdef MR_DEBUG_JMPBUFS
 	fprintf(stderr, ""semicatch setjmp %p\\n"", this_handler.handler);
-#endif
+  #endif
 
 	if (setjmp(this_handler.handler) == 0) {
 		MR_bool result = ML_call_goal_semi_handcoded(type_info, pred,
@@ -1028,10 +1029,10 @@
 		ML_UNINSTALL_AGC_HANDLER();
 		return result;
 	} else {
-#ifdef	MR_DEBUG_JMPBUFS
+  #ifdef MR_DEBUG_JMPBUFS
 		fprintf(stderr, ""semicatch caught jmp %p\\n"",
 			this_handler.handler);
-#endif
+  #endif
 
 		ML_SET_EXCEPTION_HANDLER(this_handler.prev);
 		ML_UNINSTALL_AGC_HANDLER();
@@ -1042,7 +1043,7 @@
 	}
 }
 
-#ifdef MR_USE_GCC_NESTED_FUNCTIONS
+  #ifdef MR_USE_GCC_NESTED_FUNCTIONS
 
 void MR_CALL
 mercury__exception__builtin_catch_model_non(MR_Mercury_Type_Info type_info,
@@ -1077,9 +1078,9 @@
 
 	ML_INSTALL_AGC_HANDLER(type_info, handler_pred);
 
-#ifdef	MR_DEBUG_JMPBUFS
+    #ifdef MR_DEBUG_JMPBUFS
 	fprintf(stderr, ""noncatch setjmp %p\\n"", this_handler.handler);
-#endif
+    #endif
 
 	if (setjmp(this_handler.handler) == 0) {
 		ML_call_goal_non_handcoded(type_info, pred, output,
@@ -1087,10 +1088,10 @@
 		ML_SET_EXCEPTION_HANDLER(this_handler.prev);
 		ML_UNINSTALL_AGC_HANDLER();
 	} else {
-#ifdef	MR_DEBUG_JMPBUFS
+    #ifdef MR_DEBUG_JMPBUFS
 		fprintf(stderr, ""noncatch caught jmp %p\\n"",
 			this_handler.handler);
-#endif
+    #endif
 
 		ML_SET_EXCEPTION_HANDLER(this_handler.prev);
 		ML_UNINSTALL_AGC_HANDLER();
@@ -1101,7 +1102,7 @@
 	}
 }
 
-#else /* ! MR_USE_GCC_NESTED_FUNCTIONS */
+  #else /* ! MR_USE_GCC_NESTED_FUNCTIONS */
 
 struct ML_catch_env {
 	ML_ExceptionHandler	this_handler;
@@ -1146,9 +1147,9 @@
 
 	ML_INSTALL_AGC_HANDLER(type_info, handler_pred);
 
-#ifdef	MR_DEBUG_JMPBUFS
+    #ifdef MR_DEBUG_JMPBUFS
 	fprintf(stderr, ""noncatch setjmp %p\\n"", locals.this_handler.handler);
-#endif
+    #endif
 
 	if (setjmp(locals.this_handler.handler) == 0) {
 		ML_call_goal_non_handcoded(type_info, pred, output,
@@ -1170,10 +1171,10 @@
 		** for this handler.
 		*/
 
-#ifdef	MR_DEBUG_JMPBUFS
+    #ifdef MR_DEBUG_JMPBUFS
 		fprintf(stderr, ""noncatch caught jmp %p\\n"",
 			locals.this_handler.handler);
-#endif
+    #endif
 
 		ML_SET_EXCEPTION_HANDLER(locals.this_handler.prev);
 		ML_UNINSTALL_AGC_HANDLER();
@@ -1184,7 +1185,7 @@
 	}
 }
 
-#endif /* ! MR_USE_GCC_NESTED_FUNCTIONS */
+  #endif /* ! MR_USE_GCC_NESTED_FUNCTIONS */
 
 #endif /* MR_HIGHLEVEL_CODE */
 ").
@@ -1420,9 +1421,12 @@
 #ifndef MR_HIGHLEVEL_CODE
 
 /*
-** MR_trace_throw():
+** MR_throw_walk_stack():
 **	Unwind the stack as far as possible, until we reach a frame
-**	with an exception handler.  As we go, invoke
+**	with an exception handler.  As we go, invoke either or both
+**	of two actions.
+**
+**	(1) If MR_trace_enabled is set, then invoke
 **	`MR_trace(..., MR_PORT_EXCEPTION, ...)' for each stack frame,
 **	to signal to the debugger that that procedure has exited via
 **	an exception.  This allows to user to use the `retry' command
@@ -1433,23 +1437,35 @@
 **	print a warning and then continue.  It might be better to just
 **	`#ifdef' out all this code (and the code in builtin_throw which
 **	calls it) if MR_STACK_TRACE is not defined.
+**
+**	(2) In deep profiling grades, execute the actions appropriate for
+**	    execution leaving the procedure invocation via the exception port.
+**	    (Deep profiling grades always set MR_STACK_TRACE, so in such grades
+**	    we *will* be able to traverse the stack all the way.
+**
+** The arguments base_sp and base_curfr always hold MR_sp and MR_curfr.
+** They exist only because we cannot take the addresses of MR_sp and MR_curfr.
 */
 
-#define WARNING(msg)							\\
+  #ifdef MR_DEEP_PROFILING
+    #define WARNING(msg)						\\
+	do {								\\
+		MR_fatal_error(""cannot update exception counts: %s\\n"",\\
+			msg);						\\
+	} while (0)
+  #else
+    #define WARNING(msg)						\\
 	do {								\\
 		fflush(stdout);						\\
 		fprintf(stderr, ""mdb: warning: %s\\n""			\\
 			""This may result in some exception events\\n""	\\
 			""being omitted from the trace.\\n"", (msg));	\\
 	} while (0)
-
-/*
-** base_sp and base_curfr always hold MR_sp and MR_curfr. They exist
-** only because we cannot take the addresses of MR_sp and MR_curfr.
-*/
+  #endif
 
 static MR_Code *
-ML_trace_throw(MR_Code *success_pointer, MR_Word *base_sp, MR_Word *base_curfr)
+ML_throw_walk_stack(MR_Code *success_pointer, MR_Word *base_sp,
+	MR_Word *base_curfr)
 {
 	const MR_Internal	*label;
 	const MR_Label_Layout	*return_label_layout;
@@ -1469,6 +1485,20 @@
 		MR_Code 			*MR_jumpaddr;
 		MR_Stack_Walk_Step_Result	result;
 		const char			*problem;
+  #ifdef MR_DEEP_PROFILING
+		MR_CallSiteDynamic		*csd;
+		const MR_Proc_Layout		*pl;
+		MR_ProcStatic			*ps;
+		MR_ProcStatic			*proc_static;
+		int				top_csd_slot;
+		int				middle_csd_slot;
+		MR_CallSiteDynamic		*top_csd;
+		MR_CallSiteDynamic		*middle_csd;
+    #ifndef MR_USE_ACTIVATION_COUNTS
+		int				old_outermost_slot;
+		MR_ProcDynamic			*old_outermost;
+    #endif
+  #endif
 
 		/*
 		** check if we've reached a frame with an exception handler
@@ -1481,17 +1511,119 @@
 			return NULL;
 		}
 
+  #ifdef MR_DEEP_PROFILING
+
+  		/*
+		** The following code is based on the logic of
+		** runtime/mercury_deep_leave_port_body.h, differing
+		** in getting its parameters directly from stack frames
+		** guided by RTTI data and in having the additional error
+		** handling required by this. Any changes here may need to be
+		** reflected there and vice versa.
+		*/
+
+    #ifdef MR_EXEC_TRACE
+		if (! MR_disable_deep_profiling_in_debugger) {
+		/* The matching parenthesis is near the end of the loop */
+    #endif
+
+		MR_enter_instrumentation();
+
+		proc_static = entry_layout->MR_sle_proc_static;
+		top_csd_slot = proc_static->MR_ps_cur_csd_stack_slot;
+		middle_csd_slot = proc_static->MR_ps_next_csd_stack_slot;
+
+		if (top_csd_slot <= 0) {
+			MR_fatal_error(""builtin_throw: no top csd slot"");
+		}
+
+		if (middle_csd_slot <= 0) {
+			MR_fatal_error(""builtin_throw: no middle csd slot"");
+		}
+
+    #ifndef MR_USE_ACTIVATION_COUNTS
+		old_outermost_slot = proc_static->
+			MR_ps_old_outermost_stack_slot;
+
+		if (old_outermost_slot <= 0) {
+			MR_fatal_error(""builtin_throw: no old_outer slot"");
+		}
+    #endif
+
+		if (MR_DETISM_DET_STACK(entry_layout->MR_sle_detism)) {
+  			top_csd = (MR_CallSiteDynamic *)
+				MR_based_stackvar(base_sp, top_csd_slot);
+  			middle_csd = (MR_CallSiteDynamic *)
+				MR_based_stackvar(base_sp, middle_csd_slot);
+    #ifndef MR_USE_ACTIVATION_COUNTS
+  			old_outermost = (MR_ProcDynamic *)
+				MR_based_stackvar(base_sp,
+					old_outermost_slot);
+    #endif
+		} else {
+  			top_csd = (MR_CallSiteDynamic *)
+				MR_based_framevar(base_curfr, top_csd_slot);
+  			middle_csd = (MR_CallSiteDynamic *)
+				MR_based_framevar(base_curfr,
+					middle_csd_slot);
+    #ifndef MR_USE_ACTIVATION_COUNTS
+  			old_outermost = (MR_ProcDynamic *)
+				MR_based_framevar(base_curfr,
+					old_outermost_slot);
+    #endif
+  		}
+
+		csd = middle_csd;
+		MR_deep_assert(csd, NULL, NULL,
+			csd == MR_current_call_site_dynamic);
+
+    #ifdef MR_DEEP_PROFILING_PORT_COUNTS
+		csd->MR_csd_own.MR_own_excps++;
+    #endif
+
+		MR_deep_assert(csd, NULL, NULL,
+			csd->MR_csd_callee_ptr != NULL);
+		pl = csd->MR_csd_callee_ptr->MR_pd_proc_layout;
+		MR_deep_assert(csd, pl, NULL, pl != NULL);
+		ps = pl->MR_sle_proc_static;
+		MR_deep_assert(csd, pl, ps, ps != NULL);
+
+    #ifdef MR_USE_ACTIVATION_COUNTS
+		/* decrement activation count */
+		ps->MR_ps_activation_count--;
+		MR_deep_assert(csd, pl, ps, ps->MR_ps_activation_count >= 0);
+    #else
+		/* set outermost activation pointer */
+		ps->MR_ps_outermost_activation_ptr = old_outermost;
+    #endif
+
+		/* set current csd */
+		MR_current_call_site_dynamic = top_csd;
+
+		MR_leave_instrumentation();
+    #ifdef MR_EXEC_TRACE
+		/* The matching parenthesis is near the start of the loop */
+		}
+    #endif
+
+  #endif
+
+  		if (MR_trace_enabled) {
 		/*
 		** invoke MR_trace() to trace the exception
 		*/
-		if (return_label_layout->MR_sll_port != MR_PORT_EXCEPTION) {
-			MR_fatal_error(""return layout port is not exception"");
+			if (return_label_layout->MR_sll_port !=
+					MR_PORT_EXCEPTION)
+			{
+				MR_fatal_error(""return layout port ""
+					""is not exception"");
 		}
 
 		MR_jumpaddr = MR_trace(return_label_layout);
 		if (MR_jumpaddr != NULL) {
 			return MR_jumpaddr;
 		}
+		}
 
 		/*
 		** unwind the stacks back to the previous stack frame
@@ -1596,113 +1728,112 @@
 
 MR_declare_label(mercury__exception__builtin_throw_1_0_i1);
 
-/*
-** MR_MAKE_PROC_LAYOUT(entry, detism, slots, succip_locn, pred_or_func,
-**			module, name, arity, mode)
-*/
+#define	MR_DUMMY_LINE	0
+
+MR_call_sites_user_one_ho(exception, builtin_catch, 3, 0, MR_DUMMY_LINE);
+MR_proc_static_user_one_site(exception, builtin_catch, 3, 0,
+	""exception.m"", MR_DUMMY_LINE, MR_TRUE);
+MR_call_sites_user_one_ho(exception, builtin_catch, 3, 1, MR_DUMMY_LINE);
+MR_proc_static_user_one_site(exception, builtin_catch, 3, 1,
+	""exception.m"", MR_DUMMY_LINE, MR_TRUE);
+MR_call_sites_user_one_ho(exception, builtin_catch, 3, 2, MR_DUMMY_LINE);
+MR_proc_static_user_one_site(exception, builtin_catch, 3, 2,
+	""exception.m"", MR_DUMMY_LINE, MR_TRUE);
+MR_call_sites_user_one_ho(exception, builtin_catch, 3, 3, MR_DUMMY_LINE);
+MR_proc_static_user_one_site(exception, builtin_catch, 3, 3,
+	""exception.m"", MR_DUMMY_LINE, MR_TRUE);
+MR_call_sites_user_one_ho(exception, builtin_catch, 3, 4, MR_DUMMY_LINE);
+MR_proc_static_user_one_site(exception, builtin_catch, 3, 4,
+	""exception.m"", MR_DUMMY_LINE, MR_TRUE);
+MR_call_sites_user_one_ho(exception, builtin_catch, 3, 5, MR_DUMMY_LINE);
+MR_proc_static_user_one_site(exception, builtin_catch, 3, 5,
+	""exception.m"", MR_DUMMY_LINE, MR_TRUE);
 
 /*
 ** The various procedures of builtin_catch all allocate their stack frames
 ** on the nondet stack, so for the purposes of doing stack traces we say
 ** they have MR_DETISM_NON, even though they are not actually nondet.
+**
+** MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(detism, slots, succip_locn,
+**	pred_or_func, module, name, arity, mode)
 */
 
-MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_0,
-	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN,
-	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 0);
-MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_1,
-	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN,
-	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 1);
-MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_2,
-	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN,
-	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 2);
-MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_3,
-	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN,
-	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 3);
-MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_4,
-	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN,
-	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 4);
-MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_catch_3_5,
-	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN,
-	MR_PREDICATE, ""exception"", ""builtin_catch"", 3, 5);
+MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(
+	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, -1,
+	MR_PREDICATE, exception, builtin_catch, 3, 0);
+MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(
+	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, -1,
+	MR_PREDICATE, exception, builtin_catch, 3, 1);
+MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(
+	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, -1,
+	MR_PREDICATE, exception, builtin_catch, 3, 2);
+MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(
+	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, -1,
+	MR_PREDICATE, exception, builtin_catch, 3, 3);
+MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(
+	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, -1,
+	MR_PREDICATE, exception, builtin_catch, 3, 4);
+MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(
+	MR_DETISM_NON, MR_PROC_NO_SLOT_COUNT, -1,
+	MR_PREDICATE, exception, builtin_catch, 3, 5);
 
 #ifdef	MR_DEEP_PROFILING
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_0, 1);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_1, 1);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_2, 1);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_3, 1);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 1);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 1);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 0, 1);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 1, 1);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 2, 1);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 3, 1);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 1);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 1);
 #endif
 
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_0, 2);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_1, 2);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_2, 2);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_3, 2);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 2);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 2);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 0, 2);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 1, 2);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 2, 2);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 3, 2);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 2);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 2);
 
 #ifdef	MR_DEEP_PROFILING
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_0, 3);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_1, 3);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_2, 3);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_3, 3);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 3);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 3);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 0, 3);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 1, 3);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 2, 3);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 3, 3);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 3);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 3);
 #endif
 
 #ifdef	MR_DEEP_PROFILING
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 4);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 4);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 5);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 5);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 4);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 4);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 5);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 5);
 #endif
 
 #if	defined(MR_USE_TRAIL) || defined(MR_DEEP_PROFILING)
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 6);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 6);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 6);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 6);
 #endif
 
 #ifdef	MR_DEEP_PROFILING
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 7);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 7);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 7);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 7);
 #endif
 
 #ifdef	MR_DEEP_PROFILING
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_0, 8);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_1, 8);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_2, 8);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_3, 8);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_4, 8);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_catch_3_5, 8);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 0, 8);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 1, 8);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 2, 8);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 3, 8);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 4, 8);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_catch, 3, 5, 8);
 #endif
 
-MR_MAKE_PROC_LAYOUT(mercury__exception__builtin_throw_1_0,
+MR_proc_static_user_no_site(exception, builtin_throw, 1, 0,
+	""exception.m"", MR_DUMMY_LINE, MR_TRUE);
+MR_STATIC_USER_PROC_STATIC_PROC_LAYOUT(
         MR_DETISM_DET, 1, MR_LONG_LVAL_STACKVAR(1),
-        MR_PREDICATE, ""exception"", ""builtin_throw"", 1, 0);
-MR_MAKE_INTERNAL_LAYOUT(mercury__exception__builtin_throw_1_0, 1);
-
-#ifdef	MR_DEEP_PROFILING
-/* XXX the 0s are fake line numbers */
-MR_proc_static_user_ho(exception, builtin_catch, 3, 0,
-	""exception.m"", 0, MR_TRUE);
-MR_proc_static_user_ho(exception, builtin_catch, 3, 1,
-	""exception.m"", 0, MR_TRUE);
-MR_proc_static_user_ho(exception, builtin_catch, 3, 2,
-	""exception.m"", 0, MR_TRUE);
-MR_proc_static_user_ho(exception, builtin_catch, 3, 3,
-	""exception.m"", 0, MR_TRUE);
-MR_proc_static_user_ho(exception, builtin_catch, 3, 4,
-	""exception.m"", 0, MR_TRUE);
-MR_proc_static_user_ho(exception, builtin_catch, 3, 5,
-	""exception.m"", 0, MR_TRUE);
-/*
-** XXX Builtin_throw will eventually be able to make calls in deep profiling
-** grades. In the meantime, we need its proc_static structure for its callers.
-*/
-MR_proc_static_user_empty(exception, builtin_throw, 1, 0,
-	""exception.m"", 0, MR_FALSE);
-#endif
+        MR_PREDICATE, exception, builtin_throw, 1, 0);
+MR_MAKE_USER_INTERNAL_LAYOUT(exception, builtin_throw, 1, 0, 1);
 
 MR_BEGIN_MODULE(exceptions_module)
 	MR_init_entry_sl(mercury__exception__builtin_catch_3_0);
@@ -1799,7 +1930,7 @@
 
 /* mercury__exception__builtin_catch_3_0: the det version */
 #define	proc_label		mercury__exception__builtin_catch_3_0
-#define	proc_static		MR_proc_static_user_name(exception,	\
+#define	proc_layout		MR_proc_layout_user_name(exception,	\
 					builtin_catch, 3, 0)
 #define	excp_handler		MR_MODEL_DET_HANDLER
 #define	model			""[model det]""
@@ -1811,13 +1942,13 @@
 
 #include ""mercury_exception_catch_body.h""
 
-#undef	proc_static
+#undef	proc_layout
 #undef	proc_label
 
 /* mercury__exception__builtin_catch_3_2: the cc_multi version */
 /* identical to mercury__exception__builtin_catch_3_0 except for label names */
 #define	proc_label		mercury__exception__builtin_catch_3_2
-#define	proc_static		MR_proc_static_user_name(exception,	\
+#define	proc_layout		MR_proc_layout_user_name(exception,	\
 					builtin_catch, 3, 2)
 
 #include ""mercury_exception_catch_body.h""
@@ -1827,12 +1958,12 @@
 #undef	save_results
 #undef	model
 #undef	excp_handler
-#undef	proc_static
+#undef	proc_layout
 #undef	proc_label
 
 /* mercury__exception__builtin_catch_3_1: the semidet version */
 #define	proc_label		mercury__exception__builtin_catch_3_1
-#define	proc_static		MR_proc_static_user_name(exception,	\
+#define	proc_layout		MR_proc_layout_user_name(exception,	\
 					builtin_catch, 3, 1)
 #define	excp_handler		MR_MODEL_SEMI_HANDLER
 #define	model			""[model semi]""
@@ -1848,13 +1979,13 @@
 
 #include ""mercury_exception_catch_body.h""
 
-#undef	proc_static
+#undef	proc_layout
 #undef	proc_label
 
 /* mercury__exception__builtin_catch_3_3: the cc_nondet version */
 /* identical to mercury__exception__builtin_catch_3_1 except for label names */
 #define	proc_label		mercury__exception__builtin_catch_3_3
-#define	proc_static		MR_proc_static_user_name(exception,	\
+#define	proc_layout		MR_proc_layout_user_name(exception,	\
 					builtin_catch, 3, 3)
 
 #include ""mercury_exception_catch_body.h""
@@ -1864,12 +1995,12 @@
 #undef	save_results
 #undef	model
 #undef	excp_handler
-#undef	proc_static
+#undef	proc_layout
 #undef	proc_label
 
 /* mercury__exception__builtin_catch_3_4: the multi version */
 #define	proc_label		mercury__exception__builtin_catch_3_4
-#define	proc_static		MR_proc_static_user_name(exception,	\
+#define	proc_layout		MR_proc_layout_user_name(exception,	\
 					builtin_catch, 3, 4)
 #define	excp_handler		MR_MODEL_NON_HANDLER
 #define	model			""[model non]""
@@ -1883,13 +2014,13 @@
 
 #include ""mercury_exception_catch_body.h""
 
-#undef	proc_static
+#undef	proc_layout
 #undef	proc_label
 
 /* mercury__exception__builtin_catch_3_5: the nondet version */
 /* identical to mercury__exception__builtin_catch_3_4 except for label names */
 #define	proc_label		mercury__exception__builtin_catch_3_5
-#define	proc_static		MR_proc_static_user_name(exception,	\
+#define	proc_layout		MR_proc_layout_user_name(exception,	\
 					builtin_catch, 3, 5)
 
 #include ""mercury_exception_catch_body.h""
@@ -1901,7 +2032,7 @@
 #undef	save_results
 #undef	model
 #undef	excp_handler
-#undef	proc_static
+#undef	proc_layout
 #undef	proc_label
 
 /*
@@ -1924,18 +2055,25 @@
 	MR_bool				trace_from_full;
 	MR_Word				*orig_curfr;
 	MR_Unsigned			exception_event_number;
+	MR_bool				walk_stack;
 
 	exception = MR_r1;
 	exception_event_number = MR_trace_event_number;
 
 	/*
-	** let the debugger trace exception throwing
+	** let the debugger and/or the deep profiler trace exception throwing
 	*/
-	if (MR_trace_enabled) {
+#ifdef	MR_DEEP_PROFILING
+	walk_stack = MR_TRUE;
+#else
+	walk_stack = MR_trace_enabled;
+#endif
+
+	if (walk_stack) {
 		MR_Code *MR_jumpaddr;
 		MR_trace_set_exception_value(exception);
 		MR_save_transient_registers();
-		MR_jumpaddr = ML_trace_throw(MR_succip, MR_sp, MR_curfr);
+		MR_jumpaddr = ML_throw_walk_stack(MR_succip, MR_sp, MR_curfr);
 		MR_restore_transient_registers();
 		if (MR_jumpaddr != NULL) MR_GOTO(MR_jumpaddr);
 	}
@@ -2000,14 +2138,14 @@
 						(long) exception_event_number);
 				}
 			}
-			if (MR_trace_enabled) {
+			if (walk_stack) {
 				/*
-				** The stack has already been unwound
-				** by ML_trace_throw(), so we can't dump it.
+				** The stack has already been unwound by
+				** ML_throw_walk_stack(), so we can't dump it.
 				** (In fact, if we tried to dump the now-empty
 				** stack, we'd get incorrect results, since
-				** ML_trace_throw() does not restore MR_succip
-				** to the appropriate value.)
+				** ML_throw_walk_stack() does not restore
+				** MR_succip to the appropriate value.)
 				*/
 			} else {
 				MR_dump_stack(MR_succip, MR_sp, MR_curfr,
@@ -2230,20 +2368,20 @@
 void
 mercury_sys_init_exceptions_write_out_proc_statics(FILE *fp)
 {
-	MR_write_out_proc_static(fp, (MR_ProcStatic *)
-		&MR_proc_static_user_name(exception, builtin_catch, 3, 0));
-	MR_write_out_proc_static(fp, (MR_ProcStatic *)
-		&MR_proc_static_user_name(exception, builtin_catch, 3, 1));
-	MR_write_out_proc_static(fp, (MR_ProcStatic *)
-		&MR_proc_static_user_name(exception, builtin_catch, 3, 2));
-	MR_write_out_proc_static(fp, (MR_ProcStatic *)
-		&MR_proc_static_user_name(exception, builtin_catch, 3, 3));
-	MR_write_out_proc_static(fp, (MR_ProcStatic *)
-		&MR_proc_static_user_name(exception, builtin_catch, 3, 4));
-	MR_write_out_proc_static(fp, (MR_ProcStatic *)
-		&MR_proc_static_user_name(exception, builtin_catch, 3, 5));
-	MR_write_out_proc_static(fp, (MR_ProcStatic *)
-		&MR_proc_static_user_name(exception, builtin_throw, 1, 0));
+	MR_write_out_user_proc_static(fp,
+		&MR_proc_layout_user_name(exception, builtin_catch, 3, 0));
+	MR_write_out_user_proc_static(fp,
+		&MR_proc_layout_user_name(exception, builtin_catch, 3, 1));
+	MR_write_out_user_proc_static(fp,
+		&MR_proc_layout_user_name(exception, builtin_catch, 3, 2));
+	MR_write_out_user_proc_static(fp,
+		&MR_proc_layout_user_name(exception, builtin_catch, 3, 3));
+	MR_write_out_user_proc_static(fp,
+		&MR_proc_layout_user_name(exception, builtin_catch, 3, 4));
+	MR_write_out_user_proc_static(fp,
+		&MR_proc_layout_user_name(exception, builtin_catch, 3, 5));
+	MR_write_out_user_proc_static(fp,
+		&MR_proc_layout_user_name(exception, builtin_throw, 1, 0));
 }
 #endif
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list