[m-rev.] for review: reduce link time in debug grades

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Oct 19 18:08:30 AEDT 2009


I have asked Julien to measure how long linking takes on Snow Leopard before
this diff, so we can see whether this diff improves link times as intended,
and so, by how much.

The diff passed bootcheck in both asm_fast.gc.debug and none.gc.debug.
I am trying it now in plain asm_fast.gc, and will try {asm_,}jump.gc.debug and
asm_fast.gc.prof overnight. Any others you think is relevant?

Zoltan.

-----------------------

Try to work around the Snow Leopard linker's performance problem with
debug grade object files by greatly reducing the number of symbols needed
to represent the debugger's data structures.

Specifically, this diff groups all label layouts in a module, each of which
previously had its own named global variable, into only a few (one to four)
global variables, each of which is an array. References to the old global
variables are replaced by references to slots in these arrays.

This same treatment could also be applied to other layout structures. However,
most layouts are label layouts, so doing just label layouts gets most of the
available benefit.

When the library and compiler are compiled in grade asm_fast.gc.debug,
this diff leads to about a 1.5% increase in the size of their generated C
source files (from 338 to 343 Mb), but a more significant reduction (about 17%)
in the size of the corresponding object files (from 155 to 128 Mb). This leads
to an overall reduction in disk requirements from 493 to 471 Mb (about 4.5%).
Since we generate the same code and data as before, with the data just being
arranged differently, the decrease in object file sizes is coming from the
reduction in relocation information, the information processed by the linker.
This should speed up the linker.

compiler/layout.m:
	Make the change described above. We now define up to four arrays:
	one each for label layouts with and without information about
	variables, one for the layout structures of user events,
	and one for the variable number lists of user events.

compiler/layout_out.m:
	Generate the new arrays that the module being compiled needs.

	Use purpose-specific types instead of booleans.

compiler/trace_gen.m:
	Use a new field in foreign_proc_code instructions to record the
	identity of any labels whose layout structures we want to refer to,
	even though layout structures have not been generated yet. The labels
	will be looked up in a map (generated together with the layout
	structures) by llds_out.m.

compiler/llds.m:
	Add this extra field to foreign_proc_code instructions.

	Add the map (which is actually in two parts) to the c_file type,
	which is the data structure representing the entire LLDS.

	Also add to the c_file type some other data structures that previously
	we used to hand around alongside it. Some of these data structures
	used to conmingle layout structures that we now separate.

compiler/stack_layout.m:
	Generate array slots instead of separate structures for label layouts.
	Return the different arrays separately.

compiler/llds_out.m:
	Order the output of layout structures to require fewer forward
	declarations. The forward declarations of the few arrays holding the
	label layout structures replace a lot of the declarations previously
	needed.

	Include the information needed by layout_out.m in the llds_out_info,
	and conform to the changes above.

	As a side-effect of all these changes, we now generate proc layout
	structures in the same order as the procedures' appearence in the HLDS,
	which is the same as their order in the source code, modulo any
	procedures added by the compiler itself (for lambdas, unification
	predicates, etc).

compiler/code_info.m:
compiler/dupelim.m:
compiler/dup_proc.m:
compiler/exprn_aux.m:
compiler/frameopt.m:
compiler/global_data.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/mercury_compile_llds_back_end.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Conform to the changes above.

runtime/mercury_goto.h:
	Add the macros used by the new code in layout_out.m and llds_out.m.
	We need new macros because the old ones assumed that the
	C preprocessor can construct the address of a label's layout structure
	from the name of the label, which is obviously no longer possible.

	Make even existing families of macros handle in bulk up to 10 labels, 
	up from the previous 8.

runtime/mercury_stack_layout.h:
	Add macros that define the fields of 

