[m-rev.] diff/for review: lookup disjunctions

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Dec 11 14:13:59 AEDT 2006


Does anyone want to review this?

Julien: when this diff has been in place for a while without problems,
we can stop supporting fact tables.

Zoltan.

For disjunctions in which all disjuncts are just facts, generate code
that does table lookup.

compiler/disj_gen.m:
	Implement lookup disjunctions. The new code based on the code in
	lookup_switch.m for generating switches in which some some switch arms
	are disjunctions. The code we generate is a specialized version
	we would generate for such switch arms.
	
compiler/lookup_switch.m:
compiler/lookup_util.m:
	Move some predicates from lookup_switch.m to lookup_util.m, to allow
	disj_gen.m to call them also.

	Reorder some argument lists to group related arguments together.
	Give some predicates more descriptive names.

	In lookup_switch.m, improve some comments. In lookup_util.m, avoid
	computing ExprnOpts many times.

compiler/switch_gen.m:
	Fix some obsolete some comments.

compiler/continuation_info.m:
	Provide for a description of the stack slot used by the new code in
	disj_gen.m.

compiler/opt_debug.m:
	Pass a maybe(proc_label) argument to the predicates that dump rvals
	and things that may contain rvals, so that rvals that are code
	constants may be printed in the short, user-friendly format
	(e.g. local_1, instead of the full, usually very long label name).
	This was helpful in debugging the change to disj_gen.m.

	Remove the old predicates whose sole purpose was to supply a
	proc_label for this purpose (e.g. dump_label_for_proc), since now
	even the predicates they are based on (e.g. dump_label) can now
	be given a proc_label.

compiler/frameopt.m:
compiler/use_local_vars.m:
compiler/switch_gen.m:
	Conform to the change to opt_debug.m.

tests/hard_coded/lookup_disj.{m,exp}:
	New test case to test the handling of the lookup tables.

	Existing test cases, specifically do_while, nasty_nondet, and
	nondet_ite* in general, and pretty_printing in hard_coded,
	are already tough tests of the handling of the code generator's
	internal data structures (such as the failure stack and the set of
	reserved stack slots).

tests/hard_coded/Mmakefile:
	Enable the new test case.

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/continuation_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.84
diff -u -b -r1.84 continuation_info.m
--- compiler/continuation_info.m	5 Dec 2006 03:50:49 -0000	1.84
+++ compiler/continuation_info.m	10 Dec 2006 04:16:46 -0000
@@ -317,6 +317,7 @@
     --->    ticket          % A ticket (trail pointer).
     ;       ticket_counter  % A copy of the ticket counter.
     ;       trace_data
+    ;       lookup_disj_cur
     ;       lookup_switch_cur
     ;       lookup_switch_max
     ;       sync_term       % A syncronization term used
@@ -908,6 +909,7 @@
     % XXX we may need to modify this, if the GC is going to garbage-collect
     % the trail.
 live_value_type(ticket_counter, live_value_unwanted).
+live_value_type(lookup_disj_cur, live_value_unwanted).
 live_value_type(lookup_switch_cur, live_value_unwanted).
 live_value_type(lookup_switch_max, live_value_unwanted).
 live_value_type(sync_term, live_value_unwanted).
Index: compiler/disj_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/disj_gen.m,v
retrieving revision 1.99
diff -u -b -r1.99 disj_gen.m
--- compiler/disj_gen.m	1 Dec 2006 15:03:54 -0000	1.99
+++ compiler/disj_gen.m	10 Dec 2006 09:42:29 -0000
@@ -33,6 +33,7 @@
 
 :- implementation.
 
+:- import_module backend_libs.builtin_ops.
 :- import_module hlds.goal_form.
 :- import_module hlds.hlds_llds.
 :- import_module libs.compiler_util.
@@ -41,10 +42,15 @@
 :- import_module libs.tree.
 :- import_module libs.tree.
 :- import_module ll_backend.code_gen.
+:- import_module ll_backend.continuation_info.
+:- import_module ll_backend.global_data.
+:- import_module ll_backend.lookup_util.
 :- import_module ll_backend.trace_gen.
 :- import_module parse_tree.prog_data.
 
 :- import_module bool.
+:- import_module int.
+:- import_module map.
 :- import_module maybe.
 :- import_module pair.
 :- import_module set.
@@ -69,16 +75,239 @@
         ;
             set.init(ResumeVars)
         ),
+        (
+            CodeModel = model_non,
+            is_lookup_disj(AddTrailOps, ResumeVars, Goals, DisjGoalInfo,
+                LookupDisjInfo, !CI)
+        ->
+            generate_lookup_disj(ResumeVars, LookupDisjInfo, Code, !CI)
+        ;
         generate_real_disj(AddTrailOps, CodeModel, ResumeVars, Goals,
             DisjGoalInfo, Code, !CI)
+        )
     ).
 
-%---------------------------------------------------------------------------%
+:- type lookup_disj_info
+    --->    lookup_disj_info(
+                ldi_variables           :: list(prog_var),
+                                        % The output variables.
+
+                ldi_store_map           :: abs_store_map,
+                ldi_branch_end          :: branch_end,
+                ldi_liveness            :: set(prog_var),
+
+                lds_cur_slot            :: lval,
+
+                lds_resume_map          :: resume_map,
+                lds_flush_code          :: code_tree,
+
+                lds_save_ticket_code    :: code_tree,
+                lds_maybe_ticket_slot   :: maybe(lval),
+
+                lds_save_hp_code        :: code_tree,
+                lds_maybe_hp_slot       :: maybe(lval),
+
+                lds_hijack_info         :: disj_hijack_info,
+                lds_prepare_hijack_code :: code_tree,
+
+                ldi_solns               :: list(list(rval)),
+                ldi_field_types         :: list(llds_type)
+            ).
+
+:- pred is_lookup_disj(bool::in, set(prog_var)::in, list(hlds_goal)::in,
+    hlds_goal_info::in, lookup_disj_info::out, code_info::in, code_info::out)
+    is semidet.
+
+is_lookup_disj(AddTrailOps, ResumeVars, Goals, DisjGoalInfo, LookupDisjInfo,
+        !CI) :-
+    code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+    MaybeTraceInfo = no,
+
+    % Lookup disjunctions rely on static ground terms to work.
+    code_info.get_globals(!.CI, Globals),
+    globals.lookup_bool_option(Globals, static_ground_terms, yes),
+
+    % Since we generate two code sequences, one for the first solution and one
+    % for all the later solutions, we don't get any benefit over the code
+    % sequence generated by generate_real_disj unless there are at least three
+    % solutions.
+    Goals = [_, _, _ | _],
+    all_disjuncts_are_conj_of_unify(Goals),
+
+    figure_out_output_vars(!.CI, DisjGoalInfo, OutVars),
+    VarTypes = get_var_types(!.CI),
+    list.map(map.lookup(VarTypes), OutVars, OutTypes),
+
+    code_info.produce_vars(ResumeVars, ResumeMap, FlushCode, !CI),
 
