[m-rev.] for review: put almost all layout structures in arrays

Zoltan Somogyi zs at csse.unimelb.edu.au
Wed Oct 28 19:26:13 AEDT 2009


For review by anyone. Note that the diffs for layout_out.m and stack_layout.m
are about the same size as the files themselves, so reviewing the files
would probably be easier.

Zoltan.

Move all the frequently occurring layout structures and components of layout
structures into arrays where possible. By replacing N global variables holding
individual layout structures or layout structure components with one global
variable holding an array of them, we reduce the sizes of the symbol tables
stored in object files, which should speed up both the C compiler and the
linker.

Measured on the modules of the library, mdbcomp and compiler directories
compiled in grade asm_fast.gc.debug, this diff reduces the size of the
generated C source files by 7.8%, the size of the generated object files
by 10.4%, and the number of symbols in the symbol tables of those object files
by a whopping 42.8%. (These improvements include, and are not on top of,
the improvements in my previous similar diff.)

runtime/mercury_stack_layout.h:
	Each label layout structure has information about the type and
	location of every variable that is live at that label. We store
	this information in three arrays: an array of pseudo-typeinfos giving
	the types of all these variables, and two arrays MR_ShortLvals and
	MR_LongLvals respectively giving their locations. (Most of the time,
	the location's encoded form fits into one byte (the MR_ShortLval)
	but sometimes it needs more bits (this is when we use MR_LongLval)).

	We used to store these three arrays, whose elements are different
	types, in a single occurrence-specific common structure,
	one after the other, with a cumbersome mechanism being required
	to access them. We now store them as segments of three separate arrays,
	of pseudo-typeinfos, MR_ShortLvals and MR_LongLvals respectively.
	This makes access simpler and faster (which will matter more to any
	accurate garbage collector than it does to the debugger). It also
	allows more scope for compression, since reusing an existing segment of
	one of the three arrays is easier than reusing an entire common
	structure, which would require the equivalent of exact matches
	on all three arrays.

	Since most label layout structures that have information about
	variables can encode the variables' locations using only MR_ShortLvals,
	create a version of the label layout structure type that omits the
	field used to record the whereabouts of the long location descriptors.

	Add macros now generated by the compiler to initialize layout
	structures.

	Simplify a one-field struct.

runtime/mercury_grade.h:
	Increment the binary compatibility version number for debuggable
	executables, since .c and .o files from before and after the change
	to label layout structures are NOT compatible.

runtime/mercury_type_info.h:
	Fix some binary-compatibility-related bit rot.

runtime/mercury_misc.h:
	Move here the existing macros used by the compiler when generating
	references to layout arrays, and add new ones.

runtime/mercury_goto.h:
	Delete the macros moved to mercury_misc.h.
	Conform to the changes in mercury_stack_layout.h.

runtime/Mmakefile:
	Prevent the unnecessary rebuilding of mercury_conf.h.

runtime/mercury_accurate_gc.c:
runtime/mercury_agc_debug.c:
runtime/mercury_layout_util.c:
runtime/mercury_stack_trace.c:
runtime/mercury_types.h:
trace/mercury_trace.c:
trace/mercury_trace_vars.c:
	Conform to the changes in mercury_stack_layout.h.

runtime/mercury_wrapper.c:
	Improve the debug support a bit.

runtime/mercury_engine.h:
	Fix style.

compiler/layout.m:
	Make the change described at the top. Almost all layout structures
	are now in arrays. The only exceptions are those that occur rarely,
	and proc layouts, whose names need to be derivable from the name
	of the procedure itself.

	Instead of having a single type "layout_data" that can represent
	different kinds of single global variables (not array slots), have
	different kinds for different purposes. This makes the code clearer
	and allows traversals that do not have to skip over inapplicable kinds
	of layout structures.

compiler/layout_out.m:
	Output the new arrays.

compiler/stack_layout.m:
	Generate the new arrays. Previously, an individual term generated by
	stack_layout.m could represent several components of a layout
	structure, with the components separated by layout_out.m. We now
	do the separation in stack_layout.m itself, adding each component
	to the array to which it belongs.

	Instead of passing around a single stack_layout_info structure,
	pass around several smaller one. This is preferable, since I found out
	the hard way that including everything in one structure would give the
	structure 51 fields. Most parts of the module work with only one
	or two of these structures, which makes their role clearer.

	Cluster related predicates together.

compiler/options.m:
doc/user_guide.texi:
	Add an option that control whether stack_layout.m will attempt to
	compress the layout arrays that can meaningfully be comressed.

compiler/llds.m:
	Remove the old distinction between a data_addr and a data_name,
	replacing both types with a single new one: data_id. Since different
	kinds of data_names were treated differently in many places,
	the distinction in types (which was intended to allow us to process
	data_addrs that wrapped data_names differently from other kinds of
	data_addrs) wasn't buying us anything anymore.

	The new data_id type allows for the possibility that the code generator
	wants to generate a reference to an address it does not know yet,
	because it is a slot in a layout array, and the slot has not been
	allocated yet.

	Add the information from which the new layout array structures
	will be generated to the LLDS.

compiler/llds_out.m:
	Call layout_out.m to output the new layout arrays.

	Adapt the decl_id type to the replacement of data_addrs by data_ids.
	Don't both keeping track of the have-vs-have-not-declared status
	of structures that are always declared at the start.

	When writing out a data_addr, for some kinds of data_addr, llds_out.m
	would write out the name of the relevant variable, while for some other
	kinds, it would write out its address. This diff separates out those
	those things into separate predicates, each of which behaves
	consistently.

compiler/mercury_compile_llds_back_end.m:
	Convey the intended contents of the new layout arrays from
	stack_layout.m to llds_out.m.

compiler/continuation_info.m:
	Add a type required by the way we now generate proc_static structures
	for deep profiling.

compiler/hlds_rtti.m:
	Add distinguishing prefixes to the field names of the rtti_proc_label
	type.

compiler/code_info.m:
compiler/code_util.m:
compiler/erl_rtti.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/ll_pseudo_type_info.m:
compiler/ml_code_util.m:
compiler/opt_debug.m:
compiler/proc_gen.m:
compiler/prog_rep.m:
compiler/rtti_out.m:
compiler/unify_gen.m:
	Conform to the changes above.

tests/EXPECT_FAIL_TESTS.asm_fast.gc.debug:
tests/EXPECT_FAIL_TESTS.asm_fast.gc.profdeep:
	Add these files to ignore expected failues in these grades.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.376
diff -u -b -r1.376 code_info.m
--- compiler/code_info.m	21 Oct 2009 06:36:18 -0000	1.376
+++ compiler/code_info.m	27 Oct 2009 05:01:49 -0000
@@ -203,7 +203,8 @@
     % Get the global static data structures that have
     % been created during code generation for closure layouts.
     %
-:- pred get_closure_layouts(code_info::in, list(layout_data)::out) is det.
+:- pred get_closure_layouts(code_info::in, list(closure_proc_id_data)::out)
+    is det.
 
 :- pred get_max_reg_in_use_at_trace(code_info::in, int::out) is det.
 
@@ -283,7 +284,7 @@
 :- pred set_persistent_temps(set(lval)::in,
     code_info::in, code_info::out) is det.
 
-:- pred set_closure_layouts(list(layout_data)::in,
+:- pred set_closure_layouts(list(closure_proc_id_data)::in,
     code_info::in, code_info::out) is det.
 
 :- pred get_closure_seq_counter(code_info::in, counter::out) is det.
@@ -441,7 +442,7 @@
                 cip_closure_layout_seq  :: counter,
 
                 % Closure layout structures generated by this procedure.
-                cip_closure_layouts     :: list(layout_data),
+                cip_closure_layouts     :: list(closure_proc_id_data),
 
                 % At each call to MR_trace, we compute the highest rN register
                 % number that contains a useful value. This slot contains the
@@ -871,17 +872,17 @@
 :- pred get_next_closure_seq_no(int::out,
     code_info::in, code_info::out) is det.
 
-:- pred add_closure_layout(layout_data::in,
+:- pred add_closure_layout(closure_proc_id_data::in,
     code_info::in, code_info::out) is det.
 
 :- pred add_scalar_static_cell(assoc_list(rval, llds_type)::in,
-    data_addr::out, code_info::in, code_info::out) is det.
+    data_id::out, code_info::in, code_info::out) is det.
 
 :- pred add_scalar_static_cell_natural_types(list(rval)::in,
-    data_addr::out, code_info::in, code_info::out) is det.
+    data_id::out, code_info::in, code_info::out) is det.
 
 :- pred add_vector_static_cell(list(llds_type)::in, list(list(rval))::in,
-    data_addr::out, code_info::in, code_info::out) is det.
+    data_id::out, code_info::in, code_info::out) is det.
 
 %---------------------------------------------------------------------------%
 
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.185
diff -u -b -r1.185 code_util.m
--- compiler/code_util.m	3 Nov 2008 03:08:01 -0000	1.185
+++ compiler/code_util.m	25 Oct 2009 09:52:26 -0000
@@ -108,7 +108,7 @@
     ProcAddr = make_entry_label_from_rtti(RttiProcLabel, Immed).
 
 make_entry_label_from_rtti(RttiProcLabel, Immed) = ProcAddr :-
-    ProcIsImported = RttiProcLabel ^ proc_is_imported,
+    ProcIsImported = RttiProcLabel ^ rpl_proc_is_imported,
     (
         ProcIsImported = yes,
         ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
@@ -132,7 +132,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.
-        ProcIsExported = RttiProcLabel ^ proc_is_exported,
+        ProcIsExported = RttiProcLabel ^ rpl_proc_is_exported,
         (
             ProcIsExported = yes,
             EntryType = entry_label_exported
@@ -144,7 +144,8 @@
     ;
         Immed = yes(ProcsPerFunc - proc(CurPredId, CurProcId)),
         Label = choose_local_label_type(ProcsPerFunc, CurPredId, CurProcId,
-            RttiProcLabel ^ pred_id, RttiProcLabel ^ proc_id, ProcLabel)
+            RttiProcLabel ^ rpl_pred_id, RttiProcLabel ^ rpl_proc_id,
+            ProcLabel)
     ).
 
 :- func choose_local_label_type(int, pred_id, proc_id, pred_id, proc_id,
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.96
diff -u -b -r1.96 continuation_info.m
--- compiler/continuation_info.m	23 Dec 2008 01:37:30 -0000	1.96
+++ compiler/continuation_info.m	26 Oct 2009 15:13:14 -0000
@@ -152,7 +152,14 @@
                 pli_need_all_names      :: bool,
                 % True iff we need the names of all the variables.
 
-                pli_deep_prof           :: maybe(proc_layout_proc_static)
+                pli_deep_prof           :: maybe(proc_deep_prof_info)
+        ).
+
+:- type proc_deep_prof_info
+    --->    proc_deep_prof_info(
+                pdpi_proc_static        :: hlds_proc_static,
+                pdpi_excp_slots         :: deep_excp_slots,
+                pdpi_orig_body          :: deep_original_body
         ).
 
 :- type proc_layout_table_info
Index: compiler/erl_rtti.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_rtti.m,v
retrieving revision 1.20
diff -u -b -r1.20 erl_rtti.m
--- compiler/erl_rtti.m	11 Jun 2009 07:00:08 -0000	1.20
+++ compiler/erl_rtti.m	25 Oct 2009 09:47:33 -0000
@@ -287,13 +287,13 @@
 :- pred erl_gen_method_wrapper(module_info::in, int::in, rtti_proc_label::in,
     elds_expr::out, prog_varset::in, prog_varset::out) is det.
 
-erl_gen_method_wrapper(ModuleInfo, NumExtra, RttiProcId, WrapperFun,
+erl_gen_method_wrapper(ModuleInfo, NumExtra, RttiProcLabel, WrapperFun,
         !VarSet) :-
-    PredId = RttiProcId ^ pred_id,
-    ProcId = RttiProcId ^ proc_id,
-    ArgTypes = RttiProcId ^ proc_arg_types,
-    ArgModes = RttiProcId ^ proc_arg_modes,
-    Detism = RttiProcId ^ proc_interface_detism,
+    PredId = RttiProcLabel ^ rpl_pred_id,
+    ProcId = RttiProcLabel ^ rpl_proc_id,
+    ArgTypes = RttiProcLabel ^ rpl_proc_arg_types,
+    ArgModes = RttiProcLabel ^ rpl_proc_arg_modes,
+    Detism = RttiProcLabel ^ rpl_proc_interface_detism,
 
     % We can't store the address of the typeclass method directly in the
     % base_typeclass_info; instead, we need to generate a wrapper function
@@ -657,24 +657,24 @@
 :- pred gen_init_special_pred(module_info::in, maybe(rtti_proc_label)::in,
     elds_expr::out, prog_varset::in, prog_varset::out) is det.
 
-gen_init_special_pred(ModuleInfo, MaybeRttiProcId, Expr, !VarSet) :-
+gen_init_special_pred(ModuleInfo, MaybeRttiProcLabel, Expr, !VarSet) :-
     (
-        MaybeRttiProcId = yes(RttiProcId),
-        erl_gen_special_pred_wrapper(ModuleInfo, RttiProcId, Expr, !VarSet)
+        MaybeRttiProcLabel = yes(RttiProcLabel),
+        erl_gen_special_pred_wrapper(ModuleInfo, RttiProcLabel, Expr, !VarSet)
     ;
-        MaybeRttiProcId = no,
+        MaybeRttiProcLabel = no,
         unexpected(this_file, "gen_init_special_pred: no special pred")
     ).
 
 :- pred erl_gen_special_pred_wrapper(module_info::in, rtti_proc_label::in,
     elds_expr::out, prog_varset::in, prog_varset::out) is det.
 
-erl_gen_special_pred_wrapper(ModuleInfo, RttiProcId, WrapperFun, !VarSet) :-
-    PredId = RttiProcId ^ pred_id,
-    ProcId = RttiProcId ^ proc_id,
-    ArgTypes = RttiProcId ^ proc_arg_types,
-    ArgModes = RttiProcId ^ proc_arg_modes,
-    Detism = RttiProcId ^ proc_interface_detism,
+erl_gen_special_pred_wrapper(ModuleInfo, RttiProcLabel, WrapperFun, !VarSet) :-
+    PredId = RttiProcLabel ^ rpl_pred_id,
+    ProcId = RttiProcLabel ^ rpl_proc_id,
+    ArgTypes = RttiProcLabel ^ rpl_proc_arg_types,
+    ArgModes = RttiProcLabel ^ rpl_proc_arg_modes,
+    Detism = RttiProcLabel ^ rpl_proc_interface_detism,
 
     % Create the variable list.
     svvarset.new_vars(list.length(ArgTypes), Ws, !VarSet),
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.89
diff -u -b -r1.89 exprn_aux.m
--- compiler/exprn_aux.m	21 Oct 2009 06:36:18 -0000	1.89
+++ compiler/exprn_aux.m	27 Oct 2009 05:53:25 -0000
@@ -78,15 +78,15 @@
     % and return a list of the code and data addresses that it references.
     %
 :- pred rval_list_addrs(list(rval)::in,
-    list(code_addr)::out, list(data_addr)::out) is det.
+    list(code_addr)::out, list(data_id)::out) is det.
 
 :- pred lval_list_addrs(list(lval)::in,
-    list(code_addr)::out, list(data_addr)::out) is det.
+    list(code_addr)::out, list(data_id)::out) is det.
 
-:- pred rval_addrs(rval::in, list(code_addr)::out, list(data_addr)::out)
+:- pred rval_addrs(rval::in, list(code_addr)::out, list(data_id)::out)
     is det.
 
-:- pred lval_addrs(lval::in, list(code_addr)::out, list(data_addr)::out)
+:- pred lval_addrs(lval::in, list(code_addr)::out, list(data_id)::out)
     is det.
 
 :- func var_lval_to_rval(prog_var, lval) = rval.
@@ -193,10 +193,10 @@
 vars_in_rval(const(_Conts), []).
 vars_in_rval(unop(_Unop, Rval), Vars) :-
     vars_in_rval(Rval, Vars).
-vars_in_rval(binop(_Binop, Rval0, Rval1), Vars) :-
-    vars_in_rval(Rval0, Vars0),
-    vars_in_rval(Rval1, Vars1),
-    list.append(Vars0, Vars1, Vars).
+vars_in_rval(binop(_Binop, RvalA, RvalB), Vars) :-
+    vars_in_rval(RvalA, VarsA),
+    vars_in_rval(RvalB, VarsB),
+    Vars = VarsA ++ VarsB.
 vars_in_rval(mem_addr(MemRef), Vars) :-
     vars_in_mem_ref(MemRef, Vars).
 
@@ -221,10 +221,10 @@
     vars_in_rval(Rval, Vars).
 vars_in_lval(prevfr_slot(Rval), Vars) :-
     vars_in_rval(Rval, Vars).
-vars_in_lval(field(_MaybeTag, Rval0, Rval1), Vars) :-
-    vars_in_rval(Rval0, Vars0),
-    vars_in_rval(Rval1, Vars1),
-    list.append(Vars0, Vars1, Vars).
+vars_in_lval(field(_MaybeTag, RvalA, RvalB), Vars) :-
+    vars_in_rval(RvalA, VarsA),
+    vars_in_rval(RvalB, VarsB),
+    Vars = VarsA ++ VarsB.
 vars_in_lval(mem_ref(Rval), Vars) :-
     vars_in_rval(Rval, Vars).
 vars_in_lval(global_var_ref(_), []).
@@ -795,31 +795,31 @@
 
 %-----------------------------------------------------------------------------%
 
-rval_addrs(lval(Lval), CodeAddrs, DataAddrs) :-
-    lval_addrs(Lval, CodeAddrs, DataAddrs).
+rval_addrs(lval(Lval), CodeAddrs, DataIds) :-
+    lval_addrs(Lval, CodeAddrs, DataIds).
 rval_addrs(var(_Var), [], []).
-rval_addrs(mkword(_Tag, Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
-rval_addrs(const(Const), CodeAddrs, DataAddrs) :-
+rval_addrs(mkword(_Tag, Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
+rval_addrs(const(Const), CodeAddrs, DataIds) :-
     ( Const = llconst_code_addr(CodeAddress) ->
         CodeAddrs = [CodeAddress],
-        DataAddrs = []
-    ; Const = llconst_data_addr(DataAddress, _) ->
+        DataIds = []
+    ; Const = llconst_data_addr(DataId, _) ->
         CodeAddrs = [],
-        DataAddrs = [DataAddress]
+        DataIds = [DataId]
     ;
         CodeAddrs = [],
-        DataAddrs = []
+        DataIds = []
     ).
-rval_addrs(unop(_Unop, Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
-rval_addrs(binop(_Binop, Rval1, Rval2), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval1, CodeAddrs1, DataAddrs1),
-    rval_addrs(Rval2, CodeAddrs2, DataAddrs2),
-    list.append(CodeAddrs1, CodeAddrs2, CodeAddrs),
-    list.append(DataAddrs1, DataAddrs2, DataAddrs).
-rval_addrs(mem_addr(Rval), CodeAddrs, DataAddrs) :-
-    mem_ref_addrs(Rval, CodeAddrs, DataAddrs).
+rval_addrs(unop(_Unop, Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
+rval_addrs(binop(_Binop, RvalA, RvalB), CodeAddrs, DataIds) :-
+    rval_addrs(RvalA, CodeAddrsA, DataIdsA),
+    rval_addrs(RvalB, CodeAddrsB, DataIdsB),
+    CodeAddrs = CodeAddrsA ++ CodeAddrsB,
+    DataIds = DataIdsA ++ DataIdsB.
+rval_addrs(mem_addr(Rval), CodeAddrs, DataIds) :-
+    mem_ref_addrs(Rval, CodeAddrs, DataIds).
 
 lval_addrs(reg(_Type, _RegNum), [], []).
 lval_addrs(stackvar(_SlotNum), [], []).
@@ -828,69 +828,69 @@
 lval_addrs(succip, [], []).
 lval_addrs(maxfr, [], []).
 lval_addrs(curfr, [], []).
-lval_addrs(prevfr_slot(Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
-lval_addrs(succfr_slot(Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
-lval_addrs(redofr_slot(Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
-lval_addrs(redoip_slot(Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
-lval_addrs(succip_slot(Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
+lval_addrs(prevfr_slot(Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
+lval_addrs(succfr_slot(Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
+lval_addrs(redofr_slot(Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
+lval_addrs(redoip_slot(Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
+lval_addrs(succip_slot(Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
 lval_addrs(hp, [], []).
 lval_addrs(sp, [], []).
 lval_addrs(parent_sp, [], []).
-lval_addrs(field(_Tag, Rval1, Rval2), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval1, CodeAddrs1, DataAddrs1),
-    rval_addrs(Rval2, CodeAddrs2, DataAddrs2),
-    list.append(CodeAddrs1, CodeAddrs2, CodeAddrs),
-    list.append(DataAddrs1, DataAddrs2, DataAddrs).
+lval_addrs(field(_Tag, RvalA, RvalB), CodeAddrs, DataIds) :-
+    rval_addrs(RvalA, CodeAddrsA, DataIdsA),
+    rval_addrs(RvalB, CodeAddrsB, DataIdsB),
+    CodeAddrs = CodeAddrsA ++ CodeAddrsB,
+    DataIds = DataIdsA ++ DataIdsB.
 lval_addrs(lvar(_Var), [], []).
 lval_addrs(temp(_Type, _TmpNum), [], []).
-lval_addrs(mem_ref(Rval), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
+lval_addrs(mem_ref(Rval), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
 lval_addrs(global_var_ref(_), [], []).
 
 rval_list_addrs([], [], []).
-rval_list_addrs([Rval | Rvals], CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs0, DataAddrs0),
-    rval_list_addrs(Rvals, CodeAddrs1, DataAddrs1),
-    list.append(CodeAddrs0, CodeAddrs1, CodeAddrs),
-    list.append(DataAddrs0, DataAddrs1, DataAddrs).
+rval_list_addrs([Rval | Rvals], CodeAddrs, DataIds) :-
+    rval_addrs(Rval, HeadCodeAddrs, HeadDataIds),
+    rval_list_addrs(Rvals, TailCodeAddrs, TailDataIds),
+    CodeAddrs = HeadCodeAddrs ++ TailCodeAddrs,
+    DataIds = HeadDataIds ++ TailDataIds.
 
 lval_list_addrs([], [], []).
-lval_list_addrs([Lval | Lvals], CodeAddrs, DataAddrs) :-
-    lval_addrs(Lval, CodeAddrs0, DataAddrs0),
-    lval_list_addrs(Lvals, CodeAddrs1, DataAddrs1),
-    list.append(CodeAddrs0, CodeAddrs1, CodeAddrs),
-    list.append(DataAddrs0, DataAddrs1, DataAddrs).
+lval_list_addrs([Lval | Lvals], CodeAddrs, DataIds) :-
+    lval_addrs(Lval, HeadCodeAddrs, HeadDataIds),
+    lval_list_addrs(Lvals, TailCodeAddrs, TailDataIds),
+    CodeAddrs = HeadCodeAddrs ++ TailCodeAddrs,
+    DataIds = HeadDataIds ++ TailDataIds.
 
 :- pred mem_ref_addrs(mem_ref::in,
-    list(code_addr)::out, list(data_addr)::out) is det.
+    list(code_addr)::out, list(data_id)::out) is det.
 
 mem_ref_addrs(stackvar_ref(_SlotNum), [], []).
 mem_ref_addrs(framevar_ref(_SlotNum), [], []).
-mem_ref_addrs(heap_ref(Rval, _Tag, _FieldNum), CodeAddrs, DataAddrs) :-
-    rval_addrs(Rval, CodeAddrs, DataAddrs).
+mem_ref_addrs(heap_ref(Rval, _Tag, _FieldNum), CodeAddrs, DataIds) :-
+    rval_addrs(Rval, CodeAddrs, DataIds).
 
     % Give a list of maybe(rval), return a list of the code and data
     % addresses that are referenced by that list.
     %
 :- pred maybe_rval_list_addrs(list(maybe(rval))::in,
-    list(code_addr)::out, list(data_addr)::out) is det.
+    list(code_addr)::out, list(data_id)::out) is det.
 
 maybe_rval_list_addrs([], [], []).
-maybe_rval_list_addrs([MaybeRval | MaybeRvals], CodeAddrs, DataAddrs) :-
+maybe_rval_list_addrs([MaybeRval | MaybeRvals], CodeAddrs, DataIds) :-
     (
         MaybeRval = yes(Rval),
-        rval_addrs(Rval, CodeAddrs0, DataAddrs0),
-        maybe_rval_list_addrs(MaybeRvals, CodeAddrs1, DataAddrs1),
-        list.append(CodeAddrs0, CodeAddrs1, CodeAddrs),
-        list.append(DataAddrs0, DataAddrs1, DataAddrs)
+        rval_addrs(Rval, HeadCodeAddrs, HeadDataIds),
+        maybe_rval_list_addrs(MaybeRvals, TailCodeAddrs, TailDataIds),
+        CodeAddrs = HeadCodeAddrs ++ TailCodeAddrs,
+        DataIds = HeadDataIds ++ TailDataIds
     ;
         MaybeRval = no,
-        maybe_rval_list_addrs(MaybeRvals, CodeAddrs, DataAddrs)
+        maybe_rval_list_addrs(MaybeRvals, CodeAddrs, DataIds)
     ).
 
 var_lval_to_rval(_Var, Lval) = lval(Lval).
Index: compiler/global_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/global_data.m,v
retrieving revision 1.42
diff -u -b -r1.42 global_data.m
--- compiler/global_data.m	21 Oct 2009 06:36:19 -0000	1.42
+++ compiler/global_data.m	27 Oct 2009 07:49:17 -0000
@@ -43,7 +43,7 @@
 :- pred global_data_update_proc_layout(pred_proc_id::in, proc_layout_info::in,
     global_data::in, global_data::out) is det.
 
-:- pred global_data_add_new_closure_layouts(list(layout_data)::in,
+:- pred global_data_add_new_closure_layouts(list(closure_proc_id_data)::in,
     global_data::in, global_data::out) is det.
 
 :- pred global_data_maybe_get_proc_layout(global_data::in, pred_proc_id::in,
@@ -59,7 +59,7 @@
     list(proc_layout_info)::out) is det.
 
 :- pred global_data_get_all_closure_layouts(global_data::in,
-    list(layout_data)::out) is det.
+    list(closure_proc_id_data)::out) is det.
 
 :- pred global_data_get_static_cell_info(global_data::in,
     static_cell_info::out) is det.
@@ -72,20 +72,20 @@
 :- func init_static_cell_info(module_name, have_unboxed_floats, bool)
     = static_cell_info.
 
-:- pred add_scalar_static_cell(assoc_list(rval, llds_type)::in, data_addr::out,
+:- pred add_scalar_static_cell(assoc_list(rval, llds_type)::in, data_id::out,
     static_cell_info::in, static_cell_info::out) is det.
 
-:- pred add_scalar_static_cell_natural_types(list(rval)::in, data_addr::out,
+:- pred add_scalar_static_cell_natural_types(list(rval)::in, data_id::out,
     static_cell_info::in, static_cell_info::out) is det.
 
 :- pred find_general_llds_types(have_unboxed_floats::in, list(mer_type)::in,
     list(list(rval))::in, list(llds_type)::out) is semidet.
 
 :- pred add_vector_static_cell(list(llds_type)::in,
-    list(list(rval))::in, data_addr::out,
+    list(list(rval))::in, data_id::out,
     static_cell_info::in, static_cell_info::out) is det.
 
-:- pred search_scalar_static_cell_offset(static_cell_info::in, data_addr::in,
+:- pred search_scalar_static_cell_offset(static_cell_info::in, data_id::in,
     int::in, rval::out) is semidet.
 
 :- pred get_static_cells(static_cell_info::in,
@@ -165,7 +165,7 @@
                 % While all closure layouts are different from all other
                 % layout_data, it is possible, although unlikely, for
                 % two closures to have the same layout.
-                gd_closure_layouts      :: list(layout_data),
+                gd_closure_layouts      :: list(closure_proc_id_data),
 
                 % Information about all the statically allocated cells
                 % created so far.
@@ -233,7 +233,7 @@
 :- type scalar_cell_group
     --->    scalar_cell_group(
                 scalar_cell_counter         :: counter, % next cell number
-                scalar_cell_group_members   :: bimap(list(rval), data_name),
+                scalar_cell_group_members   :: bimap(list(rval), data_id),
                 scalar_cell_rev_array       :: list(common_cell_value)
             ).
 
@@ -296,12 +296,12 @@
 
 %-----------------------------------------------------------------------------%
 
-add_scalar_static_cell_natural_types(Args, DataAddr, !Info) :-
+add_scalar_static_cell_natural_types(Args, DataId, !Info) :-
     list.map(associate_natural_type(!.Info ^ sci_sub_info ^ scsi_unbox_float),
         Args, ArgsTypes),
-    add_scalar_static_cell(ArgsTypes, DataAddr, !Info).
+    add_scalar_static_cell(ArgsTypes, DataId, !Info).
 
-add_scalar_static_cell(ArgsTypes0, DataAddr, !Info) :-
+add_scalar_static_cell(ArgsTypes0, DataId, !Info) :-
     % If we have an empty cell, place a dummy field in it,
     % so that the generated C structure isn't empty.
     (
@@ -312,14 +312,14 @@
         ArgsTypes = ArgsTypes0
     ),
     compute_cell_type(ArgsTypes, CellType, CellTypeAndValue),
-    do_add_scalar_static_cell(ArgsTypes, CellType, CellTypeAndValue, DataAddr,
+    do_add_scalar_static_cell(ArgsTypes, CellType, CellTypeAndValue, DataId,
         !Info).
 
 :- pred do_add_scalar_static_cell(assoc_list(rval, llds_type)::in,
-    common_cell_type::in, common_cell_value::in, data_addr::out,
+    common_cell_type::in, common_cell_value::in, data_id::out,
     static_cell_info::in, static_cell_info::out) is det.
 
-do_add_scalar_static_cell(ArgsTypes, CellType, CellValue, DataAddr, !Info) :-
+do_add_scalar_static_cell(ArgsTypes, CellType, CellValue, DataId, !Info) :-
     assoc_list.keys(ArgsTypes, Args),
     some [!CellGroup] (
         TypeNumMap0 = !.Info ^ sci_cell_type_num_map,
@@ -343,20 +343,20 @@
             !:CellGroup = init_scalar_cell_group
         ),
         MembersMap0 = !.CellGroup ^ scalar_cell_group_members,
-        ( bimap.search(MembersMap0, Args, DataNamePrime) ->
-            DataName = DataNamePrime
+        ( bimap.search(MembersMap0, Args, DataIdPrime) ->
+            DataId = DataIdPrime
         ;
             CellNumCounter0 = !.CellGroup ^ scalar_cell_counter,
             counter.allocate(CellNum, CellNumCounter0, CellNumCounter),
             !CellGroup ^ scalar_cell_counter := CellNumCounter,
-            DataName = scalar_common_ref(TypeNum, CellNum),
+            DataId = scalar_common_data_id(TypeNum, CellNum),
             RevArray0 = !.CellGroup ^ scalar_cell_rev_array,
             RevArray = [CellValue | RevArray0],
             !CellGroup ^ scalar_cell_rev_array := RevArray,
             InsertCommonData = !.Info ^ sci_sub_info ^ scsi_common_data,
             (
                 InsertCommonData = yes,
-                bimap.det_insert(MembersMap0, Args, DataName, MembersMap),
+                bimap.det_insert(MembersMap0, Args, DataId, MembersMap),
                 !CellGroup ^ scalar_cell_group_members := MembersMap
             ;
                 InsertCommonData = no
@@ -367,21 +367,18 @@
             map.set(CellGroupMap0, TypeNum, !.CellGroup, CellGroupMap),
             !Info ^ sci_scalar_cell_group_map := CellGroupMap
         )
-    ),
-    ModuleName = !.Info ^ sci_sub_info ^ scsi_module_name,
-    DataAddr = data_addr(ModuleName, DataName).
+    ).
 
 :- func init_scalar_cell_group = scalar_cell_group.
 
 init_scalar_cell_group = scalar_cell_group(counter.init(0), bimap.init, []).
 
-search_scalar_static_cell_offset(Info, DataAddr, Offset, Rval) :-
-    DataAddr = data_addr(Info ^ sci_sub_info ^ scsi_module_name, DataName),
-    DataName = scalar_common_ref(TypeNum, _CellNum),
+search_scalar_static_cell_offset(Info, DataId, Offset, Rval) :-
+    DataId = scalar_common_data_id(TypeNum, _CellNum),
     CellGroupMap = Info ^ sci_scalar_cell_group_map,
     map.lookup(CellGroupMap, TypeNum, CellGroup),
     CellGroupMembers = CellGroup ^ scalar_cell_group_members,
-    bimap.reverse_lookup(CellGroupMembers, Rvals, DataName),
+    bimap.reverse_lookup(CellGroupMembers, Rvals, DataId),
     list.index0_det(Rvals, Offset, Rval).
 
 %-----------------------------------------------------------------------------%
@@ -440,7 +437,7 @@
 
 %-----------------------------------------------------------------------------%
 
-add_vector_static_cell(LLDSTypes, VectorData, DataAddr, !Info) :-
+add_vector_static_cell(LLDSTypes, VectorData, DataId, !Info) :-
     require(list.is_not_empty(LLDSTypes), "add_vector_static_cell: no types"),
     require(list.is_not_empty(VectorData), "add_vector_static_cell: no data"),
 
@@ -475,16 +472,14 @@
         CellNumCounter0 = !.CellGroup ^ vector_cell_counter,
         counter.allocate(CellNum, CellNumCounter0, CellNumCounter),
         !CellGroup ^ vector_cell_counter := CellNumCounter,
-        DataName = vector_common_ref(TypeNum, CellNum),
+        DataId = vector_common_data_id(TypeNum, CellNum),
         CellMap0 = !.CellGroup ^ vector_cell_map,
         VectorContents = vector_contents(VectorCells),
         map.det_insert(CellMap0, CellNum, VectorContents, CellMap),
         !CellGroup ^ vector_cell_map := CellMap,
         map.set(CellGroupMap0, TypeNum, !.CellGroup, CellGroupMap),
         !Info ^ sci_vector_cell_group_map := CellGroupMap
-    ),
-    ModuleName = !.Info ^ sci_sub_info ^ scsi_module_name,
-    DataAddr = data_addr(ModuleName, DataName).
+    ).
 
 :- func init_vector_cell_group = vector_cell_group.
 
@@ -498,47 +493,45 @@
 %-----------------------------------------------------------------------------%
 
 get_static_cells(Info, ScalarDatas, VectorDatas) :-
-    ModuleName = Info ^ sci_sub_info ^ scsi_module_name,
     TypeNumMap = Info ^ sci_cell_type_num_map,
-    map.foldl(add_scalar_static_cell_for_type(ModuleName, TypeNumMap),
+    map.foldl(add_scalar_static_cell_for_type(TypeNumMap),
         Info ^ sci_scalar_cell_group_map, [], RevScalarDatas),
     list.reverse(RevScalarDatas, ScalarDatas),
-    map.foldl(add_all_vector_static_cells_for_type(ModuleName, TypeNumMap),
+    map.foldl(add_all_vector_static_cells_for_type(TypeNumMap),
         Info ^ sci_vector_cell_group_map, [], RevVectorDatas),
     list.reverse(RevVectorDatas, VectorDatas).
 
-:- pred add_scalar_static_cell_for_type(module_name::in,
-    cell_type_bimap::in, type_num::in, scalar_cell_group::in,
+:- pred add_scalar_static_cell_for_type(cell_type_bimap::in,
+    type_num::in, scalar_cell_group::in,
     list(scalar_common_data_array)::in, list(scalar_common_data_array)::out)
     is det.
 
-add_scalar_static_cell_for_type(ModuleName, TypeNumMap, TypeNum, CellGroup,
+add_scalar_static_cell_for_type(TypeNumMap, TypeNum, CellGroup,
         !Arrays) :-
     bimap.reverse_lookup(TypeNumMap, CellType, TypeNum),
     list.reverse(CellGroup ^ scalar_cell_rev_array, ArrayContents),
-    Array = scalar_common_data_array(ModuleName, CellType, TypeNum,
-        ArrayContents),
+    Array = scalar_common_data_array(CellType, TypeNum, ArrayContents),
     !:Arrays = [Array | !.Arrays].
 
-:- pred add_all_vector_static_cells_for_type(module_name::in,
-    cell_type_bimap::in, type_num::in, vector_cell_group::in,
+:- pred add_all_vector_static_cells_for_type(cell_type_bimap::in,
+    type_num::in, vector_cell_group::in,
     list(vector_common_data_array)::in, list(vector_common_data_array)::out)
     is det.
 
-add_all_vector_static_cells_for_type(ModuleName, TypeNumMap, TypeNum,
-        CellGroup, !Arrays) :-
+add_all_vector_static_cells_for_type(TypeNumMap, TypeNum, CellGroup,
+        !Arrays) :-
     bimap.reverse_lookup(TypeNumMap, CellType, TypeNum),
-    map.foldl(add_one_vector_static_cell(ModuleName, TypeNum, CellType),
+    map.foldl(add_one_vector_static_cell(TypeNum, CellType),
         CellGroup ^ vector_cell_map, !Arrays).
 
-:- pred add_one_vector_static_cell(module_name::in, type_num::in,
-    common_cell_type::in, int::in, vector_contents::in,
+:- pred add_one_vector_static_cell(type_num::in, common_cell_type::in,
+    int::in, vector_contents::in,
     list(vector_common_data_array)::in, list(vector_common_data_array)::out)
     is det.
 
-add_one_vector_static_cell(ModuleName, TypeNum, CellType, CellNum,
+add_one_vector_static_cell(TypeNum, CellType, CellNum,
         vector_contents(VectorContents), !Arrays) :-
-    Array = vector_common_data_array(ModuleName, CellType, TypeNum, CellNum,
+    Array = vector_common_data_array(CellType, TypeNum, CellNum,
         VectorContents),
     !:Arrays = [Array | !.Arrays].
 
@@ -640,7 +633,7 @@
 :- type cell_type_num_remap     == map(type_num, type_num).
                                     % Mapping of old to new type numbers.
 
-:- type scalar_cell_group_remap == map(data_name, data_name).
+:- type scalar_cell_group_remap == map(data_id, data_id).
                                     % Mapping of old to new data_names.
 
 bump_type_num_counter(Increment, !GlobalData) :-
@@ -765,30 +758,33 @@
 
 :- pred merge_scalar_cell_groups_2(type_num::in,
     list(common_cell_value)::in, list(common_cell_value)::in,
-    list(rval)::in, data_name::in,
-    bimap(list(rval), data_name)::in, bimap(list(rval), data_name)::out,
+    list(rval)::in, data_id::in,
+    bimap(list(rval), data_id)::in, bimap(list(rval), data_id)::out,
     scalar_cell_group_remap::in, scalar_cell_group_remap::out) is det.
 
 merge_scalar_cell_groups_2(TypeNum, ArrayB, ArrayAB,
-        Rvals, BDataName, !GroupMembers, !GroupRemap) :-
-    ( bimap.search(!.GroupMembers, Rvals, DataName) ->
+        Rvals, BDataId, !GroupMembers, !GroupRemap) :-
+    ( bimap.search(!.GroupMembers, Rvals, DataId) ->
         % Seen this list of rvals before in the group.
-        svmap.det_insert(BDataName, DataName, !GroupRemap)
+        svmap.det_insert(BDataId, DataId, !GroupRemap)
     ;
         % Not seen this list of rvals before in the group.
         (
-            BDataName = scalar_common_ref(_, BCellNum),
+            BDataId = scalar_common_data_id(_, BCellNum),
             % Look up what value this cell number referred to in the B array.
             % Find the cell number of the same value in the combined A+B array.
             CommonCellValue = list.det_index0(ArrayB, BCellNum),
             CellNum = nth_member_lookup0(ArrayAB, CommonCellValue),
             % Add the new data name.
-            DataName = scalar_common_ref(TypeNum, CellNum),
-            svbimap.det_insert(Rvals, DataName, !GroupMembers),
-            svmap.det_insert(BDataName, DataName, !GroupRemap)
-        ;
-            ( BDataName = vector_common_ref(_, _)
-            ; BDataName = proc_tabling_ref(_, _)
+            DataId = scalar_common_data_id(TypeNum, CellNum),
+            svbimap.det_insert(Rvals, DataId, !GroupMembers),
+            svmap.det_insert(BDataId, DataId, !GroupRemap)
+        ;
+            ( BDataId = rtti_data_id(_)
+            ; BDataId = proc_tabling_data_id(_, _)
+            ; BDataId = vector_common_data_id(_, _)
+            ; BDataId = layout_id(_)
+            ; BDataId = layout_slot_id(_, _)
             ),
             unexpected(this_file, "merge_scalar_cell_groups_2")
         )
@@ -1154,18 +1150,33 @@
 
 remap_rval_const(Remap, Const0, Const) :-
     (
-        Const0 = llconst_data_addr(Addr0, MaybeOffset),
+        Const0 = llconst_data_addr(DataId0, MaybeOffset),
         (
-            Addr0 = data_addr(ModuleName, DataName0),
-            remap_data_name(Remap, DataName0, DataName),
-            Addr = data_addr(ModuleName, DataName)
+            DataId0 = scalar_common_data_id(TypeNum0, _CellNum),
+            Remap = static_cell_remap_info(TypeNumRemap, ScalarCellGroupRemap),
+            ( map.contains(TypeNumRemap, TypeNum0) ->
+                map.lookup(ScalarCellGroupRemap, TypeNum0, ScalarCellGroup),
+                map.lookup(ScalarCellGroup, DataId0, DataId)
+            ;
+                DataId = DataId0
+            )
+        ;
+            DataId0 = vector_common_data_id(TypeNum0, CellNum),
+            Remap = static_cell_remap_info(TypeNumRemap, _),
+            ( map.search(TypeNumRemap, TypeNum0, TypeNum) ->
+                DataId = vector_common_data_id(TypeNum, CellNum)
         ;
-            ( Addr0 = rtti_addr(_)
-            ; Addr0 = layout_addr(_)
+                DataId = DataId0
+            )
+        ;
+            ( DataId0 = rtti_data_id(_)
+            ; DataId0 = proc_tabling_data_id(_, _)
+            ; DataId0 = layout_id(_)
+            ; DataId0 = layout_slot_id(_, _)
             ),
-            Addr = Addr0
+            DataId = DataId0
         ),
-        Const = llconst_data_addr(Addr,  MaybeOffset)
+        Const = llconst_data_addr(DataId,  MaybeOffset)
     ;
         ( Const0 = llconst_true
         ; Const0 = llconst_false
@@ -1179,31 +1190,6 @@
         Const = Const0
     ).
 
-:- pred remap_data_name(static_cell_remap_info::in,
-    data_name::in, data_name::out) is det.
-
-remap_data_name(Remap, DataName0, DataName) :-
-    Remap = static_cell_remap_info(TypeNumRemap, ScalarCellGroupRemap),
-    (
-        DataName0 = scalar_common_ref(TypeNum0, _Offset),
-        ( map.contains(TypeNumRemap, TypeNum0) ->
-            map.lookup(ScalarCellGroupRemap, TypeNum0, ScalarCellGroup),
-            map.lookup(ScalarCellGroup, DataName0, DataName)
-        ;
-            DataName = DataName0
-        )
-    ;
-        DataName0 = vector_common_ref(TypeNum0, Offset),
-        ( map.search(TypeNumRemap, TypeNum0, TypeNum) ->
-            DataName = vector_common_ref(TypeNum, Offset)
-        ;
-            DataName = DataName0
-        )
-    ;
-        DataName0 = proc_tabling_ref(_, _),
-        DataName = DataName0
-    ).
-
 :- pred remap_mem_ref(static_cell_remap_info::in, mem_ref::in, mem_ref::out)
     is det.
 
Index: compiler/hlds_rtti.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_rtti.m,v
retrieving revision 1.19
diff -u -b -r1.19 hlds_rtti.m
--- compiler/hlds_rtti.m	22 Sep 2009 04:38:23 -0000	1.19
+++ compiler/hlds_rtti.m	25 Oct 2009 09:51:28 -0000
@@ -38,18 +38,18 @@
 
 :- 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(mer_type),
-                pred_id                 ::  pred_id,
-                proc_id                 ::  proc_id,
-                proc_headvars           ::  assoc_list(prog_var,
+                rpl_pred_or_func            ::  pred_or_func,
+                rpl_this_module             ::  module_name,
+                rpl_proc_module             ::  module_name,
+                rpl_proc_name               ::  string,
+                rpl_proc_arity              ::  arity,
+                rpl_proc_arg_types          ::  list(mer_type),
+                rpl_pred_id                 ::  pred_id,
+                rpl_proc_id                 ::  proc_id,
+                rpl_proc_headvars           ::  assoc_list(prog_var,
                                                 prog_var_name),
-                proc_arg_modes          ::  list(arg_mode),
-                proc_interface_detism   ::  determinism,
+                rpl_proc_arg_modes          ::  list(arg_mode),
+                rpl_proc_interface_detism   ::  determinism,
 
                 % The following booleans hold values computed from the
                 % pred_info, using procedures
@@ -66,21 +66,21 @@
                 % abstract interfaces rather than hard-coding tests
                 % on the import_status.
 
-                pred_is_imported        ::  bool,
-                pred_is_pseudo_imported ::  bool,
-                pred_info_origin        ::  pred_origin,
+                rpl_pred_is_imported        ::  bool,
+                rpl_pred_is_pseudo_imported ::  bool,
+                rpl_pred_info_origin        ::  pred_origin,
 
                 % The following boolean holds a value computed from the
                 % proc_info, using procedure_is_exported/2
 
-                proc_is_exported        ::  bool,
+                rpl_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
+                rpl_proc_is_imported        ::  bool
             ).
 
     % Construct an rtti_proc_label for a given procedure.
@@ -105,35 +105,33 @@
 :- type instance_method_constraints
     --->    instance_method_constraints(
                 class_id,
-                list(mer_type),         % The types in the head of the
-                                        % instance declaration.
-                list(prog_constraint),  % The universal constraints
-                                        % on the instance declaration.
-                prog_constraints        % The contraints on the method's
-                                        % type declaration in the
+
+                % The types in the head of the instance declaration.
+                list(mer_type),
+
+                % The universal constraints on the instance declaration.
+                list(prog_constraint),
+
+                % The contraints on the method's type declaration in the
                                         % `:- typeclass' declaration.
+                prog_constraints
             ).
 
     %  A type_info_locn specifies how to access a type_info.
     %
 :- type type_info_locn
     --->    type_info(prog_var)
-                % It is a normal type_info, i.e. the type
-                % is not constrained.
+            % It is a normal type_info, i.e. the type is not constrained.
 
     ;       typeclass_info(prog_var, int).
-                % The type_info is packed inside a
-                % typeclass_info. If the int is N, it is
-                % the Nth type_info inside the typeclass_info,
-                % but there may be several superclass pointers
-                % before the block of type_infos, so it won't
-                % be the Nth word of the typeclass_info.
-                %
-                % To find the type_info inside the
-                % typeclass_info, use the predicate
-                % type_info_from_typeclass_info from Mercury
-                % code; from C code use the macro
-                % MR_typeclass_info_superclass_info.
+            % The type_info is packed inside a typeclass_info. If the int is N,
+            % it is the Nth type_info inside the typeclass_info, but there
+            % may be several superclass pointers before the block of
+            % type_infos, so it won't be the Nth word of the typeclass_info.
+            %
+            % To find the type_info inside the typeclass_info, use the
+            % predicate type_info_from_typeclass_info from Mercury code;
+            % from C code use the macro MR_typeclass_info_superclass_info.
 
     % type_info_locn_var(TypeInfoLocn, Var):
     %
@@ -388,9 +386,9 @@
         PredIsImported, PredIsPseudoImp, Origin,
         ProcIsExported, ProcIsImported).
 
-proc_label_pred_proc_id(ProcLabel, PredId, ProcId) :-
-    PredId = ProcLabel ^ pred_id,
-    ProcId = ProcLabel ^ proc_id.
+proc_label_pred_proc_id(RttiProcLabel, PredId, ProcId) :-
+    PredId = RttiProcLabel ^ rpl_pred_id,
+    ProcId = RttiProcLabel ^ rpl_proc_id.
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.41
diff -u -b -r1.41 layout.m
--- compiler/layout.m	21 Oct 2009 06:36:19 -0000	1.41
+++ compiler/layout.m	27 Oct 2009 13:42:50 -0000
@@ -48,22 +48,28 @@
 :- import_module maybe.
 
 %-----------------------------------------------------------------------------%
+%
+% Closure layouts.
+%
 
-    % This type is for strings which may contain embedded null characters.
-    % When a string_with_0s is written, a null character will be written
-    % in between each string in the list.
-:- type string_with_0s
-    --->    string_with_0s(list(string)).
-
-:- type event_set_layout_data
-    --->    event_set_layout_data(
-                event_set_data,
-
-                % Maps each event number to an rval that gives the vector
-                % of typeinfos for the arguments of that event.
-                map(int, rval)
+:- type closure_proc_id_data
+    --->    closure_proc_id_data(
+                % defines MR_ClosureId
+                caller_proc_label       :: proc_label,
+                caller_closure_seq_no   :: int,
+                closure_proc_label      :: proc_label,
+                closure_module_name     :: module_name,
+                closure_file_name       :: string,
+                closure_line_number     :: int,
+                closure_origin          :: pred_origin,
+                closure_goal_path       :: string
             ).
 
+%-----------------------------------------------------------------------------%
+%
+% Proc layouts and their components.
+%
+
 :- type user_event_data
     --->    user_event_data(
                 user_event_number       :: int,
@@ -83,11 +89,25 @@
                 maybe_user_info         :: maybe(layout_slot_name)
             ).
 
-:- type label_layout_vars
-    --->    label_layout_vars(
-                % defines MR_LabelLayout
-                basic_label_layout,
-                label_var_info
+:- type label_short_var_info
+    --->    label_short_var_info(
+                % part of MR_LabelLayout
+                lsvi_encoded_var_count  :: int, % encodes #Long=0 and #Short
+                lsvi_type_params        :: rval,
+                lsvi_ptis               :: int, % -1 if none, otherwise slot#
+                lsvi_hlds_var_nums      :: int, % -1 if none, otherwise slot#
+                lsvi_short_locns        :: int  % -1 if none, otherwise slot#
+            ).
+
+:- type label_long_var_info
+    --->    label_long_var_info(
+                % part of MR_LabelLayout
+                llvi_encoded_var_count  :: int, % encodes #Long>0 and #Short
+                llvi_type_params        :: rval,
+                llvi_ptis               :: int, % -1 if none, otherwise slot#
+                llvi_hlds_var_nums      :: int, % -1 if none, otherwise slot#
+                llvi_short_locns        :: int, % -1 if none, otherwise slot#
+                llvi_long_locns         :: int  % -1 if none, otherwise slot#
             ).
 
 :- type label_layout_no_vars
@@ -96,70 +116,35 @@
                 basic_label_layout
             ).
 
-:- type layout_data
-    --->    proc_layout_data(
-                % defines MR_ProcLayout
-                proc_layout_label       :: rtti_proc_label,
-                proc_layout_trav        :: proc_layout_stack_traversal,
-                proc_layout_more        :: maybe_proc_id_and_more
-            )
-    ;       module_layout_common_data(
-                % defines MR_ModuleCommonLayout
-                module_common_name      :: module_name,
-                string_table_size       :: int,
-                string_table            :: string_with_0s
-            )
-    ;       module_layout_data(
-                % defines MR_ModuleLayout
-                module_name             :: module_name,
-                module_common           :: layout_name,
-                proc_layout_names       :: list(layout_name),
-                file_layouts            :: list(file_layout_data),
-                trace_level             :: trace_level,
-                suppressed_events       :: int,
-                num_label_exec_count    :: int,
-                maybe_event_specs       :: maybe(event_set_layout_data)
-            )
-    ;       closure_proc_id_data(
-                % defines MR_ClosureId
-                caller_proc_label       :: proc_label,
-                caller_closure_seq_no   :: int,
-                closure_proc_label      :: proc_label,
-                closure_module_name     :: module_name,
-                closure_file_name       :: string,
-                closure_line_number     :: int,
-                closure_origin          :: pred_origin,
-                closure_goal_path       :: string
-            )
-    ;       table_io_decl_data(
-                % defines MR_TableIoDecl
-                table_io_decl_proc_ptr  :: rtti_proc_label,
-                table_io_decl_kind      :: proc_layout_kind,
-                table_io_decl_num_ptis  :: int,
-
-                % pseudo-typeinfos for headvars
-                table_io_decl_ptis      :: rval,
-
-                table_io_decl_type_params :: rval
+:- type label_layout_short_vars
+    --->    label_layout_short_vars(
+                % defines MR_LabelLayout
+                basic_label_layout,
+                label_short_var_info
             ).
 
-:- type label_var_info
-    --->    label_var_info(             % part of MR_LabelLayout
-                encoded_var_count       :: int,
-                locns_types             :: rval,
-                var_nums                :: rval,
-                type_params             :: rval
+:- type label_layout_long_vars
+    --->    label_layout_long_vars(
+                % defines MR_LabelLayout
+                basic_label_layout,
+                label_long_var_info
             ).
 
-:- type proc_layout_stack_traversal     % defines MR_StackTraversal
+%-----------------------------------------------------------------------------%
+%
+% Proc layouts and their components.
+%
+
+:- type proc_layout_stack_traversal
     --->    proc_layout_stack_traversal(
+                % defines MR_StackTraversal
                 % The proc entry label will be `no' if we don't have
                 % static code addresses.
-                entry_label             :: maybe(label),
+                plst_entry_label        :: maybe(label),
 
-                succip_slot             :: maybe(int),
-                stack_slot_count        :: int,
-                detism                  :: determinism
+                plst_succip_slot        :: maybe(int),
+                plst_stack_slot_count   :: int,
+                plst_detism             :: determinism
             ).
 
     % The deep_slot_info gives the stack slot numbers that hold
@@ -180,55 +165,106 @@
 
 :- type proc_layout_proc_static
     --->    proc_layout_proc_static(
-                hlds_proc_static        :: hlds_proc_static,
-                deep_excp_slots         :: deep_excp_slots,
-                deep_original_body      :: deep_original_body 
+                plps_file_name          :: string,
+                plps_line_number        :: int,
+                plps_is_in_interface    :: bool,
+                plps_excp_slots         :: deep_excp_slots,
+                plps_call_site_statics  :: maybe({int, int}),
+                plps_coverage_points    :: maybe({int, int})
             ).
 
-:- type maybe_proc_id_and_more
-    --->    no_proc_id_and_more
-    ;       proc_id_and_more(
-                maybe_proc_static       :: maybe(proc_layout_proc_static),
-                maybe_exec_trace        :: maybe(proc_layout_exec_trace),
+:- type table_io_decl_data
+    --->    table_io_decl_data(
+                % defines MR_TableIoDecl
+                tid_proc_ptr            :: layout_name,
+                tid_num_ptis            :: int,
 
-                % The procedure body represented as a list of bytecodes.
-                proc_body_bytes         :: list(int),
+                % pseudo-typeinfos for headvars
+                tid_ptis                :: rval,
 
-                % The name of the module_common_layout structure.
-                proc_module_common      :: layout_name
+                tid_type_params         :: rval
             ).
 
-:- type proc_layout_exec_trace          % defines MR_ExecTrace
+:- type data_or_slot_id
+    --->    data_or_slot_is_data(data_id)
+    ;       data_or_slot_is_slot(layout_slot_name).
+
+:- type proc_layout_exec_trace
     --->    proc_layout_exec_trace(
-                maybe_call_label_layout :: maybe(layout_slot_name),
+                % defines MR_ExecTrace
+                plet_maybe_call_label_slot  :: maybe(layout_slot_name),
 
                 % The label layouts of the events in the predicate.
-                % Interface events first, internal events second.
-                interface_event_layouts :: list(layout_slot_name),
-                internal_event_layouts  :: list(layout_slot_name),
+                plet_proc_event_layouts     :: layout_slot_name,
+                plet_num_proc_event_layouts :: int,
 
-                maybe_table_info        :: maybe(data_addr),
+                plet_maybe_table_info       :: maybe(data_or_slot_id),
 
                 % The variable numbers of the head variables, including the
                 % ones added by the compiler, in order. The length of the list
-                % must be the same as the procedure's arity.
-                head_var_nums           :: list(int),
+                % must be the same as the procedure's arity. The maybe will be
+                % `no' if the procedure has no head variables.
+                plet_head_var_nums          :: maybe(layout_slot_name),
+                plet_num_head_var_nums      :: int,
 
                 % Each variable name is an offset into the module's
-                % string table.
-                var_names               :: list(int),
+                % string table. The maybe will be `no' if the procedure
+                % has no variables.
+                plet_var_names              :: maybe(layout_slot_name),
+
+                plet_max_var_num            :: int,
+                plet_max_r_num              :: int,
+                plet_maybe_from_full_slot   :: maybe(int),
+                plet_maybe_io_seq_slot      :: maybe(int),
+                plet_maybe_trail_slot       :: maybe(int),
+                plet_maybe_maxfr_slot       :: maybe(int),
+                plet_eval_method            :: eval_method,
+                plet_maybe_call_table_slot  :: maybe(int),
+                plet_maybe_tail_rec_slot    :: maybe(int),
+                plet_eff_trace_level        :: trace_level,
+                plet_exec_trace_flags       :: int
+            ).
 
-                max_var_num             :: int,
-                max_r_num               :: int,
-                maybe_from_full_slot    :: maybe(int),
-                maybe_io_seq_slot       :: maybe(int),
-                maybe_trail_slot        :: maybe(int),
-                maybe_maxfr_slot        :: maybe(int),
-                eval_method             :: eval_method,
-                maybe_call_table_slot   :: maybe(int),
-                maybe_tail_rec_slot     :: maybe(int),
-                eff_trace_level         :: trace_level,
-                exec_trace_flags        :: int
+:- type maybe_proc_id_and_more
+    --->    no_proc_id_and_more
+    ;       proc_id_and_more(
+                maybe_proc_static       :: maybe(layout_slot_name),
+                maybe_exec_trace        :: maybe(layout_slot_name),
+
+                % The procedure body represented as a list of bytecodes.
+                proc_body_bytes         :: maybe(layout_slot_name),
+
+                % The name of the module_common_layout structure.
+                proc_module_common      :: layout_name
+            ).
+
+:- type proc_layout_data
+    --->    proc_layout_data(
+                % defines MR_ProcLayout
+                proc_layout_label       :: rtti_proc_label,
+                proc_layout_trav        :: proc_layout_stack_traversal,
+                proc_layout_more        :: maybe_proc_id_and_more
+            ).
+
+%-----------------------------------------------------------------------------%
+%
+% Module layouts and their components.
+%
+
+    % This type is for strings which may contain embedded null characters.
+    % When a string_with_0s is written, a null character will be written
+    % in between each string in the list.
+    %
+:- type string_with_0s
+    --->    string_with_0s(list(string)).
+
+:- type event_set_layout_data
+    --->    event_set_layout_data(
+                event_set_data,
+
+                % Maps each event number to an rval that gives the vector
+                % of typeinfos for the arguments of that event.
+                map(int, rval)
             ).
 
 :- type file_layout_data
@@ -237,31 +273,98 @@
                 line_no_label_list      :: assoc_list(int, layout_slot_name)
             ).
 
+:- type module_layout_data
+    --->    module_layout_common_data(
+                % defines MR_ModuleCommonLayout
+                module_common_name      :: module_name,
+                string_table_size       :: int,
+                string_table            :: string_with_0s
+            )
+    ;       module_layout_data(
+                % defines MR_ModuleLayout
+                module_name             :: module_name,
+                module_common           :: layout_name,
+                proc_layout_names       :: list(layout_name),
+                file_layouts            :: list(file_layout_data),
+                trace_level             :: trace_level,
+                suppressed_events       :: int,
+                num_label_exec_count    :: int,
+                maybe_event_specs       :: maybe(event_set_layout_data)
+            ).
+
 %-----------------------------------------------------------------------------%
+%
+% Global variables that hold arrays of layout structures.
+%
+
+:- type label_vars
+    --->    label_has_no_var_info
+    ;       label_has_short_var_info
+    ;       label_has_long_var_info.
 
 :- type layout_slot_name
     --->    layout_slot(layout_array_name, int).
 
 :- type layout_array_name
-    --->    label_layout_array(label_vars)
+    --->    pseudo_type_info_array
+    ;       hlds_var_nums_array
+    ;       short_locns_array
+    ;       long_locns_array
     ;       user_event_layout_array
-    ;       user_event_var_nums_array.
+    ;       user_event_var_nums_array
+    ;       label_layout_array(label_vars)
 
-:- type layout_name
-    --->    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_label_layouts(rtti_proc_label)
-    ;       proc_layout_head_var_nums(rtti_proc_label)
+    ;       proc_static_call_sites_array
+    ;       proc_static_cp_static_array
+    ;       proc_static_cp_dynamic_array
+    ;       proc_static_array
+    ;       proc_head_var_nums_array
             % 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(rtti_proc_label)
+    ;       proc_var_names_array
             % A vector of variable names (represented as offsets into
             % the string table) for a procedure layout structure.
-    ;       proc_layout_body_bytecode(rtti_proc_label)
-    ;       table_io_decl(rtti_proc_label)
+    ;       proc_body_bytecodes_array
+    ;       proc_table_io_decl_array
+    ;       proc_event_layouts_array
+    ;       proc_exec_trace_array.
+
+%-----------------------------------------------------------------------------%
+%
+% Global variables that hold individual layout structures.
+%
+
+:- type proc_layout_kind
+    --->    proc_layout_traversal
+    ;       proc_layout_proc_id(proc_layout_user_or_uci).
+
+:- type proc_layout_user_or_uci
+    --->    user
+    ;       uci.
+
+    % Each layout_name identifies a global variable holding one layout
+    % structure. We prefer to put layout structures into arrays, because
+    % one array holding all N layout structures of a given kind require
+    % less space in the symbol table and relocation information sections
+    % of object files than N separate global variables, and the reduction
+    % in the number of symbols should also improve link times. In some arrays,
+    % it is also possible to use an element or sequence of elements two or more
+    % times, giving an element of compression.
+    %
+    % The layout structures we still put into global variables individually are
+    %
+    % - procedure layouts, which have to have a name derivable from the name of
+    %   the procedure they represent, since in deep profiling grades call site
+    %   static structures contain pointers to the proc layout structures of the
+    %   callee procedures;
+    % - layouts for closures, which are relatively few in number,
+    %   so arrays would do little good; and
+    % - module layouts and their components, of which each module will have
+    %   just one, so arrays would do absolutely *no* good.
+    %
+:- type layout_name
+    --->    proc_layout(rtti_proc_label, proc_layout_kind)
     ;       closure_proc_id(proc_label, int, proc_label)
     ;       file_layout(module_name, int)
     ;       file_layout_line_number_vector(module_name, int)
@@ -278,26 +381,7 @@
     ;       module_layout_event_synth_order(module_name, int)
     ;       module_layout_event_specs(module_name)
     ;       module_common_layout(module_name)
-    ;       module_layout(module_name)
-    ;       proc_static(rtti_proc_label)
-    ;       proc_static_call_sites(rtti_proc_label)
-    ;       proc_static_coverage_point_static(rtti_proc_label)
-    ;       proc_static_coverage_point_dynamic(rtti_proc_label).
-
-:- type label_layout_details
-    --->    label_layout_details(proc_label, int, label_vars).
-
-:- type label_vars
-    --->    label_has_var_info
-    ;       label_has_no_var_info.
-
-:- type proc_layout_kind
-    --->    proc_layout_traversal
-    ;       proc_layout_proc_id(proc_layout_user_or_uci).
-
-:- type proc_layout_user_or_uci
-    --->    user
-    ;       uci.
+    ;       module_layout(module_name).
 
 %-----------------------------------------------------------------------------%
 :- end_module layout.
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.104
diff -u -b -r1.104 layout_out.m
--- compiler/layout_out.m	21 Oct 2009 06:36:19 -0000	1.104
+++ compiler/layout_out.m	28 Oct 2009 03:09:17 -0000
@@ -23,9 +23,12 @@
 :- module ll_backend.layout_out.
 :- interface.
 
+:- import_module hlds.hlds_pred.
 :- import_module ll_backend.layout.
+:- import_module ll_backend.llds.
 :- import_module ll_backend.llds_out.
 :- import_module mdbcomp.prim_data.
+:- import_module mdbcomp.program_representation.
 
 :- import_module bool.
 :- import_module io.
@@ -34,26 +37,50 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_user_event_var_nums_array_defn(llds_out_info::in,
-    list(maybe(int))::in, io::di, io::uo) is det.
-
-:- pred output_user_events_array_defn(llds_out_info::in,
-    list(user_event_data)::in, io::di, io::uo) is det.
-
-:- pred output_var_label_layouts_array_defn(llds_out_info::in,
-    list(label_layout_vars)::in, io::di, io::uo) is det.
-
-:- pred output_no_var_label_layouts_array_defn(llds_out_info::in,
-    list(label_layout_no_vars)::in, io::di, io::uo) is det.
+:- pred output_layout_array_decls(llds_out_info::in,
+    list(rval)::in, list(int)::in, list(int)::in, list(int)::in,
+    list(maybe(int))::in, list(user_event_data)::in,
+    list(label_layout_no_vars)::in,
+    list(label_layout_short_vars)::in, list(label_layout_long_vars)::in,
+    list(call_site_static_data)::in, list(coverage_point_info)::in,
+    list(proc_layout_proc_static)::in,
+    list(int)::in, list(int)::in, list(int)::in, list(table_io_decl_data)::in,
+    list(layout_slot_name)::in, list(proc_layout_exec_trace)::in,
+    io::di, io::uo) is det.
+
+:- pred output_layout_array_defns(llds_out_info::in,
+    list(rval)::in, list(int)::in, list(int)::in, list(int)::in,
+    list(maybe(int))::in, list(user_event_data)::in,
+    list(label_layout_no_vars)::in,
+    list(label_layout_short_vars)::in, list(label_layout_long_vars)::in,
+    list(call_site_static_data)::in, list(coverage_point_info)::in,
+    list(proc_layout_proc_static)::in,
+    list(int)::in, list(int)::in, list(int)::in, list(table_io_decl_data)::in,
+    list(layout_slot_name)::in, list(proc_layout_exec_trace)::in,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 %-----------------------------------------------------------------------------%
 
-    % Given a Mercury representation of a layout structure, output its
+    % Given a Mercury representation of a proc layout structure, output its
     % definition in the appropriate C global variable.
     %
-:- pred output_layout_data_defn(llds_out_info::in, layout_data::in,
+:- pred output_proc_layout_data_defn(llds_out_info::in, proc_layout_data::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
+    % Given a Mercury representation of a module layout structure, output its
+    % definition in the appropriate C global variable.
+    %
+:- pred output_module_layout_data_defn(llds_out_info::in,
+    module_layout_data::in, decl_set::in, decl_set::out,
+    io::di, io::uo) is det.
+
+    % Given a Mercury representation of a closure layout structure, output its
+    % definition in the appropriate C global variable.
+    %
+:- pred output_closure_layout_data_defn(llds_out_info::in,
+    closure_proc_id_data::in, decl_set::in, decl_set::out,
+    io::di, io::uo) is det.
+
     % Given the name of a layout structure, output the declaration
     % of the C global variable which will hold it.
     %
@@ -65,13 +92,6 @@
 :- pred output_maybe_layout_name_decl(layout_name::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-    % Given a Mercury representation of a layout structure, output the
-    % declaration of the C global variable which will hold it, if it has
-    % not already been declared.
-    %
-:- pred output_maybe_layout_data_decl(layout_data::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
 :- type being_defined
     --->    not_being_defined
     ;       being_defined.
@@ -106,10 +126,16 @@
 :- pred output_layout_array_name(use_layout_macro::in, string::in,
     layout_array_name::in, io::di, io::uo) is det.
 
+    % Given the mangled name of the module, output the id of the given layout
+    % array slot.
+    %
+:- pred output_layout_slot_id(use_layout_macro::in, string::in,
+    layout_slot_name::in, io::di, io::uo) is det.
+
     % Given the mangled name of the module, output a reference to the address
     % of the given layout array slot.
     %
-:- pred output_layout_slot_name(use_layout_macro::in, string::in,
+:- pred output_layout_slot_addr(use_layout_macro::in, string::in,
     layout_slot_name::in, io::di, io::uo) is det.
 
     % Given a reference to a layout structure, output the name of the
@@ -146,13 +172,10 @@
 :- import_module backend_libs.name_mangle.
 :- import_module backend_libs.proc_label.
 :- import_module hlds.hlds_goal.
-:- import_module hlds.hlds_pred.
 :- import_module hlds.hlds_rtti.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.trace_params.
-:- import_module ll_backend.llds.
-:- import_module mdbcomp.program_representation.
 :- import_module parse_tree.mercury_to_mercury.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_foreign.
@@ -167,6 +190,402 @@
 
 %-----------------------------------------------------------------------------%
 
+output_layout_array_decls(Info, PseudoTypeInfos, HLDSVarNums,
+        ShortLocns, LongLocns, UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
+        CallSiteStatics, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes, TableIoDecls,
+        ProcEventLayouts, ExecTraces, !IO) :-
+    MangledModuleName = Info ^ lout_mangled_module_name,
+    (
+        PseudoTypeInfos = []
+    ;
+        PseudoTypeInfos = [_ | _],
+        PseudoTypeInfoArrayName = pseudo_type_info_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            PseudoTypeInfoArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        HLDSVarNums = []
+    ;
+        HLDSVarNums = [_ | _],
+        HLDSVarNumArrayName = hlds_var_nums_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            HLDSVarNumArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        ShortLocns = []
+    ;
+        ShortLocns = [_ | _],
+        ShortLocnArrayName = short_locns_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            ShortLocnArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        LongLocns = []
+    ;
+        LongLocns = [_ | _],
+        LongLocnArrayName = long_locns_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            LongLocnArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        UserEventVarNums = []
+    ;
+        UserEventVarNums = [_ | _],
+        UserEventVarNumArrayName = user_event_var_nums_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            UserEventVarNumArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        UserEvents = []
+    ;
+        UserEvents = [_ | _],
+        UserEventsArrayName = user_event_layout_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            UserEventsArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        NoVarLabelLayouts = []
+    ;
+        NoVarLabelLayouts = [_ | _],
+        NoVarLabelLayoutArrayName = label_layout_array(label_has_no_var_info),
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            NoVarLabelLayoutArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        SVarLabelLayouts = []
+    ;
+        SVarLabelLayouts = [_ | _],
+        SVarLabelLayoutArrayName =
+            label_layout_array(label_has_short_var_info),
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            SVarLabelLayoutArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        LVarLabelLayouts = []
+    ;
+        LVarLabelLayouts = [_ | _],
+        LVarLabelLayoutArrayName =
+            label_layout_array(label_has_long_var_info),
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            LVarLabelLayoutArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        CallSiteStatics = []
+    ;
+        CallSiteStatics = [_ | _],
+        CallSiteStaticsArrayName = proc_static_call_sites_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            CallSiteStaticsArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        CoveragePoints = []
+    ;
+        CoveragePoints = [_ | _],
+        CoveragePointsStaticArrayName = proc_static_cp_static_array,
+        CoveragePointsDynamicArrayName = proc_static_cp_dynamic_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            CoveragePointsStaticArrayName, not_being_defined, !IO),
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            CoveragePointsDynamicArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        ProcStatics = []
+    ;
+        ProcStatics = [_ | _],
+        ProcStaticArrayName = proc_static_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            ProcStaticArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        ProcHeadVarNums = []
+    ;
+        ProcHeadVarNums = [_ | _],
+        ProcHeadVarNumArrayName = proc_head_var_nums_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            ProcHeadVarNumArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        ProcVarNames = []
+    ;
+        ProcVarNames = [_ | _],
+        ProcVarNameArrayName = proc_var_names_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            ProcVarNameArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        ProcBodyBytecodes = []
+    ;
+        ProcBodyBytecodes = [_ | _],
+        ProcBodyBytecodeArrayName = proc_body_bytecodes_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            ProcBodyBytecodeArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        TableIoDecls = []
+    ;
+        TableIoDecls = [_ | _],
+        TableIoDeclArrayName = proc_table_io_decl_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            TableIoDeclArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        ExecTraces = []
+    ;
+        ExecTraces = [_ | _],
+        ExecTraceArrayName = proc_exec_trace_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            ExecTraceArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ),
+    (
+        ProcEventLayouts = []
+    ;
+        ProcEventLayouts = [_ | _],
+        ProcEventLayoutArrayName = proc_event_layouts_array,
+        output_layout_array_name_storage_type_name(MangledModuleName,
+            ProcEventLayoutArrayName, not_being_defined, !IO),
+        io.write_string("[];\n", !IO)
+    ).
+
+output_layout_array_defns(Info, PseudoTypeInfos, HLDSVarNums,
+        ShortLocns, LongLocns, UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
+        CallSiteStatics, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes, TableIoDecls,
+        ProcEventLayouts, ExecTraces, !DeclSet, !IO) :-
+    (
+        PseudoTypeInfos = []
+    ;
+        PseudoTypeInfos = [_ | _],
+        output_pseudo_type_info_array_defn(Info, PseudoTypeInfos, !IO)
+    ),
+    (
+        HLDSVarNums = []
+    ;
+        HLDSVarNums = [_ | _],
+        output_hlds_var_nums_array_defn(Info, HLDSVarNums, !IO)
+    ),
+    (
+        ShortLocns = []
+    ;
+        ShortLocns = [_ | _],
+        output_short_locns_array_defn(Info, ShortLocns, !IO)
+    ),
+    (
+        LongLocns = []
+    ;
+        LongLocns = [_ | _],
+        output_long_locns_array_defn(Info, LongLocns, !IO)
+    ),
+    (
+        UserEventVarNums = []
+    ;
+        UserEventVarNums = [_ | _],
+        output_user_event_var_nums_array_defn(Info, UserEventVarNums, !IO)
+    ),
+    (
+        UserEvents = []
+    ;
+        UserEvents = [_ | _],
+        output_user_events_array_defn(Info, UserEvents, !IO)
+    ),
+    (
+        NoVarLabelLayouts = []
+    ;
+        NoVarLabelLayouts = [_ | _],
+        output_no_var_label_layouts_array_defn(Info, NoVarLabelLayouts, !IO)
+    ),
+    (
+        SVarLabelLayouts = []
+    ;
+        SVarLabelLayouts = [_ | _],
+        output_short_var_label_layouts_array_defn(Info, SVarLabelLayouts, !IO)
+    ),
+    (
+        LVarLabelLayouts = []
+    ;
+        LVarLabelLayouts = [_ | _],
+        output_long_var_label_layouts_array_defn(Info, LVarLabelLayouts, !IO)
+    ),
+    (
+        CallSiteStatics = []
+    ;
+        CallSiteStatics = [_ | _],
+        output_call_site_static_array(Info, CallSiteStatics, !DeclSet, !IO)
+    ),
+    (
+        CoveragePoints = []
+    ;
+        CoveragePoints = [_ | _],
+        list.length(CoveragePoints, NumCoveragePoints),
+        output_proc_static_cp_static_array(Info, CoveragePoints,
+            NumCoveragePoints, !IO),
+        output_proc_static_cp_dynamic_array(Info, NumCoveragePoints, !IO)
+    ),
+    (
+        ProcStatics = []
+    ;
+        ProcStatics = [_ | _],
+        output_proc_statics_array_defn(Info, ProcStatics, !IO)
+    ),
+    (
+        ProcHeadVarNums = []
+    ;
+        ProcHeadVarNums = [_ | _],
+        output_proc_head_var_nums_array(Info, ProcHeadVarNums, !IO)
+    ),
+    (
+        ProcVarNames = []
+    ;
+        ProcVarNames = [_ | _],
+        output_proc_var_names_array(Info, ProcVarNames, !IO)
+    ),
+    (
+        ProcBodyBytecodes = []
+    ;
+        ProcBodyBytecodes = [_ | _],
+        output_proc_body_bytecodes_array(Info, ProcBodyBytecodes, !IO)
+    ),
+    (
+        TableIoDecls = []
+    ;
+        TableIoDecls = [_ | _],
+        output_table_io_decl_array(Info, TableIoDecls, !IO)
+    ),
+    (
+        ProcEventLayouts = []
+    ;
+        ProcEventLayouts = [_ | _],
+        output_proc_event_layout_array(Info, ProcEventLayouts, !IO)
+    ),
+    (
+        ExecTraces = []
+    ;
+        ExecTraces = [_ | _],
+        output_exec_traces_array(Info, ExecTraces, !IO)
+    ).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #1: pseudo_typeinfos.
+%
+
+:- pred output_pseudo_type_info_array_defn(llds_out_info::in, list(rval)::in,
+    io::di, io::uo) is det.
+
+output_pseudo_type_info_array_defn(Info, PTIs, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(PTIs, NumPTIs),
+    Name = pseudo_type_info_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {", [i(NumPTIs)], !IO),
+    list.chunk(PTIs, 10, PTIChunks),
+    list.foldl2(output_pti_chunk(Info), PTIChunks, 0, _, !IO),
+    io.write_string("\n};\n\n", !IO).
+
+:- pred output_pti_chunk(llds_out_info::in, list(rval)::in, int::in, int::out,
+    io::di, io::uo) is det.
+
+output_pti_chunk(Info, ChunkPTIs, !Slot, !IO) :-
+    list.length(ChunkPTIs, NumChunkPTIs),
+    AutoComments = Info ^ lout_auto_comments,
+    (
+        AutoComments = yes,
+        io.format("\n/* slots %d+ */ MR_cast_to_pti%d(\n\t",
+            [i(!.Slot), i(NumChunkPTIs)], !IO)
+    ;
+        AutoComments = no,
+        io.format("\nMR_cast_to_pti%d(",
+            [i(NumChunkPTIs)], !IO)
+    ),
+    io.write_list(ChunkPTIs, ",\n\t", output_rval(Info), !IO),
+    io.write_string(")", !IO),
+    !:Slot = !.Slot + NumChunkPTIs.
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #2: HLDS var numbers.
+%
+
+:- pred output_hlds_var_nums_array_defn(llds_out_info::in,
+    list(int)::in, io::di, io::uo) is det.
+
+output_hlds_var_nums_array_defn(Info, VarNums, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(VarNums, NumVarNums),
+    Name = hlds_var_nums_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {", [i(NumVarNums)], !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    list.foldl2(output_number_in_vector(AutoComments), VarNums, 0, _, !IO),
+    io.write_string("\n};\n\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #3: MR_ShortLvals.
+%
+
+:- pred output_short_locns_array_defn(llds_out_info::in,
+    list(int)::in, io::di, io::uo) is det.
+
+output_short_locns_array_defn(Info, ShortLocns, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(ShortLocns, NumShortLocns),
+    Name = short_locns_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {", [i(NumShortLocns)], !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    list.foldl2(output_number_in_vector(AutoComments), ShortLocns, 0, _, !IO),
+    io.write_string("\n};\n\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #4: MR_LongLvals.
+%
+
+:- pred output_long_locns_array_defn(llds_out_info::in,
+    list(int)::in, io::di, io::uo) is det.
+
+output_long_locns_array_defn(Info, LongLocns, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(LongLocns, NumLongLocns),
+    Name = long_locns_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {", [i(NumLongLocns)], !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    list.foldl2(output_number_in_vector(AutoComments), LongLocns, 0, _, !IO),
+    io.write_string("\n};\n\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #5: user event variable numbers.
+%
+
+:- pred output_user_event_var_nums_array_defn(llds_out_info::in,
+    list(maybe(int))::in, io::di, io::uo) is det.
+
 output_user_event_var_nums_array_defn(Info, MaybeVarNums, !IO) :-
     ModuleName = Info ^ lout_mangled_module_name,
     list.length(MaybeVarNums, NumMaybeVarNums),
@@ -197,6 +616,12 @@
     !:Slot = !.Slot + 1.
 
 %-----------------------------------------------------------------------------%
+%
+% Definition of array #6: user events.
+%
+
+:- pred output_user_events_array_defn(llds_out_info::in,
+    list(user_event_data)::in, io::di, io::uo) is det.
 
 output_user_events_array_defn(Info, UserEvents, !IO) :-
     ModuleName = Info ^ lout_mangled_module_name,
@@ -214,151 +639,300 @@
 output_user_event_slot(Info, UserEvent, !Slot, !IO) :-
     UserEvent = user_event_data(UserEventNumber, UserLocnsRval,
         MaybeVarNumsSlot),
-    io.format("  { /* slot %d */ %d, ",
-        [i(!.Slot), i(UserEventNumber)], !IO),
-    io.write_string("(MR_LongLval *) ", !IO),
+    io.write_string("{ ", !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    (
+        AutoComments = yes,
+        io.format("/* slot %d */ ", [i(!.Slot)], !IO)
+    ;
+        AutoComments = no
+    ),
+    io.write_int(UserEventNumber, !IO),
+    io.write_string(", (MR_LongLval *) ", !IO),
     output_rval_as_addr(Info, UserLocnsRval, !IO),
     io.write_string(",\n    ", !IO),
     ModuleName = Info ^ lout_mangled_module_name,
-    output_layout_slot_name(use_layout_macro, ModuleName, MaybeVarNumsSlot,
+    output_layout_slot_addr(use_layout_macro, ModuleName, MaybeVarNumsSlot,
         !IO),
     io.write_string(" },\n", !IO),
     !:Slot = !.Slot + 1.
 
 %-----------------------------------------------------------------------------%
+%
+% Definition of array #7: label layout structures for labels with
+% no variable information.
+%
+
+:- pred output_no_var_label_layouts_array_defn(llds_out_info::in,
+    list(label_layout_no_vars)::in, io::di, io::uo) is det.
 
-output_var_label_layouts_array_defn(Info, LabelLayouts, !IO) :-
+output_no_var_label_layouts_array_defn(Info, LabelLayouts, !IO) :-
     ModuleName = Info ^ lout_mangled_module_name,
     list.length(LabelLayouts, NumLabelLayouts),
-    Name = label_layout_array(label_has_var_info),
+    Name = label_layout_array(label_has_no_var_info),
     output_layout_array_name_storage_type_name(ModuleName, Name,
         being_defined, !IO),
     io.format("[%d] = {\n", [i(NumLabelLayouts)], !IO),
-    list.foldl2(output_var_label_layout_slot(Info), LabelLayouts, 0, _, !IO),
+    list.foldl2(output_no_var_label_layout_slot(Info), LabelLayouts,
+        0, _, !IO),
     io.write_string("};\n\n", !IO).
 
-output_no_var_label_layouts_array_defn(Info, LabelLayouts, !IO) :-
+:- pred output_no_var_label_layout_slot(llds_out_info::in,
+    label_layout_no_vars::in, int::in, int::out, io::di, io::uo) is det.
+
+output_no_var_label_layout_slot(Info, LabelLayout, !Slot, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    LabelLayout = label_layout_no_vars(BasicLabelLayout),
+    BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
+        _, _, _, _, _, _),
+    % The procedure is given by the proc_label printed from the basic layout.
+    io.write_string("{ ", !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    (
+        AutoComments = yes,
+        io.format("/* %d, %d */\n  ",
+            [i(!.Slot), i(LabelNum)], !IO)
+    ;
+        AutoComments = no
+    ),
+    output_basic_label_layout_slot(Info, ModuleName, BasicLabelLayout, !IO),
+    io.write_string(" },\n", !IO),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #8: label layout structures for labels with
+% only short-descriptor variable information.
+%
+
+:- pred output_short_var_label_layouts_array_defn(llds_out_info::in,
+    list(label_layout_short_vars)::in, io::di, io::uo) is det.
+
+output_short_var_label_layouts_array_defn(Info, LabelLayouts, !IO) :-
     ModuleName = Info ^ lout_mangled_module_name,
     list.length(LabelLayouts, NumLabelLayouts),
-    Name = label_layout_array(label_has_no_var_info),
+    Name = label_layout_array(label_has_short_var_info),
     output_layout_array_name_storage_type_name(ModuleName, Name,
         being_defined, !IO),
     io.format("[%d] = {\n", [i(NumLabelLayouts)], !IO),
-    list.foldl2(output_no_var_label_layout_slot(Info), LabelLayouts,
+    list.foldl2(output_short_var_label_layout_slot(Info), LabelLayouts,
         0, _, !IO),
     io.write_string("};\n\n", !IO).
 
-:- pred output_var_label_layout_slot(llds_out_info::in,
-    label_layout_vars::in, int::in, int::out, io::di, io::uo) is det.
+:- pred output_short_var_label_layout_slot(llds_out_info::in,
+    label_layout_short_vars::in, int::in, int::out, io::di, io::uo) is det.
 
-output_var_label_layout_slot(Info, LabelLayout, !Slot, !IO) :-
+output_short_var_label_layout_slot(Info, LabelLayout, !Slot, !IO) :-
     ModuleName = Info ^ lout_mangled_module_name,
-    LabelLayout = label_layout_vars(BasicLabelLayout, LabelVarInfo),
+    LabelLayout = label_layout_short_vars(BasicLabelLayout, LabelVarInfo),
     BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
         _, _, _, _, _, _),
     % The procedure is given by the proc_label printed from the basic layout.
-    io.format("{/* %d, %d */\n  ", [i(!.Slot), i(LabelNum)], !IO),
-    output_basic_label_layout_slot(ModuleName, BasicLabelLayout, !IO),
+    io.write_string("{ ", !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    (
+        AutoComments = yes,
+        io.format("/* %d, %d */\n  ", [i(!.Slot), i(LabelNum)], !IO)
+    ;
+        AutoComments = no
+    ),
+    output_basic_label_layout_slot(Info, ModuleName, BasicLabelLayout, !IO),
     io.write_string(",\n  ", !IO),
 
-    LabelVarInfo = label_var_info(EncodedVarCount, LocnsTypes, VarNums,
-        TypeParams),
+    LabelVarInfo = label_short_var_info(EncodedVarCount, TypeParams, PTIsSlot,
+        HLDSVarNumsSlot, ShortLocnsSlot),
     io.write_int(EncodedVarCount, !IO),
     io.write_string(",", !IO),
     (
-        LocnsTypes = const(llconst_data_addr(LTDataAddr, no)),
-        LTDataAddr = data_addr(_,
-            scalar_common_ref(type_num(LTTypeNum), LTCellNum)),
-        VarNums = const(llconst_data_addr(VNDataAddr, no)),
-        VNDataAddr = data_addr(_,
-            scalar_common_ref(type_num(VNTypeNum), VNCellNum))
+        PTIsSlot >= 0,
+        HLDSVarNumsSlot >= 0,
+        ShortLocnsSlot >= 0
     ->
         (
-            TypeParams = const(llconst_data_addr(TPDataAddr, no)),
-            TPDataAddr = data_addr(_,
-                scalar_common_ref(type_num(TPTypeNum), TPCellNum))
+            TypeParams = const(llconst_int(0))
         ->
-            io.format("MR_LLV_CCC(%d,%d,%d,%d,%d,%d)",
-                [i(LTTypeNum), i(LTCellNum), i(VNTypeNum), i(VNCellNum),
-                i(TPTypeNum), i(TPCellNum)], !IO)
+            io.format("MR_LLVS0(%s,%d,%d,%d)",
+                [s(ModuleName),
+                i(PTIsSlot), i(HLDSVarNumsSlot), i(ShortLocnsSlot)], !IO)
         ;
-            TypeParams = const(llconst_int(0))
+            TypeParams = const(llconst_data_addr(TPDataId, no)),
+            TPDataId = scalar_common_data_id(type_num(TPTypeNum), TPCellNum)
         ->
-            io.format("MR_LLV_CC0(%d,%d,%d,%d)",
-                [i(LTTypeNum), i(LTCellNum), i(VNTypeNum), i(VNCellNum)], !IO)
+            io.format("MR_LLVSC(%s,%d,%d,%d,%d,%d)",
+                [s(ModuleName), i(TPTypeNum), i(TPCellNum),
+                i(PTIsSlot), i(HLDSVarNumsSlot), i(ShortLocnsSlot)], !IO)
         ;
-            io.format("MR_LLV_CC(%d,%d,%d,%d,",
-                [i(LTTypeNum), i(LTCellNum), i(VNTypeNum), i(VNCellNum)], !IO),
             output_rval_as_addr(Info, TypeParams, !IO),
-            io.write_string(")", !IO)
+            io.format(",MR_LLVS(%s,%d,%d,%d)",
+                [s(ModuleName),
+                i(PTIsSlot), i(HLDSVarNumsSlot), i(ShortLocnsSlot)], !IO)
         )
     ;
-        io.write_string("MR_LLV(", !IO),
-        output_rval_as_addr(Info, LocnsTypes, !IO),
-        io.write_string(",", !IO),
-        output_rval_as_addr(Info, VarNums, !IO),
-        io.write_string(",", !IO),
         output_rval_as_addr(Info, TypeParams, !IO),
-        io.write_string(")", !IO)
+        io.write_string(",", !IO),
+        ( PTIsSlot >= 0 ->
+            output_layout_slot_addr(use_layout_macro, ModuleName,
+                layout_slot(pseudo_type_info_array, PTIsSlot), !IO),
+            io.write_string(",", !IO)
+        ;
+            io.write_string("0,", !IO)
+        ),
+        ( HLDSVarNumsSlot >= 0 ->
+            output_layout_slot_addr(use_layout_macro, ModuleName,
+                layout_slot(hlds_var_nums_array, HLDSVarNumsSlot), !IO),
+            io.write_string(",", !IO)
+        ;
+            io.write_string("0,", !IO)
+        ),
+        ( ShortLocnsSlot >= 0 ->
+            output_layout_slot_addr(use_layout_macro, ModuleName,
+                layout_slot(short_locns_array, ShortLocnsSlot), !IO)
+        ;
+            io.write_string("0", !IO)
+        )
     ),
-
     io.write_string(" },\n", !IO),
     !:Slot = !.Slot + 1.
 
-:- pred output_no_var_label_layout_slot(llds_out_info::in,
-    label_layout_no_vars::in, int::in, int::out, io::di, io::uo) is det.
-
-output_no_var_label_layout_slot(Info, LabelLayout, !Slot, !IO) :-
-    ModuleName = Info ^ lout_mangled_module_name,
-    LabelLayout = label_layout_no_vars(BasicLabelLayout),
-    BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
-        _, _, _, _, _, _),
-    % The procedure is given by the proc_label printed from the basic layout.
-    io.format("{ /* %d, %d */\n  ",
-        [i(!.Slot), i(LabelNum)], !IO),
-    output_basic_label_layout_slot(ModuleName, BasicLabelLayout, !IO),
-    io.write_string(" },\n", !IO),
-    !:Slot = !.Slot + 1.
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #9: label layout structures for labels with
+% both short and long variable descriptors.
+%
 
-:- pred output_basic_label_layout_slot(string::in, basic_label_layout::in,
-    io::di, io::uo) is det.
+:- pred output_long_var_label_layouts_array_defn(llds_out_info::in,
+    list(label_layout_long_vars)::in, io::di, io::uo) is det.
 
-output_basic_label_layout_slot(ModuleName, BasicLabelLayout, !IO) :-
-    BasicLabelLayout = basic_label_layout(ProcLabel, _LabelNum,
-        ProcLayoutName, MaybePort, MaybeIsHidden, LabelNumberInModule,
-        MaybeGoalPath, MaybeUserSlotName),
+output_long_var_label_layouts_array_defn(Info, LabelLayouts, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(LabelLayouts, NumLabelLayouts),
+    Name = label_layout_array(label_has_long_var_info),
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumLabelLayouts)], !IO),
+    list.foldl2(output_long_var_label_layout_slot(Info), LabelLayouts,
+        0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_long_var_label_layout_slot(llds_out_info::in,
+    label_layout_long_vars::in, int::in, int::out, io::di, io::uo) is det.
+
+output_long_var_label_layout_slot(Info, LabelLayout, !Slot, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    LabelLayout = label_layout_long_vars(BasicLabelLayout, LabelVarInfo),
+    BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
+        _, _, _, _, _, _),
+    % The procedure is given by the proc_label printed from the basic layout.
+    io.write_string("{ ", !IO),
+    AutoComments = Info ^ lout_auto_comments,
     (
-        ProcLayoutName = proc_layout(RttiProcLabel, _),
-        ProcLabelFromRtti = make_proc_label_from_rtti(RttiProcLabel),
-        ProcLabelFromRtti = ProcLabel
-    ->
+        AutoComments = yes,
+        io.format("/* %d, %d */\n  ", [i(!.Slot), i(LabelNum)], !IO)
+    ;
+        AutoComments = no
+    ),
+    output_basic_label_layout_slot(Info, ModuleName, BasicLabelLayout, !IO),
+    io.write_string(",\n  ", !IO),
+
+    LabelVarInfo = label_long_var_info(EncodedVarCount, TypeParams, PTIsSlot,
+        HLDSVarNumsSlot, ShortLocnsSlot, LongLocnsSlot),
+    ( LongLocnsSlot >= 0 ->
         true
     ;
-        unexpected(this_file, "output_basic_label_layout_slot: != proclabels")
+        unexpected(this_file,
+            "output_long_var_label_layout_slot: no long locn")
+    ),
+
+    io.write_int(EncodedVarCount, !IO),
+    io.write_string(",", !IO),
+    (
+        PTIsSlot >= 0,
+        ShortLocnsSlot >= 0,
+        HLDSVarNumsSlot >= 0
+    ->
+        (
+            TypeParams = const(llconst_int(0))
+        ->
+            io.format("MR_LLVL0(%s,%d,%d,%d,%d)",
+                [s(ModuleName),
+                i(PTIsSlot), i(HLDSVarNumsSlot),
+                i(ShortLocnsSlot), i(LongLocnsSlot)], !IO)
+        ;
+            TypeParams = const(llconst_data_addr(TPDataId, no)),
+            TPDataId = scalar_common_data_id(type_num(TPTypeNum), TPCellNum)
+        ->
+            io.format("MR_LLVLC(%s,%d,%d,%d,%d,%d,%d)",
+                [s(ModuleName), i(TPTypeNum), i(TPCellNum),
+                i(PTIsSlot), i(HLDSVarNumsSlot),
+                i(ShortLocnsSlot), i(LongLocnsSlot)], !IO)
+        ;
+            output_rval_as_addr(Info, TypeParams, !IO),
+            io.format(",MR_LLVL(%s,%d,%d,%d,%d)",
+                [s(ModuleName),
+                i(PTIsSlot), i(HLDSVarNumsSlot),
+                i(ShortLocnsSlot), i(LongLocnsSlot)], !IO)
+        )
+    ;
+        output_rval_as_addr(Info, TypeParams, !IO),
+        io.write_string(",", !IO),
+        ( PTIsSlot >= 0 ->
+            output_layout_slot_addr(use_layout_macro, ModuleName,
+                layout_slot(pseudo_type_info_array, PTIsSlot), !IO),
+            io.write_string(",", !IO)
+        ;
+            io.write_string("0,", !IO)
+        ),
+        ( HLDSVarNumsSlot >= 0 ->
+            output_layout_slot_addr(use_layout_macro, ModuleName,
+                layout_slot(hlds_var_nums_array, HLDSVarNumsSlot), !IO),
+            io.write_string(",", !IO)
+        ;
+            io.write_string("0,", !IO)
     ),
+        ( ShortLocnsSlot >= 0 ->
+            output_layout_slot_addr(use_layout_macro, ModuleName,
+                layout_slot(short_locns_array, ShortLocnsSlot), !IO),
+            io.write_string(",", !IO)
+        ;
+            io.write_string("0,", !IO)
+        ),
+        output_layout_slot_addr(use_layout_macro, ModuleName,
+            layout_slot(long_locns_array, LongLocnsSlot), !IO)
+    ),
+    io.write_string(" },\n", !IO),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+%
+% Common code shared by arrays 7, 8 and 9.
+%
 
+:- pred output_basic_label_layout_slot(llds_out_info::in, string::in,
+    basic_label_layout::in, io::di, io::uo) is det.
+
+output_basic_label_layout_slot(_Info, ModuleName, BasicLabelLayout, !IO) :-
+    BasicLabelLayout = basic_label_layout(ProcLabel, _LabelNum,
+        _ProcLayoutName, MaybePort, MaybeIsHidden, LabelNumberInModule,
+        MaybeGoalPath, MaybeUserSlotName),
+    some [!MacroName] (
+        !:MacroName = "MR_LL",
     % MaybeIsHidden = no means that the value of the hidden field shouldn't
-    % matter; we arbitrarily set it to `not hidden'.
+        % matter; we arbitrarily make this mean `not hidden'.
     (
         ( MaybeIsHidden = no
         ; MaybeIsHidden = yes(no)
-        ),
-        (
-            MaybeUserSlotName = no,
-            MacroName = "MR_LLC"
-        ;
-            MaybeUserSlotName = yes(_),
-            MacroName = "MR_LLC_U"
         )
     ;
         MaybeIsHidden = yes(yes),
+            !:MacroName = !.MacroName ++ "_H"
+        ),
         (
-            MaybeUserSlotName = no,
-            MacroName = "MR_LLC_H"
+            MaybeUserSlotName = no
         ;
             MaybeUserSlotName = yes(_),
-            MacroName = "MR_LLC_H_U"
-        )
+            !:MacroName = !.MacroName ++ "_U"
+        ),
+        MacroName = !.MacroName
     ),
 
     io.write_string(MacroName, !IO),
@@ -376,52 +950,544 @@
     io.write_int(LabelNumberInModule, !IO),
     io.write_string(",", !IO),
     (
-        MaybeGoalPath = yes(GoalPath),
-        io.write_int(GoalPath, !IO)
+        MaybeGoalPath = yes(GoalPath),
+        io.write_int(GoalPath, !IO)
+    ;
+        MaybeGoalPath = no,
+        io.write_string("0", !IO)
+    ),
+    (
+        MaybeUserSlotName = no
+    ;
+        MaybeUserSlotName = yes(UserSlotName),
+        io.write_string(",", !IO),
+        output_layout_slot_addr(use_layout_macro, ModuleName, UserSlotName,
+            !IO)
+    ),
+    io.write_string(")", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #10: proc static call sites.
+%
+
+:- pred output_call_site_static_array(llds_out_info::in,
+    list(call_site_static_data)::in,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
+
+output_call_site_static_array(Info, CallSiteStatics, !DeclSet, !IO) :-
+    % At normal call sites, the call_site_static contains a pointer to
+    % the proc layout of the callee procedure. Regardless of whether
+    % the callee is in this module or not, we won't have declared its
+    % proc layout structure yet.
+    list.foldl2(output_call_site_static_slot_decls(Info), CallSiteStatics,
+        !DeclSet, !IO),
+
+    ModuleName = Info ^ lout_mangled_module_name,
+    Name = proc_static_call_sites_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    list.length(CallSiteStatics, NumCallSiteStatics),
+    io.format("[%d] = {\n", [i(NumCallSiteStatics)], !IO),
+    list.foldl2(output_call_site_static_slot(Info), CallSiteStatics,
+        0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_call_site_static_slot_decls(llds_out_info::in,
+    call_site_static_data::in, decl_set::in, decl_set::out,
+    io::di, io::uo) is det.
+
+:- pred output_call_site_static_slot(llds_out_info::in,
+    call_site_static_data::in, int::in, int::out, io::di, io::uo) is det.
+
+output_call_site_static_slot_decls(Info, CallSiteStatic, !DeclSet, !IO) :-
+    (
+        CallSiteStatic = normal_call(Callee, _, _, _, _),
+        CalleeProcLabel = make_proc_label_from_rtti(Callee),
+        CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
+        CalleeProcLayoutName =
+            proc_layout(Callee, proc_layout_proc_id(CalleeUserOrUci)),
+        CalleProcLayoutDataId = layout_id(CalleeProcLayoutName),
+        output_record_data_id_decls(Info, CalleProcLayoutDataId, !DeclSet, !IO)
+    ;
+        ( CallSiteStatic = special_call(_, _, _)
+        ; CallSiteStatic = higher_order_call(_, _, _)
+        ; CallSiteStatic = method_call(_, _, _)
+        ; CallSiteStatic = callback(_, _, _)
+        )
+    ).
+
+output_call_site_static_slot(Info, CallSiteStatic, !Slot, !IO) :-
+    io.write_string("{ ", !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    (
+        AutoComments = yes,
+        io.format("/* %d */ ", [i(!.Slot)], !IO)
+    ;
+        AutoComments = no
+    ),
+    (
+        CallSiteStatic = normal_call(Callee, TypeSubst, FileName, LineNumber,
+            GoalPath),
+        io.write_string("MR_callsite_normal_call, (MR_ProcLayout *)\n&", !IO),
+        CalleeProcLabel = make_proc_label_from_rtti(Callee),
+        CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
+        CalleeProcLayoutName =
+            proc_layout(Callee, proc_layout_proc_id(CalleeUserOrUci)),
+        output_layout_name(CalleeProcLayoutName, !IO),
+        ( TypeSubst = "" ->
+            io.write_string(", NULL, ", !IO)
+        ;
+            io.write_string(",\n""", !IO),
+            io.write_string(TypeSubst, !IO),
+            io.write_string(""", ", !IO)
+        )
+    ;
+        CallSiteStatic = special_call(FileName, LineNumber, GoalPath),
+        io.write_string("MR_callsite_special_call, NULL, NULL, ", !IO)
+    ;
+        CallSiteStatic = higher_order_call(FileName, LineNumber, GoalPath),
+        io.write_string("MR_callsite_higher_order_call, NULL, NULL, ", !IO)
+    ;
+        CallSiteStatic = method_call(FileName, LineNumber, GoalPath),
+        io.write_string("MR_callsite_method_call, NULL, NULL, ", !IO)
+    ;
+        CallSiteStatic = callback(FileName, LineNumber, GoalPath),
+        io.write_string("MR_callsite_callback, NULL, NULL, ", !IO)
+    ),
+    io.write_string("""", !IO),
+    io.write_string(FileName, !IO),
+    io.write_string(""", ", !IO),
+    io.write_int(LineNumber, !IO),
+    io.write_string(", """, !IO),
+    io.write_string(goal_path_to_string(GoalPath), !IO),
+    io.write_string(""" },\n", !IO),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #11: the static parts of coverage points
+% (information about the coverage point).
+%
+
+:- pred output_proc_static_cp_static_array(llds_out_info::in,
+    list(coverage_point_info)::in, int::in, io::di, io::uo) is det.
+
+output_proc_static_cp_static_array(Info, CoveragePoints, NumCoveragePoints,
+        !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    Name = proc_static_cp_static_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumCoveragePoints)], !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    list.foldl2(output_proc_static_cp_static_slot(AutoComments),
+        CoveragePoints, 0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_proc_static_cp_static_slot(bool::in,
+    coverage_point_info::in, int::in, int::out, io::di, io::uo) is det.
+
+output_proc_static_cp_static_slot(AutoComments, CoveragePoint, !Slot, !IO) :-
+    CoveragePoint = coverage_point_info(GoalPath, CPType),
+    io.write_string("{ ", !IO),
+    (
+        AutoComments = yes,
+        io.format("/* %d */ ", [i(!.Slot)], !IO)
+    ;
+        AutoComments = no
+    ),
+    io.write_string("""", !IO),
+    GoalPathString = goal_path_to_string(GoalPath),
+    io.write_string(GoalPathString, !IO),
+    io.write_string(""", ", !IO),
+    coverage_point_type_c_value(CPType, CPTypeCValue),
+    io.write_string(CPTypeCValue, !IO),
+    io.write_string(" },\n", !IO),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #12: the dynamic parts of coverage points (the counts).
+%
+
+:- pred output_proc_static_cp_dynamic_array(llds_out_info::in, int::in,
+    io::di, io::uo) is det.
+
+output_proc_static_cp_dynamic_array(Info, NumCoveragePoints, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    Name = proc_static_cp_dynamic_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    % The C compiler will arrange for the array to be initialized to all zeros.
+    io.format("[%d];\n", [i(NumCoveragePoints)], !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #13: proc static structures.
+%
+
+:- pred output_proc_statics_array_defn(llds_out_info::in,
+    list(proc_layout_proc_static)::in, io::di, io::uo) is det.
+
+output_proc_statics_array_defn(Info, ProcStatics, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(ProcStatics, NumProcStatics),
+    Name = proc_static_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumProcStatics)], !IO),
+    list.foldl2(output_proc_static_slot(Info), ProcStatics, 0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_proc_static_slot(llds_out_info::in, proc_layout_proc_static::in,
+    int::in, int::out, io::di, io::uo) is det.
+
+output_proc_static_slot(Info, ProcStatic, !Slot, !IO) :-
+    ProcStatic = proc_layout_proc_static(FileName, LineNumber,
+        IsInInterface, DeepExcpVars, MaybeCallSites, MaybeCoveragePoints),
+    io.write_string("{ ", !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    MangledModuleName = Info ^ lout_mangled_module_name,
+    (
+        AutoComments = yes,
+        io.format("/* %d */ ", [i(!.Slot)], !IO)
+    ;
+        AutoComments = no
+    ),
+    quote_and_write_string(FileName, !IO),
+    io.write_string(",", !IO),
+    io.write_int(LineNumber, !IO),
+    io.write_string(",", !IO),
+    (
+        IsInInterface = yes,
+        io.write_string("MR_TRUE", !IO)
+    ;
+        IsInInterface = no,
+        io.write_string("MR_FALSE", !IO)
+    ),
+    io.write_string(",\n  ", !IO),
+    (
+        MaybeCallSites = yes({CallSitesSlot, NumCallSites}),
+        io.write_int(NumCallSites, !IO),
+        io.write_string(",", !IO),
+        CallSitesSlotName =
+            layout_slot(proc_static_call_sites_array, CallSitesSlot),
+        output_layout_slot_addr(use_layout_macro, MangledModuleName,
+            CallSitesSlotName, !IO),
+        io.write_string(",\n", !IO)
+    ;
+        MaybeCallSites = no,
+        io.write_string("0,NULL,\n", !IO)
+    ),
+    io.write_string("#ifdef MR_USE_ACTIVATION_COUNTS\n", !IO),
+    io.write_string("0,\n", !IO),
+    io.write_string("#endif\n", !IO),
+    io.write_string("NULL,", !IO),
+    DeepExcpVars = deep_excp_slots(TopCSDSlot, MiddleCSDSlot,
+        OldOutermostSlot),
+    io.write_int(TopCSDSlot, !IO),
+    io.write_string(",", !IO),
+    io.write_int(MiddleCSDSlot, !IO),
+    io.write_string(",", !IO),
+    io.write_int(OldOutermostSlot, !IO),
+    io.write_string(",", !IO),
+    (
+        MaybeCoveragePoints = yes({CoveragePointsSlot, NumCoveragePoints}),
+        io.write_int(NumCoveragePoints, !IO),
+        io.write_string(",\n", !IO),
+        CoveragePointsStaticSlotName =
+            layout_slot(proc_static_cp_static_array, CoveragePointsSlot),
+        output_layout_slot_addr(use_layout_macro, MangledModuleName,
+            CoveragePointsStaticSlotName, !IO),
+        io.write_string(",\n", !IO),
+        CoveragePointsDynamicSlotName =
+            layout_slot(proc_static_cp_dynamic_array, CoveragePointsSlot),
+        output_layout_slot_addr(use_layout_macro, MangledModuleName,
+            CoveragePointsDynamicSlotName, !IO),
+        io.write_string(" },\n", !IO)
+    ;
+        MaybeCoveragePoints = no,
+        io.write_string("0,NULL,NULL },\n", !IO)
+    ),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #14: proc head variable numbers.
+%
+
+:- pred output_proc_head_var_nums_array(llds_out_info::in, list(int)::in,
+    io::di, io::uo) is det.
+
+output_proc_head_var_nums_array(Info, HeadVarNums, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(HeadVarNums, NumHeadVarNums),
+    Name = proc_head_var_nums_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {", [i(NumHeadVarNums)], !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    list.foldl2(output_number_in_vector(AutoComments), HeadVarNums, 0, _, !IO),
+    io.write_string("\n};\n\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #15: proc variable names.
+%
+
+:- pred output_proc_var_names_array(llds_out_info::in, list(int)::in,
+    io::di, io::uo) is det.
+
+output_proc_var_names_array(Info, VarNames, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(VarNames, NumVarNames),
+    Name = proc_var_names_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {", [i(NumVarNames)], !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    list.foldl2(output_number_in_vector(AutoComments), VarNames, 0, _, !IO),
+    io.write_string("\n};\n\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #16: proc body bytecodes names.
+%
+
+:- pred output_proc_body_bytecodes_array(llds_out_info::in, list(int)::in,
+    io::di, io::uo) is det.
+
+output_proc_body_bytecodes_array(Info, Bytecodes, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(Bytecodes, NumBytecodes),
+    Name = proc_body_bytecodes_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumBytecodes)], !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    list.foldl2(output_number_in_vector(AutoComments), Bytecodes, 0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #17: table_io structures.
+%
+
+:- pred output_table_io_decl_array(llds_out_info::in,
+    list(table_io_decl_data)::in, io::di, io::uo) is det.
+
+output_table_io_decl_array(Info, TableIoDecls, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(TableIoDecls, NumTableIoDecls),
+    Name = proc_table_io_decl_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumTableIoDecls)], !IO),
+    list.foldl2(output_table_io_decl_slot(Info), TableIoDecls, 0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_table_io_decl_slot(llds_out_info::in, table_io_decl_data::in,
+    int::in, int::out, io::di, io::uo) is det.
+
+output_table_io_decl_slot(Info, TableIoDecl, !Slot, !IO) :-
+    TableIoDecl = table_io_decl_data(ProcLayoutName, NumPTIs,
+        PTIVectorRval, TypeParamsRval),
+    io.write_string("{ ", !IO),
+    AutoComments = Info ^ lout_auto_comments,
+    (
+        AutoComments = yes,
+        io.format("/* %d */\n  ", [i(!.Slot)], !IO)
+    ;
+        AutoComments = no
+    ),
+    io.write_string("(const MR_ProcLayout *) &", !IO),
+    output_layout_name(ProcLayoutName, !IO),
+    io.write_string(",\n  ", !IO),
+    io.write_int(NumPTIs, !IO),
+    io.write_string(",\n  (const MR_PseudoTypeInfo *) ", !IO),
+    output_rval(Info, PTIVectorRval, !IO),
+    io.write_string(", (const MR_TypeParamLocns *) ", !IO),
+    output_rval(Info, TypeParamsRval, !IO),
+    io.write_string(" },\n", !IO),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #18: proc event layouts.
+%
+
+:- pred output_proc_event_layout_array(llds_out_info::in,
+    list(layout_slot_name)::in, io::di, io::uo) is det.
+
+output_proc_event_layout_array(Info, ProcEventLayoutSlotNames, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(ProcEventLayoutSlotNames, NumProcEventLayoutSlotNames),
+    Name = proc_event_layouts_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumProcEventLayoutSlotNames)], !IO),
+    output_layout_slots_in_vector(ModuleName, ProcEventLayoutSlotNames, !IO),
+    io.write_string("};\n\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Definition of array #19: execution tracing structures.
+%
+
+:- pred output_exec_traces_array(llds_out_info::in,
+    list(proc_layout_exec_trace)::in, io::di, io::uo) is det.
+
+output_exec_traces_array(Info, ExecTraces, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(ExecTraces, NumExecTraces),
+    Name = proc_exec_trace_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumExecTraces)], !IO),
+    list.foldl2(output_exec_trace_slot(Info), ExecTraces, 0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_exec_trace_slot(llds_out_info::in,
+    proc_layout_exec_trace::in, int::in, int::out, io::di, io::uo) is det.
+
+output_exec_trace_slot(Info, ExecTrace, !Slot, !IO) :-
+    ExecTrace = proc_layout_exec_trace(MaybeCallLabelSlotName,
+        EventLayoutsSlotName, NumEventLayouts, MaybeTableInfo,
+        MaybeHeadVarsSlotName, NumHeadVarNums, MaybeVarNamesSlotName,
+        MaxVarNum, MaxRegNum, MaybeFromFullSlot, MaybeIoSeqSlot,
+        MaybeTrailSlot, MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
+        MaybeTailRecSlot, EffTraceLevel, Flags),
+    AutoComments = Info ^ lout_auto_comments,
+    io.write_string("{ ", !IO),
+    (
+        AutoComments = yes,
+        io.format("/* %d */ ", [i(!.Slot)], !IO)
+    ;
+        AutoComments = no
+    ),
+
+    MangledModuleName = Info ^ lout_mangled_module_name,
+    (
+        MaybeCallLabelSlotName = yes(CallLabelSlotName),
+        io.write_string("(MR_LabelLayout *) ", !IO),
+        output_layout_slot_addr(use_layout_macro, MangledModuleName,
+            CallLabelSlotName, !IO),
+        io.write_string(",\n  ", !IO)
+    ;
+        MaybeCallLabelSlotName = no,
+        io.write_string("NULL,\n  ", !IO)
+    ),
+    io.write_string("(const MR_ModuleLayout *) &", !IO),
+    ModuleName = Info ^ lout_module_name,
+    output_layout_name(module_layout(ModuleName), !IO),
+    io.write_string(",\n  ", !IO),
+    output_layout_slot_addr(use_layout_macro, MangledModuleName,
+        EventLayoutsSlotName, !IO),
+    io.write_string(",", !IO),
+    io.write_int(NumEventLayouts, !IO),
+    io.write_string(",\n  ", !IO),
+    io.write_string("{ ", !IO),
+    (
+        MaybeTableInfo = yes(TableInfo),
+        (
+            TableInfo = data_or_slot_is_slot(TableSlotName),
+            io.write_string("(const void *) ", !IO),
+            output_layout_slot_addr(use_layout_macro, MangledModuleName,
+                TableSlotName, !IO)
+        ;
+            TableInfo = data_or_slot_is_data(TableDataId),
+            io.write_string("(const void *) &", !IO),
+            output_data_id(Info, TableDataId, !IO)
+        )
+    ;
+        MaybeTableInfo = no,
+        io.write_string("NULL", !IO)
+    ),
+    io.write_string(" },\n  ", !IO),
+    (
+        MaybeHeadVarsSlotName = yes(HeadVarNumsSlotName),
+        output_layout_slot_addr(use_layout_macro, MangledModuleName,
+            HeadVarNumsSlotName, !IO)
     ;
-        MaybeGoalPath = no,
-        io.write_string("0", !IO)
+        MaybeHeadVarsSlotName = no,
+        io.write_string("NULL", !IO)
     ),
+    io.write_string(",", !IO),
     (
-        MaybeUserSlotName = no
+        MaybeVarNamesSlotName = yes(VarNamesSlotName),
+        output_layout_slot_addr(use_layout_macro, MangledModuleName,
+            VarNamesSlotName, !IO)
     ;
-        MaybeUserSlotName = yes(UserSlotName),
-        io.write_string(",", !IO),
-        output_layout_slot_name(use_layout_macro, ModuleName, UserSlotName,
-            !IO)
+        MaybeVarNamesSlotName = no,
+        io.write_string("NULL", !IO)
     ),
-    io.write_string(")", !IO).
+    io.write_string(",\n  ", !IO),
+    io.write_int(NumHeadVarNums, !IO),
+    io.write_string(",", !IO),
+    io.write_int(MaxVarNum, !IO),
+    io.write_string(",", !IO),
+    io.write_int(MaxRegNum, !IO),
+    io.write_string(",", !IO),
+    write_maybe_slot_num(MaybeFromFullSlot, !IO),
+    io.write_string(",", !IO),
+    write_maybe_slot_num(MaybeIoSeqSlot, !IO),
+    io.write_string(",", !IO),
+    write_maybe_slot_num(MaybeTrailSlot, !IO),
+    io.write_string(",", !IO),
+    write_maybe_slot_num(MaybeMaxfrSlot, !IO),
+    io.write_string(",", !IO),
+    io.write_string(eval_method_to_c_string(EvalMethod), !IO),
+    io.write_string(",", !IO),
+    write_maybe_slot_num(MaybeCallTableSlot, !IO),
+    io.write_string(",", !IO),
+    io.write_string(trace_level_rep(EffTraceLevel), !IO),
+    io.write_string(",\n  ", !IO),
+    io.write_int(Flags, !IO),
+    io.write_string(",", !IO),
+    write_maybe_slot_num(MaybeTailRecSlot, !IO),
+    io.write_string(" },\n", !IO).
 
-%-----------------------------------------------------------------------------%
+:- pred write_maybe_slot_num(maybe(int)::in, io::di, io::uo) is det.
+
+write_maybe_slot_num(yes(SlotNum), !IO) :-
+    io.write_int(SlotNum, !IO).
+write_maybe_slot_num(no, !IO) :-
+    io.write_int(-1, !IO).
+
+:- func eval_method_to_c_string(eval_method) = string.
 
-output_layout_data_defn(Info, Data, !DeclSet, !IO) :-
+eval_method_to_c_string(eval_normal) =     "MR_EVAL_METHOD_NORMAL".
+eval_method_to_c_string(eval_loop_check) = "MR_EVAL_METHOD_LOOP_CHECK".
+eval_method_to_c_string(eval_memo) =       "MR_EVAL_METHOD_MEMO".
+eval_method_to_c_string(eval_minimal(MinimalMethod)) = Str :-
     (
-        Data = proc_layout_data(ProcLabel, Traversal, MaybeRest),
-        output_proc_layout_data_defn(Info, ProcLabel,
-            Traversal, MaybeRest, !DeclSet, !IO)
-    ;
-        Data = closure_proc_id_data(CallerProcLabel, SeqNo, ProcLabel,
-            ModuleName, FileName, LineNumber, PredOrigin, GoalPath),
-        output_closure_proc_id_data_defn(CallerProcLabel, SeqNo, ProcLabel,
-            ModuleName, FileName, LineNumber, PredOrigin, GoalPath,
-            !DeclSet, !IO)
+        MinimalMethod = stack_copy,
+        Str = "MR_EVAL_METHOD_MINIMAL_STACK_COPY"
     ;
-        Data = module_layout_common_data(ModuleName,
-            StringTableSize, StringTable),
-        output_module_common_layout_data_defn(ModuleName, StringTableSize,
-            StringTable, !DeclSet, !IO)
+        MinimalMethod = own_stacks_consumer,
+        Str = "MR_EVAL_METHOD_MINIMAL_OWN_STACKS_CONSUMER"
     ;
-        Data = module_layout_data(ModuleName, ModuleCommonLayoutName,
-            ProcLayoutNames, FileLayouts, TraceLevel,
-            SuppressedEvents, NumLabels, MaybeEventSet),
-        output_module_layout_data_defn(Info, ModuleName,
-            ModuleCommonLayoutName, ProcLayoutNames, FileLayouts, TraceLevel,
-            SuppressedEvents, NumLabels, MaybeEventSet, !DeclSet, !IO)
+        MinimalMethod = own_stacks_generator,
+        Str = "MR_EVAL_METHOD_MINIMAL_OWN_STACKS_GENERATOR"
+    ).
+eval_method_to_c_string(eval_table_io(Decl, Unitize)) = Str :-
+    (
+        Decl = table_io_proc,
+        Unitize = table_io_alone,
+        Str = "MR_EVAL_METHOD_TABLE_IO"
     ;
-        Data = table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
-            PTIVectorRval, TypeParamsRval),
-        output_table_io_decl(Info, RttiProcLabel, Kind, NumPTIs,
-            PTIVectorRval, TypeParamsRval, !DeclSet, !IO)
+        Decl = table_io_proc,
+        Unitize = table_io_unitize,
+        Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE"
+    ;
+        Decl = table_io_decl,
+        Unitize = table_io_alone,
+        Str = "MR_EVAL_METHOD_TABLE_IO_DECL"
+    ;
+        Decl = table_io_decl,
+        Unitize = table_io_unitize,
+        Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL"
     ).
 
 %-----------------------------------------------------------------------------%
@@ -431,68 +1497,86 @@
     io.write_string(";\n", !IO).
 
 output_maybe_layout_name_decl(LayoutName, !DeclSet, !IO) :-
-    ( decl_set_is_member(decl_data_addr(layout_addr(LayoutName)), !.DeclSet) ->
+    ( decl_set_is_member(decl_layout_id(LayoutName), !.DeclSet) ->
         true
     ;
         output_layout_name_decl(LayoutName, !IO),
-        decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet)
-    ).
-
-output_maybe_layout_data_decl(LayoutData, !DeclSet, !IO) :-
-    extract_layout_name(LayoutData, LayoutName),
-    output_maybe_layout_name_decl(LayoutName, !DeclSet, !IO).
-
-:- pred extract_layout_name(layout_data::in, layout_name::out) is det.
-
-extract_layout_name(Data, LayoutName) :-
-    (
-        Data = proc_layout_data(RttiProcLabel, _, MaybeRest),
-        ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-        Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
-        LayoutName = proc_layout(RttiProcLabel, Kind)
-    ;
-        Data = closure_proc_id_data(CallerProcLabel, SeqNo, ClosureProcLabel,
-            _, _, _, _, _),
-        LayoutName = closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel)
-    ;
-        Data = module_layout_common_data(ModuleName, _, _),
-        LayoutName = module_common_layout(ModuleName)
-    ;
-        Data = module_layout_data(ModuleName, _, _, _, _, _, _, _),
-        LayoutName = module_layout(ModuleName)
-    ;
-        Data = table_io_decl_data(RttiProcLabel, _, _, _, _),
-        LayoutName = table_io_decl(RttiProcLabel)
+        decl_set_insert(decl_layout_id(LayoutName), !DeclSet)
     ).
 
 :- pred output_layout_decl(layout_name::in, decl_set::in, decl_set::out,
     io::di, io::uo) is det.
 
 output_layout_decl(LayoutName, !DeclSet, !IO) :-
-    ( decl_set_is_member(decl_data_addr(layout_addr(LayoutName)), !.DeclSet) ->
+    ( decl_set_is_member(decl_layout_id(LayoutName), !.DeclSet) ->
         true
     ;
         output_layout_name_storage_type_name(LayoutName, not_being_defined,
             !IO),
         io.write_string(";\n", !IO),
-        decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet)
+        decl_set_insert(decl_layout_id(LayoutName), !DeclSet)
     ).
 
 output_layout_array_name(UseMacro, ModuleName, ArrayName, !IO) :-
     (
         UseMacro = use_layout_macro,
         (
-            ArrayName = label_layout_array(label_has_var_info),
-            io.write_string("MR_var_label_layouts", !IO)
-        ;
             ArrayName = label_layout_array(label_has_no_var_info),
             io.write_string("MR_no_var_label_layouts", !IO)
         ;
+            ArrayName = label_layout_array(label_has_short_var_info),
+            io.write_string("MR_svar_label_layouts", !IO)
+        ;
+            ArrayName = label_layout_array(label_has_long_var_info),
+            io.write_string("MR_lvar_label_layouts", !IO)
+        ;
+            ArrayName = pseudo_type_info_array,
+            io.write_string("MR_pseudo_type_infos", !IO)
+        ;
+            ArrayName = long_locns_array,
+            io.write_string("MR_long_locns", !IO)
+        ;
+            ArrayName = short_locns_array,
+            io.write_string("MR_short_locns", !IO)
+        ;
+            ArrayName = hlds_var_nums_array,
+            io.write_string("MR_hlds_var_nums", !IO)
+        ;
             ArrayName = user_event_var_nums_array,
             io.write_string("MR_user_event_var_nums", !IO)
         ;
             ArrayName = user_event_layout_array,
             io.write_string("MR_user_event_layouts", !IO)
+        ;
+            ArrayName = proc_static_call_sites_array,
+            io.write_string("MR_proc_call_sites", !IO)
+        ;
+            ArrayName = proc_static_cp_static_array,
+            io.write_string("MR_proc_cp_statics", !IO)
+        ;
+            ArrayName = proc_static_cp_dynamic_array,
+            io.write_string("MR_proc_cp_dynamics", !IO)
+        ;
+            ArrayName = proc_static_array,
+            io.write_string("MR_proc_statics", !IO)
+        ;
+            ArrayName = proc_head_var_nums_array,
+            io.write_string("MR_proc_head_var_nums", !IO)
+        ;
+            ArrayName = proc_var_names_array,
+            io.write_string("MR_proc_var_names", !IO)
+        ;
+            ArrayName = proc_body_bytecodes_array,
+            io.write_string("MR_proc_body_bytecodes", !IO)
+        ;
+            ArrayName = proc_table_io_decl_array,
+            io.write_string("MR_proc_table_io_decls", !IO)
+        ;
+            ArrayName = proc_event_layouts_array,
+            io.write_string("MR_proc_event_layouts", !IO)
+        ;
+            ArrayName = proc_exec_trace_array,
+            io.write_string("MR_proc_exec_traces", !IO)
         ),
         io.write_string("(", !IO),
         io.write_string(ModuleName, !IO),
@@ -500,30 +1584,80 @@
     ;
         UseMacro = do_not_use_layout_macro,
         (
-            ArrayName = label_layout_array(label_has_var_info),
-            io.write_string("mercury_data__var_label_layout_array__", !IO)
-        ;
             ArrayName = label_layout_array(label_has_no_var_info),
             io.write_string("mercury_data__no_var_label_layout_array__", !IO)
         ;
+            ArrayName = label_layout_array(label_has_short_var_info),
+            io.write_string("mercury_data__svar_label_layout_array__", !IO)
+        ;
+            ArrayName = label_layout_array(label_has_long_var_info),
+            io.write_string("mercury_data__lvar_label_layout_array__", !IO)
+        ;
+            ArrayName = pseudo_type_info_array,
+            io.write_string("mercury_data__pseudo_type_info_array__", !IO)
+        ;
+            ArrayName = long_locns_array,
+            io.write_string("mercury_data__long_locns_array__", !IO)
+        ;
+            ArrayName = short_locns_array,
+            io.write_string("mercury_data__short_locns_array__", !IO)
+        ;
+            ArrayName = hlds_var_nums_array,
+            io.write_string("mercury_data__hlds_var_nums_array__", !IO)
+        ;
             ArrayName = user_event_var_nums_array,
             io.write_string("mercury_data__user_event_var_nums_array__", !IO)
         ;
             ArrayName = user_event_layout_array,
             io.write_string("mercury_data__user_event_layouts_array__", !IO)
+        ;
+            ArrayName = proc_static_call_sites_array,
+            io.write_string("mercury_data__proc_call_sites_array__", !IO)
+        ;
+            ArrayName = proc_static_cp_static_array,
+            io.write_string("mercury_data__proc_cp_statics_array__", !IO)
+        ;
+            ArrayName = proc_static_cp_dynamic_array,
+            io.write_string("mercury_data__proc_cp_dynamics_array__", !IO)
+        ;
+            ArrayName = proc_static_array,
+            io.write_string("mercury_data__proc_statics_array__", !IO)
+        ;
+            ArrayName = proc_head_var_nums_array,
+            io.write_string("mercury_data__proc_head_var_nums_array__", !IO)
+        ;
+            ArrayName = proc_var_names_array,
+            io.write_string("mercury_data__proc_var_names_array__", !IO)
+        ;
+            ArrayName = proc_body_bytecodes_array,
+            io.write_string("mercury_data__proc_body_bytecodes_array__", !IO)
+        ;
+            ArrayName = proc_table_io_decl_array,
+            io.write_string("mercury_data__proc_table_io_decls_array__", !IO)
+        ;
+            ArrayName = proc_event_layouts_array,
+            io.write_string("mercury_data__proc_event_layouts_array__", !IO)
+        ;
+            ArrayName = proc_exec_trace_array,
+            io.write_string("mercury_data__proc_exec_traces_array__", !IO)
         ),
         io.write_string(ModuleName, !IO)
     ).
 
-output_layout_slot_name(UseMacro, ModuleName, SlotName, !IO) :-
+output_layout_slot_id(UseMacro, ModuleName, SlotName, !IO) :-
+    SlotName = layout_slot(ArrayName, SlotNum),
+    output_layout_array_name(UseMacro, ModuleName, ArrayName, !IO),
+    io.format("[%d]", [i(SlotNum)], !IO).
+
+output_layout_slot_addr(UseMacro, ModuleName, SlotName, !IO) :-
     SlotName = layout_slot(ArrayName, SlotNum),
     io.write_string("&", !IO),
     output_layout_array_name(UseMacro, ModuleName, ArrayName, !IO),
     io.format("[%d]", [i(SlotNum)], !IO).
 
-output_layout_name(Data, !IO) :-
+output_layout_name(Name, !IO) :-
     (
-        Data = proc_layout(RttiProcLabel, _),
+        Name = proc_layout(RttiProcLabel, _),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_proc_layout__", !IO),
         % We can't omit the mercury_ prefix on ProcLabel, even though the
@@ -532,44 +1666,14 @@
         % entry label's name to get the name of its layout structure.
         output_proc_label(make_proc_label_from_rtti(RttiProcLabel), !IO)
     ;
-        Data = proc_layout_exec_trace(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_proc_layout_exec_trace__", !IO),
-        output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
-            !IO)
-    ;
-        Data = proc_layout_label_layouts(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_proc_label_layouts__", !IO),
-        output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
-            !IO)
-    ;
-        Data = proc_layout_head_var_nums(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_head_var_nums__", !IO),
-        output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
-            !IO)
-    ;
-        Data = proc_layout_var_names(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_var_names__", !IO),
-        output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
-            !IO)
-    ;
-        Data = proc_layout_body_bytecode(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_body_bytecode__", !IO),
-        output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
-            !IO)
-    ;
-        Data = closure_proc_id(CallerProcLabel, SeqNo, _),
+        Name = closure_proc_id(CallerProcLabel, SeqNo, _),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_closure_layout__", !IO),
         output_proc_label_no_prefix(CallerProcLabel, !IO),
         io.write_string("_", !IO),
         io.write_int(SeqNo, !IO)
     ;
-        Data = file_layout(ModuleName, FileNum),
+        Name = file_layout(ModuleName, FileNum),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_file_layout__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
@@ -577,7 +1681,7 @@
         io.write_string("_", !IO),
         io.write_int(FileNum, !IO)
     ;
-        Data = file_layout_line_number_vector(ModuleName, FileNum),
+        Name = file_layout_line_number_vector(ModuleName, FileNum),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_file_lines__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
@@ -585,7 +1689,7 @@
         io.write_string("_", !IO),
         io.write_int(FileNum, !IO)
     ;
-        Data = file_layout_label_layout_vector(ModuleName, FileNum),
+        Name = file_layout_label_layout_vector(ModuleName, FileNum),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_file_label_layouts__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
@@ -593,37 +1697,37 @@
         io.write_string("_", !IO),
         io.write_int(FileNum, !IO)
     ;
-        Data = module_layout_string_table(ModuleName),
+        Name = module_layout_string_table(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_strings__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Data = module_layout_file_vector(ModuleName),
+        Name = module_layout_file_vector(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_files__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Data = module_layout_proc_vector(ModuleName),
+        Name = module_layout_proc_vector(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_procs__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Data = module_layout_label_exec_count(ModuleName, _),
+        Name = module_layout_label_exec_count(ModuleName, _),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_label_exec_counts__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Data = module_layout_event_set_desc(ModuleName),
+        Name = module_layout_event_set_desc(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout_event_set_desc__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Data = module_layout_event_arg_names(ModuleName, EventNumber),
+        Name = module_layout_event_arg_names(ModuleName, EventNumber),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout_event_arg_names__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
@@ -631,7 +1735,7 @@
         io.write_string("_", !IO),
         io.write_int(EventNumber, !IO)
     ;
-        Data = module_layout_event_synth_attrs(ModuleName, EventNumber),
+        Name = module_layout_event_synth_attrs(ModuleName, EventNumber),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout_event_synth_attrs__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
@@ -639,7 +1743,7 @@
         io.write_string("_", !IO),
         io.write_int(EventNumber, !IO)
     ;
-        Data = module_layout_event_synth_attr_args(ModuleName,
+        Name = module_layout_event_synth_attr_args(ModuleName,
             EventNumber, SynthCallArgNumber),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout_event_synth_attr_args__", !IO),
@@ -650,7 +1754,7 @@
         io.write_string("_", !IO),
         io.write_int(SynthCallArgNumber, !IO)
     ;
-        Data = module_layout_event_synth_attr_order(ModuleName,
+        Name = module_layout_event_synth_attr_order(ModuleName,
             EventNumber, SynthCallArgNumber),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout_event_synth_attr_order__", !IO),
@@ -661,7 +1765,7 @@
         io.write_string("_", !IO),
         io.write_int(SynthCallArgNumber, !IO)
     ;
-        Data = module_layout_event_synth_order(ModuleName, EventNumber),
+        Name = module_layout_event_synth_order(ModuleName, EventNumber),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout_event_synth_order__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
@@ -669,65 +1773,60 @@
         io.write_string("_", !IO),
         io.write_int(EventNumber, !IO)
     ;
-        Data = module_layout_event_specs(ModuleName),
+        Name = module_layout_event_specs(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout_event_specs__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Data = module_common_layout(ModuleName),
+        Name = module_common_layout(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_common_layout__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
     ;
-        Data = module_layout(ModuleName),
+        Name = module_layout(ModuleName),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_module_layout__", !IO),
         ModuleNameStr = sym_name_mangle(ModuleName),
         io.write_string(ModuleNameStr, !IO)
-    ;
-        Data = proc_static(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_proc_static__", !IO),
-        ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-        output_proc_label_no_prefix(ProcLabel, !IO)
-    ;
-        Data = proc_static_call_sites(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_proc_static_call_sites__", !IO),
-        ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-        output_proc_label_no_prefix(ProcLabel, !IO)
-    ;
-        Data = proc_static_coverage_point_static(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_proc_static_coverage_points_static__", !IO),
-        ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-        output_proc_label_no_prefix(ProcLabel, !IO)
-    ;
-        Data = proc_static_coverage_point_dynamic(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_proc_static_coverage_points_dynamic__", !IO),
-        ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-        output_proc_label_no_prefix(ProcLabel, !IO)
-    ;
-        Data = table_io_decl(RttiProcLabel),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_table_io_decl__", !IO),
-        ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-        output_proc_label_no_prefix(ProcLabel, !IO)
     ).
 
 output_layout_array_name_storage_type_name(ModuleName, Name, _BeingDefined,
         !IO) :-
     (
-        Name = label_layout_array(label_has_var_info),
+        Name = label_layout_array(label_has_no_var_info),
+        io.write_string("static const MR_LabelLayoutNoVarInfo ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = label_layout_array(label_has_short_var_info),
+        io.write_string("static const MR_LabelLayoutShort ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = label_layout_array(label_has_long_var_info),
         io.write_string("static const MR_LabelLayout ", !IO),
         output_layout_array_name(do_not_use_layout_macro, ModuleName,
             Name, !IO)
     ;
-        Name = label_layout_array(label_has_no_var_info),
-        io.write_string("static const MR_LabelLayoutNoVarInfo ", !IO),
+        Name = pseudo_type_info_array,
+        io.write_string("static const MR_PseudoTypeInfo ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = long_locns_array,
+        io.write_string("static const MR_LongLval ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = short_locns_array,
+        io.write_string("static const MR_ShortLval ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = hlds_var_nums_array,
+        io.write_string("static const MR_HLDSVarNum ", !IO),
         output_layout_array_name(do_not_use_layout_macro, ModuleName,
             Name, !IO)
     ;
@@ -740,13 +1839,63 @@
         io.write_string("static const struct MR_UserEvent_Struct ", !IO),
         output_layout_array_name(do_not_use_layout_macro, ModuleName,
             Name, !IO)
+    ;
+        Name = proc_static_call_sites_array,
+        io.write_string("static const MR_CallSiteStatic ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_static_cp_static_array,
+        io.write_string("static const MR_CoveragePointStatic ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_static_cp_dynamic_array,
+        io.write_string("static MR_Unsigned ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_static_array,
+        io.write_string("static MR_ProcStatic ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_head_var_nums_array,
+        io.write_string("static const MR_uint_least16_t ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_var_names_array,
+        io.write_string("static const MR_uint_least32_t ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_body_bytecodes_array,
+        io.write_string("static const MR_uint_least8_t ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_table_io_decl_array,
+        io.write_string("static const MR_TableIoDecl ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_event_layouts_array,
+        io.write_string("static const MR_LabelLayout *", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
+    ;
+        Name = proc_exec_trace_array,
+        io.write_string("static MR_STATIC_CODE_CONST MR_ExecTrace ", !IO),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
     ).
 
 output_layout_name_storage_type_name(Name, BeingDefined, !IO) :-
     (
-        Name = proc_layout(ProcLabel, Kind),
-        ProcIsImported = ProcLabel ^ proc_is_imported,
-        ProcIsExported = ProcLabel ^ proc_is_exported,
+        Name = proc_layout(RttiProcLabel, Kind),
+        ProcIsImported = RttiProcLabel ^ rpl_proc_is_imported,
+        ProcIsExported = RttiProcLabel ^ rpl_proc_is_exported,
         (
             ProcIsImported = no,
             ProcIsExported = no
@@ -765,33 +1914,6 @@
         io.write_string(" ", !IO),
         output_layout_name(Name, !IO)
     ;
-        Name = proc_layout_exec_trace(_ProcLabel),
-        io.write_string("static MR_STATIC_CODE_CONST MR_ExecTrace\n\t", !IO),
-        output_layout_name(Name, !IO)
-    ;
-        Name = proc_layout_label_layouts(_ProcLabel),
-        io.write_string("static const MR_LabelLayout *", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
-    ;
-        Name = proc_layout_head_var_nums(_ProcLabel),
-        io.write_string("static const ", !IO),
-        io.write_string("MR_uint_least16_t ", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
-    ;
-        Name = proc_layout_var_names(_ProcLabel),
-        io.write_string("static const ", !IO),
-        io.write_string("MR_uint_least32_t ", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
-    ;
-        Name = proc_layout_body_bytecode(_ProcLabel),
-        io.write_string("static const ", !IO),
-        io.write_string("MR_uint_least8_t ", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
-    ;
         Name = closure_proc_id(_CallerProcLabel, _SeqNo, ClosureProcLabel),
         io.write_string("static const ", !IO),
         (
@@ -880,67 +2002,34 @@
         io.write_string("static const MR_ModuleCommonLayout ", !IO),
         output_layout_name(Name, !IO)
     ;
-        Name = module_layout(_ModuleName),
-        io.write_string("static const MR_ModuleLayout ", !IO),
-        output_layout_name(Name, !IO)
-    ;
-        Name = proc_static(_RttiProcLabel),
-        io.write_string("static MR_ProcStatic ", !IO),
-        output_layout_name(Name, !IO)
-    ;
-        Name = proc_static_call_sites(_RttiProcLabel),
-        io.write_string("static const MR_CallSiteStatic ", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
-    ;
-        Name = proc_static_coverage_point_static(_RttiProcLabel),
-        io.write_string("static const MR_CoveragePointStatic ", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
-    ;
-        Name = proc_static_coverage_point_dynamic(_RttiProcLabel),
-        io.write_string("static MR_Unsigned ", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
-    ;
-        Name = table_io_decl(_RttiProcLabel),
-        io.write_string("static const MR_TableIoDecl ", !IO),
+        Name = module_layout(_ModuleName),
+        io.write_string("static const MR_ModuleLayout ", !IO),
         output_layout_name(Name, !IO)
     ).
 
-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_label_layouts(_)) = no.
-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(proc_layout_body_bytecode(_)) = no.
-layout_name_would_include_code_addr(closure_proc_id(_, _, _)) = no.
-layout_name_would_include_code_addr(file_layout(_, _)) = no.
-layout_name_would_include_code_addr(file_layout_line_number_vector(_, _)) = no.
-layout_name_would_include_code_addr(file_layout_label_layout_vector(_, _))
-    = no.
-layout_name_would_include_code_addr(module_layout_string_table(_)) = no.
-layout_name_would_include_code_addr(module_layout_file_vector(_)) = no.
-layout_name_would_include_code_addr(module_layout_proc_vector(_)) = no.
-layout_name_would_include_code_addr(module_layout_label_exec_count(_, _)) = no.
-layout_name_would_include_code_addr(module_layout_event_set_desc(_)) = no.
-layout_name_would_include_code_addr(module_layout_event_arg_names(_, _)) = no.
-layout_name_would_include_code_addr(module_layout_event_synth_attrs(_, _))
-    = no.
-layout_name_would_include_code_addr(
-    module_layout_event_synth_attr_args(_, _, _)) = no.
-layout_name_would_include_code_addr(
-    module_layout_event_synth_attr_order(_, _, _)) = no.
-layout_name_would_include_code_addr(module_layout_event_synth_order(_, _))
-    = no.
-layout_name_would_include_code_addr(module_layout_event_specs(_)) = no.
-layout_name_would_include_code_addr(module_common_layout(_)) = no.
-layout_name_would_include_code_addr(module_layout(_)) = no.
-layout_name_would_include_code_addr(proc_static(_)) = no.
-layout_name_would_include_code_addr(proc_static_call_sites(_)) = no.
-layout_name_would_include_code_addr(proc_static_coverage_point_static(_)) = no.
-layout_name_would_include_code_addr(proc_static_coverage_point_dynamic(_)) = no.
-layout_name_would_include_code_addr(table_io_decl(_)) = no.
+layout_name_would_include_code_addr(LayoutName) = InclCodeAddr :-
+    (
+        ( LayoutName = proc_layout(_, _)
+        ; LayoutName = closure_proc_id(_, _, _)
+        ; LayoutName = file_layout(_, _)
+        ; LayoutName = file_layout_line_number_vector(_, _)
+        ; LayoutName = file_layout_label_layout_vector(_, _)
+        ; LayoutName = module_layout_string_table(_)
+        ; LayoutName = module_layout_file_vector(_)
+        ; LayoutName = module_layout_proc_vector(_)
+        ; LayoutName = module_layout_label_exec_count(_, _)
+        ; LayoutName = module_layout_event_set_desc(_)
+        ; LayoutName = module_layout_event_arg_names(_, _)
+        ; LayoutName = module_layout_event_synth_attrs(_, _)
+        ; LayoutName = module_layout_event_synth_attr_args(_, _, _)
+        ; LayoutName = module_layout_event_synth_attr_order(_, _, _)
+        ; LayoutName = module_layout_event_synth_order(_, _)
+        ; LayoutName = module_layout_event_specs(_)
+        ; LayoutName = module_common_layout(_)
+        ; LayoutName = module_layout(_)
+        ),
+        InclCodeAddr = no
+    ).
 
 :- func proc_layout_kind_to_type(proc_layout_kind) = string.
 
@@ -959,13 +2048,8 @@
 output_rval_as_addr(Info, Rval, !IO) :-
     ( Rval = const(llconst_int(0)) ->
         io.write_string("0", !IO)
-    ; Rval = const(llconst_data_addr(DataAddr, no)) ->
-        ( DataAddr = data_addr(_, scalar_common_ref(_TypeNum, _CellNum)) ->
-            output_data_addr(DataAddr, !IO)
-        ;
-            io.write_string("&", !IO),
-            output_data_addr(DataAddr, !IO)
-        )
+    ; Rval = const(llconst_data_addr(DataId, no)) ->
+        output_data_id_addr(Info, DataId, !IO)
     ;
         io.write_string("\n", !IO),
         output_rval(Info, Rval, !IO)
@@ -992,151 +2076,35 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_proc_layout_data_defn(llds_out_info::in, 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(Info, RttiProcLabel, Traversal, MaybeRest,
-        !DeclSet, !IO) :-
-    MangledModuleName = Info ^ lout_mangled_module_name,
-    output_layout_traversal_decls(Info, Traversal, !DeclSet, !IO),
+output_proc_layout_data_defn(Info, ProcLayoutData, !DeclSet, !IO) :-
+    ProcLayoutData = proc_layout_data(RttiProcLabel, Traversal, MaybeRest),
     ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-    Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
-    (
-        MaybeRest = no_proc_id_and_more,
-        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_and_more(MaybeProcStatic, MaybeExecTrace,
-            ProcBodyBytes, ModuleCommonLayout),
-        (
-            MaybeProcStatic = yes(ProcStatic),
-            output_proc_static_data_defn(RttiProcLabel, ProcStatic, !DeclSet,
-                !IO)
-        ;
-            MaybeProcStatic = no
-        ),
-        (
-            MaybeExecTrace = yes(ExecTrace),
-            HeadVarNums = ExecTrace ^ head_var_nums,
-            output_proc_layout_head_var_nums(RttiProcLabel, HeadVarNums,
-                !DeclSet, !IO),
-            VarNames = ExecTrace ^ var_names,
-            MaxVarNum = ExecTrace ^ max_var_num,
-            output_proc_layout_var_names(RttiProcLabel, VarNames, MaxVarNum,
-                !DeclSet, !IO),
-            output_layout_exec_trace_decls(Info, RttiProcLabel, ExecTrace,
-                !DeclSet, !IO),
-            output_layout_exec_trace(MangledModuleName, RttiProcLabel,
-                ExecTrace, !DeclSet, !IO)
-        ;
-            MaybeExecTrace = no
-        ),
-        (
-            ProcBodyBytes = []
-        ;
-            ProcBodyBytes = [_ | _],
-            io.write_string("\n", !IO),
-            output_layout_name_storage_type_name(
-                proc_layout_body_bytecode(RttiProcLabel), being_defined, !IO),
-            io.write_string(" = {\n", !IO),
-            output_bytecodes_driver(ProcBodyBytes, !IO),
-            io.write_string("};\n\n", !IO)
-        ),
-
-        output_layout_decl(ModuleCommonLayout, !DeclSet, !IO),
+    Traversal = proc_layout_stack_traversal(MaybeEntryLabel, MaybeSuccipSlot,
+        StackSlotCount, Detism),
 
-        output_proc_layout_data_defn_start(RttiProcLabel, Kind, Traversal,
-            !IO),
-        Origin = RttiProcLabel ^ pred_info_origin,
-        output_layout_proc_id_group(ProcLabel, Origin, !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 the declarations needed by this definition.
         (
-            ProcBodyBytes = [],
-            io.write_string("NULL,\n", !IO)
+        MaybeEntryLabel = yes(EntryLabelDecl),
+        output_record_code_addr_decls(Info, code_label(EntryLabelDecl),
+            !DeclSet, !IO)
         ;
-            ProcBodyBytes = [_ | _],
-            output_layout_name(proc_layout_body_bytecode(RttiProcLabel), !IO),
-            io.write_string(",\n", !IO)
-        ),
-        io.write_string("&", !IO),
-        output_layout_name(ModuleCommonLayout, !IO),
-        output_proc_layout_data_defn_end(!IO)
+        MaybeEntryLabel = no
     ),
-    DeclId = decl_data_addr(layout_addr(proc_layout(RttiProcLabel, Kind))),
-    decl_set_insert(DeclId, !DeclSet).
-
-:- func maybe_proc_layout_and_more_kind(maybe_proc_id_and_more,
-    proc_label) = proc_layout_kind.
-
-maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel) = Kind :-
     (
         MaybeRest = no_proc_id_and_more,
         Kind = proc_layout_traversal
     ;
-        MaybeRest = proc_id_and_more(_, _, _, _),
-        Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel))
-    ).
-
-proc_label_user_or_uci(ordinary_proc_label(_, _, _, _, _, _)) = user.
-proc_label_user_or_uci(special_proc_label(_, _, _, _, _, _)) = uci.
-
-:- 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.
+        MaybeRest = proc_id_and_more(_, _, _, ModuleCommonLayoutDecl),
+        Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel)),
+        output_layout_decl(ModuleCommonLayoutDecl, !DeclSet, !IO)
+    ),
 
-output_proc_layout_data_defn_start(RttiProcLabel, Kind, Traversal, !IO) :-
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(proc_layout(RttiProcLabel, Kind),
-        being_defined, !IO),
+    ProcLayoutName = proc_layout(RttiProcLabel, Kind),
+    output_layout_name_storage_type_name(ProcLayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
-    output_layout_traversal_group(Traversal, !IO).
-
-:- pred output_proc_layout_data_defn_end(io::di, io::uo) is det.
-
-output_proc_layout_data_defn_end(!IO) :-
-    io.write_string("};\n", !IO).
-
-:- pred output_layout_traversal_decls(llds_out_info::in,
-    proc_layout_stack_traversal::in, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
-
-output_layout_traversal_decls(Info, Traversal, !DeclSet, !IO) :-
-    Traversal = proc_layout_stack_traversal(MaybeEntryLabel, _MaybeSuccipSlot,
-        _StackSlotCount, _Detism),
-    (
-        MaybeEntryLabel = yes(EntryLabel),
-        output_record_code_addr_decls(Info, code_label(EntryLabel),
-            !DeclSet, !IO)
-    ;
-        MaybeEntryLabel = no
-    ).
-
-:- pred output_layout_traversal_group(proc_layout_stack_traversal::in,
-    io::di, io::uo) is det.
 
-output_layout_traversal_group(Traversal, !IO) :-
-    Traversal = proc_layout_stack_traversal(MaybeEntryLabel, MaybeSuccipSlot,
-        StackSlotCount, Detism),
+    % Write out the traversal structure.
     io.write_string("{\n", !IO),
     (
         MaybeEntryLabel = yes(EntryLabel),
@@ -1147,7 +2115,7 @@
         % by module initialization code.
         io.write_string("NULL", !IO)
     ),
-    io.write_string(",\n{ ", !IO),
+    io.write_string(", ", !IO),
     (
         MaybeSuccipSlot = yes(SuccipSlot),
         io.write_int(SuccipSlot, !IO)
@@ -1155,288 +2123,118 @@
         MaybeSuccipSlot = no,
         io.write_int(-1, !IO)
     ),
-    io.write_string(" },\n", !IO),
+    io.write_string(",\n", !IO),
     io.write_int(StackSlotCount, !IO),
     io.write_string(",\n", !IO),
     io.write_string(detism_to_c_detism(Detism), !IO),
-    io.write_string("\n},\n", !IO).
-
-:- func detism_to_c_detism(determinism) = string.
-
-detism_to_c_detism(detism_det) =       "MR_DETISM_DET".
-detism_to_c_detism(detism_semi) =      "MR_DETISM_SEMI".
-detism_to_c_detism(detism_non) =       "MR_DETISM_NON".
-detism_to_c_detism(detism_multi) =     "MR_DETISM_MULTI".
-detism_to_c_detism(detism_erroneous) = "MR_DETISM_ERRONEOUS".
-detism_to_c_detism(detism_failure) =   "MR_DETISM_FAILURE".
-detism_to_c_detism(detism_cc_non) =    "MR_DETISM_CCNON".
-detism_to_c_detism(detism_cc_multi) =  "MR_DETISM_CCMULTI".
-
-:- pred output_layout_proc_id_group(proc_label::in, pred_origin::in,
-    io::di, io::uo) is det.
-
-output_layout_proc_id_group(ProcLabel, Origin, !IO) :-
-    io.write_string("{\n", !IO),
-    output_proc_id(ProcLabel, Origin, !IO),
-    io.write_string("},\n", !IO).
-
-:- pred output_layout_no_proc_id_group(io::di, io::uo) is det.
-
-output_layout_no_proc_id_group(!IO) :-
-    io.write_string("-1\n", !IO).
-
-:- pred output_layout_exec_trace_decls(llds_out_info::in, 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(Info, RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
-    ExecTrace = proc_layout_exec_trace(_MaybeCallLabelLayout,
-        _InterfaceEventSlots, _InternalEventSlots, MaybeTableInfo,
-        _HeadVarNums, _VarNames, _MaxVarNum,
-        _MaxRegNum, _MaybeFromFullSlot, _MaybeIoSeqSlot,
-        _MaybeTrailSlot, _MaybeMaxfrSlot, _EvalMethod,
-        _MaybeCallTableSlot, _MaybeTailRecSlot, _EffTraceLevel, _Flags),
-    ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-    ModuleName = get_defining_module_name(ProcLabel),
-    output_layout_decl(module_layout(ModuleName), !DeclSet, !IO),
-    (
-        MaybeTableInfo = yes(TableInfo),
-        output_record_data_addr_decls(Info, TableInfo, !DeclSet, !IO)
-    ;
-        MaybeTableInfo = no
-    ).
-
-:- func wrap_decl_data_addr(data_addr) = decl_id.
-
-wrap_decl_data_addr(DataAddr) = decl_data_addr(DataAddr).
-
-    % The job of this predicate is to minimize stack space consumption in
-    % grades that do not allow output_bytecodes to be tail recursive.
-    %
-:- pred output_bytecodes_driver(list(int)::in, io::di, io::uo) is det.
-
-output_bytecodes_driver(Bytes, !IO) :-
-    (
-        Bytes = []
-    ;
-        Bytes = [_ | _],
-        output_bytecodes(Bytes, BytesLeft, 0, 256, !IO),
-        output_bytecodes_driver(BytesLeft, !IO)
-    ).
-
-:- pred output_bytecodes(list(int)::in, list(int)::out, int::in, int::in,
-    io::di, io::uo) is det.
+    io.write_string("\n},\n", !IO),
 
-output_bytecodes(Bytes, BytesLeft, !.Seq, MaxSeq, !IO) :-
     (
-        Bytes = [],
-        BytesLeft = []
-    ;
-        Bytes = [Head | Tail],
-        ( !.Seq < MaxSeq ->
-            io.write_int(Head, !IO),
-            io.write_char(',', !IO),
-            !:Seq = !.Seq + 1,
-            ( unchecked_rem(!.Seq, 16) = 0 ->
-                io.write_char('\n', !IO)
-            ;
-                true
-            ),
-            output_bytecodes(Tail, BytesLeft, !.Seq, MaxSeq, !IO)
+        MaybeRest = no_proc_id_and_more,
+        io.write_string("-1\n", !IO)
         ;
-            BytesLeft = Bytes
-        )
-    ).
-
-:- pred output_layout_exec_trace(string::in, 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(MangledModuleName, RttiProcLabel, ExecTrace,
-        !DeclSet, !IO) :-
-    ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails,
-        InterfaceEventLabelSlots, InternalEventLabelSlots, MaybeTableInfo,
-        HeadVarNums, _VarNames, MaxVarNum, MaxRegNum,
-        MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot, MaybeMaxfrSlot,
-        EvalMethod, MaybeCallTableSlot, MaybeTailRecSlot, EffTraceLevel,
-        Flags),
+        MaybeRest = proc_id_and_more(MaybeProcStatic, MaybeExecTrace,
+            MaybeProcBodyBytes, ModuleCommonLayout),
 
-    EventLabelSlots = InterfaceEventLabelSlots ++ InternalEventLabelSlots,
-    (
-        EventLabelSlots = []
-    ;
-        EventLabelSlots = [_ | _],
-        io.write_string("\n", !IO),
-        output_layout_name_storage_type_name(
-            proc_layout_label_layouts(RttiProcLabel), being_defined, !IO),
-        io.write_string(" = {\n", !IO),
-        output_layout_slots_in_vector(MangledModuleName, EventLabelSlots, !IO),
-        io.write_string("};\n\n", !IO)
-    ),
+        % Output the proc_id structure.
+        io.write_string("{\n", !IO),
+        Origin = RttiProcLabel ^ rpl_pred_info_origin,
+        output_proc_id(ProcLabel, Origin, !IO),
+        io.write_string("},\n", !IO),
 
-    output_layout_name_storage_type_name(
-        proc_layout_exec_trace(RttiProcLabel), being_defined, !IO),
-    io.write_string(" = {\n", !IO),
-    (
-        MaybeCallLabelDetails = yes(CallLabelSlot),
-        output_layout_slot_name(use_layout_macro, MangledModuleName,
-            CallLabelSlot, !IO),
-        io.write_string(",\n", !IO)
-    ;
-        MaybeCallLabelDetails = no,
-        io.write_string("NULL,\n", !IO)
-    ),
-    io.write_string("(const MR_ModuleLayout *) &", !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),
+        MangledModuleName = Info ^ lout_mangled_module_name,
     (
-        EventLabelSlots = [],
+            MaybeExecTrace = no,
         io.write_string("NULL,\n", !IO)
     ;
-        EventLabelSlots = [_ | _],
-        output_layout_name(proc_layout_label_layouts(RttiProcLabel), !IO),
+            MaybeExecTrace = yes(ExecTraceSlotName),
+            output_layout_slot_addr(use_layout_macro, MangledModuleName,
+                ExecTraceSlotName, !IO),
         io.write_string(",\n", !IO)
     ),
-    list.length(EventLabelSlots, NumEventLabelSlots),
-    io.write_int(NumEventLabelSlots, !IO),
-    io.write_string(",\n", !IO),
-    io.write_string("{ ", !IO),
-    (
-        MaybeTableInfo = yes(TableInfo),
-        io.write_string("(const void *) &", !IO),
-        output_data_addr(TableInfo, !IO)
-    ;
-        MaybeTableInfo = no,
-        io.write_string("NULL", !IO)
-    ),
-    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", !IO),
-    io.write_string(trace_level_rep(EffTraceLevel), !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(Flags, !IO),
-    io.write_string(",\n", !IO),
-    write_maybe_slot_num(MaybeTailRecSlot, !IO),
-    io.write_string("\n};\n", !IO).
-
-:- pred write_maybe_slot_num(maybe(int)::in, io::di, io::uo) is det.
-
-write_maybe_slot_num(yes(SlotNum), !IO) :-
-    io.write_int(SlotNum, !IO).
-write_maybe_slot_num(no, !IO) :-
-    io.write_int(-1, !IO).
-
-:- func eval_method_to_c_string(eval_method) = string.
-
-eval_method_to_c_string(eval_normal) =     "MR_EVAL_METHOD_NORMAL".
-eval_method_to_c_string(eval_loop_check) = "MR_EVAL_METHOD_LOOP_CHECK".
-eval_method_to_c_string(eval_memo) =       "MR_EVAL_METHOD_MEMO".
-eval_method_to_c_string(eval_minimal(MinimalMethod)) = Str :-
-    (
-        MinimalMethod = stack_copy,
-        Str = "MR_EVAL_METHOD_MINIMAL_STACK_COPY"
-    ;
-        MinimalMethod = own_stacks_consumer,
-        Str = "MR_EVAL_METHOD_MINIMAL_OWN_STACKS_CONSUMER"
-    ;
-        MinimalMethod = own_stacks_generator,
-        Str = "MR_EVAL_METHOD_MINIMAL_OWN_STACKS_GENERATOR"
-    ).
-eval_method_to_c_string(eval_table_io(Decl, Unitize)) = Str :-
     (
-        Decl = table_io_proc,
-        Unitize = table_io_alone,
-        Str = "MR_EVAL_METHOD_TABLE_IO"
-    ;
-        Decl = table_io_proc,
-        Unitize = table_io_unitize,
-        Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE"
-    ;
-        Decl = table_io_decl,
-        Unitize = table_io_alone,
-        Str = "MR_EVAL_METHOD_TABLE_IO_DECL"
-    ;
-        Decl = table_io_decl,
-        Unitize = table_io_unitize,
-        Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL"
-    ).
-
-:- 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) :-
-    io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(proc_layout_head_var_nums(ProcLabel),
-        being_defined, !IO),
-    io.write_string(" = {\n", !IO),
+            MaybeProcStatic = no,
+            io.write_string("NULL,\n", !IO)
+        ;
+            MaybeProcStatic = yes(ProcStaticSlotName),
+            output_layout_slot_addr(use_layout_macro, MangledModuleName,
+                ProcStaticSlotName, !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)
+            MaybeProcBodyBytes = no,
+            io.write_string("NULL,\n", !IO)
     ;
-        HeadVarNums = [_ | _],
-        list.foldl(output_number_in_vector, HeadVarNums, !IO)
+            MaybeProcBodyBytes = yes(ProcBodyBytesSlotName),
+            output_layout_slot_addr(use_layout_macro, MangledModuleName,
+                ProcBodyBytesSlotName, !IO),
+            io.write_string(",\n", !IO)
+        ),
+        io.write_string("&", !IO),
+        output_layout_name(ModuleCommonLayout, !IO)
     ),
     io.write_string("};\n", !IO),
-    DeclId = decl_data_addr(layout_addr(proc_layout_head_var_nums(ProcLabel))),
+    DeclId = decl_layout_id(ProcLayoutName),
     decl_set_insert(DeclId, !DeclSet).
 
-:- 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.
+proc_label_user_or_uci(ordinary_proc_label(_, _, _, _, _, _)) = user.
+proc_label_user_or_uci(special_proc_label(_, _, _, _, _, _)) = uci.
 
-output_proc_layout_var_names(ProcLabel, VarNames, MaxVarNum, !DeclSet, !IO) :-
-    list.length(VarNames, VarNameCount),
-    expect(unify(VarNameCount, MaxVarNum), this_file,
-        "output_proc_layout_var_names: VarNameCount != MaxVarNum"),
-    io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(proc_layout_var_names(ProcLabel),
-        being_defined, !IO),
-    io.write_string(" = {\n", !IO),
+:- func detism_to_c_detism(determinism) = string.
+
+detism_to_c_detism(detism_det) =       "MR_DETISM_DET".
+detism_to_c_detism(detism_semi) =      "MR_DETISM_SEMI".
+detism_to_c_detism(detism_non) =       "MR_DETISM_NON".
+detism_to_c_detism(detism_multi) =     "MR_DETISM_MULTI".
+detism_to_c_detism(detism_erroneous) = "MR_DETISM_ERRONEOUS".
+detism_to_c_detism(detism_failure) =   "MR_DETISM_FAILURE".
+detism_to_c_detism(detism_cc_non) =    "MR_DETISM_CCNON".
+detism_to_c_detism(detism_cc_multi) =  "MR_DETISM_CCMULTI".
+
+    % The job of this predicate is to minimize stack space consumption in
+    % grades that do not allow output_bytecodes to be tail recursive.
+    %
+:- pred output_bytecodes_driver(list(int)::in, io::di, io::uo) is det.
+
+output_bytecodes_driver(Bytes, !IO) :-
     (
-        VarNames = [],
-        % ANSI/ISO C doesn't allow empty arrays, so place a dummy value
-        % in the array.
-        io.write_string("0\n", !IO)
+        Bytes = []
+    ;
+        Bytes = [_ | _],
+        output_bytecodes(Bytes, BytesLeft, 0, 256, !IO),
+        output_bytecodes_driver(BytesLeft, !IO)
+    ).
+
+:- pred output_bytecodes(list(int)::in, list(int)::out, int::in, int::in,
+    io::di, io::uo) is det.
+
+output_bytecodes(Bytes, BytesLeft, !.Seq, MaxSeq, !IO) :-
+    (
+        Bytes = [],
+        BytesLeft = []
     ;
-        VarNames = [_ | _],
-        list.foldl(output_number_in_vector, VarNames, !IO)
+        Bytes = [Head | Tail],
+        ( !.Seq < MaxSeq ->
+            io.write_int(Head, !IO),
+            io.write_char(',', !IO),
+            !:Seq = !.Seq + 1,
+            ( unchecked_rem(!.Seq, 16) = 0 ->
+                io.write_char('\n', !IO)
+            ;
+                true
     ),
-    io.write_string("};\n", !IO),
-    DeclId = decl_data_addr(layout_addr(proc_layout_var_names(ProcLabel))),
-    decl_set_insert(DeclId, !DeclSet).
+            output_bytecodes(Tail, BytesLeft, !.Seq, MaxSeq, !IO)
+        ;
+            BytesLeft = Bytes
+        )
+    ).
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_closure_proc_id_data_defn(proc_label::in, int::in,
-    proc_label::in, module_name::in, string::in, int::in, pred_origin::in,
-    string::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_closure_proc_id_data_defn(CallerProcLabel, SeqNo, ClosureProcLabel,
-        ModuleName, FileName, LineNumber, PredOrigin, GoalPath,
-        !DeclSet, !IO) :-
+output_closure_layout_data_defn(_Info, ClosureData, !DeclSet, !IO) :-
+    ClosureData = closure_proc_id_data(CallerProcLabel, SeqNo,
+        ClosureProcLabel, ModuleName, FileName, LineNumber, PredOrigin,
+        GoalPath),
     io.write_string("\n", !IO),
     LayoutName = closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel),
     output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
@@ -1451,7 +2249,7 @@
     io.write_string(",\n", !IO),
     quote_and_write_string(GoalPath, !IO),
     io.write_string("\n};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
+    decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
 
 :- pred output_proc_id(proc_label::in, pred_origin::in, io::di, io::uo) is det.
 
@@ -1590,6 +2388,21 @@
 
 %-----------------------------------------------------------------------------%
 
+output_module_layout_data_defn(Info, Data, !DeclSet, !IO) :-
+    (
+        Data = module_layout_common_data(ModuleName,
+            StringTableSize, StringTable),
+        output_module_common_layout_data_defn(ModuleName, StringTableSize,
+            StringTable, !DeclSet, !IO)
+    ;
+        Data = module_layout_data(ModuleName, ModuleCommonLayoutName,
+            ProcLayoutNames, FileLayouts, TraceLevel,
+            SuppressedEvents, NumLabels, MaybeEventSet),
+        output_module_layout_data_defn(Info, ModuleName,
+            ModuleCommonLayoutName, ProcLayoutNames, FileLayouts, TraceLevel,
+            SuppressedEvents, NumLabels, MaybeEventSet, !DeclSet, !IO)
+    ).
+
     % The version of the layout data structures -- useful for bootstrapping.
     % If you write runtime code that checks this version number and can
     % at least handle the previous version of the data structure,
@@ -1628,8 +2441,7 @@
     output_layout_name(ModuleStringTableName, !IO),
     io.write_string("\n};\n", !IO),
 
-    decl_set_insert(decl_data_addr(layout_addr(ModuleCommonLayoutName)),
-        !DeclSet).
+    decl_set_insert(decl_layout_id(ModuleCommonLayoutName), !DeclSet).
 
 :- pred output_module_layout_data_defn(llds_out_info::in,
     module_name::in, layout_name::in, list(layout_name)::in,
@@ -1654,7 +2466,7 @@
     output_layout_name_storage_type_name(LabelExecCountName,
         being_defined, !IO),
     io.write_string(";\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LabelExecCountName)), !DeclSet),
+    decl_set_insert(decl_layout_id(LabelExecCountName), !DeclSet),
 
     (
         MaybeEventSetLayout = no
@@ -1720,7 +2532,7 @@
         output_layout_name(EventSpecLayoutName, !IO)
     ),
     io.write_string("\n};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(ModuleLayoutName)), !DeclSet).
+    decl_set_insert(decl_layout_id(ModuleLayoutName), !DeclSet).
 
 :- pred output_event_specs_and_components(llds_out_info::in,
     list(event_spec)::in, module_name::in, map(int, rval)::in,
@@ -1732,8 +2544,7 @@
         !DeclSet, !IO),
 
     LayoutName = module_layout_event_specs(ModuleName),
-    DataAddr = layout_addr(LayoutName),
-    decl_set_insert(decl_data_addr(DataAddr), !DeclSet),
+    decl_set_insert(decl_layout_id(LayoutName), !DeclSet),
     output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     io.write_list(EventSpecs, ",\n",
@@ -1749,8 +2560,7 @@
 
     AttrNamesLayoutName =
         module_layout_event_arg_names(ModuleName, EventNumber),
-    AttrNamesDataAddr = layout_addr(AttrNamesLayoutName),
-    decl_set_insert(decl_data_addr(AttrNamesDataAddr), !DeclSet),
+    decl_set_insert(decl_layout_id(AttrNamesLayoutName), !DeclSet),
     output_layout_name_storage_type_name(AttrNamesLayoutName,
         being_defined, !IO),
     io.write_string(" = {\n", !IO),
@@ -1767,8 +2577,7 @@
 
         SynthAttrsLayoutName =
             module_layout_event_synth_attrs(ModuleName, EventNumber),
-        SynthAttrsDataAddr = layout_addr(SynthAttrsLayoutName),
-        decl_set_insert(decl_data_addr(SynthAttrsDataAddr), !DeclSet),
+        decl_set_insert(decl_layout_id(SynthAttrsLayoutName), !DeclSet),
         output_layout_name_storage_type_name(SynthAttrsLayoutName,
             being_defined, !IO),
         io.write_string(" = {\n", !IO),
@@ -1778,8 +2587,7 @@
 
         SynthOrderLayoutName =
             module_layout_event_synth_order(ModuleName, EventNumber),
-        SynthOrderDataAddr = layout_addr(SynthOrderLayoutName),
-        decl_set_insert(decl_data_addr(SynthOrderDataAddr), !DeclSet),
+        decl_set_insert(decl_layout_id(SynthOrderLayoutName), !DeclSet),
         output_layout_name_storage_type_name(SynthOrderLayoutName,
             being_defined, !IO),
         io.write_string(" = {\n", !IO),
@@ -1809,8 +2617,7 @@
 
         ArgsLayoutName = module_layout_event_synth_attr_args(ModuleName,
             EventNumber, AttrNumber),
-        ArgsDataAddr = layout_addr(ArgsLayoutName),
-        decl_set_insert(decl_data_addr(ArgsDataAddr), !DeclSet),
+        decl_set_insert(decl_layout_id(ArgsLayoutName), !DeclSet),
         output_layout_name_storage_type_name(ArgsLayoutName,
             being_defined, !IO),
         io.write_string(" =\n{ ", !IO),
@@ -1819,8 +2626,7 @@
 
         OrderLayoutName = module_layout_event_synth_attr_order(ModuleName,
             EventNumber, AttrNumber),
-        OrderDataAddr = layout_addr(OrderLayoutName),
-        decl_set_insert(decl_data_addr(OrderDataAddr), !DeclSet),
+        decl_set_insert(decl_layout_id(OrderLayoutName), !DeclSet),
         output_layout_name_storage_type_name(OrderLayoutName,
             being_defined, !IO),
         io.write_string(" =\n{ ", !IO),
@@ -1917,7 +2723,7 @@
         list.foldl(output_proc_layout_name_in_vector, ProcLayoutNames, !IO)
     ),
     io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(VectorName)), !DeclSet).
+    decl_set_insert(decl_layout_id(VectorName), !DeclSet).
 
 :- pred output_proc_layout_name_in_vector(layout_name::in, io::di, io::uo)
     is det.
@@ -1945,7 +2751,7 @@
     io.write_string(" = {", !IO),
     output_module_string_table_strings(EventSetDesc, [], !IO),
     io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
+    decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
 
 :- pred output_module_string_table(module_name::in,
     int::in, string_with_0s::in, decl_set::in, decl_set::out,
@@ -1958,16 +2764,14 @@
     output_layout_name_storage_type_name(TableName, being_defined, !IO),
     io.write_string(" = {", !IO),
 
-    %
     % The string table cannot be zero size; it must contain at least an
     % empty string.
-    %
     ( StringTable0 = [], FirstString = "", Rest = []
     ; StringTable0 = [FirstString | Rest]
     ),
     output_module_string_table_strings(FirstString, Rest, !IO),
     io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(TableName)), !DeclSet).
+    decl_set_insert(decl_layout_id(TableName), !DeclSet).
 
 :- pred output_module_string_table_strings(string::in, list(string)::in,
     io::di, io::uo) is det.
@@ -2024,7 +2828,7 @@
         list.foldl(output_layout_name_in_vector("&"), FileLayoutNames, !IO)
     ),
     io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(VectorName)), !DeclSet).
+    decl_set_insert(decl_layout_id(VectorName), !DeclSet).
 
 :- pred output_file_layout_data_defns(llds_out_info::in, module_name::in,
     int::in, list(file_layout_data)::in, list(layout_name)::out,
@@ -2050,7 +2854,7 @@
     assoc_list.keys_and_values(LineNoLabelList, LineNos, LabelLayoutSlots),
 
     list.length(LineNoLabelList, VectorLengths),
-    output_file_layout_line_number_vector_defn(ModuleName, FileNum,
+    output_file_layout_line_number_vector_defn(Info, ModuleName, FileNum,
         LineNos, LineNumberVectorName, !DeclSet, !IO),
     output_file_layout_label_layout_vector_defn(MangledModuleName, ModuleName,
         FileNum, LabelLayoutSlots, LabelVectorName, !DeclSet, !IO),
@@ -2067,29 +2871,31 @@
     io.write_string(",\n", !IO),
     output_layout_name(LabelVectorName, !IO),
     io.write_string("\n};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(FileLayoutName)), !DeclSet).
+    decl_set_insert(decl_layout_id(FileLayoutName), !DeclSet).
 
-:- pred output_file_layout_line_number_vector_defn(module_name::in, int::in,
-    list(int)::in, layout_name::out, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
+:- pred output_file_layout_line_number_vector_defn(llds_out_info::in,
+    module_name::in, int::in, list(int)::in, layout_name::out,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_file_layout_line_number_vector_defn(ModuleName, FileNum, LineNumbers,
-        LayoutName, !DeclSet, !IO) :-
+output_file_layout_line_number_vector_defn(Info, ModuleName, FileNum,
+        LineNumbers, LayoutName, !DeclSet, !IO) :-
     LayoutName = file_layout_line_number_vector(ModuleName, FileNum),
     io.write_string("\n", !IO),
     output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
-    io.write_string(" = {\n", !IO),
+    io.write_string(" = {", !IO),
     (
         LineNumbers = [],
         % ANSI/ISO C doesn't allow empty arrays, so place a dummy value
         % in the array.
-        io.write_string("0\n", !IO)
+        io.write_string("\n0", !IO)
     ;
         LineNumbers = [_ | _],
-        list.foldl(output_number_in_vector, LineNumbers, !IO)
+        AutoComments = Info ^ lout_auto_comments,
+        list.foldl2(output_number_in_vector(AutoComments), LineNumbers,
+            0, _, !IO)
     ),
-    io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
+    io.write_string("\n};\n", !IO),
+    decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
 
 :- pred output_file_layout_label_layout_vector_defn(string::in,
     module_name::in, int::in, list(layout_slot_name)::in, layout_name::out,
@@ -2111,7 +2917,7 @@
         output_layout_slots_in_vector(MangledModuleName, LabelSlots, !IO)
     ),
     io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
+    decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
 
 %-----------------------------------------------------------------------------%
 
@@ -2123,11 +2929,14 @@
     SlotName = layout_slot(ArrayName, SlotNum),
     (
         (
-            ArrayName = label_layout_array(label_has_var_info),
-            Macro = "MR_var_label_layout_refs"
-        ;
             ArrayName = label_layout_array(label_has_no_var_info),
             Macro = "MR_no_var_label_layout_refs"
+        ;
+            ArrayName = label_layout_array(label_has_short_var_info),
+            Macro = "MR_svar_label_layout_refs"
+        ;
+            ArrayName = label_layout_array(label_has_long_var_info),
+            Macro = "MR_lvar_label_layout_refs"
         ),
         find_slots_in_same_array(ArrayName, SlotNames, [], RevTailSlotNums,
             OtherArraySlotNames),
@@ -2140,11 +2949,26 @@
         list.foldl(output_layout_slot_chunk(Macro, ModuleName),
             SlotNumChunks, !IO),
         output_layout_slots_in_vector(ModuleName, OtherArraySlotNames, !IO)
+
     ;
-        ( ArrayName = user_event_var_nums_array
+        ( ArrayName = pseudo_type_info_array
+        ; ArrayName = long_locns_array
+        ; ArrayName = short_locns_array
+        ; ArrayName = hlds_var_nums_array
+        ; ArrayName = user_event_var_nums_array
         ; ArrayName = user_event_layout_array
+        ; ArrayName = proc_static_call_sites_array
+        ; ArrayName = proc_static_cp_static_array
+        ; ArrayName = proc_static_cp_dynamic_array
+        ; ArrayName = proc_static_array
+        ; ArrayName = proc_var_names_array
+        ; ArrayName = proc_head_var_nums_array
+        ; ArrayName = proc_body_bytecodes_array
+        ; ArrayName = proc_table_io_decl_array
+        ; ArrayName = proc_event_layouts_array
+        ; ArrayName = proc_exec_trace_array
         ),
-        output_layout_slot_name(use_layout_macro, ModuleName, SlotName, !IO),
+        output_layout_slot_addr(use_layout_macro, ModuleName, SlotName, !IO),
         io.write_string(",\n", !IO),
         output_layout_slots_in_vector(ModuleName, SlotNames, !IO)
     ).
@@ -2179,249 +3003,43 @@
     io.write_string(")\n", !IO).
 
 %-----------------------------------------------------------------------------%
-
-:- pred quote_and_write_string(string::in, io::di, io::uo) is det.
-
-quote_and_write_string(String, !IO) :-
-    io.write_string("""", !IO),
-    c_util.output_quoted_string(String, !IO),
-    io.write_string("""", !IO).
-
-:- pred output_number_in_vector(int::in, io::di, io::uo) is det.
-
-output_number_in_vector(Num, !IO) :-
-    io.write_int(Num, !IO),
-    io.write_string(",\n", !IO).
-
-:- pred output_layout_name_in_vector(string::in, layout_name::in,
-    io::di, io::uo) is det.
-
-output_layout_name_in_vector(Prefix, Name, !IO) :-
-    io.write_string(Prefix, !IO),
-    output_layout_name(Name, !IO),
-    io.write_string(",\n", !IO).
-
-:- pred output_data_addr_in_vector(string::in, data_addr::in,
-    io::di, io::uo) is det.
-
-output_data_addr_in_vector(Prefix, DataAddr, !IO) :-
-    io.write_string(Prefix, !IO),
-    output_data_addr(DataAddr, !IO),
-    io.write_string(",\n", !IO).
-
 %-----------------------------------------------------------------------------%
+%
+% Utility predicates.
+%
 
-:- 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, ProcLayoutProcStatic,
-        !DeclSet, !IO) :-
-    ProcLayoutProcStatic = proc_layout_proc_static(HLDSProcStatic,
-        DeepExcpVars, _),
-    HLDSProcStatic = hlds_proc_static(FileName, LineNumber, IsInInterface,
-        CallSites, CoveragePoints),
-
-    % Write out data the proc static will reference.
-    list.foldl2(output_call_site_static_decl, CallSites, !DeclSet, !IO),
-    output_call_site_static_array(RttiProcLabel, CallSites, !DeclSet, !IO),
-    output_coverage_point_static_array(RttiProcLabel, CoveragePoints, !DeclSet,
-        !IO),
-    length(CoveragePoints, NumCoveragePoints),
-    output_coverage_point_dynamic_array(RttiProcLabel, NumCoveragePoints,
-        !DeclSet, !IO),
-
-    % Write out the proc static.
-    LayoutName = proc_static(RttiProcLabel),
-    io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
-    io.write_string(" = {\n", !IO),
-    quote_and_write_string(FileName, !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(LineNumber, !IO),
-    io.write_string(",\n", !IO),
-    (
-        IsInInterface = yes,
-        io.write_string("MR_TRUE", !IO)
-    ;
-        IsInInterface = no,
-        io.write_string("MR_FALSE", !IO)
-    ),
-    io.write_string(",\n", !IO),
-    io.write_int(list.length(CallSites), !IO),
-    io.write_string(",\n", !IO),
-    CallSitesLayoutName = proc_static_call_sites(RttiProcLabel),
-    output_layout_name(CallSitesLayoutName, !IO),
-    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", !IO),
-    DeepExcpVars = deep_excp_slots(TopCSDSlot, MiddleCSDSlot,
-        OldOutermostSlot),
-    io.write_int(TopCSDSlot, !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(MiddleCSDSlot, !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(OldOutermostSlot, !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(NumCoveragePoints, !IO),
-    io.write_string(",\n", !IO),
-    CoveragePointStaticName = proc_static_coverage_point_static(RttiProcLabel),
-    output_layout_name(CoveragePointStaticName, !IO),
-    io.write_string(",\n", !IO),
-    CoveragePointDynamicName =
-        proc_static_coverage_point_dynamic(RttiProcLabel),
-    output_layout_name(CoveragePointDynamicName, !IO),
-    io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
-
-:- pred output_call_site_static_array(rtti_proc_label::in,
-    list(call_site_static_data)::in, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
-
-output_call_site_static_array(RttiProcLabel, CallSites, !DeclSet, !IO) :-
-    LayoutName = proc_static_call_sites(RttiProcLabel),
-    io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
-    io.write_string(" = {\n", !IO),
-    list.foldl2(output_call_site_static, CallSites, 0, _, !IO),
-    io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
-
-:- pred output_call_site_static(call_site_static_data::in, int::in, int::out,
+:- pred output_number_in_vector(bool::in, int::in, int::in, int::out,
     io::di, io::uo) is det.
 
-output_call_site_static(CallSiteStatic, Index, Index + 1, !IO) :-
-    io.write_string("{ /* ", !IO),
-    io.write_int(Index, !IO),
-    io.write_string(" */ ", !IO),
+output_number_in_vector(AutoComments, VarNum, !Slot, !IO) :-
+    ( !.Slot mod 10 = 0 ->
     (
-        CallSiteStatic = normal_call(Callee, TypeSubst, FileName, LineNumber,
-            GoalPath),
-        io.write_string("MR_callsite_normal_call, (MR_ProcLayout *)\n&", !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)
+            AutoComments = yes,
+            io.format("\n/* slots %d+ */ ", [i(!.Slot)], !IO)
         ;
-            io.write_string(",\n""", !IO),
-            io.write_string(TypeSubst, !IO),
-            io.write_string(""", ", !IO)
+            AutoComments = no,
+            io.nl(!IO)
         )
     ;
-        CallSiteStatic = special_call(FileName, LineNumber, GoalPath),
-        io.write_string("MR_callsite_special_call, NULL, NULL, ", !IO)
-    ;
-        CallSiteStatic = higher_order_call(FileName, LineNumber, GoalPath),
-        io.write_string("MR_callsite_higher_order_call, NULL, NULL, ", !IO)
-    ;
-        CallSiteStatic = method_call(FileName, LineNumber, GoalPath),
-        io.write_string("MR_callsite_method_call, NULL, NULL, ", !IO)
-    ;
-        CallSiteStatic = callback(FileName, LineNumber, GoalPath),
-        io.write_string("MR_callsite_callback, NULL, NULL, ", !IO)
+        io.write_string(" ", !IO)
     ),
-    io.write_string("""", !IO),
-    io.write_string(FileName, !IO),
-    io.write_string(""", ", !IO),
-    io.write_int(LineNumber, !IO),
-    io.write_string(", """, !IO),
-    io.write_string(goal_path_to_string(GoalPath), !IO),
-    io.write_string(""" },\n", !IO).
-
-:- pred output_call_site_static_decl(call_site_static_data::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_call_site_static_decl(CallSiteStatic, !DeclSet, !IO) :-
-    (
-        CallSiteStatic = normal_call(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(_, _, _)
-    ;
-        CallSiteStatic = higher_order_call(_, _, _)
-    ;
-        CallSiteStatic = method_call(_, _, _)
-    ;
-        CallSiteStatic = callback(_, _, _)
-    ).
-
-%-----------------------------------------------------------------------------%
+    io.format("%d,", [i(VarNum)], !IO),
+    !:Slot = !.Slot + 1.
 
-    % Write out a C representation of the coverage point static data.
-    %
-:- pred output_coverage_point_static_array(rtti_proc_label::in,
-    list(coverage_point_info)::in, decl_set::in, decl_set::out,
+:- pred output_layout_name_in_vector(string::in, layout_name::in,
     io::di, io::uo) is det.
 
-output_coverage_point_static_array(RttiProcLabel, CoveragePoints, !DeclSet,
-        !IO) :-
-    LayoutName = proc_static_coverage_point_static(RttiProcLabel),
-    io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
-    io.write_string(" = {\n", !IO),
-    list.foldl(output_coverage_point_static, CoveragePoints, !IO),
-    io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
-
-:- pred output_coverage_point_static(coverage_point_info::in, io::di, io::uo)
-    is det.
-
-output_coverage_point_static(coverage_point_info(GoalPath, CPType), !IO) :-
-    io.write_string("{ """, !IO),
-    GoalPathString = goal_path_to_string(GoalPath),
-    io.write_string(GoalPathString, !IO),
-    io.write_string(""", ", !IO),
-    coverage_point_type_c_value(CPType, CPTypeCValue),
-    io.write_string(CPTypeCValue, !IO),
-    io.write_string(" },\n", !IO).
-
-:- pred output_coverage_point_dynamic_array(rtti_proc_label::in, int::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_coverage_point_dynamic_array(RttiProcLabel, NumCoveragePoints,
-        !DeclSet, !IO) :-
-    LayoutName = proc_static_coverage_point_dynamic(RttiProcLabel),
-    io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
-    io.write_string(" = {\n", !IO),
-    duplicate(NumCoveragePoints, "0,", Zeros),
-    io.write_strings(Zeros, !IO),
-    io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
-
-%-----------------------------------------------------------------------------%
-
-:- pred output_table_io_decl(llds_out_info::in, rtti_proc_label::in,
-    proc_layout_kind::in, int::in, rval::in, rval::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_table_io_decl(Info, RttiProcLabel, ProcLayoutKind, NumPTIs,
-        PTIVectorRval, TypeParamsRval, !DeclSet, !IO) :-
-    output_record_rval_decls(Info, PTIVectorRval, !DeclSet, !IO),
-    LayoutName = table_io_decl(RttiProcLabel),
-    ProcLayoutName = proc_layout(RttiProcLabel, ProcLayoutKind),
-    output_layout_decl(ProcLayoutName, !DeclSet, !IO),
+output_layout_name_in_vector(Prefix, Name, !IO) :-
+    io.write_string(Prefix, !IO),
+    output_layout_name(Name, !IO),
+    io.write_string(",\n", !IO).
 
-    io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
-    io.write_string(" = {\n(const MR_ProcLayout *) &", !IO),
-    output_layout_name(ProcLayoutName, !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(NumPTIs, !IO),
-    io.write_string(",\n(const MR_PseudoTypeInfo *) ", !IO),
-    output_rval(Info, PTIVectorRval, !IO),
-    io.write_string(",\n(const MR_TypeParamLocns *) ", !IO),
-    output_rval(Info, TypeParamsRval, !IO),
-    io.write_string("\n};\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
+:- pred quote_and_write_string(string::in, io::di, io::uo) is det.
 
-%-----------------------------------------------------------------------------%
+quote_and_write_string(String, !IO) :-
+    io.write_string("""", !IO),
+    c_util.output_quoted_string(String, !IO),
+    io.write_string("""", !IO).
 
 output_pred_or_func(PredOrFunc, !IO) :-
     (
Index: compiler/ll_pseudo_type_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ll_pseudo_type_info.m,v
retrieving revision 1.23
diff -u -b -r1.23 ll_pseudo_type_info.m
--- compiler/ll_pseudo_type_info.m	21 Sep 2009 04:08:53 -0000	1.23
+++ compiler/ll_pseudo_type_info.m	27 Oct 2009 05:55:04 -0000
@@ -90,9 +90,9 @@
         LldsType = lt_integer
     ;
         Pseudo = plain_arity_zero_pseudo_type_info(RttiTypeCtor),
-        DataAddr = rtti_addr(
+        DataId = rtti_data_id(
             ctor_rtti_id(RttiTypeCtor, type_ctor_pseudo_type_info(Pseudo))),
-        Rval = const(llconst_data_addr(DataAddr, no)),
+        Rval = const(llconst_data_addr(DataId, no)),
         LldsType = lt_data_ptr
     ;
         Pseudo = plain_pseudo_type_info(RttiTypeCtor, Args),
@@ -114,9 +114,9 @@
 convert_plain_type_info(TypeInfo, !StaticCellInfo, Rval, LldsType) :-
     (
         TypeInfo = plain_arity_zero_type_info(RttiTypeCtor),
-        DataAddr = rtti_addr(ctor_rtti_id(RttiTypeCtor,
+        DataId = rtti_data_id(ctor_rtti_id(RttiTypeCtor,
             type_ctor_type_info(TypeInfo))),
-        Rval = const(llconst_data_addr(DataAddr, no)),
+        Rval = const(llconst_data_addr(DataId, no)),
         LldsType = lt_data_ptr
     ;
         TypeInfo = plain_type_info(RttiTypeCtor, Args),
@@ -138,9 +138,9 @@
 
 convert_compound_pseudo_type_info(RttiTypeCtor, ArgRvals0, Args,
         !StaticCellInfo, Rval, LldsType) :-
-    TypeCtorInfoDataAddr = rtti_addr(
+    TypeCtorInfoDataId = rtti_data_id(
         ctor_rtti_id(RttiTypeCtor, type_ctor_type_ctor_info)),
-    TypeCtorInfoRval = const(llconst_data_addr(TypeCtorInfoDataAddr, no)),
+    TypeCtorInfoRval = const(llconst_data_addr(TypeCtorInfoDataId, no)),
     LldsType = lt_data_ptr,
     list.map_foldl((pred(A::in, AR::out, SCI0::in, SCI::out) is det :-
         (
@@ -153,8 +153,8 @@
     ), Args, ArgRvals1, !StaticCellInfo),
     list.append(ArgRvals0, ArgRvals1, ArgRvals),
     add_scalar_static_cell_natural_types([TypeCtorInfoRval | ArgRvals],
-        DataAddr, !StaticCellInfo),
-    Rval = const(llconst_data_addr(DataAddr, no)).
+        DataId, !StaticCellInfo),
+    Rval = const(llconst_data_addr(DataId, no)).
 
 :- pred convert_compound_type_info(rtti_type_ctor::in, list(rval)::in,
     list(rtti_type_info)::in, static_cell_info::in, static_cell_info::out,
@@ -164,17 +164,17 @@
         Rval, LldsType) :-
     TypeCtorInfoData = type_ctor_type_info(
         plain_arity_zero_type_info(RttiTypeCtor)),
-    TypeCtorInfoDataAddr = rtti_addr(
+    TypeCtorInfoDataId = rtti_data_id(
         ctor_rtti_id(RttiTypeCtor, TypeCtorInfoData)),
-    TypeCtorInfoRval = const(llconst_data_addr(TypeCtorInfoDataAddr, no)),
+    TypeCtorInfoRval = const(llconst_data_addr(TypeCtorInfoDataId, no)),
     LldsType = lt_data_ptr,
     list.map_foldl((pred(A::in, AR::out, SCI0::in, SCI::out) is det :-
         convert_plain_type_info(A, SCI0, SCI, AR, _LldsType)
     ), Args, ArgRvals1, !StaticCellInfo),
     list.append(ArgRvals0, ArgRvals1, ArgRvals),
     add_scalar_static_cell_natural_types([TypeCtorInfoRval | ArgRvals],
-        DataAddr, !StaticCellInfo),
-    Rval = const(llconst_data_addr(DataAddr, no)).
+        DataId, !StaticCellInfo),
+    Rval = const(llconst_data_addr(DataId, no)).
 
 %-----------------------------------------------------------------------------%
 :- end_module ll_pseudo_type_info.
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.364
diff -u -b -r1.364 llds.m
--- compiler/llds.m	21 Oct 2009 06:36:20 -0000	1.364
+++ compiler/llds.m	27 Oct 2009 07:49:52 -0000
@@ -75,16 +75,31 @@
                 cfile_scalar_common_data    :: list(scalar_common_data_array),
                 cfile_vector_common_data    :: list(vector_common_data_array),
                 cfile_rtti_data             :: list(rtti_data),
+                cfile_ptis                  :: list(rval),
+                cfile_hlds_var_nums         :: list(int),
+                cfile_short_locns           :: list(int),
+                cfile_long_locns            :: list(int),
                 cfile_user_event_var_nums   :: list(maybe(int)),
                 cfile_user_events           :: list(user_event_data),
-                cfile_var_label_layouts     :: list(label_layout_vars),
                 cfile_no_var_label_layouts  :: list(label_layout_no_vars),
+                cfile_svar_label_layouts    :: list(label_layout_short_vars),
+                cfile_lvar_label_layouts    :: list(label_layout_long_vars),
                 cfile_i_label_to_layout_map :: map(label, layout_slot_name),
-                cfile_p_label_to_layout_map :: map(label, data_addr),
-                cfile_proc_layout_data      :: list(layout_data),
-                cfile_module_layout_data    :: list(layout_data),
-                cfile_closure_layout_data   :: list(layout_data),
-                cfile_other_layout_data     :: list(layout_data),
+                cfile_p_label_to_layout_map :: map(label, data_id),
+                cfile_call_sites            :: list(call_site_static_data),
+                cfile_coverage_points       :: list(coverage_point_info),
+                cfile_proc_statics          :: list(proc_layout_proc_static),
+                cfile_proc_head_var_nums    :: list(int),
+                cfile_proc_var_names        :: list(int),
+                cfile_proc_body_bytecodes   :: list(int),
+                cfile_table_io_decls        :: list(table_io_decl_data),
+                cfile_table_io_decl_map     :: map(pred_proc_id,
+                                                layout_slot_name),
+                cfile_proc_event_layouts    :: list(layout_slot_name),
+                cfile_exec_traces           :: list(proc_layout_exec_trace),
+                cfile_proc_layouts          :: list(proc_layout_data),
+                cfile_module_layout_data    :: list(module_layout_data),
+                cfile_closure_layout_data   :: list(closure_proc_id_data),
                 cfile_code                  :: list(comp_gen_c_module),
                 cfile_user_init_c_names     :: list(string),
                 cfile_user_final_c_names    :: list(string),
@@ -94,21 +109,20 @@
     % Global variables generated by the compiler.
 :- type tabling_info_struct
     --->    tabling_info_struct(
-                tis_module_name             :: module_name,
-                                            % The basename of this C file.
+                % The id of the procedure whose table this structure is.
                 tis_proc_label              :: proc_label,
-                                            % The id of the procedure whose
-                                            % table this structure represents.
                 tis_eval_method             :: eval_method,
 
                 tis_num_inputs              :: int,
                 tis_num_outputs             :: int,
                 tis_input_steps             :: list(table_step_desc),
                 tis_maybe_output_steps      :: maybe(list(table_step_desc)),
-                tis_ptis                    :: rval,
+
                                             % Pseudo-typeinfos for headvars.
-                tis_type_params             :: rval,
+                tis_ptis                    :: rval,
                                             % Where to fill the ptis in from.
+                tis_type_params             :: rval,
+
                 tis_size_limit              :: maybe(int),
                 tis_stats                   :: table_attr_statistics
             ).
@@ -128,15 +142,18 @@
 
 :- type common_cell_arg_group
     --->    common_cell_grouped_args(
-                llds_type,      % The shared type of the fields in the group.
-                int,            % The number of fields in the group. This will
-                                % contain the length of the list in the third
-                                % argument, but computed only once. It ought
-                                % to be more than one; if a field cannot be
-                                % grouped with neighbouring values of the same
-                                % type, it should be stored as an ungrouped
-                                % arg.
-                list(rval)      % The field values themselves.
+                % The shared type of the fields in the group.
+                llds_type,
+
+                % The number of fields in the group. This will contain
+                % the length of the list in the third argument, but computed
+                % only once. It ought to be more than one; if a field cannot be
+                % grouped with neighbouring values of the same type, it should
+                % be stored as an ungrouped arg.
+                int,
+
+                % The field values themselves.
+                list(rval)
             )
     ;       common_cell_ungrouped_arg(
                 llds_type,      % The type of the field.
@@ -148,29 +165,29 @@
 
 :- type scalar_common_data_array
     --->    scalar_common_data_array(
-                scda_module     :: module_name,
-                                % The basename of this C file.
-                scda_rval_types :: common_cell_type,
                                 % The type of the elements of the array.
-                scda_type_num   :: type_num,
+                scda_rval_types :: common_cell_type,
+
                                 % The type number.
-                scda_values     :: list(common_cell_value)
+                scda_type_num   :: type_num,
+
                                 % The array elements, starting at offset 0.
+                scda_values     :: list(common_cell_value)
             ).
 
 :- type vector_common_data_array
     --->    vector_common_data_array(
-                vcda_module     :: module_name,
-                                % The basename of this C file.
-                vcda_rval_types :: common_cell_type,
                                 % The type of the elements of the array.
-                vcda_type_num   :: type_num,
+                vcda_rval_types :: common_cell_type,
                                 % The type number.
+                vcda_type_num   :: type_num,
+
+                % The number of this vector, among all the vector cells
+                % with this type for the elements.
                 vcda_vector_num :: int,
-                                % The number of this vector, among all the
-                                % vector cells with this type for the elements.
-                vcda_values     :: list(common_cell_value)
+
                                 % The array elements, starting at offset 0.
+                vcda_values     :: list(common_cell_value)
             ).
 
 :- type comp_gen_c_module
@@ -183,27 +200,33 @@
 
 :- type c_procedure
     --->    c_procedure(
-                cproc_name              :: string,
                                         % Predicate name.
-                cproc_orig_arity        :: int,
+                cproc_name              :: string,
+
                                         % Original arity.
-                cproc_id                :: pred_proc_id,
+                cproc_orig_arity        :: int,
+
                                         % The pred_proc_id of this code.
-                cproc_code_model        :: code_model,
+                cproc_id                :: pred_proc_id,
+
                                         % The code model of the procedure.
-                cproc_code              :: list(instruction),
+                cproc_code_model        :: code_model,
+
                                         % The code for this procedure.
-                cproc_proc_label        :: proc_label,
+                cproc_code              :: list(instruction),
+
                                         % Proc_label of this procedure.
-                cproc_label_nums        :: counter,
+                cproc_proc_label        :: proc_label,
+
                                         % Source for new label numbers.
-                cproc_may_alter_rtti    :: may_alter_rtti,
-                                        % The compiler is allowed to perform
-                                        % optimizations on this c_procedure
-                                        % that could alter RTTI information
-                                        % (e.g. the set of variables live at
-                                        % a label) only if this field is set
+                cproc_label_nums        :: counter,
+
+                % The compiler is allowed to perform optimizations on this
+                % c_procedure that could alter RTTI information (e.g. the set
+                % of variables live at a label) only if this field is set
                                         % to `may_alter_rtti'.
+                cproc_may_alter_rtti    :: may_alter_rtti,
+
                 cproc_c_global_vars     :: set(string)
             ).
 
@@ -1130,31 +1153,47 @@
             % in the list.
 
     ;       llconst_code_addr(code_addr)
-    ;       llconst_data_addr(data_addr, maybe(int)).
+    ;       llconst_data_addr(data_id, maybe(int)).
             % If the second arg is yes(Offset), then increment the address
             % of the first by Offset words.
 
-:- type data_addr
-    --->    data_addr(module_name, data_name)
-            % module name; which var
-    ;       rtti_addr(rtti_id)
-    ;       layout_addr(layout_name).
-
-:- type data_name
-    --->    scalar_common_ref(type_num, int)
-            % We store all standalone (scalar) common cells of the same type
-            % in an array. A reference to one of these cells contains the
-            % the type number (which becomes the distinguishing part of the
-            % name of the global variable containing all these scalar cells)
-            % which is stored in the first integer, and the offset within
-            % this array, which is stored in the second integer.
-
-    ;       vector_common_ref(type_num, int)
-            % We store each vector of common cells in its own global variable,
-            % identified by a sequence number. The first integer is this
-            % sequence number; the second is the offset in the array.
+    % A data_id is an lval representing the given variable or array slot.
+    % Most references to the data_ref will want to take the address of this
+    % lval (by sticking a & in front of it), but in a few situations we need
+    % to be able to refer to the lval itself. One of those situations is when
+    % we are defining the variable. Another is when the variable is an array,
+    % and its name is implicitly taken by the C compiler as the address of the
+    % first element.
+    %
+:- type data_id
+    --->    rtti_data_id(rtti_id)
+            % The global variable holding the RTTI structure identified
+            % by the rtti_id.
+
+    ;       proc_tabling_data_id(proc_label, proc_tabling_struct_id)
+            % The tabling structure of the kind identified by the
+            % proc_tabling_struct_id for the procedure given by the
+            % proc_label.
+
+    ;       scalar_common_data_id(type_num, int)
+            % scalar_common_ref(TypeNum, CellNum) is the slot at index CellNum
+            % in the array of scalar cells of type TypeNum.
+
+    ;       vector_common_data_id(type_num, int)
+            % vector_common_ref(TypeNum, CellNum) is the sequence of slots
+            % starting at index CellNum in the array of vector cells of
+            % type TypeNum.
+
+    ;       layout_id(layout_name)
+            % The global variable holding the layout structure identified
+            % by the layout_name.
+
+    ;       layout_slot_id(layout_slot_id_kind, pred_proc_id).
+            % The slot reserved for the given pred_proc_id in in the array
+            % identified by the layout_slot_id_kind.
 
-    ;       proc_tabling_ref(proc_label, proc_tabling_struct_id).
+:- type layout_slot_id_kind
+    --->    table_io_decl_id.
 
 :- type reg_type
     --->    reg_r       % general-purpose (integer) regs
@@ -1475,15 +1514,14 @@
     unexpected(this_file, "var unexpected in llds.rval_type").
     %
     % Note that mkword and data_addr consts must be of type data_ptr,
-    % not of type word, to ensure that static consts containing
-    % them get type `const MR_Word *', not type `MR_Word'; this is
-    % necessary because casts from pointer to int must not be used
-    % in the initializers for constant expressions -- if they are,
-    % then lcc barfs, and gcc generates bogus code on some systems,
-    % (e.g. IRIX with shared libs).  If the second argument to mkword
-    % is an integer, not a pointer, then we will end up casting it
-    % to a pointer, but casts from integer to pointer are OK, it's
-    % only the reverse direction we need to avoid.
+    % not of type word, to ensure that static consts containing them
+    % get type `const MR_Word *', not type `MR_Word'; this is necessary because
+    % casts from pointer to int must not be used in the initializers for
+    % constant expressions -- if they are, then lcc barfs, and gcc generates
+    % bogus code on some systems, (e.g. IRIX with shared libs). If the second
+    % argument to mkword is an integer, not a pointer, then we will end up
+    % casting it to a pointer, but casts from integer to pointer are OK;
+    % it is only the reverse direction we need to avoid.
     %
 rval_type(mkword(_, _), lt_data_ptr).
 rval_type(const(Const), Type) :-
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.333
diff -u -b -r1.333 llds_out.m
--- compiler/llds_out.m	21 Oct 2009 06:36:20 -0000	1.333
+++ compiler/llds_out.m	28 Oct 2009 07:22:33 -0000
@@ -1,10 +1,10 @@
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 % vim: ft=mercury ts=4 sw=4 et
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 % Copyright (C) 1996-2009 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 %
 % File: llds_out.m.
 % Main authors: conway, fjh, zs.
@@ -12,12 +12,14 @@
 % This module defines the routines for printing out LLDS,
 % the Low Level Data Structure.
 %
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- module ll_backend.llds_out.
 :- interface.
 
+:- import_module backend_libs.rtti.
 :- import_module hlds.hlds_llds.
+:- import_module hlds.hlds_pred.
 :- import_module libs.globals.
 :- import_module libs.trace_params.
 :- import_module ll_backend.layout.
@@ -30,13 +32,17 @@
 :- import_module list.
 :- import_module map.
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- type llds_out_info
     --->    llds_out_info(
+                lout_module_name                :: module_name,
                 lout_mangled_module_name        :: string,
-                lout_internal_label_to_layout   :: map(label, layout_slot_name),
-                lout_entry_label_to_layout      :: map(label, data_addr),
+                lout_internal_label_to_layout   :: map(label,
+                                                    layout_slot_name),
+                lout_entry_label_to_layout      :: map(label, data_id),
+                lout_table_io_decl_map          :: map(pred_proc_id,
+                                                    layout_slot_name),
                 lout_auto_comments              :: bool,
                 lout_line_numbers               :: bool,
                 lout_emit_c_loops               :: bool,
@@ -53,7 +59,7 @@
                 lout_globals                    :: globals
             ).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
     % Given a 'c_file' structure, output the LLDS code inside it
     % into a .c file. The second argument gives the set of labels that have
@@ -86,17 +92,21 @@
     % declarations of any static constants, etc. that need to be declared
     % before output_data_addr(DataAddr) is called.
     %
-:- pred output_record_data_addr_decls(llds_out_info::in, data_addr::in,
+:- pred output_record_data_id_decls(llds_out_info::in, data_id::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
-:- pred output_record_data_addr_decls_format(llds_out_info::in, data_addr::in,
+:- pred output_record_data_id_decls_format(llds_out_info::in, data_id::in,
     string::in, string::in, int::in, int::out, decl_set::in, decl_set::out,
     io::di, io::uo) is det.
 
-:- pred output_record_data_addrs_decls(llds_out_info::in, list(data_addr)::in,
+:- pred output_record_data_ids_decls(llds_out_info::in, list(data_id)::in,
     string::in, string::in, int::in, int::out, decl_set::in, decl_set::out,
     io::di, io::uo) is det.
 
-:- pred output_data_addr(data_addr::in, io::di, io::uo) is det.
+:- pred output_data_id(llds_out_info::in, data_id::in, io::di, io::uo)
+    is det.
+
+:- pred output_data_id_addr(llds_out_info::in, data_id::in, io::di, io::uo)
+    is det.
 
 :- func proc_tabling_info_var_name(proc_label) = string.
 
@@ -154,11 +164,12 @@
     % to put these in a new module (maybe llds_out_util).
 
 :- type decl_id
-    --->    decl_common_type(type_num)
-    ;       decl_scalar_common_array(type_num)
-    ;       decl_float_label(string)
+    --->    decl_float_label(string)
+    ;       decl_common_type(type_num)
     ;       decl_code_addr(code_addr)
-    ;       decl_data_addr(data_addr)
+    ;       decl_rtti_id(rtti_id)
+    ;       decl_layout_id(layout_name)
+    ;       decl_tabling_id(proc_label, proc_tabling_struct_id)
     ;       decl_foreign_proc_struct(string)
     ;       decl_c_global_var(c_global_var_ref)
     ;       decl_type_info_like_struct(int)
@@ -176,7 +187,7 @@
 
 :- pred decl_set_is_member(decl_id::in, decl_set::in) is semidet.
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 % Note that we need to know the linkage not just at the definition,
 % but also at every use, because if the use is prior to the definition,
@@ -191,12 +202,12 @@
     --->    extern
     ;       static.
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- func explain_stack_slots(stack_slots, prog_varset) = string.
 
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- implementation.
 
@@ -205,7 +216,6 @@
 :- import_module backend_libs.export.
 :- import_module backend_libs.name_mangle.
 :- import_module backend_libs.proc_label.
-:- import_module backend_libs.rtti.
 :- import_module check_hlds.type_util.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_module.
@@ -237,7 +247,7 @@
 :- import_module term.
 :- import_module varset.
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- type decl_set == set_tree234(decl_id).
 
@@ -250,7 +260,7 @@
 decl_set_is_member(DeclId, DeclSet) :-
     set_tree234.contains(DeclSet, DeclId).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 output_llds(Globals, CFile, !IO) :-
     ModuleName = CFile ^ cfile_modulename,
@@ -308,14 +318,17 @@
 output_single_c_file(Globals, CFile, FileStream, !DeclSet, !IO) :-
     CFile = c_file(ModuleName, C_HeaderLines, UserForeignCode, Exports,
         TablingInfoStructs, ScalarCommonDatas, VectorCommonDatas,
-        RttiDatas, UserEventVarNums, UserEvents,
-        VarLabelLayouts, NoVarLabelLayouts,
+        RttiDatas, PseudoTypeInfos, HLDSVarNums, ShortLocns, LongLocns,
+        UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
         InternalLabelToLayoutMap, EntryLabelToLayoutMap,
+        CallSiteStatics, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes,
+        TableIoDecls, TableIoDeclMap, ProcEventLayouts, ExecTraces,
         ProcLayoutDatas, ModuleLayoutDatas, ClosureLayoutDatas,
-        OtherLayoutDatas, Modules, UserInitPredCNames, UserFinalPredCNames,
-        ComplexityProcs),
+        Modules, UserInitPredCNames, UserFinalPredCNames, ComplexityProcs),
     Info = init_llds_out_info(ModuleName, Globals,
-        InternalLabelToLayoutMap, EntryLabelToLayoutMap),
+        InternalLabelToLayoutMap, EntryLabelToLayoutMap, TableIoDeclMap),
     library.version(Version),
     io.set_output_stream(FileStream, OutputStream, !IO),
     module_name_to_file_name(Globals, ModuleName, ".m", do_not_create_dirs,
@@ -349,77 +362,28 @@
     list.foldl2(output_rtti_data_defn(Info), RttiDatas, !DeclSet, !IO),
 
     io.nl(!IO),
-    MangledModuleName = Info ^ lout_mangled_module_name,
-    (
-        UserEventVarNums = []
-    ;
-        UserEventVarNums = [_ | _],
-        UserEventVarNumArrayName = user_event_var_nums_array,
-        output_layout_array_name_storage_type_name(MangledModuleName,
-            UserEventVarNumArrayName, not_being_defined, !IO),
-        io.write_string("[];\n", !IO)
-    ),
-    (
-        UserEvents = []
-    ;
-        UserEvents = [_ | _],
-        UserEventsArrayName = user_event_layout_array,
-        output_layout_array_name_storage_type_name(MangledModuleName,
-            UserEventsArrayName, not_being_defined, !IO),
-        io.write_string("[];\n", !IO)
-    ),
-    (
-        VarLabelLayouts = []
-    ;
-        VarLabelLayouts = [_ | _],
-        VarLabelLayoutArrayName = label_layout_array(label_has_var_info),
-        output_layout_array_name_storage_type_name(MangledModuleName,
-            VarLabelLayoutArrayName, not_being_defined, !IO),
-        io.write_string("[];\n", !IO)
-    ),
-    (
-        NoVarLabelLayouts = []
-    ;
-        NoVarLabelLayouts = [_ | _],
-        NoVarLabelLayoutArrayName = label_layout_array(label_has_no_var_info),
-        output_layout_array_name_storage_type_name(MangledModuleName,
-            NoVarLabelLayoutArrayName, not_being_defined, !IO),
-        io.write_string("[];\n", !IO)
-    ),
+    output_layout_array_decls(Info, PseudoTypeInfos, HLDSVarNums,
+        ShortLocns, LongLocns, UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
+        CallSiteStatics, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes, TableIoDecls,
+        ProcEventLayouts, ExecTraces, !IO),
 
-    list.foldl2(output_layout_data_defn(Info), ProcLayoutDatas,
-        !DeclSet, !IO),
-    list.foldl2(output_layout_data_defn(Info), ModuleLayoutDatas,
+    list.foldl2(output_proc_layout_data_defn(Info), ProcLayoutDatas,
         !DeclSet, !IO),
-    list.foldl2(output_layout_data_defn(Info), ClosureLayoutDatas,
+    list.foldl2(output_module_layout_data_defn(Info), ModuleLayoutDatas,
         !DeclSet, !IO),
-    list.foldl2(output_layout_data_defn(Info), OtherLayoutDatas,
+    list.foldl2(output_closure_layout_data_defn(Info), ClosureLayoutDatas,
         !DeclSet, !IO),
     io.nl(!IO),
-    (
-        UserEventVarNums = []
-    ;
-        UserEventVarNums = [_ | _],
-        output_user_event_var_nums_array_defn(Info, UserEventVarNums, !IO)
-    ),
-    (
-        UserEvents = []
-    ;
-        UserEvents = [_ | _],
-        output_user_events_array_defn(Info, UserEvents, !IO)
-    ),
-    (
-        VarLabelLayouts = []
-    ;
-        VarLabelLayouts = [_ | _],
-        output_var_label_layouts_array_defn(Info, VarLabelLayouts, !IO)
-    ),
-    (
-        NoVarLabelLayouts = []
-    ;
-        NoVarLabelLayouts = [_ | _],
-        output_no_var_label_layouts_array_defn(Info, NoVarLabelLayouts, !IO)
-    ),
+
+    output_record_rvals_decls(Info, PseudoTypeInfos, !DeclSet, !IO),
+    output_layout_array_defns(Info, PseudoTypeInfos, HLDSVarNums,
+        ShortLocns, LongLocns, UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
+        CallSiteStatics, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes, TableIoDecls,
+        ProcEventLayouts, ExecTraces, !DeclSet, !IO),
 
     list.foldl2(output_comp_gen_c_module(Info), Modules, !DeclSet, !IO),
     list.foldl(output_user_foreign_code(Info), UserForeignCode, !IO),
@@ -448,7 +412,7 @@
 
 :- pred output_c_module_init_list(llds_out_info::in, module_name::in,
     list(comp_gen_c_module)::in, list(rtti_data)::in,
-    list(layout_data)::in, list(layout_data)::in,
+    list(proc_layout_data)::in, list(module_layout_data)::in,
     list(complexity_proc_info)::in, list(string)::in, list(string)::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
@@ -462,15 +426,13 @@
     list.chunk(AlwaysInitModules, 40, AlwaysInitModuleBunches),
     list.chunk(MaybeInitModules, 40, MaybeInitModuleBunches),
 
-    output_init_bunch_defs(AlwaysInitModuleBunches, ModuleName,
-        "always", 0, !IO),
+    output_init_bunch_defs(Info, "always", 0, AlwaysInitModuleBunches, !IO),
 
     (
         MaybeInitModuleBunches = []
     ;
         MaybeInitModuleBunches = [_ | _],
-        output_init_bunch_defs(MaybeInitModuleBunches, ModuleName,
-            "maybe", 0, !IO)
+        output_init_bunch_defs(Info, "maybe", 0,MaybeInitModuleBunches, !IO)
     ),
 
     io.write_string("/* suppress gcc -Wmissing-decls warnings */\n", !IO),
@@ -528,15 +490,13 @@
     io.write_string("\t}\n", !IO),
     io.write_string("\tdone = MR_TRUE;\n", !IO),
 
-    output_init_bunch_calls(AlwaysInitModuleBunches, ModuleName,
-        "always", 0, !IO),
+    output_init_bunch_calls(Info, "always", 0,AlwaysInitModuleBunches, !IO),
 
     (
         MaybeInitModuleBunches = []
     ;
         MaybeInitModuleBunches = [_ | _],
-        output_init_bunch_calls(MaybeInitModuleBunches, ModuleName,
-            "maybe", 0, !IO)
+        output_init_bunch_calls(Info, "maybe", 0, MaybeInitModuleBunches, !IO)
     ),
 
     output_c_data_init_list(RttiDatas, !IO),
@@ -561,8 +521,6 @@
     output_type_tables_init_list(RttiDatas, !IO),
     io.write_string("}\n\n", !IO),
 
-    output_record_debugger_init_list_decls(Info, ModuleLayoutDatas,
-        !DeclSet, !IO),
     io.write_string("\n", !IO),
     io.write_string("void ", !IO),
     output_init_name(ModuleName, !IO),
@@ -577,18 +535,19 @@
     io.write_string("}\n\n", !IO),
 
     io.write_string("#ifdef MR_DEEP_PROFILING\n", !IO),
-    output_write_proc_static_list_decls(ProcLayoutDatas, !DeclSet, !IO),
     io.write_string("\nvoid ", !IO),
     output_init_name(ModuleName, !IO),
     io.write_string(
         "write_out_proc_statics(FILE *deep_fp, FILE *procrep_fp)\n", !IO),
     io.write_string("{\n", !IO),
     ModuleCommonLayoutName = module_common_layout(ModuleName),
-    io.write_string("\tMR_write_out_module_proc_reps_start(procrep_fp, &", !IO),
+    io.write_string("\tMR_write_out_module_proc_reps_start(procrep_fp, &",
+        !IO),
     output_layout_name(ModuleCommonLayoutName, !IO),
     io.write_string(");\n", !IO),
     output_write_proc_static_list(ProcLayoutDatas, !IO),
-    io.write_string("\tMR_write_out_module_proc_reps_end(procrep_fp);\n", !IO),
+    io.write_string("\tMR_write_out_module_proc_reps_end(procrep_fp);\n",
+        !IO),
     io.write_string("}\n", !IO),
     io.write_string("\n#endif\n\n", !IO),
 
@@ -662,49 +621,61 @@
 internal_label_has_layout(InternalLabelToLayoutMap, Label) :-
     map.search(InternalLabelToLayoutMap, Label, _).
 
-:- pred entry_label_has_layout(map(label, data_addr)::in, label::in)
+:- pred entry_label_has_layout(map(label, data_id)::in, label::in)
     is semidet.
 
 entry_label_has_layout(EntryLabelToLayoutMap, Label) :-
     map.search(EntryLabelToLayoutMap, Label, _).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
-:- pred output_init_bunch_defs(list(list(comp_gen_c_module))::in,
-    module_name::in, string::in, int::in, io::di, io::uo) is det.
+:- pred output_init_bunch_defs(llds_out_info::in, string::in, int::in,
+    list(list(comp_gen_c_module))::in, io::di, io::uo) is det.
 
-output_init_bunch_defs([], _, _, _, !IO).
-output_init_bunch_defs([Bunch | Bunches], ModuleName, InitStatus, Seq, !IO) :-
+output_init_bunch_defs(_, _, _, [], !IO).
+output_init_bunch_defs(Info, InitStatus, Seq, [Bunch | Bunches], !IO) :-
     io.write_string("static void ", !IO),
-    output_bunch_name(ModuleName, InitStatus, Seq, !IO),
+    output_bunch_name(Info, InitStatus, Seq, !IO),
     io.write_string("(void)\n", !IO),
     io.write_string("{\n", !IO),
-    output_init_bunch_def(Bunch, ModuleName, !IO),
+    output_init_bunch_def(Bunch, !IO),
     io.write_string("}\n\n", !IO),
     NextSeq = Seq + 1,
-    output_init_bunch_defs(Bunches, ModuleName, InitStatus, NextSeq, !IO).
+    output_init_bunch_defs(Info, InitStatus, NextSeq, Bunches, !IO).
 
-:- pred output_init_bunch_def(list(comp_gen_c_module)::in, module_name::in,
+:- pred output_init_bunch_def(list(comp_gen_c_module)::in,
     io::di, io::uo) is det.
 
-output_init_bunch_def([], _, !IO).
-output_init_bunch_def([Module | Modules], ModuleName, !IO) :-
+output_init_bunch_def([], !IO).
+output_init_bunch_def([Module | Modules], !IO) :-
     Module = comp_gen_c_module(C_ModuleName, _),
     io.write_string("\t", !IO),
     io.write_string(C_ModuleName, !IO),
     io.write_string("();\n", !IO),
-    output_init_bunch_def(Modules, ModuleName, !IO).
+    output_init_bunch_def(Modules, !IO).
 
-:- pred output_init_bunch_calls(list(list(comp_gen_c_module))::in,
-    module_name::in, string::in, int::in, io::di, io::uo) is det.
+:- pred output_init_bunch_calls(llds_out_info::in, string::in, int::in,
+    list(list(comp_gen_c_module))::in, io::di, io::uo) is det.
 
-output_init_bunch_calls([], _, _, _, !IO).
-output_init_bunch_calls([_ | Bunches], ModuleName, InitStatus, Seq, !IO) :-
+output_init_bunch_calls(_, _, _, [], !IO).
+output_init_bunch_calls(Info, InitStatus, Seq, [_ | Bunches], !IO) :-
     io.write_string("\t", !IO),
-    output_bunch_name(ModuleName, InitStatus, Seq, !IO),
+    output_bunch_name(Info, InitStatus, Seq, !IO),
     io.write_string("();\n", !IO),
     NextSeq = Seq + 1,
-    output_init_bunch_calls(Bunches, ModuleName, InitStatus, NextSeq, !IO).
+    output_init_bunch_calls(Info, InitStatus, NextSeq, Bunches, !IO).
+
+:- pred output_bunch_name(llds_out_info::in, string::in, int::in,
+    io::di, io::uo) is det.
+
+output_bunch_name(Info, InitStatus, Number, !IO) :-
+    io.write_string("mercury__", !IO),
+    MangledModuleName = Info ^ lout_mangled_module_name,
+    io.write_string(MangledModuleName, !IO),
+    io.write_string("_", !IO),
+    io.write_string(InitStatus, !IO),
+    io.write_string("_bunch_", !IO),
+    io.write_int(Number, !IO).
 
     % Output MR_INIT_TYPE_CTOR_INFO(TypeCtorInfo, Typector);
     % for each type_ctor_info defined in this module.
@@ -726,28 +697,12 @@
     rtti_out.register_rtti_data_if_nec(Data, !IO),
     output_type_tables_init_list(Datas, !IO).
 
-    % Output declarations for each module layout defined in this module
-    % (there should only be one, of course).
-    %
-:- pred output_record_debugger_init_list_decls(llds_out_info::in,
-    list(layout_data)::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_record_debugger_init_list_decls(_, [], !DeclSet, !IO).
-output_record_debugger_init_list_decls(Info, [Data | Datas], !DeclSet, !IO) :-
-    ( Data = module_layout_data(ModuleName, _, _, _, _, _, _, _) ->
-        DataAddr = layout_addr(module_layout(ModuleName)),
-        output_record_data_addr_decls(Info, DataAddr, !DeclSet, !IO)
-    ;
-        true
-    ),
-    output_record_debugger_init_list_decls(Info, Datas, !DeclSet, !IO).
-
     % Output calls to MR_register_module_layout()
     % for each module layout defined in this module
     % (there should only be one, of course).
     %
-:- pred output_debugger_init_list(list(layout_data)::in, io::di, io::uo)
-    is det.
+:- pred output_debugger_init_list(list(module_layout_data)::in,
+    io::di, io::uo) is det.
 
 output_debugger_init_list([], !IO).
 output_debugger_init_list([Data | Datas], !IO) :-
@@ -762,30 +717,13 @@
     ),
     output_debugger_init_list(Datas, !IO).
 
-:- pred output_write_proc_static_list_decls(list(layout_data)::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_write_proc_static_list_decls([], !DeclSet, !IO).
-output_write_proc_static_list_decls([Data | Datas], !DeclSet, !IO) :-
-    (
-        Data = proc_layout_data(_, _, MaybeRest),
-        MaybeRest = proc_id_and_more(yes(_), _, _, _)
-    ->
-        output_maybe_layout_data_decl(Data, !DeclSet, !IO)
-    ;
-        true
-    ),
-    output_write_proc_static_list_decls(Datas, !DeclSet, !IO).
-
-:- pred output_write_proc_static_list(list(layout_data)::in,
+:- pred output_write_proc_static_list(list(proc_layout_data)::in,
     io::di, io::uo) is det.
 
 output_write_proc_static_list([], !IO).
-output_write_proc_static_list([Data | Datas], !IO) :-
-    (
-        Data = proc_layout_data(RttiProcLabel, _, MaybeRest),
-        MaybeRest = proc_id_and_more(yes(_), _, _, _)
-    ->
+output_write_proc_static_list([ProcLayout | ProcLayouts], !IO) :-
+    ProcLayout = proc_layout_data(RttiProcLabel, _, MaybeMore),
+    ( MaybeMore = proc_id_and_more(yes(_ProcStatic), _, _, _) ->
         ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
         UserOrUCI = proc_label_user_or_uci(ProcLabel),
         Kind = proc_layout_proc_id(UserOrUCI),
@@ -805,7 +743,7 @@
     ;
         true
     ),
-    output_write_proc_static_list(Datas, !IO).
+    output_write_proc_static_list(ProcLayouts, !IO).
 
 :- func complexity_arg_info_array_name(int) = string.
 
@@ -881,7 +819,7 @@
 complexity_arg_is_profiled(complexity_arg_info(_, Kind)) :-
     Kind = complexity_input_variable_size.
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
     % Output a comment to tell mkinit what functions to call from
     % <module>_init.c.
@@ -932,19 +870,7 @@
     io.write_string("\t" ++ Name ++ "();\n", !IO),
     output_required_init_or_final_calls(Names, !IO).
 
-:- pred output_bunch_name(module_name::in, string::in, int::in, io::di, io::uo)
-    is det.
-
-output_bunch_name(ModuleName, InitStatus, Number, !IO) :-
-    io.write_string("mercury__", !IO),
-    MangledModuleName = sym_name_mangle(ModuleName),
-    io.write_string(MangledModuleName, !IO),
-    io.write_string("_", !IO),
-    io.write_string(InitStatus, !IO),
-    io.write_string("_bunch_", !IO),
-    io.write_int(Number, !IO).
-
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_comp_gen_c_module(llds_out_info::in, comp_gen_c_module::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
@@ -964,53 +890,47 @@
     list.foldl(output_c_procedure(Info), Procedures, !IO),
     io.write_string("MR_END_MODULE\n", !IO).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_tabling_info_struct(llds_out_info::in, tabling_info_struct::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_tabling_info_struct(Info, TablingInfoStruct, !DeclSet, !IO) :-
-    TablingInfoStruct = tabling_info_struct(ModuleName, ProcLabel, EvalMethod,
+    TablingInfoStruct = tabling_info_struct(ProcLabel, EvalMethod,
         NumInputs, NumOutputs, InputSteps, MaybeOutputSteps, PTIVectorRval,
         TypeParamsRval, MaybeSizeLimit, Stats),
 
-    InfoDataAddr = data_addr(ModuleName,
-        proc_tabling_ref(ProcLabel, tabling_info)),
-    InputStepsDataAddr = data_addr(ModuleName,
-        proc_tabling_ref(ProcLabel, tabling_steps_desc(call_table))),
-    OutputStepsDataAddr = data_addr(ModuleName,
-        proc_tabling_ref(ProcLabel, tabling_steps_desc(answer_table))),
-    TipsDataAddr = data_addr(ModuleName,
-        proc_tabling_ref(ProcLabel, tabling_tips)),
+    InfoDataId =
+        proc_tabling_data_id(ProcLabel, tabling_info),
+    InputStepsDataId =
+        proc_tabling_data_id(ProcLabel, tabling_steps_desc(call_table)),
+    OutputStepsDataId =
+        proc_tabling_data_id(ProcLabel, tabling_steps_desc(answer_table)),
+    TipsDataId =
+        proc_tabling_data_id(ProcLabel, tabling_tips),
 
-    CallStatsDataName = proc_tabling_ref(ProcLabel,
+    CallStatsDataId =
+        proc_tabling_data_id(ProcLabel,
         tabling_stat_steps(call_table, curr_table)),
-    PrevCallStatsDataName = proc_tabling_ref(ProcLabel,
+    PrevCallStatsDataId =
+        proc_tabling_data_id(ProcLabel,
         tabling_stat_steps(call_table, prev_table)),
-    CallStatsDataAddr = data_addr(ModuleName, CallStatsDataName),
-    PrevCallStatsDataAddr = data_addr(ModuleName, PrevCallStatsDataName),
 
-    AnswerStatsDataName = proc_tabling_ref(ProcLabel,
+    AnswerStatsDataId =
+        proc_tabling_data_id(ProcLabel,
         tabling_stat_steps(answer_table, curr_table)),
-    PrevAnswerStatsDataName = proc_tabling_ref(ProcLabel,
+    PrevAnswerStatsDataId =
+        proc_tabling_data_id(ProcLabel,
         tabling_stat_steps(answer_table, prev_table)),
-    AnswerStatsDataAddr = data_addr(ModuleName, AnswerStatsDataName),
-    PrevAnswerStatsDataAddr = data_addr(ModuleName, PrevAnswerStatsDataName),
 
-    InputStepsDataName =
-        proc_tabling_ref(ProcLabel, tabling_steps_desc(call_table)),
-    output_table_steps_table(ModuleName, InputStepsDataName, InputSteps,
-        !DeclSet, !IO),
+    output_table_steps_table(Info, InputStepsDataId, InputSteps, !IO),
     output_record_rval_decls(Info, PTIVectorRval, !DeclSet, !IO),
 
     (
         MaybeOutputSteps = no
     ;
         MaybeOutputSteps = yes(OutputStepsA),
-        OutputStepsDataName =
-            proc_tabling_ref(ProcLabel, tabling_steps_desc(answer_table)),
-        output_table_steps_table(ModuleName, OutputStepsDataName, OutputStepsA,
-            !DeclSet, !IO),
+        output_table_steps_table(Info, OutputStepsDataId, OutputStepsA, !IO),
         output_record_rval_decls(Info, PTIVectorRval, !DeclSet, !IO)
     ),
 
@@ -1018,30 +938,28 @@
         MaybeSizeLimit = no
     ;
         MaybeSizeLimit = yes(SizeLimit1),
-        output_table_tips(ModuleName, ProcLabel, SizeLimit1, !DeclSet, !IO)
+        output_table_tips(Info, ProcLabel, SizeLimit1, !IO)
     ),
 
     (
         Stats = table_dont_gather_statistics
     ;
         Stats = table_gather_statistics,
-        output_table_step_stats(ModuleName, CallStatsDataName,
-            InputSteps, !DeclSet, !IO),
-        output_table_step_stats(ModuleName, PrevCallStatsDataName,
-            InputSteps, !DeclSet, !IO),
+        output_table_step_stats(Info, CallStatsDataId, InputSteps, !IO),
+        output_table_step_stats(Info, PrevCallStatsDataId, InputSteps, !IO),
         (
             MaybeOutputSteps = no
         ;
             MaybeOutputSteps = yes(OutputStepsB),
-            output_table_step_stats(ModuleName, AnswerStatsDataName,
-                OutputStepsB, !DeclSet, !IO),
-            output_table_step_stats(ModuleName, PrevAnswerStatsDataName,
-                OutputStepsB, !DeclSet, !IO)
+            output_table_step_stats(Info, AnswerStatsDataId, OutputStepsB,
+                !IO),
+            output_table_step_stats(Info, PrevAnswerStatsDataId, OutputStepsB,
+                !IO)
         )
     ),
 
     io.write_string("\nstatic MR_ProcTableInfo ", !IO),
-    output_data_addr(InfoDataAddr, !IO),
+    output_data_id(Info, InfoDataId, !IO),
     io.write_string(" = {\n", !IO),
     io.write_string(eval_method_to_table_type(EvalMethod), !IO),
     io.write_string(",\n", !IO),
@@ -1064,14 +982,14 @@
     io.write_string(",\n", !IO),
     io.write_string("{ 0 },\n", !IO),
     io.write_string("{\n", !IO),
-    output_data_addr(InputStepsDataAddr, !IO),
+    output_data_id_addr(Info, InputStepsDataId, !IO),
     io.write_string(",\n", !IO),
     (
         MaybeOutputSteps = no,
         io.write_string("NULL\n", !IO)
     ;
         MaybeOutputSteps = yes(_),
-        output_data_addr(OutputStepsDataAddr, !IO),
+        output_data_id_addr(Info, OutputStepsDataId, !IO),
         io.write_string("\n", !IO)
     ),
     io.write_string("},\n", !IO),
@@ -1099,12 +1017,12 @@
         io.write_string("{{{\n", !IO),
         io.write_string("0,\n", !IO),
         io.write_string("0,\n", !IO),
-        output_data_addr(CallStatsDataAddr, !IO),
+        output_data_id_addr(Info, CallStatsDataId, !IO),
         io.write_string("\n", !IO),
         io.write_string("},{\n", !IO),
         io.write_string("0,\n", !IO),
         io.write_string("0,\n", !IO),
-        output_data_addr(PrevCallStatsDataAddr, !IO),
+        output_data_id_addr(Info, PrevCallStatsDataId, !IO),
         io.write_string("\n", !IO),
         io.write_string("}},{{\n", !IO),
         (
@@ -1120,12 +1038,12 @@
             MaybeOutputSteps = yes(_),
             io.write_string("0,\n", !IO),
             io.write_string("0,\n", !IO),
-            output_data_addr(AnswerStatsDataAddr, !IO),
+            output_data_id_addr(Info, AnswerStatsDataId, !IO),
             io.write_string("\n", !IO),
             io.write_string("},{\n", !IO),
             io.write_string("0,\n", !IO),
             io.write_string("0,\n", !IO),
-            output_data_addr(PrevAnswerStatsDataAddr, !IO),
+            output_data_id_addr(Info, PrevAnswerStatsDataId, !IO),
             io.write_string("\n", !IO)
         ),
         io.write_string("}}},\n", !IO)
@@ -1140,26 +1058,24 @@
         MaybeSizeLimit = yes(SizeLimit2),
         io.write_int(SizeLimit2, !IO),
         io.write_string(",\n", !IO),
-        output_data_addr(TipsDataAddr, !IO),
+        output_data_id_addr(Info, TipsDataId, !IO),
         io.write_string("0,\n", !IO),
         io.write_string("0\n", !IO)
     ),
     io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(InfoDataAddr), !DeclSet).
+    DeclId = decl_tabling_id(ProcLabel, tabling_info),
+    decl_set_insert(DeclId, !DeclSet).
 
-:- pred output_table_steps_table(module_name::in, data_name::in,
-    list(table_step_desc)::in, decl_set::in, decl_set::out, io::di, io::uo)
-    is det.
+:- pred output_table_steps_table(llds_out_info::in, data_id::in,
+    list(table_step_desc)::in, io::di, io::uo) is det.
 
-output_table_steps_table(ModuleName, DataName, StepDescs, !DeclSet, !IO) :-
-    DataAddr = data_addr(ModuleName, DataName),
+output_table_steps_table(Info, DataId, StepDescs, !IO) :-
     io.write_string("\n", !IO),
     io.write_string("static const MR_TableStepDesc ", !IO),
-    output_data_addr(DataAddr, !IO),
+    output_data_id(Info, DataId, !IO),
     io.write_string("[] = {\n", !IO),
     output_table_steps(StepDescs, !IO),
-    io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(DataAddr), !DeclSet).
+    io.write_string("};\n", !IO).
 
 :- pred output_table_steps(list(table_step_desc)::in, io::di, io::uo) is det.
 
@@ -1182,40 +1098,35 @@
     io.write_string(" },\n", !IO),
     output_table_steps(StepDescs, !IO).
 
-:- pred output_table_tips(module_name::in, proc_label::in, int::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
+:- pred output_table_tips(llds_out_info::in, proc_label::in, int::in,
+    io::di, io::uo) is det.
 
-output_table_tips(ModuleName, ProcLabel, SizeLimit, !DeclSet, !IO) :-
+output_table_tips(Info, ProcLabel, SizeLimit, !IO) :-
     % We don't need to initialize the elements of the array, since the
     % MR_pt_num_call_table_tips field explicitly says that none of the
     % array elements are meaningful.
-    DataAddr = data_addr(ModuleName,
-        proc_tabling_ref(ProcLabel, tabling_tips)),
+    DataId = proc_tabling_data_id(ProcLabel, tabling_tips),
     io.write_string("\n", !IO),
     io.write_string("static MR_TrieNode ", !IO),
-    output_data_addr(DataAddr, !IO),
+    output_data_id(Info, DataId, !IO),
     io.write_string("[", !IO),
     io.write_int(SizeLimit, !IO),
-    io.write_string("];\n", !IO),
-    decl_set_insert(decl_data_addr(DataAddr), !DeclSet).
+    io.write_string("];\n", !IO).
 
-:- pred output_table_step_stats(module_name::in, data_name::in,
-    list(table_step_desc)::in, decl_set::in, decl_set::out, io::di, io::uo)
-    is det.
+:- pred output_table_step_stats(llds_out_info::in,
+    data_id::in, list(table_step_desc)::in, io::di, io::uo) is det.
 
-output_table_step_stats(ModuleName, DataName, Steps, !DeclSet, !IO) :-
+output_table_step_stats(Info, DataId, Steps, !IO) :-
     % We don't need to initialize the elements of the array, because
     % we want to initialize all members of the array to structures
     % that contain all zeros, and C does that for us.
-    DataAddr = data_addr(ModuleName, DataName),
     io.write_string("\n", !IO),
     io.write_string("static MR_TableStepStats ", !IO),
-    output_data_addr(DataAddr, !IO),
+    output_data_id(Info, DataId, !IO),
     io.write_string("[] = \n", !IO),
     io.write_string("{\n", !IO),
     output_table_step_stats_2(Steps, !IO),
-    io.write_string("};\n", !IO),
-    decl_set_insert(decl_data_addr(DataAddr), !DeclSet).
+    io.write_string("};\n", !IO).
 
 :- pred output_table_step_stats_2(list(table_step_desc)::in, io::di, io::uo)
     is det.
@@ -1237,7 +1148,7 @@
     io.write_string("0, 0 },\n", !IO),
     output_table_step_stats_2(StepDescs, !IO).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_static_linkage_define(io::di, io::uo) is det.
 
@@ -1279,54 +1190,44 @@
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_scalar_common_data_decl(ScalarCommonDataArray, !DeclSet, !IO) :-
-    ScalarCommonDataArray = scalar_common_data_array(_ModuleName, CellType,
-        TypeNum, _Values),
+    ScalarCommonDataArray = scalar_common_data_array(CellType, TypeNum,
+        _Values),
     io.write_string("\n", !IO),
     output_common_type_defn(TypeNum, CellType, !DeclSet, !IO),
-    VarDeclId = decl_scalar_common_array(TypeNum),
     io.write_string("MR_STATIC_LINKAGE const struct ", !IO),
     output_common_cell_type_name(TypeNum, !IO),
     io.write_string(" ", !IO),
     output_common_scalar_cell_array_name(TypeNum, !IO),
-    io.write_string("[];\n", !IO),
-    decl_set_insert(VarDeclId, !DeclSet).
+    io.write_string("[];\n", !IO).
 
 :- pred output_vector_common_data_decl(vector_common_data_array::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_vector_common_data_decl(VectorCommonDataArray, !DeclSet, !IO) :-
-    VectorCommonDataArray = vector_common_data_array(ModuleName, CellType,
+    VectorCommonDataArray = vector_common_data_array(CellType,
         TypeNum, CellNum, _Values),
     io.write_string("\n", !IO),
     output_common_type_defn(TypeNum, CellType, !DeclSet, !IO),
-    VarDeclId = decl_data_addr(data_addr(ModuleName,
-        vector_common_ref(TypeNum, CellNum))),
     io.write_string("MR_STATIC_LINKAGE const struct ", !IO),
     output_common_cell_type_name(TypeNum, !IO),
     io.write_string(" ", !IO),
     output_common_vector_cell_array_name(TypeNum, CellNum, !IO),
-    io.write_string("[];\n", !IO),
-    decl_set_insert(VarDeclId, !DeclSet).
+    io.write_string("[];\n", !IO).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_scalar_common_data_defn(llds_out_info::in,
     scalar_common_data_array::in, decl_set::in, decl_set::out,
     io::di, io::uo) is det.
 
 output_scalar_common_data_defn(Info, ScalarCommonDataArray, !DeclSet, !IO) :-
-    ScalarCommonDataArray = scalar_common_data_array(_ModuleName, _CellType,
-        TypeNum, Values),
+    ScalarCommonDataArray = scalar_common_data_array(_CellType, TypeNum,
+        Values),
     io.write_string("\n", !IO),
     ArgLists = list.map(common_cell_get_rvals, Values),
     list.condense(ArgLists, Args),
     output_record_rvals_decls(Info, Args, !DeclSet, !IO),
 
-    % Although the array should have ben declared by now, it is OK if it
-    % hasn't.
-    VarDeclId = decl_scalar_common_array(TypeNum),
-    decl_set_insert(VarDeclId, !DeclSet),
-
     io.write_string("static const struct ", !IO),
     output_common_cell_type_name(TypeNum, !IO),
     io.write_string(" ", !IO),
@@ -1342,19 +1243,13 @@
     io::di, io::uo) is det.
 
 output_vector_common_data_defn(Info, VectorCommonDataArray, !DeclSet, !IO) :-
-    VectorCommonDataArray = vector_common_data_array(ModuleName, _CellType,
-        TypeNum, CellNum, Values),
+    VectorCommonDataArray = vector_common_data_array(_CellType, TypeNum,
+        CellNum, Values),
     io.write_string("\n", !IO),
     ArgLists = list.map(common_cell_get_rvals, Values),
     list.condense(ArgLists, Args),
     output_record_rvals_decls(Info, Args, !DeclSet, !IO),
 
-    % Although the array should have ben declared by now, it is OK if it
-    % hasn't.
-    VarDeclId = decl_data_addr(data_addr(ModuleName,
-        vector_common_ref(TypeNum, CellNum))),
-    decl_set_insert(VarDeclId, !DeclSet),
-
     io.write_string("static const struct ", !IO),
     output_common_cell_type_name(TypeNum, !IO),
     io.write_string(" ", !IO),
@@ -1382,7 +1277,7 @@
 common_group_get_rvals(common_cell_grouped_args(_, _, Rvals)) = Rvals.
 common_group_get_rvals(common_cell_ungrouped_arg(_, Rval)) = [Rval].
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_user_foreign_code(llds_out_info::in, user_foreign_code::in,
     io::di, io::uo) is det.
@@ -1509,7 +1404,8 @@
 :- pred output_record_internal_label_decl_group(proc_label::in, list(int)::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_record_internal_label_decl_group(ProcLabel, LabelNums, !DeclSet, !IO) :-
+output_record_internal_label_decl_group(ProcLabel, LabelNums,
+        !DeclSet, !IO) :-
     io.write_string("MR_decl_label", !IO),
     io.write_int(list.length(LabelNums), !IO),
     io.write_string("(", !IO),
@@ -1542,7 +1438,8 @@
         DeclMacro = "MR_decl_local"
     ;
         Label = internal_label(_, _),
-        unexpected(this_file, "output_record_entry_label_decl: internal label")
+        unexpected(this_file,
+            "output_record_entry_label_decl: internal label")
     ),
     io.write_string(DeclMacro, !IO),
     io.write_string("(", !IO),
@@ -1550,17 +1447,16 @@
     io.write_string(")\n", !IO),
     decl_set_insert(decl_code_addr(code_label(Label)), !DeclSet).
 
-:- pred output_record_stack_layout_decl(llds_out_info::in, data_addr::in,
+:- pred output_record_stack_layout_decl(llds_out_info::in, data_id::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_record_stack_layout_decl(Info, DataAddr, !DeclSet, !IO) :-
-    output_record_data_addr_decls(Info, DataAddr, !DeclSet, !IO).
+output_record_stack_layout_decl(Info, DataId, !DeclSet, !IO) :-
+    output_record_data_id_decls(Info, DataId, !DeclSet, !IO).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_c_label_inits(llds_out_info::in,
-    list(label)::in, list(label)::in,
-    io::di, io::uo) is det.
+    list(label)::in, list(label)::in, io::di, io::uo) is det.
 
 output_c_label_inits(Info, EntryLabels, InternalLabels, !IO) :-
     EntryLabelToLayoutMap = Info ^ lout_entry_label_to_layout,
@@ -1571,7 +1467,8 @@
     group_init_c_labels(InternalLabelToLayoutMap, InternalLabels,
         multi_map.init, NoLayoutInternalMap,
         multi_map.init, NoVarLayoutInternalMap,
-        multi_map.init, VarLayoutInternalMap),
+        multi_map.init, SVarLayoutInternalMap,
+        multi_map.init, LVarLayoutInternalMap),
 
     multi_map.to_assoc_list(NoLayoutInternalMap, NoLayoutInternalList),
     list.foldl(output_c_internal_label_no_layout_init_group,
@@ -1581,21 +1478,27 @@
     list.foldl(output_c_internal_label_layout_init_group(Info, "_nvi"),
         NoVarLayoutInternalList, !IO),
 
-    multi_map.to_assoc_list(VarLayoutInternalMap, VarLayoutInternalList),
-    list.foldl(output_c_internal_label_layout_init_group(Info, "_vi"),
-        VarLayoutInternalList, !IO).
+    multi_map.to_assoc_list(SVarLayoutInternalMap, SVarLayoutInternalList),
+    list.foldl(output_c_internal_label_layout_init_group(Info, "_svi"),
+        SVarLayoutInternalList, !IO),
+
+    multi_map.to_assoc_list(LVarLayoutInternalMap, LVarLayoutInternalList),
+    list.foldl(output_c_internal_label_layout_init_group(Info, "_lvi"),
+        LVarLayoutInternalList, !IO).
 
 :- pred group_init_c_labels(map(label, layout_slot_name)::in, list(label)::in,
     multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
     multi_map(proc_label, {int, int})::in,
     multi_map(proc_label, {int, int})::out,
     multi_map(proc_label, {int, int})::in,
+    multi_map(proc_label, {int, int})::out,
+    multi_map(proc_label, {int, int})::in,
     multi_map(proc_label, {int, int})::out) is det.
 
 group_init_c_labels(_InternalLabelToLayoutMap, [],
-        !NoLayoutMap, !NoVarLayoutMap, !VarLayoutMap).
+        !NoLayoutMap, !NoVarLayoutMap, !SVarLayoutMap, !LVarLayoutMap).
 group_init_c_labels(InternalLabelToLayoutMap, [Label | Labels],
-        !NoLayoutMap, !NoVarLayoutMap, !VarLayoutMap) :-
+        !NoLayoutMap, !NoVarLayoutMap, !SVarLayoutMap, !LVarLayoutMap) :-
     (
         Label = internal_label(LabelNum, ProcLabel),
         ( map.search(InternalLabelToLayoutMap, Label, Slot) ->
@@ -1603,11 +1506,14 @@
             ( ArrayName = label_layout_array(Vars) ->
                 Pair = {LabelNum, SlotNum},
                 (
-                    Vars = label_has_var_info,
-                    svmulti_map.set(ProcLabel, Pair, !VarLayoutMap)
-                ;
                     Vars = label_has_no_var_info,
                     svmulti_map.set(ProcLabel, Pair, !NoVarLayoutMap)
+                ;
+                    Vars = label_has_short_var_info,
+                    svmulti_map.set(ProcLabel, Pair, !SVarLayoutMap)
+                ;
+                    Vars = label_has_long_var_info,
+                    svmulti_map.set(ProcLabel, Pair, !LVarLayoutMap)
                 )
             ;
                 unexpected(this_file, "group_init_c_labels: bad slot type")
@@ -1620,7 +1526,7 @@
         unexpected(this_file, "group_init_c_labels: entry label")
     ),
     group_init_c_labels(InternalLabelToLayoutMap, Labels,
-        !NoLayoutMap, !NoVarLayoutMap, !VarLayoutMap).
+        !NoLayoutMap, !NoVarLayoutMap, !SVarLayoutMap, !LVarLayoutMap).
 
 :- pred output_c_internal_label_no_layout_init_group(
     pair(proc_label, list(int))::in, io::di, io::uo) is det.
@@ -1685,11 +1591,11 @@
     io.write_string(",", !IO),
     io.write_int(SlotNum, !IO).
 
-:- pred output_c_entry_label_init(map(label, data_addr)::in, label::in,
+:- pred output_c_entry_label_init(map(label, data_id)::in, label::in,
     io::di, io::uo) is det.
 
 output_c_entry_label_init(EntryLabelToLayoutMap, Label, !IO) :-
-    ( map.search(EntryLabelToLayoutMap, Label, _DataAddr) ->
+    ( map.search(EntryLabelToLayoutMap, Label, _LayoutId) ->
         SuffixOpen = "_sl("
     ;
         SuffixOpen = "("
@@ -1718,7 +1624,7 @@
     output_label(Label, !IO),
     io.write_string(");\n", !IO).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_record_c_procedure_decls(llds_out_info::in, c_procedure::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
@@ -1789,7 +1695,7 @@
         LocalThreadEngineBase = no
     ),
     output_instruction_list(Info, Instrs, CallerLabel - ContLabelSet,
-        WhileSet, !IO),
+        WhileSet, not_after_layout_label, !IO),
     (
         LocalThreadEngineBase = yes,
         io.write_string("#ifdef MR_maybe_local_thread_engine_base\n", !IO),
@@ -1932,7 +1838,7 @@
         count_while_label_in_block(Label, Instrs0, !Count)
     ).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_record_instruction_decls(llds_out_info::in, instruction::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
@@ -2109,33 +2015,63 @@
         )
     ).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
+
+:- type after_layout_label
+    --->    not_after_layout_label
+    ;       after_layout_label.
 
 :- pred output_instruction_list(llds_out_info::in, list(instruction)::in,
     pair(label, set_tree234(label))::in, set_tree234(label)::in,
-    io::di, io::uo) is det.
+    after_layout_label::in, io::di, io::uo) is det.
 
-output_instruction_list(_, [], _, _, !IO).
-output_instruction_list(Info, [Instr | Instrs], ProfInfo, WhileSet, !IO) :-
+output_instruction_list(_, [], _, _, _, !IO).
+output_instruction_list(Info, [Instr | Instrs], ProfInfo, WhileSet,
+        AfterLayoutLabel0, !IO) :-
     Instr = llds_instr(Uinstr, Comment),
-    output_instruction_and_comment(Info, Uinstr, Comment, ProfInfo, !IO),
+    ( Uinstr = label(Label) ->
+        InternalLabelToLayoutMap = Info ^ lout_internal_label_to_layout,
+        ( map.search(InternalLabelToLayoutMap, Label, _) ->
+            AfterLayoutLabel = after_layout_label
+        ;
+            AfterLayoutLabel = not_after_layout_label
+        ),
     (
-        Uinstr = label(Label),
-        set_tree234.contains(WhileSet, Label)
+            AfterLayoutLabel0 = after_layout_label,
+            AfterLayoutLabel = after_layout_label
     ->
+            % Make sure that the addresses of the two labels are distinct.
+            io.write_string("\tMR_dummy_function_call();\n", !IO)
+        ;
+            true
+        ),
+        output_instruction_and_comment(Info, Uinstr, Comment, ProfInfo, !IO),
+        ( set_tree234.contains(WhileSet, Label) ->
         io.write_string("\twhile (1) {\n", !IO),
-        output_instruction_list_while(Info, Instrs, Label, ProfInfo, WhileSet,
-            !IO)
+            output_instruction_list_while(Info, Instrs, Label, ProfInfo,
+                WhileSet, !IO)
         % The matching close brace is printed in output_instruction_list
         % when before the next label, before a goto that closes the loop,
         % or when we get to the end of Instrs.
     ;
-        output_instruction_list(Info, Instrs, ProfInfo, WhileSet, !IO)
+            output_instruction_list(Info, Instrs, ProfInfo, WhileSet,
+                AfterLayoutLabel, !IO)
+        )
+    ;
+        output_instruction_and_comment(Info, Uinstr, Comment,
+            ProfInfo, !IO),
+        ( Uinstr = comment(_) ->
+            AfterLayoutLabel = AfterLayoutLabel0
+        ;
+            AfterLayoutLabel = not_after_layout_label
+        ),
+        output_instruction_list(Info, Instrs, ProfInfo, WhileSet,
+            AfterLayoutLabel, !IO)
     ).
 
-:- pred output_instruction_list_while(llds_out_info::in, list(instruction)::in,
-    label::in, pair(label, set_tree234(label))::in, set_tree234(label)::in,
-    io::di, io::uo) is det.
+:- pred output_instruction_list_while(llds_out_info::in,
+    list(instruction)::in, label::in, pair(label,
+    set_tree234(label))::in, set_tree234(label)::in, io::di, io::uo) is det.
 
 output_instruction_list_while(_, [], _, _, _, !IO) :-
     io.write_string("\tbreak; } /* end while */\n", !IO).
@@ -2145,10 +2081,11 @@
     ( Uinstr = label(_) ->
         io.write_string("\tbreak; } /* end while */\n", !IO),
         output_instruction_list(Info, [Instr | Instrs],
-            ProfInfo, WhileSet, !IO)
+            ProfInfo, WhileSet, not_after_layout_label, !IO)
     ; Uinstr = goto(code_label(Label)) ->
         io.write_string("\t/* continue */ } /* end while */\n", !IO),
-        output_instruction_list(Info, Instrs, ProfInfo, WhileSet, !IO)
+        output_instruction_list(Info, Instrs, ProfInfo, WhileSet,
+            not_after_layout_label, !IO)
     ; Uinstr = if_val(Rval, code_label(Label)) ->
         io.write_string("\tif (", !IO),
         output_test_rval(Info, Rval, !IO),
@@ -2164,19 +2101,19 @@
         ;
             true
         ),
-        output_instruction_list_while(Info, Instrs, Label, ProfInfo, WhileSet,
-            !IO)
+        output_instruction_list_while(Info, Instrs, Label, ProfInfo,
+            WhileSet, !IO)
     ; Uinstr = block(TempR, TempF, BlockInstrs) ->
         output_block_start(TempR, TempF, !IO),
-        output_instruction_list_while_block(Info, BlockInstrs, Label, ProfInfo,
-            !IO),
+        output_instruction_list_while_block(Info, BlockInstrs, Label,
+            ProfInfo, !IO),
         output_block_end(!IO),
-        output_instruction_list_while(Info, Instrs, Label, ProfInfo, WhileSet,
-            !IO)
+        output_instruction_list_while(Info, Instrs, Label, ProfInfo,
+            WhileSet, !IO)
     ;
         output_instruction_and_comment(Info, Uinstr, Comment, ProfInfo, !IO),
-        output_instruction_list_while(Info, Instrs, Label, ProfInfo, WhileSet,
-            !IO)
+        output_instruction_list_while(Info, Instrs, Label, ProfInfo,
+            WhileSet, !IO)
     ).
 
 :- pred output_instruction_list_while_block(llds_out_info::in,
@@ -2208,12 +2145,14 @@
         ;
             true
         ),
-        output_instruction_list_while_block(Info, Instrs, Label, ProfInfo, !IO)
+        output_instruction_list_while_block(Info, Instrs, Label,
+            ProfInfo, !IO)
     ; Uinstr = block(_, _, _) ->
         unexpected(this_file, "block in block")
     ;
         output_instruction_and_comment(Info, Uinstr, Comment, ProfInfo, !IO),
-        output_instruction_list_while_block(Info, Instrs, Label, ProfInfo, !IO)
+        output_instruction_list_while_block(Info, Instrs, Label,
+            ProfInfo, !IO)
     ).
 
 :- pred output_instruction_and_comment(llds_out_info::in, instr::in,
@@ -2337,7 +2276,8 @@
     ;
         Instr = block(TempR, TempF, Instrs),
         output_block_start(TempR, TempF, !IO),
-        output_instruction_list(Info, Instrs, ProfInfo, set_tree234.init, !IO),
+        output_instruction_list(Info, Instrs, ProfInfo, set_tree234.init,
+            not_after_layout_label, !IO),
         output_block_end(!IO)
     ;
         Instr = assign(Lval, Rval),
@@ -2561,7 +2501,8 @@
 
         % The comment is to make the code easier to debug;
         % we can stop printing it out once that has been done.
-        EmbeddedFrame = embedded_stack_frame_id(_StackId, FirstSlot, LastSlot),
+        EmbeddedFrame = embedded_stack_frame_id(_StackId,
+            FirstSlot, LastSlot),
         Comment = " /* " ++ int_to_string(FirstSlot) ++ ".." ++
             int_to_string(LastSlot) ++ " */",
         io.write_string(Comment, !IO),
@@ -2731,7 +2672,7 @@
             map.lookup(InternalLabelToLayoutMap, DefLabel, DefLabelLayout),
             io.write_string("#define MR_HASH_DEF_LABEL_LAYOUT ", !IO),
             MangledModuleName = Info ^ lout_mangled_module_name,
-            output_layout_slot_name(use_layout_macro, MangledModuleName,
+            output_layout_slot_addr(use_layout_macro, MangledModuleName,
                 DefLabelLayout, !IO),
             io.nl(!IO),
             list.foldl(output_foreign_proc_component(Info), Components, !IO),
@@ -2910,7 +2851,8 @@
     embedded_stack_frame_id::in, io::di, io::uo) is det.
 
 output_embedded_frame_addr(Info, EmbeddedFrame, !IO) :-
-    EmbeddedFrame = embedded_stack_frame_id(MainStackId, _FirstSlot, LastSlot),
+    EmbeddedFrame = embedded_stack_frame_id(MainStackId,
+        _FirstSlot, LastSlot),
     FrameStartRval = stack_slot_num_to_lval_ref(MainStackId, LastSlot),
     output_rval_as_type(Info, FrameStartRval, lt_data_ptr, !IO).
 
@@ -3035,7 +2977,8 @@
     ),
     output_foreign_proc_inputs(Info, Inputs, !IO).
 
-    % Output an input variable assignment at the top of the foreign code for C.
+    % Output an input variable assignment at the top of the foreign code
+    % for C.
     %
 :- pred output_foreign_proc_input(llds_out_info::in, foreign_proc_input::in,
     io::di, io::uo) is det.
@@ -3107,11 +3050,12 @@
 output_record_foreign_proc_output_lval_decls(_, [], !DeclSet, !IO).
 output_record_foreign_proc_output_lval_decls(Info, [Output | Outputs],
         !DeclSet, !IO) :-
-    Output = foreign_proc_output(Lval, _VarType, _IsDummy, _OrigType, _VarName,
-        _, _),
+    Output = foreign_proc_output(Lval, _VarType, _IsDummy, _OrigType,
+        _VarName, _, _),
     output_record_lval_decls_format(Info, Lval, "\t", "\t",
         0, _N, !DeclSet, !IO),
-    output_record_foreign_proc_output_lval_decls(Info, Outputs, !DeclSet, !IO).
+    output_record_foreign_proc_output_lval_decls(Info, Outputs,
+        !DeclSet, !IO).
 
     % Output the output variable assignments at the bottom of the foreign code
     % for C.
@@ -3121,8 +3065,8 @@
 
 output_foreign_proc_outputs(_, [], !IO).
 output_foreign_proc_outputs(Info, [Output | Outputs], !IO) :-
-    Output = foreign_proc_output(_Lval, _VarType, IsDummy, _OrigType, _VarName,
-        _MaybeForeignType, _BoxPolicy),
+    Output = foreign_proc_output(_Lval, _VarType, IsDummy, _OrigType,
+        _VarName, _MaybeForeignType, _BoxPolicy),
     (
         IsDummy = is_dummy_type
     ;
@@ -3151,7 +3095,9 @@
         (
             MaybeForeignType = yes(ForeignTypeInfo),
             ForeignTypeInfo = foreign_proc_type(ForeignType, Assertions),
-            ( list.member(foreign_type_can_pass_as_mercury_type, Assertions) ->
+            (
+                list.member(foreign_type_can_pass_as_mercury_type, Assertions)
+            ->
                 output_lval_as_word(Info, Lval, !IO),
                 io.write_string(" = ", !IO),
                 output_llds_type_cast(lt_word, !IO),
@@ -3395,8 +3341,8 @@
         ( Const = llconst_code_addr(CodeAddress) ->
             output_record_code_addr_decls_format(Info, CodeAddress,
                 FirstIndent, LaterIndent, !N, !DeclSet, !IO)
-        ; Const = llconst_data_addr(DataAddr, _) ->
-            output_record_data_addr_decls_format(Info, DataAddr,
+        ; Const = llconst_data_addr(DataId, _) ->
+            output_record_data_id_decls_format(Info, DataId,
                 FirstIndent, LaterIndent, !N, !DeclSet, !IO)
         ; Const = llconst_float(FloatVal) ->
             % If floats are boxed, but are allocated statically, then for each
@@ -3466,8 +3412,8 @@
                     io.write_string(FloatName, !IO),
                     io.write_string(" = ", !IO),
                     % Note that we just output the expression here, and
-                    % let the C compiler evaluate it, rather than evaluating it
-                    % ourselves. This avoids having to deal with some nasty
+                    % let the C compiler evaluate it, rather than evaluating
+                    % it ourselves. This avoids having to deal with some nasty
                     % issues regarding floating point accuracy when doing
                     % cross-compilation.
                     output_rval_as_type(Info, SubRvalA, lt_float, !IO),
@@ -3493,7 +3439,8 @@
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_record_rvals_decls(Info, Rvals, !DeclSet, !IO) :-
-    output_record_rvals_decls_format(Info, Rvals, "", "", 0, _, !DeclSet, !IO).
+    output_record_rvals_decls_format(Info, Rvals, "", "", 0, _,
+        !DeclSet, !IO).
 
 :- pred output_record_rvals_decls_format(llds_out_info::in, list(rval)::in,
     string::in, string::in, int::in, int::out, decl_set::in,
@@ -3527,7 +3474,7 @@
             FirstIndent, LaterIndent, !N, !DeclSet, !IO)
     ).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 %
 % The following predicates are used to compute the names used for
 % floating point static constants.
@@ -3588,7 +3535,7 @@
 float_op_name(float_times, "times").
 float_op_name(float_divide, "divide").
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
     % Return true if a data structure of the given type will eventually
     % have code addresses filled in inside it. Note that we can't just
@@ -3597,44 +3544,25 @@
     % addresses with dummy values that will have to be overridden with
     % the real code address at initialization time.
     %
-:- func data_addr_may_include_non_static_code_address(data_addr) = bool.
+:- func data_id_may_include_non_static_code_address(data_id) = bool.
 
-data_addr_may_include_non_static_code_address(data_addr(_, DataName)) =
-    data_name_may_include_non_static_code_address(DataName).
-data_addr_may_include_non_static_code_address(rtti_addr(RttiId)) =
-    rtti_id_would_include_code_addr(RttiId).
-data_addr_may_include_non_static_code_address(layout_addr(LayoutName)) =
-    layout_name_would_include_code_addr(LayoutName).
-
-:- func data_name_may_include_non_static_code_address(data_name) = bool.
-
-% Common structures can include code addresses, but only in grades with
-% static code addresses.
-data_name_may_include_non_static_code_address(scalar_common_ref(_, _)) = no.
-data_name_may_include_non_static_code_address(vector_common_ref(_, _)) = no.
-data_name_may_include_non_static_code_address(proc_tabling_ref(_, _)) = no.
-
-:- pred output_decl_id(decl_id::in, io::di, io::uo) is det.
-
-output_decl_id(decl_common_type(TypeNum), !IO) :-
-    output_common_cell_type_name(TypeNum, !IO).
-output_decl_id(decl_scalar_common_array(TypeNum), !IO) :-
-    output_common_scalar_cell_array_name(TypeNum, !IO).
-output_decl_id(decl_data_addr(DataAddr), !IO) :-
-    output_data_addr(DataAddr, !IO).
-output_decl_id(decl_code_addr(_CodeAddress), !IO) :-
-    unexpected(this_file, "output_decl_id: code_addr unexpected").
-output_decl_id(decl_float_label(_Label), !IO) :-
-    unexpected(this_file, "output_decl_id: float_label unexpected").
-output_decl_id(decl_foreign_proc_struct(_Name), !IO) :-
-    unexpected(this_file, "output_decl_id: foreign_proc_struct unexpected").
-output_decl_id(decl_c_global_var(_), !IO) :-
-    unexpected(this_file, "output_decl_id: c_global_var unexpected").
-output_decl_id(decl_type_info_like_struct(_Name), !IO) :-
-    unexpected(this_file, "output_decl_id: type_info_like_struct unexpected").
-output_decl_id(decl_typeclass_constraint_struct(_Name), !IO) :-
-    unexpected(this_file,
-        "output_decl_id: class_constraint_struct unexpected").
+data_id_may_include_non_static_code_address(DataId) = MayContain :-
+    (
+        DataId = rtti_data_id(RttiId),
+        MayContain = rtti_id_would_include_code_addr(RttiId)
+    ;
+        % Common structures can include code addresses, but only in grades
+        % with static code addresses.
+        ( DataId = proc_tabling_data_id(_, _)
+        ; DataId = scalar_common_data_id(_, _)
+        ; DataId = vector_common_data_id(_, _)
+        ; DataId = layout_slot_id(table_io_decl_id, _)
+        ),
+        MayContain = no
+    ;
+        DataId = layout_id(LayoutName),
+        MayContain = layout_name_would_include_code_addr(LayoutName)
+    ).
 
 :- pred output_cons_arg_types(list(llds_type)::in, string::in, int::in,
     io::di, io::uo) is det.
@@ -3895,7 +3823,7 @@
 ok_int_const(_, lt_code_ptr) :-
     unexpected(this_file, "ok_int_const: not integer constant").
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
     % output_lval_decls(Lval, ...) outputs the declarations of any
     % static constants, etc. that need to be declared before
@@ -4072,7 +4000,8 @@
             !IO)
     ;
         CodeAddr = do_trace_redo_fail_deep,
-        io.write_string("MR_declare_entry(MR_do_trace_redo_fail_deep);\n", !IO)
+        io.write_string("MR_declare_entry(MR_do_trace_redo_fail_deep);\n",
+            !IO)
     ;
         CodeAddr = do_call_closure(Variant),
         io.write_string("MR_declare_entry(mercury__do_call_closure_", !IO),
@@ -4080,7 +4009,8 @@
         io.write_string(");\n", !IO)
     ;
         CodeAddr = do_call_class_method(Variant),
-        io.write_string("MR_declare_entry(mercury__do_call_class_method_", !IO),
+        io.write_string("MR_declare_entry(mercury__do_call_class_method_",
+            !IO),
         io.write_string(ho_call_variant_to_string(Variant), !IO),
         io.write_string(");\n", !IO)
     ;
@@ -4104,65 +4034,54 @@
         Label = internal_label(_, _)
     ).
 
-output_record_data_addr_decls(Info, DataAddr, !DeclSet, !IO) :-
-    output_record_data_addr_decls_format(Info, DataAddr, "", "",
+output_record_data_id_decls(Info, DataId, !DeclSet, !IO) :-
+    output_record_data_id_decls_format(Info, DataId, "", "",
         0, _, !DeclSet, !IO).
 
-output_record_data_addr_decls_format(Info, DataAddr,
-        FirstIndent, LaterIndent, !N, !DeclSet, !IO) :-
-    ( DataAddr = data_addr(_, scalar_common_ref(TypeNum, _CellNum)) ->
-        DeclId = decl_scalar_common_array(TypeNum),
+output_record_data_id_decls_format(Info, DataId, FirstIndent, LaterIndent,
+        !N, !DeclSet, !IO) :-
+    (
+        ( DataId = scalar_common_data_id(_, _)
+        ; DataId = vector_common_data_id(_, _)
+        ; DataId = layout_slot_id(_, _)
+        )
+        % These are always declared at the top of the generated C source file.
+    ;
+        DataId = proc_tabling_data_id(_, _)
+        % These are always defined (and therefore declared) before being used.
+    ;
+        DataId = rtti_data_id(RttiId),
+        DeclId = decl_rtti_id(RttiId),
         ( decl_set_is_member(DeclId, !.DeclSet) ->
             true
         ;
             decl_set_insert(DeclId, !DeclSet),
             output_indent(FirstIndent, LaterIndent, !.N, !IO),
             !:N = !.N + 1,
-            io.write_string("static ", !IO),
-            output_common_cell_type_name(TypeNum, !IO),
-            io.write_string(" ", !IO),
-            output_common_scalar_cell_array_name(TypeNum, !IO),
-            io.write_string("[];\n", !IO)
+            output_rtti_id_storage_type_name_no_decl(Info, RttiId, no, !IO),
+            io.write_string(";\n", !IO)
         )
     ;
-        DeclId = decl_data_addr(DataAddr),
+        DataId = layout_id(LayoutName),
+        DeclId = decl_layout_id(LayoutName),
         ( decl_set_is_member(DeclId, !.DeclSet) ->
             true
         ;
             decl_set_insert(DeclId, !DeclSet),
-            output_data_addr_decls_2(Info, DataAddr,
-                FirstIndent, LaterIndent, !N, !IO)
-        )
-    ).
-
-:- pred output_data_addr_decls_2(llds_out_info::in, data_addr::in,
-    string::in, string::in, int::in, int::out, io::di, io::uo) is det.
-
-output_data_addr_decls_2(Info, DataAddr, FirstIndent, LaterIndent, !N, !IO) :-
     output_indent(FirstIndent, LaterIndent, !.N, !IO),
     !:N = !.N + 1,
-    (
-        DataAddr = data_addr(ModuleName, DataVarName),
-        output_data_addr_storage_type_name(Info, ModuleName, DataVarName, no,
-            LaterIndent, !IO),
-        io.write_string(";\n", !IO)
-    ;
-        DataAddr = rtti_addr(RttiId),
-        output_rtti_id_storage_type_name_no_decl(Info, RttiId, no, !IO),
-        io.write_string(";\n", !IO)
-    ;
-        DataAddr = layout_addr(LayoutName),
         output_layout_name_storage_type_name(LayoutName,
             not_being_defined, !IO),
         io.write_string(";\n", !IO)
+        )
     ).
 
-output_record_data_addrs_decls(_, [], _, _, !N, !DeclSet, !IO).
-output_record_data_addrs_decls(Info, [DataAddr | DataAddrs],
+output_record_data_ids_decls(_, [], _, _, !N, !DeclSet, !IO).
+output_record_data_ids_decls(Info, [DataId | DataIds],
         FirstIndent, LaterIndent, !N, !DeclSet, !IO) :-
-    output_record_data_addr_decls_format(Info, DataAddr,
+    output_record_data_id_decls_format(Info, DataId,
         FirstIndent, LaterIndent, !N, !DeclSet, !IO),
-    output_record_data_addrs_decls(Info, DataAddrs,
+    output_record_data_ids_decls(Info, DataIds,
         FirstIndent, LaterIndent, !N, !DeclSet, !IO).
 
 c_data_linkage_string(DefaultLinkage, BeingDefined) = LinkageStr :-
@@ -4195,38 +4114,7 @@
         "const "
     ).
 
-    % This predicate outputs the storage class, type and name of the variable
-    % specified by the first two arguments. The third argument should be true
-    % if the variable is being defined, and false if it is only being declared
-    % (since the storage class "extern" is needed only on declarations).
-    %
-:- pred output_data_addr_storage_type_name(llds_out_info::in, module_name::in,
-    data_name::in, bool::in, string::in, io::di, io::uo) is det.
-
-output_data_addr_storage_type_name(Info, ModuleName, DataVarName, BeingDefined,
-        LaterIndent, !IO) :-
-    data_name_linkage(DataVarName, Linkage),
-    LinkageStr = c_data_linkage_string(Linkage, BeingDefined),
-    io.write_string(LinkageStr, !IO),
-
-    InclCodeAddr = data_name_may_include_non_static_code_address(DataVarName),
-    Globals = Info ^ lout_globals,
-    io.write_string(c_data_const_string(Globals, InclCodeAddr), !IO),
-
-    io.write_string("struct ", !IO),
-    output_data_addr_2(ModuleName, DataVarName, !IO),
-    io.write_string("_struct\n", !IO),
-    io.write_string(LaterIndent, !IO),
-    io.write_string("\t", !IO),
-    output_data_addr_2(ModuleName, DataVarName, !IO).
-
-:- pred data_name_linkage(data_name::in, linkage::out) is det.
-
-data_name_linkage(scalar_common_ref(_, _), static).
-data_name_linkage(vector_common_ref(_, _), static).
-data_name_linkage(proc_tabling_ref(_, _), static).
-
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_indent(string::in, string::in, int::in, io::di, io::uo) is det.
 
@@ -4237,7 +4125,7 @@
         io.write_string(FirstIndent, !IO)
     ).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred maybe_output_update_prof_counter(llds_out_info::in, label::in,
     pair(label, set_tree234(label))::in, io::di, io::uo) is det.
@@ -4258,7 +4146,7 @@
         true
     ).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_goto(llds_out_info::in, code_addr::in, label::in,
     io::di, io::uo) is det.
@@ -4397,7 +4285,8 @@
         io.write_string(");\n", !IO)
     ;
         Target = do_not_reached,
-        io.write_string("MR_tailcall(MR_ENTRY(MR_do_not_reached),\n\t\t", !IO),
+        io.write_string("MR_tailcall(MR_ENTRY(MR_do_not_reached),\n\t\t",
+            !IO),
         output_label_as_code_addr(CallerLabel, !IO),
         io.write_string(");\n", !IO)
     ).
@@ -4602,8 +4491,11 @@
 :- pred code_addr_to_string_base(code_addr::in, string::out,
     bool::out, wrapper::out) is det.
 
-code_addr_to_string_base(code_label(Label), BaseStr, yes, Wrapper) :-
+code_addr_to_string_base(CodeAddr, BaseStr, NeedsPrefix, Wrapper) :-
+    (
+        CodeAddr = code_label(Label),
     BaseStr = label_to_c_string(Label, no),
+        NeedsPrefix = yes,
     IsExternal = label_is_external_to_c_module(Label),
     (
         IsExternal = yes,
@@ -4611,36 +4503,60 @@
     ;
         IsExternal = no,
         Wrapper = wrapper_label
-    ).
-code_addr_to_string_base(code_imported_proc(ProcLabel), BaseStr, yes,
-        wrapper_entry) :-
-    BaseStr = proc_label_to_c_string(ProcLabel, no).
-code_addr_to_string_base(code_succip, "MR_succip", no, wrapper_none).
-code_addr_to_string_base(do_succeed(Last), BaseStr, no, wrapper_entry) :-
+        )
+    ;
+        CodeAddr = code_imported_proc(ProcLabel),
+        BaseStr = proc_label_to_c_string(ProcLabel, no),
+        NeedsPrefix = yes,
+        Wrapper = wrapper_entry
+    ;
+        CodeAddr = code_succip,
+        BaseStr = "MR_succip",
+        NeedsPrefix = no,
+        Wrapper = wrapper_none
+    ;
+        CodeAddr = do_succeed(Last),
     (
         Last = no,
         BaseStr = "MR_do_succeed"
     ;
         Last = yes,
         BaseStr = "MR_do_last_succeed"
+        ),
+        NeedsPrefix = no,
+        Wrapper = wrapper_entry
+    ;
+        (
+            CodeAddr = do_redo,
+            BaseStr = "MR_do_redo"
+        ;
+            CodeAddr = do_fail,
+            BaseStr = "MR_do_fail"
+        ;
+            CodeAddr = do_trace_redo_fail_shallow,
+            BaseStr = "MR_do_trace_redo_fail_shallow"
+        ;
+            CodeAddr = do_trace_redo_fail_deep,
+            BaseStr = "MR_do_trace_redo_fail_deep"
+        ;
+            CodeAddr = do_not_reached,
+            BaseStr = "MR_do_not_reached"
+        ),
+        NeedsPrefix = no,
+        Wrapper = wrapper_entry
+    ;
+        CodeAddr = do_call_closure(Variant),
+        BaseStr = "mercury__do_call_closure_" ++
+            ho_call_variant_to_string(Variant),
+        NeedsPrefix = no,
+        Wrapper = wrapper_entry
+    ;
+        CodeAddr = do_call_class_method(Variant),
+        BaseStr = "mercury__do_call_class_method_" ++
+            ho_call_variant_to_string(Variant),
+        NeedsPrefix = no,
+        Wrapper = wrapper_entry
     ).
-code_addr_to_string_base(do_redo, "MR_do_redo", no, wrapper_entry).
-code_addr_to_string_base(do_fail, "MR_do_fail", no, wrapper_entry).
-code_addr_to_string_base(do_trace_redo_fail_shallow, BaseStr, no,
-        wrapper_entry) :-
-    BaseStr = "MR_do_trace_redo_fail_shallow".
-code_addr_to_string_base(do_trace_redo_fail_deep, BaseStr, no, wrapper_entry) :-
-    BaseStr = "MR_do_trace_redo_fail_deep".
-code_addr_to_string_base(do_call_closure(Variant), BaseStr, no,
-        wrapper_entry) :-
-    BaseStr = "mercury__do_call_closure_"
-        ++ ho_call_variant_to_string(Variant).
-code_addr_to_string_base(do_call_class_method(Variant), BaseStr, no,
-        wrapper_entry) :-
-    BaseStr = "mercury__do_call_class_method_"
-        ++ ho_call_variant_to_string(Variant).
-code_addr_to_string_base(do_not_reached, BaseStr, no, wrapper_entry) :-
-    BaseStr = "MR_do_not_reached".
 
 ho_call_variant_to_string(Variant) = Str :-
     (
@@ -4651,68 +4567,51 @@
         Str = int_to_string(Num)
     ).
 
-    % Output a maybe data address, with a `no' meaning NULL.
-    %
-:- pred output_maybe_data_addr(maybe(data_addr)::in, io::di, io::uo) is det.
-
-output_maybe_data_addr(MaybeDataAddr, !IO) :-
-    (
-        MaybeDataAddr = yes(DataAddr),
-        output_data_addr(DataAddr, !IO)
-    ;
-        MaybeDataAddr = no,
-        io.write_string("NULL", !IO)
-    ).
-
-    % Output a list of maybe data addresses, with a `no' meaning NULL.
+    % Output a list of data ids.
     %
-:- pred output_maybe_data_addrs(list(maybe(data_addr))::in, io::di, io::uo)
-    is det.
+:- pred output_data_ids(llds_out_info::in, list(data_id)::in,
+    io::di, io::uo) is det.
 
-output_maybe_data_addrs([], !IO).
-output_maybe_data_addrs([MaybeDataAddr | MaybeDataAddrs], !IO) :-
+output_data_ids(_, [], !IO).
+output_data_ids(Info, [DataId | DataIds], !IO) :-
     io.write_string("\t", !IO),
-    io.write_list([MaybeDataAddr | MaybeDataAddrs], ",\n\t",
-        output_maybe_data_addr, !IO),
+    io.write_list([DataId | DataIds], ",\n\t", output_data_id(Info), !IO),
     io.write_string("\n", !IO).
 
-    % Output a list of data addresses.
-    %
-:- pred output_data_addrs(list(data_addr)::in, io::di, io::uo) is det.
-
-output_data_addrs([], !IO).
-output_data_addrs([DataAddr | DataAddrs], !IO) :-
-    io.write_string("\t", !IO),
-    io.write_list([DataAddr | DataAddrs], ",\n\t", output_data_addr, !IO),
-    io.write_string("\n", !IO).
+output_data_id_addr(Info, DataId, !IO) :-
+    io.write_string("&", !IO),
+    output_data_id(Info, DataId, !IO).
 
-    % Output a data address.
+    % Output a data id.
     %
-output_data_addr(data_addr(ModuleName, DataName), !IO) :-
-    output_data_addr_2(ModuleName, DataName, !IO).
-output_data_addr(rtti_addr(RttiId), !IO) :-
-    output_rtti_id(RttiId, !IO).
-output_data_addr(layout_addr(LayoutName), !IO) :-
-    output_layout_name(LayoutName, !IO).
-
-:- pred output_data_addr_2(module_name::in, data_name::in, io::di, io::uo)
-    is det.
-
-output_data_addr_2(_ModuleName, VarName, !IO) :-
+output_data_id(Info, DataId, !IO) :-
     (
-        VarName = scalar_common_ref(TypeNum, CellNum),
-        io.write_string("&", !IO),
+        DataId = rtti_data_id(RttiId),
+        output_rtti_id(RttiId, !IO)
+    ;
+        DataId = proc_tabling_data_id(ProcLabel, TablingId),
+        io.write_string(tabling_struct_data_addr_string(ProcLabel, TablingId),
+            !IO)
+    ;
+        DataId = scalar_common_data_id(TypeNum, CellNum),
         output_common_scalar_cell_array_name(TypeNum, !IO),
         io.write_string("[", !IO),
         io.write_int(CellNum, !IO),
         io.write_string("]", !IO)
     ;
-        VarName = vector_common_ref(TypeNum, CellNum),
+        DataId = vector_common_data_id(TypeNum, CellNum),
         output_common_vector_cell_array_name(TypeNum, CellNum, !IO)
     ;
-        VarName = proc_tabling_ref(ProcLabel, TablingId),
-        io.write_string(tabling_struct_data_addr_string(ProcLabel, TablingId),
-            !IO)
+        DataId = layout_id(LayoutName),
+        output_layout_name(LayoutName, !IO)
+    ;
+        DataId = layout_slot_id(Kind, PredProcId),
+        Kind = table_io_decl_id,
+        TableIoDeclMap = Info ^ lout_table_io_decl_map,
+        map.lookup(TableIoDeclMap, PredProcId, LayoutSlotName),
+        MangledModuleName = Info ^ lout_mangled_module_name,
+        output_layout_slot_id(use_layout_macro, MangledModuleName,
+            LayoutSlotName, !IO)
     ).
 
 proc_tabling_info_var_name(ProcLabel) =
@@ -5187,7 +5086,7 @@
 output_rval(Info, Rval, !IO) :-
     (
         Rval = const(Const),
-        output_rval_const(Const, !IO)
+        output_rval_const(Info, Const, !IO)
     ;
         Rval = unop(UnaryOp, SubRvalA),
         c_util.unary_prefix_op(UnaryOp, OpString),
@@ -5215,14 +5114,14 @@
             Category = string_compare_binop,
             io.write_string("(strcmp(", !IO),
             ( SubRvalA = const(llconst_string(SubRvalAConst)) ->
-                output_rval_const(llconst_string(SubRvalAConst), !IO)
+                output_rval_const(Info, llconst_string(SubRvalAConst), !IO)
             ;
                 io.write_string("(char *) ", !IO),
                 output_rval_as_type(Info, SubRvalA, lt_data_ptr, !IO)
             ),
             io.write_string(", ", !IO),
             ( SubRvalB = const(llconst_string(SubRvalBConst)) ->
-                output_rval_const(llconst_string(SubRvalBConst), !IO)
+                output_rval_const(Info, llconst_string(SubRvalBConst), !IO)
             ;
                 io.write_string("(char *) ", !IO),
                 output_rval_as_type(Info, SubRvalB, lt_data_ptr, !IO)
@@ -5310,9 +5209,8 @@
     ;
         Rval = mkword(Tag, SubRval),
         (
-            SubRval = const(llconst_data_addr(DataAddr, no)),
-            DataAddr = data_addr(_, DataName),
-            DataName = scalar_common_ref(type_num(TypeNum), CellNum)
+            SubRval = const(llconst_data_addr(DataId, no)),
+            DataId = scalar_common_data_id(type_num(TypeNum), CellNum)
         ->
             io.write_string("MR_TAG_COMMON(", !IO),
             io.write_int(Tag, !IO),
@@ -5405,9 +5303,10 @@
         )
     ).
 
-:- pred output_rval_const(rval_const::in, io::di, io::uo) is det.
+:- pred output_rval_const(llds_out_info::in, rval_const::in,
+    io::di, io::uo) is det.
 
-output_rval_const(Const, !IO) :-
+output_rval_const(Info, Const, !IO) :-
     (
         Const = llconst_true,
         io.write_string("MR_TRUE", !IO)
@@ -5454,19 +5353,18 @@
         Const = llconst_code_addr(CodeAddress),
         output_code_addr(CodeAddress, !IO)
     ;
-        Const = llconst_data_addr(DataAddr, MaybeOffset),
+        Const = llconst_data_addr(DataId, MaybeOffset),
         % Data addresses are all assumed to be of type `MR_Word *'; we need to
         % cast them here to avoid type errors. The offset is also in MR_Words.
         (
             MaybeOffset = no,
             % The tests for special cases below increase the runtime of the
             % compiler very slightly, but the use of shorter names reduces
-            % the size of the generated C source file, which has a considerably
-            % longer lifetime. In debugging grades, the file size difference
-            % can be very substantial.
+            % the size of the generated C source file, which has a
+            % considerably longer lifetime. In debugging grades, the
+            % file size difference can be very substantial.
             (
-                DataAddr = data_addr(_, DataName),
-                DataName = scalar_common_ref(type_num(TypeNum), CellNum)
+                DataId = scalar_common_data_id(type_num(TypeNum), CellNum)
             ->
                 io.write_string("MR_COMMON(", !IO),
                 io.write_int(TypeNum, !IO),
@@ -5474,7 +5372,7 @@
                 io.write_int(CellNum, !IO),
                 io.write_string(")", !IO)
             ;
-                DataAddr = rtti_addr(RttiId),
+                DataId = rtti_data_id(RttiId),
                 rtti_id_emits_type_ctor_info(RttiId, Ctor),
                 Ctor = rtti_type_ctor(Module, Name, Arity),
                 sym_name_doesnt_need_mangling(Module),
@@ -5483,14 +5381,13 @@
                 output_type_ctor_addr(Module, Name, Arity, !IO)
             ;
                 output_llds_type_cast(lt_data_ptr, !IO),
-                io.write_string("&", !IO),
-                output_data_addr(DataAddr, !IO)
+                output_data_id_addr(Info, DataId, !IO)
             )
         ;
             MaybeOffset = yes(Offset),
             io.write_string("((", !IO),
             output_llds_type_cast(lt_data_ptr, !IO),
-            output_data_addr(DataAddr, !IO),
+            output_data_id_addr(Info, DataId, !IO),
             io.write_string(") + ", !IO),
             io.write_int(Offset, !IO),
             io.write_string(")", !IO)
@@ -5536,8 +5433,7 @@
         ->
             io.write_string("MR_BOOL_CTOR_ADDR", !IO)
         ;
-            io.write_strings(["MR_CTOR0_ADDR(", ModuleStr, ", ", Name, ")"],
-                !IO)
+            io.format("MR_CTOR0_ADDR(%s, %s)", [s(ModuleStr), s(Name)], !IO)
         )
     ; Arity = 1 ->
         (
@@ -5551,12 +5447,11 @@
         ->
             io.write_string("MR_TYPE_INFO_CTOR_ADDR", !IO)
         ;
-            io.write_strings(["MR_CTOR1_ADDR(", ModuleStr, ", ", Name, ")"],
-                !IO)
+            io.format("MR_CTOR1_ADDR(%s, %s)", [s(ModuleStr), s(Name)], !IO)
         )
     ;
-        io.write_strings(["MR_CTOR_ADDR(", ModuleStr, ", ", Name,
-            ", ", int_to_string(Arity), ")"], !IO)
+        io.format("MR_CTOR_ADDR(%s, %s, %d)",
+            [s(ModuleStr), s(Name), i(Arity)], !IO)
     ).
 
 :- pred output_lval_as_word(llds_out_info::in, lval::in,
@@ -5850,7 +5745,7 @@
 % global_var_name in mlds_to_c.m.
 c_global_var_name(env_var_ref(EnvVarName)) = "mercury_envvar_" ++ EnvVarName.
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred output_set_line_num(llds_out_info::in, prog_context::in,
     io::di, io::uo) is det.
@@ -5877,7 +5772,7 @@
         LineNumbers= no
     ).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 lval_to_string(framevar(N)) =
     "MR_fv(" ++ int_to_string(N) ++ ")".
@@ -5905,7 +5800,7 @@
 max_real_r_reg = 32.
 max_virtual_r_reg = 1024.
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred gather_c_file_labels(list(comp_gen_c_module)::in,
     list(label)::out, list(label)::out) is det.
@@ -5925,7 +5820,7 @@
     list.reverse(RevEntryLabels, EntryLabels),
     list.reverse(RevInternalLabels, InternalLabels).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- pred gather_labels_from_c_modules_acc(list(comp_gen_c_module)::in,
     list(label)::in, list(label)::out,
@@ -5945,7 +5840,8 @@
 
 gather_labels_from_c_module_acc(comp_gen_c_module(_, Procs),
         !RevEntryLabels, !RevInternalLabels) :-
-    gather_labels_from_c_procs_acc(Procs, !RevEntryLabels, !RevInternalLabels).
+    gather_labels_from_c_procs_acc(Procs,
+        !RevEntryLabels, !RevInternalLabels).
 
 :- pred gather_labels_from_c_procs_acc(list(c_procedure)::in,
     list(label)::in, list(label)::out,
@@ -5955,8 +5851,10 @@
 gather_labels_from_c_procs_acc([Proc | Procs],
         !RevEntryLabels, !RevInternalLabels) :-
     Instrs = Proc ^ cproc_code,
-    gather_labels_from_instrs_acc(Instrs, !RevEntryLabels, !RevInternalLabels),
-    gather_labels_from_c_procs_acc(Procs, !RevEntryLabels, !RevInternalLabels).
+    gather_labels_from_instrs_acc(Instrs,
+        !RevEntryLabels, !RevInternalLabels),
+    gather_labels_from_c_procs_acc(Procs,
+        !RevEntryLabels, !RevInternalLabels).
 
 :- pred gather_labels_from_instrs_acc(list(instruction)::in,
     list(label)::in, list(label)::out,
@@ -5976,9 +5874,10 @@
     ;
         true
     ),
-    gather_labels_from_instrs_acc(Instrs, !RevEntryLabels, !RevInternalLabels).
+    gather_labels_from_instrs_acc(Instrs,
+        !RevEntryLabels, !RevInternalLabels).
 
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 explain_stack_slots(StackSlots, VarSet) = Explanation :-
     map.to_assoc_list(StackSlots, StackSlotsList),
@@ -6009,10 +5908,12 @@
 %---------------------------------------------------------------------------%
 
 :- func init_llds_out_info(module_name, globals,
-    map(label, layout_slot_name), map(label, data_addr)) = llds_out_info.
+    map(label, layout_slot_name), map(label, data_id),
+    map(pred_proc_id, layout_slot_name)) = llds_out_info.
 
 init_llds_out_info(ModuleName, Globals,
-        InternalLabelToLayoutMap, EntryLabelToLayoutMap) = Info :-
+        InternalLabelToLayoutMap, EntryLabelToLayoutMap, TableIoDeclMap)
+        = Info :-
     MangledModuleName = sym_name_mangle(ModuleName),
     globals.lookup_bool_option(Globals, auto_comments, AutoComments),
     globals.lookup_bool_option(Globals, line_numbers, LineNumbers),
@@ -6030,8 +5931,8 @@
     globals.lookup_bool_option(Globals, use_macro_for_redo_fail,
         UseMacroForRedoFail),
     globals.get_trace_level(Globals, TraceLevel),
-    Info = llds_out_info(MangledModuleName,
-        InternalLabelToLayoutMap, EntryLabelToLayoutMap,
+    Info = llds_out_info(ModuleName, MangledModuleName,
+        InternalLabelToLayoutMap, EntryLabelToLayoutMap, TableIoDeclMap,
         AutoComments, LineNumbers,
         EmitCLoops, GenerateBytecode, LocalThreadEngineBase,
         ProfileCalls, ProfileTime, ProfileMemory, ProfileDeep,
Index: compiler/mercury_compile_llds_back_end.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile_llds_back_end.m,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_compile_llds_back_end.m
--- compiler/mercury_compile_llds_back_end.m	21 Oct 2009 06:36:20 -0000	1.2
+++ compiler/mercury_compile_llds_back_end.m	26 Oct 2009 15:34:08 -0000
@@ -607,9 +607,14 @@
     TypeClassInfoRttiData =
         OldTypeClassInfoRttiData ++ NewTypeClassInfoRttiData,
     stack_layout.generate_llds_layout_data(HLDS, GlobalData0, GlobalData,
-        UserEventVarNums, UserEvents, VarLabelLayouts, NoVarLabelLayouts,
+        PseudoTypeInfos, HLDSVarNums, ShortLocns, LongLocns, 
+        UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
         InternalLabelToLayoutMap, ProcLabelToLayoutMap,
-        ProcLayoutDatas, ModuleLayoutDatas, OtherLayoutDatas),
+        CallSites, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes,
+        TableIoDecls, TableIoDeclMap, ProcEventLayouts,
+        ExecTraces, ProcLayoutDatas, ModuleLayoutDatas),
 
     % Here we perform some optimizations on the LLDS data.
     % XXX This should perhaps be part of backend_pass rather than output_pass.
@@ -624,14 +629,54 @@
     % Next we put it all together and output it to one or more C files.
     RttiDatas = TypeCtorRttiData ++ TypeClassInfoRttiData,
     module_info_get_complexity_proc_infos(HLDS, ComplexityProcs),
-    construct_c_file(HLDS, C_InterfaceInfo, Procs, TablingInfoStructs,
-        ScalarCommonCellDatas, VectorCommonCellDatas, RttiDatas,
-        UserEventVarNums, UserEvents, VarLabelLayouts, NoVarLabelLayouts,
+
+    C_InterfaceInfo = foreign_interface_info(ModuleSymName, C_HeaderCode0,
+        C_Includes, C_BodyCode0, _C_ExportDecls, C_ExportDefns),
+    MangledModuleName = sym_name_mangle(ModuleSymName),
+    CModuleName = MangledModuleName ++ "_module",
+    get_c_body_code(C_BodyCode0, C_BodyCode),
+
+    % Split the code up into bite-size chunks for the C compiler.
+    %
+    globals.lookup_int_option(Globals, procs_per_c_function, ProcsPerFunc),
+    ( ProcsPerFunc = 0 ->
+        % ProcsPerFunc = 0 really means infinity -
+        % we store all the procs in a single function.
+        ChunkedModules = [comp_gen_c_module(CModuleName, Procs)]
+    ;
+        list.chunk(Procs, ProcsPerFunc, ChunkedProcs),
+        combine_chunks(ChunkedProcs, CModuleName, ChunkedModules)
+    ),
+    list.map_foldl(make_foreign_import_header_code(Globals), C_Includes,
+        C_IncludeHeaderCode, !IO),
+
+    % The lists are reversed because insertions into them are at the front.
+    % We don't want to put C_LocalHeaderCode between Start and End, because
+    % C_IncludeHeaderCode may include our own header file, which defines
+    % the module's guard macro, which in turn #ifdefs out the stuff between
+    % Start and End.
+    list.filter(foreign_decl_code_is_local, list.reverse(C_HeaderCode0),
+        C_LocalHeaderCode, C_ExportedHeaderCode),
+    make_decl_guards(ModuleSymName, Start, End),
+    C_HeaderCode = list.reverse(C_IncludeHeaderCode) ++
+        C_LocalHeaderCode ++ [Start | C_ExportedHeaderCode] ++ [End],
+
+    module_info_user_init_pred_c_names(HLDS, UserInitPredCNames),
+    module_info_user_final_pred_c_names(HLDS, UserFinalPredCNames),
+
+    CFile = c_file(ModuleSymName, C_HeaderCode, C_BodyCode, C_ExportDefns,
+        TablingInfoStructs, ScalarCommonCellDatas, VectorCommonCellDatas,
+        RttiDatas, PseudoTypeInfos, HLDSVarNums, ShortLocns, LongLocns, 
+        UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
         InternalLabelToLayoutMap, ProcLabelToLayoutMap,
-        ProcLayoutDatas, ModuleLayoutDatas, ClosureLayoutDatas,
-        OtherLayoutDatas, ComplexityProcs, CFile, !IO),
-    output_llds_file(Globals, ModuleName, CFile,
-        Verbose, Stats, !IO),
+        CallSites, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes,
+        TableIoDecls, TableIoDeclMap, ProcEventLayouts, ExecTraces,
+        ProcLayoutDatas, ModuleLayoutDatas, ClosureLayoutDatas, ChunkedModules,
+        UserInitPredCNames, UserFinalPredCNames, ComplexityProcs),
+
+    output_llds_file(Globals, ModuleName, CFile, Verbose, Stats, !IO),
 
     C_InterfaceInfo = foreign_interface_info(_, _, _, _, C_ExportDecls, _),
     export.produce_header_file(HLDS, C_ExportDecls, ModuleName, !IO),
@@ -696,65 +741,6 @@
         WantedForeignDecls, WantedForeignImports,
         WantedForeignBodys, Foreign_ExportDecls, Foreign_ExportDefns).
 
-    % Split the code up into bite-size chunks for the C compiler.
-    %
-:- pred construct_c_file(module_info::in, foreign_interface_info::in,
-    list(c_procedure)::in, list(tabling_info_struct)::in,
-    list(scalar_common_data_array)::in, list(vector_common_data_array)::in,
-    list(rtti_data)::in, list(maybe(int))::in, list(user_event_data)::in,
-    list(label_layout_vars)::in, list(label_layout_no_vars)::in,
-    map(label, layout_slot_name)::in, map(label, data_addr)::in,
-    list(layout_data)::in, list(layout_data)::in,
-    list(layout_data)::in, list(layout_data)::in,
-    list(complexity_proc_info)::in, c_file::out, io::di, io::uo) is det.
-
-construct_c_file(ModuleInfo, C_InterfaceInfo, Procedures, TablingInfoStructs,
-        ScalarCommonCellDatas, VectorCommonCellDatas, RttiDatas,
-        UserEventVarNums, UserEvents, VarLabelLayouts, NoVarLabelLayouts,
-        InternalLabelToLayoutMap, ProcLabelToLayoutMap,
-        ProcLayoutDatas, ModuleLayoutDatas, ClosureLayoutDatas,
-        OtherLayoutDatas, ComplexityProcs, CFile, !IO) :-
-    C_InterfaceInfo = foreign_interface_info(ModuleSymName, C_HeaderCode0,
-        C_Includes, C_BodyCode0, _C_ExportDecls, C_ExportDefns),
-    MangledModuleName = sym_name_mangle(ModuleSymName),
-    ModuleName = MangledModuleName ++ "_module",
-    module_info_get_globals(ModuleInfo, Globals),
-    globals.lookup_int_option(Globals, procs_per_c_function, ProcsPerFunc),
-    get_c_body_code(C_BodyCode0, C_BodyCode),
-    ( ProcsPerFunc = 0 ->
-        % ProcsPerFunc = 0 really means infinity -
-        % we store all the procs in a single function.
-        ChunkedModules = [comp_gen_c_module(ModuleName, Procedures)]
-    ;
-        list.chunk(Procedures, ProcsPerFunc, ChunkedProcs),
-        combine_chunks(ChunkedProcs, ModuleName, ChunkedModules)
-    ),
-    list.map_foldl(make_foreign_import_header_code(Globals), C_Includes,
-        C_IncludeHeaderCode, !IO),
-
-    % The lists are reversed because insertions into them are at the front.
-    % We don't want to put C_LocalHeaderCode between Start and End, because
-    % C_IncludeHeaderCode may include our own header file, which defines
-    % the module's guard macro, which in turn #ifdefs out the stuff between
-    % Start and End.
-    list.filter(foreign_decl_code_is_local, list.reverse(C_HeaderCode0),
-        C_LocalHeaderCode, C_ExportedHeaderCode),
-    make_decl_guards(ModuleSymName, Start, End),
-    C_HeaderCode = list.reverse(C_IncludeHeaderCode) ++
-        C_LocalHeaderCode ++ [Start | C_ExportedHeaderCode] ++ [End],
-
-    module_info_user_init_pred_c_names(ModuleInfo, UserInitPredCNames),
-    module_info_user_final_pred_c_names(ModuleInfo, UserFinalPredCNames),
-
-    CFile = c_file(ModuleSymName, C_HeaderCode, C_BodyCode, C_ExportDefns,
-        TablingInfoStructs, ScalarCommonCellDatas, VectorCommonCellDatas,
-        RttiDatas, UserEventVarNums, UserEvents,
-        VarLabelLayouts, NoVarLabelLayouts,
-        InternalLabelToLayoutMap, ProcLabelToLayoutMap,
-        ProcLayoutDatas, ModuleLayoutDatas, ClosureLayoutDatas,
-        OtherLayoutDatas, ChunkedModules,
-        UserInitPredCNames, UserFinalPredCNames, ComplexityProcs).
-
 :- pred foreign_decl_code_is_local(foreign_decl_code::in) is semidet.
 
 foreign_decl_code_is_local(Decl) :-
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.149
diff -u -b -r1.149 ml_code_util.m
--- compiler/ml_code_util.m	12 Oct 2009 01:34:13 -0000	1.149
+++ compiler/ml_code_util.m	25 Oct 2009 10:02:56 -0000
@@ -855,11 +855,11 @@
     ).
 
 ml_gen_proc_params_from_rtti(ModuleInfo, RttiProcId) = FuncParams :-
-    HeadVars = RttiProcId ^ proc_headvars,
-    ArgTypes = RttiProcId ^ proc_arg_types,
-    ArgModes = RttiProcId ^ proc_arg_modes,
-    PredOrFunc = RttiProcId ^ pred_or_func,
-    Detism = RttiProcId ^ proc_interface_detism,
+    HeadVars = RttiProcId ^ rpl_proc_headvars,
+    ArgTypes = RttiProcId ^ rpl_proc_arg_types,
+    ArgModes = RttiProcId ^ rpl_proc_arg_modes,
+    PredOrFunc = RttiProcId ^ rpl_pred_or_func,
+    Detism = RttiProcId ^ rpl_proc_interface_detism,
     determinism_to_code_model(Detism, CodeModel),
     HeadVarNames = list.map(
         (func(Var - Name) = Result :-
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.212
diff -u -b -r1.212 opt_debug.m
--- compiler/opt_debug.m	21 Oct 2009 06:36:21 -0000	1.212
+++ compiler/opt_debug.m	27 Oct 2009 06:22:44 -0000
@@ -83,9 +83,7 @@
 
 :- func dump_const(maybe(proc_label), rval_const) = string.
 
-:- func dump_data_addr(data_addr) = string.
-
-:- func dump_data_name(data_name) = string.
+:- func dump_data_id(data_id) = string.
 
 :- func dump_rtti_type_ctor(rtti_type_ctor) = string.
 
@@ -145,6 +143,7 @@
 :- import_module backend_libs.proc_label.
 :- import_module check_hlds.type_util.
 :- import_module hlds.hlds_data.
+:- import_module hlds.hlds_pred.
 :- import_module hlds.hlds_rtti.
 :- import_module hlds.special_pred.
 :- import_module libs.globals.
@@ -373,37 +372,41 @@
     "multi_string(...)".
 dump_const(MaybeProcLabel, llconst_code_addr(CodeAddr)) =
     "code_addr_const(" ++ dump_code_addr(MaybeProcLabel, CodeAddr) ++ ")".
-dump_const(_, llconst_data_addr(DataAddr, MaybeOffset)) = Str :-
-    DataAddrStr = dump_data_addr(DataAddr),
+dump_const(_, llconst_data_addr(DataId, MaybeOffset)) = Str :-
+    DataIdStr = dump_data_id(DataId),
     (
         MaybeOffset = no,
-        Str = "data_addr_const(" ++ DataAddrStr ++ ")"
+        Str = "data_addr_const(" ++ DataIdStr ++ ")"
     ;
         MaybeOffset = yes(Offset),
-        Str = "data_addr_const(" ++ DataAddrStr ++ ", "
+        Str = "data_addr_const(" ++ DataIdStr ++ ", "
             ++ int_to_string(Offset) ++ ")"
     ).
 
-dump_data_addr(data_addr(ModuleName, DataName)) =
-    "data_addr(" ++ sym_name_to_string(ModuleName) ++ ", "
-        ++ dump_data_name(DataName) ++ ")".
-dump_data_addr(rtti_addr(ctor_rtti_id(RttiTypeCtor, DataName))) =
-    "rtti_addr(" ++ dump_rtti_type_ctor(RttiTypeCtor) ++ ", "
+dump_data_id(rtti_data_id(ctor_rtti_id(RttiTypeCtor, DataName))) =
+    "rtti_id(" ++ dump_rtti_type_ctor(RttiTypeCtor) ++ ", "
         ++ dump_rtti_name(DataName) ++ ")".
-dump_data_addr(rtti_addr(tc_rtti_id(TCName, TCDataName))) =
-    "tc_rtti_addr(" ++ dump_rtti_type_class_name(TCName) ++ ", "
+dump_data_id(rtti_data_id(tc_rtti_id(TCName, TCDataName))) =
+    "tc_rtti_id(" ++ dump_rtti_type_class_name(TCName) ++ ", "
         ++ dump_tc_rtti_name(TCDataName) ++ ")".
-dump_data_addr(layout_addr(LayoutName)) =
-    "layout_addr(" ++ dump_layout_name(LayoutName) ++ ")".
-
-dump_data_name(scalar_common_ref(type_num(TypeNum), Offset)) =
-    "scalar_common_ref(" ++ int_to_string(TypeNum) ++ ", "
+dump_data_id(proc_tabling_data_id(ProcLabel, Id)) =
+    tabling_info_id_str(Id) ++ "(" ++ dump_proclabel(ProcLabel) ++ ")".
+dump_data_id(scalar_common_data_id(type_num(TypeNum), Offset)) =
+    "scalar_common_data_id(" ++ int_to_string(TypeNum) ++ ", "
         ++ int_to_string(Offset) ++ ")".
-dump_data_name(vector_common_ref(type_num(TypeNum), Offset)) =
-    "vector_common_ref(" ++ int_to_string(TypeNum) ++ ", "
+dump_data_id(vector_common_data_id(type_num(TypeNum), Offset)) =
+    "vector_common_data_id(" ++ int_to_string(TypeNum) ++ ", "
         ++ int_to_string(Offset) ++ ")".
-dump_data_name(proc_tabling_ref(ProcLabel, Id)) =
-    tabling_info_id_str(Id) ++ "(" ++ dump_proclabel(ProcLabel) ++ ")".
+dump_data_id(layout_id(LayoutName)) =
+    "layout_id(" ++ dump_layout_name(LayoutName) ++ ")".
+dump_data_id(layout_slot_id(table_io_decl_id, PredProcId)) =
+    "table_io_decl_id(" ++ dump_pred_proc_id(PredProcId) ++ ")".
+
+:- func dump_pred_proc_id(pred_proc_id) = string.
+
+dump_pred_proc_id(proc(PredId, ProcId)) =
+    "proc(" ++ string.int_to_string(pred_id_to_int(PredId)) ++ ", " ++
+        string.int_to_string(proc_id_to_int(ProcId)) ++ ")".
 
 dump_rtti_type_ctor(rtti_type_ctor(ModuleName, TypeName, Arity)) =
     "rtti_type_ctor(" ++ sym_name_mangle(ModuleName) ++ ", "
@@ -506,32 +509,67 @@
     (
         ArrayName = label_layout_array(LabelVars),
         (
-            LabelVars = label_has_var_info,
-            Str = "vars_label_layout_array"
-        ;
             LabelVars = label_has_no_var_info,
             Str = "no_vars_label_layout_array"
+        ;
+            LabelVars = label_has_short_var_info,
+            Str = "short_vars_label_layout_array"
+        ;
+            LabelVars = label_has_long_var_info,
+            Str = "long_vars_label_layout_array"
         )
     ;
+        ArrayName = pseudo_type_info_array,
+        Str = "pseudo_type_info_array"
+    ;
+        ArrayName = long_locns_array,
+        Str = "long_locns_array"
+    ;
+        ArrayName = short_locns_array,
+        Str = "short_locns_array"
+    ;
+        ArrayName = hlds_var_nums_array,
+        Str = "hlds_var_nums_array"
+    ;
         ArrayName = user_event_layout_array,
         Str = "user_event_layout_array"
     ;
         ArrayName = user_event_var_nums_array,
         Str = "user_event_var_nums_array"
+    ;
+        ArrayName = proc_static_array,
+        Str = "proc_static_array"
+    ;
+        ArrayName = proc_static_call_sites_array,
+        Str = "proc_static_call_sites_array"
+    ;
+        ArrayName = proc_static_cp_static_array,
+        Str = "proc_static_cp_static_array"
+    ;
+        ArrayName = proc_static_cp_dynamic_array,
+        Str = "proc_static_cp_dynamic_array"
+    ;
+        ArrayName = proc_exec_trace_array,
+        Str = "proc_exec_trace_array"
+    ;
+        ArrayName = proc_event_layouts_array,
+        Str = "proc_event_layouts_array"
+    ;
+        ArrayName = proc_head_var_nums_array,
+        Str = "proc_head_var_nums_array"
+    ;
+        ArrayName = proc_var_names_array,
+        Str = "proc_var_names_array"
+    ;
+        ArrayName = proc_body_bytecodes_array,
+        Str = "proc_body_bytecodes_array"
+    ;
+        ArrayName = proc_table_io_decl_array,
+        Str = "proc_table_io_decl_array"
     ).
 
 dump_layout_name(proc_layout(RttiProcLabel, _)) =
     "proc_layout(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
-dump_layout_name(proc_layout_exec_trace(RttiProcLabel)) =
-    "proc_layout_exec_trace(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
-dump_layout_name(proc_layout_label_layouts(RttiProcLabel)) =
-    "proc_layout_label_layouts(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
-dump_layout_name(proc_layout_head_var_nums(RttiProcLabel)) =
-    "proc_layout_head_var_nums(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
-dump_layout_name(proc_layout_var_names(RttiProcLabel)) =
-    "proc_layout_var_names(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
-dump_layout_name(proc_layout_body_bytecode(RttiProcLabel)) =
-    "proc_layout_body_bytecode(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
 dump_layout_name(closure_proc_id(ProcLabel, SeqNo, _)) =
     "closure_proc_id(" ++ dump_proclabel(ProcLabel)
         ++ int_to_string(SeqNo) ++ ")".
@@ -580,18 +618,6 @@
     "module_common_layout(" ++ sym_name_mangle(ModuleName) ++ ")".
 dump_layout_name(module_layout(ModuleName)) =
     "module_layout(" ++ sym_name_mangle(ModuleName) ++ ")".
-dump_layout_name(proc_static(RttiProcLabel)) =
-    "proc_static(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
-dump_layout_name(proc_static_call_sites(RttiProcLabel)) =
-    "proc_static_call_sites(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
-dump_layout_name(proc_static_coverage_point_static(RttiProcLabel)) =
-    "proc_static_coverage_point_static(" ++ dump_rttiproclabel(RttiProcLabel) 
-        ++ ")".
-dump_layout_name(proc_static_coverage_point_dynamic(RttiProcLabel)) =
-    "proc_static_coverage_point_dynamic(" ++ dump_rttiproclabel(RttiProcLabel) 
-        ++ ")".
-dump_layout_name(table_io_decl(RttiProcLabel)) =
-    "table_io_decl(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
 
 dump_unop(mktag) = "mktag".
 dump_unop(tag) = "tag".
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.659
diff -u -b -r1.659 options.m
--- compiler/options.m	16 Oct 2009 07:59:31 -0000	1.659
+++ compiler/options.m	25 Oct 2009 01:19:18 -0000
@@ -738,6 +738,7 @@
 
     %   - LLDS
     ;       common_data
+    ;       common_layout_data
     ;       optimize            % Also used for MLDS->MLDS optimizations.
     ;       optimize_peep
     ;       optimize_jumps
@@ -1563,6 +1564,7 @@
 
     % LLDS
     common_data                         -   bool(no),
+    common_layout_data                  -   bool(yes),
     optimize                            -   bool(no),
     optimize_peep                       -   bool(no),
     optimize_jumps                      -   bool(no),
@@ -2452,6 +2454,7 @@
 
 % LLDS optimizations
 long_option("common-data",          common_data).
+long_option("common-layout-data",   common_layout_data).
 long_option("llds-optimize",        optimize).
 long_option("llds-optimise",        optimize).
 long_option("optimize-peep",        optimize_peep).
@@ -4985,6 +4988,8 @@
     write_tabbed_lines([
         "--no-common-data",
         "\tDisable optimization of common data structures.",
+        "--no-common-layout-data",
+        "\tDisable optimization of common subsequences in layout structures.",
         "--no-llds-optimize",
         "\tDisable the low-level optimization passes.",
         "--optimize-dead-procs",
Index: compiler/proc_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_gen.m,v
retrieving revision 1.34
diff -u -b -r1.34 proc_gen.m
--- compiler/proc_gen.m	21 Oct 2009 06:36:21 -0000	1.34
+++ compiler/proc_gen.m	27 Oct 2009 07:07:10 -0000
@@ -531,7 +531,7 @@
     ).
 
 :- func generate_deep_prof_info(proc_info, deep_profile_proc_info)
-    = proc_layout_proc_static.
+    = proc_deep_prof_info.
 
 generate_deep_prof_info(ProcInfo, HLDSDeepInfo) = DeepProfInfo :-
     HLDSDeepInfo ^ deep_layout = MaybeHLDSDeepLayout,
@@ -566,7 +566,7 @@
     ),
     DeepExcpSlots = deep_excp_slots(TopCSDSlotNum, MiddleCSDSlotNum,
         OldOutermostSlotNum),
-    DeepProfInfo = proc_layout_proc_static(HLDSProcStatic, DeepExcpSlots,
+    DeepProfInfo = proc_deep_prof_info(HLDSProcStatic, DeepExcpSlots,
         OriginalProcBody).
 
 %---------------------------------------------------------------------------%
@@ -1345,9 +1345,8 @@
 
     MaybeSizeLimit = TableAttributes ^ table_attr_size_limit,
     Statistics = TableAttributes ^ table_attr_statistics,
-    ModuleName = RttiProcLabel ^ proc_module,
     ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-    Var = tabling_info_struct(ModuleName, ProcLabel, EvalMethod,
+    Var = tabling_info_struct(ProcLabel, EvalMethod,
         NumInputs, NumOutputs, InputSteps, MaybeOutputSteps, PTIVectorRval,
         TVarVectorRval, MaybeSizeLimit, Statistics),
     global_data_add_new_proc_var(PredProcId, Var, !GlobalData).
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.67
diff -u -b -r1.67 prog_rep.m
--- compiler/prog_rep.m	11 Jun 2009 07:00:17 -0000	1.67
+++ compiler/prog_rep.m	28 Oct 2009 06:00:04 -0000
@@ -57,7 +57,7 @@
 :- pred represent_proc_as_bytecodes(list(prog_var)::in, hlds_goal::in,
     instmap::in, vartypes::in, var_num_map::in, module_info::in,
     include_variable_table::in, determinism::in, 
-    stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
+    string_table::in, string_table::out, list(int)::out) is det.
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
@@ -94,17 +94,17 @@
             ).
 
 represent_proc_as_bytecodes(HeadVars, Goal, InstMap0, VarTypes, VarNumMap,
-        ModuleInfo, IncludeVarTable, ProcDetism, !StackInfo, ProcRepBytes) :-
+        ModuleInfo, IncludeVarTable, ProcDetism, !StringTable, ProcRepBytes) :-
     Goal = hlds_goal(_, GoalInfo),
     Context = goal_info_get_context(GoalInfo),
     term.context_file(Context, FileName),
     represent_var_table_as_bytecode(IncludeVarTable, VarNumMap, VarNumRep,
-        VarTableBytes, !StackInfo),
+        VarTableBytes, !StringTable),
     Info = prog_rep_info(FileName, VarTypes, VarNumMap, VarNumRep, ModuleInfo),
     InstmapDelta = goal_info_get_instmap_delta(GoalInfo),
 
-    string_to_byte_list(FileName, FileNameBytes, !StackInfo),
-    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StackInfo),
+    string_to_byte_list(FileName, FileNameBytes, !StringTable),
+    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StringTable),
     DetismByte = represent_determinism(ProcDetism),
     ProcRepBytes0 = FileNameBytes ++ VarTableBytes ++
         head_vars_to_byte_list(Info, InstMap0, InstmapDelta, HeadVars) ++
@@ -125,10 +125,10 @@
     %
 :- pred represent_var_table_as_bytecode(include_variable_table::in,
     var_num_map::in, var_num_rep::out, list(int)::out, 
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
 represent_var_table_as_bytecode(IncludeVarTable, VarNumMap, VarNumRep,
-        ByteList, !StackInfo) :-
+        ByteList, !StringTable) :-
     map.foldl(max_var_num, VarNumMap, 0) = MaxVarNum,
     ( MaxVarNum =< 255 ->
         VarNumRep = byte
@@ -139,7 +139,7 @@
     (
         IncludeVarTable = include_variable_table,
         map.foldl3(var_table_entry_bytelist(VarNumRep), VarNumMap, 0, NumVars, 
-            [], VarTableEntriesBytes, !StackInfo)
+            [], VarTableEntriesBytes, !StringTable)
     ;
         IncludeVarTable = do_not_include_variable_table,
         NumVars = 0,
@@ -156,10 +156,10 @@
 :- pred var_table_entry_bytelist(var_num_rep::in, 
     prog_var::in, pair(int, string)::in, int::in, int::out, 
     list(int)::in, list(int)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
 var_table_entry_bytelist(VarNumRep, _ProgVar, VarNum - VarName, 
-        !NumVars, !VarTableBytes, !StackInfo) :-
+        !NumVars, !VarTableBytes, !StringTable) :-
     (
         % Some variables that the compiler creates are named automatically,
         % these and unamed variables should not be included in the variable
@@ -176,7 +176,7 @@
             VarNumRep = short,
             short_to_byte_list(VarNum, VarBytes)
         ),
-        string_to_byte_list(VarName, VarNameBytes, !StackInfo),
+        string_to_byte_list(VarName, VarNameBytes, !StringTable),
         !:VarTableBytes = VarBytes ++ VarNameBytes ++ !.VarTableBytes
     ).
 
@@ -202,40 +202,40 @@
 %---------------------------------------------------------------------------%
 
 :- pred goal_to_byte_list(hlds_goal::in, instmap::in, prog_rep_info::in,
-    list(int)::out, stack_layout_info::in, stack_layout_info::out) is det.
+    list(int)::out, string_table::in, string_table::out) is det.
 
 goal_to_byte_list(hlds_goal(GoalExpr, GoalInfo), InstMap0, Info, Bytes,
-        !StackInfo) :-
+        !StringTable) :-
     (
         GoalExpr = conj(ConjType, Goals),
         expect(unify(ConjType, plain_conj), this_file,
             "non-plain conjunction and declarative debugging"),
-        conj_to_byte_list(Goals, InstMap0, Info, ConjBytes, !StackInfo),
+        conj_to_byte_list(Goals, InstMap0, Info, ConjBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_conj)] ++
             length_to_byte_list(Goals) ++ ConjBytes
     ;
         GoalExpr = disj(Goals),
-        disj_to_byte_list(Goals, InstMap0, Info, DisjBytes, !StackInfo),
+        disj_to_byte_list(Goals, InstMap0, Info, DisjBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_disj)] ++
             length_to_byte_list(Goals) ++ DisjBytes
     ;
         GoalExpr = negation(SubGoal),
-        goal_to_byte_list(SubGoal, InstMap0, Info, SubGoalBytes, !StackInfo),
+        goal_to_byte_list(SubGoal, InstMap0, Info, SubGoalBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_neg)] ++ SubGoalBytes
     ;
         GoalExpr = if_then_else(_, Cond, Then, Else),
         Cond = hlds_goal(_, CondGoalInfo),
         InstMapDelta = goal_info_get_instmap_delta(CondGoalInfo),
         instmap.apply_instmap_delta(InstMap0, InstMapDelta, InstMap1),
-        goal_to_byte_list(Cond, InstMap0, Info, CondBytes, !StackInfo),
-        goal_to_byte_list(Then, InstMap1, Info, ThenBytes, !StackInfo),
-        goal_to_byte_list(Else, InstMap0, Info, ElseBytes, !StackInfo),
+        goal_to_byte_list(Cond, InstMap0, Info, CondBytes, !StringTable),
+        goal_to_byte_list(Then, InstMap1, Info, ThenBytes, !StringTable),
+        goal_to_byte_list(Else, InstMap0, Info, ElseBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_ite)] ++
             CondBytes ++ ThenBytes ++ ElseBytes
     ;
         GoalExpr = unify(_, _, _, Uni, _),
         atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info,
-            AtomicBytes, BoundVars, !StackInfo),
+            AtomicBytes, BoundVars, !StringTable),
         (
             Uni = assign(Target, Source),
             ExprBytes = [goal_type_to_byte(goal_assign)] ++
@@ -244,7 +244,7 @@
                 AtomicBytes
         ;
             Uni = construct(Var, ConsId, Args, ArgModes, _, _, _),
-            cons_id_to_byte_list(ConsId, ConsIdBytes, !StackInfo),
+            cons_id_to_byte_list(ConsId, ConsIdBytes, !StringTable),
             ( list.all_true(lhs_final_is_ground(Info), ArgModes) ->
                 ExprBytes = [goal_type_to_byte(goal_construct)] ++
                     var_to_byte_list(Info, Var) ++
@@ -261,7 +261,7 @@
             )
         ;
             Uni = deconstruct(Var, ConsId, Args, ArgModes, _, _),
-            cons_id_to_byte_list(ConsId, ConsIdBytes, !StackInfo),
+            cons_id_to_byte_list(ConsId, ConsIdBytes, !StringTable),
             ( list.member(Var, BoundVars) ->
                 filter_input_args(Info, ArgModes, Args, MaybeArgs),
                 ExprBytes = [goal_type_to_byte(goal_partial_deconstruct)]++
@@ -288,7 +288,7 @@
         )
     ;
         GoalExpr = switch(SwitchVar, CanFail, Cases),
-        cases_to_byte_list(Cases, InstMap0, Info, CasesBytes, !StackInfo),
+        cases_to_byte_list(Cases, InstMap0, Info, CasesBytes, !StringTable),
         CanFailByte = can_fail_to_byte(CanFail),
         ExprBytes = [goal_type_to_byte(goal_switch)] ++
             [CanFailByte] ++
@@ -304,12 +304,12 @@
         ;
             MaybeCut = 1
         ),
-        goal_to_byte_list(SubGoal, InstMap0, Info, GoalBytes, !StackInfo),
+        goal_to_byte_list(SubGoal, InstMap0, Info, GoalBytes, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_scope)] ++ [MaybeCut] ++ GoalBytes
     ;
         GoalExpr = generic_call(GenericCall, Args, _, _),
         atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info,
-            AtomicBytes, _BoundVars, !StackInfo),
+            AtomicBytes, _BoundVars, !StringTable),
         (
             GenericCall = higher_order(PredVar, _, _, _),
             ExprBytes = [goal_type_to_byte(goal_ho_call)] ++
@@ -325,7 +325,7 @@
                 AtomicBytes
         ;
             GenericCall = event_call(EventName),
-            string_to_byte_list(EventName, EventNameBytes, !StackInfo),
+            string_to_byte_list(EventName, EventNameBytes, !StringTable),
             ExprBytes = [goal_type_to_byte(goal_event_call)] ++
                 EventNameBytes ++
                 vars_to_byte_list(Info, Args) ++
@@ -344,13 +344,13 @@
     ;
         GoalExpr = plain_call(PredId, _, Args, Builtin, _, _),
         atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info,
-            AtomicBytes, _BoundVars, !StackInfo),
+            AtomicBytes, _BoundVars, !StringTable),
         module_info_pred_info(Info ^ pri_module_info, PredId, PredInfo),
         ModuleSymName = pred_info_module(PredInfo),
         ModuleName = sym_name_to_string(ModuleSymName),
         PredName = pred_info_name(PredInfo),
-        string_to_byte_list(ModuleName, ModuleNameBytes, !StackInfo),
-        string_to_byte_list(PredName, PredNameBytes, !StackInfo),
+        string_to_byte_list(ModuleName, ModuleNameBytes, !StringTable),
+        string_to_byte_list(PredName, PredNameBytes, !StringTable),
         (
             Builtin = not_builtin,
             ExprBytes = [goal_type_to_byte(goal_plain_call)] ++
@@ -374,7 +374,7 @@
         GoalExpr = call_foreign_proc(_, _PredId, _, Args, _, _, _),
         ArgVars = list.map(foreign_arg_var, Args),
         atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info,
-            AtomicBytes, _BoundVars, !StackInfo),
+            AtomicBytes, _BoundVars, !StringTable),
         ExprBytes = [goal_type_to_byte(goal_foreign)] ++
             vars_to_byte_list(Info, ArgVars) ++ AtomicBytes
     ;
@@ -420,10 +420,10 @@
 
 :- pred atomic_goal_info_to_byte_list(hlds_goal_info::in, instmap::in,
     prog_rep_info::in, list(int)::out, list(prog_var)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
 atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info, Bytes, BoundVars,
-        !StackInfo) :-
+        !StringTable) :-
     Context = goal_info_get_context(GoalInfo),
     term.context_file(Context, FileName0),
     ( FileName0 = Info ^ pri_filename ->
@@ -437,16 +437,16 @@
     instmap_changed_vars(InstMap0, InstMap, Info ^ pri_vartypes,
         Info ^ pri_module_info, ChangedVars),
     set.to_sorted_list(ChangedVars, BoundVars),
-    string_to_byte_list(FileName, FileNameBytes, !StackInfo),
+    string_to_byte_list(FileName, FileNameBytes, !StringTable),
     Bytes = FileNameBytes ++
         lineno_to_byte_list(LineNo) ++
         vars_to_byte_list(Info, BoundVars).
 
 :- pred cons_id_and_arity_to_byte_list(cons_id::in, list(int)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
-cons_id_and_arity_to_byte_list(ConsId, ConsIdBytes, !StackInfo) :-
-    cons_id_to_byte_list(ConsId, FunctorBytes, !StackInfo),
+cons_id_and_arity_to_byte_list(ConsId, ConsIdBytes, !StringTable) :-
+    cons_id_to_byte_list(ConsId, FunctorBytes, !StringTable),
     MaybeArity = cons_id_maybe_arity(ConsId),
     (
         MaybeArity = yes(Arity)
@@ -458,10 +458,10 @@
     ConsIdBytes = FunctorBytes ++ ArityBytes.
 
 :- pred cons_id_to_byte_list(cons_id::in, list(int)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
-cons_id_to_byte_list(SymName, Bytes, !StackInfo) :-
-    string_to_byte_list(cons_id_rep(SymName), Bytes, !StackInfo).
+cons_id_to_byte_list(SymName, Bytes, !StringTable) :-
+    string_to_byte_list(cons_id_rep(SymName), Bytes, !StringTable).
 
 :- func cons_id_rep(cons_id) = string.
 
@@ -492,43 +492,43 @@
 %---------------------------------------------------------------------------%
 
 :- pred conj_to_byte_list(hlds_goals::in, instmap::in, prog_rep_info::in,
-    list(int)::out, stack_layout_info::in, stack_layout_info::out) is det.
+    list(int)::out, string_table::in, string_table::out) is det.
 
-conj_to_byte_list([], _, _, [], !StackInfo).
-conj_to_byte_list([Goal | Goals], InstMap0, Info, Bytes, !StackInfo) :-
-    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StackInfo),
+conj_to_byte_list([], _, _, [], !StringTable).
+conj_to_byte_list([Goal | Goals], InstMap0, Info, Bytes, !StringTable) :-
+    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StringTable),
     Goal = hlds_goal(_, GoalInfo),
     InstMapDelta = goal_info_get_instmap_delta(GoalInfo),
     instmap.apply_instmap_delta(InstMap0, InstMapDelta, InstMap1),
-    conj_to_byte_list(Goals, InstMap1, Info, GoalsBytes, !StackInfo),
+    conj_to_byte_list(Goals, InstMap1, Info, GoalsBytes, !StringTable),
     Bytes = GoalBytes ++ GoalsBytes.
 
 %---------------------------------------------------------------------------%
 
 :- pred disj_to_byte_list(hlds_goals::in, instmap::in, prog_rep_info::in,
-    list(int)::out, stack_layout_info::in, stack_layout_info::out) is det.
+    list(int)::out, string_table::in, string_table::out) is det.
 
-disj_to_byte_list([], _, _, [], !StackInfo).
-disj_to_byte_list([Goal | Goals], InstMap0, Info, Bytes, !StackInfo) :-
-    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StackInfo),
-    disj_to_byte_list(Goals, InstMap0, Info, GoalsBytes, !StackInfo),
+disj_to_byte_list([], _, _, [], !StringTable).
+disj_to_byte_list([Goal | Goals], InstMap0, Info, Bytes, !StringTable) :-
+    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StringTable),
+    disj_to_byte_list(Goals, InstMap0, Info, GoalsBytes, !StringTable),
     Bytes = GoalBytes ++ GoalsBytes.
 
 %---------------------------------------------------------------------------%
 
 :- pred cases_to_byte_list(list(case)::in, instmap::in, prog_rep_info::in,
-    list(int)::out, stack_layout_info::in, stack_layout_info::out) is det.
+    list(int)::out, string_table::in, string_table::out) is det.
 
-cases_to_byte_list([], _, _, [], !StackInfo).
-cases_to_byte_list([Case | Cases], InstMap0, Info, Bytes, !StackInfo) :-
+cases_to_byte_list([], _, _, [], !StringTable).
+cases_to_byte_list([Case | Cases], InstMap0, Info, Bytes, !StringTable) :-
     Case = case(MainConsId, OtherConsIds, Goal),
-    cons_id_and_arity_to_byte_list(MainConsId, MainConsIdBytes, !StackInfo),
+    cons_id_and_arity_to_byte_list(MainConsId, MainConsIdBytes, !StringTable),
     list.map_foldl(cons_id_and_arity_to_byte_list, OtherConsIds,
-        OtherConsIdsByteLists, !StackInfo),
+        OtherConsIdsByteLists, !StringTable),
     list.condense(OtherConsIdsByteLists, OtherConsIdsBytes),
     NumOtherConsIdBytes = length_to_byte_list(OtherConsIds),
-    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StackInfo),
-    cases_to_byte_list(Cases, InstMap0, Info, CasesBytes, !StackInfo),
+    goal_to_byte_list(Goal, InstMap0, Info, GoalBytes, !StringTable),
+    cases_to_byte_list(Cases, InstMap0, Info, CasesBytes, !StringTable),
     Bytes = MainConsIdBytes ++ NumOtherConsIdBytes ++ OtherConsIdsBytes
         ++ GoalBytes ++ CasesBytes.
 
@@ -546,10 +546,10 @@
 % halves their range.
 
 :- pred string_to_byte_list(string::in, list(int)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
-string_to_byte_list(String, Bytes, !StackInfo) :-
-    stack_layout.lookup_string_in_table(String, Index, !StackInfo),
+string_to_byte_list(String, Bytes, !StringTable) :-
+    stack_layout.lookup_string_in_table(String, Index, !StringTable),
     int32_to_byte_list(Index, Bytes).
 
 :- func vars_to_byte_list(prog_rep_info, list(prog_var)) = list(int).
Index: compiler/rtti_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rtti_out.m,v
retrieving revision 1.80
diff -u -b -r1.80 rtti_out.m
--- compiler/rtti_out.m	14 Oct 2009 05:28:43 -0000	1.80
+++ compiler/rtti_out.m	27 Oct 2009 14:13:34 -0000
@@ -458,8 +458,7 @@
 output_type_info_defn(Info, TypeInfo, !DeclSet, !IO) :-
     (
         rtti_data_to_id(rtti_data_type_info(TypeInfo), RttiId),
-        DataAddr = rtti_addr(RttiId),
-        decl_set_is_member(decl_data_addr(DataAddr), !.DeclSet)
+        decl_set_is_member(decl_rtti_id(RttiId), !.DeclSet)
     ->
         true
     ;
@@ -524,8 +523,7 @@
         true
     ;
         rtti_data_to_id(rtti_data_pseudo_type_info(PseudoTypeInfo), RttiId),
-        DataAddr = rtti_addr(RttiId),
-        decl_set_is_member(decl_data_addr(DataAddr), !.DeclSet)
+        decl_set_is_member(decl_rtti_id(RttiId), !.DeclSet)
     ->
         true
     ;
@@ -1473,8 +1471,7 @@
         "output_rtti_data_decl_chunk_entries: empty list").
 output_rtti_data_decl_chunk_entries(IsArray, [RttiId | RttiIds],
         !DeclSet, !IO) :-
-    DataAddr = rtti_addr(RttiId),
-    decl_set_insert(decl_data_addr(DataAddr), !DeclSet),
+    decl_set_insert(decl_rtti_id(RttiId), !DeclSet),
     io.write_string("\t", !IO),
     output_rtti_id(RttiId, !IO),
     (
@@ -1512,8 +1509,7 @@
 output_generic_rtti_data_decl(Info, RttiId, !DeclSet, !IO) :-
     output_rtti_id_storage_type_name(Info, RttiId, no, !DeclSet, !IO),
     io.write_string(";\n", !IO),
-    DataAddr = rtti_addr(RttiId),
-    decl_set_insert(decl_data_addr(DataAddr), !DeclSet).
+    decl_set_insert(decl_rtti_id(RttiId), !DeclSet).
 
 :- pred output_generic_rtti_data_defn_start(llds_out_info::in, rtti_id::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
@@ -1521,8 +1517,7 @@
 output_generic_rtti_data_defn_start(Info, RttiId, !DeclSet, !IO) :-
     io.write_string("\n", !IO),
     output_rtti_id_storage_type_name(Info, RttiId, yes, !DeclSet, !IO),
-    DataAddr = rtti_addr(RttiId),
-    decl_set_insert(decl_data_addr(DataAddr), !DeclSet).
+    decl_set_insert(decl_rtti_id(RttiId), !DeclSet).
 
 output_rtti_id_storage_type_name_no_decl(Info, RttiId, BeingDefined, !IO) :-
     decl_set_init(DeclSet0),
@@ -1763,7 +1758,7 @@
 
 output_record_rtti_id_decls(Info, RttiId, FirstIndent, LaterIndent,
         !N, !DeclSet, !IO) :-
-    output_record_data_addr_decls_format(Info, rtti_addr(RttiId),
+    output_record_data_id_decls_format(Info, rtti_data_id(RttiId),
         FirstIndent, LaterIndent, !N, !DeclSet, !IO).
 
 :- pred output_cast_addr_of_rtti_ids(string::in, list(rtti_id)::in,
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rtti_to_mlds.m,v
retrieving revision 1.94
diff -u -b -r1.94 rtti_to_mlds.m
--- compiler/rtti_to_mlds.m	12 Oct 2009 01:34:14 -0000	1.94
+++ compiler/rtti_to_mlds.m	25 Oct 2009 10:03:40 -0000
@@ -1505,7 +1505,7 @@
     % hence we need to generate a wrapper function which unboxes the arguments
     % if necessary.
     ( univ_to_type(RttiProcIdUniv, RttiProcId) ->
-        ( RttiProcId ^ proc_arity = 0 ->
+        ( RttiProcId ^ rpl_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 the procedure will be
@@ -1535,8 +1535,8 @@
         % with any function labels used when generating code for the wrapped
         % procedure.
 
-        PredId = RttiProcId ^ pred_id,
-        ProcId = RttiProcId ^ proc_id,
+        PredId = RttiProcId ^ rpl_pred_id,
+        ProcId = RttiProcId ^ rpl_proc_id,
         module_info_proc_info(ModuleInfo, PredId, ProcId, ProcInfo),
         !:Info = ml_gen_info_init(ModuleInfo, PredId, ProcId, ProcInfo,
             !.GlobalData),
@@ -1561,7 +1561,7 @@
     % Construct an rval for the address of this procedure
     % (this is similar to ml_gen_proc_addr_rval).
     ml_gen_pred_label_from_rtti(ModuleInfo, RttiProcId, PredLabel, PredModule),
-    ProcId = RttiProcId ^ proc_id,
+    ProcId = RttiProcId ^ rpl_proc_id,
     QualifiedProcLabel = qual(PredModule, module_qual,
         mlds_proc_label(PredLabel, ProcId)),
     Params = ml_gen_proc_params_from_rtti(ModuleInfo, RttiProcId),
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.149
diff -u -b -r1.149 stack_layout.m
--- compiler/stack_layout.m	21 Oct 2009 06:36:22 -0000	1.149
+++ compiler/stack_layout.m	28 Oct 2009 07:20:03 -0000
@@ -37,6 +37,7 @@
 :- import_module ll_backend.layout.
 :- import_module ll_backend.llds.
 :- import_module mdbcomp.prim_data.
+:- import_module mdbcomp.program_representation.
 :- import_module parse_tree.prog_data.
 
 :- import_module assoc_list.
@@ -51,17 +52,23 @@
     %
 :- pred generate_llds_layout_data(module_info::in,
     global_data::in, global_data::out,
+    list(rval)::out, list(int)::out, list(int)::out, list(int)::out,
     list(maybe(int))::out, list(user_event_data)::out,
-    list(label_layout_vars)::out, list(label_layout_no_vars)::out,
-    map(label, layout_slot_name)::out, map(label, data_addr)::out,
-    list(layout_data)::out, list(layout_data)::out, list(layout_data)::out)
-    is det.
+    list(label_layout_no_vars)::out,
+    list(label_layout_short_vars)::out, list(label_layout_long_vars)::out,
+    map(label, layout_slot_name)::out, map(label, data_id)::out,
+    list(call_site_static_data)::out, list(coverage_point_info)::out,
+    list(proc_layout_proc_static)::out,
+    list(int)::out, list(int)::out, list(int)::out,
+    list(table_io_decl_data)::out, map(pred_proc_id, layout_slot_name)::out,
+    list(layout_slot_name)::out, list(proc_layout_exec_trace)::out,
+    list(proc_layout_data)::out, list(module_layout_data)::out) is det.
 
 :- pred construct_closure_layout(proc_label::in, int::in,
     closure_layout_info::in, proc_label::in, module_name::in,
     string::in, int::in, pred_origin::in, string::in,
     static_cell_info::in, static_cell_info::out,
-    assoc_list(rval, llds_type)::out, layout_data::out) is det.
+    assoc_list(rval, llds_type)::out, closure_proc_id_data::out) is det.
 
 :- pred convert_table_arg_info(table_arg_infos::in, int::out,
     rval::out, rval::out, static_cell_info::in, static_cell_info::out) is det.
@@ -75,10 +82,9 @@
     %
 :- pred represent_determinism_rval(determinism::in, rval::out) is det.
 
-:- type stack_layout_info.
-
+:- type string_table.
 :- pred lookup_string_in_table(string::in, int::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
@@ -103,7 +109,6 @@
 :- import_module ll_backend.ll_pseudo_type_info.
 :- import_module ll_backend.prog_rep.
 :- import_module ll_backend.trace_gen.
-:- import_module mdbcomp.program_representation.
 :- import_module parse_tree.prog_event.
 
 :- import_module bool.
@@ -121,93 +126,119 @@
 %---------------------------------------------------------------------------%
 
 generate_llds_layout_data(ModuleInfo, !GlobalData,
-        UserEventVarNums, UserEvents, VarLabelLayouts, NoVarLabelLayouts,
+        PseudoTypeInfoRvals, HLDSVarNums, ShortLocns, LongLocns,
+        UserEventVarNums, UserEvents,
+        NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
         InternalLabelToLayoutMap, ProcLabelToLayoutMap,
-        ProcLayouts, ModuleLayouts, OtherLayouts) :-
-    global_data_get_all_proc_layouts(!.GlobalData, ProcLayoutList),
-    module_info_get_globals(ModuleInfo, Globals),
-    globals.lookup_bool_option(Globals, agc_stack_layout, AgcLayout),
-    globals.lookup_bool_option(Globals, trace_stack_layout, TraceLayout),
-    globals.lookup_bool_option(Globals, procid_stack_layout, ProcIdLayout),
-    globals.lookup_bool_option(Globals, profile_deep, DeepProfiling),
-    globals.lookup_bool_option(Globals, static_code_addresses, StaticCodeAddr),
-    globals.lookup_bool_option(Globals, unboxed_float, OptUnboxedFloat),
-    (
-        OptUnboxedFloat = yes,
-        UnboxedFloat = have_unboxed_floats
-    ;
-        OptUnboxedFloat = no,
-        UnboxedFloat = do_not_have_unboxed_floats
-    ),
-    globals.get_trace_level(Globals, TraceLevel),
-    globals.get_trace_suppress(Globals, TraceSuppress),
+        CallSiteStatics, CoveragePoints, ProcStatics,
+        ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes,
+        TableIoDecls, TableIoDeclMap, ProcEventLayouts, ExecTraces,
+        ProcLayouts, ModuleLayouts) :-
 
-    map.init(StringMap0),
+    Params = init_stack_layout_params(ModuleInfo),
     map.init(LabelTables0),
-    StringTable0 = string_table(StringMap0, [], 0),
+    StringTable0 = init_string_table,
     global_data_get_static_cell_info(!.GlobalData, StaticCellInfo0),
-    counter.init(1, LabelCounter0),
-    counter.init(0, UserEventCounter0),
-    counter.init(0, VarLabelLayoutSlotCounter0),
-    counter.init(0, NoVarLabelLayoutSlotCounter0),
-    map.init(InternalLabelToLayoutMap0),
-    map.init(ProcLabelToLayoutMap0),
-    LayoutInfo0 = stack_layout_info(ModuleInfo,
-        AgcLayout, TraceLayout, ProcIdLayout, StaticCodeAddr, UnboxedFloat,
-        LabelCounter0, [], [], [],
-        UserEventCounter0, 0, cord.empty, cord.empty,
-        VarLabelLayoutSlotCounter0, NoVarLabelLayoutSlotCounter0, [], [],
-        InternalLabelToLayoutMap0, ProcLabelToLayoutMap0,
-        StringTable0, LabelTables0, StaticCellInfo0, no),
-    lookup_string_in_table("", _, LayoutInfo0, LayoutInfo1),
-    lookup_string_in_table("<too many variables>", _,
-        LayoutInfo1, LayoutInfo2),
-    list.foldl(construct_layouts(DeepProfiling), ProcLayoutList,
-        LayoutInfo2, LayoutInfo),
-    LabelsCounter = LayoutInfo ^ sli_label_counter,
+    LabelLayoutInfo0 = init_label_layouts_info,
+    ProcLayoutInfo0 = init_proc_layouts_info,
+
+    global_data_get_all_proc_layouts(!.GlobalData, ProcLayoutList),
+    list.foldl5(construct_proc_and_label_layouts_for_proc(Params),
+        ProcLayoutList,
+        LabelTables0, LabelTables,
+        StringTable0, StringTable,
+        StaticCellInfo0, StaticCellInfo1,
+        LabelLayoutInfo0, LabelLayoutInfo,
+        ProcLayoutInfo0, ProcLayoutInfo),
+
+    LabelsCounter = LabelLayoutInfo ^ lli_label_counter,
     counter.allocate(NumLabels, LabelsCounter, _),
-    TableIoDecls = LayoutInfo ^ sli_table_infos,
-    OtherLayouts = TableIoDecls,
 
-    RevProcLayouts = LayoutInfo ^ sli_rev_proc_layouts,
-    RevProcLayoutNames = LayoutInfo ^ sli_rev_proc_layout_names,
+    RevCallSiteStatics =
+        ProcLayoutInfo ^ pli_proc_statics ^ psi_rev_call_sites,
+    RevCoveragePoints =
+        ProcLayoutInfo ^ pli_proc_statics ^ psi_rev_coverage_points,
+    RevProcStatics =
+        ProcLayoutInfo ^ pli_proc_statics ^ psi_rev_proc_statics,
+    list.reverse(RevCallSiteStatics, CallSiteStatics),
+    list.reverse(RevCoveragePoints, CoveragePoints),
+    list.reverse(RevProcStatics, ProcStatics),
+
+    RevProcHeadVarNums =
+        ProcLayoutInfo ^ pli_exec_traces ^ eti_rev_proc_head_var_nums,
+    RevProcVarNames =
+        ProcLayoutInfo ^ pli_exec_traces ^ eti_rev_proc_var_names,
+    RevProcEventLayouts =
+        ProcLayoutInfo ^ pli_exec_traces ^ eti_rev_proc_event_layouts,
+    RevTableIoDecls =
+        ProcLayoutInfo ^ pli_exec_traces ^ eti_rev_table_io_decl_datas,
+    RevExecTraces =
+        ProcLayoutInfo ^ pli_exec_traces ^ eti_rev_exec_traces,
+    list.reverse(RevProcHeadVarNums, ProcHeadVarNums),
+    list.reverse(RevProcVarNames, ProcVarNames),
+    list.reverse(RevProcEventLayouts, ProcEventLayouts),
+    list.reverse(RevTableIoDecls, TableIoDecls),
+    list.reverse(RevExecTraces, ExecTraces),
+
+    TableIoDeclMap = ProcLayoutInfo ^ pli_exec_traces ^ eti_table_io_decl_map,
+
+    RevProcBodyBytecodes = ProcLayoutInfo ^ pli_rev_proc_bytes,
+    RevProcLayouts = ProcLayoutInfo ^ pli_rev_proc_layouts,
+    RevProcLayoutNames = ProcLayoutInfo ^ pli_rev_proc_layout_names,
+    list.reverse(RevProcBodyBytecodes, ProcBodyBytecodes),
     list.reverse(RevProcLayouts, ProcLayouts),
     list.reverse(RevProcLayoutNames, ProcLayoutNames),
 
-    UserEventVarNumsCord = LayoutInfo ^ sli_user_event_var_nums,
+    RevPseudoTypeInfoRvals = LabelLayoutInfo ^ lli_rev_ptis,
+    RevLongLocns = LabelLayoutInfo ^ lli_rev_long_locns,
+    RevShortLocns = LabelLayoutInfo ^ lli_rev_short_locns,
+    RevHLDSVarNums = LabelLayoutInfo ^ lli_rev_hlds_var_nums,
+    list.reverse(RevPseudoTypeInfoRvals, PseudoTypeInfoRvals),
+    list.reverse(RevLongLocns, LongLocns),
+    list.reverse(RevShortLocns, ShortLocns),
+    list.reverse(RevHLDSVarNums, HLDSVarNums),
+
+    UserEventVarNumsCord = LabelLayoutInfo ^ lli_user_event_var_nums,
+    UserEventsCord = LabelLayoutInfo ^ lli_user_events,
     UserEventVarNums = cord.list(UserEventVarNumsCord),
-    UserEventsCord = LayoutInfo ^ sli_user_events,
     UserEvents = cord.list(UserEventsCord),
 
-    RevVarLabelLayouts = LayoutInfo ^ sli_rev_var_label_layouts,
-    RevNoVarLabelLayouts = LayoutInfo ^ sli_rev_no_var_label_layouts,
-    list.reverse(RevVarLabelLayouts, VarLabelLayouts),
+    RevNoVarLabelLayouts = LabelLayoutInfo ^ lli_rev_no_var_label_layouts,
+    RevSVarLabelLayouts = LabelLayoutInfo ^ lli_rev_svar_label_layouts,
+    RevLVarLabelLayouts = LabelLayoutInfo ^ lli_rev_lvar_label_layouts,
     list.reverse(RevNoVarLabelLayouts, NoVarLabelLayouts),
+    list.reverse(RevSVarLabelLayouts, SVarLabelLayouts),
+    list.reverse(RevLVarLabelLayouts, LVarLabelLayouts),
 
-    InternalLabelToLayoutMap = LayoutInfo ^ sli_i_label_to_layout_map,
-    ProcLabelToLayoutMap = LayoutInfo ^ sli_p_label_to_layout_map,
+    InternalLabelToLayoutMap = LabelLayoutInfo ^ lli_i_label_to_layout_map,
+    ProcLabelToLayoutMap = ProcLayoutInfo ^ pli_p_label_to_layout_map,
 
-    StringTable = LayoutInfo ^ sli_string_table,
-    LabelTables = LayoutInfo ^ sli_label_tables,
-    StaticCellInfo1 = LayoutInfo ^ sli_static_cell_info,
     StringTable = string_table(_, RevStringList, StringOffset),
     list.reverse(RevStringList, StringList),
     ConcatStrings = string_with_0s(StringList),
 
+    TraceLayout = Params ^ slp_trace_stack_layout,
     (
         TraceLayout = yes,
         module_info_get_name(ModuleInfo, ModuleName),
-        globals.lookup_bool_option(Globals, rtti_line_numbers, LineNumbers),
+        RttiLineNumbers = Params ^ slp_rtti_line_numbers,
         (
-            LineNumbers = yes,
+            RttiLineNumbers = yes,
             EffLabelTables = LabelTables
         ;
-            LineNumbers = no,
+            RttiLineNumbers = no,
             map.init(EffLabelTables)
         ),
         format_label_tables(EffLabelTables, SourceFileLayouts),
+        TraceSuppress = Params ^ slp_trace_suppress,
         SuppressedEvents = encode_suppressed_events(TraceSuppress),
-        HasUserEvent = LayoutInfo ^ sli_has_user_event,
+        (
+            UserEvents = [],
+            HasUserEvent = no
+        ;
+            UserEvents = [_ | _],
+            HasUserEvent = yes
+        ),
         (
             HasUserEvent = no,
             MaybeEventSet = no,
@@ -227,22 +258,24 @@
         ModuleCommonLayout = module_layout_common_data(ModuleName,
             StringOffset, ConcatStrings),
         ModuleCommonLayoutName = module_common_layout(ModuleName),
+        TraceLevel = Params ^ slp_trace_level,
         ModuleLayout = module_layout_data(ModuleName,
             ModuleCommonLayoutName, ProcLayoutNames, SourceFileLayouts,
             TraceLevel, SuppressedEvents, NumLabels, MaybeEventSet),
         ModuleLayouts = [ModuleCommonLayout, ModuleLayout]
     ;
         TraceLayout = no,
+        DeepProfiling = Params ^ slp_deep_profiling,
+        (
         DeepProfiling = yes,
         module_info_get_name(ModuleInfo, ModuleName),
         ModuleCommonLayout = module_layout_common_data(ModuleName,
             StringOffset, ConcatStrings),
-        ModuleLayouts = [ModuleCommonLayout],
-        StaticCellInfo = StaticCellInfo1
+            ModuleLayouts = [ModuleCommonLayout]
     ;
-        TraceLayout = no,
         DeepProfiling = no,
-        ModuleLayouts = [],
+            ModuleLayouts = []
+        ),
         StaticCellInfo = StaticCellInfo1
     ),
     global_data_set_static_cell_info(StaticCellInfo, !GlobalData).
@@ -328,70 +361,76 @@
 
 %---------------------------------------------------------------------------%
 
+    % The per-sourcefile label table maps line numbers to the list of
+    % labels that correspond to that line. Each label is accompanied
+    % by a flag that says whether the label is the return site of a call
+    % or not, and if it is, whether the called procedure is known.
+    %
+:- type is_label_return
+    --->    known_callee(label)
+    ;       unknown_callee
+    ;       not_a_return.
+
+:- type line_no_info == pair(layout_slot_name, is_label_return).
+
+:- type file_label_table == map(int, list(line_no_info)).
+
+:- type label_tables == map(string, file_label_table).
+
     % Construct the layouts that concern a single procedure: the procedure
     % layout and the layouts of the labels inside that procedure. Also update
     % the module-wide label table with the labels defined in this procedure.
     %
-:- pred construct_layouts(bool::in, proc_layout_info::in,
-    stack_layout_info::in, stack_layout_info::out) is det.
+:- pred construct_proc_and_label_layouts_for_proc(stack_layout_params::in,
+    proc_layout_info::in,
+    label_tables::in, label_tables::out,
+    string_table::in, string_table::out,
+    static_cell_info::in, static_cell_info::out,
+    label_layouts_info::in, label_layouts_info::out,
+    proc_layouts_info::in, proc_layouts_info::out) is det.
 
-construct_layouts(DeepProfiling, ProcLayoutInfo, !Info) :-
-    ProcLayoutInfo = proc_layout_info(RttiProcLabel,
-        EntryLabel,
-        _Detism,
-        _StackSlots,
-        _SuccipLoc,
-        _EvalMethod,
-        _EffTraceLevel,
-        _MaybeCallLabel,
-        _MaxTraceReg,
-        HeadVars,
-        _ArgModes,
-        Goal,
-        _NeedGoalRep,
-        _InstMap,
-        _TraceSlotInfo,
-        ForceProcIdLayout,
-        VarSet,
-        _VarTypes,
-        InternalMap,
-        MaybeTableIoDecl,
-        _NeedsAllNames,
-        _MaybeDeepProfInfo),
+construct_proc_and_label_layouts_for_proc(Params, PLI, !LabelTables,
+        !StringTable, !StaticCellInfo, !LabelLayoutInfo, !ProcLayoutInfo) :-
+    PLI = proc_layout_info(RttiProcLabel, EntryLabel,
+        _Detism, _StackSlots, _SuccipLoc, _EvalMethod, _EffTraceLevel,
+        _MaybeCallLabel, _MaxTraceReg, HeadVars, _ArgModes,
+        Goal, _NeedGoalRep, _InstMap,
+        _TraceSlotInfo, ForceProcIdLayout, VarSet, _VarTypes,
+        InternalMap, MaybeTableIoDecl, _NeedsAllNames, _MaybeDeepProfInfo),
     map.to_assoc_list(InternalMap, Internals),
     compute_var_number_map(HeadVars, VarSet, Internals, Goal, VarNumMap),
 
     ProcLabel = get_proc_label(EntryLabel),
-    get_procid_stack_layout(!.Info, ProcIdLayout0),
-    bool.or(ProcIdLayout0, ForceProcIdLayout, ProcIdLayout),
+    bool.or(Params ^ slp_procid_stack_layout, ForceProcIdLayout, ProcIdLayout),
     (
         ( ProcIdLayout = yes
         ; MaybeTableIoDecl = yes(_)
         )
     ->
-        Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel))
+        UserOrUci = proc_label_user_or_uci(ProcLabel),
+        Kind = proc_layout_proc_id(UserOrUci)
     ;
         Kind = proc_layout_traversal
     ),
     ProcLayoutName = proc_layout(RttiProcLabel, Kind),
     (
-        ( !.Info ^ sli_agc_stack_layout = yes
-        ; !.Info ^ sli_trace_stack_layout = yes
+        ( Params ^ slp_agc_stack_layout = yes
+        ; Params ^ slp_trace_stack_layout = yes
         ),
-        valid_proc_layout(ProcLayoutInfo)
+        valid_proc_layout(PLI)
     ->
-        list.map_foldl(
-            construct_internal_layout(ProcLabel, ProcLayoutName, VarNumMap),
-            Internals, InternalLabelInfos, !Info)
+        list.map_foldl3(
+            construct_internal_layout(Params, ProcLabel, ProcLayoutName,
+                VarNumMap),
+            Internals, InternalLabelInfos,
+            !StringTable, !StaticCellInfo, !LabelLayoutInfo)
     ;
         InternalLabelInfos = []
     ),
-    get_label_tables(!.Info, LabelTables0),
-    list.foldl(update_label_table, InternalLabelInfos,
-        LabelTables0, LabelTables),
-    set_label_tables(LabelTables, !Info),
-    construct_proc_layout(ProcLayoutInfo, InternalLabelInfos, Kind, VarNumMap,
-        DeepProfiling, !Info).
+    list.foldl(update_label_table, InternalLabelInfos, !LabelTables),
+    construct_proc_layout(Params, PLI, ProcLayoutName, Kind,
+        InternalLabelInfos, VarNumMap, !.LabelLayoutInfo,
+        !StringTable, !StaticCellInfo, !ProcLayoutInfo).
 
 %---------------------------------------------------------------------------%
 
@@ -492,108 +531,70 @@
     Line > 0.
 
 %---------------------------------------------------------------------------%
+%
+% Construct proc layouts.
+%
 
-:- pred 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.
-
-construct_proc_traversal(EntryLabel, Detism, NumStackSlots,
-        MaybeSuccipLoc, Traversal, !Info) :-
-    (
-        MaybeSuccipLoc = yes(Location),
-        ( determinism_components(Detism, _, at_most_many) ->
-            SuccipLval = framevar(Location)
-        ;
-            SuccipLval = stackvar(Location)
-        ),
-        represent_locn_as_int(locn_direct(SuccipLval), SuccipInt),
-        MaybeSuccipInt = yes(SuccipInt)
-    ;
-        MaybeSuccipLoc = no,
-        % Use a dummy location if there is no succip slot on the stack.
-        %
-        % This case can arise in two circumstances. First, procedures that
-        % use the nondet stack have a special slot for the succip, so the
-        % succip is not stored in a general purpose slot. Second, procedures
-        % that use the det stack but which do not call other procedures
-        % do not save the succip on the stack.
-        %
-        % The tracing system does not care about the location of the saved
-        % succip. The accurate garbage collector does. It should know from
-        % the determinism that the procedure uses the nondet stack, which
-        % takes care of the first possibility above. Procedures that do not
-        % call other procedures do not establish resumption points and thus
-        % agc is not interested in them. As far as stack dumps go, calling
-        % error counts as a call, so any procedure that may call error
-        % (directly or indirectly) will have its saved succip location
-        % recorded, so the stack dump will work.
+    % Construct a procedure-specific layout.
         %
-        % Future uses of stack layouts will have to have similar constraints.
-        MaybeSuccipInt = no
-    ),
-    get_static_code_addresses(!.Info, StaticCodeAddr),
+:- pred construct_proc_layout(stack_layout_params::in, proc_layout_info::in,
+    layout_name::in, proc_layout_kind::in, list(internal_label_info)::in,
+    var_num_map::in,
+    label_layouts_info::in, string_table::in, string_table::out,
+    static_cell_info::in, static_cell_info::out,
+    proc_layouts_info::in, proc_layouts_info::out) is det.
+
+construct_proc_layout(Params, PLI, ProcLayoutName, Kind,
+        InternalLabelInfos, VarNumMap, LabelLayoutInfo,
+        !StringTable, !StaticCellInfo, !ProcLayoutInfo) :-
+    PLI = proc_layout_info(RttiProcLabel, EntryLabel,
+        Detism, StackSlots, SuccipLoc, EvalMethod, EffTraceLevel,
+        MaybeCallLabel, MaxTraceReg, HeadVars, ArgModes,
+        Goal, NeedGoalRep, InstMap,
+        TraceSlotInfo, _ForceProcIdLayout, VarSet, VarTypes,
+        InternalMap, MaybeTableInfo, NeedsAllNames, MaybeDeepProfInfo),
+    construct_proc_traversal(Params, EntryLabel, Detism, StackSlots,
+        SuccipLoc, Traversal),
+    PredId = RttiProcLabel ^ rpl_pred_id,
+    ProcId = RttiProcLabel ^ rpl_proc_id,
+    PredProcId = proc(PredId, ProcId),
     (
-        StaticCodeAddr = yes,
-        MaybeEntryLabel = yes(EntryLabel)
+        MaybeTableInfo = no,
+        MaybeTableSlotName = no
     ;
-        StaticCodeAddr = no,
-        MaybeEntryLabel = no
+        MaybeTableInfo = yes(TableInfo),
+        TableExecTraceInfo0 = !.ProcLayoutInfo ^ pli_exec_traces,
+        construct_exec_trace_table_data(PredProcId, ProcLayoutName, TableInfo,
+            MaybeTableSlotName, !StaticCellInfo,
+            TableExecTraceInfo0, TableExecTraceInfo),
+        !ProcLayoutInfo ^ pli_exec_traces := TableExecTraceInfo
     ),
-    Traversal = proc_layout_stack_traversal(MaybeEntryLabel,
-        MaybeSuccipInt, NumStackSlots, Detism).
-
-    % Construct a procedure-specific layout.
-    %
-:- pred construct_proc_layout(proc_layout_info::in,
-    list(internal_label_info)::in, proc_layout_kind::in, var_num_map::in,
-    bool::in, stack_layout_info::in, stack_layout_info::out) is det.
-
-construct_proc_layout(ProcLayoutInfo, InternalLabelInfos, Kind, VarNumMap,
-        DeepProfiling, !Info) :-
-    ProcLayoutInfo = proc_layout_info(RttiProcLabel,
-        EntryLabel,
-        Detism,
-        StackSlots,
-        SuccipLoc,
-        EvalMethod,
-        EffTraceLevel,
-        MaybeCallLabel,
-        MaxTraceReg,
-        HeadVars,
-        ArgModes,
-        Goal,
-        NeedGoalRep,
-        InstMap,
-        TraceSlotInfo,
-        _ForceProcIdLayout,
-        VarSet,
-        VarTypes,
-        InternalMap,
-        MaybeTableInfo,
-        NeedsAllNames,
-        MaybeProcStatic),
-    construct_proc_traversal(EntryLabel, Detism, StackSlots,
-        SuccipLoc, Traversal, !Info),
     (
         Kind = proc_layout_traversal,
         More = no_proc_id_and_more
     ;
         Kind = proc_layout_proc_id(_),
-        get_trace_stack_layout(!.Info, TraceStackLayout),
+        TraceStackLayout = Params ^ slp_trace_stack_layout,
         (
             TraceStackLayout = yes,
             not map.is_empty(InternalMap),
-            valid_proc_layout(ProcLayoutInfo)
+            valid_proc_layout(PLI)
         ->
-            construct_trace_layout(RttiProcLabel, EvalMethod, EffTraceLevel,
-                MaybeCallLabel, MaxTraceReg, HeadVars, ArgModes, TraceSlotInfo,
-                VarSet, VarTypes, MaybeTableInfo, NeedsAllNames, VarNumMap,
-                InternalLabelInfos, ExecTrace, !Info),
-            MaybeExecTrace = yes(ExecTrace)
+            ExecTraceInfo0 = !.ProcLayoutInfo ^ pli_exec_traces,
+            construct_exec_trace_layout(Params, RttiProcLabel,
+                EvalMethod, EffTraceLevel, MaybeCallLabel, MaybeTableSlotName,
+                MaxTraceReg, HeadVars, ArgModes, TraceSlotInfo,
+                VarSet, VarTypes, MaybeTableInfo, NeedsAllNames,
+                VarNumMap, InternalLabelInfos, ExecTraceSlotName,
+                LabelLayoutInfo, !StringTable,
+                ExecTraceInfo0, ExecTraceInfo),
+            !ProcLayoutInfo ^ pli_exec_traces := ExecTraceInfo,
+            MaybeExecTraceSlotName = yes(ExecTraceSlotName)
         ;
-            MaybeExecTrace = no
+            MaybeExecTraceSlotName = no
         ),
-        ModuleInfo = !.Info ^ sli_module_info,
+        ModuleInfo = Params ^ slp_module_info,
+        DeepProfiling = Params ^ slp_deep_profiling,
         (
             ( NeedGoalRep = trace_needs_body_rep
             ; DeepProfiling = yes
@@ -607,12 +608,18 @@
                 IncludeVarTable = do_not_include_variable_table
             ),
 
-            % When the proc static is availiable (used with deep profiling) use
+            % When the program is compiled with deep profiling, use
             % the version of the procedure saved before the deep profiling
             % transformation as the program representation.
             (
-                MaybeProcStatic = yes(ProcStatic),
-                DeepOriginalBody = ProcStatic ^ deep_original_body,
+                MaybeDeepProfInfo = yes(DeepProfInfo),
+                ProcStaticInfo0 = !.ProcLayoutInfo ^ pli_proc_statics,
+                construct_proc_static_layout(DeepProfInfo, ProcStaticSlotName,
+                    ProcStaticInfo0, ProcStaticInfo),
+                !ProcLayoutInfo ^ pli_proc_statics := ProcStaticInfo,
+                MaybeProcStaticSlotName = yes(ProcStaticSlotName),
+
+                DeepOriginalBody = DeepProfInfo ^ pdpi_orig_body,
                 DeepOriginalBody = deep_original_body(BytecodeBody,
                     BytecodeHeadVars, BytecodeInstMap, BytecodeVarTypes,
                     BytecodeDetism),
@@ -628,7 +635,8 @@
                     BytecodeVarNumMap = !.VarNumMap
                 )
             ;
-                MaybeProcStatic = no,
+                MaybeDeepProfInfo = no,
+                MaybeProcStaticSlotName = no,
                 BytecodeHeadVars = HeadVars,
                 BytecodeBody = Goal,
                 BytecodeInstMap = InstMap,
@@ -638,54 +646,256 @@
             ),
             represent_proc_as_bytecodes(BytecodeHeadVars, BytecodeBody,
                 BytecodeInstMap, BytecodeVarTypes, BytecodeVarNumMap,
-                ModuleInfo, IncludeVarTable, BytecodeDetism, !Info, ProcBytes)
+                ModuleInfo, IncludeVarTable, BytecodeDetism, !StringTable,
+                ProcBytes),
+
+            % Calling find_sequence on ProcBytes is very unlikely to find
+            % any matching sequences, though there is no reason why we
+            % cannot try.
+            list.reverse(ProcBytes, RevProcBytes),
+            list.length(ProcBytes, NumProcBytes),
+
+            RevAllProcBytes0 = !.ProcLayoutInfo ^ pli_rev_proc_bytes,
+            RevAllProcBytes = RevProcBytes ++ RevAllProcBytes0,
+            !ProcLayoutInfo ^ pli_rev_proc_bytes := RevAllProcBytes,
+
+            NextProcByte0 = !.ProcLayoutInfo ^ pli_next_proc_byte,
+            ProcByteSlot = NextProcByte0,
+            NextProcByte = NumProcBytes + NextProcByte0,
+            !ProcLayoutInfo ^ pli_next_proc_byte := NextProcByte,
+
+            ProcBytesSlotName = layout_slot(proc_body_bytecodes_array,
+                ProcByteSlot),
+            MaybeProcBytesSlotName = yes(ProcBytesSlotName)
+        ;
+            (
+                MaybeDeepProfInfo = yes(DeepProfInfo),
+                ProcStaticInfo0 = !.ProcLayoutInfo ^ pli_proc_statics,
+                construct_proc_static_layout(DeepProfInfo, ProcStaticSlotName,
+                    ProcStaticInfo0, ProcStaticInfo),
+                !ProcLayoutInfo ^ pli_proc_statics := ProcStaticInfo,
+                MaybeProcStaticSlotName = yes(ProcStaticSlotName)
         ;
-            ProcBytes = []
+                MaybeDeepProfInfo = no,
+                MaybeProcStaticSlotName = no
+            ),
+            MaybeProcBytesSlotName = no
         ),
         module_info_get_name(ModuleInfo, ModuleName),
-        ModuleCommonLayout = module_common_layout(ModuleName),
-        More = proc_id_and_more(MaybeProcStatic, MaybeExecTrace,
-            ProcBytes, ModuleCommonLayout)
+        ModuleCommonLayoutName = module_common_layout(ModuleName),
+        More = proc_id_and_more(MaybeProcStaticSlotName,
+            MaybeExecTraceSlotName, MaybeProcBytesSlotName,
+            ModuleCommonLayoutName)
     ),
+
     ProcLayout = proc_layout_data(RttiProcLabel, Traversal, More),
-    LayoutName = proc_layout(RttiProcLabel, Kind),
-    add_proc_layout_data(EntryLabel, LayoutName, ProcLayout, !Info),
+
+    RevProcLayouts0 = !.ProcLayoutInfo ^ pli_rev_proc_layouts,
+    RevProcLayouts = [ProcLayout | RevProcLayouts0],
+    !ProcLayoutInfo ^ pli_rev_proc_layouts := RevProcLayouts,
+
+    RevProcLayoutNames0 = !.ProcLayoutInfo ^ pli_rev_proc_layout_names,
+    RevProcLayoutNames = [ProcLayoutName | RevProcLayoutNames0],
+    !ProcLayoutInfo ^ pli_rev_proc_layout_names := RevProcLayoutNames,
+
+    LabelToLayoutMap0 = !.ProcLayoutInfo ^ pli_p_label_to_layout_map,
+    map.det_insert(LabelToLayoutMap0, EntryLabel, layout_id(ProcLayoutName),
+        LabelToLayoutMap),
+    !ProcLayoutInfo ^ pli_p_label_to_layout_map := LabelToLayoutMap.
+
+:- pred construct_proc_traversal(stack_layout_params::in, label::in,
+    determinism::in, int::in, maybe(int)::in, proc_layout_stack_traversal::out)
+    is det.
+
+construct_proc_traversal(Params, EntryLabel, Detism, NumStackSlots,
+        MaybeSuccipLoc, Traversal) :-
     (
-        MaybeTableInfo = no
+        MaybeSuccipLoc = yes(Location),
+        ( determinism_components(Detism, _, at_most_many) ->
+            SuccipLval = framevar(Location)
     ;
-        MaybeTableInfo = yes(TableInfo),
-        get_layout_static_cell_info(!.Info, StaticCellInfo0),
-        make_table_data(RttiProcLabel, Kind, TableInfo, MaybeTableData,
-            StaticCellInfo0, StaticCellInfo),
-        set_layout_static_cell_info(StaticCellInfo, !Info),
-        add_table_data(MaybeTableData, !Info)
+            SuccipLval = stackvar(Location)
+        ),
+        represent_locn_as_int(locn_direct(SuccipLval), SuccipInt),
+        MaybeSuccipInt = yes(SuccipInt)
+    ;
+        MaybeSuccipLoc = no,
+        % Use a dummy location if there is no succip slot on the stack.
+        %
+        % This case can arise in two circumstances. First, procedures that
+        % use the nondet stack have a special slot for the succip, so the
+        % succip is not stored in a general purpose slot. Second, procedures
+        % that use the det stack but which do not call other procedures
+        % do not save the succip on the stack.
+        %
+        % The tracing system does not care about the location of the saved
+        % succip. The accurate garbage collector does. It should know from
+        % the determinism that the procedure uses the nondet stack, which
+        % takes care of the first possibility above. Procedures that do not
+        % call other procedures do not establish resumption points and thus
+        % agc is not interested in them. As far as stack dumps go, calling
+        % error counts as a call, so any procedure that may call error
+        % (directly or indirectly) will have its saved succip location
+        % recorded, so the stack dump will work.
+        %
+        % Future uses of stack layouts will have to have similar constraints.
+        MaybeSuccipInt = no
+    ),
+    StaticCodeAddr = Params ^ slp_static_code_addresses,
+    (
+        StaticCodeAddr = yes,
+        MaybeEntryLabel = yes(EntryLabel)
+    ;
+        StaticCodeAddr = no,
+        MaybeEntryLabel = no
+    ),
+    Traversal = proc_layout_stack_traversal(MaybeEntryLabel,
+        MaybeSuccipInt, NumStackSlots, Detism).
+
+:- type proc_layouts_info
+    --->    proc_layouts_info(
+                pli_proc_statics            :: proc_statics_info,
+                pli_exec_traces             :: exec_traces_info,
+
+                pli_next_proc_byte          :: int,
+                pli_rev_proc_bytes          :: list(int),
+
+                % The list of proc_layouts in the module.
+                pli_rev_proc_layouts        :: list(proc_layout_data),
+                pli_rev_proc_layout_names   :: list(layout_name),
+
+                % This maps each proc label with a layout
+                % to the id of its layout structure.
+                pli_p_label_to_layout_map   :: map(label, data_id)
+            ).
+
+:- func init_proc_layouts_info = proc_layouts_info.
+
+init_proc_layouts_info = Info :-
+    ProcStaticInfo = init_proc_statics_info,
+    ExecTraceInfo = init_exec_traces_info,
+    Info = proc_layouts_info(ProcStaticInfo, ExecTraceInfo,
+        0, [], [], [], map.init).
+
+%---------------------------------------------------------------------------%
+%
+% Construct proc static structures.
+%
+
+:- pred construct_proc_static_layout(proc_deep_prof_info::in,
+    layout_slot_name::out,
+    proc_statics_info::in, proc_statics_info::out) is det.
+
+construct_proc_static_layout(DeepProfInfo, ProcStaticSlotName,
+        !ProcStaticInfo) :-
+    DeepProfInfo = proc_deep_prof_info(HLDSProcStatic, DeepExcpSlots,
+        _OrigBody),
+    HLDSProcStatic = hlds_proc_static(FileName, LineNumber, IsInInterface,
+        CallSites, CoveragePoints),
+    (
+        CallSites = [],
+        MaybeCallSitesTuple = no
+    ;
+        CallSites = [_ | _],
+        list.reverse(CallSites, RevCallSites),
+        list.length(CallSites, NumCallSites),
+
+        RevAllCallSites0 = !.ProcStaticInfo ^ psi_rev_call_sites,
+        RevAllCallSites = RevCallSites ++ RevAllCallSites0,
+        !ProcStaticInfo ^ psi_rev_call_sites := RevAllCallSites,
+
+        NextCallSite0 = !.ProcStaticInfo ^ psi_next_call_site,
+        CallSiteSlot = NextCallSite0,
+        NextCallSite = NextCallSite0 + NumCallSites,
+        !ProcStaticInfo ^ psi_next_call_site := NextCallSite,
+
+        MaybeCallSitesTuple = yes({CallSiteSlot, NumCallSites})
+    ),
+    (
+        CoveragePoints = [],
+        MaybeCoveragePointsTuple = no
+    ;
+        CoveragePoints = [_ | _],
+        list.reverse(CoveragePoints, RevCoveragePoints),
+        list.length(CoveragePoints, NumCoveragePoints),
+
+        RevAllCoveragePoints0 = !.ProcStaticInfo ^ psi_rev_coverage_points,
+        RevAllCoveragePoints = RevCoveragePoints ++ RevAllCoveragePoints0,
+        !ProcStaticInfo ^ psi_rev_coverage_points := RevAllCoveragePoints,
+
+        NextCoveragePoint0 = !.ProcStaticInfo ^ psi_next_coverage_point,
+        CoveragePointSlot = NextCoveragePoint0,
+        NextCoveragePoint = NextCoveragePoint0 + NumCoveragePoints,
+        !ProcStaticInfo ^ psi_next_coverage_point := NextCoveragePoint,
+
+        MaybeCoveragePointsTuple = yes({CoveragePointSlot, NumCoveragePoints})
+    ),
+
+    ProcStatic = proc_layout_proc_static(FileName, LineNumber, IsInInterface,
+        DeepExcpSlots, MaybeCallSitesTuple, MaybeCoveragePointsTuple),
+
+    RevProcStatics0 = !.ProcStaticInfo ^ psi_rev_proc_statics,
+    RevProcStatics = [ProcStatic | RevProcStatics0],
+    !ProcStaticInfo ^ psi_rev_proc_statics := RevProcStatics,
+
+    ProcStaticCounter0 = !.ProcStaticInfo ^ psi_next_proc_static,
+    counter.allocate(ProcStaticSlot, ProcStaticCounter0, ProcStaticCounter),
+    ProcStaticSlotName = layout_slot(proc_static_array, ProcStaticSlot),
+    !ProcStaticInfo ^ psi_next_proc_static := ProcStaticCounter.
+
+%---------------------------------------------------------------------------%
+
+:- type proc_statics_info
+    --->    proc_statics_info(
+                % The arrays that hold (components of) proc static structures.
+                psi_next_call_site          :: int,
+                psi_next_coverage_point     :: int,
+                psi_next_proc_static        :: counter,
+
+                psi_rev_call_sites          :: list(call_site_static_data),
+                psi_rev_coverage_points     :: list(coverage_point_info),
+                psi_rev_proc_statics        :: list(proc_layout_proc_static)
     ).
 
-:- pred construct_trace_layout(rtti_proc_label::in,
-    eval_method::in, trace_level::in, maybe(label)::in, int::in,
+:- func init_proc_statics_info = proc_statics_info.
+
+init_proc_statics_info = Info :-
+    Info = proc_statics_info(0, 0, counter.init(0), [], [], []).
+
+%---------------------------------------------------------------------------%
+%
+% Construct exec trace structures.
+%
+
+:- pred construct_exec_trace_layout(stack_layout_params::in,
+    rtti_proc_label::in, eval_method::in, trace_level::in, maybe(label)::in,
+    maybe(layout_slot_name)::in, int::in,
     list(prog_var)::in, list(mer_mode)::in,
     trace_slot_info::in, prog_varset::in, vartypes::in,
     maybe(proc_layout_table_info)::in, bool::in, var_num_map::in,
-    list(internal_label_info)::in, proc_layout_exec_trace::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-construct_trace_layout(RttiProcLabel, EvalMethod, EffTraceLevel,
-        MaybeCallLabel, MaxTraceReg, HeadVars, ArgModes, TraceSlotInfo,
-        _VarSet, VarTypes, MaybeTableInfo, NeedsAllNames, VarNumMap,
-        InternalLabelInfos, ExecTrace, !Info) :-
+    list(internal_label_info)::in, layout_slot_name::out,
+    label_layouts_info::in,
+    string_table::in, string_table::out,
+    exec_traces_info::in, exec_traces_info::out) is det.
+
+construct_exec_trace_layout(Params, RttiProcLabel, EvalMethod,
+        EffTraceLevel, MaybeCallLabel, MaybeTableSlotName, MaxTraceReg,
+        HeadVars, ArgModes, TraceSlotInfo, _VarSet, VarTypes, MaybeTableInfo,
+        NeedsAllNames, VarNumMap, InternalLabelInfos, ExecTraceName,
+        LabelLayoutInfo, !StringTable, !ExecTraceInfo) :-
     collect_event_data_addrs(InternalLabelInfos,
         [], RevInterfaceEventLayoutNames, [], RevInternalEventLayoutNames),
     list.reverse(RevInterfaceEventLayoutNames, InterfaceEventLayoutNames),
     list.reverse(RevInternalEventLayoutNames, InternalEventLayoutNames),
     construct_var_name_vector(VarNumMap,
-        NeedsAllNames, MaxVarNum, VarNameVector, !Info),
+        NeedsAllNames, MaxVarNum, VarNameVector, !StringTable),
     list.map(convert_var_to_int(VarNumMap), HeadVars, HeadVarNumVector),
     TraceSlotInfo = trace_slot_info(MaybeFromFullSlot, MaybeIoSeqSlot,
         MaybeTrailSlots, MaybeMaxfrSlot, MaybeCallTableSlot, MaybeTailRecSlot),
-    ModuleInfo = !.Info ^ sli_module_info,
+    ModuleInfo = Params ^ slp_module_info,
     (
         MaybeCallLabel = yes(CallLabel),
-        map.lookup(!.Info ^ sli_i_label_to_layout_map, CallLabel,
+        map.lookup(LabelLayoutInfo ^ lli_i_label_to_layout_map, CallLabel,
             CallLabelSlotName),
         MaybeCallLabelSlotName = yes(CallLabelSlotName)
     ;
@@ -694,28 +904,192 @@
     ),
     (
         MaybeTableInfo = no,
-        MaybeTableDataAddr = no
+        MaybeTable = no
     ;
         MaybeTableInfo = yes(TableInfo),
         (
             TableInfo = proc_table_io_decl(_),
-            MaybeTableDataAddr = yes(layout_addr(table_io_decl(RttiProcLabel)))
+            (
+                MaybeTableSlotName = yes(TableSlotName),
+                MaybeTable = yes(data_or_slot_is_slot(TableSlotName))
+            ;
+                MaybeTableSlotName = no,
+                unexpected(this_file,
+                    "construct_exec_trace_layout: MaybeTableSlotName = no")
+            )
         ;
             TableInfo = proc_table_struct(_),
-            module_info_get_name(ModuleInfo, ModuleName),
+            expect(unify(MaybeTableSlotName, no), this_file,
+                "construct_exec_trace_layout: MaybeTableSlotName != no"),
             ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
-            MaybeTableDataAddr = yes(data_addr(ModuleName,
-                proc_tabling_ref(ProcLabel, tabling_info)))
+            TableDataId = proc_tabling_data_id(ProcLabel, tabling_info),
+            MaybeTable = yes(data_or_slot_is_data(TableDataId))
         )
     ),
+
+    RevEventLayouts0 = !.ExecTraceInfo ^ eti_rev_proc_event_layouts,
+    ProcEventLayouts = InterfaceEventLayoutNames ++ InternalEventLayoutNames,
+    list.reverse(ProcEventLayouts, RevProcEventLayouts),
+    RevEventLayouts = RevProcEventLayouts ++ RevEventLayouts0,
+    !ExecTraceInfo ^ eti_rev_proc_event_layouts := RevEventLayouts,
+
+    NextEventLayout0 = !.ExecTraceInfo ^ eti_next_proc_event_layout,
+    EventLayoutsSlot = NextEventLayout0,
+    list.length(ProcEventLayouts, NumProcEventLayouts),
+    NextEventLayout = NextEventLayout0 + NumProcEventLayouts,
+    !ExecTraceInfo ^ eti_next_proc_event_layout := NextEventLayout,
+    EventLayoutsSlotName = layout_slot(proc_event_layouts_array,
+        EventLayoutsSlot),
+
+    CompressArrays = Params ^ slp_compress_arrays,
+    (
+        HeadVarNumVector = [_ | _],
+        RevHeadVarNums0 = !.ExecTraceInfo ^ eti_rev_proc_head_var_nums,
+        NextHeadVarNum0 = !.ExecTraceInfo ^ eti_next_proc_head_var_num,
+        list.reverse(HeadVarNumVector, RevHeadVarNumVector),
+        list.length(HeadVarNumVector, NumHeadVars),
+        (
+            CompressArrays = yes,
+            find_sequence(RevHeadVarNumVector, RevHeadVarNums0,
+                0, OldHeadVarNumOffset)
+        ->
+            HeadVarNumSlot = NextHeadVarNum0 - OldHeadVarNumOffset - NumHeadVars
+        ;
+            RevHeadVarNums = RevHeadVarNumVector ++ RevHeadVarNums0,
+            !ExecTraceInfo ^ eti_rev_proc_head_var_nums := RevHeadVarNums,
+
+            HeadVarNumSlot = NextHeadVarNum0,
+            NextHeadVarNum = NextHeadVarNum0 + NumHeadVars,
+            !ExecTraceInfo ^ eti_next_proc_head_var_num := NextHeadVarNum
+        ),
+        HeadVarNumSlotName = layout_slot(proc_head_var_nums_array,
+            HeadVarNumSlot),
+        MaybeHeadVarsSlotName = yes(HeadVarNumSlotName)
+    ;
+        HeadVarNumVector = [],
+        MaybeHeadVarsSlotName = no,
+        NumHeadVars = 0
+    ),
+
+    (
+        VarNameVector = [_ | _],
+        RevVarNames0 = !.ExecTraceInfo ^ eti_rev_proc_var_names,
+        NextVarName0 = !.ExecTraceInfo ^ eti_next_proc_var_name,
+        list.reverse(VarNameVector, RevVarNameVector),
+        list.length(VarNameVector, NumVarNames),
+        (
+            CompressArrays = yes,
+            find_sequence(RevVarNameVector, RevVarNames0, 0, OldVarNameOffset)
+        ->
+            VarNameSlot = NextVarName0 - OldVarNameOffset - NumVarNames
+        ;
+            RevVarNames = RevVarNameVector ++ RevVarNames0,
+            !ExecTraceInfo ^ eti_rev_proc_var_names := RevVarNames,
+
+            VarNameSlot = NextVarName0,
+            NextVarName = NextVarName0 + NumVarNames,
+            !ExecTraceInfo ^ eti_next_proc_var_name := NextVarName
+        ),
+        VarNameSlotName = layout_slot(proc_var_names_array, VarNameSlot),
+        MaybeVarNamesSlotName = yes(VarNameSlotName)
+    ;
+        VarNameVector = [],
+        MaybeVarNamesSlotName = no
+    ),
+
     encode_exec_trace_flags(ModuleInfo, HeadVars, ArgModes, VarTypes,
         0, Flags),
     ExecTrace = proc_layout_exec_trace(MaybeCallLabelSlotName,
-        InterfaceEventLayoutNames, InternalEventLayoutNames,
-        MaybeTableDataAddr, HeadVarNumVector, VarNameVector,
+        EventLayoutsSlotName, NumProcEventLayouts, MaybeTable,
+        MaybeHeadVarsSlotName, NumHeadVars, MaybeVarNamesSlotName,
         MaxVarNum, MaxTraceReg, MaybeFromFullSlot, MaybeIoSeqSlot,
         MaybeTrailSlots, MaybeMaxfrSlot, EvalMethod,
-        MaybeCallTableSlot, MaybeTailRecSlot, EffTraceLevel, Flags).
+        MaybeCallTableSlot, MaybeTailRecSlot, EffTraceLevel, Flags),
+
+    RevExecTraces0 = !.ExecTraceInfo ^ eti_rev_exec_traces,
+    RevExecTraces = [ExecTrace | RevExecTraces0],
+    !ExecTraceInfo ^ eti_rev_exec_traces := RevExecTraces,
+
+    ExecTraceCounter0 = !.ExecTraceInfo ^ eti_next_exec_trace,
+    counter.allocate(ExecTraceSlot, ExecTraceCounter0, ExecTraceCounter),
+    ExecTraceName = layout_slot(proc_exec_trace_array, ExecTraceSlot),
+    !ExecTraceInfo ^ eti_next_exec_trace := ExecTraceCounter.
+
+%---------------------------------------------------------------------------%
+
+:- pred construct_exec_trace_table_data(pred_proc_id::in, layout_name::in,
+    proc_layout_table_info::in, maybe(layout_slot_name)::out,
+    static_cell_info::in, static_cell_info::out,
+    exec_traces_info::in, exec_traces_info::out) is det.
+
+construct_exec_trace_table_data(PredProcId, ProcLayoutName, TableInfo,
+        MaybeTableSlotName, !StaticCellInfo, !ExecTraceInfo) :-
+    (
+        TableInfo = proc_table_io_decl(TableIOInfo),
+        TableIOInfo = proc_table_io_info(TableArgInfos),
+        convert_table_arg_info(TableArgInfos, NumPTIs, PTIVectorRval,
+            TVarVectorRval, !StaticCellInfo),
+
+        TableIoDeclData = table_io_decl_data(ProcLayoutName,
+            NumPTIs, PTIVectorRval, TVarVectorRval),
+
+        RevTableIoDeclDatas0 = !.ExecTraceInfo ^ eti_rev_table_io_decl_datas,
+        RevTableIoDeclDatas = [TableIoDeclData | RevTableIoDeclDatas0],
+        !ExecTraceInfo ^ eti_rev_table_io_decl_datas := RevTableIoDeclDatas,
+
+        TableDataCounter0 = !.ExecTraceInfo ^ eti_next_table_io_decl_data,
+        counter.allocate(Slot, TableDataCounter0, TableDataCounter),
+        !ExecTraceInfo ^ eti_next_table_io_decl_data := TableDataCounter,
+
+        TableDataSlotName = layout_slot(proc_table_io_decl_array, Slot),
+        MaybeTableSlotName = yes(TableDataSlotName),
+
+        TableIoDeclMap0 = !.ExecTraceInfo ^ eti_table_io_decl_map,
+        map.det_insert(TableIoDeclMap0, PredProcId, TableDataSlotName,
+            TableIoDeclMap),
+        !ExecTraceInfo ^ eti_table_io_decl_map := TableIoDeclMap
+    ;
+        TableInfo = proc_table_struct(_TableStructInfo),
+        % This structure is generated by add_tabling_info_struct in proc_gen.m.
+        MaybeTableSlotName = no
+    ).
+
+convert_table_arg_info(TableArgInfos, NumPTIs,
+        PTIVectorRval, TVarVectorRval, !StaticCellInfo) :-
+    TableArgInfos = table_arg_infos(Args, TVarSlotMap),
+    list.length(Args, NumPTIs),
+    list.map_foldl(construct_table_arg_pti_rval, Args, PTIRvalsTypes,
+        !StaticCellInfo),
+    add_scalar_static_cell(PTIRvalsTypes, PTIVectorAddr, !StaticCellInfo),
+    PTIVectorRval = const(llconst_data_addr(PTIVectorAddr, no)),
+    map.map_values_only(convert_slot_to_locn_map, TVarSlotMap, TVarLocnMap),
+    construct_tvar_vector(TVarLocnMap, TVarVectorRval, !StaticCellInfo).
+
+:- pred convert_slot_to_locn_map(table_locn::in, set(layout_locn)::out) is det.
+
+convert_slot_to_locn_map(SlotLocn, LvalLocns) :-
+    (
+        SlotLocn = table_locn_direct(SlotNum),
+        LvalLocn = locn_direct(reg(reg_r, SlotNum))
+    ;
+        SlotLocn = table_locn_indirect(SlotNum, Offset),
+        LvalLocn = locn_indirect(reg(reg_r, SlotNum), Offset)
+    ),
+    LvalLocns = set.make_singleton_set(LvalLocn).
+
+:- pred construct_table_arg_pti_rval(
+    table_arg_info::in, pair(rval, llds_type)::out,
+    static_cell_info::in, static_cell_info::out) is det.
+
+construct_table_arg_pti_rval(ClosureArg, ArgRval - ArgRvalType,
+        !StaticCellInfo) :-
+    ClosureArg = table_arg_info(_, _, _, Type),
+    ExistQTvars = [],
+    NumUnivQTvars = -1,
+    ll_pseudo_type_info.construct_typed_llds_pseudo_type_info(Type,
+        NumUnivQTvars, ExistQTvars, !StaticCellInfo, ArgRval, ArgRvalType).
+
+%---------------------------------------------------------------------------%
 
 :- pred collect_event_data_addrs(list(internal_label_info)::in,
     list(layout_slot_name)::in, list(layout_slot_name)::out,
@@ -763,6 +1137,8 @@
     ),
     collect_event_data_addrs(Infos, !RevInterfaces, !RevInternals).
 
+%---------------------------------------------------------------------------%
+
 :- pred encode_exec_trace_flags(module_info::in, list(prog_var)::in,
     list(mer_mode)::in, vartypes::in, int::in, int::out) is det.
 
@@ -776,12 +1152,14 @@
         true
     ).
 
+%---------------------------------------------------------------------------%
+
 :- pred construct_var_name_vector(var_num_map::in,
     bool::in, int::out, list(int)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
 construct_var_name_vector(VarNumMap, NeedsAllNames, MaxVarNum, Offsets,
-        !Info) :-
+        !StringTable) :-
     map.values(VarNumMap, VarNames0),
     (
         NeedsAllNames = yes,
@@ -794,7 +1172,7 @@
     ( SortedVarNames = [FirstVarNum - _ | _] ->
         MaxVarNum0 = FirstVarNum,
         construct_var_name_rvals(SortedVarNames, 1, MaxVarNum0, MaxVarNum,
-            Offsets, !Info)
+            Offsets, !StringTable)
     ;
         % Since variable numbers start at 1, MaxVarNum = 0 implies
         % an empty array.
@@ -809,13 +1187,13 @@
 
 :- pred construct_var_name_rvals(assoc_list(int, string)::in,
     int::in, int::in, int::out, list(int)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    string_table::in, string_table::out) is det.
 
-construct_var_name_rvals([], _CurNum, MaxNum, MaxNum, [], !Info).
+construct_var_name_rvals([], _CurNum, MaxNum, MaxNum, [], !StringTable).
 construct_var_name_rvals([Var - Name | VarNamesTail], CurNum,
-        !MaxNum, [Offset | OffsetsTail], !Info) :-
+        !MaxNum, [Offset | OffsetsTail], !StringTable) :-
     ( Var = CurNum ->
-        lookup_string_in_table(Name, Offset, !Info),
+        lookup_string_in_table(Name, Offset, !StringTable),
         !:MaxNum = Var,
         VarNames = VarNamesTail
     ;
@@ -823,7 +1201,7 @@
         VarNames = [Var - Name | VarNamesTail]
     ),
     construct_var_name_rvals(VarNames, CurNum + 1,
-        !MaxNum, OffsetsTail, !Info).
+        !MaxNum, OffsetsTail, !StringTable).
 
 %---------------------------------------------------------------------------%
 
@@ -932,16 +1310,49 @@
 
 %---------------------------------------------------------------------------%
 
+:- type exec_traces_info
+    --->    exec_traces_info(
+                % The arrays that hold (components of) exec trace structures.
+                eti_next_proc_head_var_num  :: int,
+                eti_next_proc_var_name      :: int,
+                eti_next_proc_event_layout  :: int,
+                eti_next_table_io_decl_data :: counter,
+                eti_next_exec_trace         :: counter,
+
+                eti_rev_proc_head_var_nums  :: list(int),
+                eti_rev_proc_var_names      :: list(int),
+                eti_rev_proc_event_layouts  :: list(layout_slot_name),
+                eti_rev_table_io_decl_datas :: list(table_io_decl_data),
+                eti_rev_exec_traces         :: list(proc_layout_exec_trace),
+
+                eti_table_io_decl_map       :: map(pred_proc_id,
+                                                layout_slot_name)
+            ).
+
+:- func init_exec_traces_info = exec_traces_info.
+
+init_exec_traces_info = Info :-
+    Info = exec_traces_info(0, 0, 0, counter.init(0), counter.init(0),
+        [], [], [], [], [], map.init).
+
+%---------------------------------------------------------------------------%
+%
+% Construct label layout structures.
+%
+
     % Construct the layout describing a single internal label
     % for accurate GC and/or execution tracing.
     %
-:- pred construct_internal_layout(proc_label::in,
-    layout_name::in, var_num_map::in, pair(int, internal_layout_info)::in,
-    internal_label_info::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+:- pred construct_internal_layout(stack_layout_params::in,
+    proc_label::in, layout_name::in, var_num_map::in,
+    pair(int, internal_layout_info)::in, internal_label_info::out,
+    string_table::in, string_table::out,
+    static_cell_info::in, static_cell_info::out,
+    label_layouts_info::in, label_layouts_info::out) is det.
 
-construct_internal_layout(ProcLabel, ProcLayoutName, VarNumMap,
-        LabelNum - Internal, LabelLayout, !Info) :-
+construct_internal_layout(Params, ProcLabel, ProcLayoutName, VarNumMap,
+        LabelNum - Internal, LabelLayout,
+        !StringTable, !StaticCellInfo, !LabelLayoutInfo) :-
     Internal = internal_layout_info(Trace, Resume, Return),
     (
         Trace = no,
@@ -967,7 +1378,7 @@
         MaybePort = yes(Port),
         MaybeIsHidden = yes(IsHidden),
         GoalPathStr = goal_path_to_string(GoalPath),
-        lookup_string_in_table(GoalPathStr, GoalPathNum, !Info),
+        lookup_string_in_table(GoalPathStr, GoalPathNum, !StringTable),
         MaybeGoalPath = yes(GoalPathNum)
     ;
         Trace = no,
@@ -982,7 +1393,7 @@
         ReturnInfo = return_layout_info(TargetsContexts, _),
         ( find_valid_return_context(TargetsContexts, _, _, GoalPath) ->
             GoalPathStr = goal_path_to_string(GoalPath),
-            lookup_string_in_table(GoalPathStr, GoalPathNum, !Info),
+            lookup_string_in_table(GoalPathStr, GoalPathNum, !StringTable),
             MaybeGoalPath = yes(GoalPathNum)
         ;
             % If tracing is enabled, then exactly one of the calls for which
@@ -1002,7 +1413,7 @@
         Return = yes(_),
         unexpected(this_file, "label has both trace and return layout info")
     ),
-    get_agc_stack_layout(!.Info, AgcStackLayout),
+    AgcStackLayout = Params ^ slp_agc_stack_layout,
     (
         Return = no,
         set.init(ReturnLiveVarSet),
@@ -1032,8 +1443,7 @@
         Resume = no,
         Return = no
     ->
-        MaybeVarInfo = no,
-        LabelVars = label_has_no_var_info
+        MaybeVarInfo = no_var_info
     ;
         % XXX Ignore differences in insts inside layout_var_infos.
         set.union(TraceLiveVarSet, ResumeLiveVarSet, LiveVarSet0),
@@ -1041,58 +1451,54 @@
         map.union(set.intersect, TraceTypeVarMap, ResumeTypeVarMap,
             TypeVarMap0),
         map.union(set.intersect, TypeVarMap0, ReturnTypeVarMap, TypeVarMap),
-        construct_livelval_rvals(LiveVarSet, VarNumMap, TypeVarMap,
-            EncodedLength, LiveValRval, NamesRval, TypeParamRval, !Info),
-        VarInfo = label_var_info(EncodedLength, LiveValRval, NamesRval,
-            TypeParamRval),
-        MaybeVarInfo = yes(VarInfo),
-        LabelVars = label_has_var_info
+        construct_label_var_info(Params, LiveVarSet, VarNumMap, TypeVarMap,
+            MaybeVarInfo, !StaticCellInfo, !LabelLayoutInfo)
     ),
     (
         MaybeUserInfo = no,
         MaybeUserDataSlot = no
     ;
         MaybeUserInfo = yes(UserInfo),
-        set_has_user_event(yes, !Info),
         UserInfo = user_event_info(UserEventNumber, Attributes),
-        construct_user_data_array(VarNumMap, Attributes,
-            UserLocnsArray, UserAttrMaybeVarNums, !Info),
+        construct_user_data_array(Params, VarNumMap, Attributes,
+            UserLocnsArray, UserAttrMaybeVarNums, !StaticCellInfo),
 
-        get_layout_static_cell_info(!.Info, StaticCellInfo0),
         add_scalar_static_cell(UserLocnsArray, UserLocnsDataAddr,
-            StaticCellInfo0, StaticCellInfo),
-        set_layout_static_cell_info(StaticCellInfo, !Info),
+            !StaticCellInfo),
         UserLocnsRval = const(llconst_data_addr(UserLocnsDataAddr, no)),
 
         list.length(UserAttrMaybeVarNums, NumVarNums),
-        VarNumSlotNum0 = !.Info ^ sli_next_user_event_var_num,
+        VarNumSlotNum0 = !.LabelLayoutInfo ^ lli_next_user_event_var_num,
         VarNumSlotNum = VarNumSlotNum0 + NumVarNums,
-        !Info ^ sli_next_user_event_var_num := VarNumSlotNum,
+        !LabelLayoutInfo ^ lli_next_user_event_var_num := VarNumSlotNum,
         UserAttrVarNumsSlot = layout_slot(user_event_var_nums_array,
             VarNumSlotNum0),
 
-        VarNums0 = !.Info ^ sli_user_event_var_nums,
+        VarNums0 = !.LabelLayoutInfo ^ lli_user_event_var_nums,
         VarNums = VarNums0 ++ cord.from_list(UserAttrMaybeVarNums),
-        !Info ^ sli_user_event_var_nums := VarNums,
+        !LabelLayoutInfo ^ lli_user_event_var_nums := VarNums,
 
-        UserEventCounter0 = !.Info ^ sli_next_user_event,
+        UserEventCounter0 = !.LabelLayoutInfo ^ lli_next_user_event,
         counter.allocate(UserEventSlotNum,
             UserEventCounter0, UserEventCounter),
-        !Info ^ sli_next_user_event := UserEventCounter,
+        !LabelLayoutInfo ^ lli_next_user_event := UserEventCounter,
         UserEventSlot = layout_slot(user_event_layout_array, UserEventSlotNum),
 
         UserData = user_event_data(UserEventNumber, UserLocnsRval,
             UserAttrVarNumsSlot),
-        UserEvents0 = !.Info ^ sli_user_events,
+        UserEvents0 = !.LabelLayoutInfo ^ lli_user_events,
         UserEvents = UserEvents0 ++ cord.singleton(UserData),
-        !Info ^ sli_user_events := UserEvents,
+        !LabelLayoutInfo ^ lli_user_events := UserEvents,
 
         MaybeUserDataSlot = yes(UserEventSlot)
     ),
 
     (
         Trace = yes(_),
-        allocate_label_number(LabelNumber0, !Info),
+        LabelNumCounter0 = !.LabelLayoutInfo ^ lli_label_counter,
+        counter.allocate(LabelNumber0, LabelNumCounter0, LabelNumCounter),
+        !LabelLayoutInfo ^ lli_label_counter := LabelNumCounter,
+
         % MR_ml_label_exec_count[0] is never written out; it is reserved for
         % cases like this, for labels without events, and for handwritten
         % labels.
@@ -1110,81 +1516,109 @@
         MaybePort, MaybeIsHidden, LabelNumber, MaybeGoalPath,
         MaybeUserDataSlot),
     (
-        MaybeVarInfo = yes(LayoutVarInfo),
-        VarsLayout = label_layout_vars(BasicLayout, LayoutVarInfo),
-        add_vars_internal_layout_data(Label, VarsLayout, Slot, !Info)
-    ;
-        MaybeVarInfo = no,
+        MaybeVarInfo = no_var_info,
+        LabelVars = label_has_no_var_info,
         NoVarsLayout = label_layout_no_vars(BasicLayout),
-        add_no_vars_internal_layout_data(Label, NoVarsLayout, Slot, !Info)
+        add_no_vars_internal_layout_data(Label, NoVarsLayout, Slot,
+            !LabelLayoutInfo)
+    ;
+        MaybeVarInfo = short_var_info(SLayoutVarInfo),
+        LabelVars = label_has_short_var_info,
+        SVarsLayout = label_layout_short_vars(BasicLayout, SLayoutVarInfo),
+        add_short_vars_internal_layout_data(Label, SVarsLayout, Slot,
+            !LabelLayoutInfo)
+    ;
+        MaybeVarInfo = long_var_info(LLayoutVarInfo),
+        LabelVars = label_has_long_var_info,
+        LVarsLayout = label_layout_long_vars(BasicLayout, LLayoutVarInfo),
+        add_long_vars_internal_layout_data(Label, LVarsLayout, Slot,
+            !LabelLayoutInfo)
     ),
     LabelLayout = internal_label_info(ProcLabel, LabelNum, LabelVars, Slot,
         Internal).
 
-:- pred construct_user_data_array(var_num_map::in,
+:- pred add_no_vars_internal_layout_data(label::in, label_layout_no_vars::in,
+    int::out, label_layouts_info::in, label_layouts_info::out) is det.
+
+add_no_vars_internal_layout_data(Label, Layout, Slot, !LLI) :-
+    RevLayouts0 = !.LLI ^ lli_rev_no_var_label_layouts,
+    RevLayouts = [Layout | RevLayouts0],
+
+    Counter0 = !.LLI ^ lli_next_no_var_label_layout,
+    counter.allocate(Slot, Counter0, Counter),
+    LayoutName = layout_slot(label_layout_array(label_has_no_var_info), Slot),
+
+    LabelToLayoutMap0 = !.LLI ^ lli_i_label_to_layout_map,
+    map.det_insert(LabelToLayoutMap0, Label, LayoutName, LabelToLayoutMap),
+
+    !LLI ^ lli_rev_no_var_label_layouts := RevLayouts,
+    !LLI ^ lli_next_no_var_label_layout := Counter,
+    !LLI ^ lli_i_label_to_layout_map := LabelToLayoutMap.
+
+:- pred add_short_vars_internal_layout_data(label::in,
+    label_layout_short_vars::in, int::out,
+    label_layouts_info::in, label_layouts_info::out) is det.
+
+add_short_vars_internal_layout_data(Label, Layout, Slot, !LLI) :-
+    RevLayouts0 = !.LLI ^ lli_rev_svar_label_layouts,
+    RevLayouts = [Layout | RevLayouts0],
+
+    Counter0 = !.LLI ^ lli_next_svar_label_layout,
+    counter.allocate(Slot, Counter0, Counter),
+    LayoutArray = label_layout_array(label_has_short_var_info),
+    LayoutName = layout_slot(LayoutArray, Slot),
+
+    LabelToLayoutMap0 = !.LLI ^ lli_i_label_to_layout_map,
+    map.det_insert(LabelToLayoutMap0, Label, LayoutName, LabelToLayoutMap),
+
+    !LLI ^ lli_rev_svar_label_layouts := RevLayouts,
+    !LLI ^ lli_next_svar_label_layout := Counter,
+    !LLI ^ lli_i_label_to_layout_map := LabelToLayoutMap.
+
+:- pred add_long_vars_internal_layout_data(label::in,
+    label_layout_long_vars::in, int::out,
+    label_layouts_info::in, label_layouts_info::out) is det.
+
+add_long_vars_internal_layout_data(Label, Layout, Slot, !LLI) :-
+    RevLayouts0 = !.LLI ^ lli_rev_lvar_label_layouts,
+    RevLayouts = [Layout | RevLayouts0],
+
+    Counter0 = !.LLI ^ lli_next_lvar_label_layout,
+    counter.allocate(Slot, Counter0, Counter),
+    LayoutArray = label_layout_array(label_has_long_var_info),
+    LayoutName = layout_slot(LayoutArray, Slot),
+
+    LabelToLayoutMap0 = !.LLI ^ lli_i_label_to_layout_map,
+    map.det_insert(LabelToLayoutMap0, Label, LayoutName, LabelToLayoutMap),
+
+    !LLI ^ lli_rev_lvar_label_layouts := RevLayouts,
+    !LLI ^ lli_next_lvar_label_layout := Counter,
+    !LLI ^ lli_i_label_to_layout_map := LabelToLayoutMap.
+
+:- pred construct_user_data_array(stack_layout_params::in, var_num_map::in,
     list(maybe(user_attribute))::in,
     assoc_list(rval, llds_type)::out, list(maybe(int))::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+    static_cell_info::in, static_cell_info::out) is det.
 
-construct_user_data_array(_, [], [], [], !Info).
-construct_user_data_array(VarNumMap, [MaybeAttr | MaybeAttrs],
+construct_user_data_array(_, _, [], [], [], !Info).
+construct_user_data_array(Params, VarNumMap, [MaybeAttr | MaybeAttrs],
         [LocnRvalAndType | LocnRvalAndTypes], [MaybeVarNum | MaybeVarNums],
-        !Info) :-
+        !StaticCellInfo) :-
     (
         MaybeAttr = yes(Attr),
         Attr = user_attribute(Locn, Var),
-        represent_locn_or_const_as_int_rval(Locn, LocnRval, LocnRvalType,
-            !Info),
+        represent_locn_or_const_as_int_rval(Params, Locn, LocnRval,
+            LocnRvalType, !StaticCellInfo),
         LocnRvalAndType = LocnRval - LocnRvalType,
         convert_var_to_int(VarNumMap, Var, VarNum),
-        MaybeVarNum = yes(VarNum)
-    ;
-        MaybeAttr = no,
-        LocnRvalAndType = const(llconst_int(0)) - lt_unsigned,
-        MaybeVarNum = no
-    ),
-    construct_user_data_array(VarNumMap, MaybeAttrs, LocnRvalAndTypes,
-        MaybeVarNums, !Info).
-
-%---------------------------------------------------------------------------%
-
-:- pred construct_livelval_rvals(set(layout_var_info)::in,
-    var_num_map::in, map(tvar, set(layout_locn))::in, int::out,
-    rval::out, rval::out, rval::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-construct_livelval_rvals(LiveLvalSet, VarNumMap, TVarLocnMap,
-        EncodedLength, LiveValRval, NamesRval, TypeParamRval, !Info) :-
-    set.to_sorted_list(LiveLvalSet, LiveLvals),
-    sort_livevals(LiveLvals, SortedLiveLvals),
-    construct_liveval_arrays(SortedLiveLvals, VarNumMap,
-        EncodedLength, LiveValRval, NamesRval, !Info),
-    StaticCellInfo0 = !.Info ^ sli_static_cell_info,
-    construct_tvar_vector(TVarLocnMap, TypeParamRval,
-        StaticCellInfo0, StaticCellInfo),
-    !Info ^ sli_static_cell_info := StaticCellInfo.
-
-:- pred construct_tvar_vector(map(tvar, set(layout_locn))::in,
-    rval::out, static_cell_info::in, static_cell_info::out) is det.
-
-construct_tvar_vector(TVarLocnMap, TypeParamRval, !StaticCellInfo) :-
-    ( map.is_empty(TVarLocnMap) ->
-        TypeParamRval = const(llconst_int(0))
-    ;
-        construct_tvar_rvals(TVarLocnMap, Vector),
-        add_scalar_static_cell(Vector, DataAddr, !StaticCellInfo),
-        TypeParamRval = const(llconst_data_addr(DataAddr, no))
-    ).
-
-:- pred construct_tvar_rvals(map(tvar, set(layout_locn))::in,
-    assoc_list(rval, llds_type)::out) is det.
-
-construct_tvar_rvals(TVarLocnMap, Vector) :-
-    map.to_assoc_list(TVarLocnMap, TVarLocns),
-    construct_type_param_locn_vector(TVarLocns, 1, TypeParamLocs),
-    list.length(TypeParamLocs, TypeParamsLength),
-    LengthRval = const(llconst_int(TypeParamsLength)),
-    Vector = [LengthRval - lt_unsigned | TypeParamLocs].
+        MaybeVarNum = yes(VarNum)
+    ;
+        MaybeAttr = no,
+        LocnRvalAndType = const(llconst_int(0)) - lt_unsigned,
+        MaybeVarNum = no
+    ),
+    construct_user_data_array(Params, VarNumMap, MaybeAttrs,
+        LocnRvalAndTypes, MaybeVarNums, !StaticCellInfo).
 
 %---------------------------------------------------------------------------%
 
@@ -1246,7 +1680,7 @@
     ),
     list.sort(CompareVarInfos, NamedVarInfos0, NamedVarInfos),
     list.sort(CompareVarInfos, OtherInfos0, OtherInfos),
-    list.append(NamedVarInfos, OtherInfos, FinalInfos).
+    FinalInfos = NamedVarInfos ++ OtherInfos.
 
 :- pred get_name_from_live_value_type(live_value_type::in,
     string::out) is det.
@@ -1295,166 +1729,259 @@
 
 %---------------------------------------------------------------------------%
 
-:- type liveval_array_info
-    --->    live_array_info(
-                rval,       % Rval describing the location of a live value.
-                            % Always of llds type uint_least8 if the cell
-                            % is in the byte array, and unsigned if it
-                            % is in the int array.
-                rval,       % Rval describing the type of a live value.
-                llds_type,  % The llds type of the rval describing the type.
-                rval        % Rval describing the variable number of a
-                            % live value. Always of llds type uint_least16.
-                            % Contains zero if the live value is not
-                            % a variable. Contains the hightest possible
-                            % uint_least16 value if the variable number
+:- type liveval_array_slot
+    --->    liveval_array_slot(
+                % This rval is the pseudo_type_info for the type of the
+                % live value.
+                lai_type            :: rval,
+
+                % This is the variable number of a live value. Contains zero
+                % if the live value is not a variable, and contains the
+                % hightest possible uint_least16 value if the variable number
                             % does not fit in 16 bits.
+                lai_hlds_var_num    :: int,
+
+                % This describes the location of the live value as either
+                % a MR_LongLval or MR_ShortLval.
+                lai_locn_desc       :: int
             ).
 
-    % Construct a vector of (locn, live_value_type) pairs,
-    % and a corresponding vector of variable names.
-    %
-:- pred construct_liveval_arrays(list(layout_var_info)::in,
-    var_num_map::in, int::out, rval::out, rval::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
+:- func project_array_slot_pti(liveval_array_slot) = rval.
 
-construct_liveval_arrays(VarInfos, VarNumMap, EncodedLength,
-        TypeLocnVector, NumVector, !Info) :-
-    int.pow(2, short_count_bits, BytesLimit),
-    construct_liveval_array_infos(VarInfos, VarNumMap,
-        0, BytesLimit, IntArrayInfo, ByteArrayInfo, !Info),
+project_array_slot_pti(liveval_array_slot(PTI, _, _)) = PTI.
+
+:- func project_array_slot_hlds_var_num(liveval_array_slot) = int.
+
+project_array_slot_hlds_var_num(liveval_array_slot(_, VarNum, _)) = VarNum.
+
+:- func project_array_slot_locn(liveval_array_slot) = int.
+
+project_array_slot_locn(liveval_array_slot(_, _, Locn)) = Locn.
+
+%---------------------------------------------------------------------------%
+
+:- type maybe_var_info
+    --->    no_var_info
+    ;       short_var_info(label_short_var_info)
+    ;       long_var_info(label_long_var_info).
 
-    list.length(IntArrayInfo, IntArrayLength),
-    list.length(ByteArrayInfo, ByteArrayLength),
-    list.append(IntArrayInfo, ByteArrayInfo, AllArrayInfo),
-
-    EncodedLength = IntArrayLength << short_count_bits + ByteArrayLength,
-
-    SelectLocns = (pred(ArrayInfo::in, LocnRval::out) is det :-
-        ArrayInfo = live_array_info(LocnRval, _, _, _)
-    ),
-    SelectTypes = (pred(ArrayInfo::in, TypeRval - TypeType::out) is det :-
-        ArrayInfo = live_array_info(_, TypeRval, TypeType, _)
-    ),
-    AddRevNums = (pred(ArrayInfo::in, NumRvals0::in, NumRvals::out) is det :-
-        ArrayInfo = live_array_info(_, _, _, NumRval),
-        NumRvals = [NumRval | NumRvals0]
-    ),
-
-    list.map(SelectTypes, AllArrayInfo, AllTypeRvalsTypes),
-    list.map(SelectLocns, IntArrayInfo, IntLocns),
-    list.map(associate_type(lt_unsigned), IntLocns, IntLocnsTypes),
-    list.map(SelectLocns, ByteArrayInfo, ByteLocns),
-    list.map(associate_type(lt_uint_least8), ByteLocns, ByteLocnsTypes),
-    list.append(IntLocnsTypes, ByteLocnsTypes, AllLocnsTypes),
-    list.append(AllTypeRvalsTypes, AllLocnsTypes, TypeLocnVectorRvalsTypes),
-    get_layout_static_cell_info(!.Info, StaticCellInfo0),
-    add_scalar_static_cell(TypeLocnVectorRvalsTypes, TypeLocnVectorAddr,
-        StaticCellInfo0, StaticCellInfo1),
-    TypeLocnVector = const(llconst_data_addr(TypeLocnVectorAddr, no)),
-    set_layout_static_cell_info(StaticCellInfo1, !Info),
+:- pred construct_label_var_info(stack_layout_params::in,
+    set(layout_var_info)::in, var_num_map::in, map(tvar, set(layout_locn))::in,
+    maybe_var_info::out, static_cell_info::in, static_cell_info::out,
+    label_layouts_info::in, label_layouts_info::out) is det.
 
-    get_trace_stack_layout(!.Info, TraceStackLayout),
+construct_label_var_info(Params, VarInfoSet, VarNumMap, TVarLocnMap,
+        MaybeVarInfo, !StaticCellInfo, !LabelLayoutInfo) :-
+    construct_tvar_vector(TVarLocnMap, TypeParamsRval, !StaticCellInfo),
+
+    set.to_sorted_list(VarInfoSet, VarInfos0),
+    sort_livevals(VarInfos0, VarInfos),
+
+    int.pow(2, short_count_bits, BytesLimit),
+    ModuleInfo = Params ^ slp_module_info,
+    construct_liveval_array_slots(VarInfos, ModuleInfo, VarNumMap,
+        0, BytesLimit, LongArrayInfos, ShortArrayInfos, !StaticCellInfo),
+
+    AllArrayInfos = LongArrayInfos ++ ShortArrayInfos,
+    PTIs = list.map(project_array_slot_pti, AllArrayInfos),
+    HLDSVarNums = list.map(project_array_slot_hlds_var_num, AllArrayInfos),
+    ShortLocns = list.map(project_array_slot_locn, ShortArrayInfos),
+    LongLocns = list.map(project_array_slot_locn, LongArrayInfos),
+
+    list.length(PTIs, NumPTIs),
+    list.length(HLDSVarNums, NumHLDSVarNums),
+    list.length(ShortLocns, NumShortLocns),
+    list.length(LongLocns, NumLongLocns),
+    expect(unify(NumPTIs, NumHLDSVarNums), this_file,
+        "construct_liveval_arrays: NumPTIs != NumHLDSVarNums"),
+    expect(unify(NumPTIs, NumLongLocns + NumShortLocns), this_file,
+        "construct_liveval_arrays: NumPTIs != NumLongLocns + NumShortLocns"),
+
+    EncodedLength = NumLongLocns << short_count_bits + NumShortLocns,
+
+    % XXX As an optimization, instead of always adding PTIs, HLDSVarNums,
+    % ShortLocns and LongLocns to their respective arrays, we could see
+    % whether those arrays already contain the required sequences.
+
+    CompressArrays = Params ^ slp_compress_arrays,
+    ( NumPTIs > 0 ->
+        AllRevPTIs0 = !.LabelLayoutInfo ^ lli_rev_ptis,
+        NextPTISlot0 = !.LabelLayoutInfo ^ lli_next_pti,
+        list.reverse(PTIs, RevPTIs),
     (
-        TraceStackLayout = yes,
-        list.foldl(AddRevNums, AllArrayInfo, [], RevVarNumRvals),
-        list.reverse(RevVarNumRvals, VarNumRvals),
-        list.map(associate_type(lt_uint_least16), VarNumRvals,
-            VarNumRvalsTypes),
-        get_layout_static_cell_info(!.Info, StaticCellInfo2),
-        add_scalar_static_cell(VarNumRvalsTypes, NumVectorAddr,
-            StaticCellInfo2, StaticCellInfo),
-        set_layout_static_cell_info(StaticCellInfo, !Info),
-        NumVector = const(llconst_data_addr(NumVectorAddr, no))
+            CompressArrays = yes,
+            find_sequence(RevPTIs, AllRevPTIs0, 0, OldPTIOffset)
+        ->
+            PTISlot = NextPTISlot0 - OldPTIOffset - NumPTIs
     ;
-        TraceStackLayout = no,
-        NumVector = const(llconst_int(0))
-    ).
+            AllRevPTIs = RevPTIs ++ AllRevPTIs0,
+            !LabelLayoutInfo ^ lli_rev_ptis := AllRevPTIs,
 
-:- pred associate_type(llds_type::in, rval::in, pair(rval, llds_type)::out)
-    is det.
+            PTISlot = NextPTISlot0,
+            NextPTISlot = NextPTISlot0 + NumPTIs,
+            !LabelLayoutInfo ^ lli_next_pti := NextPTISlot
+        )
+    ;
+        PTISlot = -1
+    ),
+    % The garbage collector does not need HLDS variable numbers; only the
+    % debugger does.
+    (
+        NumHLDSVarNums > 0,
+        Params ^ slp_trace_stack_layout = yes
+    ->
+        AllRevHLDSVarNums0 = !.LabelLayoutInfo ^ lli_rev_hlds_var_nums,
+        NextHLDSVarNumSlot0 = !.LabelLayoutInfo ^ lli_next_hlds_var_num,
+        list.reverse(HLDSVarNums, RevHLDSVarNums),
+        (
+            CompressArrays = yes,
+            find_sequence(RevHLDSVarNums, AllRevHLDSVarNums0,
+                0, OldHLDSVarNumsOffset)
+        ->
+            HLDSVarNumSlot = NextHLDSVarNumSlot0 - OldHLDSVarNumsOffset -
+                NumHLDSVarNums
+        ;
+            AllRevHLDSVarNums = RevHLDSVarNums ++ AllRevHLDSVarNums0,
+            !LabelLayoutInfo ^ lli_rev_hlds_var_nums := AllRevHLDSVarNums,
+
+            HLDSVarNumSlot = NextHLDSVarNumSlot0,
+            NextHLDSVarNumSlot = NextHLDSVarNumSlot0 + NumHLDSVarNums,
+            !LabelLayoutInfo ^ lli_next_hlds_var_num := NextHLDSVarNumSlot
+        )
+    ;
+        HLDSVarNumSlot = -1
+    ),
+    ( NumShortLocns > 0 ->
+        AllRevShortLocns0 = !.LabelLayoutInfo ^ lli_rev_short_locns,
+        NextShortLocnSlot0 = !.LabelLayoutInfo ^ lli_next_short_locn,
+        list.reverse(ShortLocns, RevShortLocns),
+        (
+            CompressArrays = yes,
+            find_sequence(RevShortLocns, AllRevShortLocns0,
+                0, OldShortLocnsOffset)
+        ->
+            ShortLocnSlot = NextShortLocnSlot0 - OldShortLocnsOffset -
+                NumShortLocns
+        ;
+            AllRevShortLocns = RevShortLocns ++ AllRevShortLocns0,
+            !LabelLayoutInfo ^ lli_rev_short_locns := AllRevShortLocns,
+
+            ShortLocnSlot = NextShortLocnSlot0,
+            NextShortLocnSlot = NextShortLocnSlot0 + NumShortLocns,
+            !LabelLayoutInfo ^ lli_next_short_locn := NextShortLocnSlot
+        )
+    ;
+        ShortLocnSlot = -1
+    ),
+    ( NumLongLocns > 0 ->
+        AllRevLongLocns0 = !.LabelLayoutInfo ^ lli_rev_long_locns,
+        NextLongLocnSlot0 = !.LabelLayoutInfo ^ lli_next_long_locn,
+        list.reverse(LongLocns, RevLongLocns),
+        (
+            CompressArrays = yes,
+            find_sequence(RevLongLocns, AllRevLongLocns0,
+                0, OldLongLocnsOffset)
+        ->
+            LongLocnSlot = NextLongLocnSlot0 - OldLongLocnsOffset -
+                NumLongLocns
+        ;
+            AllRevLongLocns = RevLongLocns ++ AllRevLongLocns0,
+            !LabelLayoutInfo ^ lli_rev_long_locns := AllRevLongLocns,
+
+            LongLocnSlot = NextLongLocnSlot0,
+            NextLongLocnSlot = NextLongLocnSlot0 + NumLongLocns,
+            !LabelLayoutInfo ^ lli_next_long_locn := NextLongLocnSlot
+        ),
 
-associate_type(LldsType, Rval, Rval - LldsType).
+        LVarInfo = label_long_var_info(EncodedLength, TypeParamsRval,
+            PTISlot, HLDSVarNumSlot, ShortLocnSlot, LongLocnSlot),
+        MaybeVarInfo = long_var_info(LVarInfo)
+    ;
+        SVarInfo = label_short_var_info(EncodedLength, TypeParamsRval,
+            PTISlot, HLDSVarNumSlot, ShortLocnSlot),
+        MaybeVarInfo = short_var_info(SVarInfo)
+    ).
+
+:- pred construct_liveval_array_slots(list(layout_var_info)::in,
+    module_info::in, var_num_map::in, int::in, int::in,
+    list(liveval_array_slot)::out, list(liveval_array_slot)::out,
+    static_cell_info::in, static_cell_info::out) is det.
 
-:- pred construct_liveval_array_infos(list(layout_var_info)::in,
-    var_num_map::in, int::in, int::in,
-    list(liveval_array_info)::out, list(liveval_array_info)::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-construct_liveval_array_infos([], _, _, _, [], [], !Info).
-construct_liveval_array_infos([VarInfo | VarInfos], VarNumMap,
-        BytesSoFar, BytesLimit, IntVars, ByteVars, !Info) :-
+construct_liveval_array_slots([], _, _, _, _, [], [], !Info).
+construct_liveval_array_slots([VarInfo | VarInfos], ModuleInfo, VarNumMap,
+        BytesSoFar, BytesLimit, LongArraySlots, ShortArraySlots,
+        !StaticCellInfo) :-
     VarInfo = layout_var_info(Locn, LiveValueType, _),
-    represent_live_value_type(LiveValueType, TypeRval, TypeRvalType, !Info),
-    construct_liveval_num_rval(VarNumMap, VarInfo, VarNumRval, !Info),
+    represent_live_value_type_and_var_num(VarNumMap, LiveValueType,
+        TypeRval, VarNum, !StaticCellInfo),
     (
         LiveValueType = live_value_var(_, _, Type, _),
-        get_module_info(!.Info, ModuleInfo),
         check_dummy_type(ModuleInfo, Type) = is_dummy_type,
         % We want to preserve I/O states in registers.
         \+ (
             Locn = locn_direct(reg(_, _))
         )
     ->
-        unexpected(this_file, "construct_liveval_array_infos: " ++
+        unexpected(this_file, "construct_liveval_array_slots: " ++
             "unexpected reference to dummy value")
     ;
         BytesSoFar < BytesLimit,
-        represent_locn_as_byte(Locn, LocnByteRval)
+        represent_locn_as_byte(Locn, ShortLocn)
     ->
-        Var = live_array_info(LocnByteRval, TypeRval, TypeRvalType,
-            VarNumRval),
-        construct_liveval_array_infos(VarInfos, VarNumMap,
-            BytesSoFar + 1, BytesLimit, IntVars, ByteVars0, !Info),
-        ByteVars = [Var | ByteVars0]
-    ;
-        represent_locn_as_int_rval(Locn, LocnRval),
-        Var = live_array_info(LocnRval, TypeRval, TypeRvalType, VarNumRval),
-        construct_liveval_array_infos(VarInfos, VarNumMap,
-            BytesSoFar, BytesLimit, IntVars0, ByteVars, !Info),
-        IntVars = [Var | IntVars0]
-    ).
-
-:- pred construct_liveval_num_rval(var_num_map::in,
-    layout_var_info::in, rval::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-construct_liveval_num_rval(VarNumMap,
-        layout_var_info(_, LiveValueType, _), VarNumRval, !Info) :-
-    ( LiveValueType = live_value_var(Var, _, _, _) ->
-        convert_var_to_int(VarNumMap, Var, VarNum),
-        VarNumRval = const(llconst_int(VarNum))
+        ArraySlot = liveval_array_slot(TypeRval, VarNum, ShortLocn),
+        construct_liveval_array_slots(VarInfos, ModuleInfo, VarNumMap,
+            BytesSoFar + 1, BytesLimit, LongArraySlots, ShortArraySlots0,
+            !StaticCellInfo),
+        ShortArraySlots = [ArraySlot | ShortArraySlots0]
     ;
-        VarNumRval = const(llconst_int(0))
+        represent_locn_as_int(Locn, LongLocn),
+        ArraySlot = liveval_array_slot(TypeRval, VarNum, LongLocn),
+        construct_liveval_array_slots(VarInfos, ModuleInfo, VarNumMap,
+            BytesSoFar, BytesLimit, LongArraySlots0, ShortArraySlots,
+            !StaticCellInfo),
+        LongArraySlots = [ArraySlot | LongArraySlots0]
     ).
 
-:- pred convert_var_to_int(var_num_map::in, prog_var::in,
-    int::out) is det.
+:- pred construct_tvar_vector(map(tvar, set(layout_locn))::in,
+    rval::out, static_cell_info::in, static_cell_info::out) is det.
 
-convert_var_to_int(VarNumMap, Var, VarNum) :-
-    map.lookup(VarNumMap, Var, VarNum0 - _),
-    % The variable number has to fit into two bytes. We reserve the largest
-    % such number (Limit) to mean that the variable number is too large
-    % to be represented. This ought not to happen, since compilation
-    % would be glacial at best for procedures with that many variables.
-    Limit = (1 << (2 * byte_bits)) - 1,
-    int.min(VarNum0, Limit, VarNum).
+construct_tvar_vector(TVarLocnMap, TypeParamRval, !StaticCellInfo) :-
+    ( map.is_empty(TVarLocnMap) ->
+        TypeParamRval = const(llconst_int(0))
+    ;
+        construct_tvar_rvals(TVarLocnMap, Vector),
+        add_scalar_static_cell(Vector, DataAddr, !StaticCellInfo),
+        TypeParamRval = const(llconst_data_addr(DataAddr, no))
+    ).
+
+:- pred construct_tvar_rvals(map(tvar, set(layout_locn))::in,
+    assoc_list(rval, llds_type)::out) is det.
+
+construct_tvar_rvals(TVarLocnMap, Vector) :-
+    map.to_assoc_list(TVarLocnMap, TVarLocns),
+    construct_type_param_locn_vector(TVarLocns, 1, TypeParamLocs),
+    list.length(TypeParamLocs, TypeParamsLength),
+    LengthRval = const(llconst_int(TypeParamsLength)),
+    Vector = [LengthRval - lt_unsigned | TypeParamLocs].
 
 %---------------------------------------------------------------------------%
+%
+% Construct closure layout structures.
+%
 
-    % The representation we build here should be kept in sync
-    % with runtime/mercury_ho_call.h, which contains macros to access
-    % the data structures we build here.
-    %
 construct_closure_layout(CallerProcLabel, SeqNo,
         ClosureLayoutInfo, ClosureProcLabel, ModuleName,
         FileName, LineNumber, Origin, GoalPath, !StaticCellInfo,
         RvalsTypes, Data) :-
-    DataAddr = layout_addr(
-        closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel)),
+    % The representation we build here should be kept in sync
+    % with runtime/mercury_ho_call.h, which contains macros to access
+    % the data structures we build here.
+    %
+    ClosureId = closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel),
+    DataId = layout_id(ClosureId),
     Data = closure_proc_id_data(CallerProcLabel, SeqNo, ClosureProcLabel,
         ModuleName, FileName, LineNumber, Origin, GoalPath),
-    ProcIdRvalType = const(llconst_data_addr(DataAddr, no)) - lt_data_ptr,
+    ProcIdRvalType = const(llconst_data_addr(DataId, no)) - lt_data_ptr,
     ClosureLayoutInfo = closure_layout_info(ClosureArgs, TVarLocnMap),
     construct_closure_arg_rvals(ClosureArgs,
         ClosureArgRvalsTypes, !StaticCellInfo),
@@ -1492,63 +2019,6 @@
 
 %---------------------------------------------------------------------------%
 
-:- pred make_table_data(rtti_proc_label::in,
-    proc_layout_kind::in, proc_layout_table_info::in, maybe(layout_data)::out,
-    static_cell_info::in, static_cell_info::out) is det.
-
-make_table_data(RttiProcLabel, Kind, TableInfo, MaybeTableData,
-        !StaticCellInfo) :-
-    (
-        TableInfo = proc_table_io_decl(TableIOInfo),
-        TableIOInfo = proc_table_io_info(TableArgInfos),
-        convert_table_arg_info(TableArgInfos, NumPTIs, PTIVectorRval,
-            TVarVectorRval, !StaticCellInfo),
-        TableData = table_io_decl_data(RttiProcLabel, Kind,
-            NumPTIs, PTIVectorRval, TVarVectorRval),
-        MaybeTableData = yes(TableData)
-    ;
-        TableInfo = proc_table_struct(_TableStructInfo),
-        % This structure is generated by add_tabling_info_struct in proc_gen.m.
-        MaybeTableData = no
-    ).
-
-convert_table_arg_info(TableArgInfos, NumPTIs,
-        PTIVectorRval, TVarVectorRval, !StaticCellInfo) :-
-    TableArgInfos = table_arg_infos(Args, TVarSlotMap),
-    list.length(Args, NumPTIs),
-    list.map_foldl(construct_table_arg_pti_rval, Args, PTIRvalsTypes,
-        !StaticCellInfo),
-    add_scalar_static_cell(PTIRvalsTypes, PTIVectorAddr, !StaticCellInfo),
-    PTIVectorRval = const(llconst_data_addr(PTIVectorAddr, no)),
-    map.map_values_only(convert_slot_to_locn_map, TVarSlotMap, TVarLocnMap),
-    construct_tvar_vector(TVarLocnMap, TVarVectorRval, !StaticCellInfo).
-
-:- pred convert_slot_to_locn_map(table_locn::in, set(layout_locn)::out) is det.
-
-convert_slot_to_locn_map(SlotLocn, LvalLocns) :-
-    (
-        SlotLocn = table_locn_direct(SlotNum),
-        LvalLocn = locn_direct(reg(reg_r, SlotNum))
-    ;
-        SlotLocn = table_locn_indirect(SlotNum, Offset),
-        LvalLocn = locn_indirect(reg(reg_r, SlotNum), Offset)
-    ),
-    LvalLocns = set.make_singleton_set(LvalLocn).
-
-:- pred construct_table_arg_pti_rval(
-    table_arg_info::in, pair(rval, llds_type)::out,
-    static_cell_info::in, static_cell_info::out) is det.
-
-construct_table_arg_pti_rval(ClosureArg, ArgRval - ArgRvalType,
-        !StaticCellInfo) :-
-    ClosureArg = table_arg_info(_, _, _, Type),
-    ExistQTvars = [],
-    NumUnivQTvars = -1,
-    ll_pseudo_type_info.construct_typed_llds_pseudo_type_info(Type,
-        NumUnivQTvars, ExistQTvars, !StaticCellInfo, ArgRval, ArgRvalType).
-
-%---------------------------------------------------------------------------%
-
     % Construct a representation of the type of a value.
     %
     % For values representing variables, this will be a pseudo_type_info
@@ -1559,81 +2029,111 @@
     % type_info) defined by hand in builtin.m to stand for values of
     % each such kind; one for succips, one for hps, etc.
     %
-:- pred represent_live_value_type(live_value_type::in, rval::out,
-    llds_type::out, stack_layout_info::in, stack_layout_info::out) is det.
+:- pred represent_live_value_type_and_var_num(var_num_map::in,
+    live_value_type::in, rval::out, int::out,
+    static_cell_info::in, static_cell_info::out) is det.
 
-represent_live_value_type(live_value_succip, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("succip", Rval).
-represent_live_value_type(live_value_hp, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("hp", Rval).
-represent_live_value_type(live_value_curfr, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("curfr", Rval).
-represent_live_value_type(live_value_maxfr, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("maxfr", Rval).
-represent_live_value_type(live_value_redofr, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("redofr", Rval).
-represent_live_value_type(live_value_redoip, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("redoip", Rval).
-represent_live_value_type(live_value_trail_ptr, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("trail_ptr", Rval).
-represent_live_value_type(live_value_ticket, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("ticket", Rval).
-represent_live_value_type(RegionType, Rval, lt_data_ptr, !Info) :-
-    ( RegionType = live_value_region_ite
-    ; RegionType = live_value_region_disj
-    ; RegionType = live_value_region_commit
-    ),
+represent_live_value_type_and_var_num(VarNumMap, LiveValueType, TypeRval,
+        VarNum, !StaticCellInfo) :-
+    (
+        (
+            LiveValueType = live_value_succip,
+            Name = "succip"
+        ;
+            LiveValueType = live_value_hp,
+            Name = "hp"
+        ;
+            LiveValueType = live_value_curfr,
+            Name = "curfr"
+        ;
+            LiveValueType = live_value_maxfr,
+            Name = "maxfr"
+        ;
+            LiveValueType = live_value_redofr,
+            Name = "redofr"
+        ;
+            LiveValueType = live_value_redoip,
+            Name = "redoip"
+        ;
+            LiveValueType = live_value_trail_ptr,
+            Name = "trailptr"
+        ;
+            LiveValueType = live_value_ticket,
+            Name = "ticket"
+        ;
     % Neither the garbage collector nor the debugger need info about
     % regions.
-    represent_special_live_value_type("unwanted", Rval).
-represent_live_value_type(live_value_unwanted, Rval, lt_data_ptr, !Info) :-
-    represent_special_live_value_type("unwanted", Rval).
-represent_live_value_type(live_value_var(_, _, Type, _), Rval, LldsType,
-        !Info) :-
+            LiveValueType = live_value_region_ite,
+            Name = "unwanted"
+        ;
+            LiveValueType = live_value_region_disj,
+            Name = "unwanted"
+        ;
+            LiveValueType = live_value_region_commit,
+            Name = "unwanted"
+        ;
+            LiveValueType = live_value_unwanted,
+            Name = "unwanted"
+        ),
+        represent_special_live_value_type(Name, TypeRval),
+        VarNum = 0
+    ;
+        LiveValueType = live_value_var(Var, _, Type, _),
     % For a stack layout, we can treat all type variables as universally
     % quantified. This is not the argument of a constructor, so we do not
-    % need to distinguish between type variables that are and aren't in scope;
-    % we can take the variable number directly from the procedure's tvar set.
+        % need to distinguish between type variables that are and are not
+        % in scope; we can take the variable number directly from the
+        % procedure's tvar set.
     ExistQTvars = [],
     NumUnivQTvars = -1,
-    get_layout_static_cell_info(!.Info, StaticCellInfo0),
-    ll_pseudo_type_info.construct_typed_llds_pseudo_type_info(Type,
-        NumUnivQTvars, ExistQTvars, StaticCellInfo0, StaticCellInfo,
-        Rval, LldsType),
-    set_layout_static_cell_info(StaticCellInfo, !Info).
+        ll_pseudo_type_info.construct_llds_pseudo_type_info(Type,
+            NumUnivQTvars, ExistQTvars, !StaticCellInfo, TypeRval),
+        convert_var_to_int(VarNumMap, Var, VarNum)
+    ).
 
 :- pred represent_special_live_value_type(string::in, rval::out) is det.
 
 represent_special_live_value_type(SpecialTypeName, Rval) :-
     RttiTypeCtor = rtti_type_ctor(unqualified(""), SpecialTypeName, 0),
-    DataAddr = rtti_addr(ctor_rtti_id(RttiTypeCtor, type_ctor_type_ctor_info)),
-    Rval = const(llconst_data_addr(DataAddr, no)).
+    DataId =
+        rtti_data_id(ctor_rtti_id(RttiTypeCtor, type_ctor_type_ctor_info)),
+    Rval = const(llconst_data_addr(DataId, no)).
+
+:- pred convert_var_to_int(var_num_map::in, prog_var::in, int::out) is det.
+
+convert_var_to_int(VarNumMap, Var, VarNum) :-
+    map.lookup(VarNumMap, Var, VarNum0 - _),
+    % The variable number has to fit into two bytes. We reserve the largest
+    % such number (Limit) to mean that the variable number is too large
+    % to be represented. This ought not to happen, since compilation
+    % would be glacial at best for procedures with that many variables.
+    Limit = (1 << (2 * byte_bits)) - 1,
+    int.min(VarNum0, Limit, VarNum).
 
 %---------------------------------------------------------------------------%
 
-:- pred represent_locn_or_const_as_int_rval(rval::in, rval::out,
-    llds_type::out, stack_layout_info::in, stack_layout_info::out) is det.
+:- pred represent_locn_or_const_as_int_rval(stack_layout_params::in,
+    rval::in, rval::out, llds_type::out,
+    static_cell_info::in, static_cell_info::out) is det.
 
-represent_locn_or_const_as_int_rval(LvalOrConst, Rval, Type, !Info) :-
+represent_locn_or_const_as_int_rval(Params, LvalOrConst, Rval, Type,
+        !StaticCellInfo) :-
     (
         LvalOrConst = lval(Lval),
         represent_locn_as_int_rval(locn_direct(Lval), Rval),
         Type = lt_unsigned
     ;
         LvalOrConst = const(_Const),
-        get_unboxed_floats(!.Info, UnboxedFloats),
+        UnboxedFloats = Params ^ slp_unboxed_floats,
         LLDSType = rval_type_as_arg(UnboxedFloats, LvalOrConst),
-
-        get_layout_static_cell_info(!.Info, StaticCellInfo0),
-        add_scalar_static_cell([LvalOrConst - LLDSType], DataAddr,
-            StaticCellInfo0, StaticCellInfo),
-        set_layout_static_cell_info(StaticCellInfo, !Info),
-        Rval = const(llconst_data_addr(DataAddr, no)),
+        add_scalar_static_cell([LvalOrConst - LLDSType], DataId,
+            !StaticCellInfo),
+        Rval = const(llconst_data_addr(DataId, no)),
         Type = lt_data_ptr
     ;
         LvalOrConst = mkword(Tag, LvalOrConstBase),
-        represent_locn_or_const_as_int_rval(LvalOrConstBase, BaseRval, Type,
-            !Info),
+        represent_locn_or_const_as_int_rval(Params, LvalOrConstBase, BaseRval,
+            Type, !StaticCellInfo),
         Rval = mkword(Tag, BaseRval)
     ;
         ( LvalOrConst = binop(_, _, _)
@@ -1792,14 +2292,13 @@
     % Construct a representation of a variable location as a byte,
     % if this is possible.
     %
-:- pred represent_locn_as_byte(layout_locn::in, rval::out) is semidet.
+:- pred represent_locn_as_byte(layout_locn::in, int::out) is semidet.
 
-represent_locn_as_byte(LayoutLocn, Rval) :-
+represent_locn_as_byte(LayoutLocn, Byte) :-
     LayoutLocn = locn_direct(Lval),
     represent_lval_as_byte(Lval, Byte),
     0 =< Byte,
-    Byte < 256,
-    Rval = const(llconst_int(Byte)).
+    Byte < 256.
 
     % Construct a representation of an lval in a byte, if possible.
     %
@@ -1855,223 +2354,167 @@
 
 %---------------------------------------------------------------------------%
 
-represent_determinism_rval(Detism,
-    const(llconst_int(code_model.represent_determinism(Detism)))).
-
-%---------------------------------------------------------------------------%
-%
-% Access to the stack_layout data structure.
-%
-
-    % The per-sourcefile label table maps line numbers to the list of
-    % labels that correspond to that line. Each label is accompanied
-    % by a flag that says whether the label is the return site of a call
-    % or not, and if it is, whether the called procedure is known.
-
-:- type is_label_return
-    --->    known_callee(label)
-    ;       unknown_callee
-    ;       not_a_return.
-
-:- type line_no_info == pair(layout_slot_name, is_label_return).
-
-:- type file_label_table == map(int, list(line_no_info)).
-
-:- type stack_layout_info
-    --->    stack_layout_info(
-                sli_module_info             :: module_info,
-
-                % Should we generate agc info?
-                sli_agc_stack_layout        :: bool,
-
-                % Should we generate tracing info?
-                sli_trace_stack_layout      :: bool,
-
-                % Should we generate proc id info?
-                sli_procid_stack_layout     :: bool,
-
-                % Do we have static code addresses?
-                sli_static_code_addresses   :: bool,
-
-                sli_unboxed_floats          :: have_unboxed_floats,
-                sli_label_counter           :: counter,
-                sli_table_infos             :: list(layout_data),
-
-                % The list of proc_layouts in the module.
-                sli_rev_proc_layouts        :: list(layout_data),
-                sli_rev_proc_layout_names   :: list(layout_name),
-
-                sli_next_user_event         :: counter,
-                sli_next_user_event_var_num :: int,
-                sli_user_events             :: cord(user_event_data),
-                sli_user_event_var_nums     :: cord(maybe(int)),
+:- type label_layouts_info
+    --->    label_layouts_info(
+                % The arrays that hold components of label layouts.
+                lli_next_pti                :: int,
+                lli_next_long_locn          :: int,
+                lli_next_short_locn         :: int,
+                lli_next_hlds_var_num       :: int,
+                lli_rev_ptis                :: list(rval),
+                lli_rev_long_locns          :: list(int),
+                lli_rev_short_locns         :: list(int),
+                lli_rev_hlds_var_nums       :: list(int),
+
+                lli_next_user_event         :: counter,
+                lli_next_user_event_var_num :: int,
+                lli_user_events             :: cord(user_event_data),
+                lli_user_event_var_nums     :: cord(maybe(int)),
 
                 % The list of slots in the with-var-info and without-var-info
                 % label layout arrays.
-                sli_next_var_label_layout   :: counter,
-                sli_next_no_var_label_layout:: counter,
-                sli_rev_var_label_layouts   :: list(label_layout_vars),
-                sli_rev_no_var_label_layouts:: list(label_layout_no_vars),
+                lli_next_no_var_label_layout:: counter,
+                lli_next_svar_label_layout  :: counter,
+                lli_next_lvar_label_layout  :: counter,
+                lli_rev_no_var_label_layouts:: list(label_layout_no_vars),
+                lli_rev_svar_label_layouts  :: list(label_layout_short_vars),
+                lli_rev_lvar_label_layouts  :: list(label_layout_long_vars),
 
-                % This maps each internal label with a layout
-                % to the id of its layout structure.
-                sli_i_label_to_layout_map   :: map(label, layout_slot_name),
+                lli_label_counter           :: counter,
 
-                % This maps each proc label with a layout
+                % This maps each internal label with a layout
                 % to the id of its layout structure.
-                sli_p_label_to_layout_map   :: map(label, data_addr),
-
-                sli_string_table            :: string_table,
-
-                % Maps each filename that contributes labels to this module
-                % to a table describing those labels.
-                sli_label_tables            :: map(string, file_label_table),
-
-                sli_static_cell_info        :: static_cell_info,
-                sli_has_user_event          :: bool
+                lli_i_label_to_layout_map   :: map(label, layout_slot_name)
             ).
 
-:- pred get_module_info(stack_layout_info::in, module_info::out) is det.
-:- pred get_agc_stack_layout(stack_layout_info::in, bool::out) is det.
-:- pred get_trace_stack_layout(stack_layout_info::in, bool::out) is det.
-:- pred get_procid_stack_layout(stack_layout_info::in, bool::out) is det.
-:- pred get_static_code_addresses(stack_layout_info::in, bool::out) is det.
-:- pred get_unboxed_floats(stack_layout_info::in, have_unboxed_floats::out)
-    is det.
-:- pred get_table_infos(stack_layout_info::in, list(layout_data)::out) is det.
-:- pred get_rev_proc_layouts(stack_layout_info::in, list(layout_data)::out)
-    is det.
-:- pred get_rev_var_label_layouts(stack_layout_info::in,
-    list(label_layout_vars)::out) is det.
-:- pred get_rev_no_var_label_layouts(stack_layout_info::in,
-    list(label_layout_no_vars)::out) is det.
-:- pred get_internal_label_to_layout_map(stack_layout_info::in,
-    map(label, layout_slot_name)::out) is det.
-:- pred get_proc_label_to_layout_map(stack_layout_info::in,
-    map(label, data_addr)::out) is det.
-:- pred get_string_table(stack_layout_info::in, string_table::out) is det.
-:- pred get_label_tables(stack_layout_info::in,
-    map(string, file_label_table)::out) is det.
-:- pred get_layout_static_cell_info(stack_layout_info::in,
-    static_cell_info::out) is det.
-:- pred get_has_user_event(stack_layout_info::in, bool::out) is det.
-
-get_module_info(LI, LI ^ sli_module_info).
-get_agc_stack_layout(LI, LI ^ sli_agc_stack_layout).
-get_trace_stack_layout(LI, LI ^ sli_trace_stack_layout).
-get_procid_stack_layout(LI, LI ^ sli_procid_stack_layout).
-get_static_code_addresses(LI, LI ^ sli_static_code_addresses).
-get_unboxed_floats(LI, LI ^ sli_unboxed_floats).
-get_table_infos(LI, LI ^ sli_table_infos).
-get_rev_proc_layouts(LI, LI ^ sli_rev_proc_layouts).
-get_rev_var_label_layouts(LI, LI ^ sli_rev_var_label_layouts).
-get_rev_no_var_label_layouts(LI, LI ^ sli_rev_no_var_label_layouts).
-get_internal_label_to_layout_map(LI, LI ^ sli_i_label_to_layout_map).
-get_proc_label_to_layout_map(LI, LI ^ sli_p_label_to_layout_map).
-get_string_table(LI, LI ^ sli_string_table).
-get_label_tables(LI, LI ^ sli_label_tables).
-get_layout_static_cell_info(LI, LI ^ sli_static_cell_info).
-get_has_user_event(LI, LI ^ sli_has_user_event).
-
-:- pred allocate_label_number(int::out,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-allocate_label_number(LabelNum, !LI) :-
-    Counter0 = !.LI ^ sli_label_counter,
-    counter.allocate(LabelNum, Counter0, Counter),
-    !LI ^ sli_label_counter := Counter.
-
-:- pred add_table_data(maybe(layout_data)::in,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-add_table_data(MaybeTableIoDeclData, !LI) :-
-    (
-        MaybeTableIoDeclData = yes(TableIoDeclData),
-        TableIoDecls0 = !.LI ^ sli_table_infos,
-        TableIoDecls = [TableIoDeclData | TableIoDecls0],
-        !LI ^ sli_table_infos := TableIoDecls
-    ;
-        MaybeTableIoDeclData = no
-    ).
+:- func init_label_layouts_info = label_layouts_info.
 
-:- pred add_proc_layout_data(label::in, layout_name::in, layout_data::in,
-    stack_layout_info::in, stack_layout_info::out) is det.
+init_label_layouts_info = Info :-
+    Info = label_layouts_info(0, 0, 0, 0, [], [], [], [],
+        counter.init(0), 0, cord.empty, cord.empty,
+        counter.init(0), counter.init(0), counter.init(0), [], [], [],
+        counter.init(1), map.init).
 
-add_proc_layout_data(Label, ProcLayoutName, ProcLayout, !LI) :-
-    RevProcLayouts0 = !.LI ^ sli_rev_proc_layouts,
-    RevProcLayouts = [ProcLayout | RevProcLayouts0],
+%---------------------------------------------------------------------------%
 
-    RevProcLayoutNames0 = !.LI ^ sli_rev_proc_layout_names,
-    RevProcLayoutNames = [ProcLayoutName | RevProcLayoutNames0],
+    % Look for Search as a sub-sequence in the second argument, and
+    % return its offset if it exists. We use this to avoid adding existing
+    % sequences to arrays.
+    %
+    % When we stored information about pseudo-typeinfos, variable numbers,
+    % and variable locations in separate structures (not arrays), our use
+    % of common structures for them ensured that any identical copies of
+    % such structures would be optimized away. This optimization is even
+    % more effective, since it it allows the sequence we need for one label
+    % to be found as (a) a subsequence of the longer sequence for another
+    % label, and (b) straddling the sequences of two (or possibly even more)
+    % other labels.
+    %
+    % We use the straightforward, brute force algorithm instead of more
+    % sophisticated algorithms like Knuth-Morris-Pratt because (a) those
+    % algorithms are nontrivial to adapt to working on lists instead of arrays
+    % without losing their edge, and (b) this algorithm is fast enough.
+    % Turning this on optimization reduces the size of the generated .c and .o
+    % files by about 12% and 11% respectively (measured on the files in the
+    % library, mdbcomp and compiler directories in grade asm_fast.gc.debug),
+    % but even without the type_spec pragmas, it increases sequential bootcheck
+    % time only a little bit, from 3hr2m to 3hr6m (on alys, which is a Dell
+    % Inspiron 9400 laptop).
+    %
+    % Another possible optimization would be to look whether some sequence of
+    % elements at the current end of the array could be extended into the
+    % search sequence, instead of adding the whole search sequence to the
+    % array.
+    %
+:- pred find_sequence(list(T)::in, list(T)::in, int::in, int::out) is semidet.
+:- pragma type_spec(find_sequence/4, T = int).
+:- pragma type_spec(find_sequence/4, T = rval).
+
+find_sequence(Search, [Head | Tail], CurOffset, FoundAtOffset) :-
+    ( find_sequence_attempt(Search, [Head | Tail]) ->
+        FoundAtOffset = CurOffset
+    ;
+        find_sequence(Search, Tail, CurOffset + 1, FoundAtOffset)
+    ).
+
+:- pred find_sequence_attempt(list(T)::in, list(T)::in) is semidet.
+:- pragma type_spec(find_sequence_attempt/2, T = int).
+:- pragma type_spec(find_sequence_attempt/2, T = rval).
+
+find_sequence_attempt([], _).
+find_sequence_attempt([SearchHead | SearchTail], [Head | Tail]) :-
+    SearchHead = Head,
+    find_sequence_attempt(SearchTail, Tail).
 
-    LabelToLayoutMap0 = !.LI ^ sli_p_label_to_layout_map,
-    map.det_insert(LabelToLayoutMap0, Label, layout_addr(ProcLayoutName),
-        LabelToLayoutMap),
+%---------------------------------------------------------------------------%
+
+represent_determinism_rval(Detism,
+    const(llconst_int(code_model.represent_determinism(Detism)))).
 
-    !LI ^ sli_rev_proc_layouts := RevProcLayouts,
-    !LI ^ sli_rev_proc_layout_names := RevProcLayoutNames,
-    !LI ^ sli_p_label_to_layout_map := LabelToLayoutMap.
+%---------------------------------------------------------------------------%
+%
+% The structure holding all the relevant parameters.
+%
 
-:- pred add_vars_internal_layout_data(label::in, label_layout_vars::in,
-    int::out, stack_layout_info::in, stack_layout_info::out) is det.
+:- type stack_layout_params
+    --->    stack_layout_params(
+                slp_module_info             :: module_info,
+
+                % What kind of execution tracing, if any, are we doing?
+                slp_trace_level             :: trace_level,
+                slp_trace_suppress          :: trace_suppress_items,
 
-add_vars_internal_layout_data(Label, Layout, Slot, !LI) :-
-    RevLayouts0 = !.LI ^ sli_rev_var_label_layouts,
-    RevLayouts = [Layout | RevLayouts0],
+                % Is deep profiling enabled?
+                slp_deep_profiling          :: bool,
 
-    Counter0 = !.LI ^ sli_next_var_label_layout,
-    counter.allocate(Slot, Counter0, Counter),
-    LayoutName = layout_slot(label_layout_array(label_has_var_info), Slot),
+                % Should we generate agc info?
+                slp_agc_stack_layout        :: bool,
 
-    LabelToLayoutMap0 = !.LI ^ sli_i_label_to_layout_map,
-    map.det_insert(LabelToLayoutMap0, Label, LayoutName, LabelToLayoutMap),
+                % Should we generate tracing info?
+                slp_trace_stack_layout      :: bool,
 
-    !LI ^ sli_rev_var_label_layouts := RevLayouts,
-    !LI ^ sli_next_var_label_layout := Counter,
-    !LI ^ sli_i_label_to_layout_map := LabelToLayoutMap.
+                % Should we generate proc id info?
+                slp_procid_stack_layout     :: bool,
 
-:- pred add_no_vars_internal_layout_data(label::in, label_layout_no_vars::in,
-    int::out, stack_layout_info::in, stack_layout_info::out) is det.
+                % Should we try to compress arrays?
+                slp_compress_arrays         :: bool,
 
-add_no_vars_internal_layout_data(Label, Layout, Slot, !LI) :-
-    RevLayouts0 = !.LI ^ sli_rev_no_var_label_layouts,
-    RevLayouts = [Layout | RevLayouts0],
+                % Do we have static code addresses or unboxed floats?
+                slp_static_code_addresses   :: bool,
+                slp_unboxed_floats          :: have_unboxed_floats,
 
-    Counter0 = !.LI ^ sli_next_no_var_label_layout,
-    counter.allocate(Slot, Counter0, Counter),
-    LayoutName = layout_slot(label_layout_array(label_has_no_var_info), Slot),
+                % Do we want to include information about labels' line numbers?
+                slp_rtti_line_numbers       :: bool
+            ).
 
-    LabelToLayoutMap0 = !.LI ^ sli_i_label_to_layout_map,
-    map.det_insert(LabelToLayoutMap0, Label, LayoutName, LabelToLayoutMap),
+:- func init_stack_layout_params(module_info) = stack_layout_params.
 
-    !LI ^ sli_rev_no_var_label_layouts := RevLayouts,
-    !LI ^ sli_next_no_var_label_layout := Counter,
-    !LI ^ sli_i_label_to_layout_map := LabelToLayoutMap.
-
-:- pred set_string_table(string_table::in,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-:- pred set_label_tables(map(string, file_label_table)::in,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-:- pred set_layout_static_cell_info(static_cell_info::in,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-:- pred set_has_user_event(bool::in,
-    stack_layout_info::in, stack_layout_info::out) is det.
-
-set_string_table(ST, !LI) :-
-    !LI ^ sli_string_table := ST.
-set_label_tables(LT, !LI) :-
-    !LI ^ sli_label_tables := LT.
-set_layout_static_cell_info(SCI, !LI) :-
-    !LI ^ sli_static_cell_info := SCI.
-set_has_user_event(HUE, !LI) :-
-    !LI ^ sli_has_user_event := HUE.
+init_stack_layout_params(ModuleInfo) = Params :-
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.get_trace_level(Globals, TraceLevel),
+    globals.get_trace_suppress(Globals, TraceSuppress),
+    globals.lookup_bool_option(Globals, deep_profiling, DeepProfiling),
+    globals.lookup_bool_option(Globals, agc_stack_layout, AgcLayout),
+    globals.lookup_bool_option(Globals, trace_stack_layout, TraceLayout),
+    globals.lookup_bool_option(Globals, procid_stack_layout, ProcIdLayout),
+    globals.lookup_bool_option(Globals, common_layout_data, CommonLayoutData),
+    globals.lookup_bool_option(Globals, static_code_addresses, StaticCodeAddr),
+    globals.lookup_bool_option(Globals, unboxed_float, UnboxedFloatOpt),
+    globals.lookup_bool_option(Globals, rtti_line_numbers, RttiLineNumbers),
+    (
+        UnboxedFloatOpt = no,
+        UnboxedFloat = do_not_have_unboxed_floats
+    ;
+        UnboxedFloatOpt = yes,
+        UnboxedFloat = have_unboxed_floats
+    ),
+    Params = stack_layout_params(ModuleInfo, TraceLevel, TraceSuppress,
+        DeepProfiling, AgcLayout, TraceLayout, ProcIdLayout, CommonLayoutData,
+        StaticCodeAddr, UnboxedFloat, RttiLineNumbers).
 
 %---------------------------------------------------------------------------%
 %
-% Access to the string_table data structure.
+% The string_table data structure.
 %
 
 :- type string_table
@@ -2086,9 +2529,16 @@
                 int
             ).
 
-lookup_string_in_table(String, Offset, !Info) :-
-    StringTable0 = !.Info ^ sli_string_table,
-    StringTable0 = string_table(TableMap0, TableList0, TableOffset0),
+:- func init_string_table = string_table.
+
+init_string_table = !:StringTable :-
+    map.init(StringMap0),
+    !:StringTable = string_table(StringMap0, [], 0),
+    lookup_string_in_table("", _, !StringTable),
+    lookup_string_in_table("<too many variables>", _, !StringTable).
+
+lookup_string_in_table(String, Offset, !StringTable) :-
+    !.StringTable = string_table(TableMap0, TableList0, TableOffset0),
     ( map.search(TableMap0, String, OldOffset) ->
         Offset = OldOffset
     ;
@@ -2109,8 +2559,7 @@
         Offset = TableOffset0,
         map.det_insert(TableMap0, String, TableOffset0, TableMap),
         TableList = [String | TableList0],
-        StringTable = string_table(TableMap, TableList, TableOffset),
-        set_string_table(StringTable, !Info)
+        !:StringTable = string_table(TableMap, TableList, TableOffset)
     ;
         % Says that the name of the variable is "TOO_MANY_VARIABLES".
         Offset = 1
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.194
diff -u -b -r1.194 unify_gen.m
--- compiler/unify_gen.m	21 Sep 2009 04:08:59 -0000	1.194
+++ compiler/unify_gen.m	27 Oct 2009 06:18:31 -0000
@@ -533,18 +533,18 @@
         expect(unify(Args, []), this_file,
             "generate_construction_2: type_ctor_info constant has args"),
         RttiTypeCtor = rtti_type_ctor(ModuleName, TypeName, TypeArity),
-        DataAddr = rtti_addr(ctor_rtti_id(RttiTypeCtor,
+        DataId = rtti_data_id(ctor_rtti_id(RttiTypeCtor,
             type_ctor_type_ctor_info)),
-        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
+        assign_const_to_var(Var, const(llconst_data_addr(DataId, no)), !CI),
         Code = empty
     ;
         ConsTag = base_typeclass_info_tag(ModuleName, ClassId, Instance),
         expect(unify(Args, []), this_file,
             "generate_construction_2: base_typeclass_info constant has args"),
         TCName = generate_class_name(ClassId),
-        DataAddr = rtti_addr(tc_rtti_id(TCName,
+        DataId = rtti_data_id(tc_rtti_id(TCName,
             type_class_base_typeclass_info(ModuleName, Instance))),
-        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
+        assign_const_to_var(Var, const(llconst_data_addr(DataId, no)), !CI),
         Code = empty
     ;
         ConsTag = tabling_info_tag(PredId, ProcId),
@@ -552,10 +552,8 @@
             "generate_construction_2: tabling_info constant has args"),
         get_module_info(!.CI, ModuleInfo),
         ProcLabel = make_proc_label(ModuleInfo, PredId, ProcId),
-        module_info_get_name(ModuleInfo, ModuleName),
-        DataAddr = data_addr(ModuleName,
-            proc_tabling_ref(ProcLabel, tabling_info)),
-        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
+        DataId = proc_tabling_data_id(ProcLabel, tabling_info),
+        assign_const_to_var(Var, const(llconst_data_addr(DataId, no)), !CI),
         Code = empty
     ;
         ConsTag = deep_profiling_proc_layout_tag(PredId, ProcId),
@@ -563,24 +561,23 @@
             "generate_construction_2: deep_profiling_proc_static has args"),
         get_module_info(!.CI, ModuleInfo),
         RttiProcLabel = make_rtti_proc_label(ModuleInfo, PredId, ProcId),
-        Origin = RttiProcLabel ^ pred_info_origin,
+        Origin = RttiProcLabel ^ rpl_pred_info_origin,
         ( Origin = origin_special_pred(_) ->
             UserOrUCI = uci
         ;
             UserOrUCI = user
         ),
         ProcKind = proc_layout_proc_id(UserOrUCI),
-        DataAddr = layout_addr(proc_layout(RttiProcLabel, ProcKind)),
-        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
+        DataId = layout_id(proc_layout(RttiProcLabel, ProcKind)),
+        assign_const_to_var(Var, const(llconst_data_addr(DataId, no)), !CI),
         Code = empty
     ;
         ConsTag = table_io_decl_tag(PredId, ProcId),
         expect(unify(Args, []), this_file,
             "generate_construction_2: table_io_decl has args"),
-        get_module_info(!.CI, ModuleInfo),
-        RttiProcLabel = make_rtti_proc_label(ModuleInfo, PredId, ProcId),
-        DataAddr = layout_addr(table_io_decl(RttiProcLabel)),
-        assign_const_to_var(Var, const(llconst_data_addr(DataAddr, no)), !CI),
+        PredProcId = proc(PredId, ProcId),
+        DataId = layout_slot_id(table_io_decl_id, PredProcId),
+        assign_const_to_var(Var, const(llconst_data_addr(DataId, no)), !CI),
         Code = empty
     ;
         ConsTag = reserved_address_tag(RA),
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.596
diff -u -b -r1.596 user_guide.texi
--- doc/user_guide.texi	4 Oct 2009 21:19:44 -0000	1.596
+++ doc/user_guide.texi	26 Oct 2009 17:59:14 -0000
@@ -8785,6 +8785,11 @@
 @findex --common-data
 Disable optimization of common data structures.
 
+ at item --no-layout-common-data
+ at findex --no-layout-common-data
+ at findex --common-layout-data
+Disable optimization of common subsequences in layout structures.
+
 @item --no-llds-optimize
 @findex --no-llds-optimize
 @findex --llds-optimize
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/Mmakefile,v
retrieving revision 1.147
diff -u -b -r1.147 Mmakefile
--- runtime/Mmakefile	16 Aug 2009 10:18:36 -0000	1.147
+++ runtime/Mmakefile	24 Oct 2009 01:53:16 -0000
@@ -415,14 +415,16 @@
 	@mv mercury_conf.h mercury_conf.h.tmp
 	@sed -e '/Generated by configure/s:mercury_conf:runtime/mercury_conf:' \
 		< mercury_conf.h.tmp > mercury_conf.h
-	# check to ensure there were no mispelt autoconf variable names
+	# Check to ensure there were no misspelt autoconf variable names.
 	if grep -n '[^$$]@' mercury_conf.h; then false; else true; fi
-	# check if we need to update the timestamp
+	# Check if we need to update the file, and if yes, do so.
 	if test -f mercury_conf.h.was -a -f mercury_conf.h.date && \
 		cmp mercury_conf.h.was mercury_conf.h > /dev/null ; \
 		then mv mercury_conf.h.was mercury_conf.h ; \
-		else echo datestamp > mercury_conf.h.date ; \
 	fi
+	# Update the datestamp to show that mercury_conf.h is now current,
+	# even if its modification date is old.
+	echo datestamp > mercury_conf.h.date ;
 	@-rm -f mercury_conf.h.tmp mercury_conf.h.was
 
 mercury_conf.h: mercury_conf.h.date
Index: runtime/mercury_accurate_gc.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_accurate_gc.c,v
retrieving revision 1.47
diff -u -b -r1.47 mercury_accurate_gc.c
--- runtime/mercury_accurate_gc.c	3 Jan 2007 05:17:15 -0000	1.47
+++ runtime/mercury_accurate_gc.c	24 Oct 2009 04:44:13 -0000
@@ -353,8 +353,8 @@
 #endif
 
     /* 
-    ** If we have already scheduled a garbage collection, undo the
-    ** last change, and do a new one.
+    ** If we have already scheduled a garbage collection, undo the last change,
+    ** and do a new one.
     */
     if (gc_scheduled) {
 #ifdef MR_DEBUG_AGC_SCHEDULING
@@ -384,19 +384,17 @@
     } else {
         callee_was_model_semi = MR_FALSE;
         /*
-        ** XXX we ought to also overwrite the redoip,
-        **     otherwise we might miss failure-driven loops
-        **     which don't contain any returns.
+        ** XXX we ought to also overwrite the redoip, otherwise we might miss
+        ** failure-driven loops which don't contain any returns.
         */
         /*
         ** Save the old succip and its location.
         **
-        ** Note that curfr always points to an ordinary procedure
-        ** frame, never to a temp frame, so it is safe to access
-        ** the succip slot of that frame without checking what kind
-        ** of frame it is.
+        ** Note that curfr always points to an ordinary procedure frame,
+        ** never to a temp frame, so it is safe to access the succip slot
+        ** of that frame without checking what kind of frame it is.
         */
-        assert(location.MR_long_lval == -1);
+        assert(location == -1);
             /* succip is saved in succip_slot */
         saved_success_location = MR_succip_slot_addr(curfr_at_signal);
         saved_success = *saved_success_location;
@@ -410,8 +408,7 @@
 #endif
 
     /*
-    ** Replace the old succip with the address of the
-    ** garbage collector.
+    ** Replace the old succip with the address of the garbage collector.
     */
     *saved_success_location = MR_ENTRY(mercury__garbage_collect_0_0);
 
@@ -704,8 +701,8 @@
         fflush(NULL);
     }
 
-    short_var_count = MR_short_desc_var_count(label_layout);
     long_var_count = MR_long_desc_var_count(label_layout);
+    short_var_count = MR_short_desc_var_count(label_layout);
 
     /* Get the type parameters from the stack frame. */
 
@@ -717,10 +714,10 @@
     ** caller-save registers (they are all callee-save).
     */
     /*
-    ** XXX this won't handle calls to semidet existentially typed procedures:
-    **      we will try to dereference the type_infos for the
-    **      existential type vars here, even if the success
-    **      indicator is false and hence the registers are not live.
+    ** XXX This won't handle calls to semidet existentially typed procedures.
+    ** We will try to dereference the type_infos for the existential type vars
+    ** here, even if the success indicator is false and hence the registers
+    ** are not live.
     */
     type_params = MR_materialize_type_params_base(label_layout,
         (registers_live ? MR_fake_reg : NULL), stack_pointer, current_frame);
@@ -739,7 +736,7 @@
         allocated_memory_cells = NULL;
     }
 
-    for (; i < short_var_count; i++) {
+    for (i = 0; i < short_var_count; i++) {
         locn = MR_short_desc_var_locn(label_layout, i);
         pseudo_type_info = MR_var_pti(label_layout, i);
 
Index: runtime/mercury_agc_debug.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_agc_debug.c,v
retrieving revision 1.29
diff -u -b -r1.29 mercury_agc_debug.c
--- runtime/mercury_agc_debug.c	3 Jan 2007 05:17:15 -0000	1.29
+++ runtime/mercury_agc_debug.c	24 Oct 2009 04:45:14 -0000
@@ -244,13 +244,14 @@
     MR_Word             saved_regs[MR_MAX_FAKE_REG];
     MR_Word             *current_regs;
 
-    short_var_count = MR_short_desc_var_count(label_layout);
     long_var_count = MR_long_desc_var_count(label_layout);
+    short_var_count = MR_short_desc_var_count(label_layout);
 
     /*
-    ** For the top stack frame, we should pass a pointer to a filled-in saved_regs
-    ** instead of NULL. For other stack frames, passing NULL is fine, since output
-    ** arguments are not live yet for any call except the top one.
+    ** For the top stack frame, we should pass a pointer to a filled-in
+    ** saved_regs instead of NULL. For other stack frames, passing NULL
+    ** is fine, since output arguments are not live yet for any call
+    ** except the top one.
     */
 
     MR_restore_registers();
@@ -294,7 +295,7 @@
         }
     }
 
-    for (; i < short_var_count; i++) {
+    for (i = 0; i < short_var_count; i++) {
         fprintf(stderr, "%-12s\t", "");
         if (MR_PROC_LAYOUT_HAS_PROC_ID(label_layout->MR_sll_entry)) {
             MR_print_proc_id(stderr, label_layout->MR_sll_entry);
Index: runtime/mercury_engine.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_engine.h,v
retrieving revision 1.49
diff -u -b -r1.49 mercury_engine.h
--- runtime/mercury_engine.h	11 Oct 2007 11:45:22 -0000	1.49
+++ runtime/mercury_engine.h	24 Oct 2009 01:40:35 -0000
@@ -277,6 +277,7 @@
 **
 ** this_context Points to the "backing store" for the context currently
 **              executing on this engine.
+**
 ** context      Stores all the context information for the context currently
 **              executing in this engine.
 **
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.51
diff -u -b -r1.51 mercury_goto.h
--- runtime/mercury_goto.h	21 Oct 2009 06:36:35 -0000	1.51
+++ runtime/mercury_goto.h	23 Oct 2009 17:29:09 -0000
@@ -1257,172 +1257,6 @@
 
 /*---------------------------------------------------------------------------*/
 
-#define	MR_var_label_layouts(m)						\
-	MR_PASTE2(mercury_data__var_label_layout_array__, m)
-
-#define	MR_no_var_label_layouts(m)					\
-	MR_PASTE2(mercury_data__no_var_label_layout_array__, m)
-
-#define	MR_user_event_var_nums(m)					\
-	MR_PASTE2(mercury_data__user_event_var_nums_array__, m)
-
-#define	MR_user_event_layouts(m)					\
-	MR_PASTE2(mercury_data__user_event_layouts_array__, m)
-
-/*---------------------------------------------------------------------------*/
-
-#define	MR_var_label_layout_refs1(m, s1)				\
-	&MR_var_label_layouts(m)[s1],
-
-#define	MR_var_label_layout_refs2(m, s1, s2) 				\
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)
-
-#define	MR_var_label_layout_refs3(m, s1, s2, s3) 			\
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)
-
-#define	MR_var_label_layout_refs4(m, s1, s2, s3, s4) 			\
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)				\
-	MR_var_label_layout_refs1(m, s4)
-
-#define	MR_var_label_layout_refs5(m, s1, s2, s3, s4, s5) 		\
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)				\
-	MR_var_label_layout_refs1(m, s4)				\
-	MR_var_label_layout_refs1(m, s5)
-
-#define	MR_var_label_layout_refs6(m, s1, s2, s3, s4, s5, s6) 		\
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)				\
-	MR_var_label_layout_refs1(m, s4)				\
-	MR_var_label_layout_refs1(m, s5)				\
-	MR_var_label_layout_refs1(m, s6)
-
-#define	MR_var_label_layout_refs7(m, s1, s2, s3, s4, s5, s6, s7) 	\
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)				\
-	MR_var_label_layout_refs1(m, s4)				\
-	MR_var_label_layout_refs1(m, s5)				\
-	MR_var_label_layout_refs1(m, s6)				\
-	MR_var_label_layout_refs1(m, s7)
-
-#define	MR_var_label_layout_refs8(m, s1, s2, s3, s4, s5, s6, s7, s8) 	\
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)				\
-	MR_var_label_layout_refs1(m, s4)				\
-	MR_var_label_layout_refs1(m, s5)				\
-	MR_var_label_layout_refs1(m, s6)				\
-	MR_var_label_layout_refs1(m, s7)				\
-	MR_var_label_layout_refs1(m, s8)
-
-#define	MR_var_label_layout_refs9(m, s1, s2, s3, s4, s5, s6, s7, s8, s9) \
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)				\
-	MR_var_label_layout_refs1(m, s4)				\
-	MR_var_label_layout_refs1(m, s5)				\
-	MR_var_label_layout_refs1(m, s6)				\
-	MR_var_label_layout_refs1(m, s7)				\
-	MR_var_label_layout_refs1(m, s8)				\
-	MR_var_label_layout_refs1(m, s9)
-
-#define	MR_var_label_layout_refs10(m, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
-	MR_var_label_layout_refs1(m, s1)				\
-	MR_var_label_layout_refs1(m, s2)				\
-	MR_var_label_layout_refs1(m, s3)				\
-	MR_var_label_layout_refs1(m, s4)				\
-	MR_var_label_layout_refs1(m, s5)				\
-	MR_var_label_layout_refs1(m, s6)				\
-	MR_var_label_layout_refs1(m, s7)				\
-	MR_var_label_layout_refs1(m, s8)				\
-	MR_var_label_layout_refs1(m, s9)				\
-	MR_var_label_layout_refs1(m, s10)
-
-#define	MR_no_var_label_layout_refs1(m, s1)				\
-	&MR_no_var_label_layouts(m)[s1],
-
-#define	MR_no_var_label_layout_refs2(m, s1, s2)				\
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)
-
-#define	MR_no_var_label_layout_refs3(m, s1, s2, s3) 			\
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)
-
-#define	MR_no_var_label_layout_refs4(m, s1, s2, s3, s4) 		\
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)				\
-	MR_no_var_label_layout_refs1(m, s4)
-
-#define	MR_no_var_label_layout_refs5(m, s1, s2, s3, s4, s5) 		\
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)				\
-	MR_no_var_label_layout_refs1(m, s4)				\
-	MR_no_var_label_layout_refs1(m, s5)
-
-#define	MR_no_var_label_layout_refs6(m, s1, s2, s3, s4, s5, s6) 	\
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)				\
-	MR_no_var_label_layout_refs1(m, s4)				\
-	MR_no_var_label_layout_refs1(m, s5)				\
-	MR_no_var_label_layout_refs1(m, s6)
-
-#define	MR_no_var_label_layout_refs7(m, s1, s2, s3, s4, s5, s6, s7) 	\
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)				\
-	MR_no_var_label_layout_refs1(m, s4)				\
-	MR_no_var_label_layout_refs1(m, s5)				\
-	MR_no_var_label_layout_refs1(m, s6)				\
-	MR_no_var_label_layout_refs1(m, s7)
-
-#define	MR_no_var_label_layout_refs8(m, s1, s2, s3, s4, s5, s6, s7, s8)	\
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)				\
-	MR_no_var_label_layout_refs1(m, s4)				\
-	MR_no_var_label_layout_refs1(m, s5)				\
-	MR_no_var_label_layout_refs1(m, s6)				\
-	MR_no_var_label_layout_refs1(m, s7)				\
-	MR_no_var_label_layout_refs1(m, s8)
-
-#define	MR_no_var_label_layout_refs9(m, s1, s2, s3, s4, s5, s6, s7, s8, s9) \
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)				\
-	MR_no_var_label_layout_refs1(m, s4)				\
-	MR_no_var_label_layout_refs1(m, s5)				\
-	MR_no_var_label_layout_refs1(m, s6)				\
-	MR_no_var_label_layout_refs1(m, s7)				\
-	MR_no_var_label_layout_refs1(m, s8)				\
-	MR_no_var_label_layout_refs1(m, s9)
-
-#define	MR_no_var_label_layout_refs10(m, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
-	MR_no_var_label_layout_refs1(m, s1)				\
-	MR_no_var_label_layout_refs1(m, s2)				\
-	MR_no_var_label_layout_refs1(m, s3)				\
-	MR_no_var_label_layout_refs1(m, s4)				\
-	MR_no_var_label_layout_refs1(m, s5)				\
-	MR_no_var_label_layout_refs1(m, s6)				\
-	MR_no_var_label_layout_refs1(m, s7)				\
-	MR_no_var_label_layout_refs1(m, s8)				\
-	MR_no_var_label_layout_refs1(m, s9)				\
-	MR_no_var_label_layout_refs1(m, s10)
-
-/*---------------------------------------------------------------------------*/
-
 #define	MR_init_label1(e, l1)						\
 	MR_init_label(MR_label_name(MR_add_prefix(e), l1));
 
@@ -1577,84 +1411,6 @@
 
 /*---------------------------------------------------------------------------*/
 
-#define	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_ml_sl(MR_label_name(MR_add_prefix(e), l1),	\
-		&MR_var_label_layouts(m)[s1]);
-
-#define	MR_init_label_vi2(e, m, l1,s1, l2,s2)				\
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)
-
-#define	MR_init_label_vi3(e, m, l1,s1, l2,s2, l3,s3)			\
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)
-
-#define	MR_init_label_vi4(e, m, l1,s1, l2,s2, l3,s3, l4,s4)		\
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)					\
-	MR_init_label_vi1(e, m, l4, s4)
-
-#define	MR_init_label_vi5(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5)	\
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)					\
-	MR_init_label_vi1(e, m, l4, s4)					\
-	MR_init_label_vi1(e, m, l5, s5)
-
-#define	MR_init_label_vi6(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6) \
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)					\
-	MR_init_label_vi1(e, m, l4, s4)					\
-	MR_init_label_vi1(e, m, l5, s5)					\
-	MR_init_label_vi1(e, m, l6, s6)
-
-#define	MR_init_label_vi7(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7) \
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)					\
-	MR_init_label_vi1(e, m, l4, s4)					\
-	MR_init_label_vi1(e, m, l5, s5)					\
-	MR_init_label_vi1(e, m, l6, s6)					\
-	MR_init_label_vi1(e, m, l7, s7)
-
-#define	MR_init_label_vi8(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8) \
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)					\
-	MR_init_label_vi1(e, m, l4, s4)					\
-	MR_init_label_vi1(e, m, l5, s5)					\
-	MR_init_label_vi1(e, m, l6, s6)					\
-	MR_init_label_vi1(e, m, l7, s7)					\
-	MR_init_label_vi1(e, m, l8, s8)
-
-#define	MR_init_label_vi9(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9) \
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)					\
-	MR_init_label_vi1(e, m, l4, s4)					\
-	MR_init_label_vi1(e, m, l5, s5)					\
-	MR_init_label_vi1(e, m, l6, s6)					\
-	MR_init_label_vi1(e, m, l7, s7)					\
-	MR_init_label_vi1(e, m, l8, s8)					\
-	MR_init_label_vi1(e, m, l9, s9)
-
-#define	MR_init_label_vi10(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9, l10,s10) \
-	MR_init_label_vi1(e, m, l1, s1)					\
-	MR_init_label_vi1(e, m, l2, s2)					\
-	MR_init_label_vi1(e, m, l3, s3)					\
-	MR_init_label_vi1(e, m, l4, s4)					\
-	MR_init_label_vi1(e, m, l5, s5)					\
-	MR_init_label_vi1(e, m, l6, s6)					\
-	MR_init_label_vi1(e, m, l7, s7)					\
-	MR_init_label_vi1(e, m, l8, s8)					\
-	MR_init_label_vi1(e, m, l9, s9)					\
-	MR_init_label_vi1(e, m, l10, s10)
-
-/*---------------------------------------------------------------------------*/
-
 #define	MR_init_label_nvi1(e, m, l1, s1)				\
 	MR_init_label_ml_sl(MR_label_name(MR_add_prefix(e), l1),	\
 		&MR_no_var_label_layouts(m)[s1]);
@@ -1733,6 +1489,162 @@
 
 /*---------------------------------------------------------------------------*/
 
+#define	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_ml_sl(MR_label_name(MR_add_prefix(e), l1),	\
+		(MR_LabelLayout *) &MR_svar_label_layouts(m)[s1]);
+
+#define	MR_init_label_svi2(e, m, l1,s1, l2,s2)				\
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)
+
+#define	MR_init_label_svi3(e, m, l1,s1, l2,s2, l3,s3)			\
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)
+
+#define	MR_init_label_svi4(e, m, l1,s1, l2,s2, l3,s3, l4,s4)		\
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)				\
+	MR_init_label_svi1(e, m, l4, s4)
+
+#define	MR_init_label_svi5(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5)	\
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)				\
+	MR_init_label_svi1(e, m, l4, s4)				\
+	MR_init_label_svi1(e, m, l5, s5)
+
+#define	MR_init_label_svi6(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6) \
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)				\
+	MR_init_label_svi1(e, m, l4, s4)				\
+	MR_init_label_svi1(e, m, l5, s5)				\
+	MR_init_label_svi1(e, m, l6, s6)
+
+#define	MR_init_label_svi7(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7) \
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)				\
+	MR_init_label_svi1(e, m, l4, s4)				\
+	MR_init_label_svi1(e, m, l5, s5)				\
+	MR_init_label_svi1(e, m, l6, s6)				\
+	MR_init_label_svi1(e, m, l7, s7)
+
+#define	MR_init_label_svi8(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8) \
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)				\
+	MR_init_label_svi1(e, m, l4, s4)				\
+	MR_init_label_svi1(e, m, l5, s5)				\
+	MR_init_label_svi1(e, m, l6, s6)				\
+	MR_init_label_svi1(e, m, l7, s7)				\
+	MR_init_label_svi1(e, m, l8, s8)
+
+#define	MR_init_label_svi9(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9) \
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)				\
+	MR_init_label_svi1(e, m, l4, s4)				\
+	MR_init_label_svi1(e, m, l5, s5)				\
+	MR_init_label_svi1(e, m, l6, s6)				\
+	MR_init_label_svi1(e, m, l7, s7)				\
+	MR_init_label_svi1(e, m, l8, s8)				\
+	MR_init_label_svi1(e, m, l9, s9)
+
+#define	MR_init_label_svi10(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9, l10,s10) \
+	MR_init_label_svi1(e, m, l1, s1)				\
+	MR_init_label_svi1(e, m, l2, s2)				\
+	MR_init_label_svi1(e, m, l3, s3)				\
+	MR_init_label_svi1(e, m, l4, s4)				\
+	MR_init_label_svi1(e, m, l5, s5)				\
+	MR_init_label_svi1(e, m, l6, s6)				\
+	MR_init_label_svi1(e, m, l7, s7)				\
+	MR_init_label_svi1(e, m, l8, s8)				\
+	MR_init_label_svi1(e, m, l9, s9)				\
+	MR_init_label_svi1(e, m, l10, s10)
+
+/*---------------------------------------------------------------------------*/
+
+#define	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_ml_sl(MR_label_name(MR_add_prefix(e), l1),	\
+		&MR_lvar_label_layouts(m)[s1]);
+
+#define	MR_init_label_lvi2(e, m, l1,s1, l2,s2)				\
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)
+
+#define	MR_init_label_lvi3(e, m, l1,s1, l2,s2, l3,s3)			\
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)
+
+#define	MR_init_label_lvi4(e, m, l1,s1, l2,s2, l3,s3, l4,s4)		\
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)				\
+	MR_init_label_lvi1(e, m, l4, s4)
+
+#define	MR_init_label_lvi5(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5)	\
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)				\
+	MR_init_label_lvi1(e, m, l4, s4)				\
+	MR_init_label_lvi1(e, m, l5, s5)
+
+#define	MR_init_label_lvi6(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6) \
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)				\
+	MR_init_label_lvi1(e, m, l4, s4)				\
+	MR_init_label_lvi1(e, m, l5, s5)				\
+	MR_init_label_lvi1(e, m, l6, s6)
+
+#define	MR_init_label_lvi7(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7) \
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)				\
+	MR_init_label_lvi1(e, m, l4, s4)				\
+	MR_init_label_lvi1(e, m, l5, s5)				\
+	MR_init_label_lvi1(e, m, l6, s6)				\
+	MR_init_label_lvi1(e, m, l7, s7)
+
+#define	MR_init_label_lvi8(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8) \
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)				\
+	MR_init_label_lvi1(e, m, l4, s4)				\
+	MR_init_label_lvi1(e, m, l5, s5)				\
+	MR_init_label_lvi1(e, m, l6, s6)				\
+	MR_init_label_lvi1(e, m, l7, s7)				\
+	MR_init_label_lvi1(e, m, l8, s8)
+
+#define	MR_init_label_lvi9(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9) \
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)				\
+	MR_init_label_lvi1(e, m, l4, s4)				\
+	MR_init_label_lvi1(e, m, l5, s5)				\
+	MR_init_label_lvi1(e, m, l6, s6)				\
+	MR_init_label_lvi1(e, m, l7, s7)				\
+	MR_init_label_lvi1(e, m, l8, s8)				\
+	MR_init_label_lvi1(e, m, l9, s9)
+
+#define	MR_init_label_lvi10(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9, l10,s10) \
+	MR_init_label_lvi1(e, m, l1, s1)				\
+	MR_init_label_lvi1(e, m, l2, s2)				\
+	MR_init_label_lvi1(e, m, l3, s3)				\
+	MR_init_label_lvi1(e, m, l4, s4)				\
+	MR_init_label_lvi1(e, m, l5, s5)				\
+	MR_init_label_lvi1(e, m, l6, s6)				\
+	MR_init_label_lvi1(e, m, l7, s7)				\
+	MR_init_label_lvi1(e, m, l8, s8)				\
+	MR_init_label_lvi1(e, m, l9, s9)				\
+	MR_init_label_lvi1(e, m, l10, s10)
+
+/*---------------------------------------------------------------------------*/
+
 #define	MR_decl_extern_entry(e)						\
 	MR_declare_extern_entry(MR_add_prefix(e));
 
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.78
diff -u -b -r1.78 mercury_grade.h
--- runtime/mercury_grade.h	5 Sep 2008 11:19:33 -0000	1.78
+++ runtime/mercury_grade.h	23 Oct 2009 02:35:36 -0000
@@ -64,7 +64,7 @@
 */
 
 #define MR_GRADE_PART_0 v15_
-#define MR_GRADE_EXEC_TRACE_VERSION_NO  8
+#define MR_GRADE_EXEC_TRACE_VERSION_NO  9
 #define MR_GRADE_DEEP_PROF_VERSION_NO   3
 
 #ifdef MR_HIGHLEVEL_CODE
Index: runtime/mercury_layout_util.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_layout_util.c,v
retrieving revision 1.41
diff -u -b -r1.41 mercury_layout_util.c
--- runtime/mercury_layout_util.c	8 Jan 2007 09:15:22 -0000	1.41
+++ runtime/mercury_layout_util.c	28 Oct 2009 07:46:49 -0000
@@ -98,7 +98,7 @@
         type_params = (MR_TypeInfoParams) MR_NEW_ARRAY(MR_Word, count + 1);
 
         for (i = 0; i < count; i++) {
-            if (tvar_locns->MR_tp_param_locns[i].MR_long_lval != 0) {
+            if (tvar_locns->MR_tp_param_locns[i] != 0) {
                 type_params[i + 1] = (MR_TypeInfo)
                     MR_lookup_long_lval_base(tvar_locns->MR_tp_param_locns[i],
                         saved_regs, base_sp, base_curfr, &succeeded);
@@ -132,7 +132,7 @@
         type_params = (MR_TypeInfoParams) MR_NEW_ARRAY(MR_Word, count + 1);
 
         for (i = 0; i < count; i++) {
-            if (tvar_locns->MR_tp_param_locns[i].MR_long_lval != 0) {
+            if (tvar_locns->MR_tp_param_locns[i] != 0) {
                 type_params[i + 1] = (MR_TypeInfo)
                     MR_lookup_closure_long_lval(
                         tvar_locns->MR_tp_param_locns[i], closure, &succeeded);
@@ -166,7 +166,7 @@
         type_params = (MR_TypeInfoParams) MR_NEW_ARRAY(MR_Word, count + 1);
 
         for (i = 0; i < count; i++) {
-            if (tvar_locns->MR_tp_param_locns[i].MR_long_lval != 0)
+            if (tvar_locns->MR_tp_param_locns[i] != 0)
             {
                 type_params[i + 1] = (MR_TypeInfo)
                     MR_lookup_typeclass_info_long_lval(
@@ -199,7 +199,7 @@
         type_params = (MR_TypeInfoParams) MR_NEW_ARRAY(MR_Word, count + 1);
 
         for (i = 0; i < count; i++) {
-            if (tvar_locns->MR_tp_param_locns[i].MR_long_lval != 0) {
+            if (tvar_locns->MR_tp_param_locns[i] != 0) {
                 type_params[i + 1] = (MR_TypeInfo)
                     MR_lookup_answer_block_long_lval(
                         tvar_locns->MR_tp_param_locns[i], answer_block,
@@ -325,11 +325,10 @@
             break;
 
         case MR_LONG_LVAL_TYPE_INDIRECT:
-            indirect_lval.MR_long_lval = locn_num;
+            indirect_lval = locn_num;
 
             offset = MR_LONG_LVAL_INDIRECT_OFFSET(indirect_lval);
-            sublocn.MR_long_lval =
-                MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
+            sublocn = MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
 
             if (MR_print_locn) {
                 printf("closure offset %d from ", offset);
@@ -445,11 +444,10 @@
             break;
 
         case MR_LONG_LVAL_TYPE_INDIRECT:
-            indirect_lval.MR_long_lval = locn_num;
+            indirect_lval = locn_num;
 
             offset = MR_LONG_LVAL_INDIRECT_OFFSET(indirect_lval);
-            sublocn.MR_long_lval =
-                MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
+            sublocn = MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
 
             if (MR_print_locn) {
                 printf("typeclassinfo offset %d from ", offset);
@@ -562,11 +560,10 @@
             break;
 
         case MR_LONG_LVAL_TYPE_INDIRECT:
-            indirect_lval.MR_long_lval = locn_num;
+            indirect_lval = locn_num;
 
             offset = MR_LONG_LVAL_INDIRECT_OFFSET(indirect_lval);
-            sublocn.MR_long_lval =
-                MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
+            sublocn = MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
 
             if (MR_print_locn) {
                 printf("answer_block offset %d from ", offset);
@@ -683,11 +680,10 @@
             break;
 
         case MR_LONG_LVAL_TYPE_INDIRECT:
-            indirect_lval.MR_long_lval = locn_num;
+            indirect_lval = locn_num;
 
             offset = MR_LONG_LVAL_INDIRECT_OFFSET(indirect_lval);
-            sublocn.MR_long_lval =
-                MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
+            sublocn = MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(indirect_lval);
 
             if (MR_print_locn) {
                 printf("long offset %d from ", offset);
@@ -835,25 +831,26 @@
     MR_bool             succeeded;
     MR_LongLval         long_locn;
     MR_ShortLval        short_locn;
+    int                 num_longs;
 
     pseudo_type_info = MR_var_pti(label_layout, i);
     *type_info = MR_create_type_info(type_params, pseudo_type_info);
 
-    if (i < MR_long_desc_var_count(label_layout)) {
+    num_longs = MR_long_desc_var_count(label_layout);
+    if (i < num_longs) {
         if (MR_print_locn) {
-            printf("looking up long lval\n");
+            printf("looking up long lval: ");
         }
 
-        long_locn.MR_long_lval =
-            MR_long_desc_var_locn(label_layout, i).MR_long_lval;
+        long_locn = MR_long_desc_var_locn(label_layout, i);
         *value = MR_lookup_long_lval_base(long_locn,
             saved_regs, base_sp, base_curfr, &succeeded);
     } else {
         if (MR_print_locn) {
-            printf("looking up short lval\n");
+            printf("looking up short lval: ");
         }
 
-        short_locn = MR_short_desc_var_locn(label_layout, i),
+        short_locn = MR_short_desc_var_locn(label_layout, i - num_longs),
         *value = MR_lookup_short_lval_base(short_locn,
             saved_regs, base_sp, base_curfr, &succeeded);
     }
Index: runtime/mercury_misc.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_misc.h,v
retrieving revision 1.28
diff -u -b -r1.28 mercury_misc.h
--- runtime/mercury_misc.h	24 Apr 2006 04:38:41 -0000	1.28
+++ runtime/mercury_misc.h	28 Oct 2009 03:08:38 -0000
@@ -43,6 +43,8 @@
 
 extern	void	MR_perform_registered_exception_cleanups(void);
 
+/*---------------------------------------------------------------------------*/
+
 /*
 ** These macros are shorthands to allow reductions in the size of compiler
 ** generated C source files.
@@ -66,4 +68,292 @@
 #define	MR_TAG_XCOMMON(tag, typenum, cellnum)			\
 	(MR_mkword(MR_mktag(tag), MR_XCOMMON(typenum, cellnum)))
 
+/*---------------------------------------------------------------------------*/
+
+#define	MR_pseudo_type_infos(m)						\
+	MR_PASTE2(mercury_data__pseudo_type_info_array__, m)
+
+#define	MR_hlds_var_nums(m)						\
+	MR_PASTE2(mercury_data__hlds_var_nums_array__, m)
+
+#define	MR_short_locns(m)						\
+	MR_PASTE2(mercury_data__short_locns_array__, m)
+
+#define	MR_long_locns(m)						\
+	MR_PASTE2(mercury_data__long_locns_array__, m)
+
+#define	MR_user_event_var_nums(m)					\
+	MR_PASTE2(mercury_data__user_event_var_nums_array__, m)
+
+#define	MR_user_event_layouts(m)					\
+	MR_PASTE2(mercury_data__user_event_layouts_array__, m)
+
+#define	MR_no_var_label_layouts(m)					\
+	MR_PASTE2(mercury_data__no_var_label_layout_array__, m)
+
+#define	MR_svar_label_layouts(m)					\
+	MR_PASTE2(mercury_data__svar_label_layout_array__, m)
+
+#define	MR_lvar_label_layouts(m)					\
+	MR_PASTE2(mercury_data__lvar_label_layout_array__, m)
+
+/*---------------------------------------------------------------------------*/
+
+#define	MR_proc_call_sites(m)						\
+	MR_PASTE2(mercury_data__proc_call_sites_array__, m)
+
+#define	MR_proc_cp_statics(m)						\
+	MR_PASTE2(mercury_data__proc_cp_statics_array__, m)
+
+#define	MR_proc_cp_dynamics(m)						\
+	MR_PASTE2(mercury_data__proc_cp_dynamics_array__, m)
+
+#define	MR_proc_statics(m)						\
+	MR_PASTE2(mercury_data__proc_statics_array__, m)
+
+#define	MR_proc_head_var_nums(m)					\
+	MR_PASTE2(mercury_data__proc_head_var_nums_array__, m)
+
+#define	MR_proc_var_names(m)						\
+	MR_PASTE2(mercury_data__proc_var_names_array__, m)
+
+#define	MR_proc_body_bytecodes(m)					\
+	MR_PASTE2(mercury_data__proc_body_bytecodes_array__, m)
+
+#define	MR_proc_table_io_decls(m)					\
+	MR_PASTE2(mercury_data__proc_table_io_decls_array__, m)
+
+#define	MR_proc_event_layouts(m)					\
+	MR_PASTE2(mercury_data__proc_event_layouts_array__, m)
+
+#define	MR_proc_exec_traces(m)						\
+	MR_PASTE2(mercury_data__proc_exec_traces_array__, m)
+
+/*---------------------------------------------------------------------------*/
+
+#define	MR_no_var_label_layout_refs1(m, s1)				\
+	&MR_no_var_label_layouts(m)[s1],
+
+#define	MR_no_var_label_layout_refs2(m, s1, s2)				\
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)
+
+#define	MR_no_var_label_layout_refs3(m, s1, s2, s3) 			\
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)
+
+#define	MR_no_var_label_layout_refs4(m, s1, s2, s3, s4) 		\
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)				\
+	MR_no_var_label_layout_refs1(m, s4)
+
+#define	MR_no_var_label_layout_refs5(m, s1, s2, s3, s4, s5) 		\
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)				\
+	MR_no_var_label_layout_refs1(m, s4)				\
+	MR_no_var_label_layout_refs1(m, s5)
+
+#define	MR_no_var_label_layout_refs6(m, s1, s2, s3, s4, s5, s6) 	\
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)				\
+	MR_no_var_label_layout_refs1(m, s4)				\
+	MR_no_var_label_layout_refs1(m, s5)				\
+	MR_no_var_label_layout_refs1(m, s6)
+
+#define	MR_no_var_label_layout_refs7(m, s1, s2, s3, s4, s5, s6, s7) 	\
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)				\
+	MR_no_var_label_layout_refs1(m, s4)				\
+	MR_no_var_label_layout_refs1(m, s5)				\
+	MR_no_var_label_layout_refs1(m, s6)				\
+	MR_no_var_label_layout_refs1(m, s7)
+
+#define	MR_no_var_label_layout_refs8(m, s1, s2, s3, s4, s5, s6, s7, s8)	\
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)				\
+	MR_no_var_label_layout_refs1(m, s4)				\
+	MR_no_var_label_layout_refs1(m, s5)				\
+	MR_no_var_label_layout_refs1(m, s6)				\
+	MR_no_var_label_layout_refs1(m, s7)				\
+	MR_no_var_label_layout_refs1(m, s8)
+
+#define	MR_no_var_label_layout_refs9(m, s1, s2, s3, s4, s5, s6, s7, s8, s9) \
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)				\
+	MR_no_var_label_layout_refs1(m, s4)				\
+	MR_no_var_label_layout_refs1(m, s5)				\
+	MR_no_var_label_layout_refs1(m, s6)				\
+	MR_no_var_label_layout_refs1(m, s7)				\
+	MR_no_var_label_layout_refs1(m, s8)				\
+	MR_no_var_label_layout_refs1(m, s9)
+
+#define	MR_no_var_label_layout_refs10(m, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
+	MR_no_var_label_layout_refs1(m, s1)				\
+	MR_no_var_label_layout_refs1(m, s2)				\
+	MR_no_var_label_layout_refs1(m, s3)				\
+	MR_no_var_label_layout_refs1(m, s4)				\
+	MR_no_var_label_layout_refs1(m, s5)				\
+	MR_no_var_label_layout_refs1(m, s6)				\
+	MR_no_var_label_layout_refs1(m, s7)				\
+	MR_no_var_label_layout_refs1(m, s8)				\
+	MR_no_var_label_layout_refs1(m, s9)				\
+	MR_no_var_label_layout_refs1(m, s10)
+
+#define	MR_svar_label_layout_refs1(m, s1)				\
+	(MR_LabelLayout *) &MR_svar_label_layouts(m)[s1],
+
+#define	MR_svar_label_layout_refs2(m, s1, s2) 				\
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)
+
+#define	MR_svar_label_layout_refs3(m, s1, s2, s3) 			\
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)
+
+#define	MR_svar_label_layout_refs4(m, s1, s2, s3, s4) 			\
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)				\
+	MR_svar_label_layout_refs1(m, s4)
+
+#define	MR_svar_label_layout_refs5(m, s1, s2, s3, s4, s5) 		\
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)				\
+	MR_svar_label_layout_refs1(m, s4)				\
+	MR_svar_label_layout_refs1(m, s5)
+
+#define	MR_svar_label_layout_refs6(m, s1, s2, s3, s4, s5, s6) 		\
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)				\
+	MR_svar_label_layout_refs1(m, s4)				\
+	MR_svar_label_layout_refs1(m, s5)				\
+	MR_svar_label_layout_refs1(m, s6)
+
+#define	MR_svar_label_layout_refs7(m, s1, s2, s3, s4, s5, s6, s7) 	\
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)				\
+	MR_svar_label_layout_refs1(m, s4)				\
+	MR_svar_label_layout_refs1(m, s5)				\
+	MR_svar_label_layout_refs1(m, s6)				\
+	MR_svar_label_layout_refs1(m, s7)
+
+#define	MR_svar_label_layout_refs8(m, s1, s2, s3, s4, s5, s6, s7, s8) 	\
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)				\
+	MR_svar_label_layout_refs1(m, s4)				\
+	MR_svar_label_layout_refs1(m, s5)				\
+	MR_svar_label_layout_refs1(m, s6)				\
+	MR_svar_label_layout_refs1(m, s7)				\
+	MR_svar_label_layout_refs1(m, s8)
+
+#define	MR_svar_label_layout_refs9(m, s1, s2, s3, s4, s5, s6, s7, s8, s9) \
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)				\
+	MR_svar_label_layout_refs1(m, s4)				\
+	MR_svar_label_layout_refs1(m, s5)				\
+	MR_svar_label_layout_refs1(m, s6)				\
+	MR_svar_label_layout_refs1(m, s7)				\
+	MR_svar_label_layout_refs1(m, s8)				\
+	MR_svar_label_layout_refs1(m, s9)
+
+#define	MR_svar_label_layout_refs10(m, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
+	MR_svar_label_layout_refs1(m, s1)				\
+	MR_svar_label_layout_refs1(m, s2)				\
+	MR_svar_label_layout_refs1(m, s3)				\
+	MR_svar_label_layout_refs1(m, s4)				\
+	MR_svar_label_layout_refs1(m, s5)				\
+	MR_svar_label_layout_refs1(m, s6)				\
+	MR_svar_label_layout_refs1(m, s7)				\
+	MR_svar_label_layout_refs1(m, s8)				\
+	MR_svar_label_layout_refs1(m, s9)				\
+	MR_svar_label_layout_refs1(m, s10)
+
+#define	MR_lvar_label_layout_refs1(m, s1)				\
+	&MR_lvar_label_layouts(m)[s1],
+
+#define	MR_lvar_label_layout_refs2(m, s1, s2) 				\
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)
+
+#define	MR_lvar_label_layout_refs3(m, s1, s2, s3) 			\
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)
+
+#define	MR_lvar_label_layout_refs4(m, s1, s2, s3, s4) 			\
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)				\
+	MR_lvar_label_layout_refs1(m, s4)
+
+#define	MR_lvar_label_layout_refs5(m, s1, s2, s3, s4, s5) 		\
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)				\
+	MR_lvar_label_layout_refs1(m, s4)				\
+	MR_lvar_label_layout_refs1(m, s5)
+
+#define	MR_lvar_label_layout_refs6(m, s1, s2, s3, s4, s5, s6) 		\
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)				\
+	MR_lvar_label_layout_refs1(m, s4)				\
+	MR_lvar_label_layout_refs1(m, s5)				\
+	MR_lvar_label_layout_refs1(m, s6)
+
+#define	MR_lvar_label_layout_refs7(m, s1, s2, s3, s4, s5, s6, s7) 	\
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)				\
+	MR_lvar_label_layout_refs1(m, s4)				\
+	MR_lvar_label_layout_refs1(m, s5)				\
+	MR_lvar_label_layout_refs1(m, s6)				\
+	MR_lvar_label_layout_refs1(m, s7)
+
+#define	MR_lvar_label_layout_refs8(m, s1, s2, s3, s4, s5, s6, s7, s8) 	\
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)				\
+	MR_lvar_label_layout_refs1(m, s4)				\
+	MR_lvar_label_layout_refs1(m, s5)				\
+	MR_lvar_label_layout_refs1(m, s6)				\
+	MR_lvar_label_layout_refs1(m, s7)				\
+	MR_lvar_label_layout_refs1(m, s8)
+
+#define	MR_lvar_label_layout_refs9(m, s1, s2, s3, s4, s5, s6, s7, s8, s9) \
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)				\
+	MR_lvar_label_layout_refs1(m, s4)				\
+	MR_lvar_label_layout_refs1(m, s5)				\
+	MR_lvar_label_layout_refs1(m, s6)				\
+	MR_lvar_label_layout_refs1(m, s7)				\
+	MR_lvar_label_layout_refs1(m, s8)				\
+	MR_lvar_label_layout_refs1(m, s9)
+
+#define	MR_lvar_label_layout_refs10(m, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
+	MR_lvar_label_layout_refs1(m, s1)				\
+	MR_lvar_label_layout_refs1(m, s2)				\
+	MR_lvar_label_layout_refs1(m, s3)				\
+	MR_lvar_label_layout_refs1(m, s4)				\
+	MR_lvar_label_layout_refs1(m, s5)				\
+	MR_lvar_label_layout_refs1(m, s6)				\
+	MR_lvar_label_layout_refs1(m, s7)				\
+	MR_lvar_label_layout_refs1(m, s8)				\
+	MR_lvar_label_layout_refs1(m, s9)				\
+	MR_lvar_label_layout_refs1(m, s10)
+
 #endif /* not MERCURY_MISC_H */
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.117
diff -u -b -r1.117 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	21 Oct 2009 06:36:35 -0000	1.117
+++ runtime/mercury_stack_layout.h	28 Oct 2009 07:24:31 -0000
@@ -44,7 +44,7 @@
 
 /*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_Determinism
+** Definitions for MR_Determinism.
 */
 
 /*
@@ -86,11 +86,11 @@
 
 /*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_LongLval and MR_ShortLval
+** Definitions for MR_LongLval and MR_ShortLval.
 */
 
 /*
-** MR_LongLval is a MR_Unsigned which describes a location.
+** MR_LongLval is a MR_int_least32_t which describes a location.
 ** This includes lvals such as stack slots, general registers, and special
 ** registers such as succip, hp, etc, as well as locations whose address is
 ** given as a typeinfo inside the type class info structure pointed to by an
@@ -124,18 +124,15 @@
 ** (a) an integer with MR_LONG_LVAL_OFFSETBITS bits giving the index of
 ** the typeinfo inside a type class info (to be interpreted by
 ** MR_typeclass_info_type_info or the predicate
-** private_builtin:type_info_from_typeclass_info, which calls it) and
+** private_builtin.type_info_from_typeclass_info, which calls it) and
 ** (b) a MR_LongLval value giving the location of the pointer to the
-** type class info. This MR_LongLval value will *not* have an indirect
-** tag.
+** type class info. This MR_LongLval value will *not* have an indirect tag.
 **
 ** This data is generated in stack_layout.represent_locn_as_int,
 ** which must be kept in sync with the constants and macros defined here.
 */
 
-struct MR_LongLval_Struct {
-    MR_Unsigned MR_long_lval;
-};
+typedef MR_uint_least32_t   MR_LongLval;
 
 typedef enum {
     MR_LONG_LVAL_TYPE_CONS_0,
@@ -161,26 +158,22 @@
 #define MR_LONG_LVAL_CONST_TAGBITS  2
 
 #define MR_LONG_LVAL_TYPE(Locn)                                             \
-    ((MR_LongLvalType)                                                      \
-        ((Locn).MR_long_lval & ((1 << MR_LONG_LVAL_TAGBITS) - 1)))
+    ((MR_LongLvalType) ((Locn) & ((1 << MR_LONG_LVAL_TAGBITS) - 1)))
 
 #define MR_LONG_LVAL_NUMBER(Locn)                                           \
-    ((int) (Locn).MR_long_lval >> MR_LONG_LVAL_TAGBITS)
+    ((int) ((Locn) >> MR_LONG_LVAL_TAGBITS))
 
 #define MR_LONG_LVAL_CONST(Locn)                                            \
-    (* (MR_Word *) ((Locn).MR_long_lval &                                   \
-        ~ ((1 << MR_LONG_LVAL_CONST_TAGBITS) - 1)))
+    (* (MR_Word *) ((Locn) & ~ ((1 << MR_LONG_LVAL_CONST_TAGBITS) - 1)))
 
 /* This must be in sync with stack_layout.offset_bits */
 #define MR_LONG_LVAL_OFFSETBITS 6
 
 #define MR_LONG_LVAL_INDIRECT_OFFSET(LocnNumber)                            \
-    ((int) ((LocnNumber).MR_long_lval &                                     \
-        ((1 << MR_LONG_LVAL_OFFSETBITS) - 1)))
+    ((int) ((LocnNumber) & ((1 << MR_LONG_LVAL_OFFSETBITS) - 1)))
 
 #define MR_LONG_LVAL_INDIRECT_BASE_LVAL_INT(LocnNumber)                     \
-    (((MR_uint_least32_t) (LocnNumber).MR_long_lval)                        \
-        >> MR_LONG_LVAL_OFFSETBITS)
+    (((MR_uint_least32_t) (LocnNumber)) >> MR_LONG_LVAL_OFFSETBITS)
 
 #define MR_LONG_LVAL_STACKVAR_INT(n)                                        \
     (((n) << MR_LONG_LVAL_TAGBITS) + MR_LONG_LVAL_TYPE_STACKVAR)
@@ -228,7 +221,7 @@
         (((MR_Word) Locn) & ((1 << MR_SHORT_LVAL_TAGBITS) - 1)))
 
 #define MR_SHORT_LVAL_NUMBER(Locn)                                          \
-    ((int) ((MR_Word) Locn) >> MR_SHORT_LVAL_TAGBITS)
+    ((int) (((MR_Word) Locn) >> MR_SHORT_LVAL_TAGBITS))
 
 #define MR_SHORT_LVAL_STACKVAR(n)                                           \
     ((MR_ShortLval) (((n) << MR_SHORT_LVAL_TAGBITS)                         \
@@ -244,7 +237,7 @@
 
 /*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_UserEvent and MR_UserEventSpec
+** Definitions for MR_UserEvent and MR_UserEventSpec.
 */
 
 /*
@@ -353,7 +346,7 @@
 
 /*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_LabelLayout
+** Definitions for MR_LabelLayout.
 */
 
 /*
@@ -390,9 +383,9 @@
 **
 ** The remaining fields give information about the values live at the given
 ** label, if this information is available. If it is available, the
-** MR_has_valid_var_count macro will return true and the last three fields are
-** meaningful; if it is not available, the macro will return false and the last
-** three fields are not meaningful (i.e. you are looking at an
+** MR_has_valid_var_count macro will return true and the fields after the count
+** are meaningful; if it is not available, the macro will return false and
+** those fields are not meaningful (i.e. you are looking at an
 ** MR_LabelLayoutNoVarInfo structure).
 **
 ** The format in which we store information about the values live at the label
@@ -411,17 +404,20 @@
 ** the values need to be distinct; this is why MR_SHORT_COUNT_BITS is
 ** more than 8.)
 **
-** The MR_sll_locns_types field points to a memory area that contains three
-** vectors back to back. The first vector has #Long + #Short word-sized
-** elements, each of which is a pointer to a MR_PseudoTypeInfo giving the type
-** of a live data item, with a small integer instead of a pointer representing
-** a special kind of live data item (e.g. a saved succip or hp). The second
-** vector is an array of #Long MR_LongLvals, and the third is an array of
-** #Short MR_ShortLvals, each of which describes a location. The
-** pseudotypeinfo pointed to by the slot at subscript i in the first vector
-** describes the type of the data stored in slot i in the second vector if
-** i < #Long, and the type of the data stored in slot i - #Long in the third
-** vector otherwise.
+** The MR_sll_types field points to an array of #Long + #Short
+** MR_PseudoTypeInfos each giving the type of a live data item, with
+** a small integer instead of a pointer representing a special kind of
+** live data item (e.g. a saved succip or hp). This field will be null if 
+** #Long + #Short is zero.
+**
+** The MR_sll_long_locns field points to an array of #Long MR_LongLvals,
+** while the MR_sll_short_locns field points to an array of #Short
+** MR_ShortLvals. The element at index i in the MR_sll_long_locns vector
+** will have its type described by the element at index i in the MR_sll_types
+** vector, while the element at index i in the MR_sll_short_locns vector
+** will have its type described by the element at index #Long + i in the
+** MR_sll_types vector. MR_sll_long_locns will be NULL if #Long is zero,
+** and similarly MR_sll_short_locns will be NULL if #Short is zero.
 **
 ** The MR_sll_var_nums field may be NULL, which means that there is no
 ** information about the variable numbers of the live values. If the field
@@ -444,8 +440,8 @@
 ** parameters can materialize all the type parameters from their location
 ** descriptions in one go. This is an optimization, since the type parameter
 ** vector could simply be indexed on demand by the type variable's variable
-** number stored within the MR_PseudoTypeInfos stored inside the first vector
-** pointed to by the MR_sll_locns_types field.
+** number stored within the MR_PseudoTypeInfos stored inside the vector
+** pointed to by the MR_sll_types field.
 **
 ** Since we allocate type variable numbers sequentially, the MR_tp_param_locns
 ** vector will usually be dense. However, after all variables whose types
@@ -486,12 +482,28 @@
     MR_uint_least16_t       MR_sll_label_num_in_module;
     MR_uint_least32_t       MR_sll_goal_path;
     const MR_UserEvent      *MR_sll_user_event;
-    MR_Integer              MR_sll_var_count; /* >= 0 */
-    const void              *MR_sll_locns_types;
-    const MR_HLDSVarNum     *MR_sll_var_nums;
+    MR_Integer              MR_sll_var_count; /* >= 0, encoding Long > 0 */
     const MR_TypeParamLocns *MR_sll_tvars;
+    const MR_PseudoTypeInfo *MR_sll_types;
+    const MR_HLDSVarNum     *MR_sll_var_nums;
+    const MR_ShortLval      *MR_sll_short_locns;
+    const MR_LongLval       *MR_sll_long_locns;
 };
 
+typedef struct MR_LabelLayoutShort_Struct {
+    const MR_ProcLayout     *MR_sll_entry;
+    MR_int_least8_t         MR_sll_port;
+    MR_int_least8_t         MR_sll_hidden;
+    MR_uint_least16_t       MR_sll_label_num_in_module;
+    MR_uint_least32_t       MR_sll_goal_path;
+    const MR_UserEvent      *MR_sll_user_event;
+    MR_Integer              MR_sll_var_count; /* >= 0 , encoding Long == 0*/
+    const MR_TypeParamLocns *MR_sll_tvars;
+    const MR_PseudoTypeInfo *MR_sll_types;
+    const MR_HLDSVarNum     *MR_sll_var_nums;
+    const MR_ShortLval      *MR_sll_short_locns;
+} MR_LabelLayoutShort;
+
 typedef struct MR_LabelLayoutNoVarInfo_Struct {
     const MR_ProcLayout     *MR_sll_entry;
     MR_int_least8_t         MR_sll_port;
@@ -516,25 +528,19 @@
         (((sll)->MR_sll_var_count) >= 0)
 #define MR_has_valid_var_info(sll)                                          \
         (((sll)->MR_sll_var_count) > 0)
-#define MR_long_desc_var_count(sll)                                         \
-        (((sll)->MR_sll_var_count) >> MR_SHORT_COUNT_BITS)
 #define MR_short_desc_var_count(sll)                                        \
         (((sll)->MR_sll_var_count) & MR_SHORT_COUNT_MASK)
+#define MR_long_desc_var_count(sll)                                         \
+        (((sll)->MR_sll_var_count) >> MR_SHORT_COUNT_BITS)
 #define MR_all_desc_var_count(sll)                                          \
         (MR_long_desc_var_count(sll) + MR_short_desc_var_count(sll))
 
 #define MR_var_pti(sll, i)                                                  \
-        (((MR_PseudoTypeInfo *) ((sll)->MR_sll_locns_types))[(i)])
-#define MR_end_of_var_ptis(sll)                                             \
-        (&MR_var_pti((sll), MR_all_desc_var_count(sll)))
-#define MR_long_desc_var_locn(sll, i)                                       \
-        (((MR_LongLval *) MR_end_of_var_ptis(sll))[(i)])
-#define MR_end_of_long_desc_var_locns(sll)                                  \
-        (&MR_long_desc_var_locn((sll), MR_long_desc_var_count(sll)))
+        ((sll)->MR_sll_types[(i)])
 #define MR_short_desc_var_locn(sll, i)                                      \
-        (((MR_ShortLval *)                                                  \
-            MR_end_of_long_desc_var_locns(sll))                             \
-                [((i) - MR_long_desc_var_count(sll))])
+        ((sll)->MR_sll_short_locns[(i)])
+#define MR_long_desc_var_locn(sll, i)                                       \
+        ((sll)->MR_sll_long_locns[(i)])
 
 /*
 ** Define a stack layout for an internal label.
@@ -574,6 +580,11 @@
 ** the others are the fields of MR_LabelLayouts.
 */
 
+/*
+** The following macros are obsolete. They should be deleted as soon as
+** workspaces referring to them have been updated and recompiled.
+*/
+
 #define MR_DEF_LL_GEN(e, ln, port, h, num, path, ue, vc, lt, vn, tv)        \
     static const MR_LabelLayout                                             \
         MR_LABEL_LAYOUT_NAME(MR_label_name(MR_add_prefix(e), ln))           \
@@ -613,55 +624,55 @@
 
 #define MR_DEF_LLXCCC(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc, tvt, tvc)\
     MR_DEF_LL_GEN(e, ln, port, MR_FALSE, num, path, NULL, vc,               \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc),                                               \
-        MR_XCOMMON(tvt, tvc))
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc),                                                \
+        MR_COMMON(tvt, tvc))
 
 #define MR_DEF_LLXCC0(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc)       \
     MR_DEF_LL_GEN(e, ln, port, MR_FALSE, num, path, NULL, vc,               \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc), 0)
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc), 0)
 
 #define MR_DEF_LLTXCCC(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc, tvt,tvc)\
     MR_DEF_LL_GEN(e, ln, port, MR_TRUE, num, path, NULL, vc,                \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc),                                               \
-        MR_XCOMMON(tvt, tvc))
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc),                                                \
+        MR_COMMON(tvt, tvc))
 
 #define MR_DEF_LLTXCC0(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc)      \
     MR_DEF_LL_GEN(e, ln, port, MR_TRUE, num, path, NULL, vc,                \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc), 0)
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc), 0)
 
 #define MR_DEF_LLXCCC_U(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc, tvt, tvc)\
     MR_DEF_LL_GEN(e, ln, port, MR_FALSE, num, path,                         \
         &MR_USER_LAYOUT_NAME(MR_label_name(MR_add_prefix(e), ln)),          \
         vc,                                                                 \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc),                                               \
-        MR_XCOMMON(tvt, tvc))
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc),                                                \
+        MR_COMMON(tvt, tvc))
 
 #define MR_DEF_LLXCC0_U(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc)     \
     MR_DEF_LL_GEN(e, ln, port, MR_FALSE, num, path,                         \
         &MR_USER_LAYOUT_NAME(MR_label_name(MR_add_prefix(e), ln)),          \
         vc,                                                                 \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc), 0)
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc), 0)
 
 #define MR_DEF_LLTXCCC_U(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc, tvt,tvc)\
     MR_DEF_LL_GEN(e, ln, port, MR_TRUE, num, path,                          \
         &MR_USER_LAYOUT_NAME(MR_label_name(MR_add_prefix(e), ln)),          \
         vc,                                                                 \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc),                                               \
-        MR_XCOMMON(tvt, tvc))
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc),                                                \
+        MR_COMMON(tvt, tvc))
 
 #define MR_DEF_LLTXCC0_U(e, ln, port, num, path, vc, ltt, ltc, vnt, vnc)    \
     MR_DEF_LL_GEN(e, ln, port, MR_TRUE, num, path,                          \
         &MR_USER_LAYOUT_NAME(MR_label_name(MR_add_prefix(e), ln)),          \
         vc,                                                                 \
-        MR_XCOMMON(ltt, ltc),                                               \
-        MR_XCOMMON(vnt, vnc), 0)
+        MR_COMMON(ltt, ltc),                                                \
+        MR_COMMON(vnt, vnc), 0)
 
 #define MR_DEF_LLNVI(e, ln, port, num, path)                                \
     MR_DEF_LLNVI_GEN(e, ln, port, MR_FALSE, path, NULL)
@@ -772,57 +783,156 @@
 **
 ** We need to cast the addresses of proc layout structures because there
 ** are several kinds of proc layouts, of different (though compatible) types.
-**
-** We need to cast the values we intend to put into the MR_sll_locns_types,
-** MR_sll_var_nums and MR_sll_tvars field because (due to our representation
-** scheme, documented with the MR_LabelLayout type) the values supplied by
-** the compiler will usually be references to slots in arrays of data-specific
-** types.
 */
 
-#define MR_LLC(e, port, num, path)                                          \
+#define MR_LL(e, port, num, path)                                           \
         MR_PROC_LAYOUT(MR_add_prefix(e)),                                   \
         MR_PASTE2(MR_PORT_, port),                                          \
         MR_NOT_HIDDEN, (num), (path), NULL
 
-#define MR_LLC_H(e, port, num, path)                                        \
+#define MR_LL_H(e, port, num, path)                                         \
         MR_PROC_LAYOUT(MR_add_prefix(e)),                                   \
         MR_PASTE2(MR_PORT_, port),                                          \
         MR_HIDDEN, (num), (path), NULL
 
-#define MR_LLC_U(e, port, num, path, ue)                                    \
+#define MR_LL_U(e, port, num, path, ue)                                     \
         MR_PROC_LAYOUT(MR_add_prefix(e)),                                   \
         MR_PASTE2(MR_PORT_, port),                                          \
         MR_NOT_HIDDEN, (num), (path), (ue)
 
-#define MR_LLC_H_U(e, port, num, path, ue)                                  \
+#define MR_LL_H_U(e, port, num, path, ue)                                   \
         MR_PROC_LAYOUT(MR_add_prefix(e)),                                   \
         MR_PASTE2(MR_PORT_, port),                                          \
         MR_HIDDEN, (num), (path), (ue)
 
+#if 0
+/* these are new but already obsolete */
 #define MR_LLV(lt, vn, tp)                                                  \
         (const void *) (lt),                                                \
         (const MR_uint_least16_t *) (vn),                                   \
         (const MR_TypeParamLocns *) (tp)
 
 #define MR_LLV_CC(ltt, ltc, vnt, vnc, tp)                                   \
-        (const void *) MR_XCOMMON(ltt, ltc),                                \
-        (const MR_uint_least16_t *) MR_XCOMMON(vnt, vnc),                   \
+        (const void *) MR_COMMON(ltt, ltc),                                 \
+        (const MR_uint_least16_t *) MR_COMMON(vnt, vnc),                    \
         (const MR_TypeParamLocns *) (tp)
 
 #define MR_LLV_CCC(ltt, ltc, vnt, vnc, tpt, tpc)                            \
-        (const void *) MR_XCOMMON(ltt, ltc),                                \
-        (const MR_uint_least16_t *) MR_XCOMMON(vnt, vnc),                   \
-        (const MR_TypeParamLocns *) MR_XCOMMON(tpt, tpc)
+        (const void *) MR_COMMON(ltt, ltc),                                 \
+        (const MR_uint_least16_t *) MR_COMMON(vnt, vnc),                    \
+        (const MR_TypeParamLocns *) MR_COMMON(tpt, tpc)
 
 #define MR_LLV_CC0(ltt, ltc, vnt, vnc)                                      \
-        (const void *) MR_XCOMMON(ltt, ltc),                                \
-        (const MR_uint_least16_t *) MR_XCOMMON(vnt, vnc),                   \
+        (const void *) MR_COMMON(ltt, ltc),                                 \
+        (const MR_uint_least16_t *) MR_COMMON(vnt, vnc),                    \
         (const MR_TypeParamLocns *) 0
+#endif
+
+#define MR_LLVS(m, p, h, s)                                                 \
+        &MR_pseudo_type_infos(m)[p],                                        \
+        &MR_hlds_var_nums(m)[h],                                            \
+        &MR_short_locns(m)[s]
+
+#define MR_LLVL(m, p, h, s, l)                                              \
+        &MR_pseudo_type_infos(m)[p],                                        \
+        &MR_hlds_var_nums(m)[h],                                            \
+        &MR_short_locns(m)[s],                                              \
+        &MR_long_locns(m)[l]
+
+#define MR_LLVS0(m, p, h, s)                                                \
+        0,                                                                  \
+        MR_LLVS(m, p, h, s)
+
+#define MR_LLVL0(m, p, h, s, l)                                             \
+        0,                                                                  \
+        MR_LLVL(m, p, h, s, l)
+
+#define MR_LLVSC(m, tpt, tpc, p, h, s)                                      \
+        (const MR_TypeParamLocns *) MR_COMMON(tpt, tpc),                    \
+        MR_LLVS(m, p, h, s)
+
+#define MR_LLVLC(m, tpt, tpc, p, h, s, l)                                   \
+        (const MR_TypeParamLocns *) MR_COMMON(tpt, tpc),                    \
+        MR_LLVL(m, p, h, s, l)
+
+#define MR_cast_to_pti1(r1)                                                 \
+        (MR_PseudoTypeInfo) (r1),
+
+#define MR_cast_to_pti2(r1, r2)                                             \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),
+
+#define MR_cast_to_pti3(r1, r2, r3)                                         \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3)
+
+#define MR_cast_to_pti4(r1, r2, r3, r4)                                     \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3),                                           \
+        (MR_PseudoTypeInfo) (r4),
+
+#define MR_cast_to_pti5(r1, r2, r3, r4, r5)                                 \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3),                                           \
+        (MR_PseudoTypeInfo) (r4),                                           \
+        (MR_PseudoTypeInfo) (r5),
+
+#define MR_cast_to_pti6(r1, r2, r3, r4, r5, r6)                             \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3),                                           \
+        (MR_PseudoTypeInfo) (r4),                                           \
+        (MR_PseudoTypeInfo) (r5),                                           \
+        (MR_PseudoTypeInfo) (r6),
+
+#define MR_cast_to_pti7(r1, r2, r3, r4, r5, r6, r7)                         \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3),                                           \
+        (MR_PseudoTypeInfo) (r4),                                           \
+        (MR_PseudoTypeInfo) (r5),                                           \
+        (MR_PseudoTypeInfo) (r6),                                           \
+        (MR_PseudoTypeInfo) (r7),
+
+#define MR_cast_to_pti8(r1, r2, r3, r4, r5, r6, r7, r8)                     \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3),                                           \
+        (MR_PseudoTypeInfo) (r4),                                           \
+        (MR_PseudoTypeInfo) (r5),                                           \
+        (MR_PseudoTypeInfo) (r6),                                           \
+        (MR_PseudoTypeInfo) (r7),                                           \
+        (MR_PseudoTypeInfo) (r8),
+
+#define MR_cast_to_pti9(r1, r2, r3, r4, r5, r6, r7, r8, r9)                 \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3),                                           \
+        (MR_PseudoTypeInfo) (r4),                                           \
+        (MR_PseudoTypeInfo) (r5),                                           \
+        (MR_PseudoTypeInfo) (r6),                                           \
+        (MR_PseudoTypeInfo) (r7),                                           \
+        (MR_PseudoTypeInfo) (r8),                                           \
+        (MR_PseudoTypeInfo) (r9),
+
+#define MR_cast_to_pti10(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10)           \
+        (MR_PseudoTypeInfo) (r1),                                           \
+        (MR_PseudoTypeInfo) (r2),                                           \
+        (MR_PseudoTypeInfo) (r3),                                           \
+        (MR_PseudoTypeInfo) (r4),                                           \
+        (MR_PseudoTypeInfo) (r5),                                           \
+        (MR_PseudoTypeInfo) (r6),                                           \
+        (MR_PseudoTypeInfo) (r7),                                           \
+        (MR_PseudoTypeInfo) (r8),                                           \
+        (MR_PseudoTypeInfo) (r9),                                           \
+        (MR_PseudoTypeInfo) (r10),
 
 /*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_ProcLayout
+** Definitions for MR_ProcLayout.
 */
 
 /*
@@ -1070,10 +1180,7 @@
         }                                                                   \
     } while (0)
 
-/*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_ProcLayout
-**
 ** Proc layout structures contain one, two or three substructures.
 **
 ** - The first substructure is the MR_StackTraversal structure, which contains
@@ -1298,7 +1405,7 @@
             MR_MAKE_PROC_LAYOUT_ADDR(                                       \
                 MR_proc_entry_user_name(module, name,                       \
                     arity, mode)),                                          \
-            { succip_locn },                                                \
+            succip_locn,                                                    \
             slots,                                                          \
             detism                                                          \
         },                                                                  \
@@ -1324,7 +1431,7 @@
             MR_MAKE_PROC_LAYOUT_ADDR(                                       \
                 MR_proc_entry_uci_name(module, name,                        \
                     type, arity, mode)),                                    \
-            { succip_locn },                                                \
+            succip_locn,                                                    \
             slots,                                                          \
             detism                                                          \
         },                                                                  \
@@ -1429,7 +1536,7 @@
 
 /*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_ModuleLayout
+** Definitions for MR_ModuleLayout.
 **
 ** The layout structure for a module contains the following fields.
 **
@@ -1533,7 +1640,7 @@
 
 /*-------------------------------------------------------------------------*/
 /*
-** Definitions for MR_ClosureId
+** Definitions for MR_ClosureId.
 **
 ** Each closure contains an MR_ClosureId structure. The proc_id field
 ** identifies the procedure called by the closure. The other fields identify
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.84
diff -u -b -r1.84 mercury_stack_trace.c
--- runtime/mercury_stack_trace.c	1 Jun 2009 09:28:01 -0000	1.84
+++ runtime/mercury_stack_trace.c	23 Oct 2009 03:37:03 -0000
@@ -308,7 +308,7 @@
             proc_layout->MR_sle_stack_slots;
     } else {
         /* succip is always saved in succip_slot */
-        assert(location.MR_long_lval == -1);
+        assert(location == -1);
         /*
         ** Note that curfr always points to an ordinary procedure frame,
         ** never to a temp frame, and this property continues to hold
Index: runtime/mercury_type_info.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_type_info.h,v
retrieving revision 1.129
diff -u -b -r1.129 mercury_type_info.h
--- runtime/mercury_type_info.h	30 Oct 2008 06:45:59 -0000	1.129
+++ runtime/mercury_type_info.h	23 Oct 2009 02:45:36 -0000
@@ -88,8 +88,8 @@
 
 /*
 ** Check that the RTTI version is in a sensible range.
-** The lower bound should be the lowest currently supported version
-** number.  The upper bound is the current version number.
+** The lower bound should be the lowest currently supported version number.
+** The upper bound is the current version number.
 ** If you increase the lower bound you should also increase the binary
 ** compatibility version number in runtime/mercury_grade.h (MR_GRADE_PART_0).
 **
@@ -100,7 +100,7 @@
 */
 
 #define MR_TYPE_CTOR_INFO_CHECK_RTTI_VERSION_RANGE(typector)    \
-    assert((typector)->MR_type_ctor_version == MR_RTTI_VERSION__FUNCTOR_NUMBERS)
+    assert((typector)->MR_type_ctor_version >= MR_RTTI_VERSION__FUNCTOR_NUMBERS)
 
 /*---------------------------------------------------------------------------*/
 
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_types.h,v
retrieving revision 1.57
diff -u -b -r1.57 mercury_types.h
--- runtime/mercury_types.h	11 Jun 2009 08:28:32 -0000	1.57
+++ runtime/mercury_types.h	23 Oct 2009 02:40:01 -0000
@@ -247,7 +247,6 @@
 
 typedef struct MR_CallSiteDynList_Struct        MR_CallSiteDynList;
 
-typedef struct MR_LongLval_Struct               MR_LongLval;
 typedef struct MR_ProcLayout_Struct             MR_ProcLayout;
 typedef struct MR_ModuleCommonLayout_Struct     MR_ModuleCommonLayout;
 typedef struct MR_ModuleLayout_Struct           MR_ModuleLayout;
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.199
diff -u -b -r1.199 mercury_wrapper.c
--- runtime/mercury_wrapper.c	23 Aug 2009 22:52:35 -0000	1.199
+++ runtime/mercury_wrapper.c	24 Oct 2009 02:06:42 -0000
@@ -1266,8 +1266,10 @@
     { "small-det-stack-size-kwords",    1, 0, MR_SMALL_DETSTACK_SIZE_KWORDS },
     { "small-nondetstack-size",         1, 0, MR_SMALL_NONDETSTACK_SIZE },
     { "small-nondet-stack-size",        1, 0, MR_SMALL_NONDETSTACK_SIZE },
-    { "small-nondetstack-size-kwords",  1, 0, MR_SMALL_NONDETSTACK_SIZE_KWORDS },
-    { "small-nondet-stack-size-kwords", 1, 0, MR_SMALL_NONDETSTACK_SIZE_KWORDS },
+    { "small-nondetstack-size-kwords",
+        1, 0, MR_SMALL_NONDETSTACK_SIZE_KWORDS },
+    { "small-nondet-stack-size-kwords",
+        1, 0, MR_SMALL_NONDETSTACK_SIZE_KWORDS },
     { "solutions-heap-size",            1, 0, MR_SOLUTIONS_HEAP_SIZE },
     { "solutions-heap-size-kwords",     1, 0, MR_SOLUTIONS_HEAP_SIZE_KWORDS },
     { "trail-size",                     1, 0, MR_TRAIL_SIZE },
@@ -1342,8 +1344,10 @@
     { "coverage-test-if-exec",          1, 0, MR_COVERAGE_TEST_IF_EXEC_OPT },
     { "tc-output-file",                 1, 0, MR_TRACE_COUNT_FILE },
     { "trace-count-output-file",        1, 0, MR_TRACE_COUNT_FILE },
-    { "tc-summary-file",                1, 0, MR_TRACE_COUNT_SUMMARY_FILE_OPT },
-    { "trace-count-summary-file",       1, 0, MR_TRACE_COUNT_SUMMARY_FILE_OPT },
+    { "tc-summary-file",
+        1, 0, MR_TRACE_COUNT_SUMMARY_FILE_OPT },
+    { "trace-count-summary-file",
+        1, 0, MR_TRACE_COUNT_SUMMARY_FILE_OPT },
     { "tc-summary-cmd",                 1, 0, MR_TRACE_COUNT_SUMMARY_CMD_OPT },
     { "trace-count-summary-cmd",        1, 0, MR_TRACE_COUNT_SUMMARY_CMD_OPT },
     { "tc-summary-max",                 1, 0, MR_TRACE_COUNT_SUMMARY_MAX_OPT },
@@ -1947,9 +1951,9 @@
                     ** Particular rounding modes are only supported if the
                     ** corresponding FE_* macro is defined.  The four below are
                     ** the ones from C99.  C99 says that these macros
-                    ** should expand to a nonnegative value, so we use a negative value
-                    ** to indicate that the selected rounding mode is not supported by
-                    ** the system.
+                    ** should expand to a nonnegative value, so we use a
+                    ** negative value to indicate that the selected rounding
+                    ** mode is not supported by the system.
                     */
                     if (MR_streq(MR_optarg, "downward")) {
                         #if defined(FE_DOWNWARD)
@@ -1980,14 +1984,14 @@
                     }
 
                     if (rounding_mode < 0) {
-                        printf("Mercury runtime: the selected rounding mode is "
-                            "not supported by this system.\n");
+                        printf("Mercury runtime: the selected rounding mode "
+                            "is not supported by this system.\n");
                         fflush(stdout);
                         exit(1);
                     } else {
                         if (fesetround(rounding_mode) != 0) {
-                            printf("Mercury runtime: could not establish selected "
-                                "rounding mode.\n");
+                            printf("Mercury runtime: could not establish "
+                                "the selected rounding mode.\n");
                             fflush(stdout);
                             exit(1);
                         }
@@ -1996,7 +2000,8 @@
 #else
                 printf("Mercury runtime: `--fp-rounding-mode' is specified "
                     "in MERCURY_OPTIONS\n");
-                printf("but the rounding mode cannot be changed on this system.\n");
+                printf("but the rounding mode cannot be changed"
+                    "on this system.\n");
                 fflush(stdout);
                 exit(1);
 #endif
@@ -2070,6 +2075,8 @@
                     MR_watch_csd_start_name = strdup(MR_optarg+1);
                 } else if (MR_optarg[0] == 'j') {
                     MR_lld_start_name = strdup(MR_optarg+1);
+                } else if (MR_streq(MR_optarg, "l")) {
+                    MR_printlocndebug = MR_TRUE;
                 } else if (MR_streq(MR_optarg, "m")) {
                     MR_memdebug       = MR_TRUE;
                 } else if (MR_streq(MR_optarg, "o")) {
@@ -2476,7 +2483,8 @@
 
     if (use_own_timer) {
         printf("%8.3fu ",
-            ((double) (MR_user_time_at_finish - MR_user_time_at_start)) / 1000);
+            ((double) (MR_user_time_at_finish - MR_user_time_at_start))
+                / 1000);
     }
 
 #ifdef  MR_TYPE_CTOR_STATS
@@ -2488,9 +2496,8 @@
 #endif  /* MR_STACK_FRAME_STATS */
 
     /*
-    ** Save the Mercury registers and
-    ** restore the C callee-save registers before returning,
-    ** since they may be used by the C code that called us.
+    ** Save the Mercury registers and restore the C callee-save registers
+    ** before returning, since they may be used by the C code that called us.
     */
     MR_save_registers();
     MR_restore_regs_from_mem(c_regs);
@@ -2654,8 +2661,8 @@
     assert(pthread_self() == MR_primordial_thread);
     MR_LOCK(&MR_thread_barrier_lock, "MR_do_interpreter");
     while (MR_thread_barrier_count > 0) {
-        while (MR_WAIT(&MR_thread_barrier_cond, &MR_thread_barrier_lock) != 0) {
-        }
+        while (MR_WAIT(&MR_thread_barrier_cond, &MR_thread_barrier_lock) != 0)
+            ;
     }
     MR_UNLOCK(&MR_thread_barrier_lock, "MR_do_interpreter");
   #endif
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
Index: tests/EXPECT_FAIL_TESTS.asm_fast.gc.debug
===================================================================
RCS file: tests/EXPECT_FAIL_TESTS.asm_fast.gc.debug
diff -N tests/EXPECT_FAIL_TESTS.asm_fast.gc.debug
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/EXPECT_FAIL_TESTS.asm_fast.gc.debug	24 Oct 2009 09:55:31 -0000
@@ -0,0 +1,5 @@
+term/append
+term/occur
+term/pl4_01
+term/select
+term/sum
Index: tests/EXPECT_FAIL_TESTS.asm_fast.gc.profdeep
===================================================================
RCS file: tests/EXPECT_FAIL_TESTS.asm_fast.gc.profdeep
diff -N tests/EXPECT_FAIL_TESTS.asm_fast.gc.profdeep
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/EXPECT_FAIL_TESTS.asm_fast.gc.profdeep	28 Oct 2009 01:44:25 -0000
@@ -0,0 +1,3 @@
+general/string_format_test_2
+general/string_format_test_3
+hard_coded/solver_default_eq_cmp
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.108
diff -u -b -r1.108 mercury_trace.c
--- trace/mercury_trace.c	25 Nov 2008 07:46:56 -0000	1.108
+++ trace/mercury_trace.c	24 Oct 2009 11:43:22 -0000
@@ -692,6 +692,8 @@
     const MR_LabelLayout    *return_label_layout;
     const MR_LabelLayout    *call_label;
     const MR_ProcLayout     *level_layout;
+    int                     call_all_var_count;
+    int                     call_long_var_count;
     MR_Word                 *args;
     int                     arg_max;
     int                     arg_num;
@@ -792,7 +794,9 @@
     type_params = MR_materialize_type_params_base(return_label_layout,
         saved_regs, base_sp, base_curfr);
 
-    for (i = 0; i < MR_all_desc_var_count(call_label); i++) {
+    call_all_var_count = MR_all_desc_var_count(call_label);
+    call_long_var_count = MR_long_desc_var_count(call_label);
+    for (i = 0; i < call_all_var_count; i++) {
         /*
         ** Check if the argument is of type io.state.  We check this before
         ** calling MR_trace_find_input_arg, since MR_trace_find_input_arg may
@@ -816,16 +820,16 @@
                 goto report_problem;
             }
 
-            if (i < MR_long_desc_var_count(call_label)) {
+            if (i < call_long_var_count) {
                 MR_LongLval     long_locn;
 
-                long_locn.MR_long_lval =
-                    MR_long_desc_var_locn(call_label, i).MR_long_lval;
+                long_locn = MR_long_desc_var_locn(call_label, i);
                 arg_num = MR_get_register_number_long(long_locn);
             } else {
                 MR_ShortLval    short_locn;
 
-                short_locn = MR_short_desc_var_locn(call_label, i);
+                short_locn = MR_short_desc_var_locn(call_label,
+                    i - call_long_var_count);
                 arg_num = MR_get_register_number_short(short_locn);
             }
 
@@ -1375,25 +1379,29 @@
     MR_uint_least16_t var_num, MR_bool *succeeded)
 {
     int i;
+    int all_var_count;
+    int long_var_count;
 
     if (label_layout->MR_sll_var_nums == NULL) {
         *succeeded = MR_FALSE;
         return 0;
     }
 
-    for (i = 0; i < MR_all_desc_var_count(label_layout); i++) {
+    all_var_count = MR_all_desc_var_count(label_layout);
+    long_var_count = MR_long_desc_var_count(label_layout);
+    for (i = 0; i < all_var_count; i++) {
         if (var_num == label_layout->MR_sll_var_nums[i]) {
-            if (i < MR_long_desc_var_count(label_layout)) {
+            if (i < long_var_count) {
                 MR_LongLval     long_locn;
 
-                long_locn.MR_long_lval =
-                    MR_long_desc_var_locn(label_layout, i).MR_long_lval;
+                long_locn = MR_long_desc_var_locn(label_layout, i);
                 return MR_lookup_long_lval_base(long_locn,
                     saved_regs, base_sp, base_curfr, succeeded);
             } else {
                 MR_ShortLval    short_locn;
 
-                short_locn = MR_short_desc_var_locn(label_layout, i);
+                short_locn = MR_short_desc_var_locn(label_layout,
+                    i - long_var_count);
                 return MR_lookup_short_lval_base(short_locn,
                     saved_regs, base_sp, base_curfr, succeeded);
             }
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_vars.c,v
retrieving revision 1.83
diff -u -b -r1.83 mercury_trace_vars.c
--- trace/mercury_trace_vars.c	12 Jan 2009 01:46:49 -0000	1.83
+++ trace/mercury_trace_vars.c	28 Oct 2009 07:50:10 -0000
@@ -421,10 +421,6 @@
         return "there is no information about live variables";
     }
 
-    if (level_layout->MR_sll_var_nums == NULL) {
-        return "there are no names for the live variables";
-    }
-
     if (! MR_find_context(level_layout, &filename, &linenumber)) {
         filename = "";
         linenumber = 0;
@@ -448,10 +444,10 @@
         var_count = MR_all_desc_var_count(level_layout);
     } else {
         /*
-        ** If the count of variables is zero, then the rest of the information
-        ** about the set of live variables (e.g. the type parameter array
-        ** pointer) is not present. Continuing would therefore lead to a
-        ** core dump.
+        ** If the count of variables is negative, then the rest of the
+        ** information about the set of live variables (e.g. the type
+        ** parameter array pointer) is not present. Continuing would
+        ** therefore lead to a core dump.
         **
         ** Instead, we set up the remaining meaningful fields of MR_point.
         */
@@ -460,13 +456,17 @@
         return NULL;
     }
 
+    if (var_count > 0 && level_layout->MR_sll_var_nums == NULL) {
+        return "there are no names for the live variables";
+    }
+
     user = level_layout->MR_sll_user_event;
-    if (user != NULL) {
-        user_spec = &MR_user_event_spec(level_layout);
-        attr_count = user_spec->MR_ues_num_attrs;
-    } else {
+    if (user == NULL) {
         user_spec = NULL;
         attr_count = 0;
+    } else {
+        user_spec = &MR_user_event_spec(level_layout);
+        attr_count = user_spec->MR_ues_num_attrs;
     }
 
     total_count = var_count + attr_count;
@@ -640,6 +640,14 @@
         }
     }
 
+#ifdef  MR_DEBUG_LVAL_REP
+    printf("var_count encoded %d, long %d, short %d, total %d\n",
+        level_layout->MR_sll_var_count,
+        MR_long_desc_var_count(level_layout),
+        MR_short_desc_var_count(level_layout),
+        var_count);
+#endif
+
     for (i = 0; i < var_count; i++) {
         MR_HLDSVarNum   hlds_var_num;
         int             head_var_num;
@@ -648,6 +656,11 @@
 
         hlds_var_num = level_layout->MR_sll_var_nums[i];
         name = MR_hlds_var_name(entry, hlds_var_num);
+
+#ifdef  MR_DEBUG_LVAL_REP
+        printf("i %d, hlds_var_num %d, name %s\n", i, hlds_var_num, name);
+#endif
+
         if (name == NULL || MR_streq(name, "")) {
             /* This value is not a variable or is not named by the user. */
             continue;
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list