tests/debugger/*.{inp,exp}:
	Update these test cases to account for the new (and better) order
	of proc layout structures. Where inputs changed, this was to ensure
	that we still select the same procedures from lists of procedures,
	e.g. to put a breakpoint on.

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.375
diff -u -b -r1.375 code_info.m
--- compiler/code_info.m	4 Sep 2009 02:27:49 -0000	1.375
+++ compiler/code_info.m	17 Oct 2009 06:45:56 -0000
@@ -2208,7 +2208,8 @@
             MD = proc_may_duplicate,
             MarkCode = singleton(
                 llds_instr(foreign_proc_code([], Components,
-                    proc_will_not_call_mercury, no, no, no, no, no, MD), "")
+                    proc_will_not_call_mercury, no, no, no, no, no, no, MD),
+                    "")
             )
         ;
             UseMinimalModelStackCopyCut = no,
@@ -2296,7 +2297,7 @@
             MD = proc_may_duplicate,
             CutCode = singleton(
                 llds_instr(foreign_proc_code([], Components,
-                    proc_will_not_call_mercury, no, no, no, no, no, MD),
+                    proc_will_not_call_mercury, no, no, no, no, no, no, MD),
                     "commit for temp frame hijack")
             )
         ;
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.93
diff -u -b -r1.93 dupelim.m
--- compiler/dupelim.m	11 Feb 2008 03:56:07 -0000	1.93
+++ compiler/dupelim.m	17 Oct 2009 07:00:44 -0000
@@ -145,9 +145,10 @@
     set(label)::in, set(label)::out) is det.
 
 add_pragma_pref_labels(Instr, !FoldFixed) :-
+    Instr = llds_instr(Uinstr, _),
     (
-        Instr = llds_instr(foreign_proc_code(_, _, _, MaybeFixedLabel,
-            MaybeLayoutLabel, MaybeOnlyLayoutLabel, _, _, _), _)
+        Uinstr = foreign_proc_code(_, _, _, MaybeFixedLabel,
+            MaybeLayoutLabel, MaybeOnlyLayoutLabel, _, MaybeDefLabel, _, _)
     ->
         (
             MaybeFixedLabel = yes(FixedLabel),
@@ -166,6 +167,12 @@
             svset.insert(OnlyLayoutLabel, !FoldFixed)
         ;
             MaybeOnlyLayoutLabel = no
+        ),
+        (
+            MaybeDefLabel = yes(DefLabel),
+            svset.insert(DefLabel, !FoldFixed)
+        ;
+            MaybeDefLabel = no
         )
     ;
         true
@@ -439,7 +446,7 @@
         ; Instr0 = decr_sp(_)
         ; Instr0 = decr_sp_and_return(_)
         ; Instr0 = fork_new_child(_, _)
-        ; Instr0 = foreign_proc_code(_, _, _, _, _, _, _, _, _)
+        ; Instr0 = foreign_proc_code(_, _, _, _, _, _, _, _, _, _)
         ),
         Instr = Instr0
     ).
@@ -826,7 +833,7 @@
         ; InstrA = incr_sp(_, _, _)
         ; InstrA = decr_sp(_)
         ; InstrA = decr_sp_and_return(_)
-        ; InstrA = foreign_proc_code(_, _, _, _, _, _, _, _, _)
+        ; InstrA = foreign_proc_code(_, _, _, _, _, _, _, _, _, _)
         ; InstrA = fork_new_child(_, _)
         ; InstrA = init_sync_term(_, _)
         ; InstrA = join_and_continue(_, _)
Index: compiler/dupproc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupproc.m,v
retrieving revision 1.24
diff -u -b -r1.24 dupproc.m
--- compiler/dupproc.m	11 Feb 2008 03:56:07 -0000	1.24
+++ compiler/dupproc.m	17 Oct 2009 07:01:04 -0000
@@ -232,7 +232,7 @@
     ;
         % The labels occurring in foreign_proc_code instructions
         % cannot be substituted.
-        Instr = foreign_proc_code(_, _, _, _, _, _, _, _, _),
+        Instr = foreign_proc_code(_, _, _, _, _, _, _, _, _, _),
         StdInstr = Instr
     ;
         % These instructions have no labels inside them, or anything else
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.88
diff -u -b -r1.88 exprn_aux.m
--- compiler/exprn_aux.m	2 Jun 2008 02:27:26 -0000	1.88
+++ compiler/exprn_aux.m	17 Oct 2009 07:01:36 -0000
@@ -393,12 +393,12 @@
 %       Uinstr = discard_tickets_to(Rval)
     ;
         Uinstr0 = foreign_proc_code(Decls, Components0, MayCallMercury,
-            MaybeLabel1, MaybeLabel2, MaybeLabel3, MaybeLabel4,
+            MaybeLabel1, MaybeLabel2, MaybeLabel3, MaybeLabel4, MaybeLabel5,
             ReferStackSlot, MayDupl),
         list.map_foldl(transform_lval_in_component(Transform),
             Components0, Components, !Acc),
         Uinstr = foreign_proc_code(Decls, Components, MayCallMercury,
-            MaybeLabel1, MaybeLabel2, MaybeLabel3, MaybeLabel4,
+            MaybeLabel1, MaybeLabel2, MaybeLabel3, MaybeLabel4, MaybeLabel5,
             ReferStackSlot, MayDupl)
     ;
         Uinstr0 = init_sync_term(Lval0, BranchCount),
Index: compiler/frameopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/frameopt.m,v
retrieving revision 1.116
diff -u -b -r1.116 frameopt.m
--- compiler/frameopt.m	14 Oct 2009 05:28:32 -0000	1.116
+++ compiler/frameopt.m	17 Oct 2009 07:05:37 -0000
@@ -1088,7 +1088,8 @@
                 Uinstr = arbitrary_c_code(_, _, _)
             ;
                 Uinstr = foreign_proc_code(_, _, MayCallMercury, _,
-                    MaybeLayout, MaybeOnlyLayout, _, NeedStack, _),
+                    MaybeLayout, MaybeOnlyLayout, _, MaybeDefLabel,
+                    NeedStack, _),
                 (
                     MayCallMercury = proc_may_call_mercury
                 ;
@@ -1096,6 +1097,8 @@
                 ;
                     MaybeOnlyLayout = yes(_)
                 ;
+                    MaybeDefLabel = yes(_)
+                ;
                     NeedStack = yes
                 )
             ;
@@ -1224,7 +1227,7 @@
             BlockInstrs = AllButLastInstrs ++ [LastInstr]
         ;
             LastUinstr0 = foreign_proc_code(D, Comps0, MC, FNL, FL, FOL, NF0,
-                S, MD)
+                MDL, S, MD)
         ->
             (
                 NF0 = no,
@@ -1237,7 +1240,7 @@
                 replace_labels_comps(Comps0, Comps, PreExitDummyLabelMap)
             ),
             LastUinstr = foreign_proc_code(D, Comps, MC, FNL, FL, FOL, NF,
-                S, MD),
+                MDL, S, MD),
             LastInstr = llds_instr(LastUinstr, Comment),
             BlockInstrs = AllButLastInstrs ++ [LastInstr]
         ;
@@ -1357,7 +1360,7 @@
         ;
             % Only may_call_mercury foreign_proc_codes can clobber succip.
             Uinstr = foreign_proc_code(_, _, proc_may_call_mercury,
-                _, _, _, _, _, _)
+                _, _, _, _, _, _, _)
         )
     ->
         CanClobberSuccip = yes
Index: compiler/global_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/global_data.m,v
retrieving revision 1.41
diff -u -b -r1.41 global_data.m
--- compiler/global_data.m	21 Sep 2009 04:08:53 -0000	1.41
+++ compiler/global_data.m	17 Oct 2009 08:05:17 -0000
@@ -927,9 +927,9 @@
         remap_rval(Remap, Rval0, Rval),
         Instr  = if_val(Rval, CodeAddr)
     ;
-        Instr0 = foreign_proc_code(A, Comps0, B, C, D, E, F, G, H),
+        Instr0 = foreign_proc_code(A, Comps0, B, C, D, E, F, G, H, I),
         list.map(remap_foreign_proc_component(Remap), Comps0, Comps),
-        Instr  = foreign_proc_code(A, Comps,  B, C, D, E, F, G, H)
+        Instr  = foreign_proc_code(A, Comps,  B, C, D, E, F, G, H, I)
     ;
         Instr0 = computed_goto(Rval0, MaybeLabels),
         remap_rval(Remap, Rval0, Rval),
Index: compiler/ite_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ite_gen.m,v
retrieving revision 1.108
diff -u -b -r1.108 ite_gen.m
--- compiler/ite_gen.m	6 Jan 2009 03:56:25 -0000	1.108
+++ compiler/ite_gen.m	17 Oct 2009 07:19:02 -0000
@@ -532,15 +532,15 @@
         MD = proc_may_duplicate,
         PNegCondCode = singleton(
             llds_instr(foreign_proc_code([], PNegCondComponents,
-                proc_will_not_call_mercury, no, no, no, no, yes, MD), "")
+                proc_will_not_call_mercury, no, no, no, no, no, yes, MD), "")
         ),
         PNegThenCode = singleton(
             llds_instr(foreign_proc_code([], PNegThenComponents,
-                proc_will_not_call_mercury, no, no, no, no, yes, MD), "")
+                proc_will_not_call_mercury, no, no, no, no, no, yes, MD), "")
         ),
         PNegElseCode = singleton(
             llds_instr(foreign_proc_code([], PNegElseComponents,
-                proc_will_not_call_mercury, no, no, no, no, yes, MD), "")
+                proc_will_not_call_mercury, no, no, no, no, no, yes, MD), "")
         )
     ;
         PNegCondCode = empty,
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.111
diff -u -b -r1.111 jumpopt.m
--- compiler/jumpopt.m	21 Sep 2009 04:08:53 -0000	1.111
+++ compiler/jumpopt.m	17 Oct 2009 07:06:39 -0000
@@ -723,7 +723,7 @@
     ;
         Uinstr0 = foreign_proc_code(Decls, Components0, MayCallMercury,
             MaybeFixNoLayout, MaybeFixLayout, MaybeFixOnlyLayout,
-            MaybeNoFix0, StackSlotRef, MaybeDup),
+            MaybeNoFix0, MaybeDefLabel, StackSlotRef, MaybeDup),
         some [!Redirect] (
             list.map_foldl(short_foreign_proc_component(Instrmap),
                 Components0, Components, no, !:Redirect),
@@ -776,7 +776,7 @@
                 Comment = Comment0 ++ " (some redirects)",
                 Uinstr = foreign_proc_code(Decls, Components, MayCallMercury,
                     MaybeFixNoLayout, MaybeFixLayout, MaybeFixOnlyLayout,
-                    MaybeNoFix, StackSlotRef, MaybeDup),
+                    MaybeNoFix, MaybeDefLabel, StackSlotRef, MaybeDup),
                 Instr = llds_instr(Uinstr, Comment),
                 NewRemain = specified([Instr], Instrs0)
             )
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.40
diff -u -b -r1.40 layout.m
--- compiler/layout.m	25 Nov 2008 07:46:40 -0000	1.40
+++ compiler/layout.m	18 Oct 2009 15:01:17 -0000
@@ -58,13 +58,21 @@
 :- type event_set_layout_data
     --->    event_set_layout_data(
                 event_set_data,
-                map(int, rval)          % Maps each event number to an rval
-                                        % that gives the vector of typeinfos
-                                        % for the arguments of that event.
+
+                % Maps each event number to an rval that gives the vector
+                % of typeinfos for the arguments of that event.
+                map(int, rval)
             ).
 
-:- type layout_data
-    --->    label_layout_data(          % defines MR_LabelLayout
+:- type user_event_data
+    --->    user_event_data(
+                user_event_number       :: int,
+                user_event_locns        :: rval,
+                user_event_var_nums     :: layout_slot_name
+            ).
+
+:- type basic_label_layout
+    --->    basic_label_layout(
                 proc_label              :: proc_label,
                 label_num               :: int,
                 proc_layout_name        :: layout_name,
@@ -72,20 +80,37 @@
                 maybe_is_hidden         :: maybe(bool),
                 label_num_in_module     :: int,
                 maybe_goal_path         :: maybe(int), % offset
-                maybe_user_info         :: maybe(user_event_data),
-                maybe_var_info          :: maybe(label_var_info)
-            )
-    ;       proc_layout_data(           % defines MR_ProcLayout
+                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_layout_no_vars
+    --->    label_layout_no_vars(
+                % defines MR_LabelLayoutNoVarInfo
+                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_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_layout_data(
+                % defines MR_ModuleLayout
                 module_name             :: module_name,
                 module_common           :: layout_name,
                 proc_layout_names       :: list(layout_name),
@@ -95,7 +120,8 @@
                 num_label_exec_count    :: int,
                 maybe_event_specs       :: maybe(event_set_layout_data)
             )
-    ;       closure_proc_id_data(       % defines MR_ClosureId
+    ;       closure_proc_id_data(
+                % defines MR_ClosureId
                 caller_proc_label       :: proc_label,
                 caller_closure_seq_no   :: int,
                 closure_proc_label      :: proc_label,
@@ -106,19 +132,15 @@
                 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,
-                table_io_decl_ptis      :: rval,
+
                                         % pseudo-typeinfos for headvars
-                table_io_decl_type_params :: rval
-            ).
+                table_io_decl_ptis      :: rval,
 
-:- type user_event_data
-    --->    user_event_data(
-                user_event_number       :: int,
-                user_event_locns        :: rval,
-                user_event_var_nums     :: list(maybe(int))
+                table_io_decl_type_params :: rval
             ).
 
 :- type label_var_info
@@ -131,10 +153,10 @@
 
 :- type proc_layout_stack_traversal     % defines MR_StackTraversal
     --->    proc_layout_stack_traversal(
+                % The proc entry label will be `no' if we don't have
+                % static code addresses.
                 entry_label             :: maybe(label),
-                                        % The proc entry label; will be `no'
-                                        % if we don't have static code
-                                        % addresses.
+
                 succip_slot             :: maybe(int),
                 stack_slot_count        :: int,
                 detism                  :: determinism
@@ -168,35 +190,33 @@
     ;       proc_id_and_more(
                 maybe_proc_static       :: maybe(proc_layout_proc_static),
                 maybe_exec_trace        :: maybe(proc_layout_exec_trace),
+
+                % The procedure body represented as a list of bytecodes.
                 proc_body_bytes         :: list(int),
-                                        % The procedure body represented as
-                                        % a list of bytecodes.
+
+                % The name of the module_common_layout structure.
                 proc_module_common      :: layout_name
-                                        % The name of the module_common_layout
-                                        % structure.
             ).
 
 :- type proc_layout_exec_trace          % defines MR_ExecTrace
     --->    proc_layout_exec_trace(
-                maybe_call_label_layout :: maybe(label_layout_details),
+                maybe_call_label_layout :: maybe(layout_slot_name),
 
-                proc_label_layouts      :: list(data_addr),
-                                        % The label layouts of the events in
-                                        % the predicate. Interface events
-                                        % first, internal events second.
+                % 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),
 
                 maybe_table_info        :: maybe(data_addr),
+
+                % 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),
-                                        % 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.
 
+                % Each variable name is an offset into the module's
+                % string table.
                 var_names               :: list(int),
-                                        % Each variable name is an offset into
-                                        % the module's string table.
 
                 max_var_num             :: int,
                 max_r_num               :: int,
@@ -214,16 +234,21 @@
 :- type file_layout_data
     --->    file_layout_data(
                 file_name               :: string,
-                line_no_label_list      :: assoc_list(int, layout_name)
+                line_no_label_list      :: assoc_list(int, layout_slot_name)
             ).
 
 %-----------------------------------------------------------------------------%
 
+:- type layout_slot_name
+    --->    layout_slot(layout_array_name, int).
+
+:- type layout_array_name
+    --->    label_layout_array(label_vars)
+    ;       user_event_layout_array
+    ;       user_event_var_nums_array.
+
 :- type layout_name
-    --->    label_layout(proc_label, int, label_vars)
-    ;       user_event_layout(proc_label, int)
-    ;       user_event_attr_var_nums(proc_label, int)
-    ;       proc_layout(rtti_proc_label, proc_layout_kind)
+    --->    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)
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.103
diff -u -b -r1.103 layout_out.m
--- compiler/layout_out.m	14 Oct 2009 05:28:35 -0000	1.103
+++ compiler/layout_out.m	18 Oct 2009 18:34:59 -0000
@@ -24,12 +24,27 @@
 :- interface.
 
 :- import_module ll_backend.layout.
-:- import_module ll_backend.llds.
 :- import_module ll_backend.llds_out.
 :- import_module mdbcomp.prim_data.
 
 :- import_module bool.
 :- import_module io.
+:- import_module list.
+:- import_module maybe.
+
+%-----------------------------------------------------------------------------%
+
+:- 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.
 
 %-----------------------------------------------------------------------------%
 
@@ -46,6 +61,7 @@
 
     % Given the name 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_name_decl(layout_name::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
@@ -56,13 +72,45 @@
 :- 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.
+
     % Given a reference to a layout structure, output the storage class
     % (e.g. static), type and name of the global variable that will
-    % hold it. The bool says whether the output is part of the definition of
-    % that variable (this influences e.g. whether we output "extern" or not).
+    % hold it. The second arg says whether the output is part of the definition
+    % of that variable (this influences e.g. whether we output "extern"
+    % or not).
     %
-:- pred output_layout_name_storage_type_name(layout_name::in, bool::in,
-    io::di, io::uo) is det.
+:- pred output_layout_name_storage_type_name(layout_name::in,
+    being_defined::in, io::di, io::uo) is det.
+
+    % Given a mangled module name and a reference to a layout array, output
+    % the storage class (e.g. static), type and name of the global variable
+    % that will hold it. The bool says whether the output is part of the
+    % definition of that variable (this influences e.g. whether we output
+    % "extern" or not).
+    %
+:- pred output_layout_array_name_storage_type_name(string::in,
+    layout_array_name::in, being_defined::in, io::di, io::uo) is det.
+
+:- type use_layout_macro
+    --->    do_not_use_layout_macro
+    ;       use_layout_macro.
+
+    % Given the mangled name of the module and a reference to a layout array,
+    % output the name of the global variable that will hold it. The first arg
+    % says whether we should use a macro to refer to the global. Using the
+    % macro generates shorter code, but is not valid in all contexts.
+    %
+:- 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 a reference to the address
+    % of the given layout array slot.
+    %
+:- pred output_layout_slot_name(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
     % global variable that will hold it.
@@ -74,13 +122,6 @@
     %
 :- func layout_name_would_include_code_addr(layout_name) = bool.
 
-    % Given a label, return a string giving the name of the global variable
-    % containing the label layout structure that would be associated with it.
-    % Make_label_layout_name does not guarantee that the label *has* an
-    % associated label layout structure.
-    %
-:- func make_label_layout_name(label) = string.
-
     % For a given procedure label, return whether the procedure is
     % user-defined or part of a compiler-generated unify, compare or index
     % predicate.
@@ -110,6 +151,7 @@
 :- 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.
@@ -118,27 +160,245 @@
 :- import_module assoc_list.
 :- import_module char.
 :- import_module int.
-:- import_module list.
 :- import_module map.
-:- import_module maybe.
 :- import_module pair.
 :- import_module string.
 :- import_module varset.
 
 %-----------------------------------------------------------------------------%
 
-output_layout_data_defn(Info, Data, !DeclSet, !IO) :-
+output_user_event_var_nums_array_defn(Info, MaybeVarNums, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(MaybeVarNums, NumMaybeVarNums),
+    Name = user_event_var_nums_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {", [i(NumMaybeVarNums)], !IO),
+    list.foldl2(output_maybe_var_num_slot, MaybeVarNums, 0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_maybe_var_num_slot(maybe(int)::in, int::in, int::out,
+    io::di, io::uo) is det.
+
+output_maybe_var_num_slot(MaybeVarNum, !Slot, !IO) :-
+    (
+        MaybeVarNum = no,
+        % Zero means not a variable, which is what we want.
+        VarNum = 0
+    ;
+        MaybeVarNum = yes(VarNum)
+    ),
+    ( !.Slot mod 10 = 0 ->
+        io.format("\n/* slot %d */ ", [i(!.Slot)], !IO)
+    ;
+        io.write_string(" ", !IO)
+    ),
+    io.format("%d,", [i(VarNum)], !IO),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+
+output_user_events_array_defn(Info, UserEvents, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    list.length(UserEvents, NumUserEvents),
+    Name = user_event_layout_array,
+    output_layout_array_name_storage_type_name(ModuleName, Name,
+        being_defined, !IO),
+    io.format("[%d] = {\n", [i(NumUserEvents)], !IO),
+    list.foldl2(output_user_event_slot(Info), UserEvents, 0, _, !IO),
+    io.write_string("};\n\n", !IO).
+
+:- pred output_user_event_slot(llds_out_info::in, user_event_data::in,
+    int::in, int::out, io::di, io::uo) is det.
+
+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),
+    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,
+        !IO),
+    io.write_string(" },\n", !IO),
+    !:Slot = !.Slot + 1.
+
+%-----------------------------------------------------------------------------%
+
+output_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),
+    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),
+    io.write_string("};\n\n", !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_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_no_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.
+
+output_var_label_layout_slot(Info, LabelLayout, !Slot, !IO) :-
+    ModuleName = Info ^ lout_mangled_module_name,
+    LabelLayout = label_layout_vars(BasicLabelLayout, LabelVarInfo),
+    BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
+        _, _, _, _, _, _),
+    % The procedure is given by the proc_label printed from the basic layout.
+    io.format("  { /* slot %d, label %d */\n", [i(!.Slot), i(LabelNum)], !IO),
+    output_basic_label_layout_slot(ModuleName, BasicLabelLayout, !IO),
+    io.write_string(",\n  ", !IO),
+
+    LabelVarInfo = label_var_info(EncodedVarCount, LocnsTypes, VarNums,
+        TypeParams),
+    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))
+    ->
+        (
+            TypeParams = const(llconst_data_addr(TPDataAddr, no)),
+            TPDataAddr = data_addr(_,
+                scalar_common_ref(type_num(TPTypeNum), TPCellNum))
+        ->
+            io.format("MR_LLV_CCC(%d,%d,%d,%d,%d,%d)",
+                [i(LTTypeNum), i(LTCellNum), i(VNTypeNum), i(VNCellNum),
+                i(TPTypeNum), i(TPCellNum)], !IO)
+        ;
+            TypeParams = const(llconst_int(0))
+        ->
+            io.format("MR_LLV_CC0(%d,%d,%d,%d)",
+                [i(LTTypeNum), i(LTCellNum), i(VNTypeNum), i(VNCellNum)], !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.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(" },\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.
+
+:- pred output_basic_label_layout_slot(string::in, basic_label_layout::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),
+    (
+        ProcLayoutName = proc_layout(RttiProcLabel, _),
+        ProcLabelFromRtti = make_proc_label_from_rtti(RttiProcLabel),
+        ProcLabelFromRtti = ProcLabel
+    ->
+        true
+    ;
+        unexpected(this_file, "output_basic_label_layout_slot: != proclabels")
+    ),
+
+    % MaybeIsHidden = no means that the value of the hidden field shouldn't
+    % matter; we arbitrarily set it to `not hidden'.
+    (
+        ( MaybeIsHidden = no
+        ; MaybeIsHidden = yes(no)
+        ),
+        (
+            MaybeUserSlotName = no,
+            MacroName = "MR_LLC"
+        ;
+            MaybeUserSlotName = yes(_),
+            MacroName = "MR_LLC_U"
+        )
+    ;
+        MaybeIsHidden = yes(yes),
+        (
+            MaybeUserSlotName = no,
+            MacroName = "MR_LLC_H"
+        ;
+            MaybeUserSlotName = yes(_),
+            MacroName = "MR_LLC_H_U"
+        )
+    ),
+
+    io.write_string(MacroName, !IO),
+    io.write_string("(", !IO),
+    output_proc_label_no_prefix(ProcLabel, !IO),
+    io.write_string(", ", !IO),
+    (
+        MaybePort = yes(Port),
+        io.write_string(trace_port_to_string(Port), !IO),
+        io.write_string(",", !IO)
+    ;
+        MaybePort = no,
+        io.write_string("NONE,", !IO)
+    ),
+    io.write_int(LabelNumberInModule, !IO),
+    io.write_string(",", !IO),
+    (
+        MaybeGoalPath = yes(GoalPath),
+        io.write_int(GoalPath, !IO)
+    ;
+        MaybeGoalPath = no,
+        io.write_string("0", !IO)
+    ),
     (
-        Data = label_layout_data(ProcLabel, LabelNum, ProcLayoutAddr,
-            MaybePort, MaybeIsHidden, LabelNumber, MaybeGoalPath,
-            MaybeUserData, MaybeVarInfo),
-        output_label_layout_data_defn(Info, ProcLabel, LabelNum,
-            ProcLayoutAddr, MaybePort, MaybeIsHidden, LabelNumber,
-            MaybeGoalPath, MaybeUserData, MaybeVarInfo, !DeclSet, !IO)
+        MaybeUserSlotName = no
     ;
+        MaybeUserSlotName = yes(UserSlotName),
+        io.write_string(",", !IO),
+        output_layout_slot_name(use_layout_macro, ModuleName, UserSlotName,
+            !IO)
+    ),
+    io.write_string(")", !IO).
+
+%-----------------------------------------------------------------------------%
+
+output_layout_data_defn(Info, Data, !DeclSet, !IO) :-
+    (
         Data = proc_layout_data(ProcLabel, Traversal, MaybeRest),
-        output_proc_layout_data_defn(Info, ProcLabel, Traversal, MaybeRest,
-            !DeclSet, !IO)
+        output_proc_layout_data_defn(Info, ProcLabel,
+            Traversal, MaybeRest, !DeclSet, !IO)
     ;
         Data = closure_proc_id_data(CallerProcLabel, SeqNo, ProcLabel,
             ModuleName, FileName, LineNumber, PredOrigin, GoalPath),
@@ -167,7 +427,7 @@
 %-----------------------------------------------------------------------------%
 
 output_layout_name_decl(LayoutName, !IO) :-
-    output_layout_name_storage_type_name(LayoutName, no, !IO),
+    output_layout_name_storage_type_name(LayoutName, not_being_defined, !IO),
     io.write_string(";\n", !IO).
 
 output_maybe_layout_name_decl(LayoutName, !DeclSet, !IO) :-
@@ -186,17 +446,6 @@
 
 extract_layout_name(Data, LayoutName) :-
     (
-        Data = label_layout_data(ProcLabel, LabelNum, _, _, _, _, _, _,
-            MaybeVarInfo),
-        (
-            MaybeVarInfo = yes(_),
-            LabelVars = label_has_var_info
-        ;
-            MaybeVarInfo = no,
-            LabelVars = label_has_no_var_info
-        ),
-        LayoutName = label_layout(ProcLabel, LabelNum, LabelVars)
-    ;
         Data = proc_layout_data(RttiProcLabel, _, MaybeRest),
         ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
         Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
@@ -223,50 +472,62 @@
     ( decl_set_is_member(decl_data_addr(layout_addr(LayoutName)), !.DeclSet) ->
         true
     ;
-        output_layout_name_storage_type_name(LayoutName, no, !IO),
+        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)
     ).
 
-    % This code should be kept in sync with output_layout_name/3 below.
-make_label_layout_name(Label) = Name :-
-    % We can't omit the mercury_ prefix on LabelName, even though the
-    % mercury_data_prefix duplicates it, because there is no simple way
-    % to make the MR_init_label_sl macro delete that prefix from the
-    % label's name to get the name of its layout structure.
-    LabelName = label_to_c_string(Label, yes),
-    string.append_list([
-        mercury_data_prefix,
-        "_label_layout__",
-        LabelName
-    ], Name).
-
-output_layout_name(Data, !IO) :-
+output_layout_array_name(UseMacro, ModuleName, ArrayName, !IO) :-
     (
-        Data = label_layout(ProcLabel, LabelNum, _),
-        % This code should be kept in sync with make_label_layout_name/1 above.
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_label_layout__", !IO),
-        io.write_string(
-            label_to_c_string(internal_label(LabelNum, ProcLabel), yes), !IO)
+        UseMacro = use_layout_macro,
+        (
+            ArrayName = label_layout_array(label_has_var_info),
+            io.write_string("MR_var_label_layouts", !IO)
     ;
-        Data = user_event_layout(ProcLabel, LabelNum),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_user_event_layout__", !IO),
-        io.write_string(
-            label_to_c_string(internal_label(LabelNum, ProcLabel), yes), !IO)
+            ArrayName = label_layout_array(label_has_no_var_info),
+            io.write_string("MR_no_var_label_layouts", !IO)
     ;
-        Data = user_event_attr_var_nums(ProcLabel, LabelNum),
-        io.write_string(mercury_data_prefix, !IO),
-        io.write_string("_user_event_attr_var_nums__", !IO),
-        io.write_string(
-            label_to_c_string(internal_label(LabelNum, ProcLabel), yes), !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)
+        ),
+        io.write_string("(", !IO),
+        io.write_string(ModuleName, !IO),
+        io.write_string(")", !IO)
+    ;
+        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 = 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)
+        ),
+        io.write_string(ModuleName, !IO)
+    ).
+
+output_layout_slot_name(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) :-
+    (
         Data = 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
-        % mercury_data_prefix duplicates it, because there is no simply way
+        % mercury_data_prefix duplicates it, because there is no simple way
         % to make the MR_init_entryl_sl macro delete that prefix from the
         % entry label's name to get the name of its layout structure.
         output_proc_label(make_proc_label_from_rtti(RttiProcLabel), !IO)
@@ -457,23 +718,32 @@
         output_proc_label_no_prefix(ProcLabel, !IO)
     ).
 
-output_layout_name_storage_type_name(Name, BeingDefined, !IO) :-
+output_layout_array_name_storage_type_name(ModuleName, Name, _BeingDefined,
+        !IO) :-
     (
-        Name = label_layout(_ProcLabel, _LabelNum, LabelVars),
-        io.write_string("static const ", !IO),
-        io.write_string(label_vars_to_type(LabelVars), !IO),
-        io.write_string(" ", !IO),
-        output_layout_name(Name, !IO)
-    ;
-        Name = user_event_layout(_ProcLabel, _LabelNum),
-        io.write_string("static const struct MR_UserEvent_Struct ", !IO),
-        output_layout_name(Name, !IO)
+        Name = label_layout_array(label_has_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),
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
     ;
-        Name = user_event_attr_var_nums(_ProcLabel, _LabelNum),
+        Name = user_event_var_nums_array,
         io.write_string("static const MR_HLDSVarNum ", !IO),
-        output_layout_name(Name, !IO),
-        io.write_string("[]", !IO)
+        output_layout_array_name(do_not_use_layout_macro, ModuleName,
+            Name, !IO)
     ;
+        Name = user_event_layout_array,
+        io.write_string("static const struct MR_UserEvent_Struct ", !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,
@@ -484,9 +754,9 @@
             io.write_string("static ", !IO)
         ;
             (
-                BeingDefined = yes
+                BeingDefined = being_defined
             ;
-                BeingDefined = no,
+                BeingDefined = not_being_defined,
                 io.write_string("extern ", !IO)
             )
         ),
@@ -638,9 +908,6 @@
         output_layout_name(Name, !IO)
     ).
 
-layout_name_would_include_code_addr(label_layout(_, _, _)) = no.
-layout_name_would_include_code_addr(user_event_layout(_, _)) = no.
-layout_name_would_include_code_addr(user_event_attr_var_nums(_, _)) = no.
 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.
@@ -675,11 +942,6 @@
 layout_name_would_include_code_addr(proc_static_coverage_point_dynamic(_)) = no.
 layout_name_would_include_code_addr(table_io_decl(_)) = no.
 
-:- func label_vars_to_type(label_vars) = string.
-
-label_vars_to_type(label_has_var_info) =    "MR_LabelLayout".
-label_vars_to_type(label_has_no_var_info) = "MR_LabelLayoutNoVarInfo".
-
 :- func proc_layout_kind_to_type(proc_layout_kind) = string.
 
 proc_layout_kind_to_type(proc_layout_traversal) = "MR_ProcLayout_Traversal".
@@ -688,177 +950,6 @@
 
 %-----------------------------------------------------------------------------%
 
-:- type rval_or_numpair_or_none
-    --->    kind_rval(rval)
-    ;       kind_num_pair(type_num, int)
-    ;       kind_none.
-
-:- pred output_rval_or_numpair_or_none(llds_out_info::in,
-    rval_or_numpair_or_none::in, io::di, io::uo) is det.
-
-output_rval_or_numpair_or_none(Info, RvalOrNumPairOrNone, !IO) :-
-    (
-        RvalOrNumPairOrNone = kind_rval(Rval),
-        io.write_string(", ", !IO),
-        output_rval_as_addr(Info, Rval, !IO)
-    ;
-        RvalOrNumPairOrNone = kind_num_pair(type_num(Num1), Num2),
-        io.write_string(", ", !IO),
-        io.write_int(Num1, !IO),
-        io.write_string(", ", !IO),
-        io.write_int(Num2, !IO)
-    ;
-        RvalOrNumPairOrNone = kind_none
-    ).
-
-:- pred output_label_layout_data_defn(llds_out_info::in, proc_label::in,
-    int::in, layout_name::in, maybe(trace_port)::in, maybe(bool)::in, int::in,
-    maybe(int)::in, maybe(user_event_data)::in, maybe(label_var_info)::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_label_layout_data_defn(Info, ProcLabel, LabelNum, ProcLayoutAddr,
-        MaybePort, MaybeIsHidden, LabelNumberInModule, MaybeGoalPath,
-        MaybeUserData, MaybeVarInfo, !DeclSet, !IO) :-
-    output_layout_decl(ProcLayoutAddr, !DeclSet, !IO),
-    (
-        MaybeUserData = no,
-        UserChars = ""
-    ;
-        MaybeUserData = yes(UserData),
-        UserChars = "_U",
-        UserData = user_event_data(UserEventNumber, UserLocnsRval,
-            UserAttrMaybeVarNums),
-
-        AttrVarNumsLayoutName = user_event_attr_var_nums(ProcLabel, LabelNum),
-        AttrVarNumsDataAddr = layout_addr(AttrVarNumsLayoutName),
-        decl_set_insert(decl_data_addr(AttrVarNumsDataAddr), !DeclSet),
-        output_layout_name_storage_type_name(AttrVarNumsLayoutName, no, !IO),
-        io.write_string(" = {\n", !IO),
-        io.write_list(UserAttrMaybeVarNums, ", ", output_maybe_var_num, !IO),
-        io.write_string("\n};\n\n", !IO),
-
-        UserLayoutName = user_event_layout(ProcLabel, LabelNum),
-        UserDataAddr = layout_addr(UserLayoutName),
-        decl_set_insert(decl_data_addr(UserDataAddr), !DeclSet),
-        output_layout_name_storage_type_name(UserLayoutName, no, !IO),
-        io.write_string(" = {\n", !IO),
-        io.write_int(UserEventNumber, !IO),
-        io.write_string(",\n(MR_LongLval *) ", !IO),
-        output_rval_as_addr(Info, UserLocnsRval, !IO),
-        io.write_string(",\n", !IO),
-        output_layout_name(AttrVarNumsLayoutName, !IO),
-        io.write_string("\n};\n\n", !IO)
-    ),
-    (
-        MaybeIsHidden = yes(yes),
-        HiddenChars = "T"
-    ;
-        MaybeIsHidden = yes(no),
-        HiddenChars = ""
-    ;
-        MaybeIsHidden = no,
-        % The value of the hidden field shouldn't matter here.
-        HiddenChars = ""
-    ),
-    (
-        MaybeVarInfo = yes(VarInfo0),
-        VarInfo0 = label_var_info(EncodedVarCount1, LocnsTypes0, VarNums0,
-            TypeParams0),
-        output_record_rval_decls(Info, LocnsTypes0, !DeclSet, !IO),
-        output_record_rval_decls(Info, VarNums0, !DeclSet, !IO),
-        output_record_rval_decls(Info, TypeParams0, !DeclSet, !IO),
-        LabelVars = label_has_var_info,
-        (
-            LocnsTypes0 = const(llconst_data_addr(LTDataAddr, no)),
-            LTDataAddr = data_addr(_, scalar_common_ref(LTTypeNum, LTCellNum)),
-            VarNums0 = const(llconst_data_addr(VNDataAddr, no)),
-            VNDataAddr = data_addr(_, scalar_common_ref(VNTypeNum, VNCellNum))
-        ->
-            (
-                TypeParams0 = const(llconst_data_addr(TPDataAddr, no)),
-                TPDataAddr = data_addr(_,
-                    scalar_common_ref(TPTypeNum, TPCellNum))
-            ->
-                CommonChars = "XCCC",
-                LocnsTypes1 = kind_num_pair(LTTypeNum, LTCellNum),
-                VarNums1 = kind_num_pair(VNTypeNum, VNCellNum),
-                TypeParams1 = kind_num_pair(TPTypeNum, TPCellNum)
-            ;
-                TypeParams0 = const(llconst_int(0))
-            ->
-                CommonChars = "XCC0",
-                LocnsTypes1 = kind_num_pair(LTTypeNum, LTCellNum),
-                VarNums1 = kind_num_pair(VNTypeNum, VNCellNum),
-                TypeParams1 = kind_none
-            ;
-                CommonChars = "",
-                LocnsTypes1 = kind_rval(LocnsTypes0),
-                VarNums1 = kind_rval(VarNums0),
-                TypeParams1 = kind_rval(TypeParams0)
-            )
-        ;
-            CommonChars = "",
-            LocnsTypes1 = kind_rval(LocnsTypes0),
-            VarNums1 = kind_rval(VarNums0),
-            TypeParams1 = kind_rval(TypeParams0)
-        ),
-        Macro0 = "MR_DEF_LL" ++ HiddenChars ++ CommonChars,
-        MaybeVarInfoTuple = yes({EncodedVarCount1, LocnsTypes1, VarNums1,
-            TypeParams1})
-    ;
-        MaybeVarInfo = no,
-        LabelVars = label_has_no_var_info,
-        Macro0 = "MR_DEF_LLNVI" ++ HiddenChars,
-        MaybeVarInfoTuple = no
-    ),
-    Macro = Macro0 ++ UserChars,
-    LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
-    io.write_string("\n", !IO),
-    io.write_string(Macro, !IO),
-    io.write_string("(", !IO),
-    output_proc_label_no_prefix(ProcLabel, !IO),
-    io.write_string(",\n", !IO),
-    io.write_int(LabelNum, !IO),
-    io.write_string(", ", !IO),
-    (
-        MaybePort = yes(Port),
-        io.write_string(trace_port_to_string(Port), !IO)
-    ;
-        MaybePort = no,
-        io.write_string("NONE", !IO)
-    ),
-    io.write_string(", ", !IO),
-    io.write_int(LabelNumberInModule, !IO),
-    io.write_string(", ", !IO),
-    (
-        MaybeGoalPath = yes(GoalPath),
-        io.write_int(GoalPath, !IO)
-    ;
-        MaybeGoalPath = no,
-        io.write_string("0", !IO)
-    ),
-    (
-        MaybeVarInfoTuple = yes({EncodedVarCount,
-            LocnsTypes, VarNums, TypeParams}),
-        io.write_string(", ", !IO),
-        io.write_int(EncodedVarCount, !IO),
-        output_rval_or_numpair_or_none(Info, LocnsTypes, !IO),
-        output_rval_or_numpair_or_none(Info, VarNums, !IO),
-        output_rval_or_numpair_or_none(Info, TypeParams, !IO)
-    ;
-        MaybeVarInfoTuple = no
-    ),
-    io.write_string(");\n", !IO),
-    decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
-
-:- pred output_maybe_var_num(maybe(int)::in, io::di, io::uo) is det.
-
-output_maybe_var_num(no, !IO) :-
-    % Zero means not a variable, which is what we want.
-    io.write_int(0, !IO).
-output_maybe_var_num(yes(VarNum), !IO) :-
-    io.write_int(VarNum, !IO).
-
     % Output the rval in a context in which it is immediately cast to an
     % address.
     %
@@ -867,7 +958,7 @@
 
 output_rval_as_addr(Info, Rval, !IO) :-
     ( Rval = const(llconst_int(0)) ->
-        io.write_string(" 0", !IO)
+        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)
@@ -907,6 +998,7 @@
 
 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),
     ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
     Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
@@ -937,7 +1029,8 @@
                 !DeclSet, !IO),
             output_layout_exec_trace_decls(Info, RttiProcLabel, ExecTrace,
                 !DeclSet, !IO),
-            output_layout_exec_trace(RttiProcLabel, ExecTrace, !DeclSet, !IO)
+            output_layout_exec_trace(MangledModuleName, RttiProcLabel,
+                ExecTrace, !DeclSet, !IO)
         ;
             MaybeExecTrace = no
         ),
@@ -947,7 +1040,7 @@
             ProcBodyBytes = [_ | _],
             io.write_string("\n", !IO),
             output_layout_name_storage_type_name(
-                proc_layout_body_bytecode(RttiProcLabel), yes, !IO),
+                proc_layout_body_bytecode(RttiProcLabel), being_defined, !IO),
             io.write_string(" = {\n", !IO),
             output_bytecodes_driver(ProcBodyBytes, !IO),
             io.write_string("};\n\n", !IO)
@@ -1014,7 +1107,7 @@
 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),
-        yes, !IO),
+        being_defined, !IO),
     io.write_string(" = {\n", !IO),
     output_layout_traversal_group(Traversal, !IO).
 
@@ -1097,26 +1190,14 @@
     io::di, io::uo) is det.
 
 output_layout_exec_trace_decls(Info, RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
-    ExecTrace = proc_layout_exec_trace(MaybeCallLabelLayout,
-        EventDataAddrs, MaybeTableInfo, _HeadVarNums, _VarNames, _MaxVarNum,
+    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_label_layout_addrs_in_vector(EventDataAddrs, "MR_DECL_LABEL_LAYOUT",
-        !IO),
-    EventDataDeclIds = list.map(wrap_decl_data_addr, EventDataAddrs),
-    list.foldl(decl_set_insert, EventDataDeclIds, !DeclSet),
-    (
-        MaybeCallLabelLayout = yes(CallLabelDetails),
-        CallLabelDetails = label_layout_details(CallProcLabel, LabelNum,
-            LabelVars),
-        CallLabelLayout = label_layout(CallProcLabel, LabelNum, LabelVars),
-        output_layout_decl(CallLabelLayout, !DeclSet, !IO)
-    ;
-        MaybeCallLabelLayout = no
-    ),
     output_layout_decl(module_layout(ModuleName), !DeclSet, !IO),
     (
         MaybeTableInfo = yes(TableInfo),
@@ -1167,40 +1248,40 @@
         )
     ).
 
-:- pred output_layout_exec_trace(rtti_proc_label::in,
+:- 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(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
+output_layout_exec_trace(MangledModuleName, RttiProcLabel, ExecTrace,
+        !DeclSet, !IO) :-
     ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails,
-        EventDataAddrs, MaybeTableInfo, HeadVarNums, _VarNames, MaxVarNum,
-        MaxRegNum, MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
-        MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot, MaybeTailRecSlot,
-        EffTraceLevel, Flags),
+        InterfaceEventLabelSlots, InternalEventLabelSlots, MaybeTableInfo,
+        HeadVarNums, _VarNames, MaxVarNum, MaxRegNum,
+        MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot, MaybeMaxfrSlot,
+        EvalMethod, MaybeCallTableSlot, MaybeTailRecSlot, EffTraceLevel,
+        Flags),
 
+    EventLabelSlots = InterfaceEventLabelSlots ++ InternalEventLabelSlots,
     (
-        EventDataAddrs = []
+        EventLabelSlots = []
     ;
-        EventDataAddrs = [_ | _],
+        EventLabelSlots = [_ | _],
         io.write_string("\n", !IO),
         output_layout_name_storage_type_name(
-            proc_layout_label_layouts(RttiProcLabel), yes, !IO),
+            proc_layout_label_layouts(RttiProcLabel), being_defined, !IO),
         io.write_string(" = {\n", !IO),
-        output_label_layout_addrs_in_vector(EventDataAddrs, "MR_LABEL_LAYOUT",
-            !IO),
+        output_layout_slots_in_vector(MangledModuleName, EventLabelSlots, !IO),
         io.write_string("};\n\n", !IO)
     ),
 
     output_layout_name_storage_type_name(
-        proc_layout_exec_trace(RttiProcLabel), yes, !IO),
+        proc_layout_exec_trace(RttiProcLabel), being_defined, !IO),
     io.write_string(" = {\n", !IO),
     (
-        MaybeCallLabelDetails = yes(CallLabelDetails),
-        io.write_string("MR_LABEL_LAYOUT_REF(", !IO),
-        CallLabelDetails = label_layout_details(CallProcLabel, CallLabelNum,
-            _),
-        output_label(internal_label(CallLabelNum, CallProcLabel), no, !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)
@@ -1211,15 +1292,15 @@
     output_layout_name(module_layout(ModuleName), !IO),
     io.write_string(",\n", !IO),
     (
-        EventDataAddrs = [],
+        EventLabelSlots = [],
         io.write_string("NULL,\n", !IO)
     ;
-        EventDataAddrs = [_ | _],
+        EventLabelSlots = [_ | _],
         output_layout_name(proc_layout_label_layouts(RttiProcLabel), !IO),
         io.write_string(",\n", !IO)
     ),
-    list.length(EventDataAddrs, NumEventDataAddrs),
-    io.write_int(NumEventDataAddrs, !IO),
+    list.length(EventLabelSlots, NumEventLabelSlots),
+    io.write_int(NumEventLabelSlots, !IO),
     io.write_string(",\n", !IO),
     io.write_string("{ ", !IO),
     (
@@ -1308,7 +1389,7 @@
 output_proc_layout_head_var_nums(ProcLabel, HeadVarNums, !DeclSet, !IO) :-
     io.write_string("\n", !IO),
     output_layout_name_storage_type_name(proc_layout_head_var_nums(ProcLabel),
-        yes, !IO),
+        being_defined, !IO),
     io.write_string(" = {\n", !IO),
     (
         HeadVarNums = [],
@@ -1331,8 +1412,8 @@
     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), yes,
-        !IO),
+    output_layout_name_storage_type_name(proc_layout_var_names(ProcLabel),
+        being_defined, !IO),
     io.write_string(" = {\n", !IO),
     (
         VarNames = [],
@@ -1358,7 +1439,7 @@
         !DeclSet, !IO) :-
     io.write_string("\n", !IO),
     LayoutName = closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel),
-    output_layout_name_storage_type_name(LayoutName, yes, !IO),
+    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
     io.write_string(" = {\n{\n", !IO),
     output_proc_id(ClosureProcLabel, PredOrigin, !IO),
     io.write_string("},\n", !IO),
@@ -1534,7 +1615,8 @@
 
     ModuleCommonLayoutName = module_common_layout(ModuleName),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(ModuleCommonLayoutName, yes, !IO),
+    output_layout_name_storage_type_name(ModuleCommonLayoutName,
+        being_defined, !IO),
     io.write_string(" = {\n", !IO),
     io.write_int(layout_version_number, !IO),
     io.write_string(",\n", !IO),
@@ -1549,26 +1631,28 @@
     decl_set_insert(decl_data_addr(layout_addr(ModuleCommonLayoutName)),
         !DeclSet).
 
-:- pred output_module_layout_data_defn(llds_out_info::in, module_name::in,
-    layout_name::in, list(layout_name)::in, list(file_layout_data)::in,
-    trace_level::in, int::in, int::in, maybe(event_set_layout_data)::in,
+:- pred output_module_layout_data_defn(llds_out_info::in,
+    module_name::in, layout_name::in, list(layout_name)::in,
+    list(file_layout_data)::in, trace_level::in, int::in, int::in,
+    maybe(event_set_layout_data)::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_module_layout_data_defn(Info, ModuleName, ModuleCommonLayoutName,
-        ProcLayoutNames, FileLayouts, TraceLevel, SuppressedEvents,
-        NumLabels, MaybeEventSetLayout, !DeclSet, !IO) :-
+output_module_layout_data_defn(Info, ModuleName,
+        ModuleCommonLayoutName, ProcLayoutNames, FileLayouts, TraceLevel,
+        SuppressedEvents, NumLabels, MaybeEventSetLayout, !DeclSet, !IO) :-
     output_layout_decl(module_common_layout(ModuleName), !DeclSet, !IO),
     output_module_layout_proc_vector_defn(ModuleName, ProcLayoutNames,
         ProcVectorName, !DeclSet, !IO),
-    output_file_layout_data_defns(Info, ModuleName, 0, FileLayouts,
-        FileLayoutNames, !DeclSet, !IO),
+    output_file_layout_data_defns(Info, ModuleName,
+        0, FileLayouts, FileLayoutNames, !DeclSet, !IO),
     output_file_layout_vector_data_defn(ModuleName, FileLayoutNames,
         FileVectorName, !DeclSet, !IO),
 
     io.write_string("\n", !IO),
     LabelExecCountName = module_layout_label_exec_count(ModuleName,
         NumLabels),
-    output_layout_name_storage_type_name(LabelExecCountName, yes, !IO),
+    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),
 
@@ -1587,7 +1671,7 @@
 
     ModuleLayoutName = module_layout(ModuleName),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(ModuleLayoutName, yes, !IO),
+    output_layout_name_storage_type_name(ModuleLayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     io.write_string("&", !IO),
     output_layout_name(ModuleCommonLayoutName, !IO),
@@ -1650,7 +1734,7 @@
     LayoutName = module_layout_event_specs(ModuleName),
     DataAddr = layout_addr(LayoutName),
     decl_set_insert(decl_data_addr(DataAddr), !DeclSet),
-    output_layout_name_storage_type_name(LayoutName, yes, !IO),
+    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     io.write_list(EventSpecs, ",\n",
         output_event_spec(Info, ModuleName, TypesRvalMap), !IO),
@@ -1667,7 +1751,8 @@
         module_layout_event_arg_names(ModuleName, EventNumber),
     AttrNamesDataAddr = layout_addr(AttrNamesLayoutName),
     decl_set_insert(decl_data_addr(AttrNamesDataAddr), !DeclSet),
-    output_layout_name_storage_type_name(AttrNamesLayoutName, yes, !IO),
+    output_layout_name_storage_type_name(AttrNamesLayoutName,
+        being_defined, !IO),
     io.write_string(" = {\n", !IO),
     io.write_list(Attrs, ", ", output_attr_name, !IO),
     io.write_string("\n};\n\n", !IO),
@@ -1684,7 +1769,8 @@
             module_layout_event_synth_attrs(ModuleName, EventNumber),
         SynthAttrsDataAddr = layout_addr(SynthAttrsLayoutName),
         decl_set_insert(decl_data_addr(SynthAttrsDataAddr), !DeclSet),
-        output_layout_name_storage_type_name(SynthAttrsLayoutName, yes, !IO),
+        output_layout_name_storage_type_name(SynthAttrsLayoutName,
+            being_defined, !IO),
         io.write_string(" = {\n", !IO),
         io.write_list(Attrs, ",\n",
             output_synth_attr(ModuleName, EventNumber), !IO),
@@ -1694,7 +1780,8 @@
             module_layout_event_synth_order(ModuleName, EventNumber),
         SynthOrderDataAddr = layout_addr(SynthOrderLayoutName),
         decl_set_insert(decl_data_addr(SynthOrderDataAddr), !DeclSet),
-        output_layout_name_storage_type_name(SynthOrderLayoutName, yes, !IO),
+        output_layout_name_storage_type_name(SynthOrderLayoutName,
+            being_defined, !IO),
         io.write_string(" = {\n", !IO),
         % The -1 acts as sentinel.
         io.write_list(SynthOrder ++ [-1], ", ", io.write_int, !IO),
@@ -1724,7 +1811,8 @@
             EventNumber, AttrNumber),
         ArgsDataAddr = layout_addr(ArgsLayoutName),
         decl_set_insert(decl_data_addr(ArgsDataAddr), !DeclSet),
-        output_layout_name_storage_type_name(ArgsLayoutName, yes, !IO),
+        output_layout_name_storage_type_name(ArgsLayoutName,
+            being_defined, !IO),
         io.write_string(" =\n{ ", !IO),
         io.write_list(ArgAttrNums, ", ", io.write_int, !IO),
         io.write_string(" };\n\n", !IO),
@@ -1733,7 +1821,8 @@
             EventNumber, AttrNumber),
         OrderDataAddr = layout_addr(OrderLayoutName),
         decl_set_insert(decl_data_addr(OrderDataAddr), !DeclSet),
-        output_layout_name_storage_type_name(OrderLayoutName, yes, !IO),
+        output_layout_name_storage_type_name(OrderLayoutName,
+            being_defined, !IO),
         io.write_string(" =\n{ ", !IO),
         OrderSentinel = Order ++ [-1],
         io.write_list(OrderSentinel, ", ", io.write_int, !IO),
@@ -1816,7 +1905,7 @@
     list.foldl2(output_layout_decl, ProcLayoutNames, !DeclSet, !IO),
     VectorName = module_layout_proc_vector(ModuleName),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(VectorName, yes, !IO),
+    output_layout_name_storage_type_name(VectorName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     (
         ProcLayoutNames = [],
@@ -1852,7 +1941,7 @@
 output_event_set_desc_defn(ModuleName, EventSetDesc, !DeclSet, !IO) :-
     LayoutName = module_layout_event_set_desc(ModuleName),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, yes, !IO),
+    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
     io.write_string(" = {", !IO),
     output_module_string_table_strings(EventSetDesc, [], !IO),
     io.write_string("};\n", !IO),
@@ -1866,7 +1955,7 @@
         string_with_0s(StringTable0), !DeclSet, !IO) :-
     TableName = module_layout_string_table(ModuleName),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(TableName, yes, !IO),
+    output_layout_name_storage_type_name(TableName, being_defined, !IO),
     io.write_string(" = {", !IO),
 
     %
@@ -1923,7 +2012,7 @@
     list.foldl2(output_layout_decl, FileLayoutNames, !DeclSet, !IO),
     VectorName = module_layout_file_vector(ModuleName),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(VectorName, yes, !IO),
+    output_layout_name_storage_type_name(VectorName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     (
         FileLayoutNames = [],
@@ -1945,32 +2034,30 @@
 output_file_layout_data_defns(Info, ModuleName, FileNum,
         [FileLayout | FileLayouts], [FileLayoutName | FileLayoutNames],
         !DeclSet, !IO) :-
-    output_file_layout_data_defn(Info, ModuleName, FileNum, FileLayout,
-        FileLayoutName, !DeclSet, !IO),
-    output_file_layout_data_defns(Info, ModuleName, FileNum + 1, FileLayouts,
-        FileLayoutNames, !DeclSet, !IO).
+    output_file_layout_data_defn(Info, ModuleName,
+        FileNum, FileLayout, FileLayoutName, !DeclSet, !IO),
+    output_file_layout_data_defns(Info, ModuleName,
+        FileNum + 1, FileLayouts, FileLayoutNames, !DeclSet, !IO).
 
-:- pred output_file_layout_data_defn(llds_out_info::in, module_name::in,
-    int::in, file_layout_data::in, layout_name::out,
+:- pred output_file_layout_data_defn(llds_out_info::in,
+    module_name::in, int::in, file_layout_data::in, layout_name::out,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
 output_file_layout_data_defn(Info, ModuleName, FileNum, FileLayout,
         FileLayoutName, !DeclSet, !IO) :-
+    MangledModuleName = Info ^ lout_mangled_module_name,
     FileLayout = file_layout_data(FileName, LineNoLabelList),
-    list.map2(line_no_label_to_label_layout_addr, LineNoLabelList,
-        LineNos, LabelLayoutAddrs),
-    list.foldl2(output_record_data_addr_decls(Info), LabelLayoutAddrs,
-        !DeclSet, !IO),
+    assoc_list.keys_and_values(LineNoLabelList, LineNos, LabelLayoutSlots),
 
     list.length(LineNoLabelList, VectorLengths),
     output_file_layout_line_number_vector_defn(ModuleName, FileNum,
         LineNos, LineNumberVectorName, !DeclSet, !IO),
-    output_file_layout_label_layout_vector_defn(ModuleName, FileNum,
-        LabelLayoutAddrs, LabelVectorName, !DeclSet, !IO),
+    output_file_layout_label_layout_vector_defn(MangledModuleName, ModuleName,
+        FileNum, LabelLayoutSlots, LabelVectorName, !DeclSet, !IO),
 
     FileLayoutName = file_layout(ModuleName, FileNum),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(FileLayoutName, yes, !IO),
+    output_layout_name_storage_type_name(FileLayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     quote_and_write_string(FileName, !IO),
     io.write_string(",\n", !IO),
@@ -1990,7 +2077,7 @@
         LayoutName, !DeclSet, !IO) :-
     LayoutName = file_layout_line_number_vector(ModuleName, FileNum),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, yes, !IO),
+    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     (
         LineNumbers = [],
@@ -2004,97 +2091,94 @@
     io.write_string("};\n", !IO),
     decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
 
-:- pred output_file_layout_label_layout_vector_defn(module_name::in, int::in,
-    list(data_addr)::in, layout_name::out, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
+:- pred output_file_layout_label_layout_vector_defn(string::in,
+    module_name::in, int::in, list(layout_slot_name)::in, layout_name::out,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_file_layout_label_layout_vector_defn(ModuleName, FileNum, LabelAddrs,
-        LayoutName, !DeclSet, !IO) :-
+output_file_layout_label_layout_vector_defn(MangledModuleName, ModuleName,
+        FileNum, LabelSlots, LayoutName, !DeclSet, !IO) :-
     LayoutName = file_layout_label_layout_vector(ModuleName, FileNum),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, yes, !IO),
+    output_layout_name_storage_type_name(LayoutName, being_defined, !IO),
     io.write_string(" = {\n", !IO),
     (
-        LabelAddrs = [],
+        LabelSlots = [],
         % ANSI/ISO C doesn't allow empty arrays, so place a dummy value
         % in the array.
         io.write_string("NULL\n", !IO)
     ;
-        LabelAddrs = [_ | _],
-        output_label_layout_addrs_in_vector(LabelAddrs, "MR_LABEL_LAYOUT", !IO)
+        LabelSlots = [_ | _],
+        output_layout_slots_in_vector(MangledModuleName, LabelSlots, !IO)
     ),
     io.write_string("};\n", !IO),
     decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_label_layout_addrs_in_vector(list(data_addr)::in, string::in,
+:- pred output_layout_slots_in_vector(string::in, list(layout_slot_name)::in,
     io::di, io::uo) is det.
 
-output_label_layout_addrs_in_vector([], _, !IO).
-output_label_layout_addrs_in_vector([DataAddr | DataAddrs], Macro, !IO) :-
+output_layout_slots_in_vector(_ModuleName, [], !IO).
+output_layout_slots_in_vector(ModuleName, [SlotName | SlotNames], !IO) :-
+    SlotName = layout_slot(ArrayName, SlotNum),
     (
-        DataAddr = layout_addr(LayoutName),
-        LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info)
-    ->
-        groupable_labels(ProcLabel, 1, _N, [LabelNum], RevLabelNums,
-            DataAddrs, RemainingDataAddrs),
-        list.reverse(RevLabelNums, LabelNums),
-        io.write_string(Macro, !IO),
-        io.write_int(list.length(LabelNums), !IO),
-        io.write_string("(", !IO),
-        output_proc_label_no_prefix(ProcLabel, !IO),
-        io.write_string(",", !IO),
-        io.write_list(LabelNums, ",", io.write_int, !IO),
-        io.write_string(")\n", !IO),
-        output_label_layout_addrs_in_vector(RemainingDataAddrs, Macro, !IO)
+        (
+            ArrayName = label_layout_array(label_has_var_info),
+            Macro = "MR_var_label_layout_refs"
     ;
-        unexpected(this_file,
-            "output_label_layout_addrs_in_vector: not label layout")
+            ArrayName = label_layout_array(label_has_no_var_info),
+            Macro = "MR_no_var_label_layout_refs"
+        ),
+        find_slots_in_same_array(ArrayName, SlotNames, [], RevTailSlotNums,
+            OtherArraySlotNames),
+        list.reverse(RevTailSlotNums, TailSlotNums),
+        SlotNums = [SlotNum | TailSlotNums],
+        % There must be a macro of the form Macro<n> for all values of <n>
+        % between 1 and ChunkSize.
+        ChunkSize = 10,
+        list.chunk(SlotNums, ChunkSize, SlotNumChunks),
+        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 = user_event_layout_array
+        ),
+        output_layout_slot_name(use_layout_macro, ModuleName, SlotName, !IO),
+        io.write_string(",\n", !IO),
+        output_layout_slots_in_vector(ModuleName, SlotNames, !IO)
     ).
 
-:- pred groupable_labels(proc_label::in, int::in, int::out,
-    list(int)::in, list(int)::out, list(data_addr)::in, list(data_addr)::out)
-    is det.
+:- pred find_slots_in_same_array(layout_array_name::in,
+    list(layout_slot_name)::in, list(int)::in, list(int)::out,
+    list(layout_slot_name)::out) is det.
 
-groupable_labels(GroupProcLabel, !Count, !RevLabelsNums, !DataAddrs) :-
-    (
-        !.DataAddrs = []
-    ;
-        !.DataAddrs = [DataAddr | DataAddrsTail],
-        (
-            DataAddr = layout_addr(LayoutName),
-            LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info)
-        ->
-            % There must be a macro of the form MR_LABEL_LAYOUT<n> and
-            % MR_DECL_LABEL_LAYOUT<n> for every <n> up to MaxChunkSize.
-            MaxChunkSize = 9,
-            (
-                % We cannot group together labels from different procedures.
-                ProcLabel = GroupProcLabel,
-                % Leave room for the one we're adding.
-                !.Count < MaxChunkSize
-            ->
-                !:DataAddrs = DataAddrsTail,
-                !:Count = !.Count + 1,
-                !:RevLabelsNums = [LabelNum | !.RevLabelsNums],
-                groupable_labels(GroupProcLabel, !Count, !RevLabelsNums,
-                    !DataAddrs)
-            ;
-                true
-            )
+find_slots_in_same_array(_ArrayName, [], !RevSlotNums, []).
+find_slots_in_same_array(ArrayName, [SlotName | SlotNames], !RevSlotNums,
+        OtherArraySlotNames) :-
+    SlotName = layout_slot(SlotArrayName, SlotNum),
+    ( SlotArrayName = ArrayName ->
+        !:RevSlotNums = [SlotNum | !.RevSlotNums],
+        find_slots_in_same_array(ArrayName, SlotNames, !RevSlotNums,
+            OtherArraySlotNames)
         ;
-            unexpected(this_file, "groupable_labels: not label layout")
-        )
+        OtherArraySlotNames = [SlotName | SlotNames]
     ).
 
-%-----------------------------------------------------------------------------%
+:- pred output_layout_slot_chunk(string::in, string::in, list(int)::in,
+    io::di, io::uo) is det.
 
-:- pred line_no_label_to_label_layout_addr(pair(int, layout_name)::in,
-    int::out, data_addr::out) is det.
+output_layout_slot_chunk(Macro, ModuleName, SlotNums, !IO) :-
+    list.length(SlotNums, Length),
+    io.write_string(Macro, !IO),
+    io.write_int(Length, !IO),
+    io.write_string("(", !IO),
+    io.write_string(ModuleName, !IO),
+    io.write_string(", ", !IO),
+    io.write_list(SlotNums, ",", io.write_int, !IO),
+    io.write_string(")\n", !IO).
 
-line_no_label_to_label_layout_addr(LineNo - LabelLayout, LineNo, DataAddr) :-
-    DataAddr = layout_addr(LabelLayout).
+%-----------------------------------------------------------------------------%
 
 :- pred quote_and_write_string(string::in, io::di, io::uo) is det.
 
@@ -2150,7 +2234,7 @@
     % Write out the proc static.
     LayoutName = proc_static(RttiProcLabel),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, yes, !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),
@@ -2198,7 +2282,7 @@
 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, yes, !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),
@@ -2279,7 +2363,7 @@
         !IO) :-
     LayoutName = proc_static_coverage_point_static(RttiProcLabel),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, yes, !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),
@@ -2304,7 +2388,7 @@
         !DeclSet, !IO) :-
     LayoutName = proc_static_coverage_point_dynamic(RttiProcLabel),
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, yes, !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),
@@ -2325,7 +2409,7 @@
     output_layout_decl(ProcLayoutName, !DeclSet, !IO),
 
     io.write_string("\n", !IO),
-    output_layout_name_storage_type_name(LayoutName, yes, !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),
Index: compiler/livemap.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/livemap.m,v
retrieving revision 1.92
diff -u -b -r1.92 livemap.m
--- compiler/livemap.m	11 Feb 2008 03:56:08 -0000	1.92
+++ compiler/livemap.m	17 Oct 2009 07:23:08 -0000
@@ -356,7 +356,7 @@
         build_live_lval_info(AffectsLiveness, LiveLvalInfo, Code,
             !Livevals, !ContainsBadUserCode)
     ;
-        Uinstr0 = foreign_proc_code(_, Components, _, _, _, _, _, _, _),
+        Uinstr0 = foreign_proc_code(_, Components, _, _, _, _, _, _, _, _),
         build_livemap_foreign_proc_components(Components,
             !Livevals, !ContainsBadUserCode)
     ).
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.363
diff -u -b -r1.363 llds.m
--- compiler/llds.m	21 Sep 2009 04:08:53 -0000	1.363
+++ compiler/llds.m	18 Oct 2009 15:10:40 -0000
@@ -24,6 +24,7 @@
 :- import_module hlds.code_model.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_llds.
+:- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
 :- import_module ll_backend.layout.
 :- import_module mdbcomp.prim_data.
@@ -74,10 +75,20 @@
                 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_layout_data           :: list(layout_data),
+                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_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_code                  :: list(comp_gen_c_module),
                 cfile_user_init_c_names     :: list(string),
-                cfile_user_final_c_names    :: list(string)
+                cfile_user_final_c_names    :: list(string),
+                cfile_complexity            :: list(complexity_proc_info)
             ).
 
     % Global variables generated by the compiler.
@@ -513,12 +524,13 @@
                 fproc_fix_layout        :: maybe(label),
                 fproc_fix_onlylayout    :: maybe(label),
                 fproc_nofix             :: maybe(label),
+                fproc_hash_def_label    :: maybe(label),
                 fproc_stack_slot_ref    :: bool,
                 fproc_maybe_dupl        :: proc_may_duplicate
             )
             % foreign_proc_code(Decls, Components. MayCallMercury,
-            %   FixNoLayout, FixLayout, FixOnlyLayout, NoFix, StackSlotRef,
-            %   MayBeDupl)
+            %   FixNoLayout, FixLayout, FixOnlyLayout, NoFix, HashDef,
+            %   StackSlotRef, MayBeDupl)
             %
             % Decls says what local variable declarations are required for
             % Components, which in turn can specify how the inputs should be
@@ -551,6 +563,18 @@
             % not mentioned in C code and has no associated layout structure,
             % being mentioned only in foreign_proc_fail_to components).
             %
+            % If HashDef is yes, then when the code generator generates C code
+            % for this foreign_proc, it should surround it with code that
+            % #defines the symbol MR_HASH_DEF_LABEL_LAYOUT to the address of
+            % the label layout structure of the given label. We use this
+            % mechanism to pass such addresses to the debugger because when
+            % the LLDS code is generated, we do not yet know what the address
+            % will be (even in C source form), since the slots in the arrays
+            % of label layout structures have not yet been allocated.
+            %
+            % If we are generating code for a target language other than C,
+            % HashDef will always be no.
+            %
             % StackSlotRef says whether the contents of the foreign_proc
             % C code can refer to stack slots. User-written shouldn't refer
             % to stack slots, the question is whether any compiler-generated
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.332
diff -u -b -r1.332 llds_out.m
--- compiler/llds_out.m	14 Oct 2009 05:28:35 -0000	1.332
+++ compiler/llds_out.m	18 Oct 2009 15:21:45 -0000
@@ -18,9 +18,9 @@
 :- interface.
 
 :- import_module hlds.hlds_llds.
-:- import_module hlds.hlds_module.
 :- import_module libs.globals.
 :- import_module libs.trace_params.
+:- import_module ll_backend.layout.
 :- import_module ll_backend.llds.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
@@ -34,6 +34,9 @@
 
 :- type llds_out_info
     --->    llds_out_info(
+                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_auto_comments              :: bool,
                 lout_line_numbers               :: bool,
                 lout_emit_c_loops               :: bool,
@@ -50,16 +53,13 @@
                 lout_globals                    :: globals
             ).
 
-:- func init_llds_out_info(globals) = llds_out_info.
-
 %-----------------------------------------------------------------------------%
 
     % 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
     % layout structures.
     %
-:- pred output_llds(globals::in, c_file::in, list(complexity_proc_info)::in,
-    map(label, data_addr)::in, io::di, io::uo) is det.
+:- pred output_llds(globals::in, c_file::in, io::di, io::uo) is det.
 
     % output_record_rval_decls(Info, Rval, !DeclSet) outputs the declarations
     % of any static constants, etc. that need to be declared before
@@ -208,10 +208,10 @@
 :- import_module backend_libs.rtti.
 :- import_module check_hlds.type_util.
 :- import_module hlds.hlds_data.
+:- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.options.
-:- import_module ll_backend.layout.
 :- import_module ll_backend.layout_out.
 :- import_module ll_backend.pragma_c_gen.
 :- import_module ll_backend.rtti_out.
@@ -228,8 +228,8 @@
 :- import_module int.
 :- import_module library.   % for the version number.
 :- import_module maybe.
-:- import_module pair.
 :- import_module multi_map.
+:- import_module pair.
 :- import_module set.
 :- import_module set_tree234.
 :- import_module string.
@@ -252,7 +252,7 @@
 
 %-----------------------------------------------------------------------------%
 
-output_llds(Globals, CFile, ComplexityProcs, StackLayoutLabels, !IO) :-
+output_llds(Globals, CFile, !IO) :-
     ModuleName = CFile ^ cfile_modulename,
     module_name_to_file_name(Globals, ModuleName, ".c", do_create_dirs,
         FileName, !IO),
@@ -260,8 +260,7 @@
     (
         Result = ok(FileStream),
         decl_set_init(DeclSet0),
-        output_single_c_file(Globals, CFile, ComplexityProcs,
-            StackLayoutLabels, FileStream, DeclSet0, _, !IO),
+        output_single_c_file(Globals, CFile, FileStream, DeclSet0, _, !IO),
         io.close_output(FileStream, !IO)
     ;
         Result = error(Error),
@@ -303,17 +302,20 @@
         GenerateBytecode = no
     ).
 
-:- pred output_single_c_file(globals::in, c_file::in,
-    list(complexity_proc_info)::in, map(label, data_addr)::in,
-    io.output_stream::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_single_c_file(Globals, CFile, ComplexityProcs, StackLayoutLabels,
-        FileStream, !DeclSet, !IO) :-
-    Info = init_llds_out_info(Globals),
+:- pred output_single_c_file(globals::in, c_file::in, io.output_stream::in,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
+
+output_single_c_file(Globals, CFile, FileStream, !DeclSet, !IO) :-
     CFile = c_file(ModuleName, C_HeaderLines, UserForeignCode, Exports,
         TablingInfoStructs, ScalarCommonDatas, VectorCommonDatas,
-        RttiDatas, LayoutDatas0, Modules,
-        UserInitPredCNames, UserFinalPredCNames),
+        RttiDatas, UserEventVarNums, UserEvents,
+        VarLabelLayouts, NoVarLabelLayouts,
+        InternalLabelToLayoutMap, EntryLabelToLayoutMap,
+        ProcLayoutDatas, ModuleLayoutDatas, ClosureLayoutDatas,
+        OtherLayoutDatas, Modules, UserInitPredCNames, UserFinalPredCNames,
+        ComplexityProcs),
+    Info = init_llds_out_info(ModuleName, Globals,
+        InternalLabelToLayoutMap, EntryLabelToLayoutMap),
     library.version(Version),
     io.set_output_stream(FileStream, OutputStream, !IO),
     module_name_to_file_name(Globals, ModuleName, ".m", do_not_create_dirs,
@@ -328,8 +330,7 @@
     output_foreign_header_include_lines(Info, C_HeaderLines, !IO),
     io.write_string("\n", !IO),
 
-    gather_c_file_labels(Modules, Labels),
-    order_layout_datas(LayoutDatas0, LayoutDatas),
+    gather_c_file_labels(Modules, EntryLabels, InternalLabels),
 
     output_static_linkage_define(!IO),
     list.foldl2(output_scalar_common_data_decl, ScalarCommonDatas,
@@ -337,7 +338,7 @@
     list.foldl2(output_vector_common_data_decl, VectorCommonDatas,
         !DeclSet, !IO),
     output_rtti_data_decl_list(Info, RttiDatas, !DeclSet, !IO),
-    output_record_c_label_decls(Info, StackLayoutLabels, Labels,
+    output_record_c_label_decls(Info, EntryLabels, InternalLabels,
         !DeclSet, !IO),
     list.foldl2(output_tabling_info_struct(Info), TablingInfoStructs,
         !DeclSet, !IO),
@@ -346,16 +347,87 @@
     list.foldl2(output_vector_common_data_defn(Info), VectorCommonDatas,
         !DeclSet, !IO),
     list.foldl2(output_rtti_data_defn(Info), RttiDatas, !DeclSet, !IO),
-    list.foldl2(output_layout_data_defn(Info), LayoutDatas, !DeclSet, !IO),
 
-    list.foldl2(output_comp_gen_c_module(Info, StackLayoutLabels), Modules,
+    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)
+    ),
+
+    list.foldl2(output_layout_data_defn(Info), ProcLayoutDatas,
+        !DeclSet, !IO),
+    list.foldl2(output_layout_data_defn(Info), ModuleLayoutDatas,
+        !DeclSet, !IO),
+    list.foldl2(output_layout_data_defn(Info), ClosureLayoutDatas,
         !DeclSet, !IO),
+    list.foldl2(output_layout_data_defn(Info), OtherLayoutDatas,
+        !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)
+    ),
+
+    list.foldl2(output_comp_gen_c_module(Info), Modules, !DeclSet, !IO),
     list.foldl(output_user_foreign_code(Info), UserForeignCode, !IO),
     list.foldl(io.write_string, Exports, !IO),
     io.write_string("\n", !IO),
     output_c_module_init_list(Info, ModuleName, Modules, RttiDatas,
-        LayoutDatas, ComplexityProcs, StackLayoutLabels, UserInitPredCNames,
-        UserFinalPredCNames, !DeclSet, !IO),
+        ProcLayoutDatas, ModuleLayoutDatas, ComplexityProcs,
+        UserInitPredCNames, UserFinalPredCNames, !DeclSet, !IO),
     io.set_output_stream(OutputStream, _, !IO).
 
 :- pred module_gather_env_var_names(list(comp_gen_c_module)::in,
@@ -374,45 +446,17 @@
     set.union(Proc ^ cproc_c_global_vars, !EnvVarNames),
     proc_gather_env_var_names(Procs, !EnvVarNames).
 
-:- pred order_layout_datas(list(layout_data)::in, list(layout_data)::out)
-    is det.
-
-order_layout_datas(LayoutDatas0, LayoutDatas) :-
-    order_layout_datas_2(LayoutDatas0, [], ProcLayouts,
-        [], LabelLayouts, [], OtherLayouts),
-    % list.reverse(RevProcLayouts, ProcLayouts),
-    % list.reverse(RevLabelLayouts, LabelLayouts),
-    % list.reverse(RevOtherLayouts, OtherLayouts),
-    list.condense([ProcLayouts, LabelLayouts, OtherLayouts], LayoutDatas).
-
-:- pred order_layout_datas_2(list(layout_data)::in,
-    list(layout_data)::in, list(layout_data)::out,
-    list(layout_data)::in, list(layout_data)::out,
-    list(layout_data)::in, list(layout_data)::out) is det.
-
-order_layout_datas_2([], !ProcLayouts, !LabelLayouts, !OtherLayouts).
-order_layout_datas_2([Layout | Layouts], !ProcLayouts, !LabelLayouts,
-        !OtherLayouts) :-
-    ( Layout = proc_layout_data(_, _, _) ->
-        !:ProcLayouts = [Layout | !.ProcLayouts]
-    ; Layout = label_layout_data(_, _, _, _, _, _, _, _, _) ->
-        !:LabelLayouts = [Layout | !.LabelLayouts]
-    ;
-        !:OtherLayouts = [Layout | !.OtherLayouts]
-    ),
-    order_layout_datas_2(Layouts, !ProcLayouts, !LabelLayouts, !OtherLayouts).
-
 :- 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(complexity_proc_info)::in, map(label, data_addr)::in,
-    list(string)::in, list(string)::in,
+    list(comp_gen_c_module)::in, list(rtti_data)::in,
+    list(layout_data)::in, list(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.
 
-output_c_module_init_list(Info, ModuleName, Modules, RttiDatas, LayoutDatas,
-        ComplexityProcs, StackLayoutLabels, InitPredNames, FinalPredNames,
-        !DeclSet, !IO) :-
+output_c_module_init_list(Info, ModuleName, Modules, RttiDatas,
+        ProcLayoutDatas, ModuleLayoutDatas, ComplexityProcs,
+        InitPredNames, FinalPredNames, !DeclSet, !IO) :-
     MustInit = (pred(Module::in) is semidet :-
-        module_defines_label_with_layout(Module, StackLayoutLabels)
+        module_defines_label_with_layout(Info, Module)
     ),
     list.filter(MustInit, Modules, AlwaysInitModules, MaybeInitModules),
     list.chunk(AlwaysInitModules, 40, AlwaysInitModuleBunches),
@@ -517,7 +561,8 @@
     output_type_tables_init_list(RttiDatas, !IO),
     io.write_string("}\n\n", !IO),
 
-    output_record_debugger_init_list_decls(Info, LayoutDatas, !DeclSet, !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),
@@ -528,11 +573,11 @@
     io.write_string("\t\treturn;\n", !IO),
     io.write_string("\t}\n", !IO),
     io.write_string("\tdone = MR_TRUE;\n", !IO),
-    output_debugger_init_list(LayoutDatas, !IO),
+    output_debugger_init_list(ModuleLayoutDatas, !IO),
     io.write_string("}\n\n", !IO),
 
     io.write_string("#ifdef MR_DEEP_PROFILING\n", !IO),
-    output_write_proc_static_list_decls(LayoutDatas, !DeclSet, !IO),
+    output_write_proc_static_list_decls(ProcLayoutDatas, !DeclSet, !IO),
     io.write_string("\nvoid ", !IO),
     output_init_name(ModuleName, !IO),
     io.write_string(
@@ -542,7 +587,7 @@
     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(LayoutDatas, !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("}\n", !IO),
     io.write_string("\n#endif\n\n", !IO),
@@ -588,17 +633,40 @@
     io.write_string(
         "static const void *const MR_grade = &MR_GRADE_VAR;\n", !IO).
 
-:- pred module_defines_label_with_layout(comp_gen_c_module::in,
-    map(label, data_addr)::in) is semidet.
+:- pred module_defines_label_with_layout(llds_out_info::in,
+    comp_gen_c_module::in) is semidet.
 
-module_defines_label_with_layout(Module, StackLayoutLabels) :-
+module_defines_label_with_layout(Info, Module) :-
     % Checking whether the set is empty or not
     % allows us to avoid calling gather_c_module_labels.
-    \+ map.is_empty(StackLayoutLabels),
+    InternalLabelToLayoutMap = Info ^ lout_internal_label_to_layout,
+    EntryLabelToLayoutMap = Info ^ lout_entry_label_to_layout,
+    (
+        \+ map.is_empty(InternalLabelToLayoutMap)
+    ;
+        \+ map.is_empty(EntryLabelToLayoutMap)
+    ),
     Module = comp_gen_c_module(_, Procedures),
-    gather_c_module_labels(Procedures, Labels),
-    list.member(Label, Labels),
-    map.search(StackLayoutLabels, Label, _).
+    gather_c_module_labels(Procedures, EntryLabels, InternalLabels),
+    (
+        find_first_match(internal_label_has_layout(InternalLabelToLayoutMap),
+            InternalLabels, _)
+    ;
+        find_first_match(entry_label_has_layout(EntryLabelToLayoutMap),
+            EntryLabels, _)
+    ).
+
+:- pred internal_label_has_layout(map(label, layout_slot_name)::in, label::in)
+    is semidet.
+
+internal_label_has_layout(InternalLabelToLayoutMap, Label) :-
+    map.search(InternalLabelToLayoutMap, Label, _).
+
+:- pred entry_label_has_layout(map(label, data_addr)::in, label::in)
+    is semidet.
+
+entry_label_has_layout(EntryLabelToLayoutMap, Label) :-
+    map.search(EntryLabelToLayoutMap, Label, _).
 
 %-----------------------------------------------------------------------------%
 
@@ -878,24 +946,21 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_comp_gen_c_module(llds_out_info::in, map(label, data_addr)::in,
-    comp_gen_c_module::in, decl_set::in, decl_set::out, io::di, io::uo)
-    is det.
+:- 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.
 
-output_comp_gen_c_module(Info, StackLayoutLabels, CompGenCModule,
-        !DeclSet, !IO) :-
+output_comp_gen_c_module(Info, CompGenCModule, !DeclSet, !IO) :-
     CompGenCModule = comp_gen_c_module(ModuleName, Procedures),
     io.write_string("\n", !IO),
-    list.foldl2(output_record_c_procedure_decls(Info, StackLayoutLabels),
-        Procedures, !DeclSet, !IO),
+    list.foldl2(output_record_c_procedure_decls(Info), Procedures,
+        !DeclSet, !IO),
     io.write_string("\n", !IO),
     io.write_string("MR_BEGIN_MODULE(", !IO),
     io.write_string(ModuleName, !IO),
     io.write_string(")\n", !IO),
-    gather_c_module_labels(Procedures, Labels),
-    output_c_label_inits(StackLayoutLabels, Labels, !IO),
+    gather_c_module_labels(Procedures, EntryLabels, InternalLabels),
+    output_c_label_inits(Info, EntryLabels, InternalLabels, !IO),
     io.write_string("MR_BEGIN_CODE\n", !IO),
-    io.write_string("\n", !IO),
     list.foldl(output_c_procedure(Info), Procedures, !IO),
     io.write_string("MR_END_MODULE\n", !IO).
 
@@ -1401,101 +1466,50 @@
     ).
 
 :- pred output_record_c_label_decls(llds_out_info::in,
-    map(label, data_addr)::in, list(label)::in, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
+    list(label)::in, list(label)::in,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_record_c_label_decls(Info, StackLayoutLabels, Labels, !DeclSet, !IO) :-
-    group_c_labels_with_layouts(StackLayoutLabels, Labels,
-        multi_map.init, DeclLLMap, multi_map.init, LocalLabels,
-        [], RevAddrsToDecl, [], RevOtherLabels),
-    multi_map.to_assoc_list(DeclLLMap, DeclLLList),
-    list.foldl2(output_label_layout_decls, DeclLLList, !DeclSet, !IO),
-    multi_map.to_assoc_list(LocalLabels, LocalLabelList),
-    list.foldl2(output_local_label_decls, LocalLabelList, !DeclSet, !IO),
-    list.reverse(RevAddrsToDecl, AddrsToDecl),
-    list.foldl2(output_record_stack_layout_decl(Info), AddrsToDecl,
+output_record_c_label_decls(Info, EntryLabels, InternalLabels,
+        !DeclSet, !IO) :-
+    group_decl_c_labels(InternalLabels, multi_map.init, InternalLabelMap),
+    multi_map.to_assoc_list(InternalLabelMap, InternalLabelList),
+    list.foldl2(output_record_internal_label_decls, InternalLabelList,
         !DeclSet, !IO),
-    list.reverse(RevOtherLabels, OtherLabels),
-    list.foldl2(output_record_c_label_decl(Info, StackLayoutLabels),
-        OtherLabels, !DeclSet, !IO).
+    list.foldl2(output_record_entry_label_decl(Info), EntryLabels,
+        !DeclSet, !IO).
 
-:- pred group_c_labels_with_layouts(map(label, data_addr)::in, list(label)::in,
-    multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
-    multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
-    list(data_addr)::in, list(data_addr)::out,
-    list(label)::in, list(label)::out) is det.
+:- pred group_decl_c_labels(list(label)::in,
+    multi_map(proc_label, int)::in, multi_map(proc_label, int)::out) is det.
 
-group_c_labels_with_layouts(_StackLayoutLabels, [],
-        !DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers).
-group_c_labels_with_layouts(StackLayoutLabels, [Label | Labels],
-        !DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers) :-
+group_decl_c_labels([], !InternalLabelMap).
+group_decl_c_labels([Label | Labels], !InternalLabelMap) :-
     (
         Label = internal_label(LabelNum, ProcLabel),
-        ( map.search(StackLayoutLabels, Label, DataAddr) ->
-            (
-                DataAddr = layout_addr(LayoutName),
-                LayoutName = label_layout(ProcLabel, LabelNum,
-                    LabelVars),
-                LabelVars = label_has_var_info
-            ->
-                svmulti_map.set(ProcLabel, LabelNum, !DeclLLMap)
-            ;
-                svmulti_map.set(ProcLabel, LabelNum, !OtherLocalMap),
-                !:RevAddrsToDecl = [DataAddr | !.RevAddrsToDecl]
-            )
-        ;
-            svmulti_map.set(ProcLabel, LabelNum, !OtherLocalMap)
-        )
+        svmulti_map.set(ProcLabel, LabelNum, !InternalLabelMap)
     ;
         Label = entry_label(_, _),
-        !:RevOthers = [Label | !.RevOthers]
+        unexpected(this_file, "group_decl_c_labels: entry label")
     ),
-    group_c_labels_with_layouts(StackLayoutLabels, Labels,
-        !DeclLLMap, !OtherLocalMap, !RevAddrsToDecl, !RevOthers).
-
-:- pred output_label_layout_decls(pair(proc_label, list(int))::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_label_layout_decls(ProcLabel - LabelNums0, !DeclSet, !IO) :-
-    % There must be a macro of the form MR_DECL_LL<n> for every <n>
-    % up to MaxChunkSize.
-    list.reverse(LabelNums0, LabelNums),
-    MaxChunkSize = 10,
-    list.chunk(LabelNums, MaxChunkSize, LabelNumChunks),
-    list.foldl2(output_label_layout_decl_group(ProcLabel), LabelNumChunks,
-        !DeclSet, !IO).
-
-:- pred output_label_layout_decl_group(proc_label::in, list(int)::in,
-    decl_set::in, decl_set::out, io::di, io::uo) is det.
-
-output_label_layout_decl_group(ProcLabel, LabelNums, !DeclSet, !IO) :-
-    io.write_string("MR_DECL_LL", !IO),
-    io.write_int(list.length(LabelNums), !IO),
-    io.write_string("(", !IO),
-    output_proc_label_no_prefix(ProcLabel, !IO),
-    io.write_string(", ", !IO),
-    io.write_list(LabelNums, ",", io.write_int, !IO),
-    io.write_string(")\n", !IO).
+    group_decl_c_labels(Labels, !InternalLabelMap).
 
-:- pred output_local_label_decls(pair(proc_label, list(int))::in,
+:- pred output_record_internal_label_decls(pair(proc_label, list(int))::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_local_label_decls(ProcLabel - LabelNums0, !DeclSet, !IO) :-
+output_record_internal_label_decls(ProcLabel - RevLabelNums, !DeclSet, !IO) :-
+    list.reverse(RevLabelNums, LabelNums),
     % There must be a macro of the form MR_decl_label<n> for every <n>
     % up to MaxChunkSize.
-    list.reverse(LabelNums0, LabelNums),
-    MaxChunkSize = 8,
+    MaxChunkSize = 10,
     list.chunk(LabelNums, MaxChunkSize, LabelNumChunks),
-    list.foldl2(output_local_label_decl_group(ProcLabel), LabelNumChunks,
-        !DeclSet, !IO),
-    list.foldl(insert_var_info_label_layout_decl(ProcLabel), LabelNums,
-        !DeclSet),
-    list.foldl(insert_code_addr_decl(ProcLabel), LabelNums, !DeclSet).
+    list.foldl2(output_record_internal_label_decl_group(ProcLabel),
+        LabelNumChunks, !DeclSet, !IO),
+    list.foldl(insert_internal_label_code_addr_decl(ProcLabel), LabelNums,
+        !DeclSet).
 
-:- pred output_local_label_decl_group(proc_label::in, list(int)::in,
+:- 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_local_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),
@@ -1503,82 +1517,37 @@
     io.write_string(", ", !IO),
     io.write_list(LabelNums, ",", io.write_int, !IO),
     io.write_string(")\n", !IO),
-    list.foldl(insert_code_addr_decl(ProcLabel), LabelNums, !DeclSet).
-
-:- pred insert_var_info_label_layout_decl(proc_label::in, int::in,
-    decl_set::in, decl_set::out) is det.
-
-insert_var_info_label_layout_decl(ProcLabel, LabelNum, !DeclSet) :-
-    LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info),
-    DataAddr = layout_addr(LayoutName),
-    DeclId = decl_data_addr(DataAddr),
-    decl_set_insert(DeclId, !DeclSet).
+    list.foldl(insert_internal_label_code_addr_decl(ProcLabel), LabelNums,
+        !DeclSet).
 
-:- pred insert_code_addr_decl(proc_label::in, int::in,
+:- pred insert_internal_label_code_addr_decl(proc_label::in, int::in,
     decl_set::in, decl_set::out) is det.
 
-insert_code_addr_decl(ProcLabel, LabelNum, !DeclSet) :-
+insert_internal_label_code_addr_decl(ProcLabel, LabelNum, !DeclSet) :-
     DeclId = decl_code_addr(code_label(internal_label(LabelNum, ProcLabel))),
     decl_set_insert(DeclId, !DeclSet).
 
-:- pred output_record_c_label_decl(llds_out_info::in,
-    map(label, data_addr)::in, label::in, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
+:- pred output_record_entry_label_decl(llds_out_info::in, label::in,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_record_c_label_decl(Info, StackLayoutLabels, Label, !DeclSet, !IO) :-
-    % Declare the stack layout entry for this label, if needed.
-    ( map.search(StackLayoutLabels, Label, DataAddr) ->
-        (
-            Label = internal_label(LabelNum, ProcLabel),
-            DataAddr = layout_addr(LayoutName),
-            LayoutName = label_layout(ProcLabel, LabelNum, LabelVars)
-        ->
-            (
-                LabelVars = label_has_var_info,
-                Macro = "MR_DECL_LL"
-            ;
-                LabelVars = label_has_no_var_info,
-                Macro = "MR_DECL_LLNVI"
-            ),
-            io.write_string(Macro, !IO),
-            io.write_string("(", !IO),
-            output_proc_label_no_prefix(ProcLabel, !IO),
-            io.write_string(", ", !IO),
-            io.write_int(LabelNum, !IO),
-            % The final semicolon is in the macro definition.
-            io.write_string(")\n", !IO),
-            % The macro declares both the label layout structure and the label.
-            AlreadyDeclaredLabel = yes
-        ;
-            output_record_stack_layout_decl(Info, DataAddr, !DeclSet, !IO),
-            AlreadyDeclaredLabel = no
-        )
-    ;
-        AlreadyDeclaredLabel = no
-    ),
-    (
-        AlreadyDeclaredLabel = no,
-        % Declare the label itself.
+output_record_entry_label_decl(_Info, Label, !DeclSet, !IO) :-
         (
             Label = entry_label(entry_label_exported, _),
-            DeclMacro = "MR_def_extern_entry("
+        DeclMacro = "MR_def_extern_entry"
         ;
             Label = entry_label(entry_label_local, _),
-            DeclMacro = "MR_decl_static("
+        DeclMacro = "MR_decl_static"
         ;
             Label = entry_label(entry_label_c_local, _),
-            DeclMacro = "MR_decl_local("
+        DeclMacro = "MR_decl_local"
         ;
             Label = internal_label(_, _),
-            DeclMacro = "MR_decl_label("
+        unexpected(this_file, "output_record_entry_label_decl: internal label")
         ),
         io.write_string(DeclMacro, !IO),
-        io.write_string("", !IO),
+    io.write_string("(", !IO),
         output_label(Label, no, !IO),
-        io.write_string(")\n", !IO)
-    ;
-        AlreadyDeclaredLabel = yes
-    ),
+    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,
@@ -1587,59 +1556,89 @@
 output_record_stack_layout_decl(Info, DataAddr, !DeclSet, !IO) :-
     output_record_data_addr_decls(Info, DataAddr, !DeclSet, !IO).
 
-:- pred output_c_label_inits(map(label, data_addr)::in, list(label)::in,
+%-----------------------------------------------------------------------------%
+
+:- pred output_c_label_inits(llds_out_info::in,
+    list(label)::in, list(label)::in,
     io::di, io::uo) is det.
 
-output_c_label_inits(StackLayoutLabels, Labels, !IO) :-
-    group_c_labels(StackLayoutLabels, Labels, multi_map.init, NoLayoutMap,
-        multi_map.init, LayoutMap, [], RevOtherLabels),
-    list.reverse(RevOtherLabels, OtherLabels),
-    list.foldl(output_c_label_init(StackLayoutLabels), OtherLabels, !IO),
-    multi_map.to_assoc_list(NoLayoutMap, NoLayoutList),
-    multi_map.to_assoc_list(LayoutMap, LayoutList),
-    list.foldl(output_c_label_init_group(""), NoLayoutList, !IO),
-    list.foldl(output_c_label_init_group("_sl"), LayoutList, !IO).
+output_c_label_inits(Info, EntryLabels, InternalLabels, !IO) :-
+    EntryLabelToLayoutMap = Info ^ lout_entry_label_to_layout,
+    list.foldl(output_c_entry_label_init(EntryLabelToLayoutMap),
+        EntryLabels, !IO),
+
+    InternalLabelToLayoutMap = Info ^ lout_internal_label_to_layout,
+    group_init_c_labels(InternalLabelToLayoutMap, InternalLabels,
+        multi_map.init, NoLayoutInternalMap,
+        multi_map.init, NoVarLayoutInternalMap,
+        multi_map.init, VarLayoutInternalMap),
+
+    multi_map.to_assoc_list(NoLayoutInternalMap, NoLayoutInternalList),
+    list.foldl(output_c_internal_label_no_layout_init_group,
+        NoLayoutInternalList, !IO),
+
+    multi_map.to_assoc_list(NoVarLayoutInternalMap, NoVarLayoutInternalList),
+    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).
 
-:- pred group_c_labels(map(label, data_addr)::in, list(label)::in,
-    multi_map(proc_label, int)::in, multi_map(proc_label, int)::out,
+:- 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,
-    list(label)::in, list(label)::out) is det.
-
-group_c_labels(_StackLayoutLabels, [], !NoLayoutMap, !LayoutMap, !RevOthers).
-group_c_labels(StackLayoutLabels, [Label | Labels], !NoLayoutMap, !LayoutMap,
-        !RevOthers) :-
+    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).
+group_init_c_labels(InternalLabelToLayoutMap, [Label | Labels],
+        !NoLayoutMap, !NoVarLayoutMap, !VarLayoutMap) :-
     (
         Label = internal_label(LabelNum, ProcLabel),
-        ( map.search(StackLayoutLabels, Label, _DataAddr) ->
-            svmulti_map.set(ProcLabel, LabelNum, !LayoutMap)
+        ( map.search(InternalLabelToLayoutMap, Label, Slot) ->
+            Slot = layout_slot(ArrayName, SlotNum),
+            ( 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)
+                )
+            ;
+                unexpected(this_file, "group_init_c_labels: bad slot type")
+            )
         ;
             svmulti_map.set(ProcLabel, LabelNum, !NoLayoutMap)
         )
     ;
         Label = entry_label(_, _),
-        !:RevOthers = [Label | !.RevOthers]
+        unexpected(this_file, "group_init_c_labels: entry label")
     ),
-    group_c_labels(StackLayoutLabels, Labels, !NoLayoutMap, !LayoutMap,
-        !RevOthers).
+    group_init_c_labels(InternalLabelToLayoutMap, Labels,
+        !NoLayoutMap, !NoVarLayoutMap, !VarLayoutMap).
 
-:- pred output_c_label_init_group(string::in,
+:- pred output_c_internal_label_no_layout_init_group(
     pair(proc_label, list(int))::in, io::di, io::uo) is det.
 
-output_c_label_init_group(Suffix, ProcLabel - RevLabelNums, !IO) :-
+output_c_internal_label_no_layout_init_group(ProcLabel - RevLabelNums, !IO) :-
     list.reverse(RevLabelNums, LabelNums),
-    % There must be macros of the form MR_init_label<n> and
-    % MR_init_label_sl<n> for every <n> up to MaxChunkSize.
-    MaxChunkSize = 8,
+    % There must be macros of the form MR_init_label_nvi<n> for every <n>
+    % up to MaxChunkSize.
+    MaxChunkSize = 10,
     list.chunk(LabelNums, MaxChunkSize, LabelNumChunks),
-    list.foldl(output_c_label_init_chunk(Suffix, ProcLabel),
+    list.foldl(output_c_internal_label_no_layout_init_chunk(ProcLabel),
         LabelNumChunks, !IO).
 
-:- pred output_c_label_init_chunk(string::in,
-    proc_label::in, list(int)::in, io::di, io::uo) is det.
+:- pred output_c_internal_label_no_layout_init_chunk(proc_label::in,
+    list(int)::in, io::di, io::uo) is det.
 
-output_c_label_init_chunk(Suffix, ProcLabel, LabelNums, !IO) :-
+output_c_internal_label_no_layout_init_chunk(ProcLabel, LabelNums, !IO) :-
     io.write_string("\tMR_init_label", !IO),
-    io.write_string(Suffix, !IO),
     io.write_int(list.length(LabelNums), !IO),
     io.write_string("(", !IO),
     output_proc_label_no_prefix(ProcLabel, !IO),
@@ -1647,26 +1646,54 @@
     io.write_list(LabelNums, ",", io.write_int, !IO),
     io.write_string(")\n", !IO).
 
-:- pred output_c_label_init(map(label, data_addr)::in, label::in,
+:- pred output_c_internal_label_layout_init_group(llds_out_info::in,
+    string::in, pair(proc_label, list({int, int}))::in,
     io::di, io::uo) is det.
 
-output_c_label_init(StackLayoutLabels, Label, !IO) :-
-    ( map.search(StackLayoutLabels, Label, DataAddr) ->
-        SuffixOpen = "_sl(",
-        ( DataAddr = layout_addr(proc_layout(_, _)) ->
-            % Labels whose stack layouts are proc layouts may need
-            % to have the code address in that layout initialized
-            % at run time (if code addresses are not static).
-            InitProcLayout = yes
-        ;
-            % Labels whose stack layouts are internal layouts
-            % do not have code addresses in their layouts.
-            InitProcLayout = no
-        )
+output_c_internal_label_layout_init_group(Info, Suffix,
+        ProcLabel - RevLabelSlotNums, !IO) :-
+    list.reverse(RevLabelSlotNums, LabelSlotNums),
+    % There must be macros of the form MR_init_label_vi<n> for every <n>
+    % up to MaxChunkSize.
+    MaxChunkSize = 10,
+    list.chunk(LabelSlotNums, MaxChunkSize, LabelSlotNumChunks),
+    list.foldl(
+        output_c_internal_label_layout_init_chunk(Info, Suffix, ProcLabel),
+        LabelSlotNumChunks, !IO).
+
+:- pred output_c_internal_label_layout_init_chunk(llds_out_info::in,
+    string::in, proc_label::in, list({int, int})::in, io::di, io::uo) is det.
+
+output_c_internal_label_layout_init_chunk(Info, Suffix, ProcLabel,
+        LabelSlotNums, !IO) :-
+    io.write_string("\tMR_init_label", !IO),
+    io.write_string(Suffix, !IO),
+    io.write_int(list.length(LabelSlotNums), !IO),
+    io.write_string("(", !IO),
+    output_proc_label_no_prefix(ProcLabel, !IO),
+    io.write_string(", ", !IO),
+    ModuleName = Info ^ lout_mangled_module_name,
+    io.write_string(ModuleName, !IO),
+    io.write_string(",\n\t\t", !IO),
+    io.write_list(LabelSlotNums, ", ", write_int_pair, !IO),
+    io.write_string(")\n", !IO).
+
+:- pred write_int_pair({int, int}::in, io::di, io::uo) is det.
+
+write_int_pair({LabelNum, SlotNum}, !IO) :- 
+    io.write_int(LabelNum, !IO),
+    io.write_string(",", !IO),
+    io.write_int(SlotNum, !IO).
+
+:- pred output_c_entry_label_init(map(label, data_addr)::in, label::in,
+    io::di, io::uo) is det.
+
+output_c_entry_label_init(EntryLabelToLayoutMap, Label, !IO) :-
+    ( map.search(EntryLabelToLayoutMap, Label, _DataAddr) ->
+        SuffixOpen = "_sl("
     ;
-        SuffixOpen = "(",
+        SuffixOpen = "("
         % This label has no stack layout to initialize.
-        InitProcLayout = no
     ),
     (
         Label = entry_label(entry_label_exported, ProcLabel),
@@ -1680,38 +1707,28 @@
     ;
         Label = internal_label(_, _),
         % These should have been separated out by group_c_labels.
-        unexpected(this_file, "output_c_label_init: internal/2")
+        unexpected(this_file, "output_c_entry_label_init: internal/2")
     ),
     io.write_string(TabInitMacro, !IO),
     io.write_string(SuffixOpen, !IO),
     output_proc_label_no_prefix(ProcLabel, !IO),
     io.write_string(");\n", !IO),
-    (
-        InitProcLayout = yes,
+
         io.write_string("\tMR_INIT_PROC_LAYOUT_ADDR(", !IO),
         output_label(Label, !IO),
-        io.write_string(");\n", !IO)
-    ;
-        InitProcLayout = no
-    ).
-
-:- pred label_is_proc_entry(label::in, bool::out) is det.
+    io.write_string(");\n", !IO).
 
-label_is_proc_entry(internal_label(_, _), no).
-label_is_proc_entry(entry_label(_, _), yes).
+%-----------------------------------------------------------------------------%
 
-:- pred output_record_c_procedure_decls(llds_out_info::in,
-    map(label, data_addr)::in, c_procedure::in, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
+:- 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.
 
-output_record_c_procedure_decls(Info, StackLayoutLabels, Proc,
-        !DeclSet, !IO) :-
+output_record_c_procedure_decls(Info, Proc, !DeclSet, !IO) :-
     Instrs = Proc ^ cproc_code,
     CGlobalVarSet = Proc ^ cproc_c_global_vars,
     set.to_sorted_list(CGlobalVarSet, CGlobalVars),
     list.foldl2(output_c_global_var_decl, CGlobalVars, !DeclSet, !IO),
-    list.foldl2(output_record_instruction_decls(Info, StackLayoutLabels),
-        Instrs, !DeclSet, !IO).
+    list.foldl2(output_record_instruction_decls(Info), Instrs, !DeclSet, !IO).
 
 :- pred output_c_global_var_decl(string::in,
     decl_set::in, decl_set::out, io::di, io::uo) is det.
@@ -1917,19 +1934,17 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred output_record_instruction_decls(llds_out_info::in,
-    map(label, data_addr)::in, instruction::in, decl_set::in, decl_set::out,
-    io::di, io::uo) is det.
+:- pred output_record_instruction_decls(llds_out_info::in, instruction::in,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_record_instruction_decls(Info, StackLayoutLabels, Instr,
-        !DeclSet, !IO) :-
+output_record_instruction_decls(Info, Instr, !DeclSet, !IO) :-
     Instr = llds_instr(Uinstr, _),
-    output_record_instr_decls(Info, StackLayoutLabels, Uinstr, !DeclSet, !IO).
+    output_record_instr_decls(Info, Uinstr, !DeclSet, !IO).
 
-:- pred output_record_instr_decls(llds_out_info::in, map(label, data_addr)::in,
-    instr::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
+:- pred output_record_instr_decls(llds_out_info::in, instr::in,
+    decl_set::in, decl_set::out, io::di, io::uo) is det.
 
-output_record_instr_decls(Info, StackLayoutLabels, Instr, !DeclSet, !IO) :-
+output_record_instr_decls(Info, Instr, !DeclSet, !IO) :-
     (
         ( Instr = comment(_)
         ; Instr = livevals(_)
@@ -1945,8 +1960,8 @@
         )
     ;
         Instr = block(_TempR, _TempF, Instrs),
-        list.foldl2(output_record_instruction_decls(Info, StackLayoutLabels),
-            Instrs, !DeclSet, !IO)
+        list.foldl2(output_record_instruction_decls(Info), Instrs,
+            !DeclSet, !IO)
     ;
         Instr = assign(Lval, Rval),
         output_record_lval_decls(Info, Lval, !DeclSet, !IO),
@@ -2060,22 +2075,7 @@
         Instr = region_set_fixed_slot(_SetOp, _EmbeddedFrame, ValueRval),
         output_record_rval_decls(Info, ValueRval, !DeclSet, !IO)
     ;
-        Instr = foreign_proc_code(_, Comps, _, _,
-            MaybeLayoutLabel, MaybeOnlyLayoutLabel, _, _, _),
-        (
-            MaybeLayoutLabel = yes(Label),
-            map.lookup(StackLayoutLabels, Label, DataAddr),
-            output_record_stack_layout_decl(Info, DataAddr, !DeclSet, !IO)
-        ;
-            MaybeLayoutLabel = no
-        ),
-        (
-            MaybeOnlyLayoutLabel = yes(OnlyLabel),
-            map.lookup(StackLayoutLabels, OnlyLabel, OnlyDataAddr),
-            output_record_stack_layout_decl(Info, OnlyDataAddr, !DeclSet, !IO)
-        ;
-            MaybeOnlyLayoutLabel = no
-        ),
+        Instr = foreign_proc_code(_, Comps, _, _, _, _, _, _, _, _),
         list.foldl2(output_record_foreign_proc_component_decls(Info), Comps,
             !DeclSet, !IO)
     ;
@@ -2718,10 +2718,25 @@
         io.write_int(N, !IO),
         io.write_string(");\n", !IO)
     ;
-        Instr = foreign_proc_code(Decls, Components, _, _, _, _, _, _, _),
+        Instr = foreign_proc_code(Decls, Components, _, _, _, _, _,
+            MaybeDefLabel, _, _),
         io.write_string("\t{\n", !IO),
         output_foreign_proc_decls(Decls, !IO),
+        (
+            MaybeDefLabel = no,
+            list.foldl(output_foreign_proc_component(Info), Components, !IO)
+        ;
+            MaybeDefLabel = yes(DefLabel),
+            InternalLabelToLayoutMap = Info ^ lout_internal_label_to_layout,
+            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,
+                DefLabelLayout, !IO),
+            io.nl(!IO),
         list.foldl(output_foreign_proc_component(Info), Components, !IO),
+            io.write_string("#undef MR_HASH_DEF_LABEL_LAYOUT\n", !IO)
+        ),
         io.write_string("\t}\n", !IO)
     ;
         Instr = init_sync_term(Lval, N),
@@ -3697,6 +3712,7 @@
 
 :- pred output_common_cell_value(llds_out_info::in, common_cell_value::in,
     io::di, io::uo) is det. 
+
 output_common_cell_value(Info, CellValue, !IO) :-
     io.write_string("{\n", !IO),
     (
@@ -4136,7 +4152,8 @@
         io.write_string(";\n", !IO)
     ;
         DataAddr = layout_addr(LayoutName),
-        output_layout_name_storage_type_name(LayoutName, no, !IO),
+        output_layout_name_storage_type_name(LayoutName,
+            not_being_defined, !IO),
         io.write_string(";\n", !IO)
     ).
 
@@ -5890,55 +5907,76 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred gather_c_file_labels(list(comp_gen_c_module)::in, list(label)::out)
-    is det.
+:- pred gather_c_file_labels(list(comp_gen_c_module)::in,
+    list(label)::out, list(label)::out) is det.
 
-gather_c_file_labels(Modules, Labels) :-
-    gather_labels_from_c_modules(Modules, [], Labels1),
-    list.reverse(Labels1, Labels).
-
-:- pred gather_c_module_labels(list(c_procedure)::in, list(label)::out) is det.
-
-gather_c_module_labels(Procs, Labels) :-
-    gather_labels_from_c_procs(Procs, [], Labels1),
-    list.reverse(Labels1, Labels).
+gather_c_file_labels(Modules, EntryLabels, InternalLabels) :-
+    gather_labels_from_c_modules_acc(Modules,
+        [], RevEntryLabels, [], RevInternalLabels),
+    list.reverse(RevEntryLabels, EntryLabels),
+    list.reverse(RevInternalLabels, InternalLabels).
+
+:- pred gather_c_module_labels(list(c_procedure)::in,
+    list(label)::out, list(label)::out) is det.
+
+gather_c_module_labels(Procs, EntryLabels, InternalLabels) :-
+    gather_labels_from_c_procs_acc(Procs,
+        [], RevEntryLabels, [], RevInternalLabels),
+    list.reverse(RevEntryLabels, EntryLabels),
+    list.reverse(RevInternalLabels, InternalLabels).
 
 %-----------------------------------------------------------------------------%
 
-:- pred gather_labels_from_c_modules(list(comp_gen_c_module)::in,
+:- pred gather_labels_from_c_modules_acc(list(comp_gen_c_module)::in,
+    list(label)::in, list(label)::out,
     list(label)::in, list(label)::out) is det.
 
-gather_labels_from_c_modules([], !Labels).
-gather_labels_from_c_modules([Module | Modules], !Labels) :-
-    gather_labels_from_c_module(Module, !Labels),
-    gather_labels_from_c_modules(Modules, !Labels).
+gather_labels_from_c_modules_acc([], !RevEntryLabels, !RevInternalLabels).
+gather_labels_from_c_modules_acc([Module | Modules],
+        !RevEntryLabels, !RevInternalLabels) :-
+    gather_labels_from_c_module_acc(Module,
+        !RevEntryLabels, !RevInternalLabels),
+    gather_labels_from_c_modules_acc(Modules,
+        !RevEntryLabels, !RevInternalLabels).
 
-:- pred gather_labels_from_c_module(comp_gen_c_module::in,
+:- pred gather_labels_from_c_module_acc(comp_gen_c_module::in,
+    list(label)::in, list(label)::out,
     list(label)::in, list(label)::out) is det.
 
-gather_labels_from_c_module(comp_gen_c_module(_, Procs), Labels0, Labels) :-
-    gather_labels_from_c_procs(Procs, Labels0, Labels).
+gather_labels_from_c_module_acc(comp_gen_c_module(_, Procs),
+        !RevEntryLabels, !RevInternalLabels) :-
+    gather_labels_from_c_procs_acc(Procs, !RevEntryLabels, !RevInternalLabels).
 
-:- pred gather_labels_from_c_procs(list(c_procedure)::in,
+:- pred gather_labels_from_c_procs_acc(list(c_procedure)::in,
+    list(label)::in, list(label)::out,
     list(label)::in, list(label)::out) is det.
 
-gather_labels_from_c_procs([], Labels, Labels).
-gather_labels_from_c_procs([Proc | Procs], !Labels) :-
+gather_labels_from_c_procs_acc([], !RevEntryLabels, !RevInternalLabels).
+gather_labels_from_c_procs_acc([Proc | Procs],
+        !RevEntryLabels, !RevInternalLabels) :-
     Instrs = Proc ^ cproc_code,
-    gather_labels_from_instrs(Instrs, !Labels),
-    gather_labels_from_c_procs(Procs, !Labels).
+    gather_labels_from_instrs_acc(Instrs, !RevEntryLabels, !RevInternalLabels),
+    gather_labels_from_c_procs_acc(Procs, !RevEntryLabels, !RevInternalLabels).
 
-:- pred gather_labels_from_instrs(list(instruction)::in,
+:- pred gather_labels_from_instrs_acc(list(instruction)::in,
+    list(label)::in, list(label)::out,
     list(label)::in, list(label)::out) is det.
 
-gather_labels_from_instrs([], !Labels).
-gather_labels_from_instrs([Instr | Instrs], !Labels) :-
+gather_labels_from_instrs_acc([], !RevEntryLabels, !RevInternalLabels).
+gather_labels_from_instrs_acc([Instr | Instrs],
+        !RevEntryLabels, !RevInternalLabels) :-
     ( Instr = llds_instr(label(Label), _) ->
-        !:Labels = [Label | !.Labels]
+        (
+            Label = entry_label(_, _),
+            !:RevEntryLabels = [Label | !.RevEntryLabels]
+        ;
+            Label = internal_label(_, _),
+            !:RevInternalLabels = [Label | !.RevInternalLabels]
+        )
     ;
         true
     ),
-    gather_labels_from_instrs(Instrs, !Labels).
+    gather_labels_from_instrs_acc(Instrs, !RevEntryLabels, !RevInternalLabels).
 
 %-----------------------------------------------------------------------------%
 
@@ -5970,7 +6008,12 @@
 
 %---------------------------------------------------------------------------%
 
-init_llds_out_info(Globals) = Info :-
+:- func init_llds_out_info(module_name, globals,
+    map(label, layout_slot_name), map(label, data_addr)) = llds_out_info.
+
+init_llds_out_info(ModuleName, Globals,
+        InternalLabelToLayoutMap, EntryLabelToLayoutMap) = Info :-
+    MangledModuleName = sym_name_mangle(ModuleName),
     globals.lookup_bool_option(Globals, auto_comments, AutoComments),
     globals.lookup_bool_option(Globals, line_numbers, LineNumbers),
     globals.lookup_bool_option(Globals, emit_c_loops, EmitCLoops),
@@ -5987,8 +6030,10 @@
     globals.lookup_bool_option(Globals, use_macro_for_redo_fail,
         UseMacroForRedoFail),
     globals.get_trace_level(Globals, TraceLevel),
-    Info = llds_out_info(AutoComments, LineNumbers, EmitCLoops,
-        GenerateBytecode, LocalThreadEngineBase,
+    Info = llds_out_info(MangledModuleName,
+        InternalLabelToLayoutMap, EntryLabelToLayoutMap,
+        AutoComments, LineNumbers,
+        EmitCLoops, GenerateBytecode, LocalThreadEngineBase,
         ProfileCalls, ProfileTime, ProfileMemory, ProfileDeep,
         UnboxedFloat, StaticGroundFloats, UseMacroForRedoFail,
         TraceLevel, Globals).
Index: compiler/llds_to_x86_64.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_to_x86_64.m,v
retrieving revision 1.11
diff -u -b -r1.11 llds_to_x86_64.m
--- compiler/llds_to_x86_64.m	11 Feb 2008 03:56:10 -0000	1.11
+++ compiler/llds_to_x86_64.m	17 Oct 2009 07:07:17 -0000
@@ -430,7 +430,7 @@
 instr_to_x86_64(!RegMap, decr_sp_and_return(NumSlots), Instrs) :-
     Instrs = [x86_64_comment("<<decr_sp_and_return>> " ++
         string.int_to_string(NumSlots))].
-instr_to_x86_64(!RegMap, foreign_proc_code(_, _, _, _, _, _, _, _, _),
+instr_to_x86_64(!RegMap, foreign_proc_code(_, _, _, _, _, _, _, _, _, _),
         Instr) :-
     Instr = [x86_64_comment("<<foreign_proc_code>>")].
 instr_to_x86_64(!RegMap, init_sync_term(_, _), Instr) :-
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.1
diff -u -b -r1.1 mercury_compile_llds_back_end.m
--- compiler/mercury_compile_llds_back_end.m	14 Oct 2009 05:28:38 -0000	1.1
+++ compiler/mercury_compile_llds_back_end.m	18 Oct 2009 15:10:38 -0000
@@ -604,10 +604,12 @@
     globals.lookup_bool_option(Globals, new_type_class_rtti, NewTypeClassRtti),
     generate_type_class_info_rtti(HLDS, NewTypeClassRtti,
         NewTypeClassInfoRttiData),
-    list.append(OldTypeClassInfoRttiData, NewTypeClassInfoRttiData,
-        TypeClassInfoRttiData),
-    stack_layout.generate_llds(HLDS, GlobalData0, GlobalData, StackLayoutDatas,
-        LayoutLabels),
+    TypeClassInfoRttiData =
+        OldTypeClassInfoRttiData ++ NewTypeClassInfoRttiData,
+    stack_layout.generate_llds_layout_data(HLDS, GlobalData0, GlobalData,
+        UserEventVarNums, UserEvents, VarLabelLayouts, NoVarLabelLayouts,
+        InternalLabelToLayoutMap, ProcLabelToLayoutMap,
+        ProcLayoutDatas, ModuleLayoutDatas, OtherLayoutDatas),
 
     % Here we perform some optimizations on the LLDS data.
     % XXX This should perhaps be part of backend_pass rather than output_pass.
@@ -621,12 +623,14 @@
 
     % Next we put it all together and output it to one or more C files.
     RttiDatas = TypeCtorRttiData ++ TypeClassInfoRttiData,
-    LayoutDatas = ClosureLayoutDatas ++ StackLayoutDatas,
-    construct_c_file(HLDS, C_InterfaceInfo, Procs, TablingInfoStructs,
-        ScalarCommonCellDatas, VectorCommonCellDatas, RttiDatas, LayoutDatas,
-        CFile, !IO),
     module_info_get_complexity_proc_infos(HLDS, ComplexityProcs),
-    output_llds_file(Globals, ModuleName, CFile, ComplexityProcs, LayoutLabels,
+    construct_c_file(HLDS, C_InterfaceInfo, Procs, TablingInfoStructs,
+        ScalarCommonCellDatas, VectorCommonCellDatas, RttiDatas,
+        UserEventVarNums, UserEvents, VarLabelLayouts, NoVarLabelLayouts,
+        InternalLabelToLayoutMap, ProcLabelToLayoutMap,
+        ProcLayoutDatas, ModuleLayoutDatas, ClosureLayoutDatas,
+        OtherLayoutDatas, ComplexityProcs, CFile, !IO),
+    output_llds_file(Globals, ModuleName, CFile,
         Verbose, Stats, !IO),
 
     C_InterfaceInfo = foreign_interface_info(_, _, _, _, C_ExportDecls, _),
@@ -697,12 +701,19 @@
 :- 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(layout_data)::in, c_file::out, io::di, io::uo)
-    is det.
+    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, LayoutDatas,
-        CFile, !IO) :-
+        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),
@@ -737,8 +748,12 @@
 
     CFile = c_file(ModuleSymName, C_HeaderCode, C_BodyCode, C_ExportDefns,
         TablingInfoStructs, ScalarCommonCellDatas, VectorCommonCellDatas,
-        RttiDatas, LayoutDatas, ChunkedModules, UserInitPredCNames,
-        UserFinalPredCNames).
+        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.
 
@@ -815,11 +830,9 @@
     combine_chunks_2(Chunks, ModuleName, Num1, Modules).
 
 :- pred output_llds_file(globals::in, module_name::in, c_file::in,
-    list(complexity_proc_info)::in, map(llds.label, llds.data_addr)::in,
     bool::in, bool::in, io::di, io::uo) is det.
 
-output_llds_file(Globals, ModuleName, LLDS0, ComplexityProcs,
-        StackLayoutLabels, Verbose, Stats, !IO) :-
+output_llds_file(Globals, ModuleName, LLDS0, Verbose, Stats, !IO) :-
     maybe_write_string(Verbose, "% Writing output to `", !IO),
     module_name_to_file_name(Globals, ModuleName, ".c", do_create_dirs,
         FileName, !IO),
@@ -827,7 +840,7 @@
     maybe_write_string(Verbose, "'...", !IO),
     maybe_flush_output(Verbose, !IO),
     transform_llds(Globals, LLDS0, LLDS),
-    output_llds(Globals, LLDS, ComplexityProcs, StackLayoutLabels, !IO),
+    output_llds(Globals, LLDS, !IO),
     maybe_write_string(Verbose, " done.\n", !IO),
     maybe_flush_output(Verbose, !IO),
     maybe_report_stats(Stats, !IO).
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/middle_rec.m,v
retrieving revision 1.138
diff -u -b -r1.138 middle_rec.m
--- compiler/middle_rec.m	11 Jun 2009 07:00:13 -0000	1.138
+++ compiler/middle_rec.m	17 Oct 2009 07:17:28 -0000
@@ -514,33 +514,38 @@
 :- pred find_used_registers_instr(instr::in,
     set(int)::in, set(int)::out) is det.
 
-find_used_registers_instr(comment(_), !Used).
-find_used_registers_instr(livevals(LvalSet), !Used) :-
+find_used_registers_instr(Uinstr, !Used) :-
+    (
+        ( Uinstr = comment(_)
+        ; Uinstr = llcall(_, _, _, _, _, _)
+        ; Uinstr = mkframe(_, _)
+        ; Uinstr = label(_)
+        ; Uinstr = goto(_)
+        ; Uinstr = arbitrary_c_code(_, _, _)
+        ; Uinstr = push_region_frame(_Id, _EmbeddedStackFrame)
+        ; Uinstr = use_and_maybe_pop_region_frame(_UseOp, _EmbeddedStackFrame)
+        ; Uinstr = discard_ticket
+        ; Uinstr = prune_ticket
+        ; Uinstr = incr_sp(_, _, _)
+        ; Uinstr = decr_sp(_)
+        ; Uinstr = decr_sp_and_return(_)
+        )
+    ;
+        Uinstr = livevals(LvalSet),
     set.to_sorted_list(LvalSet, LvalList),
-    find_used_registers_lvals(LvalList, !Used).
-find_used_registers_instr(block(_, _, Instrs), !Used) :-
-    find_used_registers(Instrs, !Used).
-find_used_registers_instr(assign(Lval, Rval), !Used) :-
-    find_used_registers_lval(Lval, !Used),
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(keep_assign(Lval, Rval), !Used) :-
+        find_used_registers_lvals(LvalList, !Used)
+    ;
+        Uinstr = block(_, _, Instrs),
+        find_used_registers(Instrs, !Used)
+    ;
+        ( Uinstr = assign(Lval, Rval)
+        ; Uinstr = keep_assign(Lval, Rval)
+        ),
     find_used_registers_lval(Lval, !Used),
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(llcall(_, _, _, _, _, _), !Used).
-find_used_registers_instr(mkframe(_, _), !Used).
-find_used_registers_instr(label(_), !Used).
-find_used_registers_instr(goto(_), !Used).
-find_used_registers_instr(computed_goto(Rval, _), !Used) :-
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(arbitrary_c_code(_, _, _), !Used).
-find_used_registers_instr(if_val(Rval, _), !Used) :-
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(save_maxfr(Lval), !Used) :-
-    find_used_registers_lval(Lval, !Used).
-find_used_registers_instr(restore_maxfr(Lval), !Used) :-
-    find_used_registers_lval(Lval, !Used).
-find_used_registers_instr(incr_hp(Lval, _, _, Rval, _, _, MaybeRegionRval,
-        MaybeReuse), !Used) :-
+        find_used_registers_rval(Rval, !Used)
+    ;
+        Uinstr = incr_hp(Lval, _, _, Rval, _, _, MaybeRegionRval,
+            MaybeReuse),
     find_used_registers_lval(Lval, !Used),
     find_used_registers_rval(Rval, !Used),
     (
@@ -560,46 +565,40 @@
         )
     ;
         MaybeReuse = no_llds_reuse
-    ).
-find_used_registers_instr(mark_hp(Lval), !Used) :-
-    find_used_registers_lval(Lval, !Used).
-find_used_registers_instr(restore_hp(Rval), !Used) :-
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(free_heap(Rval), !Used) :-
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(push_region_frame(_Id, _EmbeddedStackFrame), !Used).
-find_used_registers_instr(region_fill_frame(_FillOp, _EmbeddedStackFrame,
-        IdRval, NumLval, AddrLval), !Used) :-
+        )
+    ;
+        Uinstr = region_fill_frame(_FillOp, _EmbeddedStackFrame,
+            IdRval, NumLval, AddrLval),
     find_used_registers_rval(IdRval, !Used),
     find_used_registers_lval(NumLval, !Used),
-    find_used_registers_lval(AddrLval, !Used).
-find_used_registers_instr(region_set_fixed_slot(_SetOp, _EmbeddedStackFrame,
-        ValueRval), !Used) :-
-    find_used_registers_rval(ValueRval, !Used).
-find_used_registers_instr(use_and_maybe_pop_region_frame(_UseOp,
-    _EmbeddedStackFrame), !Used).
-find_used_registers_instr(store_ticket(Lval), !Used) :-
-    find_used_registers_lval(Lval, !Used).
-find_used_registers_instr(reset_ticket(Rval, _Rsn), !Used) :-
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(discard_ticket, !Used).
-find_used_registers_instr(prune_ticket, !Used).
-find_used_registers_instr(mark_ticket_stack(Lval), !Used) :-
-    find_used_registers_lval(Lval, !Used).
-find_used_registers_instr(prune_tickets_to(Rval), !Used) :-
-    find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(incr_sp(_, _, _), !Used).
-find_used_registers_instr(decr_sp(_), !Used).
-find_used_registers_instr(decr_sp_and_return(_), !Used).
-find_used_registers_instr(foreign_proc_code(_, Components,
-        _, _, _, _, _, _, _), !Used) :-
-    find_used_registers_components(Components, !Used).
-find_used_registers_instr(init_sync_term(Lval, _), !Used) :-
-    find_used_registers_lval(Lval, !Used).
-find_used_registers_instr(fork_new_child(Lval, _), !Used) :-
-    find_used_registers_lval(Lval, !Used).
-find_used_registers_instr(join_and_continue(Lval, _), !Used) :-
-    find_used_registers_lval(Lval, !Used).
+        find_used_registers_lval(AddrLval, !Used)
+    ;
+        Uinstr = region_set_fixed_slot(_SetOp, _EmbeddedStackFrame, ValueRval),
+        find_used_registers_rval(ValueRval, !Used)
+    ;
+        Uinstr = foreign_proc_code(_, Components, _, _, _, _, _, _, _, _),
+        find_used_registers_components(Components, !Used)
+    ;
+        ( Uinstr = computed_goto(Rval, _)
+        ; Uinstr = if_val(Rval, _)
+        ; Uinstr = restore_hp(Rval)
+        ; Uinstr = free_heap(Rval)
+        ; Uinstr = reset_ticket(Rval, _Rsn)
+        ; Uinstr = prune_tickets_to(Rval)
+        ),
+        find_used_registers_rval(Rval, !Used)
+    ;
+        ( Uinstr = save_maxfr(Lval)
+        ; Uinstr = restore_maxfr(Lval)
+        ; Uinstr = mark_hp(Lval)
+        ; Uinstr = store_ticket(Lval)
+        ; Uinstr = mark_ticket_stack(Lval)
+        ; Uinstr = init_sync_term(Lval, _)
+        ; Uinstr = fork_new_child(Lval, _)
+        ; Uinstr = join_and_continue(Lval, _)
+        ),
+        find_used_registers_lval(Lval, !Used)
+    ).
 
 :- pred find_used_registers_components(
     list(foreign_proc_component)::in,
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.211
diff -u -b -r1.211 opt_debug.m
--- compiler/opt_debug.m	14 Oct 2009 05:28:41 -0000	1.211
+++ compiler/opt_debug.m	18 Oct 2009 13:13:48 -0000
@@ -97,6 +97,10 @@
 
 :- func dump_tc_rtti_name(tc_rtti_name) = string.
 
+:- func dump_layout_slot_name(layout_slot_name) = string.
+
+:- func dump_layout_array_name(layout_array_name) = string.
+
 :- func dump_layout_name(layout_name) = string.
 
 :- func dump_unop(unary_op) = string.
@@ -493,22 +497,29 @@
     string.append_list(EncodedTCTypes, TypesStr),
     Str = "tc_instance(" ++ TypesStr ++ ")".
 
-dump_layout_name(label_layout(ProcLabel, LabelNum, LabelVars)) = Str :-
-    LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
+dump_layout_slot_name(layout_slot(Array, Slot)) = Str :-
+    ArrayStr = dump_layout_array_name(Array),
+    SlotStr = string.int_to_string(Slot),
+    Str = ArrayStr ++ "[" ++ SlotStr ++ "]".
+
+dump_layout_array_name(ArrayName) = Str :-
+    (
+        ArrayName = label_layout_array(LabelVars),
     (
         LabelVars = label_has_var_info,
-        LabelVarsStr = "label_has_var_info"
+            Str = "vars_label_layout_array"
     ;
         LabelVars = label_has_no_var_info,
-        LabelVarsStr = "label_has_no_var_info"
-    ),
-    Str = "label_layout(" ++ LabelStr ++ ", " ++ LabelVarsStr ++ ")".
-dump_layout_name(user_event_layout(ProcLabel, LabelNum)) = Str :-
-    LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
-    Str = "user_event_layout(" ++ LabelStr ++ ")".
-dump_layout_name(user_event_attr_var_nums(ProcLabel, LabelNum)) = Str :-
-    LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
-    Str = "user_event_attr_var_nums(" ++ LabelStr ++ ")".
+            Str = "no_vars_label_layout_array"
+        )
+    ;
+        ArrayName = user_event_layout_array,
+        Str = "user_event_layout_array"
+    ;
+        ArrayName = user_event_var_nums_array,
+        Str = "user_event_var_nums_array"
+    ).
+
 dump_layout_name(proc_layout(RttiProcLabel, _)) =
     "proc_layout(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
 dump_layout_name(proc_layout_exec_trace(RttiProcLabel)) =
@@ -993,7 +1004,7 @@
         Str = "join_and_continue(" ++ dump_lval(MaybeProcLabel, Lval) ++ ", "
             ++ dump_label(MaybeProcLabel, Label) ++ ")"
     ;
-        Instr = foreign_proc_code(Decls, Comps, MCM, MFNL, MFL, MFOL, MNF,
+        Instr = foreign_proc_code(Decls, Comps, MCM, MFNL, MFL, MFOL, MNF, MDL,
             SSR, MD),
         Str = "foreign_proc_code(\n"
             ++ "declarations:\n" ++ dump_decls(Decls)
@@ -1003,6 +1014,7 @@
             ++ dump_maybe_label("fix layout:", MaybeProcLabel, MFL)
             ++ dump_maybe_label("fix onlylayout:", MaybeProcLabel, MFOL)
             ++ dump_maybe_label("nofix:", MaybeProcLabel, MNF)
+            ++ dump_maybe_label("maybe def:", MaybeProcLabel, MDL)
             ++ dump_bool_msg("stack slot ref:", SSR)
             ++ dump_may_duplicate(MD) ++ "\n"
             ++ ")"
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.170
diff -u -b -r1.170 opt_util.m
--- compiler/opt_util.m	11 Feb 2008 21:26:06 -0000	1.170
+++ compiler/opt_util.m	17 Oct 2009 08:11:09 -0000
@@ -966,7 +966,7 @@
         Uinstr = prune_tickets_to(Rval),
         Refers = rval_refers_stackvars(Rval)
     ;
-        Uinstr = foreign_proc_code(_, Components, _, _, _, _, _, _, _),
+        Uinstr = foreign_proc_code(_, Components, _, _, _, _, _, _, _, _),
         Refers = bool.or_list(list.map(foreign_proc_component_refers_stackvars,
             Components))
     ).
@@ -1112,7 +1112,7 @@
 can_instr_branch_away(init_sync_term(_, _)) = no.
 can_instr_branch_away(fork_new_child(_, _)) = no.
 can_instr_branch_away(join_and_continue(_, _)) = yes.
-can_instr_branch_away(foreign_proc_code(_, Comps, _, _, _, _, _, _, _)) =
+can_instr_branch_away(foreign_proc_code(_, Comps, _, _, _, _, _, _, _, _)) =
     can_components_branch_away(Comps).
 
 :- func can_components_branch_away(list(foreign_proc_component)) = bool.
@@ -1191,7 +1191,7 @@
 can_instr_fall_through(init_sync_term(_, _)) = yes.
 can_instr_fall_through(fork_new_child(_, _)) = yes.
 can_instr_fall_through(join_and_continue(_, _)) = no.
-can_instr_fall_through(foreign_proc_code(_, _, _, _, _, _, _, _, _)) = yes.
+can_instr_fall_through(foreign_proc_code(_, _, _, _, _, _, _, _, _, _)) = yes.
 
     % Check whether an instruction sequence can possibly fall through
     % to the next instruction without using its label.
@@ -1242,17 +1242,97 @@
 can_use_livevals(init_sync_term(_, _), no).
 can_use_livevals(fork_new_child(_, _), no).
 can_use_livevals(join_and_continue(_, _), no).
-can_use_livevals(foreign_proc_code(_, _, _, _, _, _, _, _, _), no).
+can_use_livevals(foreign_proc_code(_, _, _, _, _, _, _, _, _, _), no).
 
 instr_labels(Instr, Labels, CodeAddrs) :-
     instr_labels_2(Instr, Labels0, CodeAddrs1),
     instr_rvals_and_lvals(Instr, Rvals, Lvals),
     exprn_aux.rval_list_addrs(Rvals, CodeAddrs2, _),
     exprn_aux.lval_list_addrs(Lvals, CodeAddrs3, _),
-    list.append(CodeAddrs1, CodeAddrs2, CodeAddrs12),
-    list.append(CodeAddrs12, CodeAddrs3, CodeAddrs),
+    CodeAddrs = CodeAddrs1 ++ CodeAddrs2 ++ CodeAddrs3,
     find_label_code_addrs(CodeAddrs, Labels0, Labels).
 
+    % Determine all the labels and code_addresses that are directly referenced
+    % by an instruction (not counting ones referenced indirectly via rvals or
+    % lvals).
+    %
+:- pred instr_labels_2(instr::in, list(label)::out, list(code_addr)::out)
+    is det.
+
+instr_labels_2(Uinstr, Labels, CodeAddrs) :-
+    (
+        ( Uinstr = comment(_)
+        ; Uinstr = livevals(_)
+        ; Uinstr = assign(_,_)
+        ; Uinstr = keep_assign(_,_)
+        ; Uinstr = mkframe(_, no)
+        ; Uinstr = label(_)
+        ; Uinstr = arbitrary_c_code(_, _, _)
+        ; Uinstr = save_maxfr(_)
+        ; Uinstr = restore_maxfr(_)
+        ; Uinstr = incr_hp(_, _, _, _, _, _, _, _)
+        ; Uinstr = mark_hp(_)
+        ; Uinstr = restore_hp(_)
+        ; Uinstr = free_heap(_)
+        ; Uinstr = push_region_frame(_, _)
+        ; Uinstr = region_fill_frame(_, _, _, _, _)
+        ; Uinstr = region_set_fixed_slot(_, _, _)
+        ; Uinstr = use_and_maybe_pop_region_frame(_, _)
+        ; Uinstr = store_ticket(_)
+        ; Uinstr = reset_ticket(_, _)
+        ; Uinstr = discard_ticket
+        ; Uinstr = prune_ticket
+        ; Uinstr = mark_ticket_stack(_)
+        ; Uinstr = prune_tickets_to(_)
+        ; Uinstr = incr_sp(_, _, _)
+        ; Uinstr = decr_sp(_)
+        ; Uinstr = init_sync_term(_, _)
+        ),
+        Labels = [],
+        CodeAddrs = []
+    ;
+        Uinstr = llcall(Target, Ret, _, _, _, _),
+        Labels = [],
+        CodeAddrs = [Target, Ret]
+    ;
+        ( Uinstr = mkframe(_, yes(Addr))
+        ; Uinstr = goto(Addr)
+        ; Uinstr = if_val(_, Addr)
+        ),
+        Labels = [],
+        CodeAddrs = [Addr]
+    ;
+        Uinstr = decr_sp_and_return(_),
+        % XXX decr_sp_and_return does refer to a code addr, but the code addr
+        % it refers to is the original succip (now in a stack slot), which is
+        % not necessarily the current succip. However, we introduce
+        % decr_sp_and_return so late that this predicate should never be
+        % invoked on such instructions.
+        unexpected(this_file, "instr_labels_2: decr_sp_and_return")
+    ;
+        Uinstr = fork_new_child(_, Child),
+        Labels = [Child],
+        CodeAddrs = []
+    ;
+        Uinstr = join_and_continue(_, Label),
+        Labels = [Label],
+        CodeAddrs = []
+    ;
+        Uinstr = block(_, _, Instrs),
+        instr_list_labels(Instrs, Labels, CodeAddrs)
+    ;
+        Uinstr = computed_goto(_, MaybeLabels),
+        possible_targets_maybe_labels(MaybeLabels, [], RevLabels),
+        list.reverse(RevLabels, Labels),
+        CodeAddrs = []
+    ;
+        Uinstr = foreign_proc_code(_, _, _, MaybeFixLabel, MaybeLayoutLabel,
+            MaybeOnlyLayoutLabel, MaybeSubLabel, MaybeDefLabel, _, _),
+        foreign_proc_labels(MaybeFixLabel, MaybeLayoutLabel,
+            MaybeOnlyLayoutLabel, MaybeSubLabel, MaybeDefLabel, Labels),
+        CodeAddrs = []
+    ).
+
     % Find out which code addresses are also labels.
     %
 :- pred find_label_code_addrs(list(code_addr)::in,
@@ -1267,125 +1347,81 @@
     ),
     find_label_code_addrs(Rest, Labels1, Labels).
 
-    % Determine all the labels and code_addresses that are directly referenced
-    % by an instruction (not counting ones referenced indirectly via rvals or
-    % lvals).
-    %
-:- pred instr_labels_2(instr::in, list(label)::out, list(code_addr)::out)
-    is det.
-
-instr_labels_2(comment(_), [], []).
-instr_labels_2(livevals(_), [], []).
-instr_labels_2(block(_, _, Instrs), Labels, CodeAddrs) :-
-    instr_list_labels(Instrs, Labels, CodeAddrs).
-instr_labels_2(assign(_,_), [], []).
-instr_labels_2(keep_assign(_,_), [], []).
-instr_labels_2(llcall(Target, Ret, _, _, _, _), [], [Target, Ret]).
-instr_labels_2(mkframe(_, yes(Addr)), [], [Addr]).
-instr_labels_2(mkframe(_, no), [], []).
-instr_labels_2(label(_), [], []).
-instr_labels_2(goto(Addr), [], [Addr]).
-instr_labels_2(computed_goto(_, MaybeLabels), Labels, []) :-
-    possible_targets_maybe_labels(MaybeLabels, [], RevLabels),
-    list.reverse(RevLabels, Labels).
-instr_labels_2(arbitrary_c_code(_, _, _), [], []).
-instr_labels_2(if_val(_, Addr), [], [Addr]).
-instr_labels_2(save_maxfr(_), [], []).
-instr_labels_2(restore_maxfr(_), [], []).
-instr_labels_2(incr_hp(_, _, _, _, _, _, _, _), [], []).
-instr_labels_2(mark_hp(_), [], []).
-instr_labels_2(restore_hp(_), [], []).
-instr_labels_2(free_heap(_), [], []).
-instr_labels_2(push_region_frame(_, _), [], []).
-instr_labels_2(region_fill_frame(_, _, _, _, _), [], []).
-instr_labels_2(region_set_fixed_slot(_, _, _), [], []).
-instr_labels_2(use_and_maybe_pop_region_frame(_, _), [], []).
-instr_labels_2(store_ticket(_), [], []).
-instr_labels_2(reset_ticket(_, _), [], []).
-instr_labels_2(discard_ticket, [], []).
-instr_labels_2(prune_ticket, [], []).
-instr_labels_2(mark_ticket_stack(_), [], []).
-instr_labels_2(prune_tickets_to(_), [], []).
-instr_labels_2(incr_sp(_, _, _), [], []).
-instr_labels_2(decr_sp(_), [], []).
-instr_labels_2(decr_sp_and_return(_), [], []) :-
-    % XXX decr_sp_and_return does refer to a code addr, but the code addr it
-    % refers to is the original succip (now in a stack slot), which is not
-    % necessarily the current succip. However, we introduce decr_sp_and_return
-    % so late that this predicate should never be invoked on such instructions.
-    unexpected(this_file, "instr_labels_2: decr_sp_and_return").
-instr_labels_2(init_sync_term(_, _), [], []).
-instr_labels_2(fork_new_child(_, Child), [Child], []).
-instr_labels_2(join_and_continue(_, Label), [Label], []).
-instr_labels_2(foreign_proc_code(_, _, _, MaybeFixLabel, MaybeLayoutLabel,
-        MaybeOnlyLayoutLabel, MaybeSubLabel, _, _), Labels, []) :-
-    foreign_proc_labels(MaybeFixLabel, MaybeLayoutLabel,
-        MaybeOnlyLayoutLabel, MaybeSubLabel, Labels).
-
-possible_targets(comment(_), [], []).
-possible_targets(livevals(_), [], []).
-possible_targets(block(_, _, _), _, _) :-
-    unexpected(this_file, "block in possible_targets").
-possible_targets(assign(_, _), [], []).
-possible_targets(keep_assign(_, _), [], []).
-possible_targets(llcall(_, Return, _, _, _, _), Labels, CodeAddrs) :-
+possible_targets(Uinstr, Labels, CodeAddrs) :-
+    (
+        ( Uinstr = comment(_)
+        ; Uinstr = livevals(_)
+        ; Uinstr = assign(_,_)
+        ; Uinstr = keep_assign(_,_)
+        ; Uinstr = mkframe(_, _)
+        ; Uinstr = label(_)
+        ; Uinstr = arbitrary_c_code(_, _, _)
+        ; Uinstr = save_maxfr(_)
+        ; Uinstr = restore_maxfr(_)
+        ; Uinstr = incr_hp(_, _, _, _, _, _, _, _)
+        ; Uinstr = mark_hp(_)
+        ; Uinstr = restore_hp(_)
+        ; Uinstr = free_heap(_)
+        ; Uinstr = push_region_frame(_, _)
+        ; Uinstr = region_fill_frame(_, _, _, _, _)
+        ; Uinstr = region_set_fixed_slot(_, _, _)
+        ; Uinstr = use_and_maybe_pop_region_frame(_, _)
+        ; Uinstr = store_ticket(_)
+        ; Uinstr = reset_ticket(_, _)
+        ; Uinstr = discard_ticket
+        ; Uinstr = prune_ticket
+        ; Uinstr = mark_ticket_stack(_)
+        ; Uinstr = prune_tickets_to(_)
+        ; Uinstr = incr_sp(_, _, _)
+        ; Uinstr = decr_sp(_)
+        ; Uinstr = init_sync_term(_, _)
+        ; Uinstr = fork_new_child(_, _)
+        ),
+        Labels = [],
+        CodeAddrs = []
+    ;
+        Uinstr = llcall(_, Return, _, _, _, _),
     ( Return = code_label(ReturnLabel) ->
         Labels = [ReturnLabel],
         CodeAddrs = []
     ;
         Labels = [],
         CodeAddrs = [Return]
-    ).
-possible_targets(mkframe(_, _), [], []).
-possible_targets(label(_), [], []).
-possible_targets(goto(CodeAddr), Labels, CodeAddrs) :-
+        )
+    ;
+        ( Uinstr = goto(CodeAddr)
+        ; Uinstr = if_val(_, CodeAddr)
+        ),
     ( CodeAddr = code_label(Label) ->
         Labels = [Label],
         CodeAddrs = []
     ;
         Labels = [],
         CodeAddrs = [CodeAddr]
-    ).
-possible_targets(computed_goto(_, MaybeLabels), Labels, []) :-
-    possible_targets_maybe_labels(MaybeLabels, [], RevLabels),
-    list.reverse(RevLabels, Labels).
-possible_targets(arbitrary_c_code(_, _, _), [], []).
-possible_targets(if_val(_, CodeAddr), Labels, CodeAddrs) :-
-    ( CodeAddr = code_label(Label) ->
+        )
+    ;
+        Uinstr = decr_sp_and_return(_),
+        % XXX see the comment in instr_labels_2.
+        unexpected(this_file, "possible_targets: decr_sp_and_return")
+    ;
+        Uinstr = join_and_continue(_, Label),
         Labels = [Label],
         CodeAddrs = []
     ;
-        Labels = [],
-        CodeAddrs = [CodeAddr]
+        Uinstr = block(_, _, _),
+        unexpected(this_file, "block in possible_targets")
+    ;
+        Uinstr = computed_goto(_, MaybeLabels),
+        possible_targets_maybe_labels(MaybeLabels, [], RevLabels),
+        list.reverse(RevLabels, Labels),
+        CodeAddrs = []
+    ;
+        Uinstr = foreign_proc_code(_, _, _, MaybeFixLabel, MaybeLayoutLabel,
+            MaybeOnlyLayoutLabel, MaybeSubLabel, MaybeDefLabel, _, _),
+        foreign_proc_labels(MaybeFixLabel, MaybeLayoutLabel,
+            MaybeOnlyLayoutLabel, MaybeSubLabel, MaybeDefLabel, Labels),
+        CodeAddrs = []
     ).