-:- pred disj_gen.generate_real_disj(bool::in, code_model::in,
-    set(prog_var)::in, list(hlds_goal)::in, hlds_goal_info::in,
+    % We cannot release this stack slot anywhere, since it will be needed
+    % after backtracking.
+    code_info.acquire_temp_slot(lookup_disj_cur, CurSlot, !CI),
+    code_info.maybe_save_ticket(AddTrailOps, SaveTicketCode, MaybeTicketSlot,
+        !CI),
+    code_info.get_globals(!.CI, Globals),
+    globals.lookup_bool_option(Globals, reclaim_heap_on_nondet_failure,
+        ReclaimHeap),
+    code_info.maybe_save_hp(ReclaimHeap, SaveHpCode, MaybeHpSlot, !CI),
+    code_info.prepare_for_disj_hijack(model_non, HijackInfo, PrepareHijackCode,
+        !CI),
+
+    % Every update to the code_info that needs to persist beyond the
+    % disjunction as a whole (e.g. the reservations of the stack slots required
+    % to implement the hijack) must be done before we remember this position.
+    code_info.remember_position(!.CI, CurPos),
+
+    goal_info_get_store_map(DisjGoalInfo, StoreMap),
+    generate_constants_for_disjuncts(Goals, OutVars, StoreMap, Solns,
+        no, MaybeEnd, MaybeLiveness, !CI),
+    (
+        MaybeLiveness = yes(Liveness)
+    ;
+        MaybeLiveness = no,
+        unexpected(this_file, "is_lookup_disj: no liveness")
+    ),
+    code_info.reset_to_position(CurPos, !CI),
+
+    code_info.get_globals(!.CI, Globals),
+    globals.lookup_bool_option(Globals, unboxed_float, UnboxFloat),
+    find_general_llds_types(UnboxFloat, OutTypes, Solns, LLDSTypes),
+    LookupDisjInfo = lookup_disj_info(OutVars, StoreMap, MaybeEnd, Liveness,
+        CurSlot, ResumeMap, FlushCode, SaveTicketCode, MaybeTicketSlot,
+        SaveHpCode, MaybeHpSlot, HijackInfo, PrepareHijackCode,
+        Solns, LLDSTypes).
+
+:- pred generate_lookup_disj(set(prog_var)::in, lookup_disj_info::in,
     code_tree::out, code_info::in, code_info::out) is det.
 
+generate_lookup_disj(ResumeVars, LookupDisjInfo, Code, !CI) :-
+    LookupDisjInfo = lookup_disj_info(OutVars, StoreMap, MaybeEnd, Liveness,
+        CurSlot, ResumeMap, FlushCode, SaveTicketCode, MaybeTicketSlot,
+        SaveHpCode, MaybeHpSlot, HijackInfo, PrepareHijackCode,
+        Solns, LLDSTypes),
+
+    list.length(Solns, NumSolns),
+    list.length(OutVars, NumOutVars),
+
+    code_info.add_vector_static_cell(LLDSTypes, Solns, SolnVectorAddr, !CI),
+    SolnVectorAddrRval = const(llconst_data_addr(SolnVectorAddr, no)),
+
+    code_info.get_next_label(EndLabel, !CI),
+
+    % Since we release BaseReg only after the calls to generate_branch_end
+    % (invoked through set_liveness_and_end_branch) we must ensure that
+    % generate_branch_end won't want to overwrite BaseReg.
+    code_info.acquire_reg_not_in_storemap(StoreMap, BaseReg, !CI),
+
+    BaseRegInitCode = node([
+        assign(BaseReg,
+            mem_addr(heap_ref(SolnVectorAddrRval, 0, const(llconst_int(0)))))
+            - "Compute base address for this case"
+    ]),
+    SaveSlotCode = node([
+        assign(CurSlot, const(llconst_int(NumOutVars)))
+            - "Setup current slot in the solution array"
+    ]),
+
+    code_info.remember_position(!.CI, DisjEntry),
+
+    code_info.make_resume_point(ResumeVars, resume_locs_stack_only,
+        ResumeMap, ResumePoint, !CI),
+    code_info.effect_resume_point(ResumePoint, model_non, UpdateRedoipCode,
+        !CI),
+    generate_offset_assigns(OutVars, 0, BaseReg, !CI),
+    code_info.flush_resume_vars_to_stack(FirstFlushResumeVarsCode, !CI),
+
+    % Forget the variables that are needed only at the resumption point at
+    % the start of the next disjunct, so that we don't generate exceptions
+    % when their storage is clobbered by the movement of the live variables
+    % to the places indicated in the store map.
+    code_info.pop_resume_point(!CI),
+    code_info.pickup_zombies(FirstZombies, !CI),
+    code_info.make_vars_forward_dead(FirstZombies, !CI),
+
+    set_liveness_and_end_branch(StoreMap, MaybeEnd, Liveness,
+        FirstBranchEndCode, !CI),
+    code_info.release_reg(BaseReg, !CI),
+
+    GotoEndCode = node([
+        goto(code_label(EndLabel)) - "goto end of lookup disj"
+    ]),
+
+    code_info.reset_to_position(DisjEntry, !CI),
+    code_info.generate_resume_point(ResumePoint, ResumePointCode, !CI),
+
+    code_info.maybe_reset_ticket(MaybeTicketSlot, reset_reason_undo,
+        RestoreTicketCode),
+    code_info.maybe_restore_hp(MaybeHpSlot, RestoreHpCode),
+
+    code_info.acquire_reg_not_in_storemap(StoreMap, LaterBaseReg, !CI),
+    code_info.get_next_label(UndoLabel, !CI),
+    code_info.get_next_label(AfterUndoLabel, !CI),
+    MaxSlot = (NumSolns - 1) * NumOutVars,
+    TestMoreSolnsCode = node([
+        assign(LaterBaseReg, lval(CurSlot))
+            - "Init later base register",
+        if_val(binop(int_ge, lval(LaterBaseReg), const(llconst_int(MaxSlot))),
+            code_label(UndoLabel))
+            - "Jump to undo hijack code if there are no more solutions",
+        assign(CurSlot,
+            binop(int_add, lval(CurSlot), const(llconst_int(NumOutVars))))
+            - "Update current slot",
+        goto(code_label(AfterUndoLabel))
+            - "Jump around undo hijack code",
+        label(UndoLabel)
+            - "Undo hijack code"
+    ]),
+    code_info.undo_disj_hijack(HijackInfo, UndoHijackCode, !CI),
+    AfterUndoLabelCode = node([
+        label(AfterUndoLabel)
+            - "Return later answer code",
+        assign(LaterBaseReg,
+            mem_addr(heap_ref(SolnVectorAddrRval, 0, lval(LaterBaseReg))))
+            - "Compute base address in later array for this solution"
+    ]),
+
+    % We need to call effect_resume_point in order to push ResumePoint
+    % onto the failure continuation stack, so pop_resume_point can pop
+    % it off. However, since the redoip already points there, we don't need
+    % to execute _LaterUpdateRedoipCode.
+    code_info.effect_resume_point(ResumePoint, model_non,
+        _LaterUpdateRedoipCode, !CI),
+
+    generate_offset_assigns(OutVars, 0, LaterBaseReg, !CI),
+    code_info.flush_resume_vars_to_stack(LaterFlushResumeVarsCode, !CI),
+
+    % Forget the variables that are needed only at the resumption point at
+    % the start of the next disjunct, so that we don't generate exceptions
+    % when their storage is clobbered by the movement of the live variables
+    % to the places indicated in the store map.
+    code_info.pop_resume_point(!CI),
+    code_info.pickup_zombies(LaterZombies, !CI),
+    code_info.make_vars_forward_dead(LaterZombies, !CI),
+
+    set_liveness_and_end_branch(StoreMap, MaybeEnd, Liveness,
+        LaterBranchEndCode, !CI),
+
+    code_info.after_all_branches(StoreMap, MaybeEnd, !CI),
+
+    EndLabelCode = node([
+        label(EndLabel) - "end of lookup disj"
+    ]),
+
+    Comment = node([comment("lookup disj") - ""]),
+    Code = tree_list([Comment, FlushCode, BaseRegInitCode,
+        SaveSlotCode, SaveTicketCode, SaveHpCode, PrepareHijackCode,
+        UpdateRedoipCode, FirstFlushResumeVarsCode, FirstBranchEndCode,
+        GotoEndCode, ResumePointCode, RestoreTicketCode, RestoreHpCode,
+        TestMoreSolnsCode, UndoHijackCode, AfterUndoLabelCode,
+        LaterFlushResumeVarsCode, LaterBranchEndCode, EndLabelCode]).
+
+%---------------------------------------------------------------------------%
+
+:- pred generate_real_disj(bool::in, code_model::in, set(prog_var)::in,
+    list(hlds_goal)::in, hlds_goal_info::in, code_tree::out,
+    code_info::in, code_info::out) is det.
+
 generate_real_disj(AddTrailOps, CodeModel, ResumeVars, Goals, DisjGoalInfo,
         Code, !CI)  :-
     % Make sure that the variables whose values will be needed on backtracking
@@ -119,8 +348,8 @@
 
     % Save the values of any stack slots we may hijack, and if necessary,
     % set the redofr slot of the top frame to point to this frame.
-    code_info.prepare_for_disj_hijack(CodeModel, HijackInfo,
-        PrepareHijackCode, !CI),
+    code_info.prepare_for_disj_hijack(CodeModel, HijackInfo, PrepareHijackCode,
+        !CI),
 
     code_info.get_next_label(EndLabel, !CI),
 
@@ -161,8 +390,8 @@
     % we arrive at this disjunct.
     (
         MaybeEntryResumePoint = yes(EntryResumePoint),
-        code_info.generate_resume_point(EntryResumePoint,
-            EntryResumePointCode, !CI)
+        code_info.generate_resume_point(EntryResumePoint, EntryResumePointCode,
+            !CI)
     ;
         MaybeEntryResumePoint = no,
         EntryResumePointCode = empty
@@ -181,8 +410,8 @@
             code_info.maybe_restore_hp(MaybeHpSlot0, RestoreHpCode),
 
             % Reset the solver state if necessary.
-            code_info.maybe_reset_ticket(MaybeTicketSlot,
-                reset_reason_undo, RestoreTicketCode)
+            code_info.maybe_reset_ticket(MaybeTicketSlot, reset_reason_undo,
+                RestoreTicketCode)
         ;
             MaybeEntryResumePoint = no,
             RestoreHpCode = empty,
@@ -265,14 +494,14 @@
         % the place indicated by StoreMap, and accumulate information about
         % the code_info state at the ends of the branches so far.
         goal_info_get_store_map(DisjGoalInfo, StoreMap),
-        code_info.generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd1,
-            SaveCode, !CI),
+        code_info.generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd1, SaveCode,
+            !CI),
 
         BranchCode = node([
             goto(code_label(EndLabel)) - "skip to end of nondet disj"
         ]),
 
-        disj_gen.generate_disjuncts(Goals, CodeModel, FullResumeMap,
+        generate_disjuncts(Goals, CodeModel, FullResumeMap,
             yes(NextResumePoint), HijackInfo, DisjGoalInfo,
             EndLabel, ReclaimHeap, MaybeHpSlot, MaybeTicketSlot, BranchStart,
             MaybeEnd1, MaybeEnd, RestCode, !CI),
Index: compiler/frameopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/frameopt.m,v
retrieving revision 1.108
diff -u -b -r1.108 frameopt.m
--- compiler/frameopt.m	1 Dec 2006 15:03:56 -0000	1.108
+++ compiler/frameopt.m	10 Dec 2006 08:26:23 -0000
@@ -2051,7 +2051,7 @@
             % This can happen if fulljump optimization has redirected the
             % return.
             Comments = [comment("exit side labels "
-                ++ dump_labels_for_proc(ProcLabel, SideLabels)) - ""]
+                ++ dump_labels(yes(ProcLabel), SideLabels)) - ""]
         ),
         PrevNeedsFrame = prev_block_needs_frame(OrdNeedsFrame, BlockInfo0),
         ( Type = exit_block(ExitInfo) ->
@@ -2221,19 +2221,19 @@
         SideLabels, MaybeFallThrough, Type),
     expect(unify(Label, BlockLabel), this_file,
         "describe_block: label mismatch"),
