[m-rev.] for post-commit review: more improvements for zm_rcpsp_cpx

Zoltan Somogyi zs at unimelb.edu.au
Wed Mar 28 10:19:28 AEDT 2012


Improve the performance of the compiler further on the zm_rcpsp_cpx.m
stress test, reducing the compilation time of a variant of that test
from 135 seconds to 92. (The biggest remaining bottleneck is the divide_by_set
predicate called from liveness.m; eliminating that bottleneck should get
about a factor of 3 further speedup. I am now working on that.)

These changes make the compiler about 1.2% slower on tools/speedtest.
However, the overall effect of my previous change and this one is still
positive for tools/speedtest. In any case, the big speedup in the worst case
trumps the slight slowdown in average cases.

compiler/equiv_type_hlds.m:
	Avoid quadratic behavior in code that replaces types in insts
	in the uni-modes of unifications by building a cache of the results
	of the test that checks whether an inst may contain a type (most
	don't). In a sequence of unifications in which each unification
	has an argument that was built by a previous unification, this cache
	should mean that most of the time, the test does not need to recurse
	into the inst of the argument.

	Rename some predicates to avoid ambiguity.

	Change some predicates from several clauses (with inconsistent
	argument names in the debugger) to single clauses with explicit
	switches.

compiler/inst_match.m:
	Avoid quadratic behavior in the code that tests whether an inst
	is ground, which is called a lot by common subexpression elimination.
	Both the cause and the fix (a cache of recent test results) are
	similar to equiv_type_hlds.m.

compiler/common.m:
	Delete some unused predicate arguments to make calls slightly faster.

	Remove a double negation.

compiler/simplify.m:
	Conform to the changes to common.m.

compiler/hlds_out_mode.m:
	Add code to print out uni-modes in a structured fashion,
	optionally printing the address in memory at which each inst
	is stored. This was needed to find the information that lead
	to the fix to inst_match.m.

	Move some predicates that are used ONLY for dumping HLDS components
	for debugging, NOT for generating any interface files, here from
	mercury_to_mercury.m. They should have been here in the first place.

	Change the names of some of those predicates to avoid ambiguities.

compiler/mercury_to_mercury.m:
	Remove the predicates moved to hlds_out_mode.m.

	Change the names of some predicates to avoid ambiguities.

	Export some predicates now needed by hlds_out_mode.m.

	Change some predicates from several clauses (with inconsistent
	argument names in the debugger) to single clauses with explicit
	switches.

compiler/hlds_out_goal.m:
	When given the dump option 'y', invoke the new predicates in
	hlds_out_mode.m to print structured uni-modes.

compiler/hlds_out_module.m:
	Fix the code to print inst tables; the old code generated hard-to-read
	output due to missing newlines and odd punctuation.

	Give some predicates more meaningful names.

compiler/hlds_out_pred.m:
	If the dump options call only for the printing of the inst and mode
	tables, do not dump any predicates.

	Give some predicates more meaningful names.

compiler/handle_options.m:
	Add implications about dump options: if the user asks for
	information about a detail, he/she is also asking for the things
	that contain that detail, since otherwise the question of whether to
	print detail would never ever come up. This is needed to implement
	the change to hlds_out_pred.m without repeating many tests at the
	dumping of each predicate (the creation of HLDS dumps is slow enough
	already).

doc/user_guide.texi:
	Document the new dump options.

compiler/intermod.m:
	Change the names of some predicates to avoid ambiguities.

compiler/prog_data.m:
	Fix formatting.

compiler/mode_debug.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
	Conform to the changes above.

Zoltan.

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/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
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/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/common.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/common.m,v
retrieving revision 1.117
diff -u -b -r1.117 common.m
--- compiler/common.m	13 Feb 2012 00:11:34 -0000	1.117
+++ compiler/common.m	26 Mar 2012 17:07:47 -0000
@@ -49,8 +49,7 @@
     % have seen before, replace the construction with an assignment from the
     % variable unified with that cell.
     %
-:- pred common_optimise_unification(unification::in, prog_var::in,
-    unify_rhs::in, unify_mode::in, unify_context::in,
+:- pred common_optimise_unification(unification::in, unify_mode::in,
     hlds_goal_expr::in, hlds_goal_expr::out,
     hlds_goal_info::in, hlds_goal_info::out,
     simplify_info::in, simplify_info::out) is det.
@@ -236,7 +235,7 @@
 
 %---------------------------------------------------------------------------%
 
-common_optimise_unification(Unification0, _Left0, _Right0, Mode, _Context,
+common_optimise_unification(Unification0, Mode,
         GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info) :-
     (
         Unification0 = construct(Var, ConsId, ArgVars, _, _, _, SubInfo),
@@ -281,16 +280,11 @@
     Mode = LVarMode - _,
     simplify_info_get_module_info(!.Info, ModuleInfo),
     mode_get_insts(ModuleInfo, LVarMode, _, Inst),
-    (
         % Don't optimise partially instantiated construction unifications,
         % because it would be tricky to work out how to mode the replacement
         % assignment unifications. In the vast majority of cases, the variable
         % is ground.
-        \+ inst_is_ground(ModuleInfo, Inst)
-    ->
-        GoalExpr = GoalExpr0,
-        GoalInfo = GoalInfo0
-    ;
+    ( inst_is_ground(ModuleInfo, Inst) ->
         TypeCtor = lookup_var_type_ctor(!.Info, Var),
         simplify_info_get_common_info(!.Info, CommonInfo0),
         VarEqv0 = CommonInfo0 ^ var_eqv,
@@ -336,6 +330,9 @@
             Struct = structure(Var, ArgVars),
             record_cell_in_maps(TypeCtor, ConsId, Struct, VarEqv1, !Info)
         )
+    ;
+        GoalExpr = GoalExpr0,
+        GoalInfo = GoalInfo0
     ).
 
 :- pred common_optimise_deconstruct(prog_var::in, cons_id::in,
Index: compiler/equiv_type_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/equiv_type_hlds.m,v
retrieving revision 1.71
diff -u -b -r1.71 equiv_type_hlds.m
--- compiler/equiv_type_hlds.m	13 Feb 2012 00:11:37 -0000	1.71
+++ compiler/equiv_type_hlds.m	26 Mar 2012 15:37:44 -0000
@@ -48,6 +48,7 @@
 :- import_module recompilation.
 
 :- import_module bool.
+:- import_module io.
 :- import_module list.
 :- import_module map.
 :- import_module maybe.
@@ -221,16 +222,16 @@
     inst_table_get_any_insts(!.InstTable, AnyInsts0),
     inst_table_get_shared_insts(!.InstTable, SharedInsts0),
     inst_table_get_mostly_uniq_insts(!.InstTable, MostlyUniqInsts0),
-    replace_in_inst_table(replace_in_maybe_inst_det(EqvMap),
+    replace_in_one_inst_table(replace_in_maybe_inst_det(EqvMap),
         EqvMap, UnifyInsts0, UnifyInsts, !Cache),
     replace_in_merge_inst_table(EqvMap, MergeInsts0, MergeInsts, !Cache),
-    replace_in_inst_table(replace_in_maybe_inst_det(EqvMap),
+    replace_in_one_inst_table(replace_in_maybe_inst_det(EqvMap),
         EqvMap, GroundInsts0, GroundInsts, !Cache),
-    replace_in_inst_table(replace_in_maybe_inst_det(EqvMap),
+    replace_in_one_inst_table(replace_in_maybe_inst_det(EqvMap),
         EqvMap, AnyInsts0, AnyInsts, !Cache),
-    replace_in_inst_table(replace_in_maybe_inst(EqvMap),
+    replace_in_one_inst_table(replace_in_maybe_inst(EqvMap),
         EqvMap, SharedInsts0, SharedInsts, !Cache),
-    replace_in_inst_table(replace_in_maybe_inst(EqvMap),
+    replace_in_one_inst_table(replace_in_maybe_inst(EqvMap),
         EqvMap, MostlyUniqInsts0, MostlyUniqInsts, !.Cache, _),
     inst_table_set_unify_insts(UnifyInsts, !InstTable),
     inst_table_set_merge_insts(MergeInsts, !InstTable),
@@ -239,12 +240,12 @@
     inst_table_set_shared_insts(SharedInsts, !InstTable),
     inst_table_set_mostly_uniq_insts(MostlyUniqInsts, !InstTable).
 
-:- pred replace_in_inst_table(
+:- pred replace_in_one_inst_table(
     pred(T, T, inst_cache, inst_cache)::(pred(in, out, in, out) is det),
     eqv_map::in, map(inst_name, T)::in, map(inst_name, T)::out,
     inst_cache::in, inst_cache::out) is det.
 
-replace_in_inst_table(P, EqvMap, Map0, Map, !Cache) :-
+replace_in_one_inst_table(P, EqvMap, Map0, Map, !Cache) :-
     map.to_assoc_list(Map0, AL0),
     list.map_foldl(
         (pred((Name0 - T0)::in, (Name - T)::out,
@@ -618,19 +619,21 @@
 :- pred replace_in_mode(eqv_map::in, mer_mode::in, mer_mode::out, bool::out,
     tvarset::in, tvarset::out, inst_cache::in, inst_cache::out) is det.
 
-replace_in_mode(EqvMap, Mode0 @ (InstA0 -> InstB0), Mode,
-        Changed, !TVarSet, !Cache) :-
+replace_in_mode(EqvMap, Mode0, Mode, Changed, !TVarSet, !Cache) :-
+    (
+        Mode0 = (InstA0 -> InstB0),
     replace_in_inst(EqvMap, InstA0, InstA, ChangedA, !TVarSet, !Cache),
     replace_in_inst(EqvMap, InstB0, InstB, ChangedB, !TVarSet, !Cache),
     Changed = ChangedA `or` ChangedB,
     ( Changed = yes, Mode = (InstA -> InstB)
     ; Changed = no, Mode = Mode0
-    ).
-replace_in_mode(EqvMap, Mode0 @ user_defined_mode(Name, Insts0), Mode,
-        Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        Mode0 = user_defined_mode(Name, Insts0),
     replace_in_insts(EqvMap, Insts0, Insts, Changed, !TVarSet, !Cache),
     ( Changed = yes, Mode = user_defined_mode(Name, Insts)
     ; Changed = no, Mode = Mode0
+        )
     ).
 
 :- pred replace_in_inst(eqv_map::in, mer_inst::in, mer_inst::out,
@@ -663,33 +666,60 @@
         Changed = no
     ).
 
+%-----------------------------------------------------------------------------%
+
     % Return true if any type may occur inside the given inst.
     %
     % The logic here should be a conservative approximation of the code
     % of replace_in_inst_2.
     %
+    % The no_inline pragma is there to allow lookup_inst_may_occur
+    % and record_inst_may_occur to be inlined in type_may_occur_in_inst
+    % WITHOUT any possibility, however remote, of them being inlined
+    % in procedures outside this module. Since the table they deal with
+    % is local to this module, such cross-module inlining would not work.
+    %
 :- func type_may_occur_in_inst(mer_inst) = bool.
+:- pragma no_inline(type_may_occur_in_inst/1).
 
-type_may_occur_in_inst(any(_, none)) = no.
-type_may_occur_in_inst(any(_, higher_order(_PredInstInfo))) = no.
-    % This is a conservative approximation; the mode in _PredInstInfo
-    % may contain a reference to a type.
-type_may_occur_in_inst(free) = no.
-type_may_occur_in_inst(free(_)) = yes.
-type_may_occur_in_inst(bound(_, BoundInsts)) =
-    type_may_occur_in_bound_insts(BoundInsts).
-type_may_occur_in_inst(ground(_, none)) = no.
-type_may_occur_in_inst(ground(_, higher_order(_PredInstInfo))) = yes.
-    % This is a conservative approximation; the mode in _PredInstInfo
-    % may contain a reference to a type.
-type_may_occur_in_inst(not_reached) = no.
-type_may_occur_in_inst(inst_var(_)) = no.
-type_may_occur_in_inst(constrained_inst_vars(_, CInst)) =
-    type_may_occur_in_inst(CInst).
-type_may_occur_in_inst(defined_inst(_)) = yes.
-    % This is also a conservative approximation.
-type_may_occur_in_inst(abstract_inst(_, Insts)) =
-    type_may_occur_in_insts(Insts).
+type_may_occur_in_inst(Inst) = MayOccur :-
+    (
+        ( Inst = free
+        ; Inst = ground(_, none)
+        ; Inst = any(_, none)
+        ; Inst = not_reached
+        ; Inst = inst_var(_)
+        ),
+        MayOccur = no
+    ;
+        % The last three entries here are conservative approximations;
+        % e.g. the _PredInstInfo may contain a reference to a type.
+        ( Inst = free(_)
+        ; Inst = ground(_, higher_order(_PredInstInfo))
+        ; Inst = any(_, higher_order(_PredInstInfo))
+        ; Inst = defined_inst(_)
+        ),
+        MayOccur = yes
+    ;
+        Inst = bound(_, BoundInsts),
+        promise_pure (
+            semipure lookup_inst_may_occur(Inst, Found, OldMayOccur),
+            (
+                Found = yes,
+                MayOccur = OldMayOccur
+            ;
+                Found = no,
+                MayOccur = type_may_occur_in_bound_insts(BoundInsts),
+                impure record_inst_may_occur(Inst, MayOccur)
+            )
+        )
+    ;
+        Inst = abstract_inst(_, ArgInsts),
+        MayOccur = type_may_occur_in_insts(ArgInsts)
+    ;
+        Inst = constrained_inst_vars(_, CInst),
+        MayOccur = type_may_occur_in_inst(CInst)
+    ).
 
     % Return true if any type may occur inside any of the given bound insts.
     %
@@ -699,11 +729,12 @@
 :- func type_may_occur_in_bound_insts(list(bound_inst)) = bool.
 
 type_may_occur_in_bound_insts([]) = no.
-type_may_occur_in_bound_insts([bound_functor(_, Insts) | BoundInsts]) =
+type_may_occur_in_bound_insts([BoundInst | BoundInsts]) = MayOccur :-
+    BoundInst = bound_functor(_, Insts),
     ( type_may_occur_in_insts(Insts) = yes ->
-        yes
+        MayOccur = yes
     ;
-        type_may_occur_in_bound_insts(BoundInsts)
+        MayOccur = type_may_occur_in_bound_insts(BoundInsts)
     ).
 
     % Return true if any type may occur inside any of the given insts.
@@ -721,12 +752,111 @@
         type_may_occur_in_insts(Insts)
     ).
 
+%-----------------------------------------------------------------------------%
+%
+% The expansion of terms by the superhomogeneous transformation generates code
+% that looks like this:
+%
+%   V1 = [],
+%   V2 = e1,
+%   V3 = [V2 | V1],
+%   V4 = e2,
+%   V5 = [V3 | V4]
+%
+% The insts on those unifications will contain insts from earlier unifications.
+% For example, the inst on the unification building V5 will give V5 an inst
+% that contains the insts of V3 and V4.
+%
+% If there are N elements in a list, testing the insts of the N variables
+% representing the N cons cells in the list would ordinarily take O(N^2) steps.
+% Since N could be very large, this is disastrous.
+%
+% We avoid quadratic performance by caching the results of recent calls
+% to type_may_occur_in_inst for insts that are susceptible to this problem.
+% This way, the test on the inst of e.g. V5 will find the results of the tests
+% on the insts of V3 and V4 already available. This reduces the overall
+% complexity of testing the insts of those N variables to O(n).
+%
+% The downsides of this cache include the costs of the lookups, and
+% the fact that it keeps the cached insts alive.
+
+:- pragma foreign_decl("C",
+"
+typedef struct {
+    MR_Word     tice_inst_addr;
+    MR_Word     tice_may_occur;
+} TypeInInstCacheEntry;
+
+#define TYPE_IN_INST_CACHE_SIZE 1307
+
+/*
+** Every entry should be implicitly initialized to zeros. Since zero is
+** not a valid address for an inst, uninitialized entries cannot be mistaken
+** for filled-in entries.
+*/
+
+static  TypeInInstCacheEntry  type_in_inst_cache[TYPE_IN_INST_CACHE_SIZE];
+").
+
+    % Look up Inst in the cache. If it is there, return Found = yes
+    % and set MayOccur. Otherwise, return Found = no.
+    %
+:- semipure pred lookup_inst_may_occur(mer_inst::in,
+    bool::out, bool::out) is det.
+
+:- pragma foreign_proc("C",
+    lookup_inst_may_occur(Inst::in, Found::out, MayOccur::out),
+    [will_not_call_mercury, promise_semipure],
+"
+    MR_Unsigned hash;
+
+    hash = (MR_Unsigned) Inst;
+    hash = hash >> MR_LOW_TAG_BITS;
+    hash = hash % TYPE_IN_INST_CACHE_SIZE;
+
+    if (type_in_inst_cache[hash].tice_inst_addr == Inst) {
+        Found = MR_BOOL_YES;
+        MayOccur = type_in_inst_cache[hash].tice_may_occur;
+    } else {
+        Found = MR_BOOL_NO;
+    }
+").
+
+    % Record the result for Inst in the cache.
+    %
+:- impure pred record_inst_may_occur(mer_inst::in, bool::in) is det.
+
+:- pragma foreign_proc("C",
+    record_inst_may_occur(Inst::in, MayOccur::in),
+    [will_not_call_mercury],
+"
+    MR_Unsigned hash;
+
+    hash = (MR_Unsigned) Inst;
+    hash = hash >> MR_LOW_TAG_BITS;
+    hash = hash % TYPE_IN_INST_CACHE_SIZE;
+    /* We overwrite any existing entry in the slot. */
+    type_in_inst_cache[hash].tice_inst_addr = Inst;
+    type_in_inst_cache[hash].tice_may_occur = MayOccur;
+").
+
+%-----------------------------------------------------------------------------%
+
 :- pred replace_in_inst_2(eqv_map::in, mer_inst::in, mer_inst::out, bool::out,
     tvarset::in, tvarset::out, inst_cache::in, inst_cache::out) is det.
 
-replace_in_inst_2(_, any(_, none) @ Inst, Inst, no, !TVarSet, !Cache).
-replace_in_inst_2(EqvMap, any(Uniq, higher_order(PredInstInfo0)) @ Inst0, Inst,
-        Changed, !TVarSet, !Cache) :-
+replace_in_inst_2(EqvMap, Inst0, Inst, Changed, !TVarSet, !Cache) :-
+    (
+        ( Inst0 = free
+        ; Inst0 = ground(_, none)
+        ; Inst0 = any(_, none)
+        ; Inst0 = not_reached
+        ; Inst0 = inst_var(_)
+        ),
+        Inst = Inst0,
+        Changed = no
+    ;
+        Inst0 = any(Uniq, higher_order(PredInstInfo0)),
     PredInstInfo0 = pred_inst_info(PorF, Modes0, MaybeArgRegs, Det),
     replace_in_modes(EqvMap, Modes0, Modes, Changed, !TVarSet, !Cache),
     (
@@ -736,24 +866,23 @@
     ;
         Changed = no,
         Inst = Inst0
-    ).
-replace_in_inst_2(_, free @ Inst, Inst, no, !TVarSet, !Cache).
-replace_in_inst_2(EqvMap, free(Type0) @ Inst0, Inst, Changed,
-        !TVarSet, !Cache) :-
-    equiv_type.replace_in_type(EqvMap, Type0, Type, Changed, !TVarSet, no, _),
+        )
+    ;
+        Inst0 = free(Type0),
+        equiv_type.replace_in_type(EqvMap, Type0, Type, Changed, !TVarSet,
+            no, _),
     ( Changed = yes, Inst = free(Type)
     ; Changed = no, Inst = Inst0
-    ).
-replace_in_inst_2(EqvMap, bound(Uniq, BoundInsts0) @ Inst0, Inst,
-        Changed, !TVarSet, !Cache) :-
-    replace_in_bound_insts(EqvMap, BoundInsts0, BoundInsts, Changed, !TVarSet,
-        !Cache),
+        )
+    ;
+        Inst0 = bound(Uniq, BoundInsts0),
+        replace_in_bound_insts(EqvMap, BoundInsts0, BoundInsts, Changed,
+            !TVarSet, !Cache),
     ( Changed = yes, Inst = bound(Uniq, BoundInsts)
     ; Changed = no, Inst = Inst0
-    ).
-replace_in_inst_2(_, ground(_, none) @ Inst, Inst, no, !TVarSet, !Cache).
-replace_in_inst_2(EqvMap, ground(Uniq, higher_order(PredInstInfo0)) @ Inst0,
-        Inst, Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        Inst0 = ground(Uniq, higher_order(PredInstInfo0)),
     PredInstInfo0 = pred_inst_info(PorF, Modes0, MaybeArgRegs, Det),
     replace_in_modes(EqvMap, Modes0, Modes, Changed, !TVarSet, !Cache),
     (
@@ -763,93 +892,94 @@
     ;
         Changed = no,
         Inst = Inst0
-    ).
-replace_in_inst_2(_, not_reached @ Inst, Inst, no, !TVarSet, !Cache).
-replace_in_inst_2(_, inst_var(_) @ Inst, Inst, no, !TVarSet, !Cache).
-replace_in_inst_2(EqvMap, constrained_inst_vars(Vars, CInst0) @ Inst0, Inst,
-        Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        Inst0 = constrained_inst_vars(Vars, CInst0),
     replace_in_inst(EqvMap, CInst0, CInst, Changed, !TVarSet, !Cache),
     ( Changed = yes, Inst = constrained_inst_vars(Vars, CInst)
     ; Changed = no, Inst = Inst0
-    ).
-replace_in_inst_2(EqvMap, Inst0 @ defined_inst(InstName0), Inst,
-         Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        Inst0 = defined_inst(InstName0),
     replace_in_inst_name(EqvMap, InstName0, InstName, Changed,
         !TVarSet, !Cache),
     ( Changed = yes, Inst = defined_inst(InstName)
     ; Changed = no, Inst = Inst0
-    ).
-replace_in_inst_2(EqvMap, Inst0 @ abstract_inst(Name, Insts0), Inst,
-        Changed, !TVarSet, !Cache) :-
-    replace_in_insts(EqvMap, Insts0, Insts, Changed, !TVarSet, !Cache),
-    ( Changed = yes, Inst = abstract_inst(Name, Insts)
+        )
+    ;
+        Inst0 = abstract_inst(Name, ArgInsts0),
+        replace_in_insts(EqvMap, ArgInsts0, ArgInsts, Changed,
+            !TVarSet, !Cache),
+        ( Changed = yes, Inst = abstract_inst(Name, ArgInsts)
     ; Changed = no, Inst = Inst0
+        )
     ).
 
 :- pred replace_in_inst_name(eqv_map::in, inst_name::in, inst_name::out,
     bool::out, tvarset::in, tvarset::out,
     inst_cache::in, inst_cache::out) is det.
 
-replace_in_inst_name(EqvMap, InstName0 @ user_inst(Name, Insts0), InstName,
-        Changed, !TVarSet, !Cache) :-
+replace_in_inst_name(EqvMap, InstName0, InstName, Changed, !TVarSet, !Cache) :-
+    (
+        InstName0 = user_inst(Name, Insts0),
     replace_in_insts(EqvMap, Insts0, Insts, Changed, !TVarSet, !Cache),
     ( Changed = yes, InstName = user_inst(Name, Insts)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap, InstName0 @ merge_inst(InstA0, InstB0), InstName,
-        Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = merge_inst(InstA0, InstB0),
     replace_in_inst(EqvMap, InstA0, InstA, ChangedA, !TVarSet, !Cache),
     replace_in_inst(EqvMap, InstB0, InstB, ChangedB, !TVarSet, !Cache),
     Changed = ChangedA `or` ChangedB,
     ( Changed = yes, InstName = merge_inst(InstA, InstB)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap,
-        InstName0 @ unify_inst(Live, InstA0, InstB0, Real),
-        InstName, Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = unify_inst(Live, InstA0, InstB0, Real),
     replace_in_inst(EqvMap, InstA0, InstA, ChangedA, !TVarSet, !Cache),
     replace_in_inst(EqvMap, InstB0, InstB, ChangedB, !TVarSet, !Cache),
     Changed = ChangedA `or` ChangedB,
     ( Changed = yes, InstName = unify_inst(Live, InstA, InstB, Real)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap, InstName0 @ ground_inst(Name0, Live, Uniq, Real),
-        InstName, Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = ground_inst(Name0, Live, Uniq, Real),
     replace_in_inst_name(EqvMap, Name0, Name, Changed, !TVarSet, !Cache),
     ( Changed = yes, InstName = ground_inst(Name, Live, Uniq, Real)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap, InstName0 @ any_inst(Name0, Live, Uniq, Real),
-        InstName, Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = any_inst(Name0, Live, Uniq, Real),
     replace_in_inst_name(EqvMap, Name0, Name, Changed, !TVarSet, !Cache),
     ( Changed = yes, InstName = any_inst(Name, Live, Uniq, Real)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap, InstName0 @ shared_inst(Name0), InstName,
-         Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = shared_inst(Name0),
     replace_in_inst_name(EqvMap, Name0, Name, Changed, !TVarSet, !Cache),
     ( Changed = yes, InstName = shared_inst(Name)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap, InstName0 @ mostly_uniq_inst(Name0),
-        InstName, Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = mostly_uniq_inst(Name0),
     replace_in_inst_name(EqvMap, Name0, Name, Changed, !TVarSet, !Cache),
     ( Changed = yes, InstName = mostly_uniq_inst(Name)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap, InstName0 @ typed_ground(Uniq, Type0), InstName,
-        Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = typed_ground(Uniq, Type0),
     replace_in_type(EqvMap, Type0, Type, Changed, !TVarSet, no, _),
     ( Changed = yes, InstName = typed_ground(Uniq, Type)
     ; Changed = no, InstName = InstName0
-    ).
-replace_in_inst_name(EqvMap, InstName0 @ typed_inst(Type0, Name0),
-        InstName, Changed, !TVarSet, !Cache) :-
+        )
+    ;
+        InstName0 = typed_inst(Type0, Name0),
     replace_in_type(EqvMap, Type0, Type, TypeChanged, !TVarSet, no, _),
     replace_in_inst_name(EqvMap, Name0, Name, Changed0, !TVarSet, !Cache),
     Changed = TypeChanged `or` Changed0,
     ( Changed = yes, InstName = typed_inst(Type, Name)
     ; Changed = no, InstName = InstName0
+        )
     ).
 
 :- pred replace_in_bound_insts(eqv_map::in, list(bound_inst)::in,
@@ -884,6 +1014,7 @@
 
     % We hash-cons (actually map-cons) insts created by this pass
     % to avoid losing sharing.
+    %
 :- type inst_cache == map(mer_inst, mer_inst).
 
 :- pred hash_cons_inst(mer_inst::in, mer_inst::out,
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.377
diff -u -b -r1.377 handle_options.m
--- compiler/handle_options.m	13 Feb 2012 00:11:38 -0000	1.377
+++ compiler/handle_options.m	27 Mar 2012 21:03:48 -0000
@@ -383,13 +383,67 @@
         true
     ;
         DumpAliasOption = string(DumpAlias),
-        convert_dump_alias(DumpAlias, DumpOptions)
+        convert_dump_alias(DumpAlias, AliasDumpOptions)
     ->
-        map.set(dump_hlds_options, string(DumpOptions), !OptionTable)
+        map.set(dump_hlds_options, string(AliasDumpOptions), !OptionTable)
     ;
         add_error("Invalid argument to option `--hlds-dump-alias'.", !Errors)
     ),
 
+    some [!DumpOptions] (
+        lookup_string_option(!.OptionTable, dump_hlds_options, !:DumpOptions),
+        % If we want structured insts in arg-modes, then we want arg-modes.
+        (
+            string.contains_char(!.DumpOptions, 'y'),
+            not string.contains_char(!.DumpOptions, 'a')
+        ->
+            !:DumpOptions = "a" ++ !.DumpOptions
+        ;
+            true
+        ),
+        % If we want arg-modes, then we want the unifications they apply to.
+        (
+            string.contains_char(!.DumpOptions, 'a'),
+            not string.contains_char(!.DumpOptions, 'u')
+        ->
+            !:DumpOptions = "u" ++ !.DumpOptions
+        ;
+            true
+        ),
+        % If we want any of the things that decorate predicates or the goals
+        % inside predicates, then we want the predicates themselves.
+        (
+            ( string.contains_char(!.DumpOptions, 'A')
+            ; string.contains_char(!.DumpOptions, 'B')
+            ; string.contains_char(!.DumpOptions, 'D')
+            ; string.contains_char(!.DumpOptions, 'G')
+            ; string.contains_char(!.DumpOptions, 'P')
+            ; string.contains_char(!.DumpOptions, 'R')
+            ; string.contains_char(!.DumpOptions, 'S')
+            ; string.contains_char(!.DumpOptions, 'b')
+            ; string.contains_char(!.DumpOptions, 'c')
+            ; string.contains_char(!.DumpOptions, 'd')
+            ; string.contains_char(!.DumpOptions, 'f')
+            ; string.contains_char(!.DumpOptions, 'g')
+            ; string.contains_char(!.DumpOptions, 'i')
+            ; string.contains_char(!.DumpOptions, 'l')
+            ; string.contains_char(!.DumpOptions, 'm')
+            ; string.contains_char(!.DumpOptions, 'n')
+            ; string.contains_char(!.DumpOptions, 'p')
+            ; string.contains_char(!.DumpOptions, 's')
+            ; string.contains_char(!.DumpOptions, 't')
+            ; string.contains_char(!.DumpOptions, 'u')
+            ; string.contains_char(!.DumpOptions, 'z')
+            ),
+            not string.contains_char(!.DumpOptions, 'x')
+        ->
+            !:DumpOptions = "x" ++ !.DumpOptions
+        ;
+            true
+        ),
+        map.set(dump_hlds_options, string(!.DumpOptions), !OptionTable)
+    ),
+
     map.lookup(!.OptionTable, c_compiler_type, C_CompilerType0),
     (
         C_CompilerType0 = string(C_CompilerTypeStr),
Index: compiler/hlds_out_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out_goal.m,v
retrieving revision 1.14
diff -u -b -r1.14 hlds_out_goal.m
--- compiler/hlds_out_goal.m	13 Feb 2012 00:11:40 -0000	1.14
+++ compiler/hlds_out_goal.m	27 Mar 2012 07:37:03 -0000
@@ -870,10 +870,8 @@
     write_unify_rhs_2(Info, RHS, ModuleInfo, VarSet, InstVarSet,
         AppendVarNums, Indent, Follow, VarType, TypeQual, !IO),
     (
-        (
-            string.contains_char(DumpOptions, 'u')
-        ;
-            string.contains_char(DumpOptions, 'p')
+        ( string.contains_char(DumpOptions, 'u')
+        ; string.contains_char(DumpOptions, 'p')
         )
     ->
         (
@@ -1219,10 +1217,17 @@
         io.write_string(")\n", !IO),
         DumpOptions = Info ^ hoi_dump_hlds_options,
         ( string.contains_char(DumpOptions, 'a') ->
+            ( string.contains_char(DumpOptions, 'y') ->
+                write_indent(Indent, !IO),
+                io.write_string("% arg-modes\n", !IO),
+                mercury_output_structured_uni_mode_list(ArgModes, Indent,
+                    do_incl_addr, InstVarSet, !IO)
+            ;
             write_indent(Indent, !IO),
             io.write_string("% arg-modes ", !IO),
             mercury_output_uni_mode_list(ArgModes, InstVarSet, !IO),
             io.write_string("\n", !IO)
+            )
         ;
             true
         )
Index: compiler/hlds_out_mode.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out_mode.m,v
retrieving revision 1.5
diff -u -b -r1.5 hlds_out_mode.m
--- compiler/hlds_out_mode.m	13 Feb 2012 00:11:40 -0000	1.5
+++ compiler/hlds_out_mode.m	27 Mar 2012 10:51:48 -0000
@@ -43,14 +43,48 @@
 
 %-----------------------------------------------------------------------------%
 
+:- type incl_addr
+    --->    do_not_incl_addr
+    ;       do_incl_addr.
+
+    % Output a list of insts in a format that makes them easy to read
+    % but may not be valid Mercury.
+    %
+:- pred mercury_output_structured_inst_list(list(mer_inst)::in, int::in,
+    incl_addr::in, inst_varset::in, io::di, io::uo) is det.
+:- func mercury_structured_inst_list_to_string(list(mer_inst), int,
+    incl_addr, inst_varset) = string.
+
+    % Output an inst in a format that makes it easy to read
+    % but may not be valid Mercury.
+    % The `int' argument specifies the indentation level.
+    % (These routines are used with `--debug-modes'.)
+    %
+:- pred mercury_output_structured_inst(mer_inst::in, int::in,
+    incl_addr::in, inst_varset::in, io::di, io::uo) is det.
+:- func mercury_structured_inst_to_string(mer_inst, int,
+    incl_addr, inst_varset) = string.
+
+%-----------------------------------------------------------------------------%
+
+:- pred mercury_output_structured_uni_mode(uni_mode::in, int::in,
+    incl_addr::in, inst_varset::in, io::di, io::uo) is det.
+:- func mercury_structured_uni_mode_to_string(uni_mode, int, incl_addr,
+    inst_varset) = string.
+
+:- pred mercury_output_structured_uni_mode_list(list(uni_mode)::in, int::in,
+    incl_addr::in, inst_varset::in, io::di, io::uo) is det.
+:- func mercury_structured_uni_mode_list_to_string(list(uni_mode), int,
+    incl_addr, inst_varset) = string.
+
+%-----------------------------------------------------------------------------%
+
 :- pred mercury_output_uni_mode(uni_mode::in, inst_varset::in,
     io::di, io::uo) is det.
-
 :- func mercury_uni_mode_to_string(uni_mode, inst_varset) = string.
 
 :- pred mercury_output_uni_mode_list(list(uni_mode)::in, inst_varset::in,
     io::di, io::uo) is det.
-
 :- func mercury_uni_mode_list_to_string(list(uni_mode), inst_varset) = string.
 
 %-----------------------------------------------------------------------------%
@@ -77,9 +111,11 @@
 :- import_module parse_tree.prog_io_util.
 :- import_module parse_tree.prog_util.
 
+:- import_module int.
 :- import_module pair.
 :- import_module require.
 :- import_module set.
+:- import_module string.
 :- import_module term.
 :- import_module varset.
 
@@ -375,52 +411,392 @@
 
 %-----------------------------------------------------------------------------%
 
-mercury_output_uni_mode_list(UniModes, VarSet, !IO) :-
-    mercury_format_uni_mode_list(UniModes, VarSet, !IO).
+mercury_output_structured_uni_mode_list(Insts, Indent, InclAddr, InstVarSet,
+        !IO) :-
+    mercury_format_structured_uni_mode_list(Insts, 1, Indent, InclAddr,
+        InstVarSet, !IO).
+
+mercury_structured_uni_mode_list_to_string(Insts, Indent, InclAddr, InstVarSet)
+        = String :-
+    mercury_format_structured_uni_mode_list(Insts, 1, Indent, InclAddr,
+        InstVarSet, "", String).
+
+:- pred mercury_format_structured_uni_mode_list(list(uni_mode)::in, int::in,
+    int::in, incl_addr::in, inst_varset::in, U::di, U::uo) is det <= output(U).
+
+mercury_format_structured_uni_mode_list([], _, _, _, _, !U).
+mercury_format_structured_uni_mode_list([UniMode | UniModes], ArgNum, Indent,
+        InclAddr, InstVarSet, !U) :-
+    mercury_format_tabs(Indent, !U),
+    add_string("argument ", !U),
+    add_int(ArgNum, !U),
+    add_string(":\n", !U),
+    mercury_format_structured_uni_mode(UniMode, Indent,
+        InclAddr, InstVarSet, !U),
+    mercury_format_structured_uni_mode_list(UniModes, ArgNum +1, Indent,
+        InclAddr, InstVarSet, !U).
+
+%-----------------------------------------------------------------------------%
+
+mercury_output_structured_uni_mode(Inst, Indent, InclAddr, InstVarSet,
+        !IO) :-
+    mercury_format_structured_uni_mode(Inst, Indent, InclAddr, InstVarSet,
+        !IO).
+
+mercury_structured_uni_mode_to_string(Inst, Indent, InclAddr, InstVarSet)
+        = String :-
+    mercury_format_structured_uni_mode(Inst, Indent, InclAddr, InstVarSet,
+        "", String).
+
+:- pred mercury_format_structured_uni_mode(uni_mode::in, int::in,
+    incl_addr::in, inst_varset::in, U::di, U::uo) is det <= output(U).
+
+mercury_format_structured_uni_mode(UniMode, Indent, InclAddr, InstVarSet,
+        !U) :-
+    UniMode = (InstA1 - InstB1 -> InstA2 - InstB2),
+    get_inst_addr(InstA1, InstA1Addr),
+    get_inst_addr(InstA2, InstA2Addr),
+    get_inst_addr(InstB1, InstB1Addr),
+    get_inst_addr(InstB2, InstB2Addr),
+
+    mercury_format_tabs(Indent, !U),
+    add_string("old lhs inst:\n", !U),
+    mercury_format_structured_inst(InstA1, Indent, InclAddr, InstVarSet, !U),
+
+    mercury_format_tabs(Indent, !U),
+    ( InstB1Addr = InstA1Addr ->
+        % We have printed the old lhs inst.
+        add_string("old rhs inst: same as old lhs inst\n", !U)
+    ;
+        add_string("old rhs inst:\n", !U),
+        mercury_format_structured_inst(InstB1, Indent, InclAddr,
+            InstVarSet, !U)
+    ),
+
+    mercury_format_tabs(Indent, !U),
+    ( InstA2Addr = InstA1Addr ->
+        % We have printed the old lhs inst.
+        add_string("new lhs inst: unchanged\n", !U)
+    ; InstA2Addr = InstB1Addr ->
+        % We have printed or described the old rhs inst.
+        add_string("new lhs inst: changed to old rhs inst\n", !U)
+    ;
+        add_string("new lhs inst:\n", !U),
+        mercury_format_structured_inst(InstA2, Indent, InclAddr,
+            InstVarSet, !U)
+    ),
+
+    mercury_format_tabs(Indent, !U),
+    ( InstB2Addr = InstB1Addr ->
+        % We have printed or described the old rhs inst.
+        add_string("new rhs inst: unchanged\n", !U)
+    ; InstB2Addr = InstA2Addr ->
+        % We have printed or described the new lhs inst.
+        add_string("new rhs inst: changed to new lhs inst\n", !U)
+    ;
+        add_string("new rhs inst:\n", !U),
+        mercury_format_structured_inst(InstB2, Indent, InclAddr,
+            InstVarSet, !U)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+mercury_output_structured_inst_list(Insts, Indent, InclAddr, InstVarSet, !IO) :-
+    mercury_format_structured_inst_list(Insts, Indent, InclAddr, InstVarSet,
+        !IO).
+
+mercury_structured_inst_list_to_string(Insts, Indent, InclAddr, InstVarSet)
+        = String :-
+    mercury_format_structured_inst_list(Insts, Indent, InclAddr, InstVarSet,
+        "", String).
+
+:- pred mercury_format_structured_inst_list(list(mer_inst)::in, int::in,
+    incl_addr::in, inst_varset::in, U::di, U::uo) is det <= output(U).
+
+mercury_format_structured_inst_list([], _, _, _, !U).
+mercury_format_structured_inst_list([Inst | Insts], Indent, InclAddr,
+        InstVarSet, !U) :-
+    mercury_format_structured_inst(Inst, Indent, InclAddr, InstVarSet, !U),
+    mercury_format_structured_inst_list(Insts, Indent, InclAddr,
+        InstVarSet, !U).
+
+%-----------------------------------------------------------------------------%
+
+mercury_output_structured_inst(Inst, Indent, InclAddr, InstVarSet, !U) :-
+    mercury_format_structured_inst(Inst, Indent, InclAddr, InstVarSet, !U).
+
+mercury_structured_inst_to_string(Inst, Indent, InclAddr, InstVarSet)
+        = String :-
+    mercury_format_structured_inst(Inst, Indent, InclAddr, InstVarSet,
+        "", String).
+
+:- pred mercury_format_structured_inst(mer_inst::in, int::in, incl_addr::in,
+    inst_varset::in, U::di, U::uo) is det <= output(U).
+
+mercury_format_structured_inst(Inst, Indent, InclAddr, InstVarSet, !U) :-
+    mercury_format_tabs(Indent, !U),
+    (
+        InclAddr = do_not_incl_addr
+    ;
+        InclAddr = do_incl_addr,
+        get_inst_addr(Inst, InstAddr),
+        InstAddrStr = string.format("%x", [i(InstAddr)]),
+        add_string(InstAddrStr, !U),
+        add_string(": ", !U)
+    ),
+    (
+        Inst = any(Uniq, HOInstInfo),
+        (
+            HOInstInfo = higher_order(PredInstInfo),
+            mercury_format_any_pred_inst_info(Uniq, PredInstInfo,
+                InstVarSet, !U)
+        ;
+            HOInstInfo = none,
+            mercury_format_any_uniqueness(Uniq, !U)
+        ),
+        add_string("\n", !U)
+    ;
+        Inst = free,
+        add_string("free\n", !U)
+    ;
+        Inst = free(_T),
+        add_string("free(with some type)\n", !U)
+    ;
+        Inst = bound(Uniq, BoundInsts),
+        mercury_format_uniqueness(Uniq, "bound", !U),
+        add_string("(\n", !U),
+        mercury_format_structured_bound_insts(BoundInsts, Indent, InclAddr,
+            InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ;
+        Inst = ground(Uniq, HOInstInfo),
+        (
+            HOInstInfo = higher_order(PredInstInfo),
+            mercury_format_ground_pred_inst_info(Uniq, PredInstInfo,
+                InstVarSet, !U)
+        ;
+            HOInstInfo = none,
+            mercury_format_uniqueness(Uniq, "ground", !U)
+        ),
+        add_string("\n", !U)
+    ;
+        Inst = inst_var(Var),
+        mercury_format_var(InstVarSet, no, Var, !U),
+        add_string("\n", !U)
+    ;
+        Inst = constrained_inst_vars(Vars, ConstrainedInst),
+        mercury_format_constrained_inst_vars(Vars, ConstrainedInst,
+            simple_inst_info(InstVarSet), !U),
+        add_string("\n", !U)
+    ;
+        Inst = abstract_inst(Name, Args),
+        mercury_format_structured_inst_name(user_inst(Name, Args), 0,
+            InclAddr, InstVarSet, !U)
+    ;
+        Inst = defined_inst(InstName),
+        mercury_format_structured_inst_name(InstName, 0,
+            InclAddr, InstVarSet, !U)
+    ;
+        Inst = not_reached,
+        add_string("not_reached\n", !U)
+    ).
+
+:- pred mercury_format_structured_bound_insts(list(bound_inst)::in, int::in,
+    incl_addr::in, inst_varset::in, U::di, U::uo) is det <= output(U).
+
+mercury_format_structured_bound_insts([], _, _, _, !U).
+mercury_format_structured_bound_insts([BoundInst | BoundInsts],
+        Indent0, InclAddr, InstVarSet, !U) :-
+    BoundInst = bound_functor(ConsId, Args),
+    Indent1 = Indent0 + 1,
+    Indent2 = Indent1 + 1,
+    (
+        Args = [],
+        mercury_format_tabs(Indent1, !U),
+        mercury_format_cons_id(ConsId, needs_brackets, !U),
+        add_string("\n", !U)
+    ;
+        Args = [_ | _],
+        mercury_format_tabs(Indent1, !U),
+        mercury_format_cons_id(ConsId, does_not_need_brackets, !U),
+        add_string("(\n", !U),
+        mercury_format_structured_inst_list(Args, Indent2, InclAddr,
+            InstVarSet, !U),
+        mercury_format_tabs(Indent1, !U),
+        add_string(")\n", !U)
+    ),
+    (
+        BoundInsts = []
+    ;
+        BoundInsts = [_ | _],
+        mercury_format_tabs(Indent0, !U),
+        add_string(";\n", !U),
+        mercury_format_structured_bound_insts(BoundInsts, Indent0,
+            InclAddr, InstVarSet, !U)
+    ).
+
+:- pred get_inst_addr(mer_inst::in, int::out) is det.
+
+:- pragma foreign_proc("C",
+    get_inst_addr(Inst::in, InstAddr::out),
+    [will_not_call_mercury, promise_pure],
+"
+    InstAddr = Inst;
+").
+
+%-----------------------------------------------------------------------------%
+
+:- pred mercury_format_structured_inst_name(inst_name::in, int::in,
+    incl_addr::in, inst_varset::in, U::di, U::uo) is det <= output(U).
 
-mercury_uni_mode_list_to_string(UniModes, VarSet) = String :-
-    mercury_format_uni_mode_list(UniModes, VarSet, "", String).
+mercury_format_structured_inst_name(InstName, Indent, InclAddr, InstVarSet,
+        !U) :-
+    (
+        InstName = user_inst(Name, Args),
+        (
+            Args = [],
+            mercury_format_tabs(Indent, !U),
+            mercury_format_bracketed_sym_name(Name, !U)
+        ;
+            Args = [_ | _],
+            mercury_format_tabs(Indent, !U),
+            mercury_format_sym_name(Name, !U),
+            add_string("(\n", !U),
+            mercury_format_structured_inst_list(Args, Indent + 1, InclAddr,
+                InstVarSet, !U),
+            mercury_format_tabs(Indent, !U),
+            add_string(")\n", !U)
+        )
+    ;
+        InstName = merge_inst(InstA, InstB),
+        mercury_format_tabs(Indent, !U),
+        add_string("$merge_inst(\n", !U),
+        mercury_format_structured_inst_list([InstA, InstB], Indent + 1,
+            InclAddr, InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ;
+        InstName = shared_inst(SubInstName),
+        add_string("$shared_inst(\n", !U),
+        mercury_format_structured_inst_name(SubInstName, Indent + 1,
+            InclAddr, InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ;
+        InstName = mostly_uniq_inst(SubInstName),
+        mercury_format_tabs(Indent, !U),
+        add_string("$mostly_uniq_inst(\n", !U),
+        mercury_format_structured_inst_name(SubInstName, Indent + 1,
+            InclAddr, InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ;
+        InstName = unify_inst(IsLive, InstA, InstB, Real),
+        mercury_format_tabs(Indent, !U),
+        add_string("$unify(", !U),
+        mercury_format_is_live_comma(IsLive, !U),
+        mercury_format_real_comma(Real, !U),
+        add_string("\n", !U),
+        mercury_format_structured_inst_list([InstA, InstB], Indent + 1,
+            InclAddr, InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ;
+        InstName = ground_inst(SubInstName, IsLive, Uniq, Real),
+        mercury_format_tabs(Indent, !U),
+        add_string("$ground(", !U),
+        mercury_format_is_live_comma(IsLive, !U),
+        mercury_format_real_comma(Real, !U),
+        mercury_format_uniqueness(Uniq, "shared", !U),
+        add_string(",\n", !U),
+        mercury_format_structured_inst_name(SubInstName, Indent + 1,
+            InclAddr, InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ;
+        InstName = any_inst(SubInstName, IsLive, Uniq, Real),
+        mercury_format_tabs(Indent, !U),
+        add_string("$any(", !U),
+        mercury_format_is_live_comma(IsLive, !U),
+        mercury_format_real_comma(Real, !U),
+        mercury_format_uniqueness(Uniq, "shared", !U),
+        add_string(",\n", !U),
+        mercury_format_structured_inst_name(SubInstName, Indent + 1,
+            InclAddr, InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ;
+        InstName = typed_ground(Uniqueness, Type),
+        mercury_format_tabs(Indent, !U),
+        add_string("$typed_ground(", !U),
+        mercury_format_uniqueness(Uniqueness, "shared", !U),
+        add_string(", ", !U),
+        varset.init(TypeVarSet),
+        mercury_format_type(TypeVarSet, no, Type, !U),
+        add_string(")\n", !U)
+    ;
+        InstName = typed_inst(Type, SubInstName),
+        mercury_format_tabs(Indent, !U),
+        add_string("$typed_inst(", !U),
+        varset.init(TypeVarSet),
+        mercury_format_type(TypeVarSet, no, Type, !U),
+        add_string(",\n", !U),
+        mercury_format_structured_inst_name(SubInstName, Indent + 1,
+            InclAddr, InstVarSet, !U),
+        mercury_format_tabs(Indent, !U),
+        add_string(")\n", !U)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+mercury_output_uni_mode_list(UniModes, InstVarSet, !IO) :-
+    mercury_format_uni_mode_list(UniModes, InstVarSet, !IO).
+
+mercury_uni_mode_list_to_string(UniModes, InstVarSet) = String :-
+    mercury_format_uni_mode_list(UniModes, InstVarSet, "", String).
 
 :- pred mercury_format_uni_mode_list(list(uni_mode)::in, inst_varset::in,
     U::di, U::uo) is det <= output(U).
 
-mercury_format_uni_mode_list([], _VarSet, !IO).
-mercury_format_uni_mode_list([Mode | Modes], VarSet, !IO) :-
-    mercury_format_uni_mode(Mode, VarSet, !IO),
+mercury_format_uni_mode_list([], _InstVarSet, !IO).
+mercury_format_uni_mode_list([Mode | Modes], InstVarSet, !IO) :-
+    mercury_format_uni_mode(Mode, InstVarSet, !IO),
     (
         Modes = [],
         true
     ;
         Modes = [_ | _],
         add_string(", ", !IO),
-        mercury_format_uni_mode_list(Modes, VarSet, !IO)
+        mercury_format_uni_mode_list(Modes, InstVarSet, !IO)
     ).
 
-mercury_output_uni_mode(UniMode, VarSet, !IO) :-
-    mercury_format_uni_mode(UniMode, VarSet, !IO).
+mercury_output_uni_mode(UniMode, InstVarSet, !IO) :-
+    mercury_format_uni_mode(UniMode, InstVarSet, !IO).
 
-mercury_uni_mode_to_string(UniMode, VarSet) = String :-
-    mercury_format_uni_mode(UniMode, VarSet, "", String).
+mercury_uni_mode_to_string(UniMode, InstVarSet) = String :-
+    mercury_format_uni_mode(UniMode, InstVarSet, "", String).
 
 :- pred mercury_format_uni_mode(uni_mode::in, inst_varset::in,
     U::di, U::uo) is det <= output(U).
 
-mercury_format_uni_mode((InstA1 - InstB1 -> InstA2 - InstB2), VarSet, !IO) :-
-    mercury_format_mode((InstA1 -> InstA2), simple_inst_info(VarSet), !IO),
+mercury_format_uni_mode(UniMode, InstVarSet, !IO) :-
+    UniMode = (InstA1 - InstB1 -> InstA2 - InstB2),
+    mercury_format_mode((InstA1 -> InstA2), simple_inst_info(InstVarSet), !IO),
     add_string(" = ", !IO),
-    mercury_format_mode((InstB1 -> InstB2), simple_inst_info(VarSet), !IO).
+    mercury_format_mode((InstB1 -> InstB2), simple_inst_info(InstVarSet), !IO).
 
 %-----------------------------------------------------------------------------%
 
-mercury_output_expanded_inst(Inst, VarSet, ModuleInfo, !IO) :-
+mercury_output_expanded_inst(Inst, InstVarSet, ModuleInfo, !IO) :-
     set.init(Expansions),
     mercury_format_inst(Inst,
-        expanded_inst_info(VarSet, ModuleInfo, Expansions), !IO).
+        expanded_inst_info(InstVarSet, ModuleInfo, Expansions), !IO).
 
-mercury_expanded_inst_to_string(Inst, VarSet, ModuleInfo) = String :-
+mercury_expanded_inst_to_string(Inst, InstVarSet, ModuleInfo) = String :-
     set.init(Expansions),
     mercury_format_inst(Inst,
-        expanded_inst_info(VarSet, ModuleInfo, Expansions), "", String).
+        expanded_inst_info(InstVarSet, ModuleInfo, Expansions), "", String).
 
 :- pred mercury_format_expanded_defined_inst(inst_name::in,
     expanded_inst_info::in, U::di, U::uo) is det <= output(U).
@@ -451,10 +827,10 @@
     --->    expanded_inst_info(
                 eii_varset      :: inst_varset,
                 eii_module_info :: module_info,
+
+                % The set of already-expanded insts; further occurrences
+                % of these will be output as "...".
                 eii_expansions  :: set(inst_name)
-                                % the set of already-expanded insts;
-                                % further occurrences of these will
-                                % be output as "..."
             ).
 
 %-----------------------------------------------------------------------------%
Index: compiler/hlds_out_module.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out_module.m,v
retrieving revision 1.8
diff -u -b -r1.8 hlds_out_module.m
--- compiler/hlds_out_module.m	5 Jul 2011 03:34:32 -0000	1.8
+++ compiler/hlds_out_module.m	26 Mar 2012 09:02:34 -0000
@@ -110,9 +110,9 @@
             true
         ),
         ( string.contains_char(DumpOptions, 'M') ->
-            write_insts(Indent, InstTable, !IO),
+            write_inst_table(Indent, InstTable, !IO),
             io.write_string("\n", !IO),
-            write_modes(Indent, ModeTable, !IO),
+            write_mode_table(Indent, ModeTable, !IO),
             io.write_string("\n", !IO)
         ;
             true
@@ -175,13 +175,13 @@
     write_indent(Indent, !IO),
     io.write_string("%-------- Types --------\n", !IO),
     get_all_type_ctor_defns(TypeTable, TypeAssocList),
-    write_types_2(Info, Indent, TypeAssocList, !IO).
+    write_type_table_entries(Info, Indent, TypeAssocList, !IO).
 
-:- pred write_types_2(hlds_out_info::in, int::in,
+:- pred write_type_table_entries(hlds_out_info::in, int::in,
     assoc_list(type_ctor, hlds_type_defn)::in, io::di, io::uo) is det.
 
-write_types_2(_, _, [], !IO).
-write_types_2(Info, Indent, [TypeCtor - TypeDefn | Types], !IO) :-
+write_type_table_entries(_, _, [], !IO).
+write_type_table_entries(Info, Indent, [TypeCtor - TypeDefn | Types], !IO) :-
     hlds_data.get_type_defn_tvarset(TypeDefn, TVarSet),
     hlds_data.get_type_defn_tparams(TypeDefn, TypeParams),
     hlds_data.get_type_defn_body(TypeDefn, TypeBody),
@@ -223,7 +223,8 @@
     write_type_name(TypeCtor, !IO),
     write_type_params(TVarSet, TypeParams, !IO),
     write_type_body(Info, TypeCtor, TypeBody, Indent + 1, TVarSet, !IO),
-    write_types_2(Info, Indent, Types, !IO).
+
+    write_type_table_entries(Info, Indent, Types, !IO).
 
 :- pred write_type_params(tvarset::in, list(type_param)::in,
     io::di, io::uo) is det.
@@ -237,17 +238,17 @@
     Ps = [_ | _],
     io.write_string("(", !IO),
     mercury_output_var(TVarSet, no, P, !IO),
-    write_type_params_2(TVarSet, Ps, !IO).
+    write_type_params_loop(TVarSet, Ps, !IO),
+    io.write_string(")", !IO).
 
-:- pred write_type_params_2(tvarset::in, list(type_param)::in,
+:- pred write_type_params_loop(tvarset::in, list(type_param)::in,
     io::di, io::uo) is det.
 
-write_type_params_2(_TVarSet, [], !IO) :-
-    io.write_string(")", !IO).
-write_type_params_2(TVarSet, [P | Ps], !IO) :-
+write_type_params_loop(_TVarSet, [], !IO).
+write_type_params_loop(TVarSet, [P | Ps], !IO) :-
     io.write_string(", ", !IO),
     mercury_output_var(TVarSet, no, P, !IO),
-    write_type_params_2(TVarSet, Ps, !IO).
+    write_type_params_loop(TVarSet, Ps, !IO).
 
 :- pred write_type_body(hlds_out_info::in, type_ctor::in, hlds_type_body::in,
     int::in, tvarset::in, io::di, io::uo) is det.
@@ -370,13 +371,13 @@
     io.write_char('\t', !IO),
     write_ctor(TypeCtor, Ctor, TVarSet, TagValues, !IO),
     io.write_string("\n", !IO),
-    write_constructors_2(TypeCtor, Indent, TVarSet, Ctors, TagValues, !IO).
+    write_constructors_loop(TypeCtor, Indent, TVarSet, Ctors, TagValues, !IO).
 
-:- pred write_constructors_2(type_ctor::in, int::in, tvarset::in,
+:- pred write_constructors_loop(type_ctor::in, int::in, tvarset::in,
     list(constructor)::in, cons_tag_values::in, io::di, io::uo) is det.
 
-write_constructors_2(_TypeCtor, _Indent, _TVarSet, [], _, !IO).
-write_constructors_2(TypeCtor, Indent, TVarSet, [Ctor | Ctors], TagValues,
+write_constructors_loop(_TypeCtor, _Indent, _TVarSet, [], _, !IO).
+write_constructors_loop(TypeCtor, Indent, TVarSet, [Ctor | Ctors], TagValues,
         !IO) :-
     write_indent(Indent, !IO),
     io.write_string(";\t", !IO),
@@ -386,7 +387,8 @@
     ;
         Ctors = [_ | _],
         io.write_string("\n", !IO),
-        write_constructors_2(TypeCtor, Indent, TVarSet, Ctors, TagValues, !IO)
+        write_constructors_loop(TypeCtor, Indent, TVarSet, Ctors, TagValues,
+            !IO)
     ).
 
 :- pred write_ctor(type_ctor::in, constructor::in, tvarset::in,
@@ -595,9 +597,9 @@
 % Write out the inst table.
 %
 
-:- pred write_insts(int::in, inst_table::in, io::di, io::uo) is det.
+:- pred write_inst_table(int::in, inst_table::in, io::di, io::uo) is det.
 
-write_insts(Indent, InstTable, !IO) :-
+write_inst_table(Indent, InstTable, !IO) :-
     write_indent(Indent, !IO),
     io.write_string("%-------- Insts --------\n", !IO),
 
@@ -618,7 +620,7 @@
 write_user_inst(Indent, InstId - InstDefn, !IO) :-
     InstId = inst_id(InstName, _InstArity),
     write_indent(Indent, !IO),
-    io.format(":- inst %s:", [s(sym_name_to_string(InstName))], !IO),
+    io.format("\n:- inst %s", [s(sym_name_to_string(InstName))], !IO),
     InstDefn = hlds_inst_defn(InstVarSet, InstParams, InstBody,
         _Context, _Status),
     (
@@ -636,7 +638,8 @@
         InstBody = eqv_inst(EqvInst),
         io.write_string(":\n", !IO),
         write_indent(Indent, !IO),
-        mercury_output_inst(EqvInst, InstVarSet, !IO)
+        mercury_output_inst(EqvInst, InstVarSet, !IO),
+        io.write_string("\n", !IO)
     ).
 
 :- pred write_inst_params(inst_var::in, list(inst_var)::in, inst_varset::in,
@@ -658,9 +661,9 @@
 % Write out the mode table.
 %
 
-:- pred write_modes(int::in, mode_table::in, io::di, io::uo) is det.
+:- pred write_mode_table(int::in, mode_table::in, io::di, io::uo) is det.
 
-write_modes(Indent, _ModeTable, !IO) :-
+write_mode_table(Indent, _ModeTable, !IO) :-
     % XXX fix this up.
     write_indent(Indent, !IO),
     io.write_string("%-------- Modes --------\n", !IO),
Index: compiler/hlds_out_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out_pred.m,v
retrieving revision 1.10
diff -u -b -r1.10 hlds_out_pred.m
--- compiler/hlds_out_pred.m	13 Feb 2012 00:11:40 -0000	1.10
+++ compiler/hlds_out_pred.m	27 Mar 2012 07:39:29 -0000
@@ -322,15 +322,15 @@
 write_clauses(Info, Indent, ModuleInfo, PredId, VarSet, AppendVarNums,
         HeadVars, PredOrFunc, Clauses0, TypeQual, !IO) :-
     HeadVarList = proc_arg_vector_to_list(HeadVars),
-    write_clauses_2(Info, Indent, ModuleInfo, PredId, VarSet,
+    write_clauses_loop(Info, Indent, ModuleInfo, PredId, VarSet,
         AppendVarNums, HeadVarList, PredOrFunc, Clauses0, TypeQual, 1, !IO).
 
-:- pred write_clauses_2(hlds_out_info::in, int::in,
+:- pred write_clauses_loop(hlds_out_info::in, int::in,
     module_info::in, pred_id::in, prog_varset::in, bool::in,
     list(prog_var)::in, pred_or_func::in, list(clause)::in, maybe_vartypes::in,
     int::in, io::di, io::uo) is det.
 
-write_clauses_2(Info, Indent, ModuleInfo, PredId, VarSet, AppendVarNums,
+write_clauses_loop(Info, Indent, ModuleInfo, PredId, VarSet, AppendVarNums,
         HeadVars, PredOrFunc, Clauses0, TypeQual, ClauseNum, !IO) :-
     (
         Clauses0 = [Clause | Clauses],
@@ -342,7 +342,7 @@
         write_clause(Info, Indent, ModuleInfo, PredId, VarSet,
             AppendVarNums, HeadTerms, PredOrFunc, Clause,
             UseDeclaredModes, TypeQual, !IO),
-        write_clauses_2(Info, Indent, ModuleInfo, PredId, VarSet,
+        write_clauses_loop(Info, Indent, ModuleInfo, PredId, VarSet,
             AppendVarNums, HeadVars, PredOrFunc, Clauses, TypeQual,
             ClauseNum + 1, !IO)
     ;
@@ -523,14 +523,14 @@
     io.write_string("% variable types map ", !IO),
     io.format("(%d entries):\n", [i(NumVarTypes)], !IO),
     map.keys(VarTypes, Vars),
-    write_var_types_2(Vars, Indent, VarSet, AppendVarNums, VarTypes, TVarSet,
-        !IO).
+    write_var_types_loop(Vars, Indent, VarSet, AppendVarNums, VarTypes,
+        TVarSet, !IO).
 
-:- pred write_var_types_2(list(prog_var)::in, int::in, prog_varset::in,
+:- pred write_var_types_loop(list(prog_var)::in, int::in, prog_varset::in,
     bool::in, vartypes::in, tvarset::in, io::di, io::uo) is det.
 
-write_var_types_2([], _, _, _, _, _, !IO).
-write_var_types_2([Var | Vars], Indent, VarSet, AppendVarNums, VarTypes,
+write_var_types_loop([], _, _, _, _, _, !IO).
+write_var_types_loop([Var | Vars], Indent, VarSet, AppendVarNums, VarTypes,
         TypeVarSet, !IO) :-
     map.lookup(VarTypes, Var, Type),
     write_indent(Indent, !IO),
@@ -543,7 +543,7 @@
     io.write_string(": ", !IO),
     mercury_output_type(TypeVarSet, AppendVarNums, Type, !IO),
     io.write_string("\n", !IO),
-    write_var_types_2(Vars, Indent, VarSet, AppendVarNums, VarTypes,
+    write_var_types_loop(Vars, Indent, VarSet, AppendVarNums, VarTypes,
         TypeVarSet, !IO).
 
 :- pred write_rtti_varmaps(int::in, bool::in, rtti_varmaps::in,
@@ -658,13 +658,13 @@
         Indent, !IO) :-
     write_indent(Indent, !IO),
     io.write_string("% untuple:\n", !IO),
-    map.foldl(write_untuple_info_2(VarSet, AppendVarNums, Indent), UntupleMap,
-        !IO).
+    map.foldl(write_untuple_info_loop(VarSet, AppendVarNums, Indent),
+        UntupleMap, !IO).
 
-:- pred write_untuple_info_2(prog_varset::in, bool::in, int::in,
+:- pred write_untuple_info_loop(prog_varset::in, bool::in, int::in,
     prog_var::in, prog_vars::in, io::di, io::uo) is det.
 
-write_untuple_info_2(VarSet, AppendVarNums, Indent, OldVar, NewVars, !IO) :-
+write_untuple_info_loop(VarSet, AppendVarNums, Indent, OldVar, NewVars, !IO) :-
     write_indent(Indent, !IO),
     io.write_string("%\t", !IO),
     mercury_output_var(VarSet, AppendVarNums, OldVar, !IO),
@@ -701,20 +701,20 @@
         PredInfo, !IO) :-
     pred_info_get_procedures(PredInfo, ProcTable),
     ProcIds = pred_info_procids(PredInfo),
-    write_procs_2(Info, ProcIds, AppendVarNums, ModuleInfo, Indent, PredId,
+    write_procs_loop(Info, ProcIds, AppendVarNums, ModuleInfo, Indent, PredId,
         ImportStatus, ProcTable, !IO).
 
-:- pred write_procs_2(hlds_out_info::in, list(proc_id)::in, bool::in,
+:- pred write_procs_loop(hlds_out_info::in, list(proc_id)::in, bool::in,
     module_info::in, int::in, pred_id::in, import_status::in, proc_table::in,
     io::di, io::uo) is det.
 
-write_procs_2(_, [], _, _, _, _, _, _, !IO).
-write_procs_2(Info, [ProcId | ProcIds], AppendVarNums, ModuleInfo, Indent,
+write_procs_loop(_, [], _, _, _, _, _, _, !IO).
+write_procs_loop(Info, [ProcId | ProcIds], AppendVarNums, ModuleInfo, Indent,
         PredId, ImportStatus, ProcTable, !IO) :-
     map.lookup(ProcTable, ProcId, ProcInfo),
     write_proc(Info, Indent, AppendVarNums, ModuleInfo, PredId, ProcId,
         ImportStatus, ProcInfo, !IO),
-    write_procs_2(Info, ProcIds, AppendVarNums, ModuleInfo, Indent,
+    write_procs_loop(Info, ProcIds, AppendVarNums, ModuleInfo, Indent,
         PredId, ImportStatus, ProcTable, !IO).
 
 write_proc(Info, Indent, AppendVarNums, ModuleInfo, PredId, ProcId,
@@ -748,6 +748,8 @@
     proc_info_get_var_name_remap(Proc, VarNameRemap),
     Indent1 = Indent + 1,
 
+    DumpOptions = Info ^ hoi_dump_hlds_options,
+    ( string.contains_char(DumpOptions, 'x') ->
     write_indent(Indent1, !IO),
     io.write_string("% pred id ", !IO),
     pred_id_to_int(PredId, PredInt),
@@ -763,7 +765,6 @@
     io.write_string(determinism_to_string(InferredDeterminism), !IO),
     io.write_string("):\n", !IO),
 
-    DumpOptions = Info ^ hoi_dump_hlds_options,
     ( string.contains_char(DumpOptions, 't') ->
         write_indent(Indent, !IO),
         io.write_string("% Arg size properties: ", !IO),
@@ -803,8 +804,8 @@
             MaybeStructureReuse = yes(StructureReuse),
             StructureReuse =
                 structure_reuse_domain_and_status(ReuseAs, _ReuseStatus),
-            dump_maybe_structure_reuse_domain(VarSet, TVarSet, yes(ReuseAs),
-                !IO)
+                dump_maybe_structure_reuse_domain(VarSet, TVarSet,
+                    yes(ReuseAs), !IO)
         ;
             MaybeStructureReuse = no,
             dump_maybe_structure_reuse_domain(VarSet, TVarSet, no, !IO)
@@ -929,7 +930,8 @@
         VarNameRemapList = [VarNameRemapHead | VarNameRemapTail],
         write_indent(Indent, !IO),
         io.write_string("% var name remap: ", !IO),
-        write_var_name_remap(VarNameRemapHead, VarNameRemapTail, VarSet, !IO),
+            write_var_name_remap(VarNameRemapHead, VarNameRemapTail, VarSet,
+                !IO),
         io.nl(!IO)
     ),
 
@@ -945,7 +947,8 @@
         PredOrFunc = pf_function,
         pred_args_to_func_args(HeadModes, FuncHeadModes, RetHeadMode),
         mercury_output_func_mode_decl(ModeVarSet, unqualified(PredName),
-            FuncHeadModes, RetHeadMode, DeclaredDeterminism, ModeContext, !IO)
+                FuncHeadModes, RetHeadMode, DeclaredDeterminism, ModeContext,
+                !IO)
     ),
 
     (
@@ -993,6 +996,9 @@
         io.write_string(" :-\n", !IO),
         write_goal(Info, Goal, ModuleInfo, VarSet, AppendVarNums,
             Indent1, ".\n", !IO)
+        )
+    ;
+        true
     ).
 
 %-----------------------------------------------------------------------------%
@@ -1195,13 +1201,13 @@
 write_constraint_map(Indent, VarSet, ConstraintMap, AppendVarNums, !IO) :-
     write_indent(Indent, !IO),
     io.write_string("% Constraint Map:\n", !IO),
-    map.foldl(write_constraint_map_2(Indent, VarSet, AppendVarNums),
+    map.foldl(write_constraint_map_entry(Indent, VarSet, AppendVarNums),
         ConstraintMap, !IO).
 
-:- pred write_constraint_map_2(int::in, tvarset::in, bool::in,
+:- pred write_constraint_map_entry(int::in, tvarset::in, bool::in,
     constraint_id::in, prog_constraint::in, io::di, io::uo) is det.
 
-write_constraint_map_2(Indent, VarSet, AppendVarNums, ConstraintId,
+write_constraint_map_entry(Indent, VarSet, AppendVarNums, ConstraintId,
         ProgConstraint, !IO) :-
     write_indent(Indent, !IO),
     io.write_string("% ", !IO),
Index: compiler/inst_match.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/inst_match.m,v
retrieving revision 1.95
diff -u -b -r1.95 inst_match.m
--- compiler/inst_match.m	13 Feb 2012 00:11:40 -0000	1.95
+++ compiler/inst_match.m	27 Mar 2012 12:06:13 -0000
@@ -15,12 +15,12 @@
 % rafe: XXX The following comment needs revising in the light of
 % the new solver types design.
 %
-% The handling of `any' insts is not complete.  (See also inst_util.m) It
-% would be nice to allow `free' to match `any', but right now we only allow a
-% few special cases of that.  The reason is that although the mode analysis
-% would be pretty straight-forward, generating the correct code is quite a bit
-% trickier.  modes.m would have to be changed to handle the implicit
-% conversions from `free'/`bound'/`ground' to `any' at
+% The handling of `any' insts is not complete. (See also inst_util.m) It would
+% be nice to allow `free' to match `any', but right now we only allow a few
+% special cases of that. The reason is that although the mode analysis would be
+% pretty straight-forward, generating the correct code is quite a bit trickier.
+% modes.m would have to be changed to handle the implicit conversions from
+% `free'/`bound'/`ground' to `any' at
 %
 %   (1) procedure calls (this is just an extension of implied modes)
 %       currently we support only the easy cases of this
@@ -326,6 +326,7 @@
 
 :- import_module bool.
 :- import_module int.
+:- import_module io.
 :- import_module list.
 :- import_module map.
 :- import_module maybe.
@@ -1354,11 +1355,131 @@
 
 %-----------------------------------------------------------------------------%
 
+inst_is_ground(ModuleInfo, Inst) :-
     % inst_is_ground succeeds iff the inst passed is `ground' or the
     % equivalent. Abstract insts are not considered ground.
     %
-inst_is_ground(ModuleInfo, Inst) :-
-    inst_is_ground(ModuleInfo, no, Inst).
+    promise_pure (
+        semipure lookup_inst_is_ground(Inst, Found, OldIsGround),
+        (
+            Found = yes,
+            trace [compiletime(flag("inst-is-ground-perf")), io(!IO)] (
+                io.write_string("inst_is_ground hit\n", !IO)
+            ),
+            % Succeed if OldIsGround = yes, fail if OldIsGround = no.
+            OldIsGround = yes
+        ;
+            Found = no,
+            trace [compiletime(flag("inst-is-ground-perf")), io(!IO)] (
+                io.write_string("inst_is_ground miss\n", !IO)
+            ),
+            ( inst_is_ground(ModuleInfo, no, Inst) ->
+                impure record_inst_is_ground(Inst, yes)
+                % Succeed.
+            ;
+                impure record_inst_is_ground(Inst, no),
+                fail
+            )
+        )
+    ).
+
+%-----------------------------------------------------------------------------%
+%
+% The expansion of terms by the superhomogeneous transformation generates code
+% that looks like this:
+%
+%   V1 = [],
+%   V2 = e1,
+%   V3 = [V2 | V1],
+%   V4 = e2,
+%   V5 = [V3 | V4]
+%
+% The insts on those unifications will contain insts from earlier unifications.
+% For example, the inst on the unification building V5 will give V5 an inst
+% that contains the insts of V3 and V4.
+%
+% If there are N elements in a list, testing the insts of the N variables
+% representing the N cons cells in the list would ordinarily take O(N^2) steps.
+% Since N could be very large, this is disastrous.
+%
+% We avoid quadratic performance by caching the results of recent calls
+% to inst_is_ground for insts that are susceptible to this problem.
+% This way, the test on the inst of e.g. V5 will find the results of the tests
+% on the insts of V3 and V4 already available. This reduces the overall
+% complexity of testing the insts of those N variables to O(n).
+%
+% The downsides of this cache include the costs of the lookups, and
+% the fact that it keeps the cached insts alive.
+%
+% Note that we do not need to record the ModuleInfo argument of inst_is_ground,
+% since it is needed only to interpret insts that need access to the mode
+% tables. If we get a result for an inst with one ModuleInfo, we should get
+% the exact same result with any later ModuleInfo. The conservative nature
+% of the Boehm collector means that an inst address recorded in the cache
+% will always point to the original inst; the address cannot be reused until
+% the cache entry is itself reused.
+
+:- pragma foreign_decl("C",
+"
+typedef struct {
+    MR_Word     iig_inst_addr;
+    MR_Word     iig_is_ground;
+} InstIsGroundCacheEntry;
+
+#define INST_IS_GROUND_CACHE_SIZE 1307
+
+/*
+** Every entry should be implicitly initialized to zeros. Since zero is
+** not a valid address for an inst, uninitialized entries cannot be mistaken
+** for filled-in entries.
+*/
+
+static  InstIsGroundCacheEntry  inst_is_ground_cache[INST_IS_GROUND_CACHE_SIZE];
+").
+
+    % Look up Inst in the cache. If it is there, return Found = yes
+    % and set MayOccur. Otherwise, return Found = no.
+    %
+:- semipure pred lookup_inst_is_ground(mer_inst::in,
+    bool::out, bool::out) is det.
+
+:- pragma foreign_proc("C",
+    lookup_inst_is_ground(Inst::in, Found::out, IsGround::out),
+    [will_not_call_mercury, promise_semipure],
+"
+    MR_Unsigned hash;
+
+    hash = (MR_Unsigned) Inst;
+    hash = hash >> MR_LOW_TAG_BITS;
+    hash = hash % INST_IS_GROUND_CACHE_SIZE;
+
+    if (inst_is_ground_cache[hash].iig_inst_addr == Inst) {
+        Found = MR_BOOL_YES;
+        IsGround = inst_is_ground_cache[hash].iig_is_ground;
+    } else {
+        Found = MR_BOOL_NO;
+    }
+").
+
+    % Record the result for Inst in the cache.
+    %
+:- impure pred record_inst_is_ground(mer_inst::in, bool::in) is det.
+
+:- pragma foreign_proc("C",
+    record_inst_is_ground(Inst::in, IsGround::in),
+    [will_not_call_mercury],
+"
+    MR_Unsigned hash;
+
+    hash = (MR_Unsigned) Inst;
+    hash = hash >> MR_LOW_TAG_BITS;
+    hash = hash % INST_IS_GROUND_CACHE_SIZE;
+    /* We overwrite any existing entry in the slot. */
+    inst_is_ground_cache[hash].iig_inst_addr = Inst;
+    inst_is_ground_cache[hash].iig_is_ground = IsGround;
+").
+
+%-----------------------------------------------------------------------------%
 
 :- pred inst_is_ground(module_info::in, maybe(mer_type)::in, mer_inst::in)
     is semidet.
@@ -1405,8 +1526,8 @@
     maybe_any_to_bound(MaybeType, ModuleInfo, Uniq, HOInstInfo, Inst),
     inst_is_ground_1(ModuleInfo, MaybeType, Inst, !Expansions).
 
-    % inst_is_ground_or_any succeeds iff the inst passed is `ground',
-    % `any', or the equivalent.  Fails for abstract insts.
+    % inst_is_ground_or_any succeeds iff the inst passed is `ground', `any',
+    % or the equivalent. Fails for abstract insts.
     %
 inst_is_ground_or_any(ModuleInfo, Inst) :-
     set.init(Expansions0),
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.268
diff -u -b -r1.268 intermod.m
--- compiler/intermod.m	13 Feb 2012 00:11:40 -0000	1.268
+++ compiler/intermod.m	26 Mar 2012 09:02:34 -0000
@@ -1294,7 +1294,7 @@
         % XXX Modules could and should be reduced to the set of modules
         % that are actually needed by the items being written.
         io.write_string(":- use_module ", !IO),
-        write_modules(Modules, !IO)
+        intermod_write_modules(Modules, !IO)
     ;
         Modules = []
     ),
@@ -1309,11 +1309,11 @@
     MercInfo = merc_out_info_disable_line_numbers(MercInfo0),
     OutInfo = OutInfo0 ^ hoi_mercury_to_mercury := MercInfo,
 
-    write_types(OutInfo, Types, !IO),
-    write_insts(OutInfo, ModuleInfo, !IO),
-    write_modes(OutInfo, ModuleInfo, !IO),
-    write_classes(OutInfo, ModuleInfo, !IO),
-    write_instances(OutInfo, Instances, !IO),
+    intermod_write_types(OutInfo, Types, !IO),
+    intermod_write_insts(OutInfo, ModuleInfo, !IO),
+    intermod_write_modes(OutInfo, ModuleInfo, !IO),
+    intermod_write_classes(OutInfo, ModuleInfo, !IO),
+    intermod_write_instances(OutInfo, Instances, !IO),
 
     % Disable verbose dumping of clauses.
     OutInfoForPreds = OutInfo ^ hoi_dump_hlds_options := "",
@@ -1331,13 +1331,13 @@
     ;
         WriteHeader = no
     ),
-    write_pred_decls(ModuleInfo, PredDecls, !IO),
-    write_preds(OutInfoForPreds, ModuleInfo, Preds, !IO).
+    intermod_write_pred_decls(ModuleInfo, PredDecls, !IO),
+    intermod_write_preds(OutInfoForPreds, ModuleInfo, Preds, !IO).
 
-:- pred write_modules(list(module_name)::in, io::di, io::uo) is det.
+:- pred intermod_write_modules(list(module_name)::in, io::di, io::uo) is det.
 
-write_modules([], !IO).
-write_modules([Module | Rest], !IO) :-
+intermod_write_modules([], !IO).
+intermod_write_modules([Module | Rest], !IO) :-
     mercury_output_bracketed_sym_name(Module, !IO),
     (
         Rest = [],
@@ -1345,28 +1345,30 @@
     ;
         Rest = [_ | _],
         io.write_string(", ", !IO),
-        write_modules(Rest, !IO)
+        intermod_write_modules(Rest, !IO)
     ).
 
-:- pred write_types(hlds_out_info::in,
+:- pred intermod_write_types(hlds_out_info::in,
     assoc_list(type_ctor, hlds_type_defn)::in, io::di, io::uo) is det.
 
-write_types(OutInfo, Types, !IO) :-
-    list.foldl(write_type(OutInfo), Types, !IO).
+intermod_write_types(OutInfo, Types, !IO) :-
+    list.foldl(intermod_write_type(OutInfo), Types, !IO).
 
-:- pred write_type(hlds_out_info::in, pair(type_ctor, hlds_type_defn)::in,
-    io::di, io::uo) is det.
+:- pred intermod_write_type(hlds_out_info::in,
+    pair(type_ctor, hlds_type_defn)::in, io::di, io::uo) is det.
 
-write_type(OutInfo, TypeCtor - TypeDefn, !IO) :-
+intermod_write_type(OutInfo, TypeCtor - TypeDefn, !IO) :-
     hlds_data.get_type_defn_tvarset(TypeDefn, VarSet),
     hlds_data.get_type_defn_tparams(TypeDefn, Args),
     hlds_data.get_type_defn_body(TypeDefn, Body),
     hlds_data.get_type_defn_context(TypeDefn, Context),
     TypeCtor = type_ctor(Name, Arity),
     (
-        Body = hlds_du_type(Ctors, _, _, _, MaybeUserEqComp, MaybeDirectArgCtors,
+        Body = hlds_du_type(Ctors, _, _, _, MaybeUserEqComp,
+            MaybeDirectArgCtors,
             _, _, _),
-        TypeBody = parse_tree_du_type(Ctors, MaybeUserEqComp, MaybeDirectArgCtors)
+        TypeBody = parse_tree_du_type(Ctors, MaybeUserEqComp,
+            MaybeDirectArgCtors)
     ;
         Body = hlds_eqv_type(EqvType),
         TypeBody = parse_tree_eqv_type(EqvType)
@@ -1503,18 +1505,19 @@
     ),
     !:Values = [SymName - ForeignTag | !.Values].
 
-:- pred write_modes(hlds_out_info::in, module_info::in, io::di, io::uo) is det.
+:- pred intermod_write_modes(hlds_out_info::in, module_info::in,
+    io::di, io::uo) is det.
 
-write_modes(OutInfo, ModuleInfo, !IO) :-
+intermod_write_modes(OutInfo, ModuleInfo, !IO) :-
     module_info_get_name(ModuleInfo, ModuleName),
     module_info_get_mode_table(ModuleInfo, Modes),
     mode_table_get_mode_defns(Modes, ModeDefns),
-    map.foldl(write_mode(OutInfo, ModuleName), ModeDefns, !IO).
+    map.foldl(intermod_write_mode(OutInfo, ModuleName), ModeDefns, !IO).
 
-:- pred write_mode(hlds_out_info::in, module_name::in, mode_id::in,
+:- pred intermod_write_mode(hlds_out_info::in, module_name::in, mode_id::in,
     hlds_mode_defn::in, io::di, io::uo) is det.
 
-write_mode(OutInfo, ModuleName, ModeId, ModeDefn, !IO) :-
+intermod_write_mode(OutInfo, ModuleName, ModeId, ModeDefn, !IO) :-
     ModeId = mode_id(SymName, _Arity),
     ModeDefn = hlds_mode_defn(Varset, Args, eqv_mode(Mode), Context,
         ImportStatus),
@@ -1531,19 +1534,20 @@
         true
     ).
 
-:- pred write_insts(hlds_out_info::in, module_info::in, io::di, io::uo) is det.
+:- pred intermod_write_insts(hlds_out_info::in, module_info::in,
+    io::di, io::uo) is det.
 
-write_insts(OutInfo, ModuleInfo, !IO) :-
+intermod_write_insts(OutInfo, ModuleInfo, !IO) :-
     module_info_get_name(ModuleInfo, ModuleName),
     module_info_get_inst_table(ModuleInfo, Insts),
     inst_table_get_user_insts(Insts, UserInsts),
     user_inst_table_get_inst_defns(UserInsts, InstDefns),
-    map.foldl(write_inst(OutInfo, ModuleName), InstDefns, !IO).
+    map.foldl(intermod_write_inst(OutInfo, ModuleName), InstDefns, !IO).
 
-:- pred write_inst(hlds_out_info::in, module_name::in, inst_id::in,
+:- pred intermod_write_inst(hlds_out_info::in, module_name::in, inst_id::in,
     hlds_inst_defn::in, io::di, io::uo) is det.
 
-write_inst(OutInfo, ModuleName, InstId, InstDefn, !IO) :-
+intermod_write_inst(OutInfo, ModuleName, InstId, InstDefn, !IO) :-
     InstId = inst_id(SymName, _Arity),
     InstDefn = hlds_inst_defn(Varset, Args, Body, Context, ImportStatus),
     (
@@ -1566,18 +1570,18 @@
         true
     ).
 
-:- pred write_classes(hlds_out_info::in, module_info::in,
+:- pred intermod_write_classes(hlds_out_info::in, module_info::in,
     io::di, io::uo) is det.
 
-write_classes(OutInfo, ModuleInfo, !IO) :-
+intermod_write_classes(OutInfo, ModuleInfo, !IO) :-
     module_info_get_name(ModuleInfo, ModuleName),
     module_info_get_class_table(ModuleInfo, Classes),
-    map.foldl(write_class(OutInfo, ModuleName), Classes, !IO).
+    map.foldl(intermod_write_class(OutInfo, ModuleName), Classes, !IO).
 
-:- pred write_class(hlds_out_info::in, module_name::in, class_id::in,
+:- pred intermod_write_class(hlds_out_info::in, module_name::in, class_id::in,
     hlds_class_defn::in, io::di, io::uo) is det.
 
-write_class(OutInfo, ModuleName, ClassId, ClassDefn, !IO) :-
+intermod_write_class(OutInfo, ModuleName, ClassId, ClassDefn, !IO) :-
     ClassDefn = hlds_class_defn(ImportStatus, Constraints, HLDSFunDeps,
         _Ancestors, TVars, _Kinds, Interface, _HLDSClassInterface, TVarSet,
         Context),
@@ -1612,16 +1616,16 @@
         TVar = list.det_index1(TVars, N)
     ).
 
-:- pred write_instances(hlds_out_info::in,
+:- pred intermod_write_instances(hlds_out_info::in,
     assoc_list(class_id, hlds_instance_defn)::in, io::di, io::uo) is det.
 
-write_instances(OutInfo, Instances, !IO) :-
-    list.foldl(write_instance(OutInfo), Instances, !IO).
+intermod_write_instances(OutInfo, Instances, !IO) :-
+    list.foldl(intermod_write_instance(OutInfo), Instances, !IO).
 
-:- pred write_instance(hlds_out_info::in,
+:- pred intermod_write_instance(hlds_out_info::in,
     pair(class_id, hlds_instance_defn)::in, io::di, io::uo) is det.
 
-write_instance(OutInfo, ClassId - InstanceDefn, !IO) :-
+intermod_write_instance(OutInfo, ClassId - InstanceDefn, !IO) :-
     InstanceDefn = hlds_instance_defn(ModuleName, _, Context, Constraints,
         Types, Body, _, TVarSet, _),
     ClassId = class_id(ClassName, _),
@@ -1634,11 +1638,11 @@
     % We need to write all the declarations for local predicates so
     % the procedure labels for the C code are calculated correctly.
     %
-:- pred write_pred_decls(module_info::in, list(pred_id)::in,
+:- pred intermod_write_pred_decls(module_info::in, list(pred_id)::in,
     io::di, io::uo) is det.
 
-write_pred_decls(_, [], !IO).
-write_pred_decls(ModuleInfo, [PredId | PredIds], !IO) :-
+intermod_write_pred_decls(_, [], !IO).
+intermod_write_pred_decls(ModuleInfo, [PredId | PredIds], !IO) :-
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     Module = pred_info_module(PredInfo),
     Name = pred_info_name(PredInfo),
@@ -1693,17 +1697,18 @@
             compare(Result, ProcInt1, ProcInt2)
         ),
     list.sort(CompareProcId, ProcIds, SortedProcIds),
-    write_pred_modes(Procs, qualified(Module, Name), PredOrFunc, SortedProcIds,
-        !IO),
-    write_pragmas(PredInfo, !IO),
-    write_type_spec_pragmas(ModuleInfo, PredId, !IO),
-    write_pred_decls(ModuleInfo, PredIds, !IO).
+    intermod_write_pred_modes(Procs, qualified(Module, Name), PredOrFunc,
+        SortedProcIds, !IO),
+    intermod_write_pragmas(PredInfo, !IO),
+    intermod_write_type_spec_pragmas(ModuleInfo, PredId, !IO),
+    intermod_write_pred_decls(ModuleInfo, PredIds, !IO).
 
-:- pred write_pred_modes(map(proc_id, proc_info)::in, sym_name::in,
+:- pred intermod_write_pred_modes(map(proc_id, proc_info)::in, sym_name::in,
     pred_or_func::in, list(proc_id)::in, io::di, io::uo) is det.
 
-write_pred_modes(_, _, _, [], !IO).
-write_pred_modes(Procs, SymName, PredOrFunc, [ProcId | ProcIds], !IO) :-
+intermod_write_pred_modes(_, _, _, [], !IO).
+intermod_write_pred_modes(Procs, SymName, PredOrFunc, [ProcId | ProcIds],
+        !IO) :-
     map.lookup(Procs, ProcId, ProcInfo),
     proc_info_get_maybe_declared_argmodes(ProcInfo, MaybeArgModes),
     proc_info_get_declared_determinism(ProcInfo, MaybeDetism),
@@ -1728,19 +1733,19 @@
         mercury_output_pred_mode_decl(Varset, SymName, ArgModes,
             yes(Detism), Context, !IO)
     ),
-    write_pred_modes(Procs, SymName, PredOrFunc, ProcIds, !IO).
+    intermod_write_pred_modes(Procs, SymName, PredOrFunc, ProcIds, !IO).
 
-:- pred write_preds(hlds_out_info::in, module_info::in, list(pred_id)::in,
-    io::di, io::uo) is det.
+:- pred intermod_write_preds(hlds_out_info::in, module_info::in,
+    list(pred_id)::in, io::di, io::uo) is det.
 
-write_preds(_, _, [], !IO).
-write_preds(OutInfo, ModuleInfo, [PredId | PredIds], !IO) :-
+intermod_write_preds(_, _, [], !IO).
+intermod_write_preds(OutInfo, ModuleInfo, [PredId | PredIds], !IO) :-
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     Module = pred_info_module(PredInfo),
     Name = pred_info_name(PredInfo),
     SymName = qualified(Module, Name),
     PredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    write_pragmas(PredInfo, !IO),
+    intermod_write_pragmas(PredInfo, !IO),
     % The type specialization pragmas for exported preds should
     % already be in the interface file.
 
@@ -1762,10 +1767,12 @@
     ;
         pred_info_get_typevarset(PredInfo, TypeVarset),
         MaybeVarTypes = varset_vartypes(TypeVarset, VarTypes),
-        list.foldl(intermod_write_clause(OutInfo, ModuleInfo, PredId, VarSet,
-            HeadVars, PredOrFunc, SymName, MaybeVarTypes), Clauses, !IO)
+        list.foldl(
+            intermod_write_clause(OutInfo, ModuleInfo, PredId, VarSet,
+                HeadVars, PredOrFunc, SymName, MaybeVarTypes),
+            Clauses, !IO)
     ),
-    write_preds(OutInfo, ModuleInfo, PredIds, !IO).
+    intermod_write_preds(OutInfo, ModuleInfo, PredIds, !IO).
 
 :- pred intermod_write_clause(hlds_out_info::in, module_info::in, pred_id::in,
     prog_varset::in, list(prog_var)::in, pred_or_func::in, sym_name::in,
@@ -1782,9 +1789,9 @@
         % are named the same as variables in the enclosing clause.
         AppendVarNums = yes,
         UseDeclaredModes = yes,
-        write_clause(OutInfo, 1, ModuleInfo, PredId, VarSet, AppendVarNums,
-            ClauseHeadVars, PredOrFunc, Clause, UseDeclaredModes,
-            MaybeVarTypes, !IO)
+        write_clause(OutInfo, 1, ModuleInfo, PredId, VarSet,
+            AppendVarNums, ClauseHeadVars, PredOrFunc, Clause,
+            UseDeclaredModes, MaybeVarTypes, !IO)
     ;
         ImplLang = impl_lang_foreign(_),
         module_info_pred_info(ModuleInfo, PredId, PredInfo),
@@ -1813,8 +1820,8 @@
             ;
                 ApplicableProcIds = selected_modes(ProcIds),
                 list.foldl(
-                    write_foreign_clause(Procs, PredOrFunc, PragmaCode,
-                        Attributes, Args, VarSet, SymName),
+                    intermod_write_foreign_clause(Procs, PredOrFunc,
+                        PragmaCode, Attributes, Args, VarSet, SymName),
                     ProcIds, !IO)
             )
         ;
@@ -1822,12 +1829,12 @@
         )
     ).
 
-:- pred write_foreign_clause(proc_table::in, pred_or_func::in,
+:- pred intermod_write_foreign_clause(proc_table::in, pred_or_func::in,
     pragma_foreign_code_impl::in, pragma_foreign_proc_attributes::in,
     list(foreign_arg)::in, prog_varset::in, sym_name::in, proc_id::in,
     io::di, io::uo) is det.
 
-write_foreign_clause(Procs, PredOrFunc, PragmaImpl,
+intermod_write_foreign_clause(Procs, PredOrFunc, PragmaImpl,
         Attributes, Args, ProgVarset0, SymName, ProcId, !IO) :-
     map.lookup(Procs, ProcId, ProcInfo),
     proc_info_get_maybe_declared_argmodes(ProcInfo, MaybeArgModes),
@@ -1935,9 +1942,9 @@
     strip_headvar_unifications_from_goal_list(Goals0, HeadVars,
         RevGoals1, Goals, !HeadVarMap).
 
-:- pred write_pragmas(pred_info::in, io::di, io::uo) is det.
+:- pred intermod_write_pragmas(pred_info::in, io::di, io::uo) is det.
 
-write_pragmas(PredInfo, !IO) :-
+intermod_write_pragmas(PredInfo, !IO) :-
     Module = pred_info_module(PredInfo),
     Name = pred_info_name(PredInfo),
     Arity = pred_info_orig_arity(PredInfo),
@@ -1945,13 +1952,14 @@
     SymName = qualified(Module, Name),
     pred_info_get_markers(PredInfo, Markers),
     markers_to_marker_list(Markers, MarkerList),
-    write_pragmas(SymName, Arity, MarkerList, PredOrFunc, !IO).
+    intermod_write_pragma_markers(SymName, Arity, MarkerList, PredOrFunc, !IO).
 
-:- pred write_pragmas(sym_name::in, int::in, list(marker)::in,
+:- pred intermod_write_pragma_markers(sym_name::in, int::in, list(marker)::in,
     pred_or_func::in, io::di, io::uo) is det.
 
-write_pragmas(_, _, [], _, !IO).
-write_pragmas(SymName, Arity, [Marker | Markers], PredOrFunc, !IO) :-
+intermod_write_pragma_markers(_, _, [], _, !IO).
+intermod_write_pragma_markers(SymName, Arity, [Marker | Markers], PredOrFunc,
+        !IO) :-
     should_output_marker(Marker, ShouldOutput),
     (
         ShouldOutput = yes,
@@ -1960,28 +1968,29 @@
     ;
         ShouldOutput = no
     ),
-    write_pragmas(SymName, Arity, Markers, PredOrFunc, !IO).
+    intermod_write_pragma_markers(SymName, Arity, Markers, PredOrFunc, !IO).
 
-:- pred write_type_spec_pragmas(module_info::in, pred_id::in,
+:- pred intermod_write_type_spec_pragmas(module_info::in, pred_id::in,
     io::di, io::uo) is det.
 
-write_type_spec_pragmas(ModuleInfo, PredId, !IO) :-
+intermod_write_type_spec_pragmas(ModuleInfo, PredId, !IO) :-
     module_info_get_type_spec_info(ModuleInfo, TypeSpecInfo),
     PragmaMap = TypeSpecInfo ^ pragma_map,
     ( multi_map.search(PragmaMap, PredId, TypeSpecPragmas) ->
-        list.foldl(write_type_spec_pragma, TypeSpecPragmas, !IO)
+        list.foldl(intermod_write_type_spec_pragma, TypeSpecPragmas, !IO)
     ;
         true
     ).
 
-:- pred write_type_spec_pragma(pragma_type::in, io::di, io::uo) is det.
+:- pred intermod_write_type_spec_pragma(pragma_type::in, io::di, io::uo)
+    is det.
 
-write_type_spec_pragma(Pragma, !IO) :-
+intermod_write_type_spec_pragma(Pragma, !IO) :-
     ( Pragma = pragma_type_spec(_, _, _, _, _, _, _, _) ->
         AppendVarnums = yes,
         mercury_output_pragma_type_spec(Pragma, AppendVarnums, !IO)
     ;
-        unexpected($module, $pred, "write_type_spec_pragma")
+        unexpected($module, $pred, "no pragma_type_spec")
     ).
 
     % Is a pragma declaration required in the `.opt' file for
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.354
diff -u -b -r1.354 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	13 Feb 2012 00:11:41 -0000	1.354
+++ compiler/mercury_to_mercury.m	27 Mar 2012 06:40:50 -0000
@@ -56,6 +56,7 @@
 :- import_module io.
 :- import_module list.
 :- import_module maybe.
+:- import_module set.
 :- import_module term.
 :- import_module varset.
 
@@ -188,23 +189,6 @@
     io::di, io::uo) is det.
 :- func mercury_inst_list_to_string(list(mer_inst), inst_varset) = string.
 
-    % Output a list of insts in a format that makes them easy to read
-    % but may not be valid Mercury.
-    %
-:- pred mercury_output_structured_inst_list(list(mer_inst)::in, int::in,
-    inst_varset::in, io::di, io::uo) is det.
-:- func mercury_structured_inst_list_to_string(list(mer_inst), int,
-    inst_varset) = string.
-
-    % Output an inst in a format that makes it easy to read
-    % but may not be valid Mercury.
-    % The `int' argument specifies the indentation level.
-    % (These routines are used with `--debug-modes'.)
-    %
-:- pred mercury_output_structured_inst(mer_inst::in, int::in, inst_varset::in,
-    io::di, io::uo) is det.
-:- func mercury_structured_inst_to_string(mer_inst, int, inst_varset) = string.
-
     % Output an inst in a format that is valid Mercury.
     % (These routines are used to create `.int' files, etc.)
     %
@@ -214,15 +198,38 @@
 :- pred mercury_format_inst(mer_inst::in, InstInfo::in,
     U::di, U::uo) is det <= (output(U), inst_info(InstInfo)).
 
+:- pred mercury_format_is_live_comma(is_live::in, U::di, U::uo) is det
+    <= output(U).
+
+:- pred mercury_format_real_comma(unify_is_real::in, U::di, U::uo) is det
+    <= output(U).
+
+:- pred mercury_format_uniqueness(uniqueness::in, string::in,
+    U::di, U::uo) is det <= output(U).
+
+:- pred mercury_format_any_uniqueness(uniqueness::in,
+    U::di, U::uo) is det <= output(U).
+
+:- pred mercury_format_ground_pred_inst_info(uniqueness::in,
+    pred_inst_info::in, inst_varset::in, U::di, U::uo) is det <= output(U).
+
+:- pred mercury_format_any_pred_inst_info(uniqueness::in, pred_inst_info::in,
+    inst_varset::in, U::di, U::uo) is det <= output(U).
+
 :- pred mercury_format_inst_name(inst_name::in, InstInfo::in,
     U::di, U::uo) is det <= (output(U), inst_info(InstInfo)).
 
-    % Output a cons_id, parenthesizing it if necessary
+    % Output a cons_id, parenthesizing it if necessary.
     %
 :- pred mercury_output_cons_id(cons_id::in, needs_brackets::in,
     io::di, io::uo) is det.
-
 :- func mercury_cons_id_to_string(cons_id, needs_brackets) = string.
+:- pred mercury_format_cons_id(cons_id::in, needs_brackets::in, U::di, U::uo)
+    is det <= output(U).
+
+:- pred mercury_format_constrained_inst_vars(set(inst_var)::in, mer_inst::in,
+    InstInfo::in, U::di, U::uo) is det
+    <= (output(U), inst_info(InstInfo)).
 
     % Output a mode / list of modes / uni_mode,
     % in a format that is valid Mercury.
@@ -258,6 +265,8 @@
 :- pred mercury_output_var(varset(T)::in, bool::in, var(T)::in,
     io::di, io::uo) is det.
 :- func mercury_var_to_string(varset(T), bool, var(T)) = string.
+:- pred mercury_format_var(varset(T)::in, bool::in, var(T)::in, U::di, U::uo)
+    is det <= output(U).
 
     % Output a term, making sure that the variable number appears
     % in variable names if the boolean argument is set to `yes'.
@@ -290,13 +299,26 @@
 
 :- pred mercury_output_newline(int::in, io::di, io::uo) is det.
 
+:- pred mercury_format_tabs(int::in,
+    U::di, U::uo) is det <= output(U).
+
 :- pred mercury_output_bracketed_sym_name(sym_name::in,
     io::di, io::uo) is det.
 :- func mercury_bracketed_sym_name_to_string(sym_name) = string.
+:- pred mercury_format_bracketed_sym_name(sym_name::in,
+    U::di, U::uo) is det <= output(U).
 
-:- pred mercury_output_bracketed_sym_name(sym_name::in, needs_quotes::in,
+:- pred mercury_output_bracketed_sym_name_ngt(sym_name::in, needs_quotes::in,
     io::di, io::uo) is det.
-:- func mercury_bracketed_sym_name_to_string(sym_name, needs_quotes) = string.
+:- func mercury_bracketed_sym_name_to_string_ngt(sym_name, needs_quotes)
+    = string.
+:- pred mercury_format_bracketed_sym_name_ngt(sym_name::in, needs_quotes::in,
+    U::di, U::uo) is det <= output(U).
+
+:- pred mercury_format_sym_name(sym_name::in, U::di, U::uo)
+    is det <= output(U).
+:- pred mercury_format_sym_name_ngt(sym_name::in, needs_quotes::in,
+    U::di, U::uo) is det <= output(U).
 
 :- pred mercury_convert_var_name(string::in, string::out) is det.
 
@@ -430,7 +452,6 @@
 :- import_module pair.
 :- import_module ops.
 :- import_module require.
-:- import_module set.
 :- import_module string.
 :- import_module term.
 :- import_module term_io.
@@ -551,8 +572,8 @@
         Item = item_nothing(_ItemNothing)
     ).
 
-:- pred mercury_output_item_type_defn(merc_out_info::in, item_type_defn_info::in,
-    io::di, io::uo) is det.
+:- pred mercury_output_item_type_defn(merc_out_info::in,
+    item_type_defn_info::in, io::di, io::uo) is det.
 
 mercury_output_item_type_defn(Info, ItemTypeDefn, !IO) :-
     ItemTypeDefn = item_type_defn_info(VarSet, Name0, Args, TypeDefn, _Cond,
@@ -561,8 +582,8 @@
     maybe_output_line_number(Info, Context, !IO),
     mercury_output_type_defn(Info, VarSet, Name, Args, TypeDefn, Context, !IO).
 
-:- pred mercury_output_item_inst_defn(merc_out_info::in, item_inst_defn_info::in,
-    io::di, io::uo) is det.
+:- pred mercury_output_item_inst_defn(merc_out_info::in,
+    item_inst_defn_info::in, io::di, io::uo) is det.
 
 mercury_output_item_inst_defn(Info, ItemInstDefn, !IO) :-
     ItemInstDefn = item_inst_defn_info(VarSet, Name0, Args, InstDefn, _Cond,
@@ -814,7 +835,7 @@
     ;
         Pragma = pragma_reserve_tag(TypeName, TypeArity),
         add_string(":- pragma reserve_tag(", !IO),
-        mercury_format_bracketed_sym_name(TypeName, next_to_graphic_token,
+        mercury_format_bracketed_sym_name_ngt(TypeName, next_to_graphic_token,
             !IO),
         add_string("/", !IO),
         add_int(TypeArity, !IO),
@@ -1095,7 +1116,8 @@
             PredOrFunc = pf_predicate,
             io.write_string("pred(", !IO)
         ),
-        mercury_output_bracketed_sym_name(Name1, next_to_graphic_token, !IO),
+        mercury_output_bracketed_sym_name_ngt(Name1,
+            next_to_graphic_token, !IO),
         io.write_string("/", !IO),
         io.write_int(Arity, !IO),
         io.write_string(") is ", !IO),
@@ -1210,20 +1232,6 @@
     mercury_output_inst(Body, VarSet, !IO),
     io.write_string(".\n", !IO).
 
-mercury_output_structured_inst_list(Insts, Indent, VarSet, !IO) :-
-    mercury_format_structured_inst_list(Insts, Indent, VarSet, !IO).
-
-mercury_structured_inst_list_to_string(Insts, Indent, VarSet) = String :-
-    mercury_format_structured_inst_list(Insts, Indent, VarSet, "", String).
-
-:- pred mercury_format_structured_inst_list(list(mer_inst)::in, int::in,
-    inst_varset::in, U::di, U::uo) is det <= output(U).
-
-mercury_format_structured_inst_list([], _, _, !U).
-mercury_format_structured_inst_list([Inst | Insts], Indent0, VarSet, !U) :-
-    mercury_format_structured_inst(Inst, Indent0, VarSet, !U),
-    mercury_format_structured_inst_list(Insts, Indent0, VarSet, !U).
-
 mercury_output_inst_list(Insts, VarSet, !IO) :-
     mercury_format_inst_list(Insts, simple_inst_info(VarSet), !IO).
 
@@ -1244,71 +1252,6 @@
         mercury_format_inst_list(Insts, VarSet, !U)
     ).
 
-mercury_output_structured_inst(Inst, Indent, VarSet, !U) :-
-    mercury_format_structured_inst(Inst, Indent, VarSet, !U).
-
-mercury_structured_inst_to_string(Inst, Indent, VarSet) = String :-
-    mercury_format_structured_inst(Inst, Indent, VarSet, "", String).
-
-:- pred mercury_format_structured_inst(mer_inst::in, int::in, inst_varset::in,
-    U::di, U::uo) is det <= output(U).
-
-mercury_format_structured_inst(any(Uniq, HOInstInfo), Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    (
-        HOInstInfo = higher_order(PredInstInfo),
-        mercury_format_any_pred_inst_info(Uniq, PredInstInfo, VarSet, !U)
-    ;
-        HOInstInfo = none,
-        mercury_format_any_uniqueness(Uniq, !U)
-    ),
-    add_string("\n", !U).
-mercury_format_structured_inst(free, Indent, _, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("free\n", !U).
-mercury_format_structured_inst(free(_T), Indent, _, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("free(with some type)\n", !U).
-mercury_format_structured_inst(bound(Uniq, BoundInsts), Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    mercury_format_uniqueness(Uniq, "bound", !U),
-    add_string("(\n", !U),
-    mercury_format_structured_bound_insts(BoundInsts, Indent, VarSet, !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst(ground(Uniq, HOInstInfo), Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    (
-        HOInstInfo = higher_order(PredInstInfo),
-        mercury_format_ground_pred_inst_info(Uniq, PredInstInfo, VarSet, !U)
-    ;
-        HOInstInfo = none,
-        mercury_format_uniqueness(Uniq, "ground", !U)
-    ),
-    add_string("\n", !U).
-mercury_format_structured_inst(inst_var(Var), Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    mercury_format_var(VarSet, no, Var, !U),
-    add_string("\n", !U).
-mercury_format_structured_inst(constrained_inst_vars(Vars, Inst), Indent,
-        VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    mercury_format_constrained_inst_vars(Vars, Inst,
-        simple_inst_info(VarSet), !U),
-    add_string("\n", !U).
-mercury_format_structured_inst(abstract_inst(Name, Args), Indent, VarSet,
-        !U) :-
-    mercury_format_structured_inst_name(user_inst(Name, Args), Indent,
-        VarSet, !U).
-mercury_format_structured_inst(defined_inst(InstName), Indent, VarSet, !U) :-
-    mercury_format_structured_inst_name(InstName, Indent, VarSet, !U).
-mercury_format_structured_inst(not_reached, Indent, _, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("not_reached\n", !U).
-
-:- pred mercury_format_ground_pred_inst_info(uniqueness::in,
-    pred_inst_info::in, inst_varset::in, U::di, U::uo) is det <= output(U).
-
 mercury_format_ground_pred_inst_info(Uniq, PredInstInfo, VarSet, !U) :-
     PredInstInfo = pred_inst_info(PredOrFunc, Modes, MaybeArgRegs, Det),
     (
@@ -1365,9 +1308,6 @@
         MaybeArgRegs = arg_reg_types_unset
     ).
 
-:- pred mercury_format_any_pred_inst_info(uniqueness::in, pred_inst_info::in,
-    inst_varset::in, U::di, U::uo) is det <= output(U).
-
 mercury_format_any_pred_inst_info(Uniq, PredInstInfo, VarSet, !U) :-
     PredInstInfo = pred_inst_info(PredOrFunc, Modes, MaybeArgRegs, Det),
     (
@@ -1455,7 +1395,9 @@
 mercury_inst_to_string(Inst, VarSet) = String :-
     mercury_format_inst(Inst, simple_inst_info(VarSet), "", String).
 
-mercury_format_inst(any(Uniq, HOInstInfo), InstInfo, !U) :-
+mercury_format_inst(Inst, InstInfo, !U) :-
+    (
+        Inst = any(Uniq, HOInstInfo),
     (
         HOInstInfo = higher_order(PredInstInfo),
         mercury_format_any_pred_inst_info(Uniq, PredInstInfo,
@@ -1463,17 +1405,21 @@
     ;
         HOInstInfo = none,
         mercury_format_any_uniqueness(Uniq, !U)
-    ).
-mercury_format_inst(free, _, !U) :-
-    add_string("free", !U).
-mercury_format_inst(free(_T), _, !U) :-
-    add_string("free(with some type)", !U).
-mercury_format_inst(bound(Uniq, BoundInsts), InstInfo, !U) :-
+        )
+    ;
+        Inst = free,
+        add_string("free", !U)
+    ;
+        Inst = free(_T),
+        add_string("free(with some type)", !U)
+    ;
+        Inst = bound(Uniq, BoundInsts),
     mercury_format_uniqueness(Uniq, "bound", !U),
     add_string("(", !U),
     mercury_format_bound_insts(BoundInsts, InstInfo, !U),
-    add_string(")", !U).
-mercury_format_inst(ground(Uniq, HOInstInfo), InstInfo, !U) :-
+        add_string(")", !U)
+    ;
+        Inst = ground(Uniq, HOInstInfo),
     (
         HOInstInfo = higher_order(PredInstInfo),
         mercury_format_ground_pred_inst_info(Uniq, PredInstInfo,
@@ -1481,20 +1427,23 @@
     ;
         HOInstInfo = none,
         mercury_format_uniqueness(Uniq, "ground", !U)
+        )
+    ;
+        Inst = inst_var(Var),
+        mercury_format_var(InstInfo ^ instvarset, no, Var, !U)
+    ;
+        Inst = constrained_inst_vars(Vars, CInst),
+        mercury_format_constrained_inst_vars(Vars, CInst, InstInfo, !U)
+    ;
+        Inst = abstract_inst(Name, Args),
+        mercury_format_inst_name(user_inst(Name, Args), InstInfo, !U)
+    ;
+        Inst = defined_inst(InstName),
+        format_defined_inst(InstName, InstInfo, !U)
+    ;
+        Inst = not_reached,
+        add_string("not_reached", !U)
     ).
-mercury_format_inst(inst_var(Var), InstInfo, !U) :-
-    mercury_format_var(InstInfo ^ instvarset, no, Var, !U).
-mercury_format_inst(constrained_inst_vars(Vars, Inst), InstInfo, !U) :-
-    mercury_format_constrained_inst_vars(Vars, Inst, InstInfo, !U).
-mercury_format_inst(abstract_inst(Name, Args), InstInfo, !U) :-
-    mercury_format_inst_name(user_inst(Name, Args), InstInfo, !U).
-mercury_format_inst(defined_inst(InstName), InstInfo, !U) :-
-    format_defined_inst(InstName, InstInfo, !U).
-mercury_format_inst(not_reached, _, !U) :-
-    add_string("not_reached", !U).
-
-:- pred mercury_format_is_live_comma(is_live::in, U::di, U::uo) is det
-    <= output(U).
 
 mercury_format_is_live_comma(IsLive, !U) :-
     (
@@ -1505,9 +1454,6 @@
         add_string("dead, ", !U)
     ).
 
-:- pred mercury_format_real_comma(unify_is_real::in, U::di, U::uo) is det
-    <= output(U).
-
 mercury_format_real_comma(Real, !U) :-
     (
         Real = real_unify,
@@ -1529,99 +1475,9 @@
         add_string(", fake", !U)
     ).
 
-:- pred mercury_format_structured_inst_name(inst_name::in, int::in,
-    inst_varset::in, U::di, U::uo) is det <= output(U).
-
-mercury_format_structured_inst_name(user_inst(Name, Args), Indent, VarSet,
-        !U) :-
+mercury_format_inst_name(InstName, InstInfo, !U) :-
     (
-        Args = [],
-        mercury_format_tabs(Indent, !U),
-        mercury_format_bracketed_sym_name(Name, !U)
-    ;
-        Args = [_ | _],
-        mercury_format_tabs(Indent, !U),
-        mercury_format_sym_name(Name, !U),
-        add_string("(\n", !U),
-        mercury_format_structured_inst_list(Args, Indent + 1, VarSet, !U),
-        mercury_format_tabs(Indent, !U),
-        add_string(")\n", !U)
-    ).
-mercury_format_structured_inst_name(merge_inst(InstA, InstB), Indent, VarSet,
-        !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("$merge_inst(\n", !U),
-    mercury_format_structured_inst_list([InstA, InstB], Indent + 1, VarSet,
-        !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst_name(shared_inst(InstName), Indent, VarSet,
-        !U) :-
-    add_string("$shared_inst(\n", !U),
-    mercury_format_structured_inst_name(InstName, Indent + 1, VarSet, !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst_name(mostly_uniq_inst(InstName), Indent, VarSet,
-        !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("$mostly_uniq_inst(\n", !U),
-    mercury_format_structured_inst_name(InstName, Indent + 1, VarSet, !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst_name(unify_inst(IsLive, InstA, InstB, Real),
-        Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("$unify(", !U),
-    mercury_format_is_live_comma(IsLive, !U),
-    mercury_format_real_comma(Real, !U),
-    add_string("\n", !U),
-    mercury_format_structured_inst_list([InstA, InstB], Indent + 1, VarSet,
-        !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst_name(ground_inst(InstName, IsLive, Uniq, Real),
-        Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("$ground(", !U),
-    mercury_format_is_live_comma(IsLive, !U),
-    mercury_format_real_comma(Real, !U),
-    mercury_format_uniqueness(Uniq, "shared", !U),
-    add_string(",\n", !U),
-    mercury_format_structured_inst_name(InstName, Indent + 1, VarSet, !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst_name(any_inst(InstName, IsLive, Uniq, Real),
-        Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("$any(", !U),
-    mercury_format_is_live_comma(IsLive, !U),
-    mercury_format_real_comma(Real, !U),
-    mercury_format_uniqueness(Uniq, "shared", !U),
-    add_string(",\n", !U),
-    mercury_format_structured_inst_name(InstName, Indent + 1, VarSet, !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst_name(typed_ground(Uniqueness, Type),
-        Indent, _VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("$typed_ground(", !U),
-    mercury_format_uniqueness(Uniqueness, "shared", !U),
-    add_string(", ", !U),
-    varset.init(TypeVarSet),
-    mercury_format_type(TypeVarSet, no, Type, !U),
-    add_string(")\n", !U).
-mercury_format_structured_inst_name(typed_inst(Type, InstName),
-        Indent, VarSet, !U) :-
-    mercury_format_tabs(Indent, !U),
-    add_string("$typed_inst(", !U),
-    varset.init(TypeVarSet),
-    mercury_format_type(TypeVarSet, no, Type, !U),
-    add_string(",\n", !U),
-    mercury_format_structured_inst_name(InstName, Indent + 1, VarSet, !U),
-    mercury_format_tabs(Indent, !U),
-    add_string(")\n", !U).
-
-mercury_format_inst_name(user_inst(Name, Args), InstInfo, !U) :-
+        InstName = user_inst(Name, Args),
     (
         Args = [],
         mercury_format_bracketed_sym_name(Name, !U)
@@ -1631,61 +1487,64 @@
         add_string("(", !U),
         mercury_format_inst_list(Args, InstInfo, !U),
         add_string(")", !U)
-    ).
-mercury_format_inst_name(merge_inst(InstA, InstB), InstInfo, !U) :-
+        )
+    ;
+        InstName = merge_inst(InstA, InstB),
     add_string("$merge_inst(", !U),
     mercury_format_inst_list([InstA, InstB], InstInfo, !U),
-    add_string(")", !U).
-mercury_format_inst_name(shared_inst(InstName), InstInfo, !U) :-
+        add_string(")", !U)
+    ;
+        InstName = shared_inst(SubInstName),
     add_string("$shared_inst(", !U),
-    mercury_format_inst_name(InstName, InstInfo, !U),
-    add_string(")", !U).
-mercury_format_inst_name(mostly_uniq_inst(InstName), InstInfo, !U) :-
+        mercury_format_inst_name(SubInstName, InstInfo, !U),
+        add_string(")", !U)
+    ;
+        InstName = mostly_uniq_inst(SubInstName),
     add_string("$mostly_uniq_inst(", !U),
-    mercury_format_inst_name(InstName, InstInfo, !U),
-    add_string(")", !U).
-mercury_format_inst_name(unify_inst(IsLive, InstA, InstB, Real), InstInfo,
-        !U) :-
+        mercury_format_inst_name(SubInstName, InstInfo, !U),
+        add_string(")", !U)
+    ;
+        InstName = unify_inst(IsLive, InstA, InstB, Real),
     add_string("$unify(", !U),
     mercury_format_is_live_comma(IsLive, !U),
     mercury_format_comma_real(Real, !U),
     mercury_format_inst_list([InstA, InstB], InstInfo, !U),
-    add_string(")", !U).
-mercury_format_inst_name(ground_inst(InstName, IsLive, Uniq, Real), InstInfo,
-        !U) :-
+        add_string(")", !U)
+    ;
+        InstName = ground_inst(SubInstName, IsLive, Uniq, Real),
     add_string("$ground(", !U),
-    mercury_format_inst_name(InstName, InstInfo, !U),
+        mercury_format_inst_name(SubInstName, InstInfo, !U),
     add_string(", ", !U),
     mercury_format_is_live_comma(IsLive, !U),
     mercury_format_uniqueness(Uniq, "shared", !U),
     mercury_format_comma_real(Real, !U),
-    add_string(")", !U).
-mercury_format_inst_name(any_inst(InstName, IsLive, Uniq, Real), InstInfo,
-        !U) :-
+        add_string(")", !U)
+    ;
+        InstName = any_inst(SubInstName, IsLive, Uniq, Real),
     add_string("$any(", !U),
-    mercury_format_inst_name(InstName, InstInfo, !U),
+        mercury_format_inst_name(SubInstName, InstInfo, !U),
     add_string(", ", !U),
     mercury_format_is_live_comma(IsLive, !U),
     mercury_format_uniqueness(Uniq, "shared", !U),
     mercury_format_comma_real(Real, !U),
-    add_string(")", !U).
-mercury_format_inst_name(typed_ground(Uniqueness, Type), _InstInfo, !U) :-
+        add_string(")", !U)
+    ;
+        InstName = typed_ground(Uniqueness, Type),
     add_string("$typed_ground(", !U),
     mercury_format_uniqueness(Uniqueness, "shared", !U),
     add_string(", ", !U),
     varset.init(TypeVarSet),
     mercury_format_type(TypeVarSet, no, Type, !U),
-    add_string(")", !U).
-mercury_format_inst_name(typed_inst(Type, InstName), InstInfo, !U) :-
+        add_string(")", !U)
+    ;
+        InstName = typed_inst(Type, SubInstName),
     add_string("$typed_inst(", !U),
     varset.init(TypeVarSet),
     mercury_format_type(TypeVarSet, no, Type, !U),
     add_string(", ", !U),
-    mercury_format_inst_name(InstName, InstInfo, !U),
-    add_string(")", !U).
-
-:- pred mercury_format_uniqueness(uniqueness::in, string::in,
-    U::di, U::uo) is det <= output(U).
+        mercury_format_inst_name(SubInstName, InstInfo, !U),
+        add_string(")", !U)
+    ).
 
 mercury_format_uniqueness(shared, SharedString, !U) :-
     add_string(SharedString, !U).
@@ -1698,9 +1557,6 @@
 mercury_format_uniqueness(mostly_clobbered, _, !U) :-
     add_string("mostly_clobbered", !U).
 
-:- pred mercury_format_any_uniqueness(uniqueness::in,
-    U::di, U::uo) is det <= output(U).
-
 mercury_format_any_uniqueness(shared, !U) :-
     add_string("any", !U).
 mercury_format_any_uniqueness(unique, !U) :-
@@ -1712,39 +1568,6 @@
 mercury_format_any_uniqueness(mostly_clobbered, !U) :-
     add_string("mostly_clobbered_any", !U).
 
-:- pred mercury_format_structured_bound_insts(list(bound_inst)::in, int::in,
-    inst_varset::in, U::di, U::uo) is det <= output(U).
-
-mercury_format_structured_bound_insts([], _, _, !U).
-mercury_format_structured_bound_insts([BoundInst | BoundInsts],
-        Indent0, VarSet, !U) :-
-    BoundInst = bound_functor(ConsId, Args),
-    Indent1 = Indent0 + 1,
-    Indent2 = Indent1 + 1,
-    (
-        Args = [],
-        mercury_format_tabs(Indent1, !U),
-        mercury_format_cons_id(ConsId, needs_brackets, !U),
-        add_string("\n", !U)
-    ;
-        Args = [_ | _],
-        mercury_format_tabs(Indent1, !U),
-        mercury_format_cons_id(ConsId, does_not_need_brackets, !U),
-        add_string("(\n", !U),
-        mercury_format_structured_inst_list(Args, Indent2, VarSet, !U),
-        mercury_format_tabs(Indent1, !U),
-        add_string(")\n", !U)
-    ),
-    (
-        BoundInsts = []
-    ;
-        BoundInsts = [_ | _],
-        mercury_format_tabs(Indent0, !U),
-        add_string(";\n", !U),
-        mercury_format_structured_bound_insts(BoundInsts, Indent0,
-            VarSet, !U)
-    ).
-
 :- pred mercury_format_bound_insts(list(bound_inst)::in, InstInfo::in,
     U::di, U::uo) is det <= (output(U), inst_info(InstInfo)).
 
@@ -1775,9 +1598,6 @@
 mercury_cons_id_to_string(ConsId, NeedsBrackets) = String :-
     mercury_format_cons_id(ConsId, NeedsBrackets, "", String).
 
-:- pred mercury_format_cons_id(cons_id::in, needs_brackets::in, U::di, U::uo)
-    is det <= output(U).
-
 mercury_format_cons_id(ConsId, NeedsBrackets, !U) :-
     (
         ConsId = cons(Name, _, _),
@@ -1854,10 +1674,6 @@
         add_string("<deep_profiling_proc_layout>", !U)
     ).
 
-:- pred mercury_format_constrained_inst_vars(set(inst_var)::in, mer_inst::in,
-    InstInfo::in, U::di, U::uo) is det
-    <= (output(U), inst_info(InstInfo)).
-
 mercury_format_constrained_inst_vars(!.Vars, Inst, InstInfo, !U) :-
     ( set.remove_least(Var, !Vars) ->
         add_string("(", !U),
@@ -1908,12 +1724,11 @@
 mercury_mode_to_string(Mode, VarSet) = String :-
     mercury_format_mode(Mode, simple_inst_info(VarSet), "", String).
 
-mercury_format_mode((InstA -> InstB), InstInfo, !U) :-
+mercury_format_mode(Mode, InstInfo, !U) :-
+    (
+        Mode = (InstA -> InstB),
+        % Output higher-order pred and func modes in a nice format.
     (
-        %
-        % check for higher-order pred or func modes, and output them
-        % in a nice format
-        %
         InstA = ground(_Uniq, higher_order(
             pred_inst_info(_PredOrFunc, _Modes, _, _Det))),
         InstB = InstA
@@ -1925,8 +1740,9 @@
         add_string(" >> ", !U),
         mercury_format_inst(InstB, InstInfo, !U),
         add_string(")", !U)
-    ).
-mercury_format_mode(user_defined_mode(Name, Args), InstInfo, !U) :-
+        )
+    ;
+        Mode = user_defined_mode(Name, Args),
     (
         Args = [],
         mercury_format_bracketed_sym_name(Name, !U)
@@ -1936,6 +1752,7 @@
         add_string("(", !U),
         mercury_format_inst_list(Args, InstInfo, !U),
         add_string(")", !U)
+        )
     ).
 
 %-----------------------------------------------------------------------------%
@@ -3431,7 +3248,7 @@
 mercury_output_call(Name, Term, VarSet, _Indent, !IO) :-
     (
         Name = qualified(ModuleName, PredName),
-        mercury_output_bracketed_sym_name(ModuleName,
+        mercury_output_bracketed_sym_name_ngt(ModuleName,
             next_to_graphic_token, !IO),
         io.write_string(".", !IO),
         term.context_init(Context0),
@@ -3576,8 +3393,8 @@
     io.write_string(":- pragma foreign_import_module(", !IO),
     mercury_format_foreign_language_string(Lang, !IO),
     io.write_string(", ", !IO),
-    mercury_output_bracketed_sym_name(ModuleName, not_next_to_graphic_token,
-        !IO),
+    mercury_output_bracketed_sym_name_ngt(ModuleName,
+        not_next_to_graphic_token, !IO),
     io.write_string(").\n", !IO).
 
 %-----------------------------------------------------------------------------%
@@ -3800,8 +3617,8 @@
         )
     ;
         MaybeModes = no,
-        mercury_output_bracketed_sym_name(PredName, next_to_graphic_token,
-            !IO),
+        mercury_output_bracketed_sym_name_ngt(PredName,
+            next_to_graphic_token, !IO),
         io.write_string("/", !IO),
         io.write_int(Arity, !IO)
     ),
@@ -3809,8 +3626,8 @@
     io.write_list(Subst, ", ",
         mercury_output_type_subst(VarSet, AppendVarnums), !IO),
     io.write_string("), ", !IO),
-    mercury_output_bracketed_sym_name(SpecName, not_next_to_graphic_token,
-        !IO),
+    mercury_output_bracketed_sym_name_ngt(SpecName,
+        not_next_to_graphic_token, !IO),
     io.write_string(").\n", !IO).
 
 :- pred mercury_output_type_subst(tvarset::in, bool::in,
@@ -3963,7 +3780,7 @@
     add_string(":- pragma ", !U),
     add_string(PragmaName, !U),
     add_string("(", !U),
-    mercury_format_bracketed_sym_name(PredName, next_to_graphic_token, !U),
+    mercury_format_bracketed_sym_name_ngt(PredName, next_to_graphic_token, !U),
     add_string("/", !U),
     add_int(DeclaredArity, !U),
     (
@@ -3986,7 +3803,7 @@
     add_string(":- pragma foreign_export_enum(", !U),
     mercury_format_foreign_language_string(Lang, !U),
     add_string(", ", !U),
-    mercury_format_bracketed_sym_name(TypeName, next_to_graphic_token, !U),
+    mercury_format_bracketed_sym_name_ngt(TypeName, next_to_graphic_token, !U),
     add_string("/", !U),
     add_int(TypeArity, !U),
     add_string(", ", !U),
@@ -4028,7 +3845,7 @@
     pair(sym_name, string)::in, U::di, U::uo) is det <= output(U).
 
 mercury_format_sym_name_string_pair(SymName - String, !U) :-
-    mercury_format_bracketed_sym_name(SymName, next_to_graphic_token, !U),
+    mercury_format_bracketed_sym_name_ngt(SymName, next_to_graphic_token, !U),
     add_string(" - ", !U),
     add_quoted_string(String, !U).
 
@@ -4043,7 +3860,7 @@
     add_string(":- pragma foreign_enum(", !U),
     mercury_format_foreign_language_string(Lang, !U),
     add_string(", ", !U),
-    mercury_format_bracketed_sym_name(TypeName, next_to_graphic_token, !U),
+    mercury_format_bracketed_sym_name_ngt(TypeName, next_to_graphic_token, !U),
     add_string("/", !U),
     add_int(TypeArity, !U),
     add_string(", ", !U),
@@ -4088,7 +3905,7 @@
 
 mercury_format_pragma_fact_table(Pred, Arity, FileName, !U) :-
     add_string(":- pragma fact_table(", !U),
-    mercury_format_bracketed_sym_name(Pred, next_to_graphic_token, !U),
+    mercury_format_bracketed_sym_name_ngt(Pred, next_to_graphic_token, !U),
     add_string("/", !U),
     add_int(Arity, !U),
     add_string(", ", !U),
@@ -4132,9 +3949,6 @@
     io.write_char('\n', !IO),
     mercury_format_tabs(Indent, !IO).
 
-:- pred mercury_format_tabs(int::in,
-    U::di, U::uo) is det <= output(U).
-
 mercury_format_tabs(Indent, !U) :-
     ( Indent = 0 ->
         true
@@ -4662,9 +4476,6 @@
 mercury_var_to_string(VarSet, AppendVarnum, Var) = String :-
     mercury_format_var(VarSet, AppendVarnum, Var, "", String).
 
-:- pred mercury_format_var(varset(T)::in, bool::in, var(T)::in, U::di, U::uo)
-    is det <= output(U).
-
 mercury_format_var(VarSet, AppendVarnum, Var, !U) :-
     (
         varset.search_name(VarSet, Var, Name)
@@ -4734,40 +4545,35 @@
 :- pred mercury_output_sym_name(sym_name::in, io::di, io::uo) is det.
 
 mercury_output_sym_name(SymName, !IO) :-
-    mercury_output_sym_name(SymName, not_next_to_graphic_token, !IO).
+    mercury_output_sym_name_ngt(SymName, not_next_to_graphic_token, !IO).
 
-:- pred mercury_output_sym_name(sym_name::in, needs_quotes::in,
+:- pred mercury_output_sym_name_ngt(sym_name::in, needs_quotes::in,
     io::di, io::uo) is det.
 
-mercury_output_sym_name(Name, NextToGraphicToken, !IO) :-
-    mercury_format_sym_name(Name, NextToGraphicToken, !IO).
+mercury_output_sym_name_ngt(Name, NextToGraphicToken, !IO) :-
+    mercury_format_sym_name_ngt(Name, NextToGraphicToken, !IO).
 
 mercury_output_bracketed_sym_name(SymName, !IO) :-
-    mercury_output_bracketed_sym_name(SymName, not_next_to_graphic_token, !IO).
+    mercury_output_bracketed_sym_name_ngt(SymName, not_next_to_graphic_token,
+        !IO).
 
 mercury_bracketed_sym_name_to_string(Name) =
-    mercury_bracketed_sym_name_to_string(Name, not_next_to_graphic_token).
+    mercury_bracketed_sym_name_to_string_ngt(Name, not_next_to_graphic_token).
 
-mercury_output_bracketed_sym_name(Name, NextToGraphicToken, !IO) :-
-    mercury_format_bracketed_sym_name(Name, NextToGraphicToken, !IO).
+mercury_output_bracketed_sym_name_ngt(Name, NextToGraphicToken, !IO) :-
+    mercury_format_bracketed_sym_name_ngt(Name, NextToGraphicToken, !IO).
 
-mercury_bracketed_sym_name_to_string(Name, NextToGraphicToken) = Str :-
-    mercury_format_bracketed_sym_name(Name, NextToGraphicToken, "", Str).
-
-:- pred mercury_format_bracketed_sym_name(sym_name::in,
-    U::di, U::uo) is det <= output(U).
+mercury_bracketed_sym_name_to_string_ngt(Name, NextToGraphicToken) = Str :-
+    mercury_format_bracketed_sym_name_ngt(Name, NextToGraphicToken, "", Str).
 
 mercury_format_bracketed_sym_name(Name, !U) :-
-    mercury_format_bracketed_sym_name(Name, not_next_to_graphic_token, !U).
+    mercury_format_bracketed_sym_name_ngt(Name, not_next_to_graphic_token, !U).
 
-:- pred mercury_format_bracketed_sym_name(sym_name::in, needs_quotes::in,
-    U::di, U::uo) is det <= output(U).
-
-mercury_format_bracketed_sym_name(Name, NextToGraphicToken, !U) :-
+mercury_format_bracketed_sym_name_ngt(Name, NextToGraphicToken, !U) :-
     (
         Name = qualified(ModuleName, Name2),
         add_string("(", !U),
-        mercury_format_bracketed_sym_name(ModuleName,
+        mercury_format_bracketed_sym_name_ngt(ModuleName,
             next_to_graphic_token, !U),
         add_string(".", !U),
         mercury_format_bracketed_atom(Name2, next_to_graphic_token, !U),
@@ -4777,19 +4583,13 @@
         mercury_format_bracketed_atom(Name2, NextToGraphicToken, !U)
     ).
 
-:- pred mercury_format_sym_name(sym_name::in, U::di, U::uo)
-    is det <= output(U).
-
 mercury_format_sym_name(SymName, !U) :-
-    mercury_format_sym_name(SymName, not_next_to_graphic_token, !U).
-
-:- pred mercury_format_sym_name(sym_name::in, needs_quotes::in, U::di, U::uo)
-    is det <= output(U).
+    mercury_format_sym_name_ngt(SymName, not_next_to_graphic_token, !U).
 
-mercury_format_sym_name(Name, NextToGraphicToken, !U) :-
+mercury_format_sym_name_ngt(Name, NextToGraphicToken, !U) :-
     (
         Name = qualified(ModuleName, PredName),
-        mercury_format_bracketed_sym_name(ModuleName,
+        mercury_format_bracketed_sym_name_ngt(ModuleName,
             next_to_graphic_token, !U),
         add_string(".", !U),
         mercury_format_quoted_atom(PredName, next_to_graphic_token, !U)
Index: compiler/mode_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_debug.m,v
retrieving revision 1.33
diff -u -b -r1.33 mode_debug.m
--- compiler/mode_debug.m	21 Jul 2009 02:08:49 -0000	1.33
+++ compiler/mode_debug.m	27 Mar 2012 06:44:44 -0000
@@ -37,6 +37,8 @@
 :- import_module libs.
 :- import_module libs.file_util.
 :- import_module hlds.
+:- import_module hlds.hlds_out.
+:- import_module hlds.hlds_out.hlds_out_mode.
 :- import_module hlds.instmap.
 :- import_module parse_tree.
 :- import_module parse_tree.mercury_to_mercury.
@@ -147,7 +149,8 @@
         ;
             Minimal = no,
             io.write_string("\n", !IO),
-            mercury_output_structured_inst(Inst, 2, InstVarSet, !IO)
+            mercury_output_structured_inst(Inst, 2, do_not_incl_addr,
+                InstVarSet, !IO)
         )
     ),
     write_var_insts(VarInsts, OldInstMap, VarSet, InstVarSet,
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.238
diff -u -b -r1.238 prog_data.m
--- compiler/prog_data.m	26 Mar 2012 00:43:32 -0000	1.238
+++ compiler/prog_data.m	26 Mar 2012 09:02:34 -0000
@@ -2047,9 +2047,8 @@
                 % insts and for compiler-generated insts.
 
     ;           abstract_inst(sym_name, list(mer_inst)).
-                % An abstract inst is a defined inst which
-                % has been declared but not actually been
-                % defined (yet).
+                % An abstract inst is a defined inst which has been declared
+                % but not actually been defined (yet).
 
 :- type uniqueness
     --->        shared              % There might be other references.
@@ -2173,9 +2172,9 @@
     ;       typed_ground(uniqueness, mer_type)
     ;       typed_inst(mer_type, inst_name).
 
-    % NOTE: `is_live' records liveness in the sense used by
-    % mode analysis.  This is not the same thing as the notion of liveness
-    % used by code generation.  See compiler/notes/glossary.html.
+    % NOTE: `is_live' records liveness in the sense used by mode analysis.
+    % This is not the same thing as the notion of liveness used by code
+    % generation. See compiler/notes/glossary.html.
     %
 :- type is_live
     --->    is_live
Index: compiler/recompilation.usage.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.usage.m,v
retrieving revision 1.62
diff -u -b -r1.62 recompilation.usage.m
--- compiler/recompilation.usage.m	13 Feb 2012 00:11:48 -0000	1.62
+++ compiler/recompilation.usage.m	27 Mar 2012 06:43:38 -0000
@@ -331,8 +331,8 @@
     io::di, io::uo) is det.
 
 write_simple_item_matches_3((Name - Arity) - Matches, !IO) :-
-    mercury_output_bracketed_sym_name(unqualified(Name), next_to_graphic_token,
-        !IO),
+    mercury_output_bracketed_sym_name_ngt(unqualified(Name),
+        next_to_graphic_token, !IO),
     io.write_string("/", !IO),
     io.write_int(Arity, !IO),
     io.write_string(" - (", !IO),
@@ -465,7 +465,7 @@
         ResolvedFunctor = resolved_functor_constructor(ItemName),
         ItemName = item_name(TypeName, Arity),
         io.write_string("ctor(", !IO),
-        mercury_output_bracketed_sym_name(TypeName, next_to_graphic_token,
+        mercury_output_bracketed_sym_name_ngt(TypeName, next_to_graphic_token,
             !IO),
         io.write_string("/", !IO),
         io.write_int(Arity, !IO),
@@ -475,12 +475,12 @@
         TypeItemName = item_name(TypeName, TypeArity),
         ConsItemName = item_name(ConsName, ConsArity),
         io.write_string("field(", !IO),
-        mercury_output_bracketed_sym_name(TypeName, next_to_graphic_token,
+        mercury_output_bracketed_sym_name_ngt(TypeName, next_to_graphic_token,
             !IO),
         io.write_string("/", !IO),
         io.write_int(TypeArity, !IO),
         io.write_string(", ", !IO),
-        mercury_output_bracketed_sym_name(ConsName, next_to_graphic_token,
+        mercury_output_bracketed_sym_name_ngt(ConsName, next_to_graphic_token,
             !IO),
         io.write_string("/", !IO),
         io.write_int(ConsArity, !IO),
Index: compiler/recompilation.version.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.79
diff -u -b -r1.79 recompilation.version.m
--- compiler/recompilation.version.m	14 Dec 2011 04:55:16 -0000	1.79
+++ compiler/recompilation.version.m	27 Mar 2012 06:43:54 -0000
@@ -1214,7 +1214,7 @@
 
 write_name_arity_version_number(NameArity - VersionNumber, !IO) :-
     NameArity = Name - Arity,
-    mercury_output_bracketed_sym_name(unqualified(Name),
+    mercury_output_bracketed_sym_name_ngt(unqualified(Name),
         next_to_graphic_token, !IO),
     io.write_string("/", !IO),
     io.write_int(Arity, !IO),
@@ -1226,7 +1226,7 @@
 
 write_symname_arity_version_number(ItemName - VersionNumber, !IO) :-
     ItemName = item_name(SymName, Arity),
-    mercury_output_bracketed_sym_name(SymName, next_to_graphic_token, !IO),
+    mercury_output_bracketed_sym_name_ngt(SymName, next_to_graphic_token, !IO),
     io.write_string("/", !IO),
     io.write_int(Arity, !IO),
     io.write_string(" - ", !IO),
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.275
diff -u -b -r1.275 simplify.m
--- compiler/simplify.m	13 Feb 2012 00:11:48 -0000	1.275
+++ compiler/simplify.m	26 Mar 2012 17:10:00 -0000
@@ -1418,7 +1418,7 @@
         ;
             simplify_do_common_struct(!.Info)
         ->
-            common_optimise_unification(U0, LT0, RT0, M, C,
+            common_optimise_unification(U0, M,
                 GoalExpr0, GoalExpr, GoalInfo0, GoalInfo, !Info)
         ;
             ( simplify_do_opt_duplicate_calls(!.Info)
@@ -1429,7 +1429,7 @@
             % used for optimizing or warning about duplicate calls.
             % But we don't want to perform the optimization, so we disregard
             % the optimized goal and instead use the original one.
-            common_optimise_unification(U0, LT0, RT0, M, C,
+            common_optimise_unification(U0, M,
                 GoalExpr0, _GoalExpr1, GoalInfo0, _GoalInfo1, !Info),
             GoalExpr = GoalExpr0,
             GoalInfo = GoalInfo0
cvs diff: Diffing compiler/notes
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.648
diff -u -b -r1.648 user_guide.texi
--- doc/user_guide.texi	18 Jan 2012 03:16:18 -0000	1.648
+++ doc/user_guide.texi	27 Mar 2012 05:35:39 -0000
@@ -7198,6 +7198,8 @@
 t - results of termination analysis,
 u - unification categories and other implementation details of unifications,
 v - variable numbers in variable names,
+x - predicate type information.
+y - structured insts in the arg-modes of unification
 z - purity annotations on impure and semipure goals
 A - argument passing information,
 B - mode constraint information,
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/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_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glfw
cvs diff: Diffing extras/graphics/mercury_glfw/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/monte
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 m4
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/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
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/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/lazy_list
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
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/feedback
cvs diff: Diffing tests/feedback/mandelbrot
cvs diff: Diffing tests/feedback/mmc
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