-possible_targets(save_maxfr(_), [], []).
-possible_targets(restore_maxfr(_), [], []).
-possible_targets(incr_hp(_, _, _, _, _, _, _, _), [], []).
-possible_targets(mark_hp(_), [], []).
-possible_targets(restore_hp(_), [], []).
-possible_targets(free_heap(_), [], []).
-possible_targets(push_region_frame(_, _), [], []).
-possible_targets(region_fill_frame(_, _, _, _, _), [], []).
-possible_targets(region_set_fixed_slot(_, _, _), [], []).
-possible_targets(use_and_maybe_pop_region_frame(_, _), [], []).
-possible_targets(store_ticket(_), [], []).
-possible_targets(reset_ticket(_, _), [], []).
-possible_targets(discard_ticket, [], []).
-possible_targets(prune_ticket, [], []).
-possible_targets(mark_ticket_stack(_), [], []).
-possible_targets(prune_tickets_to(_), [], []).
-possible_targets(incr_sp(_, _, _), [], []).
-possible_targets(decr_sp(_), [], []).
-possible_targets(decr_sp_and_return(_), [], []) :-
-    % See the comment in instr_labels_2.
-    unexpected(this_file, "possible_targets: decr_sp_and_return").
-possible_targets(init_sync_term(_, _), [], []).
-possible_targets(fork_new_child(_, _), [], []).
-possible_targets(join_and_continue(_, L), [L], []).
-possible_targets(foreign_proc_code(_, _, _, MaybeFixedLabel, MaybeLayoutLabel,
-        _, MaybeSubLabel, _, _), Labels, []) :-
-    foreign_proc_labels(MaybeFixedLabel, MaybeLayoutLabel,
-        no, MaybeSubLabel, Labels).
 
 :- pred possible_targets_maybe_labels(list(maybe(label))::in,
     list(label)::in, list(label)::out) is det.