-    LabelStr = dump_label_for_proc(ProcLabel, Label),
+    LabelStr = dump_label(yes(ProcLabel), Label),
     BlockInstrsStr = dump_fullinstrs(ProcLabel, yes, BlockInstrs),
     Heading = "\nBLOCK " ++ LabelStr ++ "\n\n",
     ( map.search(PredMap, Label, PredLabel) ->
         PredStr = "previous label " ++
-            dump_label_for_proc(ProcLabel, PredLabel) ++ "\n"
+            dump_label(yes(ProcLabel), PredLabel) ++ "\n"
     ;
         PredStr = "no previous label\n"
     ),
     (
         FallInto = yes(FallIntoFromLabel),
         FallIntoStr = "fallen into from " ++
-            dump_label_for_proc(ProcLabel, FallIntoFromLabel) ++ "\n"
+            dump_label(yes(ProcLabel), FallIntoFromLabel) ++ "\n"
     ;
         FallInto = no,
         FallIntoStr = "not fallen into\n"
@@ -2244,12 +2244,12 @@
     ;
         SideLabels = [_ | _],
         SideStr = "side labels " ++
-            dump_labels_for_proc(ProcLabel, SideLabels) ++ "\n"
+            dump_labels(yes(ProcLabel), SideLabels) ++ "\n"
     ),
     (
         MaybeFallThrough = yes(FallThroughLabel),
         FallThroughStr = "falls through to " ++
-            dump_label_for_proc(ProcLabel, FallThroughLabel) ++ "\n"
+            dump_label(yes(ProcLabel), FallThroughLabel) ++ "\n"
     ;
         MaybeFallThrough = no,
         FallThroughStr = "does not fall through\n"
@@ -2336,7 +2336,7 @@
     ++ ", size: "
     ++ int_to_string(Size)
     ++ ", redoip: "
-    ++ dump_code_addr(Redoip)
+    ++ dump_code_addr(no, Redoip)
     ++ "\n".
 
 :- func describe_nondet_exit(proc_label, nondet_exit_info) = string.
@@ -2369,20 +2369,20 @@
 :- func describe_reason(proc_label, needs_frame_reason) = string.
 
 describe_reason(ProcLabel, code_needs_frame(Label)) =
-    "code " ++ dump_label_for_proc(ProcLabel, Label).
+    "code " ++ dump_label(yes(ProcLabel), Label).
 describe_reason(_ProcLabel, keep_frame) = "keep_frame".
 describe_reason(_ProcLabel, redoip_label) = "redoip_label".
 describe_reason(ProcLabel, frontier(Label, Reasons)) =
-    "frontier(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", {"
+    "frontier(" ++ dump_label(yes(ProcLabel), Label) ++ ", {"
         ++ describe_reasons(ProcLabel, to_sorted_list(Reasons)) ++ "})".
 describe_reason(ProcLabel, jump_around(Label, Reasons)) =
-    "jump_around(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", {"
+    "jump_around(" ++ dump_label(yes(ProcLabel), Label) ++ ", {"
         ++ describe_reasons(ProcLabel, to_sorted_list(Reasons)) ++ "})".
 describe_reason(ProcLabel, succ_propagated(Label, Reason)) =
-    "successor(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", "
+    "successor(" ++ dump_label(yes(ProcLabel), Label) ++ ", "
         ++ describe_reason(ProcLabel, Reason) ++ ")".
 describe_reason(ProcLabel, pred_propagated(Label, Reason)) =
-    "predecessor(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", "
+    "predecessor(" ++ dump_label(yes(ProcLabel), Label) ++ ", "
         ++ describe_reason(ProcLabel, Reason) ++ ")".
 
 :- func describe_reasons(proc_label, list(needs_frame_reason)) = string.
Index: compiler/lookup_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_switch.m,v
retrieving revision 1.72
diff -u -b -r1.72 lookup_switch.m
--- compiler/lookup_switch.m	1 Dec 2006 15:04:04 -0000	1.72
+++ compiler/lookup_switch.m	10 Dec 2006 04:38:13 -0000
@@ -11,8 +11,8 @@
 % 
 % For switches on atomic types in which the cases contain only the
 % construction of constants, generate code which just assigns the values of
-% the output variables by indexing into an array of values for each output
-% variable.
+% the output variables by indexing into an array of values for the output
+% variables.
 %
 % For switches that can fail, the generated code does a range check on the
 % index, and then does a lookup in a bit-vector to see if there is a value for
@@ -156,10 +156,10 @@
         StoreMap, !MaybeEnd, CodeModel, LookupSwitchInfo, !CI) :-
     % We need the code_info structure to generate code for the cases to
     % get the constants (if they exist). We can't throw it away at the
-    % end because we may have allocated some new static ground term labels.
+    % end because we may have allocated some new static ground terms.
 
     % Since lookup switches rely on static ground terms to work efficiently,
-    % there is no point in using a lookup switch if static-ground-terms are
+    % there is no point in using a lookup switch if static ground terms are
     % not enabled. Well, actually, it is possible that they might be a win in
     % some circumstances, but it would take a pretty complex heuristic to get
     % it right, so, lets just use a simple one - no static ground terms,
@@ -240,8 +240,9 @@
     ),
     figure_out_output_vars(!.CI, GoalInfo, OutVars),
     code_info.remember_position(!.CI, CurPos),
-    generate_constants(TaggedCases, OutVars, StoreMap, !MaybeEnd,
-        CaseSolns, MaybeLiveness, set.init, ResumeVars, no, GoalTrailOps, !CI),
+    generate_constants_for_lookup_switch(TaggedCases, OutVars, StoreMap,
+        CaseSolns, !MaybeEnd, MaybeLiveness, set.init, ResumeVars,
+        no, GoalTrailOps, !CI),
     code_info.reset_to_position(CurPos, !CI),
     (
         MaybeLiveness = yes(Liveness)
@@ -310,16 +311,17 @@
 
 %---------------------------------------------------------------------------%
 
-:- pred generate_constants(cases_list::in, list(prog_var)::in,
-    abs_store_map::in, branch_end::in, branch_end::out,
-    assoc_list(int, soln_consts)::out, maybe(set(prog_var))::out,
+:- pred generate_constants_for_lookup_switch(cases_list::in,
+    list(prog_var)::in, abs_store_map::in, assoc_list(int, soln_consts)::out,
+    branch_end::in, branch_end::out, maybe(set(prog_var))::out,
     set(prog_var)::in, set(prog_var)::out, bool::in, bool::out,
     code_info::in, code_info::out) is semidet.
 
-generate_constants([], _Vars, _StoreMap, !MaybeEnd, [], no, !ResumeVars,
-    !GoalTrailOps, !CI).
-generate_constants([Case | Cases], Vars, StoreMap, !MaybeEnd, [CaseVal | Rest],
-        MaybeLiveness, !ResumeVars, !GoalTrailOps, !CI) :-
+generate_constants_for_lookup_switch([], _Vars, _StoreMap, [], !MaybeEnd, no,
+        !ResumeVars, !GoalTrailOps, !CI).
+generate_constants_for_lookup_switch([Case | Cases], Vars, StoreMap,
+        [CaseVal | Rest], !MaybeEnd, MaybeLiveness, !ResumeVars,
+        !GoalTrailOps, !CI) :-
     Case = extended_case(_, int_tag(CaseTag), _, Goal),
     Goal = GoalExpr - GoalInfo,
 
@@ -354,23 +356,23 @@
         % generate_constants_for_disjuncts in lookup_util.m.
         code_info.pre_goal_update(GoalInfo, no, !CI),
         code_info.get_instmap(!.CI, InstMap),
-        generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, !MaybeEnd,
-            Solns, MaybeLiveness, !CI),
+        generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, Solns,
+            !MaybeEnd, MaybeLiveness, !CI),
         code_info.set_instmap(InstMap, !CI),
         code_info.post_goal_update(GoalInfo, !CI),
         CaseVal = CaseTag - several_solns(Solns)
     ;
         goal_is_conj_of_unify(Goal),
-        % The pre- and post-goal updates for the goals themselves are
-        % done as part of the call to generate_goal in
+        % The pre- and post-goal updates for the goals themselves
+        % are done as part of the call to generate_goal in
         % generate_constants_for_disjuncts in lookup_util.m.
-        generate_constants_for_arm(Goal, Vars, StoreMap, !MaybeEnd, Soln,
-            Liveness, !CI),
+        generate_constants_for_arm(Goal, Vars, StoreMap, Soln,
+            !MaybeEnd, Liveness, !CI),
         MaybeLiveness = yes(Liveness),
         CaseVal = CaseTag - one_soln(Soln)
     ),
-    generate_constants(Cases, Vars, StoreMap, !MaybeEnd, Rest, _, !ResumeVars,
-        !GoalTrailOps, !CI).
+    generate_constants_for_lookup_switch(Cases, Vars, StoreMap, Rest,
+        !MaybeEnd, _, !ResumeVars, !GoalTrailOps, !CI).
 
 %---------------------------------------------------------------------------%
 
@@ -540,7 +542,7 @@
     % Now generate the static cells into which we do the lookups of the values
     % of the output variables, if there are any.
     %
-    % We put a dummy row at the start
+    % We put a dummy row at the start.
     list.length(LLDSTypes, NumLLDSTypes),
     InitRowNumber = 1,
     DummyLaterSolnRow = list.map(default_value_for_type, LLDSTypes),
@@ -689,8 +691,8 @@
 
         % Forget the variables that are needed only at the resumption point at
         % the start of the next disjunct, so that we don't generate exceptions
-        % when their storage is clobbered by the movement of the live
-        % variables to the places indicated in the store map.
+        % when their storage is clobbered by the movement of the live variables
+        % to the places indicated in the store map.
         code_info.pop_resume_point(!CI),
         code_info.pickup_zombies(FirstZombies, !CI),
         code_info.make_vars_forward_dead(FirstZombies, !CI),
@@ -749,8 +751,8 @@
 
         % Forget the variables that are needed only at the resumption point at
         % the start of the next disjunct, so that we don't generate exceptions
-        % when their storage is clobbered by the movement of the live
-        % variables to the places indicated in the store map.
+        % when their storage is clobbered by the movement of the live variables
+        % to the places indicated in the store map.
         code_info.pop_resume_point(!CI),
         code_info.pickup_zombies(LaterZombies, !CI),
         code_info.make_vars_forward_dead(LaterZombies, !CI),
@@ -794,18 +796,6 @@
             LaterKindsCode])
     ).
 