@@ -1401,10 +1437,11 @@
     possible_targets_maybe_labels(MaybeLabels, !RevLabels).
 
 :- pred foreign_proc_labels(maybe(label)::in, maybe(label)::in,
-    maybe(label)::in, maybe(label)::in, list(label)::out) is det.
+    maybe(label)::in, maybe(label)::in, maybe(label)::in, list(label)::out)
+    is det.
 
 foreign_proc_labels(MaybeFixedLabel, MaybeLayoutLabel,
-        MaybeOnlyLayoutLabel, MaybeSubLabel, !:Labels) :-
+        MaybeOnlyLayoutLabel, MaybeSubLabel, MaybeDefLabel, !:Labels) :-
     !:Labels = [],
     (
         MaybeFixedLabel = yes(FixedLabel),
@@ -1429,6 +1466,12 @@
         !:Labels = [SubLabel | !.Labels]
     ;
         MaybeSubLabel = no
+    ),
+    (
+        MaybeDefLabel = yes(DefLabel),
+        !:Labels = [DefLabel | !.Labels]
+    ;
+        MaybeDefLabel = no
     ).
 
     % Determine all the rvals and lvals referenced by an instruction.
@@ -1502,7 +1545,7 @@
 instr_rvals_and_lvals(init_sync_term(Lval, _), [], [Lval]).
 instr_rvals_and_lvals(fork_new_child(Lval, _), [], [Lval]).
 instr_rvals_and_lvals(join_and_continue(Lval, _), [], [Lval]).
-instr_rvals_and_lvals(foreign_proc_code(_, Cs, _, _, _, _, _, _, _),
+instr_rvals_and_lvals(foreign_proc_code(_, Cs, _, _, _, _, _, _, _, _),
         Rvals, Lvals) :-
     foreign_proc_components_get_rvals_and_lvals(Cs, Rvals, Lvals).
 
@@ -1683,7 +1726,8 @@
     count_temps_lval(Lval, !R, !F).
 count_temps_instr(join_and_continue(Lval, _), !R, !F) :-
     count_temps_lval(Lval, !R, !F).
-count_temps_instr(foreign_proc_code(_, Comps, _, _, _, _, _, _, _), !R, !F) :-
+count_temps_instr(foreign_proc_code(_, Comps, _, _, _, _, _, _, _, _),
+        !R, !F) :-
     count_temps_components(Comps, !R, !F).
 
 :- pred count_temps_components(list(foreign_proc_component)::in,
@@ -1969,7 +2013,7 @@
         Uinstr = prune_tickets_to(Rval),
         Touch = touches_nondet_ctrl_rval(Rval)
     ;
-        Uinstr = foreign_proc_code(_, Components, _, _, _, _, _, _, _),
+        Uinstr = foreign_proc_code(_, Components, _, _, _, _, _, _, _, _),
         Touch = touches_nondet_ctrl_components(Components)
     ).
 
@@ -2458,8 +2502,9 @@
         replace_labels_lval(Lval0, Lval, ReplMap),
         Uinstr = join_and_continue(Lval, Label)
     ;
-        Uinstr0 = foreign_proc_code(A, Comps0, C, MaybeFix, MaybeLayout,
-            MaybeOnlyLayout, MaybeSub0, H, I),
+        Uinstr0 = foreign_proc_code(Decls, Comps0, MayCallMercury,
+            MaybeFix, MaybeLayout, MaybeOnlyLayout, MaybeSub0, MaybeDef,
+            StackSlotRef, MayDupl),
         (
             MaybeFix = no
         ;
@@ -2497,8 +2542,18 @@
             MaybeSub = yes(SubLabel),
             replace_labels_comps(Comps0, Comps, ReplMap)
         ),
-        Uinstr = foreign_proc_code(A, Comps, C, MaybeFix, MaybeLayout,
-            MaybeOnlyLayout, MaybeSub, H, I)
+        (
+            MaybeDef = no
+        ;
+            MaybeDef = yes(DefLabel0),
+            replace_labels_label(DefLabel0, DefLabel, ReplMap),
+            % We cannot replace a label that has a layout structure.
+            expect(unify(DefLabel0, DefLabel), this_file,
+                "trying to replace Mercury label with layout")
+        ),
+        Uinstr = foreign_proc_code(Decls, Comps, MayCallMercury,
+            MaybeFix, MaybeLayout, MaybeOnlyLayout, MaybeSub, MaybeDef,
+            StackSlotRef, MayDupl)
     ).
 
 replace_labels_comps([], [], _).