-:- pred set_liveness_and_end_branch(abs_store_map::in, branch_end::in,
-    set(prog_var)::in, code_tree::out, code_info::in, code_info::out) is det.
-
-set_liveness_and_end_branch(StoreMap, MaybeEnd0, Liveness, BranchEndCode,
-        !CI) :-
-    % We keep track of what variables are supposed to be live at the end
-    % of cases. We have to do this explicitly because generating a `fail' slot
-    % last would yield the wrong liveness.
-    code_info.set_forward_live_vars(Liveness, !CI),
-    code_info.generate_branch_end(StoreMap, MaybeEnd0, _MaybeEnd,
-        BranchEndCode, !CI).
-
     % Note that we specify --optimise-constructor-last-call for this module
     % in order to make this predicate tail recursive.
     %
@@ -992,19 +982,6 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred generate_offset_assigns(list(prog_var)::in, int::in, lval::in,
-    code_info::in, code_info::out) is det.
-
-generate_offset_assigns([], _, _, !CI).
-generate_offset_assigns([Var | Vars], Offset, BaseReg, !CI) :-
-    LookupLval = field(yes(0), lval(BaseReg), const(llconst_int(Offset))),
-    code_info.assign_lval_to_var(Var, LookupLval, Code, !CI),
-    expect(tree.is_empty(Code), this_file,
-        "generate_offset_assigns: nonempty code"),
-    generate_offset_assigns(Vars, Offset + 1, BaseReg, !CI).
-
-%-----------------------------------------------------------------------------%
-
 :- func default_value_for_type(llds_type) = rval.
 
 default_value_for_type(bool) = const(llconst_int(0)).
Index: compiler/lookup_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_util.m,v
retrieving revision 1.2
diff -u -b -r1.2 lookup_util.m
--- compiler/lookup_util.m	3 May 2006 06:46:15 -0000	1.2
+++ compiler/lookup_util.m	10 Dec 2006 04:39:42 -0000
@@ -58,14 +58,20 @@
     % does steps 2, 3 and 4).
     %
 :- pred generate_constants_for_arm(hlds_goal::in, list(prog_var)::in,
-    abs_store_map::in, branch_end::in, branch_end::out, list(rval)::out,
+    abs_store_map::in, list(rval)::out, branch_end::in, branch_end::out,
     set(prog_var)::out, code_info::in, code_info::out) is semidet.
 
 :- pred generate_constants_for_disjuncts(list(hlds_goal)::in,
-    list(prog_var)::in, abs_store_map::in, branch_end::in, branch_end::out,
-    list(list(rval))::out, maybe(set(prog_var))::out,
+    list(prog_var)::in, abs_store_map::in, list(list(rval))::out,
+    branch_end::in, branch_end::out, maybe(set(prog_var))::out,
     code_info::in, code_info::out) is semidet.
 
+:- pred set_liveness_and_end_branch(abs_store_map::in, branch_end::in,
+    set(prog_var)::in, code_tree::out, code_info::in, code_info::out) is det.
+
+:- pred generate_offset_assigns(list(prog_var)::in, int::in, lval::in,
+    code_info::in, code_info::out) is det.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -73,12 +79,14 @@
 :- import_module check_hlds.mode_util.
 :- import_module hlds.code_model.
 :- import_module hlds.instmap.
+:- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.tree.
 :- import_module ll_backend.code_gen.
 :- import_module ll_backend.exprn_aux.
 
 :- import_module bool.
+:- import_module int.
 :- import_module pair.
 :- import_module solutions.
 
@@ -132,19 +140,23 @@
         CaseRvals, Liveness, !CI).
 
 :- pred do_generate_constants_for_arm(hlds_goal::in, list(prog_var)::in,
-    abs_store_map::in, bool::in, branch_end::in, branch_end::out,
-    list(rval)::out, set(prog_var)::out, code_info::in, code_info::out)
-    is semidet.
+    abs_store_map::in, bool::in, list(rval)::out,
+    branch_end::in, branch_end::out, set(prog_var)::out,
+    code_info::in, code_info::out) is semidet.
 
-do_generate_constants_for_arm(Goal, Vars, StoreMap, SetToUnknown, !MaybeEnd,
-        CaseRvals, Liveness, !CI) :-
+do_generate_constants_for_arm(Goal, Vars, StoreMap, SetToUnknown, CaseRvals,
+        !MaybeEnd, Liveness, !CI) :-
     code_info.remember_position(!.CI, BranchStart),
     Goal = _GoalExpr - GoalInfo,
     goal_info_get_code_model(GoalInfo, CodeModel),
     code_gen.generate_goal(CodeModel, Goal, Code, !CI),
     tree.tree_of_lists_is_empty(Code),
     code_info.get_forward_live_vars(!.CI, Liveness),
-    get_arm_rvals(Vars, CaseRvals, !CI),
+
+    code_info.get_globals(!.CI, Globals),
+    globals.get_options(Globals, Options),
+    exprn_aux.init_exprn_opts(Options, ExprnOpts),
+    get_arm_rvals(Vars, CaseRvals, !CI, ExprnOpts),
     (
         SetToUnknown = no
     ;
@@ -157,35 +169,32 @@
     code_info.generate_branch_end(StoreMap, !MaybeEnd, _EndCode, !CI),
     code_info.reset_to_position(BranchStart, !CI).
 
-generate_constants_for_disjuncts([], _Vars, _StoreMap, !MaybeEnd, [],
+generate_constants_for_disjuncts([], _Vars, _StoreMap, [], !MaybeEnd,
         no, !CI).
 generate_constants_for_disjuncts([Disjunct0 | Disjuncts], Vars, StoreMap,
-        !MaybeEnd, [Soln | Solns], yes(Liveness), !CI) :-
-    % The pre_goal_update sanity check insists on no_resume_point, to make
-    % sure that all resume points have been handled by surrounding code.
+        [Soln | Solns], !MaybeEnd, yes(Liveness), !CI) :-
+    % The pre_goal_update sanity check insists on no_resume_point, to ensure
+    % that all resume points have been handled by surrounding code.
     Disjunct0 = DisjunctGoalExpr - DisjunctGoalInfo0,
     goal_info_set_resume_point(no_resume_point,
         DisjunctGoalInfo0, DisjunctGoalInfo),
     Disjunct = DisjunctGoalExpr - DisjunctGoalInfo,
-    do_generate_constants_for_arm(Disjunct, Vars, StoreMap, yes, !MaybeEnd,
-        Soln, Liveness, !CI),
-    generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, !MaybeEnd,
-        Solns, _, !CI).
+    do_generate_constants_for_arm(Disjunct, Vars, StoreMap, yes, Soln,
+        !MaybeEnd, Liveness, !CI),
+    generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, Solns,
+        !MaybeEnd, _, !CI).
 
 %---------------------------------------------------------------------------%
 
 :- pred get_arm_rvals(list(prog_var)::in, list(rval)::out,
-    code_info::in, code_info::out) is semidet.
+    code_info::in, code_info::out, exprn_opts::in) is semidet.
 
-get_arm_rvals([], [], !CI).
-get_arm_rvals([Var | Vars], [Rval | Rvals], !CI) :-
+get_arm_rvals([], [], !CI, _ExprnOpts).
+get_arm_rvals([Var | Vars], [Rval | Rvals], !CI, ExprnOpts) :-
     code_info.produce_variable(Var, Code, Rval, !CI),
     tree.tree_of_lists_is_empty(Code),
-    code_info.get_globals(!.CI, Globals),
-    globals.get_options(Globals, Options),
-    exprn_aux.init_exprn_opts(Options, ExprnOpts),
     rval_is_constant(Rval, ExprnOpts),
-    get_arm_rvals(Vars, Rvals, !CI).
+    get_arm_rvals(Vars, Rvals, !CI, ExprnOpts).
 
     % rval_is_constant(Rval, ExprnOpts) is true iff Rval is a constant.
     % This depends on the options governing nonlocal gotos, asm labels enabled
@@ -204,3 +213,28 @@
     rval_is_constant(Exprn0, ExprnOpts).
 
 %---------------------------------------------------------------------------%
+
+set_liveness_and_end_branch(StoreMap, MaybeEnd0, Liveness, BranchEndCode,
+        !CI) :-
+    % We keep track of what variables are supposed to be live at the end
+    % of cases. We have to do this explicitly because generating a `fail' slot
+    % last would yield the wrong liveness.
+    code_info.set_forward_live_vars(Liveness, !CI),
+    code_info.generate_branch_end(StoreMap, MaybeEnd0, _MaybeEnd,
+        BranchEndCode, !CI).
+
+generate_offset_assigns([], _, _, !CI).
+generate_offset_assigns([Var | Vars], Offset, BaseReg, !CI) :-
+    LookupLval = field(yes(0), lval(BaseReg), const(llconst_int(Offset))),
+    code_info.assign_lval_to_var(Var, LookupLval, Code, !CI),
+    expect(tree.is_empty(Code), this_file,
+        "generate_offset_assigns: nonempty code"),
+    generate_offset_assigns(Vars, Offset + 1, BaseReg, !CI).
+
+%---------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "lookup_util.m".
+
+%---------------------------------------------------------------------------%
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.183
diff -u -b -r1.183 opt_debug.m
--- compiler/opt_debug.m	5 Dec 2006 03:50:56 -0000	1.183
+++ compiler/opt_debug.m	10 Dec 2006 08:26:23 -0000
@@ -40,30 +40,26 @@
 
 :- func dump_intlist(list(int)) = string.
 
-:- func dump_livemap(livemap) = string.
+:- func dump_livemap(maybe(proc_label), livemap) = string.
 
-:- func dump_livemap_for_proc(proc_label, livemap) = string.
-
-:- func dump_livemaplist(assoc_list(label, lvalset)) = string.
-
-:- func dump_livemaplist_for_proc(proc_label, assoc_list(label, lvalset))
+:- func dump_livemaplist(maybe(proc_label), assoc_list(label, lvalset))
     = string.
 
-:- func dump_livevals(lvalset) = string.
+:- func dump_livevals(maybe(proc_label), lvalset) = string.
 
-:- func dump_livelist(list(lval)) = string.
+:- func dump_livelist(maybe(proc_label), list(lval)) = string.
 
 :- func dump_reg(reg_type, int) = string.
 
-:- func dump_lval(lval) = string.
+:- func dump_lval(maybe(proc_label), lval) = string.
 
-:- func dump_rval(rval) = string.
+:- func dump_rval(maybe(proc_label), rval) = string.
 
-:- func dump_rvals(list(rval)) = string.
+:- func dump_rvals(maybe(proc_label), list(rval)) = string.
 