Index: compiler/pragma_c_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pragma_c_gen.m,v
retrieving revision 1.114
diff -u -b -r1.114 pragma_c_gen.m
--- compiler/pragma_c_gen.m	4 Sep 2009 02:27:54 -0000	1.114
+++ compiler/pragma_c_gen.m	17 Oct 2009 07:25:09 -0000
@@ -662,7 +662,7 @@
     ),
     PragmaCCode = singleton(
         llds_instr(foreign_proc_code(Decls, Components, MayCallMercury,
-            no, no, no, MaybeFailLabel, RefersToLLDSSTack, MayDupl),
+            no, no, no, MaybeFailLabel, no, RefersToLLDSSTack, MayDupl),
             "foreign_proc inclusion")
     ),
 
@@ -948,7 +948,7 @@
         ],
         CallBlockCode = singleton(
             llds_instr(foreign_proc_code(CallDecls, CallComponents,
-                MayCallMercury, no, no, no, no, yes, MD),
+                MayCallMercury, no, no, no, no, no, yes, MD),
                 "Call and shared foreign_proc inclusion")
         ),
 
@@ -999,7 +999,7 @@
         ],
         RetryBlockCode = singleton(
             llds_instr(foreign_proc_code(RetryDecls, RetryComponents,
-                MayCallMercury, no, no, no, no, yes, MD),
+                MayCallMercury, no, no, no, no, no, yes, MD),
                 "Retry and shared foreign_proc inclusion")
         ),
 
@@ -1078,7 +1078,7 @@
         ],
         CallBlockCode = singleton(
             llds_instr(foreign_proc_code(CallDecls, CallComponents,
-                MayCallMercury, yes(SharedLabel), no, no, no, yes, MD),
+                MayCallMercury, yes(SharedLabel), no, no, no, no, yes, MD),
                 "Call foreign_proc inclusion")
         ),
 
@@ -1131,7 +1131,7 @@
         ],
         RetryBlockCode = singleton(
             llds_instr(foreign_proc_code(RetryDecls, RetryComponents,
-                MayCallMercury, yes(SharedLabel), no, no, no, yes, MD),
+                MayCallMercury, yes(SharedLabel), no, no, no, no, yes, MD),
                 "Retry foreign_proc inclusion")
         ),
 
@@ -1185,7 +1185,7 @@
         ],
         SharedBlockCode = singleton(
             llds_instr(foreign_proc_code(SharedDecls, SharedComponents,
-                MayCallMercury, no, no, no, no, yes, MD),
+                MayCallMercury, no, no, no, no, no, yes, MD),
                 "Shared foreign_proc inclusion")
         ),
 
Index: compiler/proc_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_gen.m,v
retrieving revision 1.33
diff -u -b -r1.33 proc_gen.m
--- compiler/proc_gen.m	19 Aug 2009 07:44:57 -0000	1.33
+++ compiler/proc_gen.m	17 Oct 2009 07:33:37 -0000
@@ -911,7 +911,8 @@
                 llds_instr(mkframe(NondetFrameInfo, yes(OutsideResumeAddress)),
                     "Allocate stack frame"),
                 llds_instr(foreign_proc_code([], DefineComponents,
-                    proc_will_not_call_mercury, no, no, no, no, no, MD), "")
+                    proc_will_not_call_mercury, no, no, no, no, no, no, MD),
+                    "")
             ]),
             NondetPragma = yes
         ;
@@ -1004,7 +1005,7 @@
         MD = proc_may_not_duplicate,
         UndefCode = singleton(
             llds_instr(foreign_proc_code([], UndefComponents,
-                proc_will_not_call_mercury, no, no, no, no, no, MD), "")
+                proc_will_not_call_mercury, no, no, no, no, no, no, MD), "")
         ),
         RestoreDeallocCode = empty, % always empty for nondet code
         ExitCode = StartComment ++ UndefCode ++ EndComment
@@ -1170,7 +1171,7 @@
                 SuccessCode = from_list([
                     llds_instr(livevals(LiveLvals), ""),
                     llds_instr(foreign_proc_code([], [Component],
-                        proc_may_call_mercury, no, no, no, no, no, MD), "")
+                        proc_may_call_mercury, no, no, no, no, no, no, MD), "")
                 ])
             ;
                 MaybeSpecialReturn = no,
@@ -1278,7 +1279,7 @@
     BytecodeInstructions = [
         llds_instr(label(EntryLabel), "Procedure entry point"),
         llds_instr(foreign_proc_code([], BytecodeInstructionsComponents,
-            proc_may_call_mercury, no, no, no, no, no, MD), "Entry stub")
+            proc_may_call_mercury, no, no, no, no, no, no, MD), "Entry stub")
     ].
 
 %---------------------------------------------------------------------------%
Index: compiler/reassign.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/reassign.m,v
retrieving revision 1.29
diff -u -b -r1.29 reassign.m
--- compiler/reassign.m	21 Sep 2009 04:08:58 -0000	1.29
+++ compiler/reassign.m	17 Oct 2009 07:19:28 -0000
@@ -301,7 +301,7 @@
         !:KnownContentsMap = map.init,
         !:DepLvalMap = map.init
     ;
-        Uinstr0 = foreign_proc_code(_, _, _, _, _, _, _, _, _),
+        Uinstr0 = foreign_proc_code(_, _, _, _, _, _, _, _, _, _),
         !:RevInstrs = [Instr0 | !.RevInstrs],
         % The C code may clobber any lval.
         !:KnownContentsMap = map.init,
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.148
diff -u -b -r1.148 stack_layout.m
--- compiler/stack_layout.m	14 Oct 2009 05:28:43 -0000	1.148
+++ compiler/stack_layout.m	18 Oct 2009 15:14:26 -0000
@@ -42,14 +42,20 @@
 :- import_module assoc_list.
 :- import_module list.
 :- import_module map.
+:- import_module maybe.
 
 %---------------------------------------------------------------------------%
 
     % Process all the continuation information stored in the HLDS,
     % converting it into LLDS data structures.
     %
-:- pred generate_llds(module_info::in, global_data::in, global_data::out,
-    list(layout_data)::out, map(label, data_addr)::out) is det.
+:- pred generate_llds_layout_data(module_info::in,
+    global_data::in, global_data::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.
 
 :- pred construct_closure_layout(proc_label::in, int::in,
     closure_layout_info::in, proc_label::in, module_name::in,
@@ -101,10 +107,10 @@
 :- import_module parse_tree.prog_event.
 
 :- import_module bool.
+:- import_module cord.
 :- import_module counter.
 :- import_module int.
 :- import_module map.
-:- import_module maybe.
 :- import_module pair.
 :- import_module set.
 :- import_module string.
@@ -114,7 +120,10 @@
 
 %---------------------------------------------------------------------------%
 
-generate_llds(ModuleInfo, !GlobalData, Layouts, LayoutLabels) :-
+generate_llds_layout_data(ModuleInfo, !GlobalData,
+        UserEventVarNums, UserEvents, VarLabelLayouts, NoVarLabelLayouts,
+        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),
@@ -132,16 +141,23 @@
     ),
     globals.get_trace_level(Globals, TraceLevel),
     globals.get_trace_suppress(Globals, TraceSuppress),
-    map.init(LayoutLabels0),
 
     map.init(StringMap0),
     map.init(LabelTables0),
     StringTable0 = string_table(StringMap0, [], 0),
     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, [], [], [], LayoutLabels0, [],
+        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>", _,
@@ -151,10 +167,26 @@
     LabelsCounter = LayoutInfo ^ sli_label_counter,
     counter.allocate(NumLabels, LabelsCounter, _),
     TableIoDecls = LayoutInfo ^ sli_table_infos,
-    ProcLayouts = LayoutInfo ^ sli_proc_layouts,
-    InternalLayouts = LayoutInfo ^ sli_internal_layouts,
-    LayoutLabels = LayoutInfo ^ sli_label_set,
-    ProcLayoutNames = LayoutInfo ^ sli_proc_layout_name_list,
+    OtherLayouts = TableIoDecls,
+
+    RevProcLayouts = LayoutInfo ^ sli_rev_proc_layouts,
+    RevProcLayoutNames = LayoutInfo ^ sli_rev_proc_layout_names,
+    list.reverse(RevProcLayouts, ProcLayouts),
+    list.reverse(RevProcLayoutNames, ProcLayoutNames),
+
+    UserEventVarNumsCord = LayoutInfo ^ sli_user_event_var_nums,
+    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),
+    list.reverse(RevNoVarLabelLayouts, NoVarLabelLayouts),
+
+    InternalLabelToLayoutMap = LayoutInfo ^ sli_i_label_to_layout_map,
+    ProcLabelToLayoutMap = LayoutInfo ^ sli_p_label_to_layout_map,
+
     StringTable = LayoutInfo ^ sli_string_table,
     LabelTables = LayoutInfo ^ sli_label_tables,
     StaticCellInfo1 = LayoutInfo ^ sli_static_cell_info,
@@ -162,7 +194,6 @@
     list.reverse(RevStringList, StringList),
     ConcatStrings = string_with_0s(StringList),
 
-    Layouts0 = TableIoDecls ++ ProcLayouts ++ InternalLayouts,
     (
         TraceLayout = yes,
         module_info_get_name(ModuleInfo, ModuleName),
@@ -199,19 +230,19 @@
         ModuleLayout = module_layout_data(ModuleName,
             ModuleCommonLayoutName, ProcLayoutNames, SourceFileLayouts,
             TraceLevel, SuppressedEvents, NumLabels, MaybeEventSet),
-        Layouts = [ModuleCommonLayout, ModuleLayout | Layouts0]
+        ModuleLayouts = [ModuleCommonLayout, ModuleLayout]
     ;
         TraceLayout = no,
         DeepProfiling = yes,
         module_info_get_name(ModuleInfo, ModuleName),
         ModuleCommonLayout = module_layout_common_data(ModuleName,
             StringOffset, ConcatStrings),
-        Layouts = [ModuleCommonLayout | Layouts0],
+        ModuleLayouts = [ModuleCommonLayout],
         StaticCellInfo = StaticCellInfo1
     ;
         TraceLayout = no,
         DeepProfiling = no,
-        Layouts = Layouts0,
+        ModuleLayouts = [],
         StaticCellInfo = StaticCellInfo1
     ),
     global_data_set_static_cell_info(StaticCellInfo, !GlobalData).
@@ -256,18 +287,17 @@
 
 %---------------------------------------------------------------------------%
 
-:- pred format_label_tables(map(string, label_table)::in,
+:- pred format_label_tables(map(string, file_label_table)::in,
     list(file_layout_data)::out) is det.
 
 format_label_tables(LabelTableMap, SourceFileLayouts) :-
     map.to_assoc_list(LabelTableMap, LabelTableList),
     list.map(format_label_table, LabelTableList, SourceFileLayouts).
 
-:- pred format_label_table(pair(string, label_table)::in,
+:- pred format_label_table(pair(string, file_label_table)::in,
     file_layout_data::out) is det.
 
-format_label_table(FileName - LineNoMap,
-        file_layout_data(FileName, FilteredList)) :-
+format_label_table(FileName - LineNoMap, FileLayoutData) :-
     % This step should produce a list ordered on line numbers.
     map.to_assoc_list(LineNoMap, LineNoList),
     % And this step should preserve that order.
@@ -276,7 +306,8 @@
         LineNoInfo = LineNo - (Label - _IsReturn),
         FilteredLineNoInfo = LineNo - Label
     ),
-    list.map(Filter, FlatLineNoList, FilteredList).
+    list.map(Filter, FlatLineNoList, FilteredList),
+    FileLayoutData = file_layout_data(FileName, FilteredList).
 
 :- pred flatten_label_table(assoc_list(int, list(line_no_info))::in,
     assoc_list(int, line_no_info)::in,
@@ -369,17 +400,19 @@
                 containing_proc         :: proc_label,
                 label_num_in_proc       :: int,
                 maybe_has_var_info      :: label_vars,
+                slot_in_array           :: int,
                 internal_layout_info    :: internal_layout_info
             ).
 
     % Add the given label layout to the module-wide label tables.
     %
 :- pred update_label_table(internal_label_info::in,
-    map(string, label_table)::in, map(string, label_table)::out) is det.
+    map(string, file_label_table)::in, map(string, file_label_table)::out)
+    is det.
 
 update_label_table(InternalLabelInfo, !LabelTables) :-
-    InternalLabelInfo = internal_label_info(ProcLabel, LabelNum, LabelVars,
-        InternalInfo),
+    InternalLabelInfo = internal_label_info(_ProcLabel, _LabelNum, LabelVars,
+        Slot, InternalInfo),
     InternalInfo = internal_layout_info(Port, _, Return),
     (
         Return = yes(return_layout_info(TargetsContexts, _)),
@@ -390,28 +423,27 @@
         ;
             IsReturn = unknown_callee
         ),
-        update_label_table_2(ProcLabel, LabelNum, LabelVars, Context,
-            IsReturn, !LabelTables)
+        update_label_table_2(LabelVars, Slot, Context, IsReturn, !LabelTables)
     ;
         Port = yes(trace_port_layout_info(Context, _, _, _, _, _)),
         context_is_valid(Context)
     ->
-        update_label_table_2(ProcLabel, LabelNum, LabelVars, Context,
-            not_a_return, !LabelTables)
+        update_label_table_2(LabelVars, Slot, Context, not_a_return,
+            !LabelTables)
     ;
         true
     ).
 
-:- pred update_label_table_2(proc_label::in, int::in,
-    label_vars::in, context::in, is_label_return::in,
-    map(string, label_table)::in, map(string, label_table)::out) is det.
+:- pred update_label_table_2(label_vars::in, int::in, context::in,
+    is_label_return::in,
+    map(string, file_label_table)::in, map(string, file_label_table)::out)
+    is det.
 
-update_label_table_2(ProcLabel, LabelNum, LabelVars, Context,
-        IsReturn, !LabelTables) :-
+update_label_table_2(LabelVars, Slot, Context, IsReturn, !LabelTables) :-
     term.context_file(Context, File),
     term.context_line(Context, Line),
     ( map.search(!.LabelTables, File, LabelTable0) ->
-        LabelLayout = label_layout(ProcLabel, LabelNum, LabelVars),
+        LabelLayout = layout_slot(label_layout_array(LabelVars), Slot),
         ( map.search(LabelTable0, Line, LineInfo0) ->
             LineInfo = [LabelLayout - IsReturn | LineInfo0],
             map.det_update(LabelTable0, Line, LineInfo, LabelTable),
@@ -421,9 +453,10 @@
             map.det_insert(LabelTable0, Line, LineInfo, LabelTable),
             svmap.det_update(File, LabelTable, !LabelTables)
         )
-    ; context_is_valid(Context) ->
+    ;
+        ( context_is_valid(Context) ->
         map.init(LabelTable0),
-        LabelLayout = label_layout(ProcLabel, LabelNum, LabelVars),
+            LabelLayout = layout_slot(label_layout_array(LabelVars), Slot),
         LineInfo = [LabelLayout - IsReturn],
         map.det_insert(LabelTable0, Line, LineInfo, LabelTable),
         svmap.det_insert(File, LabelTable, !LabelTables)
@@ -431,6 +464,7 @@
         % We don't have a valid context for this label,
         % so we don't enter it into any tables.
         true
+        )
     ).
 
 :- pred find_valid_return_context(
@@ -615,7 +649,7 @@
     ),
     ProcLayout = proc_layout_data(RttiProcLabel, Traversal, More),
     LayoutName = proc_layout(RttiProcLabel, Kind),
-    add_proc_layout_data(ProcLayout, LayoutName, EntryLabel, !Info),
+    add_proc_layout_data(EntryLabel, LayoutName, ProcLayout, !Info),
     (
         MaybeTableInfo = no
     ;
@@ -640,10 +674,9 @@
         _VarSet, VarTypes, MaybeTableInfo, NeedsAllNames, VarNumMap,
         InternalLabelInfos, ExecTrace, !Info) :-
     collect_event_data_addrs(InternalLabelInfos,
-        [], RevInterfaceEventDataAddrs, [], RevInternalEventDataAddrs),
-    list.reverse(RevInterfaceEventDataAddrs, InterfaceEventDataAddrs),
-    list.reverse(RevInternalEventDataAddrs, InternalEventDataAddrs),
-    EventDataAddrs = InterfaceEventDataAddrs ++ InternalEventDataAddrs,
+        [], RevInterfaceEventLayoutNames, [], RevInternalEventLayoutNames),
+    list.reverse(RevInterfaceEventLayoutNames, InterfaceEventLayoutNames),
+    list.reverse(RevInternalEventLayoutNames, InternalEventLayoutNames),
     construct_var_name_vector(VarNumMap,
         NeedsAllNames, MaxVarNum, VarNameVector, !Info),
     list.map(convert_var_to_int(VarNumMap), HeadVars, HeadVarNumVector),
@@ -652,20 +685,12 @@
     ModuleInfo = !.Info ^ sli_module_info,
     (
         MaybeCallLabel = yes(CallLabel),
-        % The label associated with an event must have variable info.
-        (
-            CallLabel = internal_label(CallLabelNum, CallProcLabel)
-        ;
-            CallLabel = entry_label(_, _),
-            unexpected(this_file,
-                "construct_trace_layout: entry call label")
-        ),
-        CallLabelDetails = label_layout_details(CallProcLabel, CallLabelNum,
-            label_has_var_info),
-        MaybeCallLabelDetails = yes(CallLabelDetails)
+        map.lookup(!.Info ^ sli_i_label_to_layout_map, CallLabel,
+            CallLabelSlotName),
+        MaybeCallLabelSlotName = yes(CallLabelSlotName)
     ;
         MaybeCallLabel = no,
-        MaybeCallLabelDetails = no
+        MaybeCallLabelSlotName = no
     ),
     (
         MaybeTableInfo = no,
@@ -685,19 +710,21 @@
     ),
     encode_exec_trace_flags(ModuleInfo, HeadVars, ArgModes, VarTypes,
         0, Flags),
-    ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails,
-        EventDataAddrs, MaybeTableDataAddr, HeadVarNumVector, VarNameVector,
+    ExecTrace = proc_layout_exec_trace(MaybeCallLabelSlotName,
+        InterfaceEventLayoutNames, InternalEventLayoutNames,
+        MaybeTableDataAddr, HeadVarNumVector, VarNameVector,
         MaxVarNum, MaxTraceReg, MaybeFromFullSlot, MaybeIoSeqSlot,
         MaybeTrailSlots, MaybeMaxfrSlot, EvalMethod,
         MaybeCallTableSlot, MaybeTailRecSlot, EffTraceLevel, Flags).
 
 :- pred collect_event_data_addrs(list(internal_label_info)::in,
-    list(data_addr)::in, list(data_addr)::out,
-    list(data_addr)::in, list(data_addr)::out) is det.
+    list(layout_slot_name)::in, list(layout_slot_name)::out,
+    list(layout_slot_name)::in, list(layout_slot_name)::out) is det.
 
 collect_event_data_addrs([], !RevInterfaces, !RevInternals).
 collect_event_data_addrs([Info | Infos], !RevInterfaces, !RevInternals) :-
-    Info = internal_label_info(ProcLabel, LabelNum, LabelVars, InternalInfo),
+    Info = internal_label_info(_ProcLabel, _LabelNum, LabelVars, Slot,
+        InternalInfo),
     InternalInfo = internal_layout_info(MaybePortInfo, _, _),
     (
         MaybePortInfo = no
@@ -711,9 +738,8 @@
             ; Port = port_fail
             ; Port = port_tailrec_call
             ),
-            LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
-            DataAddr = layout_addr(LayoutName),
-            !:RevInterfaces = [DataAddr | !.RevInterfaces]
+            LayoutName = layout_slot(label_layout_array(LabelVars), Slot),
+            !:RevInterfaces = [LayoutName | !.RevInterfaces]
         ;
             ( Port = port_ite_cond
             ; Port = port_ite_then
@@ -728,9 +754,8 @@
             ; Port = port_nondet_foreign_proc_later
             ; Port = port_user
             ),
-            LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
-            DataAddr = layout_addr(LayoutName),
-            !:RevInternals = [DataAddr | !.RevInternals]
+            LayoutName = layout_slot(label_layout_array(LabelVars), Slot),
+            !:RevInternals = [LayoutName | !.RevInternals]
         ;
             Port = port_exception
             % This port is attached to call sites, so there is no event here.
@@ -1025,23 +1050,44 @@
     ),
     (
         MaybeUserInfo = no,
-        MaybeUserData = 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, UserAttrVarNums, !Info),
+            UserLocnsArray, UserAttrMaybeVarNums, !Info),
 
         get_layout_static_cell_info(!.Info, StaticCellInfo0),
         add_scalar_static_cell(UserLocnsArray, UserLocnsDataAddr,
             StaticCellInfo0, StaticCellInfo),
         set_layout_static_cell_info(StaticCellInfo, !Info),
-
         UserLocnsRval = const(llconst_data_addr(UserLocnsDataAddr, no)),
+
+        list.length(UserAttrMaybeVarNums, NumVarNums),
+        VarNumSlotNum0 = !.Info ^ sli_next_user_event_var_num,
+        VarNumSlotNum = VarNumSlotNum0 + NumVarNums,
+        !Info ^ sli_next_user_event_var_num := VarNumSlotNum,
+        UserAttrVarNumsSlot = layout_slot(user_event_var_nums_array,
+            VarNumSlotNum0),
+
+        VarNums0 = !.Info ^ sli_user_event_var_nums,
+        VarNums = VarNums0 ++ cord.from_list(UserAttrMaybeVarNums),
+        !Info ^ sli_user_event_var_nums := VarNums,
+
+        UserEventCounter0 = !.Info ^ sli_next_user_event,
+        counter.allocate(UserEventSlotNum,
+            UserEventCounter0, UserEventCounter),
+        !Info ^ sli_next_user_event := UserEventCounter,
+        UserEventSlot = layout_slot(user_event_layout_array, UserEventSlotNum),
+
         UserData = user_event_data(UserEventNumber, UserLocnsRval,
-            UserAttrVarNums),
-        MaybeUserData = yes(UserData)
+            UserAttrVarNumsSlot),
+        UserEvents0 = !.Info ^ sli_user_events,
+        UserEvents = UserEvents0 ++ cord.singleton(UserData),
+        !Info ^ sli_user_events := UserEvents,
+
+        MaybeUserDataSlot = yes(UserEventSlot)
     ),
 
     (
@@ -1059,13 +1105,20 @@
         Trace = no,
         LabelNumber = 0
     ),
-    LayoutData = label_layout_data(ProcLabel, LabelNum, ProcLayoutName,
-        MaybePort, MaybeIsHidden, LabelNumber, MaybeGoalPath, MaybeUserData,
-        MaybeVarInfo),
-    LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
     Label = internal_label(LabelNum, ProcLabel),
-    add_internal_layout_data(LayoutData, Label, LayoutName, !Info),
-    LabelLayout = internal_label_info(ProcLabel, LabelNum, LabelVars,
+    BasicLayout = basic_label_layout(ProcLabel, LabelNum, ProcLayoutName,
+        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,
+        NoVarsLayout = label_layout_no_vars(BasicLayout),
+        add_no_vars_internal_layout_data(Label, NoVarsLayout, Slot, !Info)
+    ),
+    LabelLayout = internal_label_info(ProcLabel, LabelNum, LabelVars, Slot,
         Internal).
 
 :- pred construct_user_data_array(var_num_map::in,
@@ -1806,8 +1859,9 @@
     const(llconst_int(code_model.represent_determinism(Detism)))).
 
 %---------------------------------------------------------------------------%
-
-    % Access to the stack_layout data structure.
+%
+% 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
@@ -1819,9 +1873,9 @@
     ;       unknown_callee
     ;       not_a_return.
 
-:- type line_no_info == pair(layout_name, is_label_return).
+:- type line_no_info == pair(layout_slot_name, is_label_return).
 
-:- type label_table == map(int, list(line_no_info)).
+:- type file_label_table == map(int, list(line_no_info)).
 
 :- type stack_layout_info
     --->    stack_layout_info(
@@ -1842,20 +1896,36 @@
                 sli_unboxed_floats          :: have_unboxed_floats,
                 sli_label_counter           :: counter,
                 sli_table_infos             :: list(layout_data),
-                sli_proc_layouts            :: list(layout_data),
-                sli_internal_layouts        :: list(layout_data),
-
-                % The set of labels (both entry and internal) with layouts.
-                sli_label_set               :: map(label, data_addr),
 
                 % The list of proc_layouts in the module.
-                sli_proc_layout_name_list   :: list(layout_name),
+                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)),
+
+                % 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),
+
+                % 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),
+
+                % This maps each proc 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, label_table),
+                sli_label_tables            :: map(string, file_label_table),
 
                 sli_static_cell_info        :: static_cell_info,
                 sli_has_user_event          :: bool
@@ -1869,15 +1939,19 @@
 :- 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_proc_layout_data(stack_layout_info::in, list(layout_data)::out)
-    is det.
-:- pred get_internal_layout_data(stack_layout_info::in, list(layout_data)::out)
-    is det.
-:- pred get_label_set(stack_layout_info::in, map(label, data_addr)::out)
+:- 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, label_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.
@@ -1889,9 +1963,11 @@
 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_proc_layout_data(LI, LI ^ sli_proc_layouts).
-get_internal_layout_data(LI, LI ^ sli_internal_layouts).
-get_label_set(LI, LI ^ sli_label_set).
+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).
@@ -1918,36 +1994,64 @@
         MaybeTableIoDeclData = no
     ).
 
-:- pred add_proc_layout_data(layout_data::in, layout_name::in, label::in,
+:- pred add_proc_layout_data(label::in, layout_name::in, layout_data::in,
     stack_layout_info::in, stack_layout_info::out) is det.
 
-add_proc_layout_data(ProcLayout, ProcLayoutName, Label, !LI) :-
-    ProcLayouts0 = !.LI ^ sli_proc_layouts,
-    ProcLayouts = [ProcLayout | ProcLayouts0],
-    LabelSet0 = !.LI ^ sli_label_set,
-    map.det_insert(LabelSet0, Label, layout_addr(ProcLayoutName), LabelSet),
-    ProcLayoutNames0 = !.LI ^ sli_proc_layout_name_list,
-    ProcLayoutNames = [ProcLayoutName | ProcLayoutNames0],
-    !LI ^ sli_proc_layouts := ProcLayouts,
-    !LI ^ sli_label_set := LabelSet,
-    !LI ^ sli_proc_layout_name_list := ProcLayoutNames.
-
-:- pred add_internal_layout_data(layout_data::in,
-    label::in, layout_name::in, stack_layout_info::in,
-    stack_layout_info::out) is det.
-
-add_internal_layout_data(InternalLayout, Label, LayoutName, !LI) :-
-    InternalLayouts0 = !.LI ^ sli_internal_layouts,
-    InternalLayouts = [InternalLayout | InternalLayouts0],
-    LabelSet0 = !.LI ^ sli_label_set,
-    map.det_insert(LabelSet0, Label, layout_addr(LayoutName), LabelSet),
-    !LI ^ sli_internal_layouts := InternalLayouts,
-    !LI ^ sli_label_set := LabelSet.
+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],
+
+    LabelToLayoutMap0 = !.LI ^ sli_p_label_to_layout_map,
+    map.det_insert(LabelToLayoutMap0, Label, layout_addr(ProcLayoutName),
+        LabelToLayoutMap),
+
+    !LI ^ sli_rev_proc_layouts := RevProcLayouts,
+    !LI ^ sli_rev_proc_layout_names := RevProcLayoutNames,
+    !LI ^ sli_p_label_to_layout_map := LabelToLayoutMap.
+
+:- pred add_vars_internal_layout_data(label::in, label_layout_vars::in,
+    int::out, stack_layout_info::in, stack_layout_info::out) is det.
+
+add_vars_internal_layout_data(Label, Layout, Slot, !LI) :-
+    RevLayouts0 = !.LI ^ sli_rev_var_label_layouts,
+    RevLayouts = [Layout | RevLayouts0],
+
+    Counter0 = !.LI ^ sli_next_var_label_layout,
+    counter.allocate(Slot, Counter0, Counter),
+    LayoutName = layout_slot(label_layout_array(label_has_var_info), Slot),
+
+    LabelToLayoutMap0 = !.LI ^ sli_i_label_to_layout_map,
+    map.det_insert(LabelToLayoutMap0, Label, LayoutName, LabelToLayoutMap),
+
+    !LI ^ sli_rev_var_label_layouts := RevLayouts,
+    !LI ^ sli_next_var_label_layout := Counter,
+    !LI ^ sli_i_label_to_layout_map := LabelToLayoutMap.
+
+:- 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.
+
+add_no_vars_internal_layout_data(Label, Layout, Slot, !LI) :-
+    RevLayouts0 = !.LI ^ sli_rev_no_var_label_layouts,
+    RevLayouts = [Layout | RevLayouts0],
+
+    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),
+
+    LabelToLayoutMap0 = !.LI ^ sli_i_label_to_layout_map,
+    map.det_insert(LabelToLayoutMap0, Label, LayoutName, LabelToLayoutMap),
+
+    !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, label_table)::in,
+:- 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,
@@ -1967,7 +2071,7 @@
 
 %---------------------------------------------------------------------------%
 %
-% Access to the string_table data structure
+% Access to the string_table data structure.
 %
 
 :- type string_table
Index: compiler/trace_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trace_gen.m,v
retrieving revision 1.28
diff -u -b -r1.28 trace_gen.m
--- compiler/trace_gen.m	6 Jan 2009 03:56:27 -0000	1.28
+++ compiler/trace_gen.m	18 Oct 2009 15:50:50 -0000
@@ -629,14 +629,14 @@
             MaybeRedoLabel = yes(RedoLayoutLabel),
             redo_layout_slot(CodeModel, RedoLayoutLval),
             stackref_to_string(RedoLayoutLval, RedoLayoutStr),
-            LayoutAddrStr =
-                layout_out.make_label_layout_name(RedoLayoutLabel),
             !:CodeStr = !.CodeStr ++ "\t\t" ++ RedoLayoutStr ++
-                " = (MR_Word) (const MR_Word *) &" ++ LayoutAddrStr ++ ";\n",
-            MaybeLayoutLabel = yes(RedoLayoutLabel)
+                " = (MR_Word) (const MR_Word *) MR_HASH_DEF_LABEL_LAYOUT;\n",
+            MaybeLayoutLabel = yes(RedoLayoutLabel),
+            MaybeHashDefLabel = yes(RedoLayoutLabel)
         ;
             MaybeRedoLabel = no,
-            MaybeLayoutLabel = no
+            MaybeLayoutLabel = no,
+            MaybeHashDefLabel = no
         ),
         % Stage 3 is handled later.
         % Stage 4.
@@ -663,7 +663,7 @@
         ;
             MaybeTrailLvals = no
         ),
-        % Stage 3.
+        % Stage 3 (delayed).
         (
             MaybeFromFullSlot = yes(CallFromFullSlot),
             stackref_to_string(CallFromFullSlot, CallFromFullSlotStr),
@@ -684,7 +684,7 @@
     TraceCode1 = singleton(
         llds_instr(foreign_proc_code([], TraceComponents1,
             proc_will_not_call_mercury, no, no, MaybeLayoutLabel,
-            no, yes, proc_may_not_duplicate), "")
+            no, MaybeHashDefLabel, yes, proc_may_not_duplicate), "")
     ),
     % Stage 6.
     (
@@ -713,8 +713,8 @@
             TraceStmt3)],
         TraceCode3 = singleton(
             llds_instr(foreign_proc_code([], TraceComponents3,
-                proc_will_not_call_mercury, no, no, no, no, yes,
-                proc_may_not_duplicate),
+                proc_will_not_call_mercury, no, no, no, no, no,
+                yes, proc_may_not_duplicate),
                 "initialize tail recursion count")
         )
     ;
@@ -731,8 +731,8 @@
             TraceStmt4)],
         TraceCode4 = singleton(
             llds_instr(foreign_proc_code([], TraceComponents4,
-                proc_will_not_call_mercury, no, no, no, no, yes,
-                proc_may_not_duplicate), "")
+                proc_will_not_call_mercury, no, no, no, no, no,
+                yes, proc_may_not_duplicate), "")
         )
     ;
         MaybeCallTableLval = no,
@@ -1016,8 +1016,8 @@
         ForeignLangCodeStr)],
     ForeignLangCode = singleton(
         llds_instr(foreign_proc_code([], ForeignLangComponents,
-            proc_will_not_call_mercury, no, no, no,
-            no, yes, proc_may_duplicate), "")
+            proc_will_not_call_mercury, no, no, no, no, no,
+            yes, proc_may_duplicate), "")
     ),
     Code = ForeignLangCode ++ MaxfrCode ++ TailRecLvalCode.
 
@@ -1108,13 +1108,12 @@
 
     set.list_to_set(VarInfoList, VarInfoSet),
     LayoutLabelInfo = layout_label_info(VarInfoSet, TvarDataMap),
-    LabelStr = llds_out.label_to_c_string(Label, no),
     (
         MaybeUserInfo = no,
-        TraceStmt0 = "\t\tMR_EVENT(" ++ LabelStr ++ ")\n"
+        TraceStmt0 = "\t\tMR_EVENT_SYS\n"
     ;
         MaybeUserInfo = yes(_),
-        TraceStmt0 = "\t\tMR_USER_EVENT(" ++ LabelStr ++ ")\n"
+        TraceStmt0 = "\t\tMR_EVENT_USER\n"
     ),
     TraceStmt = "\t\t/* port " ++ trace_port_to_string(Port) ++ ", " ++
         "path <" ++ goal_path_to_string(Path) ++ "> */\n" ++
@@ -1155,8 +1154,8 @@
                 % pair is preceded by another label, and this way we can
                 % eliminate this other label.
             llds_instr(foreign_proc_code([], TraceComponents,
-                proc_may_call_mercury, no, no, yes(Label), no, yes,
-                proc_may_not_duplicate), "")
+                proc_may_call_mercury, no, no, yes(Label), no, yes(Label),
+                yes, proc_may_not_duplicate), "")
         ]),
     Code = ProduceCode ++ TailRecResetCode ++ TraceCode.
 
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.39
diff -u -b -r1.39 use_local_vars.m
--- compiler/use_local_vars.m	3 Sep 2008 03:32:19 -0000	1.39
+++ compiler/use_local_vars.m	17 Oct 2009 07:20:37 -0000
@@ -184,7 +184,7 @@
             MaybeMore = no
         ;
             Uinstr0 = foreign_proc_code(_D, Comps, _MCM, _FNL, _FL, _FOL, _NF,
-                _S, _MD),
+                _MDL, _S, _MD),
             opt_assign_find_output_in_components(Comps, NumRealRRegs,
                 !.AvoidLvals, ToLval),
             MaybeMore = yes
@@ -477,23 +477,29 @@
 
 substitute_lval_in_defn(OldLval, NewLval, Instr0, Instr) :-
     Instr0 = llds_instr(Uinstr0, Comment),
-    ( Uinstr0 = assign(ToLval, FromRval) ->
+    (
+        Uinstr0 = assign(ToLval, FromRval)
+    ->
         expect(unify(ToLval, OldLval),
             this_file, "substitute_lval_in_defn: mismatch in assign"),
         Uinstr = assign(NewLval, FromRval)
-    ; Uinstr0 = incr_hp(ToLval, MaybeTag, SizeRval, MO, Type,
-            MayUseAtomic, MaybeRegionRval, MaybeReuse) ->
+    ;
+        Uinstr0 = incr_hp(ToLval, MaybeTag, SizeRval, MO, Type,
+            MayUseAtomic, MaybeRegionRval, MaybeReuse)
+    ->
         expect(unify(ToLval, OldLval),
             this_file, "substitute_lval_in_defn: mismatch in incr_hp"),
         Uinstr = incr_hp(NewLval, MaybeTag, SizeRval, MO, Type,
             MayUseAtomic, MaybeRegionRval, MaybeReuse)
-    ; Uinstr0 = foreign_proc_code(D, Comps0, MCM, FNL, FL, FOL, NF, S, MD) ->
+    ;
+        Uinstr0 = foreign_proc_code(D, Comps0, MCM, FNL, FL, FOL, NF, MDL,
+            S, MD)
+    ->
         substitute_lval_in_defn_components(OldLval, NewLval, Comps0, Comps,
             0, NumSubsts),
-        expect(unify(NumSubsts, 1),
-            this_file,
+        expect(unify(NumSubsts, 1), this_file,
             "substitute_lval_in_defn: mismatch in foreign_proc_code"),
-        Uinstr = foreign_proc_code(D, Comps, MCM, FNL, FL, FOL, NF, S, MD)
+        Uinstr = foreign_proc_code(D, Comps, MCM, FNL, FL, FOL, NF, MDL, S, MD)
     ;
         unexpected(this_file,
             "substitute_lval_in_defn: unexpected instruction")
@@ -639,7 +645,7 @@
         exprn_aux.substitute_lval_in_instr(OldLval, NewLval, !Instr, !N),
         substitute_lval_in_instr_until_defn(OldLval, NewLval, !Instrs, !N)
     ;
-        Uinstr0 = foreign_proc_code(_, Components, _, _, _, _, _, _, _),
+        Uinstr0 = foreign_proc_code(_, Components, _, _, _, _, _, _, _, _),
         AffectsLiveness = components_affect_liveness(Components),
         (
             AffectsLiveness = no,
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
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
Index: mdbcomp/rtti_access.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/rtti_access.m,v
retrieving revision 1.13
diff -u -b -r1.13 rtti_access.m
--- mdbcomp/rtti_access.m	14 Sep 2009 05:58:22 -0000	1.13
+++ mdbcomp/rtti_access.m	18 Oct 2009 15:25:47 -0000
@@ -381,7 +381,7 @@
                         ** for the numerical suffix.
                         */
                         start_of_num == out_base_name_len &&
-                        strneq(out_name, in_name, start_of_num)
+                        MR_strneq(out_name, in_name, start_of_num)
                     )
                 ||
                     (
@@ -393,7 +393,7 @@
                         start_of_num == out_base_name_len + 1 &&
                         start_of_num > 0 &&
                         in_name[start_of_num - 1] == '_' &&
-                        strneq(out_name, in_name, start_of_num - 1)
+                        MR_strneq(out_name, in_name, start_of_num - 1)
                     )
                 ))
             {
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.50
diff -u -b -r1.50 mercury_goto.h
--- runtime/mercury_goto.h	12 Jun 2007 06:06:33 -0000	1.50
+++ runtime/mercury_goto.h	18 Oct 2009 18:36:57 -0000
@@ -16,6 +16,8 @@
 #include "mercury_label.h"	/* for MR_insert_{entry,internal}_label() */
 #include "mercury_dummy.h"	/* for MR_dummy_identify_function() */
 
+/*---------------------------------------------------------------------------*/
+
 /*
 ** Definitions for constructing the names of entry and internal labels,
 ** and the names of their layout structures.
@@ -80,6 +82,8 @@
 	MR_PASTE2(mercury_data__label_layout__,				\
 		MR_label_uci_name(mod, name, type, a, mode, num))
 
+/*---------------------------------------------------------------------------*/
+
 #define MR_PROC_LAYOUT_NAME(label)					\
 	MR_PASTE2(mercury_data__proc_layout__,label)
 #define MR_LABEL_LAYOUT_NAME(label)					\
@@ -224,6 +228,8 @@
 	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8)) 	\
 	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln9))
 
+/*---------------------------------------------------------------------------*/
+
 /*
 ** Passing the name of a label to MR_insert_{internal,entry}_label
 ** causes that name to be included in the executable as static readonly data.
@@ -242,6 +248,8 @@
   #define MR_insert_entry(n, a, l)	MR_insert_entry_label(NULL, a, l)
 #endif
 
+/*---------------------------------------------------------------------------*/
+
 /*
 ** Taking the address of a label can inhibit gcc's optimization, because it
 ** assumes that anything can jump there. Therefore we want to do it only if
@@ -258,23 +266,21 @@
 */
 
 #define MR_make_label_ai(n, a, l)		MR_insert_internal(n, a, NULL)
-#define MR_make_label_an(n, a, l)		MR_insert_internal_label(n, \
-							a, NULL)
-#define MR_make_label_sl(n, a, l)		MR_insert_internal(n, a, \
-							MR_LABEL_LAYOUT(l))
+#define MR_make_label_an(n, a, l)	MR_insert_internal_label(n, a, NULL)
+#define MR_make_label_sl(n, a, l)	MR_insert_internal(n, a, l)
 
 #define MR_make_local_ai(n, a, l)		MR_insert_entry(n, a, NULL)
-#define MR_make_local_an(n, a, l)		MR_do_insert_entry_label(n, \
-							a, NULL)
+#define MR_make_local_an(n, a, l)	MR_do_insert_entry_label(n, a, NULL)
 #define MR_make_local_sl(n, a, l)		MR_insert_entry(n, a, \
 							MR_PROC_LAYOUT(l))
 
 #define MR_make_entry_ai(n, a, l)		MR_insert_entry(n, a, NULL)
-#define MR_make_entry_an(n, a, l)		MR_do_insert_entry_label(n, \
-							a, NULL)
+#define MR_make_entry_an(n, a, l)	MR_do_insert_entry_label(n, a, NULL)
 #define MR_make_entry_sl(n, a, l)		MR_insert_entry(n, a, \
 							MR_PROC_LAYOUT(l))
 
+/*---------------------------------------------------------------------------*/
+
 #if defined(MR_INSERT_LABELS)
   #define MR_make_label(n, a, l)		MR_make_label_ai(n, a, l)
 #else