-:- func dump_mem_ref(mem_ref) = string.
+:- func dump_mem_ref(maybe(proc_label), mem_ref) = string.
 
-:- func dump_const(rval_const) = string.
+:- func dump_const(maybe(proc_label), rval_const) = string.
 
 :- func dump_data_addr(data_addr) = string.
 
@@ -85,27 +81,19 @@
 
 :- func dump_binop(binary_op) = string.
 
-:- func dump_label(label) = string.
-
-:- func dump_label_for_proc(proc_label, label) = string.
+:- func dump_label(maybe(proc_label), label) = string.
 
-:- func dump_labels(list(label)) = string.
+:- func dump_labels(maybe(proc_label), list(label)) = string.
 
-:- func dump_labels_for_proc(proc_label, list(label)) = string.
-
-:- func dump_label_pairs(list(pair(label))) = string.
+:- func dump_label_pairs(maybe(proc_label), list(pair(label))) = string.
 
 :- func dump_proclabel(proc_label) = string.
 
-:- func dump_maybe_rvals(list(maybe(rval)), int) = string.
-
-:- func dump_code_addr(code_addr) = string.
+:- func dump_maybe_rvals(maybe(proc_label), list(maybe(rval)), int) = string.
 
-:- func dump_code_addr_for_proc(proc_label, code_addr) = string.
+:- func dump_code_addr(maybe(proc_label), code_addr) = string.
 
-:- func dump_code_addrs(list(code_addr)) = string.
-
-:- func dump_code_addrs_for_proc(proc_label, list(code_addr)) = string.
+:- func dump_code_addrs(maybe(proc_label), list(code_addr)) = string.
 
 :- func dump_bool(bool) = string.
 
@@ -205,65 +193,58 @@
 dump_intlist([H | T]) =
     " " ++ int_to_string(H) ++ dump_intlist(T).
 
-dump_livemap(Livemap) =
-    dump_livemaplist(map.to_assoc_list(Livemap)).
-
-dump_livemap_for_proc(ProcLabel, Livemap) =
-    dump_livemaplist_for_proc(ProcLabel, map.to_assoc_list(Livemap)).
+dump_livemap(MaybeProcLabel, Livemap) =
+    dump_livemaplist(MaybeProcLabel, map.to_assoc_list(Livemap)).
 
-dump_livemaplist([]) = "".
-dump_livemaplist([Label - Lvalset | Livemaplist]) =
-    dump_label(Label) ++ " ->" ++ dump_livevals(Lvalset) ++ "\n"
-        ++ dump_livemaplist(Livemaplist).
-
-dump_livemaplist_for_proc(_ProcLabel, []) = "".
-dump_livemaplist_for_proc(ProcLabel, [Label - Lvalset | Livemaplist]) =
-    dump_label_for_proc(ProcLabel, Label) ++ " ->" ++
-        dump_livevals(Lvalset) ++ "\n" ++
-        dump_livemaplist_for_proc(ProcLabel, Livemaplist).
-
-dump_livevals(Lvalset) =
-    dump_livelist(set.to_sorted_list(Lvalset)).
-
-dump_livelist(Lvals) =
-    dump_livelist_2(Lvals, "").
-
-:- func dump_livelist_2(list(lval), string) = string.
-
-dump_livelist_2([], _) = "".
-dump_livelist_2([Lval | Lvallist], Prefix) =
-    Prefix ++ dump_lval(Lval) ++ dump_livelist_2(Lvallist, " ").
+dump_livemaplist(_, []) = "".
+dump_livemaplist(MaybeProcLabel, [Label - Lvalset | Livemaplist]) =
+    dump_label(MaybeProcLabel, Label) ++ " ->" ++
+        dump_livevals(MaybeProcLabel, Lvalset) ++ "\n" ++
+        dump_livemaplist(MaybeProcLabel, Livemaplist).
+
+dump_livevals(MaybeProcLabel, Lvalset) =
+    dump_livelist(MaybeProcLabel, set.to_sorted_list(Lvalset)).
+
+dump_livelist(MaybeProcLabel, Lvals) =
+    dump_livelist_2(MaybeProcLabel, Lvals, "").
+
+:- func dump_livelist_2(maybe(proc_label), list(lval), string) = string.
+
+dump_livelist_2(_, [], _) = "".
+dump_livelist_2(MaybeProcLabel, [Lval | Lvallist], Prefix) =
+    Prefix ++ dump_lval(MaybeProcLabel, Lval) ++
+        dump_livelist_2(MaybeProcLabel, Lvallist, " ").
 
 dump_reg(reg_r, N) =
     "r" ++ int_to_string(N).
 dump_reg(reg_f, N) =
     "f" ++ int_to_string(N).
 
-dump_lval(reg(Type, Num)) =
+dump_lval(_, reg(Type, Num)) =
     dump_reg(Type, Num).
-dump_lval(stackvar(N)) =
+dump_lval(_, stackvar(N)) =
     "sv" ++ int_to_string(N).
-dump_lval(parent_stackvar(N)) =
+dump_lval(_, parent_stackvar(N)) =
     "parent_sv" ++ int_to_string(N).
-dump_lval(framevar(N)) =
+dump_lval(_, framevar(N)) =
     "fv" ++ int_to_string(N).
-dump_lval(succip) = "succip".
-dump_lval(maxfr) = "maxfr".
-dump_lval(curfr) = "curfr".
-dump_lval(succfr_slot(R)) =
-    "succfr_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(prevfr_slot(R)) =
-    "prevfr_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(redofr_slot(R)) =
-    "redofr_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(redoip_slot(R)) =
-    "redoip_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(succip_slot(R)) =
-    "succip_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(hp) = "hp".
-dump_lval(sp) = "sp".
-dump_lval(parent_sp) = "parent_sp".
-dump_lval(field(MT, N, F)) = Str :-
+dump_lval(_, succip) = "succip".
+dump_lval(_, maxfr) = "maxfr".
+dump_lval(_, curfr) = "curfr".
+dump_lval(MaybeProcLabel, succfr_slot(R)) =
+    "succfr_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, prevfr_slot(R)) =
+    "prevfr_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, redofr_slot(R)) =
+    "redofr_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, redoip_slot(R)) =
+    "redoip_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, succip_slot(R)) =
+    "succip_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(_, hp) = "hp".
+dump_lval(_, sp) = "sp".
+dump_lval(_, parent_sp) = "parent_sp".
+dump_lval(MaybeProcLabel, field(MT, N, F)) = Str :-
     (
         MT = yes(T),
         string.int_to_string(T, T_str)
@@ -271,72 +252,76 @@
         MT = no,
         T_str = "no"
     ),
-    Str = "field(" ++ T_str ++ ", " ++ dump_rval(N) ++ ", "
-        ++ dump_rval(F) ++ ")".
-dump_lval(lvar(_)) = "lvar(_)".
-dump_lval(temp(Type, Num)) =
+    Str = "field(" ++ T_str ++ ", " ++ dump_rval(MaybeProcLabel, N) ++ ", "
+        ++ dump_rval(MaybeProcLabel, F) ++ ")".
+dump_lval(_, lvar(_)) = "lvar(_)".
+dump_lval(_, temp(Type, Num)) =
     "temp_" ++ dump_reg(Type, Num).
-dump_lval(mem_ref(R)) =
-    "mem_ref(" ++ dump_rval(R) ++ ")".
-dump_lval(global_var_ref(env_var_ref(VarName))) =
+dump_lval(MaybeProcLabel, mem_ref(R)) =
+    "mem_ref(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(_, global_var_ref(env_var_ref(VarName))) =
     "global_var_ref(env_var_ref(" ++ VarName ++ "))".
 
-dump_rval(lval(Lval)) =
-    dump_lval(Lval).
-dump_rval(var(Var)) =
+dump_rval(MaybeProcLabel, lval(Lval)) =
+    dump_lval(MaybeProcLabel, Lval).
+dump_rval(_, var(Var)) =
     "var(" ++ int_to_string(term.var_to_int(Var)) ++ ")".
-dump_rval(mkword(T, N)) =
-    "mkword(" ++ int_to_string(T) ++ ", " ++ dump_rval(N) ++ ")".
-dump_rval(const(C)) =
-    dump_const(C).
-dump_rval(unop(O, N)) =
-    dump_unop(O) ++ "(" ++ dump_rval(N) ++ ")".
-dump_rval(binop(O, N1, N2)) =
+dump_rval(MaybeProcLabel, mkword(T, N)) =
+    "mkword(" ++ int_to_string(T) ++ ", " ++
+        dump_rval(MaybeProcLabel, N) ++ ")".
+dump_rval(MaybeProcLabel, const(C)) =
+    dump_const(MaybeProcLabel, C).
+dump_rval(MaybeProcLabel, unop(O, N)) =
+    dump_unop(O) ++ "(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_rval(MaybeProcLabel, binop(O, N1, N2)) =
     (
         ( N1 = binop(_, _, _)
         ; N2 = binop(_, _, _)
         )
     ->
         "binop(" ++ dump_binop(O) ++ ", "
-            ++ dump_rval(N1) ++ ", " ++ dump_rval(N2) ++ ")"
+            ++ dump_rval(MaybeProcLabel, N1) ++ ", " ++
+            dump_rval(MaybeProcLabel, N2) ++ ")"
     ;
-        dump_rval(N1) ++ " " ++ dump_binop(O) ++ " " ++ dump_rval(N2)
+        dump_rval(MaybeProcLabel, N1) ++ " " ++ dump_binop(O) ++ " " ++
+        dump_rval(MaybeProcLabel, N2)
     ).
-dump_rval(mem_addr(M)) =
-    "mem_addr(" ++ dump_mem_ref(M) ++ ")".
+dump_rval(MaybeProcLabel, mem_addr(M)) =
+    "mem_addr(" ++ dump_mem_ref(MaybeProcLabel, M) ++ ")".
 