@@ -295,6 +301,7 @@
 ** to the MLDS back-end too, you may also need to change the
 ** `need_to_init_entries' predicate in compiler/mlds_to_c.m.
 */
+
 #if defined(MR_INSERT_LABELS) || defined(MR_MPROF_PROFILE_CALLS)
   #define MR_make_entry(n, a, l)		MR_make_entry_ai(n, a, l)
 #else
@@ -458,6 +465,7 @@
     ** better... for the moment, we just fall through, since
     ** that keeps the code smaller.
     */
+
     #if 0
       #define MR_ASM_FALLTHROUGH(label) \
   	goto MR_skip(label);
@@ -520,6 +528,7 @@
     ** better... for the moment, we just fall through, since
     ** that keeps the code smaller.
     */
+
     #if 0
       #define MR_ASM_FALLTHROUGH(label) \
   	goto MR_skip(label);
@@ -600,6 +609,8 @@
 
 #endif
 
+/*---------------------------------------------------------------------------*/
+
 /* for other architectures, these macros have default definitions */
 
 /*
@@ -683,6 +694,7 @@
 ** MR_ASM_ENTRY is used to declare an external entry point
 ** using a (global) assembler label.
 */
+
 #define MR_ASM_ENTRY(label) 				\
 	MR_ASM_FALLTHROUGH(label)			\
   	MR_entry(label):				\
@@ -702,6 +714,7 @@
 ** C file, their address may be taken and so there may be indirect
 ** calls.
 */
+
 #define MR_ASM_STATIC_ENTRY(label) 			\
 	MR_ASM_FALLTHROUGH(label)			\
   	MR_entry(label):				\
@@ -727,6 +740,7 @@
 ** to identical code, but for which we have different information
 ** stored in the stack layout structs, etc.
 */
+
 #define MR_ASM_LOCAL_ENTRY(label) 			\
 	MR_ASM_FALLTHROUGH(label)			\
   	MR_entry(label):				\
@@ -943,16 +957,31 @@
   	MR_make_local_an(MR_STRINGIFY(label), &&MR_entry(label), label)
   #define MR_init_local_sl(label)	\
   	MR_make_local_sl(MR_STRINGIFY(label), &&MR_entry(label), label)
+
   #define MR_define_label(label)	MR_define_local(label)
   #define MR_declare_label(label)	/* no declaration required */
+
   #define MR_init_label(label)	\
-	MR_make_label(MR_STRINGIFY(label), &&MR_entry(label), label)
+	MR_make_label(MR_STRINGIFY(label), &&MR_entry(label),		\
+		MR_LABEL_LAYOUT(label))
   #define MR_init_label_ai(label)	\
-	MR_make_label_ai(MR_STRINGIFY(label), &&MR_entry(label), label)
+	MR_make_label_ai(MR_STRINGIFY(label), &&MR_entry(label),	\
+		MR_LABEL_LAYOUT(label))
   #define MR_init_label_an(label)	\
-	MR_make_label_an(MR_STRINGIFY(label), &&MR_entry(label), label)
+	MR_make_label_an(MR_STRINGIFY(label), &&MR_entry(label),	\
+		MR_LABEL_LAYOUT(label))
   #define MR_init_label_sl(label)	\
-	MR_make_label_sl(MR_STRINGIFY(label), &&MR_entry(label), label)
+	MR_make_label_sl(MR_STRINGIFY(label), &&MR_entry(label),	\
+		MR_LABEL_LAYOUT(label))
+
+  #define MR_init_label_ml(label, layout)				\
+	MR_make_label(MR_STRINGIFY(label), &&MR_entry(label), layout)
+  #define MR_init_label_ml_ai(label, layout)				\
+	MR_make_label_ai(MR_STRINGIFY(label), &&MR_entry(label), layout)
+  #define MR_init_label_ml_an(label, layout)				\
+	MR_make_label_an(MR_STRINGIFY(label), &&MR_entry(label), layout)
+  #define MR_init_label_ml_sl(label, layout)				\
+	MR_make_label_sl(MR_STRINGIFY(label), &&MR_entry(label), layout)
 
   #define MR_LOCAL(label)	(&&MR_entry(label))
   #define MR_LABEL(label)	(&&MR_entry(label))
@@ -979,8 +1008,8 @@
   typedef MR_Code * MR_ModuleFunc(void);
 
   #define MR_BEGIN_MODULE(module_name)	\
-	MR_MODULE_STATIC_OR_EXTERN MR_Code* module_name(void); \
-	MR_MODULE_STATIC_OR_EXTERN MR_Code* module_name(void) {
+	MR_MODULE_STATIC_OR_EXTERN MR_Code * module_name(void);		\
+	MR_MODULE_STATIC_OR_EXTERN MR_Code * module_name(void) {
   #define MR_BEGIN_CODE			return 0;
   #define MR_END_MODULE			}
 
@@ -995,14 +1024,15 @@
 		MR_GOTO_LABEL(label);		\
 	}					\
 	static MR_Code* label(void) {
-  #define MR_init_entry(label)		MR_make_entry(MR_STRINGIFY(label),    \
-		  				label, label)
-  #define MR_init_entry_ai(label)	MR_make_entry_ai(MR_STRINGIFY(label), \
-		  				label, label)
-  #define MR_init_entry_an(label)	MR_make_entry_an(MR_STRINGIFY(label), \
-		  				label, label)
-  #define MR_init_entry_sl(label)	MR_make_entry_sl(MR_STRINGIFY(label), \
-		  				label, label)
+
+  #define MR_init_entry(label)						\
+	MR_make_entry(MR_STRINGIFY(label), label, label)
+  #define MR_init_entry_ai(label)					\
+	MR_make_entry_ai(MR_STRINGIFY(label), label, label)
+  #define MR_init_entry_an(label)					\
+	MR_make_entry_an(MR_STRINGIFY(label), label, label)
+  #define MR_init_entry_sl(label)					\
+	MR_make_entry_sl(MR_STRINGIFY(label), label, label)
 
   #define MR_declare_local(label)	static MR_Code *label(void)
   #define MR_define_local(label)	\
@@ -1010,14 +1040,14 @@
 	}				\
 	static MR_Code* label(void) {
 
-  #define MR_init_local(label)		MR_make_local(MR_STRINGIFY(label),    \
-		  				label, label)
-  #define MR_init_local_ai(label)	MR_make_local_ai(MR_STRINGIFY(label), \
-		  				label, label)
-  #define MR_init_local_an(label)	MR_make_local_an(MR_STRINGIFY(label), \
-		  				label, label)
-  #define MR_init_local_sl(label)	MR_make_local_sl(MR_STRINGIFY(label), \
-		  				label, label)
+  #define MR_init_local(label)						\
+	MR_make_local(MR_STRINGIFY(label),    label, label)
+  #define MR_init_local_ai(label)					\
+	MR_make_local_ai(MR_STRINGIFY(label), label, label)
+  #define MR_init_local_an(label)					\
+	MR_make_local_an(MR_STRINGIFY(label), label, label)
+  #define MR_init_local_sl(label)					\
+	MR_make_local_sl(MR_STRINGIFY(label), label, label)
 
   #define MR_declare_label(label)	static MR_Code *label(void)
   #define MR_define_label(label)	\
@@ -1025,14 +1055,23 @@
 	}				\
 	static MR_Code* label(void) {
 
-  #define MR_init_label(label)		MR_make_label(MR_STRINGIFY(label),    \
-		  				label, label)
-  #define MR_init_label_ai(label)	MR_make_label_ai(MR_STRINGIFY(label), \
-		  				label, label)
-  #define MR_init_label_an(label)	MR_make_label_an(MR_STRINGIFY(label), \
-		  				label, label)
-  #define MR_init_label_sl(label)	MR_make_label_sl(MR_STRINGIFY(label), \
-		  				label, label)
+  #define MR_init_label(label)						\
+	MR_make_label(MR_STRINGIFY(label),    label, MR_LABEL_LAYOUT(label))
+  #define MR_init_label_ai(label)					\
+	MR_make_label_ai(MR_STRINGIFY(label), label, MR_LABEL_LAYOUT(label))
+  #define MR_init_label_an(label)					\
+	MR_make_label_an(MR_STRINGIFY(label), label, MR_LABEL_LAYOUT(label))
+  #define MR_init_label_sl(label)					\
+	MR_make_label_sl(MR_STRINGIFY(label), label, MR_LABEL_LAYOUT(label))
+
+  #define MR_init_label_ml(label, layout)				\
+	MR_make_label(MR_STRINGIFY(label),    label, layout)
+  #define MR_init_label_ml_ai(label, layout)				\
+	MR_make_label_ai(MR_STRINGIFY(label), label, layout)
+  #define MR_init_label_ml_an(label, layout)				\
+	MR_make_label_an(MR_STRINGIFY(label), label, layout)
+  #define MR_init_label_ml_sl(label, layout)				\
+	MR_make_label_sl(MR_STRINGIFY(label), label, layout)
 
   #define MR_ENTRY(label) 	((MR_Code *) (label))
   #define MR_LOCAL(label)	((MR_Code *) (label))
@@ -1048,6 +1087,8 @@
 
 #endif /* !defined(MR_USE_GCC_NONLOCAL_GOTOS) */
 
+/*---------------------------------------------------------------------------*/
+
 #define MR_ENTRY_AP(label) 		MR_ENTRY(MR_add_prefix(label))
 #define MR_LOCAL_AP(label)		MR_LOCAL(MR_add_prefix(label))
 #define MR_LABEL_AP(label)		MR_LABEL(MR_add_prefix(label))
@@ -1080,6 +1121,8 @@
 #define	MR_def_uci_static(mod, name, type, arity, mode) \
 	MR_define_static(MR_proc_entry_uci_name(mod, name, type, arity, mode))
 
+/*---------------------------------------------------------------------------*/
+
 #if defined(MR_INSERT_LABELS) || defined(MR_MPROF_PROFILE_CALLS)
   #define MR_need_insert_entry(ai)		1
 #else
@@ -1209,164 +1252,486 @@
 #define	MR_init_local1_sl(e)						\
 	MR_init_local_sl(MR_add_prefix(e));
 
-#define	MR_init_label1(e, ln1)						\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));
-
-#define	MR_init_label2(e, ln1, ln2)					\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln2));
-
-#define	MR_init_label3(e, ln1, ln2, ln3)				\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln3));
-
-#define	MR_init_label4(e, ln1, ln2, ln3, ln4)				\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln4));
-
-#define	MR_init_label5(e, ln1, ln2, ln3, ln4, ln5)			\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln5));
-
-#define	MR_init_label6(e, ln1, ln2, ln3, ln4, ln5, ln6)			\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln6));
-
-#define	MR_init_label7(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7)		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln7));
-
-#define	MR_init_label8(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8)	\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln7));		\
-	MR_init_label(MR_label_name(MR_add_prefix(e), ln8));
-
 #define	MR_init_label1_sl(e)						\
 	MR_init_label_sl(MR_add_prefix(e));
 
-#define	MR_init_label_sl1(e, ln1)					\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));
+/*---------------------------------------------------------------------------*/
+
+#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));
+
+#define	MR_init_label2(e, l1, l2)					\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)
+
+#define	MR_init_label3(e, l1, l2, l3)					\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)
+
+#define	MR_init_label4(e, l1, l2, l3, l4)				\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)						\
+	MR_init_label1(e, l4)
+
+#define	MR_init_label5(e, l1, l2, l3, l4, l5)				\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)						\
+	MR_init_label1(e, l4)						\
+	MR_init_label1(e, l5)
+
+#define	MR_init_label6(e, l1, l2, l3, l4, l5, l6)			\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)						\
+	MR_init_label1(e, l4)						\
+	MR_init_label1(e, l5)						\
+	MR_init_label1(e, l6)
+
+#define	MR_init_label7(e, l1, l2, l3, l4, l5, l6, l7)			\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)						\
+	MR_init_label1(e, l4)						\
+	MR_init_label1(e, l5)						\
+	MR_init_label1(e, l6)						\
+	MR_init_label1(e, l7)
+
+#define	MR_init_label8(e, l1, l2, l3, l4, l5, l6, l7, l8)		\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)						\
+	MR_init_label1(e, l4)						\
+	MR_init_label1(e, l5)						\
+	MR_init_label1(e, l6)						\
+	MR_init_label1(e, l7)						\
+	MR_init_label1(e, l8)
+
+#define	MR_init_label9(e, l1, l2, l3, l4, l5, l6, l7, l8, l9)		\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)						\
+	MR_init_label1(e, l4)						\
+	MR_init_label1(e, l5)						\
+	MR_init_label1(e, l6)						\
+	MR_init_label1(e, l7)						\
+	MR_init_label1(e, l8)						\
+	MR_init_label1(e, l9)
+
+#define	MR_init_label10(e, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10)	\
+	MR_init_label1(e, l1)						\
+	MR_init_label1(e, l2)						\
+	MR_init_label1(e, l3)						\
+	MR_init_label1(e, l4)						\
+	MR_init_label1(e, l5)						\
+	MR_init_label1(e, l6)						\
+	MR_init_label1(e, l7)						\
+	MR_init_label1(e, l8)						\
+	MR_init_label1(e, l9)						\
+	MR_init_label1(e, l10)
+
+/*---------------------------------------------------------------------------*/
+
+#define	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl(MR_label_name(MR_add_prefix(e), l1));
+
+#define	MR_init_label_sl2(e, l1, l2)					\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)
+
+#define	MR_init_label_sl3(e, l1, l2, l3)				\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)
+
+#define	MR_init_label_sl4(e, l1, l2, l3, l4)				\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)					\
+	MR_init_label_sl1(e, l4)
+
+#define	MR_init_label_sl5(e, l1, l2, l3, l4, l5)			\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)					\
+	MR_init_label_sl1(e, l4)					\
+	MR_init_label_sl1(e, l5)
+
+#define	MR_init_label_sl6(e, l1, l2, l3, l4, l5, l6)			\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)					\
+	MR_init_label_sl1(e, l4)					\
+	MR_init_label_sl1(e, l5)					\
+	MR_init_label_sl1(e, l6)
+
+#define	MR_init_label_sl7(e, l1, l2, l3, l4, l5, l6, l7)		\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)					\
+	MR_init_label_sl1(e, l4)					\
+	MR_init_label_sl1(e, l5)					\
+	MR_init_label_sl1(e, l6)					\
+	MR_init_label_sl1(e, l7)
+
+#define	MR_init_label_sl8(e, l1, l2, l3, l4, l5, l6, l7, l8)		\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)					\
+	MR_init_label_sl1(e, l4)					\
+	MR_init_label_sl1(e, l5)					\
+	MR_init_label_sl1(e, l6)					\
+	MR_init_label_sl1(e, l7)					\
+	MR_init_label_sl1(e, l8)
+
+#define	MR_init_label_sl9(e, l1, l2, l3, l4, l5, l6, l7, l8, l9)	\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)					\
+	MR_init_label_sl1(e, l4)					\
+	MR_init_label_sl1(e, l5)					\
+	MR_init_label_sl1(e, l6)					\
+	MR_init_label_sl1(e, l7)					\
+	MR_init_label_sl1(e, l8)					\
+	MR_init_label_sl1(e, l9)
+
+#define	MR_init_label_sl10(e, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10)	\
+	MR_init_label_sl1(e, l1)					\
+	MR_init_label_sl1(e, l2)					\
+	MR_init_label_sl1(e, l3)					\
+	MR_init_label_sl1(e, l4)					\
+	MR_init_label_sl1(e, l5)					\
+	MR_init_label_sl1(e, l6)					\
+	MR_init_label_sl1(e, l7)					\
+	MR_init_label_sl1(e, l8)					\
+	MR_init_label_sl1(e, l9)					\
+	MR_init_label_sl1(e, l10)
+
+/*---------------------------------------------------------------------------*/
 
-#define	MR_init_label_sl2(e, ln1, ln2)					\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));
-
-#define	MR_init_label_sl3(e, ln1, ln2, ln3)				\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));
-
-#define	MR_init_label_sl4(e, ln1, ln2, ln3, ln4)			\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));
-
-#define	MR_init_label_sl5(e, ln1, ln2, ln3, ln4, ln5)			\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));
-
-#define	MR_init_label_sl6(e, ln1, ln2, ln3, ln4, ln5, ln6)		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln6));
-
-#define	MR_init_label_sl7(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7)		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln7));
-
-#define	MR_init_label_sl8(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8)	\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln7));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln8));
-
-#define	MR_init_label_sl1(e, ln1)					\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));
-
-#define	MR_init_label_sl2(e, ln1, ln2)					\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));
-
-#define	MR_init_label_sl3(e, ln1, ln2, ln3)				\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));
-
-#define	MR_init_label_sl4(e, ln1, ln2, ln3, ln4)			\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));
-
-#define	MR_init_label_sl5(e, ln1, ln2, ln3, ln4, ln5)			\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));
-
-#define	MR_init_label_sl6(e, ln1, ln2, ln3, ln4, ln5, ln6)		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln6));
-
-#define	MR_init_label_sl7(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7)		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln7));
-
-#define	MR_init_label_sl8(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8)	\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln7));		\
-	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln8));
+#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]);
+
+#define	MR_init_label_nvi2(e, m, l1,s1, l2,s2)				\
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)
+
+#define	MR_init_label_nvi3(e, m, l1,s1, l2,s2, l3,s3)			\
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)
+
+#define	MR_init_label_nvi4(e, m, l1,s1, l2,s2, l3,s3, l4,s4)		\
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)				\
+	MR_init_label_nvi1(e, m, l4, s4)
+
+#define	MR_init_label_nvi5(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5)	\
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)				\
+	MR_init_label_nvi1(e, m, l4, s4)				\
+	MR_init_label_nvi1(e, m, l5, s5)
+
+#define	MR_init_label_nvi6(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6) \
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)				\
+	MR_init_label_nvi1(e, m, l4, s4)				\
+	MR_init_label_nvi1(e, m, l5, s5)				\
+	MR_init_label_nvi1(e, m, l6, s6)
+
+#define	MR_init_label_nvi7(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7) \
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)				\
+	MR_init_label_nvi1(e, m, l4, s4)				\
+	MR_init_label_nvi1(e, m, l5, s5)				\
+	MR_init_label_nvi1(e, m, l6, s6)				\
+	MR_init_label_nvi1(e, m, l7, s7)
+
+#define	MR_init_label_nvi8(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8) \
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)				\
+	MR_init_label_nvi1(e, m, l4, s4)				\
+	MR_init_label_nvi1(e, m, l5, s5)				\
+	MR_init_label_nvi1(e, m, l6, s6)				\
+	MR_init_label_nvi1(e, m, l7, s7)				\
+	MR_init_label_nvi1(e, m, l8, s8)
+
+#define	MR_init_label_nvi9(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9) \
+	MR_init_label_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)				\
+	MR_init_label_nvi1(e, m, l4, s4)				\
+	MR_init_label_nvi1(e, m, l5, s5)				\
+	MR_init_label_nvi1(e, m, l6, s6)				\
+	MR_init_label_nvi1(e, m, l7, s7)				\
+	MR_init_label_nvi1(e, m, l8, s8)				\
+	MR_init_label_nvi1(e, m, l9, s9)
+
+#define	MR_init_label_nvi10(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_nvi1(e, m, l1, s1)				\
+	MR_init_label_nvi1(e, m, l2, s2)				\
+	MR_init_label_nvi1(e, m, l3, s3)				\
+	MR_init_label_nvi1(e, m, l4, s4)				\
+	MR_init_label_nvi1(e, m, l5, s5)				\
+	MR_init_label_nvi1(e, m, l6, s6)				\
+	MR_init_label_nvi1(e, m, l7, s7)				\
+	MR_init_label_nvi1(e, m, l8, s8)				\
+	MR_init_label_nvi1(e, m, l9, s9)				\
+	MR_init_label_nvi1(e, m, l10, s10)
+
+/*---------------------------------------------------------------------------*/
 
 #define	MR_decl_extern_entry(e)						\
 	MR_declare_extern_entry(MR_add_prefix(e));
@@ -1380,57 +1745,82 @@
 #define	MR_decl_local(e)						\
 	MR_declare_local(MR_add_prefix(e));
 
-#define	MR_decl_label1(e, ln1)						\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));
+#define	MR_decl_label1(e, l1)						\
+	MR_declare_label(MR_label_name(MR_add_prefix(e), l1));
 
-#define	MR_decl_label2(e, ln1, ln2)					\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln2));
-
-#define	MR_decl_label3(e, ln1, ln2, ln3)				\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln3));
-
-#define	MR_decl_label4(e, ln1, ln2, ln3, ln4)				\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln4));
-
-#define	MR_decl_label5(e, ln1, ln2, ln3, ln4, ln5)			\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln5));
-
-#define	MR_decl_label6(e, ln1, ln2, ln3, ln4, ln5, ln6)			\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln6));
-
-#define	MR_decl_label7(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7)		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln7));
-
-#define	MR_decl_label8(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8)	\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln1));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln2));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln3));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln4));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln5));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln6));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln7));		\
-	MR_declare_label(MR_label_name(MR_add_prefix(e), ln8));
+#define	MR_decl_label2(e, l1, l2)					\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)
+
+#define	MR_decl_label3(e, l1, l2, l3)					\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)
+
+#define	MR_decl_label4(e, l1, l2, l3, l4)				\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)						\
+	MR_decl_label1(e, l4)
+
+#define	MR_decl_label5(e, l1, l2, l3, l4, l5)				\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)						\
+	MR_decl_label1(e, l4)						\
+	MR_decl_label1(e, l5)
+
+#define	MR_decl_label6(e, l1, l2, l3, l4, l5, l6)			\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)						\
+	MR_decl_label1(e, l4)						\
+	MR_decl_label1(e, l5)						\
+	MR_decl_label1(e, l6)
+
+#define	MR_decl_label7(e, l1, l2, l3, l4, l5, l6, l7)			\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)						\
+	MR_decl_label1(e, l4)						\
+	MR_decl_label1(e, l5)						\
+	MR_decl_label1(e, l6)						\
+	MR_decl_label1(e, l7)
+
+#define	MR_decl_label8(e, l1, l2, l3, l4, l5, l6, l7, l8)		\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)						\
+	MR_decl_label1(e, l4)						\
+	MR_decl_label1(e, l5)						\
+	MR_decl_label1(e, l6)						\
+	MR_decl_label1(e, l7)						\
+	MR_decl_label1(e, l8)
+
+#define	MR_decl_label9(e, l1, l2, l3, l4, l5, l6, l7, l8, l9)		\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)						\
+	MR_decl_label1(e, l4)						\
+	MR_decl_label1(e, l5)						\
+	MR_decl_label1(e, l6)						\
+	MR_decl_label1(e, l7)						\
+	MR_decl_label1(e, l8)						\
+	MR_decl_label1(e, l9)
+
+#define	MR_decl_label10(e, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10)	\
+	MR_decl_label1(e, l1)						\
+	MR_decl_label1(e, l2)						\
+	MR_decl_label1(e, l3)						\
+	MR_decl_label1(e, l4)						\
+	MR_decl_label1(e, l5)						\
+	MR_decl_label1(e, l6)						\
+	MR_decl_label1(e, l7)						\
+	MR_decl_label1(e, l8)						\
+	MR_decl_label1(e, l9)						\
+	MR_decl_label1(e, l10)
+
+/*---------------------------------------------------------------------------*/
 
 /* definitions for computed gotos */
 
@@ -1444,3 +1834,5 @@
 #define MR_AND ,	/* used to separate the labels */
 
 #endif /* not MERCURY_GOTO_H */
+
+/*---------------------------------------------------------------------------*/
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.116
diff -u -b -r1.116 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	26 Nov 2008 03:01:59 -0000	1.116
+++ runtime/mercury_stack_layout.h	18 Oct 2009 12:36:01 -0000
@@ -371,11 +371,11 @@
 ** the return from the call that raised the exception).
 **
 ** The MR_sll_hidden field contains a boolean which is meaningful only if the
-** label corresponds to an execution tracing event. It will be true if the
+** label corresponds to an execution tracing event. It will be MR_HIDDEN if the
 ** event should have no effects that the user can see (no message printed, no
-** increment of the event number etc), and false otherwise. Hidden events
-** are sometimes needed by the declarative debugger to provide the proper
-** context for other events.
+** increment of the event number etc), and MR_NOT_HIDDEN otherwise. Hidden
+** events are sometimes needed by the declarative debugger to provide the
+** proper context for other events.
 **
 ** The MR_sll_goal_path field contains an offset into the module-wide string
 ** table, leading to a string that gives the goal path associated with the
@@ -471,6 +471,9 @@
 ** are ground.
 */
 
+#define MR_HIDDEN       1
+#define MR_NOT_HIDDEN   0
+
 struct MR_TypeParamLocns_Struct {
     MR_uint_least32_t       MR_tp_param_count;
     MR_LongLval             MR_tp_param_locns[MR_VARIABLE_SIZED];
@@ -563,6 +566,8 @@
         -1      /* No info about live values */                             \
     }
 
+/*-------------------------------------------------------------------------*/
+
 /*
 ** These macros are used as shorthands in generated C source files.
 ** The first two arguments are the entry label name and the label number;
@@ -590,7 +595,6 @@
         (h), (num), (path), (ue), -1                                        \
     }
 
-
 #define MR_DEF_LL(e, ln, port, num, path, vc, lt, vn, tv)                   \
     MR_DEF_LL_GEN(e, ln, port, MR_FALSE, num, path, NULL, vc, lt, vn, tv)
 
@@ -673,6 +677,8 @@
     MR_DEF_LLNVI_GEN(e, ln, port, MR_TRUE, num, path,                       \
         &MR_USER_LAYOUT_NAME(MR_label_name(MR_add_prefix(e), ln)))
 
+/*-------------------------------------------------------------------------*/
+
 #define MR_DECL_LL(e, ln)                                                   \
     MR_declare_label(MR_label_name(MR_add_prefix(e), ln));                  \
     static const MR_LabelLayout                                             \
@@ -759,6 +765,58 @@
     MR_DECL_LL(e, ln10)
 
 /*-------------------------------------------------------------------------*/
+
+/*
+** These macros are used as shorthands in generated C source files
+** for some fields of MR_LabelLayouts.
+**
+** We need to cast the addresses of proc layout structures because there
+** are several kinds of proc layouts, of different (but compatible) types.
+**
+** We need to cast the 
+*/
+
+#define MR_LLC(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)                                        \
+        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)                                    \
+        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)                                  \
+        MR_PROC_LAYOUT(MR_add_prefix(e)),                                   \
+        MR_PASTE2(MR_PORT_, port),                                          \
+        MR_HIDDEN, (num), (path), (ue)
+
+#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 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)
+
+#define MR_LLV_CC0(ltt, ltc, vnt, vnc)                                      \
+        (const void *) MR_XCOMMON(ltt, ltc),                                \
+        (const MR_uint_least16_t *) MR_XCOMMON(vnt, vnc),                   \
+        (const MR_TypeParamLocns *) 0
+
+/*-------------------------------------------------------------------------*/
 /*
 ** Definitions for MR_ProcLayout
 */
Index: runtime/mercury_trace_base.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_trace_base.h,v
retrieving revision 1.65
diff -u -b -r1.65 mercury_trace_base.h
--- runtime/mercury_trace_base.h	21 Sep 2009 16:08:48 -0000	1.65
+++ runtime/mercury_trace_base.h	18 Oct 2009 14:57:49 -0000
@@ -662,12 +662,12 @@
 ** The compiler emits the following macro at each system-defined trace event.
 */
 
-#define MR_EVENT(label)                                                 \
+#define MR_EVENT_SYS                                                    \
     {                                                                   \
         MR_Code *MR_jumpaddr;                                           \
         MR_save_transient_registers();                                  \
         MR_jumpaddr = MR_trace((const MR_LabelLayout *)                 \
-            &MR_LABEL_LAYOUT_NAME(MR_add_prefix(label)));               \
+            MR_HASH_DEF_LABEL_LAYOUT);                                  \
         MR_restore_transient_registers();                               \
         if (MR_jumpaddr != NULL) MR_GOTO(MR_jumpaddr);                  \
     }
@@ -676,7 +676,31 @@
 ** The compiler emits the following macro at each user-defined trace event.
 */
 
-#define MR_USER_EVENT(label)                                            \
+#define MR_EVENT_USER                                                   \
+    {                                                                   \
+        MR_Code *MR_jumpaddr;                                           \
+        MR_save_transient_registers();                                  \
+        MR_jumpaddr = MR_user_trace((const MR_LabelLayout *)            \
+            MR_HASH_DEF_LABEL_LAYOUT);                                  \
+        MR_restore_transient_registers();                               \
+        if (MR_jumpaddr != NULL) MR_GOTO(MR_jumpaddr);                  \
+    }
+
+/*
+** The compiler used to emit the following macros instead of those above.
+*/
+
+#define MR_EVENT(label_layout)                                          \
+    {                                                                   \
+        MR_Code *MR_jumpaddr;                                           \
+        MR_save_transient_registers();                                  \
+        MR_jumpaddr = MR_trace((const MR_LabelLayout *)                 \
+            &MR_LABEL_LAYOUT_NAME(MR_add_prefix(label)));               \
+        MR_restore_transient_registers();                               \
+        if (MR_jumpaddr != NULL) MR_GOTO(MR_jumpaddr);                  \
+    }
+
+#define MR_USER_EVENT(label_layout)                                     \
     {                                                                   \
         MR_Code *MR_jumpaddr;                                           \
         MR_save_transient_registers();                                  \
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
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
Index: tests/debugger/breakpoints.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp2,v
retrieving revision 1.14
diff -u -b -r1.14 breakpoints.exp2
--- tests/debugger/breakpoints.exp2	12 Jun 2007 06:06:33 -0000	1.14
+++ tests/debugger/breakpoints.exp2	18 Oct 2009 19:34:40 -0000
@@ -4,22 +4,22 @@
 mdb> register --quiet
 mdb> break data
 Ambiguous procedure specification. The matches are:
-0: pred breakpoints.data/1-0 (det)
-1: func breakpoints.data/0-0 (det)
+0: func breakpoints.data/0-0 (det)
+1: pred breakpoints.data/1-0 (det)
 
 Which do you want to put a breakpoint on (0-1 or *)? *
- 0: + stop  interface pred breakpoints.data/1-0 (det)
- 1: + stop  interface func breakpoints.data/0-0 (det)
-mdb> delete 0
- 0: E stop  interface pred breakpoints.data/1-0 (det)
+ 0: + stop  interface func breakpoints.data/0-0 (det)
+ 1: + stop  interface pred breakpoints.data/1-0 (det)
 mdb> delete 1
- 1: E stop  interface func breakpoints.data/0-0 (det)
+ 1: E stop  interface pred breakpoints.data/1-0 (det)
+mdb> delete 0
+ 0: E stop  interface func breakpoints.data/0-0 (det)
 mdb> break data
 Ambiguous procedure specification. The matches are:
-0: pred breakpoints.data/1-0 (det)
-1: func breakpoints.data/0-0 (det)
+0: func breakpoints.data/0-0 (det)
+1: pred breakpoints.data/1-0 (det)
 
-Which do you want to put a breakpoint on (0-1 or *)? 0
+Which do you want to put a breakpoint on (0-1 or *)? 1
  0: + stop  interface pred breakpoints.data/1-0 (det)
 mdb> continue
       E2:     C2 CALL pred breakpoints.data/1-0 (det) breakpoints.m:58 (breakpoints.m:56)
@@ -216,8 +216,8 @@
 mdb> procedures a.testmod
 List of procedures in module `a.testmod'
 
-func breakpoints.a.testmod.test_in_ab/0-0 (det)
 func breakpoints.a.testmod.test_in_a/0-0 (det)
+func breakpoints.a.testmod.test_in_ab/0-0 (det)
 mdb> break -O test_in_ab
 Ambiguous procedure specification. The matches are:
 0: func breakpoints.a.testmod.test_in_ab/0-0 (det)
Index: tests/debugger/breakpoints.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.inp,v
retrieving revision 1.10
diff -u -b -r1.10 breakpoints.inp
--- tests/debugger/breakpoints.inp	19 Jan 2007 04:42:47 -0000	1.10
+++ tests/debugger/breakpoints.inp	18 Oct 2009 18:00:05 -0000
@@ -2,10 +2,10 @@
 register --quiet
 break data
 *
-delete 0
 delete 1
+delete 0
 break data
-0
+1
 continue
 disable 0
 break info
Index: tests/debugger/completion.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/completion.exp,v
retrieving revision 1.38
diff -u -b -r1.38 completion.exp
--- tests/debugger/completion.exp	10 Jun 2008 04:05:01 -0000	1.38
+++ tests/debugger/completion.exp	18 Oct 2009 16:45:13 -0000
@@ -66,8 +66,8 @@
 completion.sub1       completion.sub2       completion.sub2.sub3
 procedures completion.sub1
 List of procedures in module `completion.sub1'
-pred completion.sub1.zp/1-0 (det)
 func completion.sub1.z1/0-0 (det)
+pred completion.sub1.zp/1-0 (det)
 mdb> 
 format        format_param  
 format_param  --flat  lines 10
Index: tests/debugger/lambdatest.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/lambdatest.exp,v
retrieving revision 1.1
diff -u -b -r1.1 lambdatest.exp
--- tests/debugger/lambdatest.exp	26 May 2005 00:17:05 -0000	1.1
+++ tests/debugger/lambdatest.exp	18 Oct 2009 16:47:15 -0000
@@ -4,10 +4,10 @@
 mdb> procedures lambdatest
 List of procedures in module `lambdatest'
 
-func lambdatest.lambda2_lambdatest_m_14/1-0 (det)
-func lambdatest.lambda_lambdatest_m_14/1-0 (det)
-func lambdatest.polycall/2-0 (det)
 pred lambdatest.main/2-0 (det)
+func lambdatest.polycall/2-0 (det)
+func lambdatest.lambda_lambdatest_m_14/1-0 (det)
+func lambdatest.lambda2_lambdatest_m_14/1-0 (det)
 mdb> break lambda_lambdatest_m_14
  0: + stop  interface func lambdatest.lambda_lambdatest_m_14/1-0 (det)
 mdb> c
Index: tests/debugger/poly_io_retry.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/poly_io_retry.exp,v
retrieving revision 1.2
diff -u -b -r1.2 poly_io_retry.exp
--- tests/debugger/poly_io_retry.exp	13 May 2005 13:45:32 -0000	1.2
+++ tests/debugger/poly_io_retry.exp	18 Oct 2009 16:48:08 -0000
@@ -7,12 +7,12 @@
 I/O tabling started.
 mdb> break polycall
 Ambiguous procedure specification. The matches are:
-0: pred poly_io_retry.polycall/3-1 (det)
-1: pred poly_io_retry.polycall/3-0 (det)
+0: pred poly_io_retry.polycall/3-0 (det)
+1: pred poly_io_retry.polycall/3-1 (det)
 
 Which do you want to put a breakpoint on (0-1 or *)? *
- 0: + stop  interface pred poly_io_retry.polycall/3-1 (det)
- 1: + stop  interface pred poly_io_retry.polycall/3-0 (det)
+ 0: + stop  interface pred poly_io_retry.polycall/3-0 (det)
+ 1: + stop  interface pred poly_io_retry.polycall/3-1 (det)
 mdb> c
       E2:     C2 CALL pred poly_io_retry.polycall/3-0 (det)
 mdb> f
Index: tests/debugger/polymorphic_output.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/polymorphic_output.exp2,v
retrieving revision 1.21
diff -u -b -r1.21 polymorphic_output.exp2
--- tests/debugger/polymorphic_output.exp2	12 Jan 2009 02:04:46 -0000	1.21
+++ tests/debugger/polymorphic_output.exp2	18 Oct 2009 16:48:30 -0000
@@ -51,10 +51,10 @@
 '_'
 browser> quit
 mdb> b -A deconstruct.det_arg/4
- 0: + stop  interface pred deconstruct.det_arg/4-3 (cc_multi)
- 1: + stop  interface pred deconstruct.det_arg/4-2 (cc_multi)
- 2: + stop  interface pred deconstruct.det_arg/4-1 (det)
- 3: + stop  interface pred deconstruct.det_arg/4-0 (det)
+ 0: + stop  interface pred deconstruct.det_arg/4-0 (det)
+ 1: + stop  interface pred deconstruct.det_arg/4-1 (det)
+ 2: + stop  interface pred deconstruct.det_arg/4-2 (cc_multi)
+ 3: + stop  interface pred deconstruct.det_arg/4-3 (cc_multi)
 mdb> c
       E3:     C3 CALL pred deconstruct.det_arg/4-1 (det)
 mdb> P
@@ -69,9 +69,9 @@
        Index (arg 3)          	3
        Argument (arg 4)       	two("two", 2, empty, empty)
 mdb> disable *
- 0: - stop  interface pred deconstruct.det_arg/4-3 (cc_multi)
- 1: - stop  interface pred deconstruct.det_arg/4-2 (cc_multi)
- 2: - stop  interface pred deconstruct.det_arg/4-1 (det)
- 3: - stop  interface pred deconstruct.det_arg/4-0 (det)
+ 0: - stop  interface pred deconstruct.det_arg/4-0 (det)
+ 1: - stop  interface pred deconstruct.det_arg/4-1 (det)
+ 2: - stop  interface pred deconstruct.det_arg/4-2 (cc_multi)
+ 3: - stop  interface pred deconstruct.det_arg/4-3 (cc_multi)
 mdb> c
 two
Index: tests/debugger/solver_test.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/solver_test.exp,v
retrieving revision 1.1
diff -u -b -r1.1 solver_test.exp
--- tests/debugger/solver_test.exp	9 Dec 2004 01:03:19 -0000	1.1
+++ tests/debugger/solver_test.exp	18 Oct 2009 16:50:08 -0000
@@ -5,14 +5,14 @@
 mdb> procedures solver_test
 List of procedures in module `solver_test'
 
-__Initialise__ for solver_test.foo/0-0 (det)
-__Compare__ for solver_test.foo/0-0 (det)
-__Unify__ for solver_test.foo/0-0 (semidet)
-pred solver_test.test_any_free_unify/2-0 (det)
-pred solver_test.init_foo/1-0 (det)
-func solver_test.representation to any foo/0/1-0 (det)
-func solver_test.representation to ground foo/0/1-0 (det)
-func solver_test.representation of any foo/0/1-0 (det)
-func solver_test.representation of ground foo/0/1-0 (det)
 pred solver_test.main/2-0 (det)
+func solver_test.representation of ground foo/0/1-0 (det)
+func solver_test.representation of any foo/0/1-0 (det)
+func solver_test.representation to ground foo/0/1-0 (det)
+func solver_test.representation to any foo/0/1-0 (det)
+pred solver_test.init_foo/1-0 (det)
+pred solver_test.test_any_free_unify/2-0 (det)
+__Unify__ for solver_test.foo/0-0 (semidet)
+__Compare__ for solver_test.foo/0-0 (det)
+__Initialise__ for solver_test.foo/0-0 (det)
 mdb> quit -y
Index: tests/debugger/uci.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/uci.exp,v
retrieving revision 1.5
diff -u -b -r1.5 uci.exp
--- tests/debugger/uci.exp	31 May 2007 02:01:21 -0000	1.5
+++ tests/debugger/uci.exp	18 Oct 2009 16:51:28 -0000
@@ -5,19 +5,19 @@
 Contexts will not be printed.
 mdb> register --quiet
 mdb> break -A unif*uci.
- 0: + stop  interface __Unify__ for uci.t4/4-0 (semidet)
- 1: + stop  interface __Unify__ for uci.t3/3-0 (semidet)
- 2: + stop  interface __Unify__ for uci.t2/2-0 (semidet)
- 3: + stop  interface __Unify__ for uci.t1/1-0 (semidet)
- 4: + stop  interface __Unify__ for uci.t0/0-0 (semidet)
- 5: + stop  interface __Unify__ for uci.i/3-0 (semidet)
+ 0: + stop  interface __Unify__ for uci.i/3-0 (semidet)
+ 1: + stop  interface __Unify__ for uci.t0/0-0 (semidet)
+ 2: + stop  interface __Unify__ for uci.t1/1-0 (semidet)
+ 3: + stop  interface __Unify__ for uci.t2/2-0 (semidet)
+ 4: + stop  interface __Unify__ for uci.t3/3-0 (semidet)
+ 5: + stop  interface __Unify__ for uci.t4/4-0 (semidet)
 mdb> break -A comp*uci.
- 6: + stop  interface __Compare__ for uci.t4/4-0 (det)
- 7: + stop  interface __Compare__ for uci.t3/3-0 (det)
- 8: + stop  interface __Compare__ for uci.t2/2-0 (det)
- 9: + stop  interface __Compare__ for uci.t1/1-0 (det)
-10: + stop  interface __Compare__ for uci.t0/0-0 (det)
-11: + stop  interface __Compare__ for uci.i/3-0 (det)
+ 6: + stop  interface __Compare__ for uci.i/3-0 (det)
+ 7: + stop  interface __Compare__ for uci.t0/0-0 (det)
+ 8: + stop  interface __Compare__ for uci.t1/1-0 (det)
+ 9: + stop  interface __Compare__ for uci.t2/2-0 (det)
+10: + stop  interface __Compare__ for uci.t3/3-0 (det)
+11: + stop  interface __Compare__ for uci.t4/4-0 (det)
 mdb> c
       E2:     C2 CALL __Compare__ for uci.t1/1-0 (det)
 mdb> print goal
cvs diff: Diffing tests/debugger/declarative
Index: tests/debugger/declarative/ite_2.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/ite_2.exp2,v
retrieving revision 1.6
diff -u -b -r1.6 ite_2.exp2
--- tests/debugger/declarative/ite_2.exp2	8 May 2006 08:17:32 -0000	1.6
+++ tests/debugger/declarative/ite_2.exp2	18 Oct 2009 16:55:51 -0000
@@ -4,12 +4,12 @@
 mdb> register --quiet
 mdb> break ite_2.ite
 Ambiguous procedure specification. The matches are:
-0: pred ite_2.ite/3-1 (multi)
-1: pred ite_2.ite/3-0 (det)
+0: pred ite_2.ite/3-0 (det)
+1: pred ite_2.ite/3-1 (multi)
 
 Which do you want to put a breakpoint on (0-1 or *)? *
- 0: + stop  interface pred ite_2.ite/3-1 (multi)
- 1: + stop  interface pred ite_2.ite/3-0 (det)
+ 0: + stop  interface pred ite_2.ite/3-0 (det)
+ 1: + stop  interface pred ite_2.ite/3-1 (multi)
 mdb> continue
        2:      2  2 CALL pred ite_2.ite/3-0 (det) ite_2.m:21 (ite_2.m:9)
 mdb> finish
Index: tests/debugger/declarative/trust.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/trust.exp,v
retrieving revision 1.11
diff -u -b -r1.11 trust.exp
--- tests/debugger/declarative/trust.exp	26 May 2005 00:17:06 -0000	1.11
+++ tests/debugger/declarative/trust.exp	18 Oct 2009 19:46:17 -0000
@@ -4,31 +4,31 @@
 Command echo enabled.
 mdb> trust trust_1.
 Ambiguous predicate or function specification. The matches are:
-0: pred trust_1.lambda_trust_1_m_15/3
-1: pred trust_1.w_cmp/3
+0: pred trust_1.w_cmp/3
+1: pred trust_1.lambda_trust_1_m_15/3
 
 Which predicate or function do you want to trust (0-1 or *)? *
-Trusting pred trust_1.lambda_trust_1_m_15/3
 Trusting pred trust_1.w_cmp/3
+Trusting pred trust_1.lambda_trust_1_m_15/3
 mdb> trusted
 Trusted Objects:
-1: predicate trust_1.lambda_trust_1_m_15/3
-2: predicate trust_1.w_cmp/3
-mdb> untrust 2
+1: predicate trust_1.w_cmp/3
+2: predicate trust_1.lambda_trust_1_m_15/3
+mdb> untrust 1
 mdb> trusted
 Trusted Objects:
-1: predicate trust_1.lambda_trust_1_m_15/3
-mdb> untrust 1
+2: predicate trust_1.lambda_trust_1_m_15/3
+mdb> untrust 2
 mdb> trusted
 There are no trusted modules, predicates or functions.
 mdb> trust trust_2
 Trusting module trust_2
 mdb> trust trust.
 Ambiguous predicate or function specification. The matches are:
-0: pred trust.dostuff/2
-1: pred trust.main/2
+0: pred trust.main/2
+1: pred trust.dostuff/2
 
-Which predicate or function do you want to trust (0-1 or *)? 1
+Which predicate or function do you want to trust (0-1 or *)? 0
 Trusting pred trust.main/2
 mdb> trusted
 Trusted Objects:
Index: tests/debugger/declarative/trust.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/trust.inp,v
retrieving revision 1.6
diff -u -b -r1.6 trust.inp
--- tests/debugger/declarative/trust.inp	20 May 2005 05:40:30 -0000	1.6
+++ tests/debugger/declarative/trust.inp	18 Oct 2009 18:00:42 -0000
@@ -5,13 +5,13 @@
 trust trust_1.
 *
 trusted
-untrust 2
-trusted
 untrust 1
 trusted
+untrust 2
+trusted
 trust trust_2
 trust trust.
-1
+0
 trusted
 trust trust_2
 trusted
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
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