-dump_rvals([]) = "".
-dump_rvals([Rval | Rvals]) =
-    dump_rval(Rval) ++ ", " ++ dump_rvals(Rvals).
-
-dump_mem_ref(stackvar_ref(N)) =
-    "stackvar_ref(" ++ dump_rval(N) ++ ")".
-dump_mem_ref(framevar_ref(N)) =
-    "framevar_ref(" ++ dump_rval(N) ++ ")".
-dump_mem_ref(heap_ref(R, T, N)) =
-    "heap_ref(" ++ dump_rval(R) ++ ", " ++ int_to_string(T) ++ ", "
-        ++ dump_rval(N) ++ ")".
-
-dump_const(llconst_true) = "true".
-dump_const(llconst_false) = "false".
-dump_const(llconst_int(I)) =
+dump_rvals(_, []) = "".
+dump_rvals(MaybeProcLabel, [Rval | Rvals]) =
+    dump_rval(MaybeProcLabel, Rval) ++ ", " ++
+        dump_rvals(MaybeProcLabel, Rvals).
+
+dump_mem_ref(MaybeProcLabel, stackvar_ref(N)) =
+    "stackvar_ref(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_mem_ref(MaybeProcLabel, framevar_ref(N)) =
+    "framevar_ref(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_mem_ref(MaybeProcLabel, heap_ref(R, T, N)) =
+    "heap_ref(" ++ dump_rval(MaybeProcLabel, R) ++ ", " ++ int_to_string(T) ++ ", "
+        ++ dump_rval(MaybeProcLabel, N) ++ ")".
+
+dump_const(_, llconst_true) = "true".
+dump_const(_, llconst_false) = "false".
+dump_const(_, llconst_int(I)) =
     int_to_string(I).
-dump_const(llconst_float(F)) =
+dump_const(_, llconst_float(F)) =
     float_to_string(F).
-dump_const(llconst_string(S)) =
+dump_const(_, llconst_string(S)) =
     """" ++ S ++ """".
-dump_const(llconst_multi_string(L, _S)) =
+dump_const(_, llconst_multi_string(L, _S)) =
     "multi_string(" ++ int_to_string(L) ++ ")".
-dump_const(llconst_code_addr(CodeAddr)) =
-    "code_addr_const(" ++ dump_code_addr(CodeAddr) ++ ")".
-dump_const(llconst_data_addr(DataAddr, MaybeOffset)) = Str :-
-    DataAddr_str = dump_data_addr(DataAddr),
+dump_const(MaybeProcLabel, llconst_code_addr(CodeAddr)) =
+    "code_addr_const(" ++ dump_code_addr(MaybeProcLabel, CodeAddr) ++ ")".
+dump_const(_, llconst_data_addr(DataAddr, MaybeOffset)) = Str :-
+    DataAddrStr = dump_data_addr(DataAddr),
     (
         MaybeOffset = no,
-        Str = "data_addr_const(" ++ DataAddr_str ++ ")"
+        Str = "data_addr_const(" ++ DataAddrStr ++ ")"
     ;
         MaybeOffset = yes(Offset),
-        Str = "data_addr_const(" ++ DataAddr_str ++ ", "
+        Str = "data_addr_const(" ++ DataAddrStr ++ ", "
             ++ int_to_string(Offset) ++ ")"
     ).
 
@@ -447,7 +432,7 @@
     Str = "tc_instance(" ++ TypesStr ++ ")".
 
 dump_layout_name(label_layout(ProcLabel, LabelNum, LabelVars)) = Str :-
-    LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+    LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
     (
         LabelVars = label_has_var_info,
         LabelVarsStr = "label_has_var_info"
@@ -457,13 +442,13 @@
     ),
     Str = "label_layout(" ++ LabelStr ++ ", " ++ LabelVarsStr ++ ")".
 dump_layout_name(user_event_layout(ProcLabel, LabelNum)) = Str :-
-    LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+    LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
     Str = "user_event_layout(" ++ LabelStr ++ ")".
 dump_layout_name(user_event_attr_names(ProcLabel, LabelNum)) = Str :-
-    LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+    LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
     Str = "user_event_attr_names(" ++ LabelStr ++ ")".
 dump_layout_name(user_event_attr_var_nums(ProcLabel, LabelNum)) = Str :-
-    LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+    LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
     Str = "user_event_attr_var_nums(" ++ LabelStr ++ ")".
 dump_layout_name(proc_layout(RttiProcLabel, _)) =
     "proc_layout(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
@@ -520,90 +505,70 @@
 dump_binop(Op) =
     llds_out.binary_op_to_string(Op).
 
-dump_maybe_rvals([], _) = "".
-dump_maybe_rvals([MR | MRs], N) = Str :-
+dump_maybe_rvals(_, [], _) = "".
+dump_maybe_rvals(MaybeProcLabel, [MR | MRs], N) = Str :-
     ( N > 0 ->
         (
             MR = yes(R),
-            MR_str = dump_rval(R)
+            MR_str = dump_rval(MaybeProcLabel, R)
         ;
             MR = no,
             MR_str = "no"
         ),
-        Str = MR_str ++ ", " ++ dump_maybe_rvals(MRs, N - 1)
+        Str = MR_str ++ ", " ++ dump_maybe_rvals(MaybeProcLabel, MRs, N - 1)
     ;
         Str = "truncated"
     ).
 
-dump_code_addr(code_label(Label)) = dump_label(Label).
-dump_code_addr(code_imported_proc(ProcLabel)) = dump_proclabel(ProcLabel).
-dump_code_addr(code_succip) = "succip".
-dump_code_addr(do_succeed(Last)) = Str :-
-    (
-        Last = no,
-        Str = "do_succeed"
-    ;
-        Last = yes,
-        Str = "do_last_succeed"
-    ).
-dump_code_addr(do_redo) = "do_redo".
-dump_code_addr(do_fail) = "do_fail".
-dump_code_addr(do_trace_redo_fail_shallow) =
-    "do_trace_redo_fail_shallow".
-dump_code_addr(do_trace_redo_fail_deep) = "do_trace_redo_fail_deep".
-dump_code_addr(do_call_closure(Variant)) =
+dump_code_addr(MaybeProcLabel, code_label(Label)) =
+    dump_label(MaybeProcLabel, Label).
+dump_code_addr(_, code_imported_proc(ProcLabel)) = dump_proclabel(ProcLabel).
+dump_code_addr(_, code_succip) = "succip".
+dump_code_addr(_, do_succeed(no)) = "do_succeed".
+dump_code_addr(_, do_succeed(yes)) = "do_last_succeed".
+dump_code_addr(_, do_redo) = "do_redo".
+dump_code_addr(_, do_fail) = "do_fail".
+dump_code_addr(_, do_trace_redo_fail_shallow) = "do_trace_redo_fail_shallow".
+dump_code_addr(_, do_trace_redo_fail_deep) = "do_trace_redo_fail_deep".
+dump_code_addr(_, do_call_closure(Variant)) =
     "do_call_closure_" ++ ho_call_variant_to_string(Variant).
-dump_code_addr(do_call_class_method(Variant)) =
+dump_code_addr(_, do_call_class_method(Variant)) =
     "do_call_class_method_" ++ ho_call_variant_to_string(Variant).
-dump_code_addr(do_not_reached) = "do_not_reached".
-
-dump_code_addr_for_proc(ProcLabel, CodeAddr) =
-    ( CodeAddr = code_label(Label) ->
-        dump_label_for_proc(ProcLabel, Label)
-    ;
-        dump_code_addr(CodeAddr)
-    ).
+dump_code_addr(_, do_not_reached) = "do_not_reached".
 
-dump_code_addrs([]) = "".
-dump_code_addrs([Addr | Addrs]) =
-    " " ++ dump_code_addr(Addr) ++ dump_code_addrs(Addrs).
+dump_code_addrs(_, []) = "".
+dump_code_addrs(MaybeProcLabel, [Addr | Addrs]) =
+    " " ++ dump_code_addr(MaybeProcLabel, Addr) ++
+        dump_code_addrs(MaybeProcLabel, Addrs).
 
-dump_code_addrs_for_proc(_, []) = "".
-dump_code_addrs_for_proc(ProcLabel, [Addr | Addrs]) =
-    " " ++ dump_code_addr_for_proc(ProcLabel, Addr) ++
-        dump_code_addrs_for_proc(ProcLabel, Addrs).
-
-dump_label(internal_label(N, ProcLabel)) =
+dump_label(no, internal_label(N, ProcLabel)) =
     dump_proclabel(ProcLabel) ++ "_i" ++ int_to_string(N).
-dump_label(entry_label(_, ProcLabel)) =
+dump_label(no, entry_label(_, ProcLabel)) =
     dump_proclabel(ProcLabel).
-
-dump_label_for_proc(CurProcLabel, internal_label(N, ProcLabel)) = Str :-
+dump_label(yes(CurProcLabel), internal_label(N, ProcLabel)) = Str :-
     string.int_to_string(N, N_str),
     ( CurProcLabel = ProcLabel ->
         Str = "local_" ++ N_str
     ;
         Str = dump_proclabel(ProcLabel) ++ "_" ++ N_str
     ).
-dump_label_for_proc(CurProcLabel, entry_label(_, ProcLabel)) = Str :-
+dump_label(yes(CurProcLabel), entry_label(_, ProcLabel)) = Str :-
     ( CurProcLabel = ProcLabel ->
         Str = "CUR_PROC_ENTRY"
     ;
         Str = dump_proclabel(ProcLabel)
     ).
 
-dump_labels([]) = "".
-dump_labels([Label | Labels]) =
-    " " ++ dump_label(Label) ++ dump_labels(Labels).
-
-dump_labels_for_proc(_, []) = "".
-dump_labels_for_proc(ProcLabel, [Label | Labels]) =
-    " " ++ dump_label_for_proc(ProcLabel, Label) ++
-        dump_labels_for_proc(ProcLabel, Labels).
-
-dump_label_pairs([]) = "".
-dump_label_pairs([L1 - L2 | Labels]) =
-    " " ++ dump_label(L1) ++ "-" ++ dump_label(L2) ++ dump_label_pairs(Labels).
+dump_labels(_, []) = "".
+dump_labels(MaybeProcLabel, [Label | Labels]) =
+    " " ++ dump_label(MaybeProcLabel, Label) ++
+        dump_labels(MaybeProcLabel, Labels).
+
+dump_label_pairs(_, []) = "".
+dump_label_pairs(MaybeProcLabel, [L1 - L2 | Labels]) =
+    " " ++ dump_label(MaybeProcLabel, L1) ++ "-" ++
+        dump_label(MaybeProcLabel, L2) ++
+        dump_label_pairs(MaybeProcLabel, Labels).
 
 :- func dump_rttiproclabel(rtti_proc_label) = string.
 
@@ -649,7 +614,7 @@
         Str = "comment(" ++ Comment ++ ")"
     ;
         Instr = livevals(Livevals),
-        Str = "livevals(" ++ dump_livevals(Livevals) ++ ")"
+        Str = "livevals(" ++ dump_livevals(yes(ProcLabel), Livevals) ++ ")"
     ;
         Instr = block(RTemps, FTemps, Instrs),
         Str = "block(" ++ int_to_string(RTemps) ++ ", "
@@ -658,7 +623,8 @@
             ++ ")"
     ;
         Instr = assign(Lval, Rval),
-        Str = dump_lval(Lval) ++ " := " ++ dump_rval(Rval)
+        Str = dump_lval(yes(ProcLabel), Lval) ++ " := " ++
+            dump_rval(yes(ProcLabel), Rval)
     ;
         Instr = llcall(Callee, ReturnLabel, _LiveInfo, _Context, _GoalPath,
             CallModel),
@@ -678,14 +644,14 @@
             CallModel = call_model_nondet(unchecked_tail_call),
             CallModelStr = "nondet unchecked_tail_call"
         ),
-        Str = "call(" ++ dump_code_addr_for_proc(ProcLabel, Callee) ++ ", "
-            ++ dump_code_addr_for_proc(ProcLabel, ReturnLabel) ++ ", ..., "
+        Str = "call(" ++ dump_code_addr(yes(ProcLabel), Callee) ++ ", "
+            ++ dump_code_addr(yes(ProcLabel), ReturnLabel) ++ ", ..., "
             ++ CallModelStr ++ ")"
     ;
         Instr = mkframe(FrameInfo, MaybeRedoip),
         (
             MaybeRedoip = yes(Redoip),
-            R_str = dump_code_addr_for_proc(ProcLabel, Redoip)
+            R_str = dump_code_addr(yes(ProcLabel), Redoip)
         ;
             MaybeRedoip = no,
             R_str = "no_redoip"
@@ -713,27 +679,27 @@
         )
     ;
         Instr = label(Label),
-        Str = dump_label_for_proc(ProcLabel, Label) ++ ":"
+        Str = dump_label(yes(ProcLabel), Label) ++ ":"
     ;
         Instr = goto(CodeAddr),
-        Str = "goto " ++ dump_code_addr_for_proc(ProcLabel, CodeAddr)
+        Str = "goto " ++ dump_code_addr(yes(ProcLabel), CodeAddr)
     ;
         Instr = computed_goto(Rval, Labels),
-        Str = "computed_goto " ++ dump_rval(Rval) ++ ":"
-            ++ dump_labels_for_proc(ProcLabel, Labels)
+        Str = "computed_goto " ++ dump_rval(yes(ProcLabel), Rval) ++ ":"
+            ++ dump_labels(yes(ProcLabel), Labels)
     ;
         Instr = arbitrary_c_code(Code, _),
         Str = "arbitrary_c_code(" ++ Code ++ ")"
     ;
         Instr = if_val(Rval, CodeAddr),
-        Str = "if (" ++ dump_rval(Rval) ++ ") goto "
-            ++ dump_code_addr_for_proc(ProcLabel, CodeAddr)
+        Str = "if (" ++ dump_rval(yes(ProcLabel), Rval) ++ ") goto "
+            ++ dump_code_addr(yes(ProcLabel), CodeAddr)
     ;
         Instr = save_maxfr(Lval),
-        Str = "save_maxfr(" ++ dump_lval(Lval) ++ ")"
+        Str = "save_maxfr(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
     ;
         Instr = restore_maxfr(Lval),
-        Str = "restore_maxfr(" ++ dump_lval(Lval) ++ ")"
+        Str = "restore_maxfr(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
     ;
         Instr = incr_hp(Lval, MaybeTag, MaybeOffset, Size, _, MayUseAtomic),
         (
@@ -750,24 +716,25 @@
             MaybeOffset = yes(Offset),
             string.int_to_string(Offset, O_str)
         ),
-        Str = "incr_hp(" ++ dump_lval(Lval) ++ ", " ++ T_str ++ ", " ++ O_str
-            ++ ", " ++ dump_rval(Size) ++
-            ", " ++ dump_may_use_atomic(MayUseAtomic) ++ ")"
+        Str = "incr_hp(" ++ dump_lval(yes(ProcLabel), Lval) ++ ", " ++
+            T_str ++ ", " ++ O_str ++ ", " ++
+            dump_rval(yes(ProcLabel), Size) ++ ", " ++
+            dump_may_use_atomic(MayUseAtomic) ++ ")"
     ;
         Instr = mark_hp(Lval),
-        Str = "mark_hp(" ++ dump_lval(Lval) ++ ")"
+        Str = "mark_hp(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
     ;
         Instr = restore_hp(Rval),
-        Str = "restore_hp(" ++ dump_rval(Rval) ++ ")"
+        Str = "restore_hp(" ++ dump_rval(yes(ProcLabel), Rval) ++ ")"
     ;
         Instr = free_heap(Rval),
-        Str = "free_heap(" ++ dump_rval(Rval) ++ ")"
+        Str = "free_heap(" ++ dump_rval(yes(ProcLabel), Rval) ++ ")"
     ;
         Instr = store_ticket(Lval),
-        Str = "store_ticket(" ++ dump_lval(Lval) ++ ")"
+        Str = "store_ticket(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
     ;
         Instr = reset_ticket(Rval, _Reason),
-        Str = "reset_ticket(" ++ dump_rval(Rval) ++ ", _)"
+        Str = "reset_ticket(" ++ dump_rval(yes(ProcLabel), Rval) ++ ", _)"
     ;
         Instr = discard_ticket,
         Str = "discard_ticket"
@@ -776,10 +743,10 @@
         Str = "prune_ticket"
     ;
         Instr = mark_ticket_stack(Lval),
-        Str = "mark_ticket_stack(" ++ dump_lval(Lval) ++ ")"
+        Str = "mark_ticket_stack(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
     ;
         Instr = prune_tickets_to(Rval),
-        Str = "prune_tickets_to(" ++ dump_rval(Rval) ++ ")"
+        Str = "prune_tickets_to(" ++ dump_rval(yes(ProcLabel), Rval) ++ ")"
     ;
         Instr = incr_sp(Size, _, Kind),
         Str = "incr_sp(" ++ int_to_string(Size) ++ ", " ++
@@ -792,25 +759,26 @@
         Str = "decr_sp_and_return(" ++ int_to_string(Size) ++ ")"
     ;
         Instr = init_sync_term(Lval, N),
-        Str = "init_sync_term(" ++ dump_lval(Lval) ++ ", "
+        Str = "init_sync_term(" ++ dump_lval(yes(ProcLabel), Lval) ++ ", "
             ++ int_to_string(N) ++ ")"
     ;
         Instr = fork(Child),
-        Str = "fork(" ++ dump_label_for_proc(ProcLabel, Child) ++ ")"
+        Str = "fork(" ++ dump_label(yes(ProcLabel), Child) ++ ")"
     ;
         Instr = join_and_continue(Lval, Label),
-        Str = "join(" ++ dump_lval(Lval) ++ ", "
-            ++ dump_label_for_proc(ProcLabel, Label) ++ ")"
+        Str = "join(" ++ dump_lval(yes(ProcLabel), Lval) ++ ", "
+            ++ dump_label(yes(ProcLabel), Label) ++ ")"
     ;
         Instr = pragma_c(Decls, Comps, MCM, MFNL, MFL, MFOL, MNF, SSR, MD),
+        MaybeProcLabel = yes(ProcLabel),
         Str = "pragma_c(\n"
             ++ "declarations:\n" ++ dump_decls(Decls)
-            ++ "components:\n" ++ dump_components(ProcLabel, Comps)
+            ++ "components:\n" ++ dump_components(MaybeProcLabel, Comps)
             ++ dump_may_call_mercury(MCM) ++ "\n"
-            ++ dump_maybe_label_for_proc("fix nolayout:", ProcLabel, MFNL)
-            ++ dump_maybe_label_for_proc("fix layout:", ProcLabel, MFL)
-            ++ dump_maybe_label_for_proc("fix onlylayout:", ProcLabel, MFOL)
-            ++ dump_maybe_label_for_proc("nofix:", ProcLabel, MNF)
+            ++ dump_maybe_label("fix nolayout:", MaybeProcLabel, MFNL)
+            ++ dump_maybe_label("fix layout:", MaybeProcLabel, MFL)
+            ++ dump_maybe_label("fix onlylayout:", MaybeProcLabel, MFOL)
+            ++ dump_maybe_label("nofix:", MaybeProcLabel, MNF)
             ++ dump_bool_msg("stack slot ref:", SSR)
             ++ dump_bool_msg("may duplicate:", MD)
             ++ ")"
@@ -821,11 +789,11 @@
 dump_may_call_mercury(proc_may_call_mercury) = "may_call_mercury".
 dump_may_call_mercury(proc_will_not_call_mercury) = "will_not_call_mercury".
 
-:- func dump_maybe_label_for_proc(string, proc_label, maybe(label)) = string.
+:- func dump_maybe_label(string, maybe(proc_label), maybe(label)) = string.
 
-dump_maybe_label_for_proc(_Msg, _ProcLabel, no) = "".
-dump_maybe_label_for_proc(Msg, ProcLabel, yes(Label)) =
-    Msg ++ " " ++ dump_label_for_proc(ProcLabel, Label) ++ "\n".
+dump_maybe_label(_Msg, _MaybeProcLabel, no) = "".
+dump_maybe_label(Msg, MaybeProcLabel, yes(Label)) =
+    Msg ++ " " ++ dump_label(MaybeProcLabel, Label) ++ "\n".
 
 :- func dump_bool_msg(string, bool) = string.
 
@@ -850,45 +818,54 @@
 dump_decl(pragma_c_struct_ptr_decl(StructTag, VarName)) =
     "decl struct" ++ StructTag ++ " " ++ VarName ++ "\n".
 
-:- func dump_components(proc_label, list(pragma_c_component)) = string.
+:- func dump_components(maybe(proc_label), list(pragma_c_component)) = string.
 
 dump_components(_, []) = "".
-dump_components(ProcLabel, [Comp | Comps]) =
-    dump_component(ProcLabel, Comp) ++ dump_components(ProcLabel, Comps).
-
-:- func dump_component(proc_label, pragma_c_component) = string.
-
-dump_component(_, pragma_c_inputs(Inputs)) = dump_input_components(Inputs).
-dump_component(_, pragma_c_outputs(Outputs)) = dump_output_components(Outputs).
+dump_components(MaybeProcLabel, [Comp | Comps]) =
+    dump_component(MaybeProcLabel, Comp) ++
+        dump_components(MaybeProcLabel, Comps).
+
+:- func dump_component(maybe(proc_label), pragma_c_component) = string.
+
+dump_component(MaybeProcLabel, pragma_c_inputs(Inputs)) =
+    dump_input_components(MaybeProcLabel, Inputs).
+dump_component(MaybeProcLabel, pragma_c_outputs(Outputs)) =
+    dump_output_components(MaybeProcLabel, Outputs).
 dump_component(_, pragma_c_user_code(_, Code)) = Code ++ "\n".
 dump_component(_, pragma_c_raw_code(Code, _, _)) = Code ++ "\n".
-dump_component(ProcLabel, pragma_c_fail_to(Label)) =
-    "fail to " ++ dump_label_for_proc(ProcLabel, Label) ++ "\n".
+dump_component(MaybeProcLabel, pragma_c_fail_to(Label)) =
+    "fail to " ++ dump_label(MaybeProcLabel, Label) ++ "\n".
 dump_component(_, pragma_c_noop) = "".
 
-:- func dump_input_components(list(pragma_c_input)) = string.
-
-dump_input_components([]) = "".
-dump_input_components([Input | Inputs]) =
-    dump_input_component(Input) ++ "\n" ++
-    dump_input_components(Inputs).
-
-:- func dump_output_components(list(pragma_c_output)) = string.
-
-dump_output_components([]) = "".
-dump_output_components([Input | Inputs]) =
-    dump_output_component(Input) ++ "\n" ++
-    dump_output_components(Inputs).
-
-:- func dump_input_component(pragma_c_input) = string.
+:- func dump_input_components(maybe(proc_label), list(pragma_c_input))
+    = string.
 
-dump_input_component(pragma_c_input(Var, _, Dummy, _, Rval, _, _)) =
-    Var ++ dump_maybe_dummy(Dummy) ++ " := " ++ dump_rval(Rval).
+dump_input_components(_, []) = "".
+dump_input_components(MaybeProcLabel, [Input | Inputs]) =
+    dump_input_component(MaybeProcLabel, Input) ++ "\n" ++
+    dump_input_components(MaybeProcLabel, Inputs).
 
-:- func dump_output_component(pragma_c_output) = string.
+:- func dump_output_components(maybe(proc_label), list(pragma_c_output))
+    = string.
 
-dump_output_component(pragma_c_output(Lval, _, Dummy, _, Var, _, _)) =
-    dump_lval(Lval) ++ " := " ++ Var ++ dump_maybe_dummy(Dummy).
+dump_output_components(_, []) = "".
+dump_output_components(MaybeProcLabel, [Input | Inputs]) =
+    dump_output_component(MaybeProcLabel, Input) ++ "\n" ++
+    dump_output_components(MaybeProcLabel, Inputs).
+
+:- func dump_input_component(maybe(proc_label), pragma_c_input) = string.
+
+dump_input_component(MaybeProcLabel,
+        pragma_c_input(Var, _, Dummy, _, Rval, _, _)) =
+    Var ++ dump_maybe_dummy(Dummy) ++ " := " ++
+        dump_rval(MaybeProcLabel, Rval).
+
+:- func dump_output_component(maybe(proc_label), pragma_c_output) = string.
+
+dump_output_component(MaybeProcLabel,
+        pragma_c_output(Lval, _, Dummy, _, Var, _, _)) =
+    dump_lval(MaybeProcLabel, Lval) ++ " := " ++ Var ++
+        dump_maybe_dummy(Dummy).
 
 :- func dump_maybe_dummy(bool) = string.
 
Index: compiler/switch_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/switch_gen.m,v
retrieving revision 1.101
diff -u -b -r1.101 switch_gen.m
--- compiler/switch_gen.m	1 Dec 2006 15:04:22 -0000	1.101
+++ compiler/switch_gen.m	10 Dec 2006 02:50:41 -0000
@@ -17,13 +17,12 @@
 %
 % Currently the following forms of indexing are used:
 %
-% For switches on atomic data types (int, char, enums),
-% if the cases are not sparse, we use the value of the switch variable
-% to index into a jump table.
+% For switches on atomic data types (int, char, enums), if the cases are not
+% sparse, we use the value of the switch variable to index into a jump table.
 %
 % If all the alternative goals for a switch on an atomic data type
 % contain only construction unifications of constants, then we generate
-% a dense lookup table (an array) for each output variable of the switch,
+% a dense lookup table (an array) for the output variables of the switch,
 % rather than a dense jump table, so that executing the switch becomes
 % a matter of doing an array index for each output variable - avoiding
 % the branch overhead of the jump-table.
@@ -35,7 +34,7 @@
 % in the form of a try-me-else chain, a try chain, a dense jump table
 % or a binary search.
 %
-% For switches on strings, we lookup the address to jump to in a hash table,
+% For switches on strings, we look up the address to jump to in a hash table,
 % using open addressing to resolve hash collisions.
 %
 % For all other cases (or if the --smart-indexing option was disabled),
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.28
diff -u -b -r1.28 use_local_vars.m
--- compiler/use_local_vars.m	1 Nov 2006 02:31:10 -0000	1.28
+++ compiler/use_local_vars.m	10 Dec 2006 08:26:23 -0000
@@ -116,7 +116,8 @@
         flatten_basic_blocks(EBBLabelSeq, EBBBlockMap, Instrs1),
         (
             AutoComments = yes,
-            NewComment = comment("\n" ++ dump_livemap(LiveMap)) - "",
+            NewComment = comment("\n" ++
+                dump_livemap(yes(ProcLabel), LiveMap)) - "",
             Comments = Comments0 ++ [NewComment]
         ;
             AutoComments = 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_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/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/stream
cvs diff: Diffing extras/stream/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
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/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
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 tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.303
diff -u -b -r1.303 Mmakefile
--- tests/hard_coded/Mmakefile	17 Nov 2006 05:57:08 -0000	1.303
+++ tests/hard_coded/Mmakefile	10 Dec 2006 09:55:38 -0000
@@ -316,12 +316,14 @@
 # The foreign_type_assertion test is currently meaningful only in C grades.
 # Mutables work properly only in C grades.
 # Trace goal with runtime conditions work properly only in C grades.
+# The lookup_disj test case uses C foreign_proc code to print progress reports.
 ifeq "$(filter il% java%,$(GRADE))" ""
 	C_ONLY_PROGS= \
 		factt \
 		factt_sort_test \
 		float_gv \
 		foreign_type_assertion \
+		lookup_disj \
 		trace_goal_env_1 \
 		trace_goal_env_2
 else
Index: tests/hard_coded/lookup_disj.exp
===================================================================
RCS file: tests/hard_coded/lookup_disj.exp
diff -N tests/hard_coded/lookup_disj.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/lookup_disj.exp	10 Dec 2006 11:22:42 -0000
@@ -0,0 +1,10 @@
+peek 1
+peek 2
+peek 3
+peek 4
+peek 5
+solution 1.10 -   one, 11, a
+solution 2.20 -   two, 12, b
+solution 3.30 - three, 13, c
+solution 4.40 -  four, 14, f(a)
+solution 5.50 -  five, 15, g(a)
Index: tests/hard_coded/lookup_disj.m
===================================================================
RCS file: tests/hard_coded/lookup_disj.m
diff -N tests/hard_coded/lookup_disj.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/lookup_disj.m	10 Dec 2006 05:30:57 -0000
@@ -0,0 +1,67 @@
+% vim: ts=4 sw=4 et ft=mercury
+
+:- module lookup_disj.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module list.
+:- import_module solutions.
+:- import_module pair.
+:- import_module string.
+
+main(!IO) :-
+    solutions(p, Solns),
+    list.foldl(write_solution, Solns, !IO).
+
+:- type t
+    --->    a
+    ;       b
+    ;       c
+    ;       f(t)
+    ;       g(t).
+
+:- type soln
+    --->    soln(
+                pair(float, string),
+                int,
+                t
+            ).
+
+:- pred p(soln::out) is multi.
+
+p(Soln) :-
+    q(Pair, Int0, T),
+    peek_at_solution(Int0, Int),
+    Soln = soln(Pair, Int, T).
+
+:- pred q(pair(float, string)::out, int::out, t::out) is multi.
+
+q(1.1 - "one",    1, a).
+q(2.2 - "two",    2, b).
+q(3.3 - "three",  3, c).
+q(4.4 - "four",   4, f(a)).
+q(5.5 - "five",   5, g(a)).
+
+:- pred peek_at_solution(int::in, int::out) is det.
+
+:- pragma foreign_proc("C",
+    peek_at_solution(Int0::in, Int::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    printf(""peek %ld\\n"", (long) Int0);
+    Int = Int0 + 10;
+").
+
+:- pred write_solution(soln::in, io::di, io::uo) is det.
+
+write_solution(Soln, !IO) :-
+    Soln = soln(Float - Str, Int, T),
+    io.format("solution %.2f - %5s, %d, ", [f(Float), s(Str), i(Int)], !IO),
+    io.write(T, !IO),
+    io.nl(!IO).
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/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