[m-rev.] diff: clauses to disjunctions cleanup

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Jan 21 11:29:56 AEDT 2008


This diff has no algorithmic changes.

Zoltan.

compiler/*.m:
	Convert predicates that used to have one clause for each kind of
	HLDS goal into explicit disjunctions, since this gives the debugger
	a meaningful name for each argument. In some cases, this exposed
	arguments that were used by *no* clause. In other cases, it allowed
	factoring out common code, as well as code that *should* have been
	common but wasn't.

	Put the disjuncts in a meaningful order. In too many cases, they were
	almost random.

	Merge the resulting predicates into their parents, in places where
	the Prolog indexing one could get from separate clauses was the only
	reason for separating those predicates from their parents in the first
	place. Similarly, merge child predicates handling generic call kinds
	and such back into the main predicate where this improves clarity.
	In some cases, this allows putting the extraction of hlds_goal_expr
	from a hlds_goal into one place, instead of repeating it in lots of
	places.

	Give some predicates more descriptive names. In some cases, rationalize
	argument order. In some cases, rationalize the order of predicates
	in the module.

	Replace some uses of booleans with purpose-specific types.

	Give some fields names, and put type-identifying prefixes on the names
	of other fields, to make tag files work better.

	In some cases, reorder fields to them put into related groups.

	Use more standard and/or more descriptive variable names

	Use a standard syntax for if-then-else in each module.

	Follow our style convention for comments.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/add_heap_ops.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_heap_ops.m,v
retrieving revision 1.37
diff -u -b -r1.37 add_heap_ops.m
--- compiler/add_heap_ops.m	30 Dec 2007 08:23:30 -0000	1.37
+++ compiler/add_heap_ops.m	5 Jan 2008 03:14:22 -0000
@@ -76,9 +76,9 @@
     %
 :- type heap_ops_info
     --->    heap_ops_info(
-                varset      :: prog_varset,
-                var_types   :: vartypes,
-                module_info :: module_info
+                heap_varset         :: prog_varset,
+                heap_var_types      :: vartypes,
+                heap_module_info    :: module_info
             ).
 
 add_heap_ops(ModuleInfo0, !Proc) :-
@@ -100,50 +100,63 @@
 :- pred goal_add_heap_ops(hlds_goal::in, hlds_goal::out,
     heap_ops_info::in, heap_ops_info::out) is det.
 
-goal_add_heap_ops(hlds_goal(GoalExpr0, GoalInfo), Goal, !Info) :-
+goal_add_heap_ops(Goal0, Goal, !Info) :-
+    Goal0 = hlds_goal(GoalExpr0, GoalInfo),
     goal_expr_add_heap_ops(GoalExpr0, GoalInfo, Goal, !Info).
 
 :- pred goal_expr_add_heap_ops(hlds_goal_expr::in, hlds_goal_info::in,
     hlds_goal::out, heap_ops_info::in, heap_ops_info::out) is det.
 
-goal_expr_add_heap_ops(conj(ConjType, Goals0), GI,
-        hlds_goal(conj(ConjType, Goals), GI), !Info) :-
-    conj_add_heap_ops(Goals0, Goals, !Info).
-
-goal_expr_add_heap_ops(disj([]), GI, hlds_goal(disj([]), GI), !Info).
-goal_expr_add_heap_ops(disj(Goals0), GoalInfo, hlds_goal(GoalExpr, GoalInfo),
-        !Info) :-
-    Goals0 = [FirstDisjunct | _],
-
-    Context = goal_info_get_context(GoalInfo),
-    CodeModel = goal_info_get_code_model(GoalInfo),
+goal_expr_add_heap_ops(GoalExpr0, GoalInfo0, Goal, !Info) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
+        conj_add_heap_ops(Goals0, Goals, !Info),
+        GoalExpr = conj(ConjType, Goals),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = disj(Disjuncts0),
+        (
+            Disjuncts0 = [],
+            GoalExpr = GoalExpr0
+        ;
+            Disjuncts0 = [FirstDisjunct0 | _],
+            Context = goal_info_get_context(GoalInfo0),
+            CodeModel = goal_info_get_code_model(GoalInfo0),
 
     % If necessary, save the heap pointer so that we can restore it
-    % on back-tracking. We don't need to do this here if it is a model_det
-    % or model_semi disjunction and the first disjunct won't allocate any heap
-    % -- in that case, we delay saving the heap pointer until just before
-    % the first disjunct that might allocate heap.
+            % on back-tracking. We don't need to do this here if it is a
+            % model_det or model_semi disjunction and the first disjunct
+            % won't allocate any heap -- in that case, we delay saving the heap
+            % pointer until just before the first disjunct that might allocate
+            % heap.
     (
         ( CodeModel = model_non
-        ; goal_may_allocate_heap(FirstDisjunct)
+                ; goal_may_allocate_heap(FirstDisjunct0)
         )
     ->
         new_saved_hp_var(SavedHeapPointerVar, !Info),
-        gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal, !Info),
-        disj_add_heap_ops(Goals0, yes, yes(SavedHeapPointerVar), GoalInfo,
-            Goals, !Info),
+                gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal,
+                    !Info),
+                disj_add_heap_ops(Disjuncts0, Disjuncts, is_first_disjunct,
+                    yes(SavedHeapPointerVar), GoalInfo0, !Info),
         GoalExpr = conj(plain_conj,
-            [MarkHeapPointerGoal, hlds_goal(disj(Goals), GoalInfo)])
+                    [MarkHeapPointerGoal,
+                        hlds_goal(disj(Disjuncts), GoalInfo0)])
     ;
-        disj_add_heap_ops(Goals0, yes, no, GoalInfo, Goals, !Info),
-        GoalExpr = disj(Goals)
-    ).
-
-goal_expr_add_heap_ops(switch(Var, CanFail, Cases0), GI,
-        hlds_goal(switch(Var, CanFail, Cases), GI), !Info) :-
-    cases_add_heap_ops(Cases0, Cases, !Info).
-
-goal_expr_add_heap_ops(negation(InnerGoal), OuterGoalInfo, Goal, !Info) :-
+                disj_add_heap_ops(Disjuncts0, Disjuncts, is_first_disjunct,
+                    no, GoalInfo0, !Info),
+                GoalExpr = disj(Disjuncts)
+            )
+        ),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = switch(Var, CanFail, Cases0),
+        cases_add_heap_ops(Cases0, Cases, !Info),
+        GoalExpr = switch(Var, CanFail, Cases),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = negation(InnerGoal),
+        OuterGoalInfo = GoalInfo0,
     % We handle negations by converting them into if-then-elses:
     %   not(G)  ===>  (if G then fail else true)
 
@@ -153,15 +166,15 @@
     determinism_components(Determinism, _CanFail, NumSolns),
     True = true_goal_with_context(Context),
     Fail = fail_goal_with_context(Context),
-    ModuleInfo = !.Info ^ module_info,
+        ModuleInfo = !.Info ^ heap_module_info,
     (
         NumSolns = at_most_zero,
         % The "then" part of the if-then-else will be unreachable, but to
-        % preserve the invariants that the MLDS back-end relies on, we need to
-        % make sure that it can't fail. So we use a call to
+            % preserve the invariants that the MLDS back-end relies on, we
+            % need to make sure that it can't fail. So we use a call to
         % `private_builtin.unused' (which will call error/1) rather than
         % `fail' for the "then" part.
-        generate_call("unused", detism_det, purity_pure, [], [],
+            heap_generate_call("unused", detism_det, purity_pure, [], [],
             ModuleInfo, Context, ThenGoal)
     ;
         ( NumSolns = at_most_one
@@ -171,14 +184,14 @@
         ThenGoal = Fail
     ),
     NewOuterGoal = if_then_else([], InnerGoal, ThenGoal, True),
-    goal_expr_add_heap_ops(NewOuterGoal, OuterGoalInfo, Goal, !Info).
-
-goal_expr_add_heap_ops(scope(Reason, Goal0), GoalInfo,
-        hlds_goal(scope(Reason, Goal), GoalInfo), !Info) :-
-    goal_add_heap_ops(Goal0, Goal, !Info).
-
-goal_expr_add_heap_ops(if_then_else(A, Cond0, Then0, Else0), GoalInfo,
-        hlds_goal(GoalExpr, GoalInfo), !Info) :-
+        goal_expr_add_heap_ops(NewOuterGoal, OuterGoalInfo, Goal, !Info)
+    ;
+        GoalExpr0 = scope(Reason, SubGoal0),
+        goal_add_heap_ops(SubGoal0, SubGoal, !Info),
+        GoalExpr = scope(Reason, SubGoal),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
     goal_add_heap_ops(Cond0, Cond, !Info),
     goal_add_heap_ops(Then0, Then, !Info),
     goal_add_heap_ops(Else0, Else1, !Info),
@@ -187,43 +200,45 @@
     % so that we can restore it if the condition fails.
     ( goal_may_allocate_heap(Cond0) ->
         new_saved_hp_var(SavedHeapPointerVar, !Info),
-        Context = goal_info_get_context(GoalInfo),
-        gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal, !Info),
+            Context = goal_info_get_context(GoalInfo0),
+            gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal,
+                !Info),
 
         % Generate code to restore the heap pointer, and insert that code
         % at the start of the Else branch.
-        gen_restore_hp(SavedHeapPointerVar, Context, RestoreHeapPointerGoal,
-            !Info),
+            gen_restore_hp(SavedHeapPointerVar, Context,
+                RestoreHeapPointerGoal, !Info),
         Else1 = hlds_goal(_, Else1GoalInfo),
         Else = hlds_goal(
             conj(plain_conj, [RestoreHeapPointerGoal, Else1]),
             Else1GoalInfo),
-        IfThenElse = hlds_goal(if_then_else(A, Cond, Then, Else), GoalInfo),
+            IfThenElseExpr = if_then_else(Vars, Cond, Then, Else),
+            IfThenElse = hlds_goal(IfThenElseExpr, GoalInfo0),
         GoalExpr = conj(plain_conj, [MarkHeapPointerGoal, IfThenElse])
     ;
-        GoalExpr = if_then_else(A, Cond, Then, Else1)
-    ).
-
-goal_expr_add_heap_ops(GoalExpr @ plain_call(_, _, _, _, _, _), GI,
-        hlds_goal(GoalExpr, GI), !Info).
-goal_expr_add_heap_ops(GoalExpr @ generic_call(_, _, _, _), GI,
-        hlds_goal(GoalExpr, GI), !Info).
-goal_expr_add_heap_ops(GoalExpr @ unify(_, _, _, _, _), GI,
-        hlds_goal(GoalExpr, GI), !Info).
-
-goal_expr_add_heap_ops(PragmaForeign, GoalInfo, Goal, !Info) :-
-    PragmaForeign = call_foreign_proc(_, _, _, _, _, _, Impl),
+            GoalExpr = if_then_else(Vars, Cond, Then, Else1)
+        ),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        ( GoalExpr0 = plain_call(_, _, _, _, _, _)
+        ; GoalExpr0 = generic_call(_, _, _, _)
+        ; GoalExpr0 = unify(_, _, _, _, _)
+        ),
+        Goal = hlds_goal(GoalExpr0, GoalInfo0)
+    ;
+        GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, Impl),
     (
         Impl = fc_impl_model_non(_, _, _, _, _, _, _, _, _),
         % XXX Implementing heap reclamation for nondet pragma foreign_code
-        % via transformation is difficult, because there's nowhere in the HLDS
-        % pragma_foreign_code goal where we can insert the heap reclamation
-        % operations. For now, we don't support this. Instead, we just generate
-        % a call to a procedure which will at runtime call error/1 with an
-        % appropriate "Sorry, not implemented" error message.
-        ModuleInfo = !.Info ^ module_info,
-        Context = goal_info_get_context(GoalInfo),
-        generate_call("reclaim_heap_nondet_pragma_foreign_code",
+            % via transformation is difficult, because there's nowhere in the
+            % HLDS pragma_foreign_code goal where we can insert the heap
+            % reclamation operations. For now, we don't support this. Instead,
+            % we just generate a call to a procedure which will at runtime
+            % call error/1 with an appropriate "Sorry, not implemented"
+            % error message.
+            ModuleInfo = !.Info ^ heap_module_info,
+            Context = goal_info_get_context(GoalInfo0),
+            heap_generate_call("reclaim_heap_nondet_pragma_foreign_code",
             detism_erroneous, purity_pure, [], [], ModuleInfo, Context,
             SorryNotImplementedCode),
         Goal = SorryNotImplementedCode
@@ -231,12 +246,13 @@
         ( Impl = fc_impl_ordinary(_, _)
         ; Impl = fc_impl_import(_, _, _, _)
         ),
-        Goal = hlds_goal(PragmaForeign, GoalInfo)
-    ).
-
-goal_expr_add_heap_ops(shorthand(_), _, _, !Info) :-
+            Goal = hlds_goal(GoalExpr0, GoalInfo0)
+        )
+    ;
+        GoalExpr0 = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "goal_expr_add_heap_ops: unexpected shorthand").
+        unexpected(this_file, "goal_expr_add_heap_ops: unexpected shorthand")
+    ).
 
 :- pred conj_add_heap_ops(hlds_goals::in, hlds_goals::out,
     heap_ops_info::in, heap_ops_info::out) is det.
@@ -244,13 +260,13 @@
 conj_add_heap_ops(Goals0, Goals, !Info) :-
     list.map_foldl(goal_add_heap_ops, Goals0, Goals, !Info).
 
-:- pred disj_add_heap_ops(hlds_goals::in, bool::in, maybe(prog_var)::in,
-    hlds_goal_info::in, hlds_goals::out,
+:- pred disj_add_heap_ops(list(hlds_goal)::in, list(hlds_goal)::out,
+    is_first_disjunct::in, maybe(prog_var)::in, hlds_goal_info::in, 
     heap_ops_info::in, heap_ops_info::out) is det.
 
-disj_add_heap_ops([], _, _, _, [], !Info).
-disj_add_heap_ops([Goal0 | Goals0], IsFirstBranch, MaybeSavedHeapPointerVar,
-        DisjGoalInfo, DisjGoals, !Info) :-
+disj_add_heap_ops([], [], _, _, _, !Info).
+disj_add_heap_ops([Goal0 | Goals0], DisjGoals, IsFirstBranch,
+        MaybeSavedHeapPointerVar, DisjGoalInfo, !Info) :-
     goal_add_heap_ops(Goal0, Goal1, !Info),
     Goal1 = hlds_goal(_, GoalInfo),
     Context = goal_info_get_context(GoalInfo),
@@ -258,7 +274,7 @@
     % If needed, reset the heap pointer before executing the goal,
     % to reclaim heap space allocated in earlier branches.
     (
-        IsFirstBranch = no,
+        IsFirstBranch = is_not_first_disjunct,
         MaybeSavedHeapPointerVar = yes(SavedHeapPointerVar0)
     ->
         gen_restore_hp(SavedHeapPointerVar0, Context, RestoreHeapPointerGoal,
@@ -279,8 +295,8 @@
         gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal, !Info),
 
         % Recursively handle the remaining disjuncts.
-        disj_add_heap_ops(Goals0, no, yes(SavedHeapPointerVar), DisjGoalInfo,
-            Goals1, !Info),
+        disj_add_heap_ops(Goals0, Goals1, is_not_first_disjunct,
+            yes(SavedHeapPointerVar), DisjGoalInfo, !Info),
         % Put this disjunct and the remaining disjuncts in a nested
         % disjunction, so that the heap pointer variable can scope over
         % these disjuncts.
@@ -291,8 +307,8 @@
         DisjGoals = [DisjGoal]
     ;
         % Just recursively handle the remaining disjuncts.
-        disj_add_heap_ops(Goals0, no, MaybeSavedHeapPointerVar, DisjGoalInfo,
-            Goals, !Info),
+        disj_add_heap_ops(Goals0, Goals, is_not_first_disjunct,
+            MaybeSavedHeapPointerVar, DisjGoalInfo, !Info),
         DisjGoals = [Goal | Goals]
     ).
 
@@ -312,16 +328,16 @@
     heap_ops_info::in, heap_ops_info::out) is det.
 
 gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal, !Info) :-
-    generate_call("mark_hp", detism_det, purity_impure, [SavedHeapPointerVar],
-        [SavedHeapPointerVar - ground_inst], !.Info ^ module_info, Context,
-        MarkHeapPointerGoal).
+    heap_generate_call("mark_hp", detism_det, purity_impure,
+        [SavedHeapPointerVar], [SavedHeapPointerVar - ground_inst],
+        !.Info ^ heap_module_info, Context, MarkHeapPointerGoal).
 
 :- pred gen_restore_hp(prog_var::in, prog_context::in, hlds_goal::out,
     heap_ops_info::in, heap_ops_info::out) is det.
 
 gen_restore_hp(SavedHeapPointerVar, Context, RestoreHeapPointerGoal, !Info) :-
-    generate_call("restore_hp", detism_det, purity_impure,
-        [SavedHeapPointerVar], [], !.Info ^ module_info, Context,
+    heap_generate_call("restore_hp", detism_det, purity_impure,
+        [SavedHeapPointerVar], [], !.Info ^ heap_module_info, Context,
         RestoreHeapPointerGoal).
 
 :- func ground_inst = mer_inst.
@@ -340,24 +356,23 @@
     heap_ops_info::in, heap_ops_info::out) is det.
 
 new_var(Name, Type, Var, !Info) :-
-    VarSet0 = !.Info ^ varset,
-    VarTypes0 = !.Info ^ var_types,
+    VarSet0 = !.Info ^ heap_varset,
+    VarTypes0 = !.Info ^ heap_var_types,
     varset.new_named_var(VarSet0, Name, Var, VarSet),
     map.det_insert(VarTypes0, Var, Type, VarTypes),
-    !:Info = !.Info ^ varset := VarSet,
-    !:Info = !.Info ^ var_types := VarTypes.
+    !:Info = !.Info ^ heap_varset := VarSet,
+    !:Info = !.Info ^ heap_var_types := VarTypes.
 
 %-----------------------------------------------------------------------------%
 
-:- pred generate_call(string::in, determinism::in, purity::in,
+:- pred heap_generate_call(string::in, determinism::in, purity::in,
     list(prog_var)::in, assoc_list(prog_var, mer_inst)::in, module_info::in,
     term.context::in, hlds_goal::out) is det.
 
-generate_call(PredName, Detism, Purity, Args, InstMap, ModuleInfo, Context,
-        CallGoal) :-
-    BuiltinModule = mercury_private_builtin_module,
-    goal_util.generate_simple_call(BuiltinModule, PredName, pf_predicate,
-        only_mode, Detism, Purity, Args, [], InstMap, ModuleInfo,
+heap_generate_call(PredName, Detism, Purity, Args, InstMap, ModuleInfo,
+        Context, CallGoal) :-
+    goal_util.generate_simple_call(mercury_private_builtin_module, PredName,
+        pf_predicate, only_mode, Detism, Purity, Args, [], InstMap, ModuleInfo,
         Context, CallGoal).
 
 %-----------------------------------------------------------------------------%
Index: compiler/add_trail_ops.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_trail_ops.m,v
retrieving revision 1.49
diff -u -b -r1.49 add_trail_ops.m
--- compiler/add_trail_ops.m	30 Dec 2007 08:23:30 -0000	1.49
+++ compiler/add_trail_ops.m	5 Jan 2008 03:13:39 -0000
@@ -103,9 +103,9 @@
     %
 :- type trail_ops_info
     --->    trail_ops_info(
-                varset          :: prog_varset,
-                var_types       :: vartypes,
-                module_info     :: module_info,
+                trail_varset        :: prog_varset,
+                trail_var_types     :: vartypes,
+                trail_module_info   :: module_info,
                 opt_trail_usage :: bool,
                 inline_ops      :: bool
             ).
@@ -130,38 +130,47 @@
 :- pred goal_add_trail_ops(hlds_goal::in, hlds_goal::out,
     trail_ops_info::in, trail_ops_info::out) is det.
 
-goal_add_trail_ops(!Goal, !Info) :-
-    !.Goal = hlds_goal(GoalExpr0, GoalInfo),
-    goal_expr_add_trail_ops(GoalExpr0, GoalInfo, !:Goal, !Info).
+goal_add_trail_ops(Goal0, Goal, !Info) :-
+    Goal0 = hlds_goal(GoalExpr0, GoalInfo),
+    goal_expr_add_trail_ops(GoalExpr0, GoalInfo, Goal, !Info).
 
 :- pred goal_expr_add_trail_ops(hlds_goal_expr::in, hlds_goal_info::in,
     hlds_goal::out, trail_ops_info::in, trail_ops_info::out) is det.
 
-goal_expr_add_trail_ops(conj(ConjType, Goals0), GI,
-        hlds_goal(conj(ConjType, Goals), GI), !Info) :-
-    conj_add_trail_ops(Goals0, Goals, !Info).
-
-goal_expr_add_trail_ops(disj([]), GI, hlds_goal(disj([]), GI), !Info).
-goal_expr_add_trail_ops(disj(Goals0), GoalInfo, hlds_goal(GoalExpr, GoalInfo),
-        !Info) :-
-    Goals0 = [_ | _],
-    Context = goal_info_get_context(GoalInfo),
-    CodeModel = goal_info_get_code_model(GoalInfo),
-    %
+goal_expr_add_trail_ops(GoalExpr0, GoalInfo0, Goal, !Info) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
+        conj_add_trail_ops(Goals0, Goals, !Info),
+        GoalExpr = conj(ConjType, Goals),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = disj(Disjuncts0),
+        (
+            Disjuncts0 = [],
+            GoalExpr = GoalExpr0
+        ;
+            Disjuncts0 = [_ | _],
+            Context = goal_info_get_context(GoalInfo0),
+            CodeModel = goal_info_get_code_model(GoalInfo0),
+
     % Allocate a new trail ticket so that we can restore things on
     % back-tracking.
-    %
     new_ticket_var(TicketVar, !Info),
     gen_store_ticket(TicketVar, Context, StoreTicketGoal, !.Info),
-    disj_add_trail_ops(Goals0, yes, CodeModel, TicketVar, Goals, !Info),
+            disj_add_trail_ops(Disjuncts0, Disjuncts, is_first_disjunct,
+                CodeModel, TicketVar, !Info),
     GoalExpr = conj(plain_conj,
-        [StoreTicketGoal, hlds_goal(disj(Goals), GoalInfo)]).
-
-goal_expr_add_trail_ops(switch(A, B, Cases0), GI,
-        hlds_goal(switch(A, B, Cases), GI), !Info) :-
-    cases_add_trail_ops(Cases0, Cases, !Info).
-
-goal_expr_add_trail_ops(negation(InnerGoal), OuterGoalInfo, Goal, !Info) :-
+                [StoreTicketGoal, hlds_goal(disj(Disjuncts), GoalInfo0)])
+        ),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = switch(Var, CanFail, Cases0),
+        cases_add_trail_ops(Cases0, Cases, !Info),
+        GoalExpr = switch(Var, CanFail, Cases),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = negation(InnerGoal),
+        OuterGoalInfo = GoalInfo0,
     % We handle negations by converting them into if-then-elses:
     %   not(G)  ===>  (if G then fail else true)
 
@@ -171,17 +180,16 @@
     determinism_components(Determinism, _CanFail, NumSolns),
     True = true_goal_with_context(Context),
     Fail = fail_goal_with_context(Context),
-    ModuleInfo = !.Info ^ module_info,
+        ModuleInfo = !.Info ^ trail_module_info,
     (
         NumSolns = at_most_zero,
         % The "then" part of the if-then-else will be unreachable, but to
-        % preserve the invariants that the MLDS back-end relies on, we need to
-        % make sure that it can't fail. So we use a call to
+            % preserve the invariants that the MLDS back-end relies on, we
+            % need to make sure that it can't fail. So we use a call to
         % `private_builtin.unused' (which will call error/1) rather than
         % `fail' for the "then" part.
-        PrivateBuiltin = mercury_private_builtin_module,
-        generate_simple_call(PrivateBuiltin, "unused", pf_predicate, only_mode,
-            detism_det, purity_pure, [], [], [], ModuleInfo, Context, ThenGoal)
+            trail_generate_call("unused", detism_det, purity_pure, [], [],
+                ModuleInfo, Context, ThenGoal)
     ;
         ( NumSolns = at_most_one
         ; NumSolns = at_most_many
@@ -190,11 +198,11 @@
         ThenGoal = Fail
     ),
     NewOuterGoal = if_then_else([], InnerGoal, ThenGoal, True),
-    goal_expr_add_trail_ops(NewOuterGoal, OuterGoalInfo, Goal, !Info).
-
-goal_expr_add_trail_ops(scope(Reason, Goal0), OuterGoalInfo,
-        hlds_goal(GoalExpr, OuterGoalInfo), !Info) :-
-    Goal0 = hlds_goal(_, InnerGoalInfo),
+        goal_expr_add_trail_ops(NewOuterGoal, OuterGoalInfo, Goal, !Info)
+    ;
+        GoalExpr0 = scope(Reason, InnerGoal0),
+        OuterGoalInfo = GoalInfo0,
+        InnerGoal0 = hlds_goal(_, InnerGoalInfo),
     InnerCodeModel = goal_info_get_code_model(InnerGoalInfo),
     OuterCodeModel = goal_info_get_code_model(OuterGoalInfo),
     (
@@ -213,11 +221,12 @@
         gen_store_ticket(TicketVar, Context, StoreTicketGoal, !.Info),
 
         % Next we execute the goal that we're committing across.
-        goal_add_trail_ops(Goal0, Goal1, !Info),
+            goal_add_trail_ops(InnerGoal0, InnerGoal, !Info),
 
-        % If the goal succeeds, then we have committed to that goal, so we need
-        % to commit the trail entries and prune any trail tickets that have
-        % been allocated since we saved the ticket counter.
+            % If the goal succeeds, then we have committed to that goal,
+            % so we need to commit the trail entries and prune any trail
+            % tickets that have been allocated since we saved the ticket
+            % counter.
         gen_reset_ticket_commit(TicketVar, Context,
             ResetTicketCommitGoal, !.Info),
         gen_prune_tickets_to(SavedTicketCounterVar, Context,
@@ -225,12 +234,13 @@
 
         % If the goal fails, then we should undo the trail entries and
         % discard this trail ticket before backtracking over it.
-        gen_reset_ticket_undo(TicketVar, Context, ResetTicketUndoGoal, !.Info),
+            gen_reset_ticket_undo(TicketVar, Context, ResetTicketUndoGoal,
+                !.Info),
         gen_discard_ticket(Context, DiscardTicketGoal, !.Info),
         FailGoal = fail_goal_with_context(Context),
 
         % Put it all together.
-        Goal2 = hlds_goal(scope(Reason, Goal1), OuterGoalInfo),
+            Goal2 = hlds_goal(scope(Reason, InnerGoal), OuterGoalInfo),
         SuccCode = hlds_goal(
             conj(plain_conj,
                 [Goal2, ResetTicketCommitGoal, PruneTicketsToGoal]),
@@ -252,19 +262,18 @@
         GoalExpr =
             conj(plain_conj, [MarkTicketStackGoal, StoreTicketGoal, Goal3])
     ;
-        goal_add_trail_ops(Goal0, Goal1, !Info),
-        GoalExpr = scope(Reason, Goal1)
-    ).
-
-goal_expr_add_trail_ops(if_then_else(ExistQVars, Cond0, Then0, Else0),
-        GoalInfo, hlds_goal(GoalExpr, GoalInfo), !Info) :-
+            goal_add_trail_ops(InnerGoal0, InnerGoal, !Info),
+            GoalExpr = scope(Reason, InnerGoal)
+        ),
+        Goal = hlds_goal(GoalExpr, OuterGoalInfo)
+    ;
+        GoalExpr0 = if_then_else(ExistQVars, Cond0, Then0, Else0),
     goal_add_trail_ops(Cond0, Cond, !Info),
     goal_add_trail_ops(Then0, Then1, !Info),
     goal_add_trail_ops(Else0, Else1, !Info),
-    %
+
     % If the condition does not modify the trail and does not create
-    % any choicepoints then we can omit the trailing code around it.
-    %
+        % any choicepoints, then we can omit the trailing code around it.
     OptTrailUsage = !.Info ^ opt_trail_usage,
     Cond = hlds_goal(_, CondGoalInfo),
     CondCodeModel = goal_info_get_code_model(CondGoalInfo),
@@ -277,18 +286,17 @@
     ;
         % Allocate a new trail ticket so that we can restore things if the
         % condition fails.
-        %
+
         new_ticket_var(TicketVar, !Info),
-        Context = goal_info_get_context(GoalInfo),
+            Context = goal_info_get_context(GoalInfo0),
         gen_store_ticket(TicketVar, Context, StoreTicketGoal, !.Info),
-        %
+
         % Commit the trail ticket entries if the condition succeeds.
-        %
         Then1 = hlds_goal(_, Then1GoalInfo),
         (
             CondCodeModel = model_non,
-            gen_reset_ticket_solve(TicketVar, Context, ResetTicketSolveGoal,
-                !.Info),
+                gen_reset_ticket_solve(TicketVar, Context,
+                    ResetTicketSolveGoal, !.Info),
             Then = hlds_goal(
                 conj(plain_conj, [ResetTicketSolveGoal, Then1]),
                 Then1GoalInfo)
@@ -296,47 +304,46 @@
             ( CondCodeModel = model_det
             ; CondCodeModel = model_semi
             ),
-            gen_reset_ticket_commit(TicketVar, Context, ResetTicketCommitGoal,
-                !.Info),
+                gen_reset_ticket_commit(TicketVar, Context,
+                    ResetTicketCommitGoal, !.Info),
             gen_prune_ticket(Context, PruneTicketGoal, !.Info),
             Then = hlds_goal(
                 conj(plain_conj,
                     [ResetTicketCommitGoal, PruneTicketGoal, Then1]),
                 Then1GoalInfo)
         ),
-        gen_reset_ticket_undo(TicketVar, Context, ResetTicketUndoGoal, !.Info),
+            gen_reset_ticket_undo(TicketVar, Context, ResetTicketUndoGoal,
+                !.Info),
         gen_discard_ticket(Context, DiscardTicketGoal, !.Info),
         Else1 = hlds_goal(_, Else1GoalInfo),
         Else = hlds_goal(
-            conj(plain_conj, [ResetTicketUndoGoal, DiscardTicketGoal, Else1]),
+                conj(plain_conj,
+                    [ResetTicketUndoGoal, DiscardTicketGoal, Else1]),
             Else1GoalInfo),
         IfThenElse = hlds_goal(
             if_then_else(ExistQVars, Cond, Then, Else),
-            GoalInfo),
+                GoalInfo0),
         GoalExpr = conj(plain_conj, [StoreTicketGoal, IfThenElse])
-    ).
-
-goal_expr_add_trail_ops(GoalExpr @ plain_call(_, _, _, _, _, _), GI,
-        hlds_goal(GoalExpr, GI), !Info).
-
-goal_expr_add_trail_ops(GoalExpr @ generic_call(_, _, _, _), GI,
-        hlds_goal(GoalExpr, GI), !Info).
-
-goal_expr_add_trail_ops(GoalExpr @ unify(_, _, _, _, _), GI,
-        hlds_goal(GoalExpr, GI), !Info).
-
-goal_expr_add_trail_ops(PragmaForeign, GoalInfo, Goal, !Info) :-
-    PragmaForeign = call_foreign_proc(_, _, _, _, _, _, Impl),
+        ),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        ( GoalExpr0 = plain_call(_, _, _, _, _, _)
+        ; GoalExpr0 = generic_call(_, _, _, _)
+        ; GoalExpr0 = unify(_, _, _, _, _)
+        ),
+        Goal = hlds_goal(GoalExpr0, GoalInfo0)
+    ;
+        GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, Impl),
     (
         Impl = fc_impl_model_non(_, _, _, _, _, _, _, _, _),
         % XXX Implementing trailing for nondet pragma foreign_code via
         % transformation is difficult, because there's nowhere in the HLDS
         % pragma_foreign_code goal where we can insert trailing operations.
         % For now, we don't support this. Instead, we just generate a call
-        % to a procedure which will at runtime call error/1 with an appropriate
-        % "Sorry, not implemented" error message.
-        ModuleInfo = !.Info^ module_info,
-        Context = goal_info_get_context(GoalInfo),
+            % to a procedure which will at runtime call error/1 with an
+            % appropriate "Sorry, not implemented" error message.
+            ModuleInfo = !.Info ^ trail_module_info,
+            Context = goal_info_get_context(GoalInfo0),
         trail_generate_call("trailed_nondet_pragma_foreign_code",
             detism_erroneous, purity_pure, [], [], ModuleInfo, Context,
             SorryNotImplementedCode),
@@ -345,12 +352,13 @@
         ( Impl = fc_impl_ordinary(_, _)
         ; Impl = fc_impl_import(_, _, _, _)
         ),
-        Goal = hlds_goal(PragmaForeign, GoalInfo)
-    ).
-
-goal_expr_add_trail_ops(shorthand(_), _, _, !Info) :-
+            Goal = hlds_goal(GoalExpr0, GoalInfo0)
+        )
+    ;
+        GoalExpr0 = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "goal_expr_add_trail_ops: unexpected shorthand").
+        unexpected(this_file, "goal_expr_add_trail_ops: unexpected shorthand")
+    ).
 
 :- pred conj_add_trail_ops(hlds_goals::in, hlds_goals::out,
     trail_ops_info::in, trail_ops_info::out) is det.
@@ -358,22 +366,22 @@
 conj_add_trail_ops(Goals0, Goals, !Info) :-
     list.map_foldl(goal_add_trail_ops, Goals0, Goals, !Info).
 
-:- pred disj_add_trail_ops(hlds_goals::in, bool::in, code_model::in,
-    prog_var::in, hlds_goals::out, trail_ops_info::in, trail_ops_info::out)
-    is det.
-
-disj_add_trail_ops([], _, _, _, [], !Info).
-disj_add_trail_ops([Goal0 | Goals0], IsFirstBranch, CodeModel, TicketVar,
-        [Goal | Goals], !Info) :-
+:- pred disj_add_trail_ops(list(hlds_goal)::in, list(hlds_goal)::out,
+    is_first_disjunct::in, code_model::in, prog_var::in,
+    trail_ops_info::in, trail_ops_info::out) is det.
+
+disj_add_trail_ops([], [], _, _, _, !Info).
+disj_add_trail_ops([Goal0 | Goals0], [Goal | Goals], IsFirstBranch, CodeModel,
+        TicketVar, !Info) :-
     Goal0 = hlds_goal(_, GoalInfo0),
     Context = goal_info_get_context(GoalInfo0),
 
     % First undo the effects of any earlier branches.
     (
-        IsFirstBranch = yes,
+        IsFirstBranch = is_first_disjunct,
         UndoList = []
     ;
-        IsFirstBranch = no,
+        IsFirstBranch = is_not_first_disjunct,
         gen_reset_ticket_undo(TicketVar, Context, ResetTicketUndoGoal, !.Info),
         UndoList0 = [ResetTicketUndoGoal],
         (
@@ -410,7 +418,8 @@
     conj_list_to_goal(UndoList ++ [Goal1] ++ PruneList, GoalInfo1, Goal),
 
     % Recursively handle the remaining disjuncts.
-    disj_add_trail_ops(Goals0, no, CodeModel, TicketVar, Goals, !Info).
+    disj_add_trail_ops(Goals0, Goals, is_not_first_disjunct, CodeModel,
+        TicketVar, !Info).
 
 :- pred cases_add_trail_ops(list(case)::in, list(case)::out,
     trail_ops_info::in, trail_ops_info::out) is det.
@@ -433,14 +442,14 @@
         GenerateInline = no,
         trail_generate_call("store_ticket", detism_det, purity_impure,
             [TicketVar], [TicketVar - trail_ground_inst],
-            Info ^ module_info, Context, SaveTicketGoal)
+            Info ^ trail_module_info, Context, SaveTicketGoal)
     ;
         GenerateInline =  yes,
         Args = [foreign_arg(TicketVar, yes("Ticket" - out_mode),
             ticket_type, native_if_possible)],
         ForeignCode = "MR_store_ticket(Ticket);",
         trail_generate_foreign_proc("store_ticket", purity_impure,
-            [TicketVar - trail_ground_inst], Info ^ module_info, Context,
+            [TicketVar - trail_ground_inst], Info ^ trail_module_info, Context,
             Args, ForeignCode, SaveTicketGoal)
     ).
 
@@ -452,14 +461,15 @@
     (
         GenerateInline = no,
         trail_generate_call("reset_ticket_undo", detism_det, purity_impure,
-            [TicketVar], [], Info ^ module_info, Context, ResetTicketGoal)
+            [TicketVar], [], Info ^ trail_module_info, Context,
+            ResetTicketGoal)
     ;
         GenerateInline = yes,
         Args = [foreign_arg(TicketVar, yes("Ticket" - in_mode),
             ticket_type, native_if_possible)],
         ForeignCode = "MR_reset_ticket(Ticket, MR_undo);",
         trail_generate_foreign_proc("reset_ticket_undo", purity_impure,
-            [], Info ^ module_info, Context, Args, ForeignCode,
+            [], Info ^ trail_module_info, Context, Args, ForeignCode,
             ResetTicketGoal)
     ).
 
@@ -471,14 +481,15 @@
     (
         GenerateInline = no,
         trail_generate_call("reset_ticket_solve", detism_det, purity_impure,
-            [TicketVar], [], Info ^ module_info, Context, ResetTicketGoal)
+            [TicketVar], [], Info ^ trail_module_info, Context,
+            ResetTicketGoal)
     ;
         GenerateInline = yes,
         Args = [foreign_arg(TicketVar, yes("Ticket" - in_mode),
             ticket_type, native_if_possible)],
         ForeignCode = "MR_reset_ticket(Ticket, MR_solve);",
         trail_generate_foreign_proc("reset_ticket_solve", purity_impure,
-            [], Info ^ module_info, Context, Args, ForeignCode,
+            [], Info ^ trail_module_info, Context, Args, ForeignCode,
             ResetTicketGoal)
     ).
 
@@ -490,14 +501,15 @@
     (
         GenerateInline = no,
         trail_generate_call("reset_ticket_commit", detism_det, purity_impure,
-            [TicketVar], [], Info ^ module_info, Context, ResetTicketGoal)
+            [TicketVar], [], Info ^ trail_module_info, Context,
+            ResetTicketGoal)
     ;
         GenerateInline = yes,
         Args = [foreign_arg(TicketVar, yes("Ticket" - in_mode),
             ticket_type, native_if_possible)],
         ForeignCode = "MR_reset_ticket(Ticket, MR_commit);",
         trail_generate_foreign_proc("reset_ticket_commit", purity_impure,
-            [], Info ^ module_info, Context, Args, ForeignCode,
+            [], Info ^ trail_module_info, Context, Args, ForeignCode,
             ResetTicketGoal)
     ).
 
@@ -509,13 +521,13 @@
     (
         GenerateInline = no,
         trail_generate_call("prune_ticket", detism_det, purity_impure,
-            [], [], Info ^ module_info, Context, PruneTicketGoal)
+            [], [], Info ^ trail_module_info, Context, PruneTicketGoal)
     ;
         GenerateInline = yes,
         Args = [],
         ForeignCode = "MR_prune_ticket();",
         trail_generate_foreign_proc("prune_ticket", purity_impure,
-            [], Info ^ module_info, Context, Args, ForeignCode,
+            [], Info ^ trail_module_info, Context, Args, ForeignCode,
             PruneTicketGoal)
     ).
 
@@ -527,13 +539,13 @@
     (
         GenerateInline = no,
         trail_generate_call("discard_ticket", detism_det, purity_impure,
-            [], [], Info ^ module_info, Context, DiscardTicketGoal)
+            [], [], Info ^ trail_module_info, Context, DiscardTicketGoal)
     ;
         GenerateInline = yes,
         Args = [],
         ForeignCode = "MR_discard_ticket();",
         trail_generate_foreign_proc("discard_ticket", purity_impure,
-            [], Info ^ module_info, Context, Args, ForeignCode,
+            [], Info ^ trail_module_info, Context, Args, ForeignCode,
             DiscardTicketGoal)
     ).
 
@@ -546,7 +558,7 @@
     (
         GenerateInline = no,
         trail_generate_call("mark_ticket_stack", detism_det, purity_impure,
-            [SavedTicketCounterVar], [], Info ^ module_info, Context,
+            [SavedTicketCounterVar], [], Info ^ trail_module_info, Context,
             MarkTicketStackGoal)
     ;
         GenerateInline = yes,
@@ -555,7 +567,7 @@
             native_if_possible)],
         ForeignCode = "MR_mark_ticket_stack(TicketCounter);",
         trail_generate_foreign_proc("mark_ticket_stack", purity_impure,
-            [], Info ^ module_info, Context, Args, ForeignCode,
+            [], Info ^ trail_module_info, Context, Args, ForeignCode,
             MarkTicketStackGoal)
     ).
 
@@ -568,7 +580,7 @@
     (
         GenerateInline = no,
         trail_generate_call("prune_tickets_to", detism_det, purity_impure,
-            [SavedTicketCounterVar], [], Info ^ module_info, Context,
+            [SavedTicketCounterVar], [], Info ^ trail_module_info, Context,
             PruneTicketsToGoal)
     ;
         GenerateInline = yes,
@@ -577,7 +589,7 @@
             native_if_possible)],
         ForeignCode = "MR_prune_tickets_to(TicketCounter);",
         trail_generate_foreign_proc("prune_tickets_to", purity_impure,
-            [], Info ^ module_info, Context, Args, ForeignCode,
+            [], Info ^ trail_module_info, Context, Args, ForeignCode,
             PruneTicketsToGoal)
     ).
 
@@ -603,12 +615,12 @@
     trail_ops_info::in, trail_ops_info::out) is det.
 
 new_var(Name, Type, Var, !Info) :-
-    VarSet0 = !.Info ^ varset,
-    VarTypes0 = !.Info ^ var_types,
+    VarSet0 = !.Info ^ trail_varset,
+    VarTypes0 = !.Info ^ trail_var_types,
     varset.new_named_var(VarSet0, Name, Var, VarSet),
     map.det_insert(VarTypes0, Var, Type, VarTypes),
-    !:Info = !.Info ^ varset := VarSet,
-    !:Info = !.Info ^ var_types := VarTypes.
+    !:Info = !.Info ^ trail_varset := VarSet,
+    !:Info = !.Info ^ trail_var_types := VarTypes.
 
 %-----------------------------------------------------------------------------%
 
@@ -628,10 +640,9 @@
 
 trail_generate_call(PredName, Detism, Purity, Args, InstMap, ModuleInfo,
         Context, CallGoal) :-
-    BuiltinModule = mercury_private_builtin_module,
-    goal_util.generate_simple_call(BuiltinModule, PredName, pf_predicate,
-        only_mode, Detism, Purity, Args, [], InstMap, ModuleInfo, Context,
-        CallGoal).
+    goal_util.generate_simple_call(mercury_private_builtin_module, PredName,
+        pf_predicate, only_mode, Detism, Purity, Args, [], InstMap, ModuleInfo,
+        Context, CallGoal).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/cse_detection.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.113
diff -u -b -r1.113 cse_detection.m
--- compiler/cse_detection.m	30 Dec 2007 08:23:34 -0000	1.113
+++ compiler/cse_detection.m	5 Jan 2008 02:23:15 -0000
@@ -103,7 +103,6 @@
     detect_cse_in_procs(ProcIds, PredId, !ModuleInfo, !IO).
 
 detect_cse_in_proc(ProcId, PredId, !ModuleInfo, !IO) :-
-    detect_cse_in_proc_2(ProcId, PredId, Redo, !ModuleInfo),
     globals.io_lookup_bool_option(very_verbose, VeryVerbose, !IO),
     (
         VeryVerbose = yes,
@@ -113,6 +112,7 @@
     ;
         VeryVerbose = no
     ),
+    detect_cse_in_proc_pass(ProcId, PredId, Redo, !ModuleInfo),
     globals.io_lookup_bool_option(detailed_statistics, Statistics, !IO),
     maybe_report_stats(Statistics, !IO),
     (
@@ -168,10 +168,10 @@
                 module_info     :: module_info
             ).
 
-:- pred detect_cse_in_proc_2(proc_id::in, pred_id::in, bool::out,
+:- pred detect_cse_in_proc_pass(proc_id::in, pred_id::in, bool::out,
     module_info::in, module_info::out) is det.
 
-detect_cse_in_proc_2(ProcId, PredId, Redo, ModuleInfo0, ModuleInfo) :-
+detect_cse_in_proc_pass(ProcId, PredId, Redo, ModuleInfo0, ModuleInfo) :-
     module_info_preds(ModuleInfo0, PredTable0),
     map.lookup(PredTable0, PredId, PredInfo0),
     pred_info_get_procedures(PredInfo0, ProcTable0),
@@ -187,7 +187,7 @@
     proc_info_get_vartypes(ProcInfo0, VarTypes0),
     proc_info_get_rtti_varmaps(ProcInfo0, RttiVarMaps0),
     CseInfo0 = cse_info(Varset0, VarTypes0, RttiVarMaps0, ModuleInfo0),
-    detect_cse_in_goal(Goal0, InstMap0, CseInfo0, CseInfo, Redo, Goal1),
+    detect_cse_in_goal(Goal0, Goal1, CseInfo0, CseInfo, InstMap0, Redo),
 
     (
         Redo = no,
@@ -221,104 +221,120 @@
     % and hoist these out of the disjunction. At the moment
     % we only look for cses that are deconstruction unifications.
     %
-:- pred detect_cse_in_goal(hlds_goal::in, instmap::in, cse_info::in,
-    cse_info::out, bool::out, hlds_goal::out) is det.
+:- pred detect_cse_in_goal(hlds_goal::in, hlds_goal::out,
+    cse_info::in, cse_info::out, instmap::in, bool::out) is det.
 
-detect_cse_in_goal(Goal0, InstMap0, !CseInfo, Redo, Goal) :-
-    detect_cse_in_goal_1(Goal0, InstMap0, !CseInfo, Redo, Goal, _InstMap).
+detect_cse_in_goal(Goal0, Goal, !CseInfo, InstMap0, Redo) :-
+    detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo,
+        InstMap0, _InstMap, Redo).
 
     % This version is the same as the above except that it returns
     % the resulting instmap on exit from the goal, which is
     % computed by applying the instmap delta specified in the
     % goal's goalinfo.
     %
-:- pred detect_cse_in_goal_1(hlds_goal::in, instmap::in, cse_info::in,
-    cse_info::out, bool::out, hlds_goal::out, instmap::out) is det.
+:- pred detect_cse_in_goal_update_instmap(hlds_goal::in, hlds_goal::out,
+    cse_info::in, cse_info::out, instmap::in, instmap::out, bool::out) is det.
 
-detect_cse_in_goal_1(hlds_goal(GoalExpr0, GoalInfo), InstMap0, !CseInfo, Redo,
-        hlds_goal(GoalExpr, GoalInfo), InstMap) :-
-    detect_cse_in_goal_2(GoalExpr0, GoalInfo, InstMap0, !CseInfo, Redo,
-        GoalExpr),
+detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, InstMap0, InstMap,
+        Redo) :-
+    Goal0 = hlds_goal(GoalExpr0, GoalInfo),
+    detect_cse_in_goal_expr(GoalExpr0, GoalExpr, !CseInfo, GoalInfo,
+        InstMap0, Redo),
+    Goal = hlds_goal(GoalExpr, GoalInfo),
     InstMapDelta = goal_info_get_instmap_delta(GoalInfo),
     instmap.apply_instmap_delta(InstMap0, InstMapDelta, InstMap).
 
     % Here we process each of the different sorts of goals.
     %
-:- pred detect_cse_in_goal_2(hlds_goal_expr::in, hlds_goal_info::in,
-    instmap::in, cse_info::in, cse_info::out, bool::out,
-    hlds_goal_expr::out) is det.
-
-detect_cse_in_goal_2(Goal @ call_foreign_proc(_, _, _, _, _, _, _), _, _,
-        !CseInfo, no, Goal).
-detect_cse_in_goal_2(Goal @ generic_call(_, _, _, _), _, _, !CseInfo,
-        no, Goal).
-detect_cse_in_goal_2(Goal @ plain_call(_, _, _, _, _, _), _, _, !CseInfo,
-        no, Goal).
-detect_cse_in_goal_2(unify(LHS, RHS0, Mode, Unify,  UnifyContext), _, InstMap0,
-        !CseInfo, Redo, unify(LHS, RHS, Mode,Unify, UnifyContext)) :-
+:- pred detect_cse_in_goal_expr(hlds_goal_expr::in, hlds_goal_expr::out,
+    cse_info::in, cse_info::out, hlds_goal_info::in,
+    instmap::in, bool::out) is det.
+
+detect_cse_in_goal_expr(GoalExpr0, GoalExpr, !CseInfo, GoalInfo, InstMap0,
+        Redo) :-
+    (
+        ( GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
+        ; GoalExpr0 = generic_call(_, _, _, _)
+        ; GoalExpr0 = plain_call(_, _, _, _, _, _)
+        ),
+        GoalExpr = GoalExpr0,
+        Redo = no
+    ;
+        GoalExpr0 = unify(LHS, RHS0, Mode, Unify,  UnifyContext),
     (
         RHS0 = rhs_lambda_goal(Purity, PredOrFunc, EvalMethod, NonLocalVars,
-            Vars, Modes, Det, Goal0),
+                Vars, Modes, Det, LambdaGoal0),
         ModuleInfo = !.CseInfo ^ module_info,
-        instmap.pre_lambda_update(ModuleInfo, Vars, Modes, InstMap0, InstMap),
-        detect_cse_in_goal(Goal0, InstMap, !CseInfo, Redo, Goal),
+            instmap.pre_lambda_update(ModuleInfo, Vars, Modes,
+                InstMap0, InstMap1),
+            detect_cse_in_goal(LambdaGoal0, LambdaGoal, !CseInfo,
+                InstMap1, Redo),
         RHS = rhs_lambda_goal(Purity, PredOrFunc, EvalMethod, NonLocalVars,
-            Vars, Modes, Det, Goal)
+                Vars, Modes, Det, LambdaGoal)
     ;
         ( RHS0 = rhs_var(_)
         ; RHS0 = rhs_functor(_, _, _)
         ),
         RHS = RHS0,
         Redo = no
-    ).
-detect_cse_in_goal_2(negation(Goal0), _GoalInfo, InstMap, !CseInfo, Redo,
-        negation(Goal)) :-
-    detect_cse_in_goal(Goal0, InstMap, !CseInfo, Redo, Goal).
-detect_cse_in_goal_2(scope(Reason, Goal0), _GoalInfo, InstMap,
-        !CseInfo, Redo, scope(Reason, Goal)) :-
-    detect_cse_in_goal(Goal0, InstMap, !CseInfo, Redo, Goal).
-detect_cse_in_goal_2(conj(ConjType, Goals0), _GoalInfo, InstMap, !CseInfo,
-        Redo, conj(ConjType, Goals)) :-
-    detect_cse_in_conj(Goals0, ConjType, InstMap, !CseInfo, Redo, Goals).
-detect_cse_in_goal_2(disj(Goals0), GoalInfo, InstMap, !CseInfo, Redo, Goal) :-
+        ),
+        GoalExpr = unify(LHS, RHS, Mode,Unify, UnifyContext)
+    ;
+        GoalExpr0 = negation(SubGoal0),
+        detect_cse_in_goal(SubGoal0, SubGoal, !CseInfo, InstMap0, Redo),
+        GoalExpr = negation(SubGoal)
+    ;
+        GoalExpr0 = scope(Reason, SubGoal0),
+        detect_cse_in_goal(SubGoal0, SubGoal, !CseInfo, InstMap0, Redo),
+        GoalExpr = scope(Reason, SubGoal)
+    ;
+        GoalExpr0 = conj(ConjType, Goals0),
+        detect_cse_in_conj(Goals0, Goals, !CseInfo, ConjType, InstMap0, Redo),
+        GoalExpr = conj(ConjType, Goals)
+    ;
+        GoalExpr0 = disj(Goals0),
     (
         Goals0 = [],
         Redo = no,
-        Goal = disj([])
+            GoalExpr = disj([])
     ;
         Goals0 = [_ | _],
         NonLocals = goal_info_get_nonlocals(GoalInfo),
         set.to_sorted_list(NonLocals, NonLocalsList),
         detect_cse_in_disj(NonLocalsList, Goals0, GoalInfo,
-            InstMap, !CseInfo, Redo, Goal)
-    ).
-detect_cse_in_goal_2(switch(Var, CanFail, Cases0), GoalInfo, InstMap,
-        !CseInfo, Redo, Goal) :-
+                InstMap0, !CseInfo, Redo, GoalExpr)
+        )
+    ;
+        GoalExpr0 = switch(Var, CanFail, Cases0),
     NonLocals = goal_info_get_nonlocals(GoalInfo),
     set.to_sorted_list(NonLocals, NonLocalsList),
     detect_cse_in_cases(NonLocalsList, Var, CanFail, Cases0, GoalInfo,
-        InstMap, !CseInfo, Redo, Goal).
-detect_cse_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0), GoalInfo,
-        InstMap, !CseInfo, Redo, Goal) :-
+            InstMap0, !CseInfo, Redo, GoalExpr)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
     NonLocals = goal_info_get_nonlocals(GoalInfo),
     set.to_sorted_list(NonLocals, NonLocalsList),
     detect_cse_in_ite(NonLocalsList, Vars, Cond0, Then0, Else0, GoalInfo,
-        InstMap, !CseInfo, Redo, Goal).
-
-detect_cse_in_goal_2(shorthand(_), _, _, _, _, _, _) :-
+            InstMap0, !CseInfo, Redo, GoalExpr)
+    ;
+        GoalExpr0 = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "detect_cse_in_goal_2: unexpected shorthand").
+        unexpected(this_file, "detect_cse_in_goal_expr: unexpected shorthand")
+    ).
 
 %-----------------------------------------------------------------------------%
 
-:- pred detect_cse_in_conj(list(hlds_goal)::in, conj_type::in, instmap::in,
-    cse_info::in, cse_info::out, bool::out, list(hlds_goal)::out) is det.
+:- pred detect_cse_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
+    cse_info::in, cse_info::out, conj_type::in, instmap::in, bool::out) is det.
 
-detect_cse_in_conj([], _ConjType, _InstMap, !CseInfo, no, []).
-detect_cse_in_conj([Goal0 | Goals0], ConjType, InstMap0, !CseInfo, Redo,
-        Goals) :-
-    detect_cse_in_goal_1(Goal0, InstMap0, !CseInfo, Redo1, Goal, InstMap1),
-    detect_cse_in_conj(Goals0, ConjType, InstMap1, !CseInfo, Redo2, TailGoals),
+detect_cse_in_conj([], [], !CseInfo, _ConjType, _InstMap, no).
+detect_cse_in_conj([Goal0 | Goals0], Goals, !CseInfo, ConjType, !.InstMap,
+        Redo) :-
+    detect_cse_in_goal_update_instmap(Goal0, Goal, !CseInfo, !InstMap, Redo1),
+    detect_cse_in_conj(Goals0, TailGoals, !CseInfo, ConjType, !.InstMap,
+        Redo2),
+    % Flatten any non-flat conjunctions we create.
     (
         Goal = hlds_goal(conj(InnerConjType, ConjGoals), _),
         ConjType = InnerConjType
@@ -341,11 +357,11 @@
     cse_info::out, bool::out, hlds_goal_expr::out) is det.
 
 detect_cse_in_disj([], Goals0, _, InstMap, !CseInfo, Redo, disj(Goals)) :-
-    detect_cse_in_disj_2(Goals0, InstMap, !CseInfo, Redo, Goals).
-detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, InstMap,
+    detect_cse_in_disjuncts(Goals0, Goals, !CseInfo, InstMap, Redo).
+detect_cse_in_disj([Var | Vars], Goals0, GoalInfo0, InstMap0,
         !CseInfo, Redo, GoalExpr) :-
     (
-        instmap.lookup_var(InstMap, Var, VarInst0),
+        instmap.lookup_var(InstMap0, Var, VarInst0),
         ModuleInfo = !.CseInfo ^ module_info,
         % XXX we only need inst_is_bound, but leave this as it is
         % until mode analysis can handle aliasing between free
@@ -360,32 +376,32 @@
             [Unify, hlds_goal(disj(Goals), GoalInfo0)]),
         Redo = yes
     ;
-        detect_cse_in_disj(Vars, Goals0, GoalInfo0, InstMap,
+        detect_cse_in_disj(Vars, Goals0, GoalInfo0, InstMap0,
             !CseInfo, Redo, GoalExpr)
     ).
 
-:- pred detect_cse_in_disj_2(list(hlds_goal)::in, instmap::in, cse_info::in,
-    cse_info::out, bool::out, list(hlds_goal)::out) is det.
+:- pred detect_cse_in_disjuncts(list(hlds_goal)::in, list(hlds_goal)::out,
+    cse_info::in, cse_info::out, instmap::in, bool::out) is det.
 
-detect_cse_in_disj_2([], _InstMap, !CseInfo, no, []).
-detect_cse_in_disj_2([Goal0 | Goals0], InstMap0, !CseInfo, Redo,
-        [Goal | Goals]) :-
-    detect_cse_in_goal(Goal0, InstMap0, !CseInfo, Redo1, Goal),
-    detect_cse_in_disj_2(Goals0, InstMap0, !CseInfo, Redo2, Goals),
+detect_cse_in_disjuncts([], [], !CseInfo, _, no).
+detect_cse_in_disjuncts([Goal0 | Goals0], [Goal | Goals], !CseInfo, InstMap0,
+        Redo) :-
+    detect_cse_in_goal(Goal0, Goal, !CseInfo, InstMap0, Redo1),
+    detect_cse_in_disjuncts(Goals0, Goals, !CseInfo, InstMap0, Redo2),
     bool.or(Redo1, Redo2, Redo).
 
 :- pred detect_cse_in_cases(list(prog_var)::in, prog_var::in, can_fail::in,
     list(case)::in, hlds_goal_info::in, instmap::in,
     cse_info::in, cse_info::out, bool::out, hlds_goal_expr::out) is det.
 
-detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo, InstMap,
+detect_cse_in_cases([], SwitchVar, CanFail, Cases0, _GoalInfo, InstMap0,
         !CseInfo, Redo, switch(SwitchVar, CanFail, Cases)) :-
-    detect_cse_in_cases_2(Cases0, InstMap, !CseInfo, Redo, Cases).
+    detect_cse_in_cases_arms(Cases0, Cases, !CseInfo, InstMap0, Redo).
 detect_cse_in_cases([Var | Vars], SwitchVar, CanFail, Cases0, GoalInfo,
-        InstMap, !CseInfo, Redo, GoalExpr) :-
+        InstMap0, !CseInfo, Redo, GoalExpr) :-
     (
         Var \= SwitchVar,
-        instmap.lookup_var(InstMap, Var, VarInst0),
+        instmap.lookup_var(InstMap0, Var, VarInst0),
         ModuleInfo = !.CseInfo ^ module_info,
         % XXX We only need inst_is_bound, but leave this as it is until
         % mode analysis can handle aliasing between free variables.
@@ -400,19 +416,19 @@
         Redo = yes
     ;
         detect_cse_in_cases(Vars, SwitchVar, CanFail, Cases0, GoalInfo,
-            InstMap, !CseInfo, Redo, GoalExpr)
+            InstMap0, !CseInfo, Redo, GoalExpr)
     ).
 
-:- pred detect_cse_in_cases_2(list(case)::in, instmap::in, cse_info::in,
-    cse_info::out, bool::out, list(case)::out) is det.
+:- pred detect_cse_in_cases_arms(list(case)::in, list(case)::out,
+    cse_info::in, cse_info::out, instmap::in, bool::out) is det.
 
-detect_cse_in_cases_2([], _, !CseInfo, no, []).
-detect_cse_in_cases_2([Case0 | Cases0], InstMap, !CseInfo, Redo,
-        [Case | Cases]) :-
+detect_cse_in_cases_arms([], [], !CseInfo, _, no).
+detect_cse_in_cases_arms([Case0 | Cases0], [Case | Cases], !CseInfo, InstMap0,
+        Redo) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
-    detect_cse_in_goal(Goal0, InstMap, !CseInfo, Redo1, Goal),
+    detect_cse_in_goal(Goal0, Goal, !CseInfo, InstMap0, Redo1),
     Case = case(MainConsId, OtherConsIds, Goal),
-    detect_cse_in_cases_2(Cases0, InstMap, !CseInfo, Redo2, Cases),
+    detect_cse_in_cases_arms(Cases0, Cases, !CseInfo, InstMap0, Redo2),
     bool.or(Redo1, Redo2, Redo).
 
 :- pred detect_cse_in_ite(list(prog_var)::in, list(prog_var)::in,
@@ -422,8 +438,8 @@
 
 detect_cse_in_ite([], IfVars, Cond0, Then0, Else0, _, InstMap, !CseInfo,
         Redo, if_then_else(IfVars, Cond, Then, Else)) :-
-    detect_cse_in_ite_2(Cond0, Then0, Else0, InstMap, !CseInfo, Redo,
-        Cond, Then, Else).
+    detect_cse_in_ite_arms(Cond0, Cond, Then0, Then, Else0, Else, !CseInfo,
+        InstMap, Redo).
 detect_cse_in_ite([Var | Vars], IfVars, Cond0, Then0, Else0, GoalInfo,
         InstMap, !CseInfo, Redo, GoalExpr) :-
     (
@@ -446,15 +462,16 @@
             InstMap, !CseInfo, Redo, GoalExpr)
     ).
 
-:- pred detect_cse_in_ite_2(hlds_goal::in, hlds_goal::in, hlds_goal::in,
-    instmap::in, cse_info::in, cse_info::out, bool::out,
-    hlds_goal::out, hlds_goal::out, hlds_goal::out) is det.
-
-detect_cse_in_ite_2(Cond0, Then0, Else0, InstMap0, !CseInfo, Redo,
-        Cond, Then, Else) :-
-    detect_cse_in_goal_1(Cond0, InstMap0, !CseInfo, Redo1, Cond, InstMap1),
-    detect_cse_in_goal(Then0, InstMap1, !CseInfo, Redo2, Then),
-    detect_cse_in_goal(Else0, InstMap0, !CseInfo, Redo3, Else),
+:- pred detect_cse_in_ite_arms(hlds_goal::in, hlds_goal::out,
+    hlds_goal::in, hlds_goal::out, hlds_goal::in, hlds_goal::out,
+    cse_info::in, cse_info::out, instmap::in, bool::out) is det.
+
+detect_cse_in_ite_arms(Cond0, Cond, Then0, Then, Else0, Else, !CseInfo,
+        InstMap0, Redo) :-
+    detect_cse_in_goal_update_instmap(Cond0, Cond, !CseInfo,
+        InstMap0, InstMap1, Redo1),
+    detect_cse_in_goal(Then0, Then, !CseInfo, InstMap1, Redo2),
+    detect_cse_in_goal(Else0, Else, !CseInfo, InstMap0, Redo3),
     bool.or(Redo1, Redo2, Redo12),
     bool.or(Redo12, Redo3, Redo).
 
Index: compiler/ctgc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ctgc.m,v
retrieving revision 1.7
diff -u -b -r1.7 ctgc.m
--- compiler/ctgc.m	31 Jul 2006 08:31:33 -0000	1.7
+++ compiler/ctgc.m	11 Jan 2008 18:46:58 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 2005-2006 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.125
diff -u -b -r1.125 dead_proc_elim.m
--- compiler/dead_proc_elim.m	30 Dec 2007 08:23:34 -0000	1.125
+++ compiler/dead_proc_elim.m	5 Jan 2008 03:23:42 -0000
@@ -466,31 +466,30 @@
     entity_queue::in, entity_queue::out, needed_map::in, needed_map::out)
     is det.
 
-dead_proc_examine_goal(hlds_goal(GoalExpr, _), CurrProc, !Queue, !Needed) :-
-    dead_proc_examine_expr(GoalExpr, CurrProc, !Queue, !Needed).
-
-:- pred dead_proc_examine_expr(hlds_goal_expr::in, pred_proc_id::in,
-    entity_queue::in, entity_queue::out, needed_map::in, needed_map::out)
-    is det.
-
-dead_proc_examine_expr(disj(Goals), CurrProc, !Queue, !Needed) :-
-    dead_proc_examine_goals(Goals, CurrProc, !Queue, !Needed).
-dead_proc_examine_expr(conj(_ConjType, Goals), CurrProc, !Queue, !Needed) :-
-    dead_proc_examine_goals(Goals, CurrProc, !Queue, !Needed).
-dead_proc_examine_expr(negation(Goal), CurrProc, !Queue, !Needed) :-
-    dead_proc_examine_goal(Goal, CurrProc, !Queue, !Needed).
-dead_proc_examine_expr(scope(_, Goal), CurrProc, !Queue, !Needed) :-
-    dead_proc_examine_goal(Goal, CurrProc, !Queue, !Needed).
-dead_proc_examine_expr(switch(_, _, Cases), CurrProc, !Queue, !Needed) :-
-    dead_proc_examine_cases(Cases, CurrProc, !Queue, !Needed).
-dead_proc_examine_expr(if_then_else(_, Cond, Then, Else), CurrProc, !Queue,
-        !Needed) :-
+dead_proc_examine_goal(Goal, CurrProc, !Queue, !Needed) :-
+    Goal = hlds_goal(GoalExpr, _),
+    (
+        ( GoalExpr = conj(_ConjType, Goals)
+        ; GoalExpr = disj(Goals)
+        ),
+        dead_proc_examine_goals(Goals, CurrProc, !Queue, !Needed)
+    ;
+        GoalExpr = switch(_Var, _CanFail, Cases),
+        dead_proc_examine_cases(Cases, CurrProc, !Queue, !Needed)
+    ;
+        ( GoalExpr = negation(SubGoal)
+        ; GoalExpr = scope(_Reason, SubGoal)
+        ),
+        dead_proc_examine_goal(SubGoal, CurrProc, !Queue, !Needed)
+    ;
+        GoalExpr = if_then_else(_, Cond, Then, Else),
     dead_proc_examine_goal(Cond, CurrProc, !Queue, !Needed),
     dead_proc_examine_goal(Then, CurrProc, !Queue, !Needed),
-    dead_proc_examine_goal(Else, CurrProc, !Queue, !Needed).
-dead_proc_examine_expr(generic_call(_,_,_,_), _, !Queue, !Needed).
-dead_proc_examine_expr(plain_call(PredId, ProcId, _,_,_,_), CurrProc, !Queue,
-        !Needed) :-
+        dead_proc_examine_goal(Else, CurrProc, !Queue, !Needed)
+    ;
+        GoalExpr = generic_call(_, _, _, _)
+    ;
+        GoalExpr = plain_call(PredId, ProcId, _,_,_,_),
     Entity = entity_proc(PredId, ProcId),
     queue.put(!.Queue, Entity, !:Queue),
     ( proc(PredId, ProcId) = CurrProc ->
@@ -538,9 +537,9 @@
         ),
         NewNotation = maybe_eliminable(1),
         svmap.set(Entity, NewNotation, !Needed)
-    ).
-dead_proc_examine_expr(call_foreign_proc(_, PredId, ProcId, _, _, _, _),
-        _CurrProc, !Queue, !Needed) :-
+        )
+    ;
+        GoalExpr = call_foreign_proc(_, PredId, ProcId, _, _, _, _),
     Entity = entity_proc(PredId, ProcId),
     trace [io(!IO), compile_time(flag("dead_proc_elim"))] (
         io.write_string("foreign_proc ", !IO),
@@ -550,10 +549,11 @@
         io.nl(!IO)
     ),
     svqueue.put(Entity, !Queue),
-    svmap.set(Entity, not_eliminable, !Needed).
-dead_proc_examine_expr(unify(_,_,_, Uni, _), _CurrProc, !Queue, !Needed) :-
+        svmap.set(Entity, not_eliminable, !Needed)
+    ;
+        GoalExpr = unify(_LHS, _RHS, _UniModes, Unification, _UnifyContext),
     (
-        Uni = construct(_, ConsId, _, _, _, _, _),
+            Unification = construct(_, ConsId, _, _, _, _, _),
         (
             (
                 ConsId = pred_const(ShroudedPredProcId, _),
@@ -599,18 +599,21 @@
             % Do nothing.
         )
     ;
-        ( Uni = deconstruct(_, _, _, _, _, _)
-        ; Uni = assign(_, _)
-        ; Uni = simple_test(_, _)
+            ( Unification = deconstruct(_, _, _, _, _, _)
+            ; Unification = assign(_, _)
+            ; Unification = simple_test(_, _)
         )
         % Do nothing.
     ;
-        Uni = complicated_unify(_, _, _),
-        unexpected(this_file, "dead_proc_examine_expr: complicated_unify")
-    ).
-dead_proc_examine_expr(shorthand(_), _, !Queue, !Needed) :-
+            Unification = complicated_unify(_, _, _),
+            % These should have been replaced with calls by now.
+            unexpected(this_file, "dead_proc_examine_goal: complicated_unify")
+        )
+    ;
+        GoalExpr = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "detect_cse_in_goal_2: unexpected shorthand").
+        unexpected(this_file, "dead_proc_examine_goal: shorthand")
+    ).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/follow_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/follow_vars.m,v
retrieving revision 1.90
diff -u -b -r1.90 follow_vars.m
--- compiler/follow_vars.m	30 Dec 2007 08:23:38 -0000	1.90
+++ compiler/follow_vars.m	5 Jan 2008 03:36:09 -0000
@@ -111,9 +111,10 @@
     abs_follow_vars_map::in, abs_follow_vars_map::out,
     int::in, int::out) is det.
 
-find_follow_vars_in_goal_expr(conj(ConjType, Goals0), conj(ConjType, Goals),
-        GoalInfo, GoalInfo, VarTypes, ModuleInfo, !FollowVarsMap,
-        !NextNonReserved) :-
+find_follow_vars_in_goal_expr(GoalExpr0, GoalExpr, !GoalInfo,
+        VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
     (
         ConjType = plain_conj,
         find_follow_vars_in_conj(Goals0, Goals, VarTypes, ModuleInfo,
@@ -122,41 +123,30 @@
         ConjType = parallel_conj,
         find_follow_vars_in_independent_goals(Goals0, Goals, VarTypes,
             ModuleInfo, !FollowVarsMap, !NextNonReserved)
-    ).
-
-find_follow_vars_in_goal_expr(disj(Goals0), disj(Goals), GoalInfo0, GoalInfo,
-        VarTypes, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
+        ),
+        GoalExpr = conj(ConjType, Goals)
+    ;
+        GoalExpr0 = disj(Goals0),
     % We record that at the end of each disjunct, live variables should
     % be in the locations given by the initial follow_vars, which reflects
     % the requirements of the code following the disjunction.
-
-    goal_info_set_store_map(!.FollowVarsMap, GoalInfo0, GoalInfo),
-    find_follow_vars_in_independent_goals(Goals0, Goals, VarTypes, ModuleInfo,
-        !FollowVarsMap, !NextNonReserved).
-
-find_follow_vars_in_goal_expr(negation(Goal0), negation(Goal),
-        GoalInfo, GoalInfo, VarTypes, ModuleInfo, !FollowVarsMap,
-        !NextNonReserved) :-
-    find_follow_vars_in_goal(Goal0, Goal, VarTypes, ModuleInfo,
-        !FollowVarsMap, !NextNonReserved).
-
-find_follow_vars_in_goal_expr(switch(Var, Det, Cases0),
-        switch(Var, Det, Cases), GoalInfo0, GoalInfo, VarTypes, ModuleInfo,
-        !FollowVarsMap, !NextNonReserved) :-
+        goal_info_set_store_map(!.FollowVarsMap, !GoalInfo),
+        find_follow_vars_in_independent_goals(Goals0, Goals, VarTypes,
+            ModuleInfo, !FollowVarsMap, !NextNonReserved),
+        GoalExpr = disj(Goals)
+    ;
+        GoalExpr0 = switch(Var, Det, Cases0),
     % We record that at the end of each arm of the switch, live variables
     % should be in the locations given by the initial follow_vars, which
     % reflects the requirements of the code following the switch.
-
-    goal_info_set_store_map(!.FollowVarsMap, GoalInfo0, GoalInfo),
+        goal_info_set_store_map(!.FollowVarsMap, !GoalInfo),
     find_follow_vars_in_cases(Cases0, Cases, VarTypes, ModuleInfo,
-        !FollowVarsMap, !NextNonReserved).
-
-find_follow_vars_in_goal_expr(
-        if_then_else(Vars, Cond0, Then0, Else0),
-        if_then_else(Vars, Cond, Then, Else),
-        GoalInfo0, GoalInfo, VarTypes, ModuleInfo,
-        FollowVarsMap0, FollowVarsMapCond,
-        NextNonReserved0, NextNonReservedCond) :-
+            !FollowVarsMap, !NextNonReserved),
+        GoalExpr = switch(Var, Det, Cases)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
+        FollowVarsMap0 = !.FollowVarsMap,
+        NextNonReserved0 = !.NextNonReserved,
 
     % Set the follow_vars field for the condition, the then-part and the
     % else-part, since in general they have requirements about where
@@ -195,37 +185,47 @@
         abs_follow_vars(FollowVarsMapElse, NextNonReservedElse),
     goal_set_follow_vars(yes(FollowVarsElse), Else1, Else),
 
-    goal_info_set_store_map(FollowVarsMap0, GoalInfo0, GoalInfo).
-
-find_follow_vars_in_goal_expr(scope(Reason, Goal0), scope(Reason, Goal),
-        GoalInfo, GoalInfo, VarTypes, ModuleInfo,
-        !FollowVarsMap, !NextNonReserved) :-
-    find_follow_vars_in_goal(Goal0, Goal, VarTypes, ModuleInfo,
-        !FollowVarsMap, !NextNonReserved).
+        goal_info_set_store_map(FollowVarsMap0, !GoalInfo),
 
-find_follow_vars_in_goal_expr(Goal @ unify(_, _, _, Unify, _), Goal,
-        GoalInfo, GoalInfo, _VarTypes, _ModuleInfo,
-        !FollowVarsMap, !NextNonReserved) :-
+        GoalExpr = if_then_else(Vars, Cond, Then, Else),
+        !:FollowVarsMap = FollowVarsMapCond,
+        !:NextNonReserved = NextNonReservedCond
+    ;
+        GoalExpr0 = negation(SubGoal0),
+        find_follow_vars_in_goal(SubGoal0, SubGoal, VarTypes, ModuleInfo,
+            !FollowVarsMap, !NextNonReserved),
+        GoalExpr = negation(SubGoal)
+    ;
+        GoalExpr0 = scope(Reason, SubGoal0),
+        find_follow_vars_in_goal(SubGoal0, SubGoal, VarTypes, ModuleInfo,
+            !FollowVarsMap, !NextNonReserved),
+        GoalExpr = scope(Reason, SubGoal)
+    ;
+        GoalExpr0 = unify(_, _, _, Unification, _),
+        GoalExpr = GoalExpr0,
     (
-        Unify = assign(LVar, RVar),
+            Unification = assign(LVar, RVar),
         map.search(!.FollowVarsMap, LVar, DesiredLoc)
     ->
         svmap.set(RVar, DesiredLoc, !FollowVarsMap)
     ;
         true
-    ).
-
-find_follow_vars_in_goal_expr(Goal @ call_foreign_proc(_, _, _, _, _, _, _),
-        Goal, GoalInfo, GoalInfo, _, _, !FollowVarsMap, !NextNonReserved).
-
-find_follow_vars_in_goal_expr(shorthand(_), _, _, _, _, _, _, _, _, _) :-
-    % these should have been expanded out by now
-    unexpected(this_file, "find_follow_vars_in_goal_2: unexpected shorthand").
-
-find_follow_vars_in_goal_expr(
-        Call @ generic_call(GenericCall, Args, Modes, Det), Call,
-        GoalInfo, GoalInfo, VarTypes, ModuleInfo,
-        !FollowVarsMap, !NextNonReserved) :-
+        )
+    ;
+        GoalExpr0 = plain_call(PredId, ProcId, Args, State, _UC, _Name),
+        GoalExpr = GoalExpr0,
+        (
+            State = inline_builtin
+        ;
+            ( State = out_of_line_builtin
+            ; State = not_builtin
+            ),
+            find_follow_vars_in_call(PredId, ProcId, Args, ModuleInfo,
+                !:FollowVarsMap, !:NextNonReserved)
+        )
+    ;
+        GoalExpr0 = generic_call(GenericCall, Args, Modes, Det),
+        GoalExpr = GoalExpr0,
     (
         GenericCall = cast(_)
         % Casts are generated inline.
@@ -247,20 +247,14 @@
             map.init, !:FollowVarsMap, 1, _),
         find_follow_vars_from_sequence(InVars, FirstInput,
             !FollowVarsMap, !:NextNonReserved)
-    ).
-
-find_follow_vars_in_goal_expr(
-        plain_call(PredId, ProcId, Args, State, UC, Name),
-        plain_call(PredId, ProcId, Args, State, UC, Name), GoalInfo, GoalInfo,
-        _, ModuleInfo, !FollowVarsMap, !NextNonReserved) :-
-    (
-        State = inline_builtin 
+        )
     ;
-        ( State = out_of_line_builtin
-        ; State = not_builtin
-        ),
-        find_follow_vars_in_call(PredId, ProcId, Args, ModuleInfo,
-            !:FollowVarsMap, !:NextNonReserved)
+        GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _),
+        GoalExpr = GoalExpr0
+    ;
+        GoalExpr0 = shorthand(_),
+        % These should have been expanded out by now.
+        unexpected(this_file, "find_follow_vars_in_goal_expr: shorthand")
     ).
 
 %-----------------------------------------------------------------------------%
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.171
diff -u -b -r1.171 higher_order.m
--- compiler/higher_order.m	30 Dec 2007 08:23:41 -0000	1.171
+++ compiler/higher_order.m	5 Jan 2008 04:49:07 -0000
@@ -111,13 +111,13 @@
         module_info_predids(PredIds0, !ModuleInfo),
         module_info_get_type_spec_info(!.ModuleInfo, TypeSpecInfo),
         TypeSpecInfo = type_spec_info(_, UserSpecPreds, _, _),
-        %
+
         % Make sure the user requested specializations are processed first,
         % since we don't want to create more versions if one of these
         % matches. We need to process these even if specialization is
         % not being performed in case any of the specialized versions
         % are called from other modules.
-        %
+
         ( set.empty(UserSpecPreds) ->
             PredIds = PredIds0,
             UserSpecPredList = []
@@ -127,28 +127,25 @@
             set.to_sorted_list(PredIdSet, PredIds),
 
             set.to_sorted_list(UserSpecPreds, UserSpecPredList),
-            !:Info = !.Info ^ ho_params ^ user_type_spec := yes,
+            !:Info = !.Info ^ hogi_params ^ param_do_user_type_spec := yes,
             list.foldl(get_specialization_requests, UserSpecPredList, !Info),
             process_requests(!Info, !IO)
         ),
 
         ( bool.or_list([HigherOrder, TypeSpec, UserTypeSpec], yes) ->
-            %
             % Process all other specializations until no more requests
             % are generated.
-            %
             list.foldl(get_specialization_requests, PredIds, !Info),
             recursively_process_requests(!Info, !IO)
         ;
             true
         ),
-        %
+
         % Remove the predicates which were used to force the production of
         % user-requested type specializations, since they are not called
         % from anywhere and are no longer needed.
-        %
         list.foldl(module_info_remove_predicate,
-            UserSpecPredList, !.Info ^ module_info, !:ModuleInfo)
+            UserSpecPredList, !.Info ^ hogi_module_info, !:ModuleInfo)
     ).
 
     % Process one lot of requests, returning requests for any
@@ -177,9 +174,9 @@
             NewPredList = [_ | _],
             % The dependencies may have changed, so the dependency graph
             % needs to rebuilt for inlining to work properly.
-            module_info_clobber_dependency_info(!.Info ^ module_info,
-                ModuleInfo),
-            !:Info = !.Info ^ module_info := ModuleInfo
+            ModuleInfo0 = !.Info ^ hogi_module_info,
+            module_info_clobber_dependency_info(ModuleInfo0, ModuleInfo),
+            !:Info = !.Info ^ hogi_module_info := ModuleInfo
         ;
             NewPredList = []
         )
@@ -191,7 +188,7 @@
     higher_order_global_info::out, io::di, io::uo) is det.
 
 recursively_process_requests(!Info, !IO) :-
-    ( set.empty(!.Info ^ requests) ->
+    ( set.empty(!.Info ^ hogi_requests) ->
         true
     ;
         process_requests(!Info, !IO),
@@ -202,22 +199,22 @@
 
 :- type higher_order_global_info
     --->    higher_order_global_info(
-                requests            :: set(request),
+                hogi_requests       :: set(request),
                                     % Requested versions.
 
-                new_preds           :: new_preds,
+                hogi_new_preds      :: new_preds,
                                     % Specialized versions for each predicate
-                                    % not changed by traverse_goal.
+                                    % not changed by traverse_proc_body.
 
-                version_info        :: map(pred_proc_id, version_info),
+                hogi_version_info   :: map(pred_proc_id, version_info),
                                     % Extra information about each specialized
                                     % version.
 
-                module_info         :: module_info,
-                goal_sizes          :: goal_sizes,
-                ho_params           :: ho_params,
+                hogi_module_info    :: module_info,
+                hogi_goal_sizes     :: goal_sizes,
+                hogi_params         :: ho_params,
 
-                next_ho_id          :: counter
+                hogi_next_id        :: counter
                                     % Number identifying a specialized
                                     % version.
             ).
@@ -226,21 +223,21 @@
     %
 :- type higher_order_info
     --->    higher_order_info(
-                global_info         :: higher_order_global_info,
+                hoi_global_info         :: higher_order_global_info,
 
-                pred_vars           :: pred_vars,
+                hoi_pred_vars           :: pred_vars,
                                     % higher_order variables.
 
-                pred_proc_id        :: pred_proc_id,
+                hoi_pred_proc_id        :: pred_proc_id,
                                     % pred_proc_id of goal being traversed.
 
-                pred_info           :: pred_info,
+                hoi_pred_info           :: pred_info,
                                     % pred_info of goal being traversed.
 
-                proc_info           :: proc_info,
+                hoi_proc_info           :: proc_info,
                                     % proc_info of goal being traversed.
 
-                changed             :: changed
+                hoi_changed             :: changed
             ).
 
 :- type request
@@ -342,17 +339,18 @@
 
 :- type ho_params
     --->    ho_params(
-                optimize_higher_order :: bool,
+                param_do_higher_order_spec  :: bool,
                                       % Propagate higher-order constants.
-                type_spec             :: bool,
+                param_do_type_spec          :: bool,
                                       % Propagate type-info constants.
-                user_type_spec        :: bool,
+                param_do_user_type_spec     :: bool,
                                       % User-guided type specialization.
-                size_limit            :: int,
+                param_size_limit            :: int,
                                       % Size limit on requested version.
-                arg_limit             :: int
-                                      % The maximum size of the higher-order
-                                      % arguments of a specialized version.
+                param_arg_limit             :: int
+                                            % The maximum size of the higher
+                                            % order arguments of a specialized
+                                            % version.
             ).
 
 :- type version_info
@@ -416,7 +414,7 @@
                                         % specialization?
             ).
 
-    % Returned by traverse_goal.
+    % Returned by traverse_proc_body.
     %
 :- type changed
     --->    changed     % Need to requantify goal + check other procs
@@ -433,80 +431,62 @@
     higher_order_global_info::in, higher_order_global_info::out) is det.
 
 get_specialization_requests(PredId, !GlobalInfo) :-
-    module_info_pred_info(!.GlobalInfo ^ module_info, PredId, PredInfo0),
+    ModuleInfo0 = !.GlobalInfo ^ hogi_module_info,
+    module_info_pred_info(ModuleInfo0, PredId, PredInfo0),
     NonImportedProcs = pred_info_non_imported_procids(PredInfo0),
     (
         NonImportedProcs = []
     ;
         NonImportedProcs = [ProcId | _],
-        MustRecompute = no,
-        list.foldl(traverse_proc(MustRecompute, PredId), NonImportedProcs,
+        list.foldl(traverse_proc(need_not_recompute, PredId), NonImportedProcs,
             !GlobalInfo),
-        module_info_proc_info(!.GlobalInfo ^ module_info, PredId, ProcId,
-            ProcInfo),
+
+        ModuleInfo1 = !.GlobalInfo ^ hogi_module_info,
+        module_info_proc_info(ModuleInfo1, PredId, ProcId, ProcInfo),
         proc_info_get_goal(ProcInfo, Goal),
         goal_size(Goal, GoalSize),
-        map.set(!.GlobalInfo ^ goal_sizes, PredId, GoalSize, GoalSizes),
-        !:GlobalInfo = !.GlobalInfo ^ goal_sizes := GoalSizes
+        GoalSizes1 = !.GlobalInfo ^ hogi_goal_sizes,
+        map.set(GoalSizes1, PredId, GoalSize, GoalSizes),
+        !:GlobalInfo = !.GlobalInfo ^ hogi_goal_sizes := GoalSizes
     ).
 
     % This is called when the first procedure of a predicate was changed.
     % It fixes up all the other procedures, ignoring the goal_size and requests
     % that come out, since that information has already been collected.
     %
-:- pred traverse_proc(bool::in, pred_id::in, proc_id::in,
+:- pred traverse_proc(must_recompute::in, pred_id::in, proc_id::in,
     higher_order_global_info::in, higher_order_global_info::out) is det.
 
 traverse_proc(MustRecompute, PredId, ProcId, !GlobalInfo) :-
     map.init(PredVars0),
-    module_info_pred_proc_info(!.GlobalInfo ^ module_info,
+    module_info_pred_proc_info(!.GlobalInfo ^ hogi_module_info,
         PredId, ProcId, PredInfo0, ProcInfo0),
     Info0 = higher_order_info(!.GlobalInfo, PredVars0, proc(PredId, ProcId),
         PredInfo0, ProcInfo0, unchanged),
-    traverse_goal(MustRecompute, Info0, Info),
+    traverse_proc_body(MustRecompute, Info0, Info),
     Info = higher_order_info(!:GlobalInfo, _, _, PredInfo, ProcInfo, _),
+    ModuleInfo0 = !.GlobalInfo ^ hogi_module_info,
     module_info_set_pred_proc_info(PredId, ProcId, PredInfo, ProcInfo,
-        !.GlobalInfo ^ module_info, ModuleInfo),
-    !:GlobalInfo = !.GlobalInfo ^ module_info := ModuleInfo.
+        ModuleInfo0, ModuleInfo),
+    !:GlobalInfo = !.GlobalInfo ^ hogi_module_info := ModuleInfo.
 
 %-----------------------------------------------------------------------------%
 %
 % Goal traversal
 %
 
-:- pred traverse_goal(bool::in,
-    higher_order_info::in, higher_order_info::out) is det.
-
-traverse_goal(MustRecompute, !Info) :-
-    VersionInfoMap = !.Info ^ global_info ^ version_info,
-    %
-    % Lookup the initial known bindings of the variables if this
-    % procedure is a specialised version.
-    %
-    (
-        map.search(VersionInfoMap, !.Info ^ pred_proc_id, VersionInfo),
-        VersionInfo = version_info(_, _, PredVars, _)
-    ->
-        !:Info = !.Info ^ pred_vars := PredVars
-    ;
-        true
-    ),
-    proc_info_get_goal(!.Info ^ proc_info, Goal0),
-    traverse_goal_2(Goal0, Goal, !Info),
-    fixup_proc_info(MustRecompute, Goal, !Info).
-
-:- pred fixup_proc_info(bool::in, hlds_goal::in,
+:- pred fixup_proc_info(must_recompute::in, hlds_goal::in,
     higher_order_info::in, higher_order_info::out) is det.
 
 fixup_proc_info(MustRecompute, Goal0, !Info) :-
     (
-        ( !.Info ^ changed = changed
-        ; MustRecompute = yes
+        ( !.Info ^ hoi_changed = changed
+        ; MustRecompute = must_recompute
         )
     ->
         some [!ModuleInfo, !ProcInfo] (
-            !:ModuleInfo = !.Info ^ global_info ^ module_info,
-            !:ProcInfo   = !.Info ^ proc_info,
+            !:ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
+            !:ProcInfo   = !.Info ^ hoi_proc_info,
             proc_info_set_goal(Goal0, !ProcInfo),
             requantify_proc(!ProcInfo),
             proc_info_get_goal(!.ProcInfo, Goal2),
@@ -517,46 +497,68 @@
             recompute_instmap_delta(RecomputeAtomic, Goal2, Goal3,
                 VarTypes, InstVarSet, InstMap, !ModuleInfo),
             proc_info_set_goal(Goal3, !ProcInfo),
-            !:Info = !.Info ^ proc_info := !.ProcInfo,
-            !:Info = !.Info ^ global_info ^ module_info := !.ModuleInfo
+            !Info ^ hoi_proc_info := !.ProcInfo,
+            !Info ^ hoi_global_info ^ hogi_module_info := !.ModuleInfo
         )
     ;
         true
     ).
 
+:- pred traverse_proc_body(must_recompute::in,
+    higher_order_info::in, higher_order_info::out) is det.
+
+traverse_proc_body(MustRecompute, !Info) :-
+    % Lookup the initial known bindings of the variables if this procedure
+    % is a specialised version.
+    VersionInfoMap = !.Info ^ hoi_global_info ^ hogi_version_info,
+    (
+        map.search(VersionInfoMap, !.Info ^ hoi_pred_proc_id, VersionInfo),
+        VersionInfo = version_info(_, _, PredVars, _)
+    ->
+        !:Info = !.Info ^ hoi_pred_vars := PredVars
+    ;
+        true
+    ),
+    proc_info_get_goal(!.Info ^ hoi_proc_info, Goal0),
+    traverse_goal(Goal0, Goal, !Info),
+    fixup_proc_info(MustRecompute, Goal, !Info).
+
     % Traverses the goal collecting higher order variables for which the value
     % is known, and specializing calls and adding specialization requests
     % to the request_info structure. The first time through the only predicate
     % we can specialize is call/N. The pred_proc_id is that of the current
     % procedure, used to find out which procedures need fixing up later.
     %
-:- pred traverse_goal_2(hlds_goal::in, hlds_goal::out,
+:- pred traverse_goal(hlds_goal::in, hlds_goal::out,
     higher_order_info::in, higher_order_info::out) is det.
 
-traverse_goal_2(hlds_goal(conj(ConjType, Goals0), GoalInfo),
-        hlds_goal(conj(ConjType, Goals), GoalInfo), !Info) :-
+traverse_goal(Goal0, Goal, !Info) :-
+    Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
     (
         ConjType = plain_conj,
-        list.map_foldl(traverse_goal_2, Goals0, Goals, !Info)
+            list.map_foldl(traverse_goal, Goals0, Goals, !Info)
     ;
         ConjType = parallel_conj,
         traverse_independent_goals(Goals0, Goals, !Info)
-    ).
-
-traverse_goal_2(hlds_goal(disj(Goals0), GoalInfo),
-        hlds_goal(disj(Goals), GoalInfo), !Info) :-
-    traverse_independent_goals(Goals0, Goals, !Info).
-
-traverse_goal_2(hlds_goal(switch(Var, CanFail, Cases0), GoalInfo),
-        hlds_goal(switch(Var, CanFail, Cases), GoalInfo), !Info) :-
+        ),
+        GoalExpr = conj(ConjType, Goals),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = disj(Goals0),
+        traverse_independent_goals(Goals0, Goals, !Info),
+        GoalExpr = disj(Goals),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = switch(Var, CanFail, Cases0),
     % A switch is treated as a disjunction.
-    %
-    traverse_cases(Cases0, Cases, !Info).
-
+        traverse_cases(Cases0, Cases, !Info),
+        GoalExpr = switch(Var, CanFail, Cases),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = generic_call(GenericCall, Args, _, _),
     % Check whether this call could be specialized.
-    %
-traverse_goal_2(Goal0, Goal, !Info) :-
-    Goal0 = hlds_goal(generic_call(GenericCall, Args, _, _), GoalInfo),
     (
         (
             GenericCall = higher_order(Var, _, _, _),
@@ -564,68 +566,67 @@
         ;
             GenericCall = class_method(Var, Method, _, _),
             MaybeMethod = yes(Method)
-        )
-    ->
+            ),
         maybe_specialize_higher_order_call(Var, MaybeMethod, Args,
             Goal0, Goals, !Info),
-        conj_list_to_goal(Goals, GoalInfo, Goal)
+            conj_list_to_goal(Goals, GoalInfo0, Goal)
     ;
+            ( GenericCall = event_call(_)
+            ; GenericCall = cast(_)
+            ),
         Goal = Goal0
-    ).
-
-traverse_goal_2(Goal0, Goal, !Info) :-
-    % Check whether this call can be specialized.
-    %
-    Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
+        )
+    ;
     GoalExpr0 = plain_call(_, _, _, _, _, _),
-    % XXX Due to the absence of alias tracking, assing Goal0 instead of Goal1
-    % would result in a mode error.
+        % Check whether this call can be specialized.
+        % XXX Due to the absence of alias tracking, passing Goal0 instead
+        % of Goal1 to maybe_specialize_call would result in a mode error.
     Goal1 = hlds_goal(GoalExpr0, GoalInfo0),
-    maybe_specialize_call(Goal1, Goal, !Info).
-
-traverse_goal_2(Goal0, Goal, !Info) :-
-    % if-then-elses are handled as disjunctions.
-    %
-    Goal0 = hlds_goal(if_then_else(Vars, Cond0, Then0, Else0), GoalInfo),
+        maybe_specialize_call(Goal1, Goal, !Info)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
+        % If-then-elses are handled as disjunctions.
     get_pre_branch_info(!.Info, PreInfo),
-    traverse_goal_2(Cond0, Cond, !Info),
-    traverse_goal_2(Then0, Then, !Info),
+        traverse_goal(Cond0, Cond, !Info),
+        traverse_goal(Then0, Then, !Info),
     get_post_branch_info(!.Info, PostThenInfo),
     set_pre_branch_info(PreInfo, !Info),
-    traverse_goal_2(Else0, Else, !Info),
+        traverse_goal(Else0, Else, !Info),
     get_post_branch_info(!.Info, PostElseInfo),
-    Goal = hlds_goal(if_then_else(Vars, Cond, Then, Else), GoalInfo),
     merge_post_branch_infos(PostThenInfo, PostElseInfo, PostInfo),
-    set_post_branch_info(PostInfo, !Info).
-
-traverse_goal_2(hlds_goal(negation(NegGoal0), GoalInfo),
-        hlds_goal(negation(NegGoal), GoalInfo), !Info) :-
-    traverse_goal_2(NegGoal0, NegGoal, !Info).
-
-traverse_goal_2(hlds_goal(scope(Reason, Goal0), GoalInfo),
-        hlds_goal(scope(Reason, Goal), GoalInfo), !Info) :-
-    traverse_goal_2(Goal0, Goal, !Info).
-
-traverse_goal_2(Goal, Goal, !Info) :-
-    Goal = hlds_goal(call_foreign_proc(_, _, _, _, _, _, _), _).
-
-traverse_goal_2(Goal0, Goal, !Info) :-
-    Goal0 = hlds_goal(GoalExpr0, _),
-    GoalExpr0 = unify(_, _, _, Unify0, _),
-    ( Unify0 = construct(_, pred_const(_, _), _, _, _, _, _) ->
+        set_post_branch_info(PostInfo, !Info),
+        GoalExpr = if_then_else(Vars, Cond, Then, Else),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = negation(SubGoal0),
+        traverse_goal(SubGoal0, SubGoal, !Info),
+        GoalExpr = negation(SubGoal),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = scope(Reason, SubGoal0),
+        traverse_goal(SubGoal0, SubGoal, !Info),
+        GoalExpr = scope(Reason, SubGoal),
+        Goal = hlds_goal(GoalExpr, GoalInfo0)
+    ;
+        GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _),
+        Goal = Goal0
+    ;
+        GoalExpr0 = unify(_, _, _, Unification0, _),
+        ( Unification0 = construct(_, pred_const(_, _), _, _, _, _, _) ->
         maybe_specialize_pred_const(Goal0, Goal, !Info)
     ;
         Goal = Goal0
     ),
-    ( Goal = hlds_goal(unify(_, _, _, Unify, _), _) ->
-        check_unify(Unify, !Info)
+        ( Goal = hlds_goal(unify(_, _, _, Unification, _), _) ->
+            check_unify(Unification, !Info)
     ;
         true
-    ).
-
-traverse_goal_2(hlds_goal(shorthand(_), _), _, !Info) :-
+        )
+    ;
+        GoalExpr0 = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "traverse_goal_2: unexpected shorthand").
+        unexpected(this_file, "traverse_goal: unexpected shorthand")
+    ).
 
     % To process a disjunction, we process each disjunct with the
     % specialization information before the goal, then merge the
@@ -660,7 +661,7 @@
 traverse_independent_goals_2(PreInfo, [Goal0 | Goals0], [Goal | Goals],
         !PostInfos, !Info) :-
     set_pre_branch_info(PreInfo, !Info),
-    traverse_goal_2(Goal0, Goal, !Info),
+    traverse_goal(Goal0, Goal, !Info),
     get_post_branch_info(!.Info, GoalPostInfo),
     !:PostInfos = [GoalPostInfo | !.PostInfos],
     traverse_independent_goals_2(PreInfo, Goals0, Goals, !PostInfos, !Info).
@@ -693,7 +694,7 @@
         !Info) :-
     set_pre_branch_info(PreInfo, !Info),
     Case0 = case(MainConsId, OtherConsIds, Goal0),
-    traverse_goal_2(Goal0, Goal, !Info),
+    traverse_goal(Goal0, Goal, !Info),
     Case = case(MainConsId, OtherConsIds, Goal),
     get_post_branch_info(!.Info, GoalPostInfo),
     !:PostInfos = [GoalPostInfo | !.PostInfos],
@@ -708,24 +709,24 @@
 :- pred get_pre_branch_info(higher_order_info::in, pre_branch_info::out)
     is det.
 
-get_pre_branch_info(Info, pre_branch_info(Info ^ pred_vars)).
+get_pre_branch_info(Info, pre_branch_info(Info ^ hoi_pred_vars)).
 
 :- pred set_pre_branch_info(pre_branch_info::in,
     higher_order_info::in, higher_order_info::out) is det.
 
 set_pre_branch_info(pre_branch_info(PreInfo),
-    Info, Info ^ pred_vars := PreInfo).
+    Info, Info ^ hoi_pred_vars := PreInfo).
 
 :- pred get_post_branch_info(higher_order_info::in, post_branch_info::out)
     is det.
 
-get_post_branch_info(Info, post_branch_info(Info ^ pred_vars)).
+get_post_branch_info(Info, post_branch_info(Info ^ hoi_pred_vars)).
 
 :- pred set_post_branch_info(post_branch_info::in,
     higher_order_info::in, higher_order_info::out) is det.
 
 set_post_branch_info(post_branch_info(PostInfo),
-    Info, Info ^ pred_vars := PostInfo).
+    Info, Info ^ hoi_pred_vars := PostInfo).
 
     % Merge a bunch of post_branch_infos into one.
     %
@@ -826,60 +827,77 @@
 :- pred check_unify(unification::in,
     higher_order_info::in, higher_order_info::out) is det.
 
-check_unify(simple_test(_, _), !Info).
+check_unify(Unification, !Info) :-
+    (
+        Unification = simple_test(_, _)
     % Testing two higher order terms for equality is not allowed.
-check_unify(assign(Var1, Var2), !Info) :-
-    maybe_add_alias(Var1, Var2, !Info).
-check_unify(deconstruct(_, _, _, _, _, _), !Info).
+    ;
+        Unification = assign(Var1, Var2),
+        maybe_add_alias(Var1, Var2, !Info)
+    ;
+        Unification = deconstruct(_, _, _, _, _, _)
     % Deconstructing a higher order term is not allowed.
-check_unify(construct(LVar, ConsId, Args, _Modes, _, _, _), !Info) :-
-    ( is_interesting_cons_id(!.Info ^ global_info ^ ho_params, ConsId) = yes ->
-        ( map.search(!.Info ^ pred_vars, LVar, Specializable) ->
+    ;
+        Unification = construct(LVar, ConsId, Args, _Modes, _, _, _),
+        Params = !.Info ^ hoi_global_info ^ hogi_params,
+        IsInteresting = is_interesting_cons_id(Params, ConsId),
+        (
+            IsInteresting = yes,
+            PredVars0 = !.Info ^ hoi_pred_vars,
+            ( map.search(PredVars0, LVar, Specializable) ->
             (
                 % We cannot specialize calls involving a variable with
                 % more than one possible value.
                 Specializable = constant(_, _),
-                map.det_update(!.Info ^ pred_vars, LVar,
-                    multiple_values, PredVars),
-                !:Info = !.Info ^ pred_vars := PredVars
+                    map.det_update(PredVars0, LVar, multiple_values, PredVars),
+                    !:Info = !.Info ^ hoi_pred_vars := PredVars
             ;
                 % If a variable is already non-specializable, it can't
                 % become specializable.
                 Specializable = multiple_values
             )
         ;
-            map.det_insert(!.Info ^ pred_vars, LVar,
-                constant(ConsId, Args), PredVars),
-            !:Info = !.Info ^ pred_vars := PredVars
+                map.det_insert(PredVars0, LVar, constant(ConsId, Args),
+                    PredVars),
+                !:Info = !.Info ^ hoi_pred_vars := PredVars
         )
     ;
-        true
+            IsInteresting = no
+        )
+    ;
+        Unification = complicated_unify(_, _, _),
+        unexpected(this_file, "check_unify: complicated unification")
     ).
-check_unify(complicated_unify(_, _, _), !Info) :-
-    unexpected(this_file, "check_unify - complicated unification").
 
 :- func is_interesting_cons_id(ho_params, cons_id) = bool.
 
-is_interesting_cons_id(_Params, cons(_, _)) = no.
+is_interesting_cons_id(Params, ConsId) = IsInteresting :-
+    (
+        ( ConsId = cons(_, _)
+        ; ConsId = string_const(_)
+        ; ConsId = float_const(_)
+        ; ConsId = tabling_info_const(_)
+        ; ConsId = deep_profiling_proc_layout(_)
+        ; ConsId = table_io_decl(_)
+        ),
+        IsInteresting = no
+    ;
+        ConsId = int_const(_),
     % We need to keep track of int_consts so we can interpret
     % superclass_info_from_typeclass_info and
     % typeinfo_from_typeclass_info.  We don't specialize based on them.
-is_interesting_cons_id(Params, int_const(_)) = Params ^ user_type_spec.
-is_interesting_cons_id(_Params, string_const(_)) = no.
-is_interesting_cons_id(_Params, float_const(_)) = no.
-is_interesting_cons_id(Params, pred_const(_, _)) =
-    Params ^ optimize_higher_order.
-is_interesting_cons_id(Params, type_ctor_info_const(_, _, _)) =
-    Params ^ user_type_spec.
-is_interesting_cons_id(Params, base_typeclass_info_const(_, _, _, _)) =
-    Params ^ user_type_spec.
-is_interesting_cons_id(Params, type_info_cell_constructor(_)) =
-    Params ^ user_type_spec.
-is_interesting_cons_id(Params, typeclass_info_cell_constructor) =
-    Params ^ user_type_spec.
-is_interesting_cons_id(_Params, tabling_info_const(_)) = no.
-is_interesting_cons_id(_Params, deep_profiling_proc_layout(_)) = no.
-is_interesting_cons_id(_Params, table_io_decl(_)) = no.
+        IsInteresting = Params ^ param_do_user_type_spec
+    ;
+        ( ConsId = type_ctor_info_const(_, _, _)
+        ; ConsId = base_typeclass_info_const(_, _, _, _)
+        ; ConsId = type_info_cell_constructor(_)
+        ; ConsId = typeclass_info_cell_constructor
+        ),
+        IsInteresting = Params ^ param_do_user_type_spec
+    ;
+        ConsId = pred_const(_, _),
+        IsInteresting = Params ^ param_do_higher_order_spec
+    ).
 
     % Process a higher-order call or class_method_call to see if it
     % could possibly be specialized.
@@ -890,11 +908,12 @@
 
 maybe_specialize_higher_order_call(PredVar, MaybeMethod, Args,
         hlds_goal(GoalExpr0, GoalInfo), Goals, !Info) :-
-    ModuleInfo = !.Info ^ global_info ^ module_info,
+    ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
     % We can specialize calls to call/N and class_method_call/N
     % if the closure or typeclass_info has a known value.
     (
-        map.search(!.Info ^ pred_vars, PredVar, constant(ConsId, CurriedArgs)),
+        map.search(!.Info ^ hoi_pred_vars, PredVar,
+            constant(ConsId, CurriedArgs)),
         (
             ConsId = pred_const(ShroudedPredProcId, _),
             MaybeMethod = no
@@ -904,10 +923,10 @@
         ;
             % A typeclass_info variable should consist of a known
             % base_typeclass_info and some argument typeclass_infos.
-            %
+
             ConsId = typeclass_info_cell_constructor,
             CurriedArgs = [BaseTypeClassInfo | OtherTypeClassArgs],
-            map.search(!.Info ^ pred_vars, BaseTypeClassInfo,
+            map.search(!.Info ^ hoi_pred_vars, BaseTypeClassInfo,
                 constant(BaseConsId, _)),
             BaseConsId = base_typeclass_info_const(_, ClassId, Instance, _),
             MaybeMethod = yes(Method),
@@ -947,11 +966,11 @@
         % instance declarations are visible in the imported module, so we
         % don't know which class constraints are redundant after type
         % specialization.
-        %
+
         MaybeMethod = yes(Method),
 
-        CallerProcInfo0 = !.Info ^ proc_info,
-        CallerPredInfo0 = !.Info ^ pred_info,
+        CallerProcInfo0 = !.Info ^ hoi_proc_info,
+        CallerPredInfo0 = !.Info ^ hoi_pred_info,
         proc_info_get_rtti_varmaps(CallerProcInfo0, CallerRttiVarMaps),
         rtti_varmaps_var_info(CallerRttiVarMaps, PredVar,
             typeclass_info_var(ClassConstraint)),
@@ -987,8 +1006,8 @@
                 AllArgs),
             list.append(ArgTypeInfoGoals, ArgTypeClassInfoGoals, ExtraGoals)
         ),
-        !:Info = !.Info ^ pred_info := CallerPredInfo,
-        !:Info = !.Info ^ proc_info := CallerProcInfo,
+        !:Info = !.Info ^ hoi_pred_info := CallerPredInfo,
+        !:Info = !.Info ^ hoi_proc_info := CallerProcInfo,
         construct_specialized_higher_order_call(PredId, ProcId,
             AllArgs, GoalInfo, Goal, !Info),
         list.append(ExtraGoals, [Goal], Goals)
@@ -1130,18 +1149,18 @@
 
 construct_specialized_higher_order_call(PredId, ProcId, AllArgs, GoalInfo,
         hlds_goal(GoalExpr, GoalInfo), !Info) :-
-    ModuleInfo = !.Info ^ global_info ^ module_info,
+    ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     ModuleName = pred_info_module(PredInfo),
     PredName = pred_info_name(PredInfo),
     SymName = qualified(ModuleName, PredName),
-    proc(CallerPredId, _) = !.Info ^ pred_proc_id,
+    proc(CallerPredId, _) = !.Info ^ hoi_pred_proc_id,
     Builtin = builtin_state(ModuleInfo, CallerPredId, PredId, ProcId),
 
     MaybeContext = no,
     GoalExpr1 = plain_call(PredId, ProcId, AllArgs, Builtin, MaybeContext,
         SymName),
-    !:Info = !.Info ^ changed := changed,
+    !:Info = !.Info ^ hoi_changed := changed,
     maybe_specialize_call(hlds_goal(GoalExpr1, GoalInfo),
         hlds_goal(GoalExpr, _), !Info).
 
@@ -1150,7 +1169,7 @@
 
 maybe_specialize_call(hlds_goal(GoalExpr0, GoalInfo),
         hlds_goal(GoalExpr, GoalInfo), !Info) :-
-    ModuleInfo0 = !.Info ^ global_info ^ module_info,
+    ModuleInfo0 = !.Info ^ hoi_global_info ^ hogi_module_info,
     GoalExpr0 = plain_call(CalledPred, CalledProc, Args0, IsBuiltin,
         MaybeContext, _SymName0),
     module_info_pred_proc_info(ModuleInfo0, CalledPred, CalledProc,
@@ -1163,7 +1182,7 @@
             MaybeContext, GoalInfo, HaveSpecialPreds, GoalExpr1, !Info)
     ->
         GoalExpr = GoalExpr1,
-        !:Info = !.Info ^ changed := changed
+        !:Info = !.Info ^ hoi_changed := changed
     ;
         polymorphism.is_typeclass_info_manipulator(ModuleInfo0,
             CalledPred, Manipulator)
@@ -1185,8 +1204,7 @@
     ->
         GoalExpr = GoalExpr0
     ;
-        CanRequest = yes,
-        maybe_specialize_ordinary_call(CanRequest, CalledPred, CalledProc,
+        maybe_specialize_ordinary_call(can_request, CalledPred, CalledProc,
             CalleePredInfo, CalleeProcInfo, Args0, IsBuiltin, MaybeContext,
             GoalInfo, Result, !Info),
         (
@@ -1216,9 +1234,9 @@
 
 maybe_specialize_pred_const(hlds_goal(GoalExpr0, GoalInfo),
         hlds_goal(GoalExpr, GoalInfo), !Info) :-
-    NewPreds   = !.Info ^ global_info ^ new_preds,
-    ModuleInfo = !.Info ^ global_info ^ module_info,
-    ProcInfo0  = !.Info ^ proc_info,
+    NewPreds   = !.Info ^ hoi_global_info ^ hogi_new_preds,
+    ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
+    ProcInfo0  = !.Info ^ hoi_proc_info,
     (
         GoalExpr0 = unify(_, _, UniMode, Unify0, Context),
         Unify0 = construct(LVar, ConsId0, Args0, _,
@@ -1240,21 +1258,20 @@
         proc_info_create_vars_from_types(ArgTypes, UncurriedArgs,
             ProcInfo0, ProcInfo1),
         list.append(Args0, UncurriedArgs, Args1),
-        !:Info = !.Info ^ proc_info := ProcInfo1,
+        !:Info = !.Info ^ hoi_proc_info := ProcInfo1,
 
         module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
             CalleePredInfo, CalleeProcInfo),
-        %
+
         % We don't create requests for higher-order terms because that would
         % result in duplication of effort if all uses of the constant end up
         % being specialized.  For parser combinator programs it would also
         % result in huge numbers of requests with no easy way to control which
         % ones should be created.
-        %
-        CanRequest = no,
+
         IsBuiltin = not_builtin,
         MaybeContext = no,
-        maybe_specialize_ordinary_call(CanRequest, PredId, ProcId,
+        maybe_specialize_ordinary_call(can_not_request, PredId, ProcId,
             CalleePredInfo, CalleeProcInfo, Args1, IsBuiltin, MaybeContext,
             GoalInfo, Result, !Info),
         (
@@ -1286,11 +1303,11 @@
                 CurriedArgModes, UniModes),
 
             % The dummy arguments can't be used anywhere.
-            ProcInfo2 = !.Info ^ proc_info,
+            ProcInfo2 = !.Info ^ hoi_proc_info,
             proc_info_get_vartypes(ProcInfo2, VarTypes2),
             map.delete_list(VarTypes2, UncurriedArgs, VarTypes),
             proc_info_set_vartypes(VarTypes, ProcInfo2, ProcInfo),
-            !:Info = !.Info ^ proc_info := ProcInfo,
+            !:Info = !.Info ^ hoi_proc_info := ProcInfo,
 
             NewPredProcId = proc(NewPredId, NewProcId),
             NewShroudedPredProcId = shroud_pred_proc_id(NewPredProcId),
@@ -1301,7 +1318,7 @@
                 UniMode, Unify, Context),
 
             % Make sure any constants in the ExtraTypeInfoGoals are recorded.
-            list.map_foldl(traverse_goal_2, ExtraTypeInfoGoals0,
+            list.map_foldl(traverse_goal, ExtraTypeInfoGoals0,
                 ExtraTypeInfoGoals, !Info),
             (
                 ExtraTypeInfoGoals = [],
@@ -1314,7 +1331,7 @@
         ;
             Result = not_specialized,
             % The dummy arguments can't be used anywhere.
-            !:Info = !.Info ^ proc_info := ProcInfo0,
+            !:Info = !.Info ^ hoi_proc_info := ProcInfo0,
             GoalExpr = GoalExpr0
         )
     ;
@@ -1329,29 +1346,33 @@
             )
     ;       not_specialized.
 
-:- pred maybe_specialize_ordinary_call(bool::in, pred_id::in, proc_id::in,
-    pred_info::in, proc_info::in, list(prog_var)::in, builtin_state::in,
-    maybe(call_unify_context)::in, hlds_goal_info::in,
-    specialization_result::out, higher_order_info::in, higher_order_info::out)
-    is det.
+:- type can_request
+    --->    can_request
+    ;       can_not_request.
+
+:- pred maybe_specialize_ordinary_call(can_request::in,
+    pred_id::in, proc_id::in, pred_info::in, proc_info::in,
+    list(prog_var)::in, builtin_state::in, maybe(call_unify_context)::in,
+    hlds_goal_info::in, specialization_result::out,
+    higher_order_info::in, higher_order_info::out) is det.
 
 maybe_specialize_ordinary_call(CanRequest, CalledPred, CalledProc,
         CalleePredInfo, CalleeProcInfo, Args0, IsBuiltin,
         MaybeContext, GoalInfo, Result, !Info) :-
-    ModuleInfo0 = !.Info ^ global_info ^ module_info,
+    ModuleInfo0 = !.Info ^ hoi_global_info ^ hogi_module_info,
     pred_info_get_import_status(CalleePredInfo, CalleeStatus),
     proc_info_get_vartypes(CalleeProcInfo, CalleeVarTypes),
     proc_info_get_headvars(CalleeProcInfo, CalleeHeadVars),
     map.apply_to_list(CalleeHeadVars, CalleeVarTypes, CalleeArgTypes),
 
-    CallerProcInfo0 = !.Info ^ proc_info,
+    CallerProcInfo0 = !.Info ^ hoi_proc_info,
     proc_info_get_vartypes(CallerProcInfo0, VarTypes),
     proc_info_get_rtti_varmaps(CallerProcInfo0, RttiVarMaps),
     find_higher_order_args(ModuleInfo0, CalleeStatus, Args0,
-        CalleeArgTypes, VarTypes, RttiVarMaps, !.Info ^ pred_vars, 1,
+        CalleeArgTypes, VarTypes, RttiVarMaps, !.Info ^ hoi_pred_vars, 1,
         [], HigherOrderArgs0),
 
-    proc(CallerPredId, _) = !.Info ^ pred_proc_id,
+    proc(CallerPredId, _) = !.Info ^ hoi_pred_proc_id,
     module_info_get_type_spec_info(ModuleInfo0, TypeSpecInfo),
     TypeSpecInfo = type_spec_info(_, ForceVersions, _, _),
     IsUserSpecProc = ( set.member(CallerPredId, ForceVersions) -> yes ; no ),
@@ -1363,7 +1384,8 @@
             % to avoid link errors.
             IsUserSpecProc = yes
         ;
-            !.Info ^ global_info ^ ho_params ^ user_type_spec = yes,
+            !.Info ^ hoi_global_info ^ hogi_params ^ param_do_user_type_spec
+                = yes,
             map.apply_to_list(Args0, VarTypes, ArgTypes),
 
             % Check whether any typeclass constraints now match an instance.
@@ -1371,7 +1393,7 @@
             CalleeClassContext = constraints(CalleeUnivConstraints0, _),
             pred_info_get_typevarset(CalleePredInfo, CalleeTVarSet),
             pred_info_get_exist_quant_tvars(CalleePredInfo, CalleeExistQTVars),
-            CallerPredInfo0 = !.Info ^ pred_info,
+            CallerPredInfo0 = !.Info ^ hoi_pred_info,
             pred_info_get_typevarset(CallerPredInfo0, TVarSet),
             pred_info_get_univ_quant_tvars(CallerPredInfo0, CallerUnivQTVars),
             type_subst_makes_instance_known(ModuleInfo0,
@@ -1398,20 +1420,22 @@
             CallGoal = plain_call(NewCalledPred, NewCalledProc, Args,
                 IsBuiltin, MaybeContext, NewName),
             Result = specialized(ExtraTypeInfoGoals, CallGoal),
-            !:Info = !.Info ^ changed := changed
+            !:Info = !.Info ^ hoi_changed := changed
         ;
             % There is a known higher order variable in the call, so we
             % put in a request for a specialized version of the pred.
             FindResult = find_result_request(Request),
             Result = not_specialized,
             (
-                CanRequest = yes,
-                set.insert(!.Info ^ global_info ^ requests, Request, Requests),
-                update_changed_status(!.Info ^ changed, request, Changed),
-                !:Info = !.Info ^ global_info ^ requests := Requests,
-                !:Info = !.Info ^ changed := Changed
+                CanRequest = can_request,
+                Requests0 = !.Info ^ hoi_global_info ^ hogi_requests,
+                Changed0 = !.Info ^ hoi_changed,
+                set.insert(Requests0, Request, Requests),
+                update_changed_status(Changed0, request, Changed),
+                !:Info = !.Info ^ hoi_global_info ^ hogi_requests := Requests,
+                !:Info = !.Info ^ hoi_changed := Changed
             ;
-                CanRequest = no
+                CanRequest = can_not_request
             )
         ;
             FindResult = find_result_no_request,
@@ -1571,12 +1595,12 @@
     % Args is the original list of arguments with the curried arguments
     % of known higher-order arguments added.
 
-    ModuleInfo = Info ^ global_info ^ module_info,
-    NewPreds = Info ^ global_info ^ new_preds,
-    Caller = Info ^ pred_proc_id,
-    PredInfo = Info ^ pred_info,
-    ProcInfo = Info ^ proc_info,
-    Params = Info ^ global_info ^ ho_params,
+    ModuleInfo = Info ^ hoi_global_info ^ hogi_module_info,
+    NewPreds = Info ^ hoi_global_info ^ hogi_new_preds,
+    Caller = Info ^ hoi_pred_proc_id,
+    PredInfo = Info ^ hoi_pred_info,
+    ProcInfo = Info ^ hoi_proc_info,
+    Params = Info ^ hoi_global_info ^ hogi_params,
 
     % WARNING - do not filter out higher-order arguments after this step,
     % except when partially matching against a previously produced
@@ -1606,9 +1630,9 @@
     ->
         Result = find_result_match(Match)
     ;
-        HigherOrder = Params ^ optimize_higher_order,
-        TypeSpec = Params ^ type_spec,
-        UserTypeSpec = Params ^ user_type_spec,
+        HigherOrder = Params ^ param_do_higher_order_spec,
+        TypeSpec = Params ^ param_do_type_spec,
+        UserTypeSpec = Params ^ param_do_user_type_spec,
         (
             UserTypeSpec = yes,
             IsUserSpecProc = yes
@@ -1659,7 +1683,7 @@
     % version (`goal_util.extra_nonlocal_typeinfos' is not used here
     % because the type variables are returned sorted by variable number,
     % which will vary between calls).
-    ProcInfo = Info ^ proc_info,
+    ProcInfo = Info ^ hoi_proc_info,
     proc_info_get_vartypes(ProcInfo, VarTypes),
     map.apply_to_list(Args, VarTypes, ArgTypes),
     type_vars_list(ArgTypes, AllTVars),
@@ -1668,7 +1692,7 @@
         ExtraTypeInfoTVars = []
     ;
         AllTVars = [_ | _],
-        proc_info_get_rtti_varmaps(Info ^ proc_info, RttiVarMaps),
+        proc_info_get_rtti_varmaps(Info ^ hoi_proc_info, RttiVarMaps),
         list.foldl(arg_contains_type_info_for_tvar(RttiVarMaps),
             Args, [], TypeInfoTVars),
         list.delete_elems(AllTVars, TypeInfoTVars, ExtraTypeInfoTVars0),
@@ -1690,8 +1714,7 @@
     ;
         VarInfo = typeclass_info_var(Constraint),
         Constraint = constraint(_ClassName, ClassArgTypes),
-        % Find out what tvars the typeclass-info contains the type-infos
-        % for.
+        % Find out what tvars the typeclass-info contains the type-infos for.
         list.filter_map(
             (pred(ClassArgType::in, ClassTVar::out) is semidet :-
                 ClassArgType = type_variable(ClassTVar, _)
@@ -1706,16 +1729,16 @@
     higher_order_info::in, higher_order_info::out) is det.
 
 construct_extra_type_infos(Types, TypeInfoVars, TypeInfoGoals, !Info) :-
-    create_poly_info(!.Info ^ global_info ^ module_info,
-        !.Info ^ pred_info, !.Info ^ proc_info, PolyInfo0),
+    create_poly_info(!.Info ^ hoi_global_info ^ hogi_module_info,
+        !.Info ^ hoi_pred_info, !.Info ^ hoi_proc_info, PolyInfo0),
     term.context_init(Context),
     polymorphism_make_type_info_vars(Types, Context,
         TypeInfoVars, TypeInfoGoals, PolyInfo0, PolyInfo),
-    poly_info_extract(PolyInfo, !.Info ^ pred_info, PredInfo,
-        !.Info ^ proc_info, ProcInfo, ModuleInfo),
-    !:Info = !.Info ^ pred_info := PredInfo,
-    !:Info = !.Info ^ proc_info := ProcInfo,
-    !:Info = !.Info ^ global_info ^ module_info := ModuleInfo.
+    poly_info_extract(PolyInfo, !.Info ^ hoi_pred_info, PredInfo,
+        !.Info ^ hoi_proc_info, ProcInfo, ModuleInfo),
+    !:Info = !.Info ^ hoi_pred_info := PredInfo,
+    !:Info = !.Info ^ hoi_proc_info := ProcInfo,
+    !:Info = !.Info ^ hoi_global_info ^ hogi_module_info := ModuleInfo.
 
 :- pred search_for_version(higher_order_info::in, ho_params::in,
     module_info::in, request::in, list(new_pred)::in,
@@ -1775,14 +1798,14 @@
         VersionExtraTypeInfoTVars, VersionArgTypes0, _,
         VersionTVarSet, _),
     higher_order_args_match(RequestHigherOrderArgs,
-        VersionHigherOrderArgs, HigherOrderArgs, MatchIsPartial),
+        VersionHigherOrderArgs, HigherOrderArgs, FullOrPartial),
     (
         % Don't accept partial matches unless the predicate is imported
         % or we are only doing user-guided type specialization.
-        MatchIsPartial = no,
+        FullOrPartial = match_is_partial,
         PartialMatch = no
     ;
-        MatchIsPartial = yes,
+        FullOrPartial = match_is_full,
         list.length(HigherOrderArgs, NumHOArgs),
         PartialMatch = yes(NumHOArgs),
         pred_info_get_markers(CalleePredInfo, Markers),
@@ -1791,7 +1814,7 @@
         \+ check_marker(Markers, marker_class_method),
         \+ check_marker(Markers, marker_class_instance_method),
         (
-            Params ^ type_spec = no
+            Params ^ param_do_type_spec = no
         ;
             pred_info_is_imported(CalleePredInfo)
         )
@@ -1818,12 +1841,16 @@
         ExtraTypeInfoTypes),
     get_extra_arguments(HigherOrderArgs, Args0, Args).
 
+:- type match_is_full
+    --->    match_is_full
+    ;       match_is_partial.
+
 :- pred higher_order_args_match(list(higher_order_arg)::in,
-    list(higher_order_arg)::in, list(higher_order_arg)::out, bool::out)
-    is semidet.
+    list(higher_order_arg)::in, list(higher_order_arg)::out,
+    match_is_full::out) is semidet.
 
-higher_order_args_match([], [], [], no).
-higher_order_args_match(RequestArgs, [], [], yes) :-
+higher_order_args_match([], [], [], match_is_full).
+higher_order_args_match(RequestArgs, [], [], match_is_partial) :-
     RequestArgs = [_ | _],
     \+ (
         list.member(RequestArg, RequestArgs),
@@ -1831,7 +1858,7 @@
         RequestConsId = pred_const(_, _)
     ).
 higher_order_args_match([RequestArg | Args1], [VersionArg | Args2],
-        Args, PartialMatch) :-
+        Args, FullOrPartial) :-
     RequestArg = higher_order_arg(ConsId1, ArgNo1, _, _, _, _, _,
         RequestIsConst),
     VersionArg = higher_order_arg(ConsId2, ArgNo2, _, _, _, _, _,
@@ -1844,7 +1871,7 @@
         VersionArg = higher_order_arg(_, _, NumArgs,
             _, _, _, HOCurriedArgs2, _),
         higher_order_args_match(HOCurriedArgs1, HOCurriedArgs2,
-            NewHOCurriedArgs, PartialMatch),
+            NewHOCurriedArgs, FullOrPartial),
         higher_order_args_match(Args1, Args2, Args3, _),
         NewRequestArg = higher_order_arg(ConsId1, ArgNo1, NumArgs,
             CurriedArgs, CurriedArgTypes, CurriedArgRttiInfo,
@@ -1859,8 +1886,8 @@
         % All the higher-order arguments must be present in the version
         % otherwise we should create a new one.
         ConsId1 \= pred_const(_, _),
-        PartialMatch = yes,
-        higher_order_args_match(Args1, [VersionArg | Args2], Args, _)
+        higher_order_args_match(Args1, [VersionArg | Args2], Args, _),
+        FullOrPartial = match_is_partial
     ).
 
     % Add the curried arguments of the higher-order terms to the argument list.
@@ -1901,9 +1928,10 @@
     higher_order_info::in, higher_order_info::out) is det.
 
 maybe_add_alias(LVar, RVar, !Info) :-
-    ( map.search(!.Info ^ pred_vars, RVar, constant(A, B)) ->
-        map.set(!.Info ^ pred_vars, LVar, constant(A, B), PredVars),
-        !:Info = !.Info ^ pred_vars := PredVars
+    PredVars0 = !.Info ^ hoi_pred_vars,
+    ( map.search(PredVars0, RVar, constant(A, B)) ->
+        map.set(PredVars0, LVar, constant(A, B), PredVars),
+        !:Info = !.Info ^ hoi_pred_vars := PredVars
     ;
         true
     ).
@@ -1929,8 +1957,8 @@
     higher_order_info::in, higher_order_info::out) is det.
 
 interpret_typeclass_info_manipulator(Manipulator, Args, Goal0, Goal, !Info) :-
-    ModuleInfo = !.Info ^ global_info ^ module_info,
-    PredVars = !.Info ^ pred_vars,
+    ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
+    PredVars = !.Info ^ hoi_pred_vars,
     (
         Args = [TypeClassInfoVar, IndexVar, TypeInfoVar],
         map.search(PredVars, TypeClassInfoVar,
@@ -1967,7 +1995,7 @@
         Uni = assign(TypeInfoVar, TypeInfoArg),
         Goal = unify(TypeInfoVar, rhs_var(TypeInfoArg), out_mode - in_mode,
             Uni, unify_context(umc_explicit, [])),
-        !:Info = !.Info ^ changed := changed
+        !:Info = !.Info ^ hoi_changed := changed
     ;
         Goal = Goal0
     ).
@@ -1984,9 +2012,9 @@
 
 specialize_special_pred(CalledPred, CalledProc, Args, MaybeContext,
         OrigGoalInfo, HaveSpecialPreds, Goal, !Info) :-
-    ModuleInfo = !.Info ^ global_info ^ module_info,
-    ProcInfo0 = !.Info ^ proc_info,
-    PredVars = !.Info ^ pred_vars,
+    ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
+    ProcInfo0 = !.Info ^ hoi_proc_info,
+    PredVars = !.Info ^ hoi_pred_vars,
     proc_info_get_vartypes(ProcInfo0, VarTypes),
     module_info_pred_info(ModuleInfo, CalledPred, CalledPredInfo),
     mercury_public_builtin_module = pred_info_module(CalledPredInfo),
@@ -2131,8 +2159,8 @@
 
 specialize_unify_or_compare_pred_for_atomic(SpecialPredType, MaybeResult,
         Arg1, Arg2, MaybeContext, OrigGoalInfo, GoalExpr, !Info) :-
-    ModuleInfo = !.Info ^ global_info ^ module_info,
-    ProcInfo0 = !.Info ^ proc_info,
+    ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
+    ProcInfo0 = !.Info ^ hoi_proc_info,
     (
         MaybeResult = no,
         in_mode(In),
@@ -2167,7 +2195,7 @@
                 Context, GoalInfo),
             GoalExpr = conj(plain_conj,
                 [CastGoal1, CastGoal2, hlds_goal(Call, GoalInfo)]),
-            !:Info = !.Info ^ proc_info := ProcInfo
+            !:Info = !.Info ^ hoi_proc_info := ProcInfo
         )
     ).
 
@@ -2179,8 +2207,8 @@
 specialize_unify_or_compare_pred_for_no_tag(WrappedType, Constructor,
         MaybeResult, Arg1, Arg2, MaybeContext, OrigGoalInfo, GoalExpr,
         !Info) :-
-    ModuleInfo = !.Info ^ global_info ^ module_info,
-    ProcInfo0 = !.Info ^ proc_info,
+    ModuleInfo = !.Info ^ hoi_global_info ^ hogi_module_info,
+    ProcInfo0 = !.Info ^ hoi_proc_info,
     Context = goal_info_get_context(OrigGoalInfo),
     unwrap_no_tag_arg(WrappedType, Context, Constructor, Arg1,
         UnwrappedArg1, ExtractGoal1, ProcInfo0, ProcInfo1),
@@ -2200,7 +2228,7 @@
             Context, GoalInfo),
         GoalExpr = conj(plain_conj,
             [ExtractGoal1, ExtractGoal2, hlds_goal(SpecialGoal, GoalInfo)]),
-        !:Info = !.Info ^ proc_info := ProcInfo2
+        !:Info = !.Info ^ hoi_proc_info := ProcInfo2
     ;
         MaybeResult = yes(ComparisonResult),
         set.insert(NonLocals0, ComparisonResult, NonLocals),
@@ -2221,7 +2249,7 @@
                 Context, GoalInfo),
             GoalExpr = conj(plain_conj, [ExtractGoal1, ExtractGoal2,
                 hlds_goal(SpecialGoal, GoalInfo)]),
-            !:Info = !.Info ^ proc_info := ProcInfo2
+            !:Info = !.Info ^ hoi_proc_info := ProcInfo2
         ;
             NeedIntCast = yes,
             generate_unsafe_type_cast(Context, CompareType,
@@ -2236,7 +2264,7 @@
             GoalExpr = conj(plain_conj,
                 [ExtractGoal1, CastGoal1, ExtractGoal2, CastGoal2,
                 hlds_goal(SpecialGoal, GoalInfo)]),
-            !:Info = !.Info ^ proc_info := ProcInfo4
+            !:Info = !.Info ^ hoi_proc_info := ProcInfo4
         )
     ).
 
@@ -2245,7 +2273,7 @@
     higher_order_info::in, higher_order_info::out) is semidet.
 
 find_special_proc(Type, SpecialId, SymName, PredId, ProcId, !Info) :-
-    ModuleInfo0 = !.Info ^ global_info ^ module_info,
+    ModuleInfo0 = !.Info ^ hoi_global_info ^ hogi_module_info,
     (
         polymorphism.get_special_proc(Type, SpecialId, ModuleInfo0, SymName0,
             PredId0, ProcId0)
@@ -2286,7 +2314,7 @@
         ModuleName = pred_info_module(PredInfo),
         Name = pred_info_name(PredInfo),
         SymName = qualified(ModuleName, Name),
-        !:Info = !.Info ^ global_info ^ module_info := ModuleInfo
+        !:Info = !.Info ^ hoi_global_info ^ hogi_module_info := ModuleInfo
     ).
 
 :- pred find_builtin_type_with_equivalent_compare(module_info::in,
@@ -2296,19 +2324,11 @@
         NeedIntCast) :-
     TypeCategory = classify_type(ModuleInfo, Type),
     (
-        TypeCategory = type_cat_int,
-        EqvType = Type,
-        NeedIntCast = no
-    ;
-        TypeCategory = type_cat_char,
-        EqvType = Type,
-        NeedIntCast = no
-    ;
-        TypeCategory = type_cat_string,
-        EqvType = Type,
-        NeedIntCast = no
-    ;
-        TypeCategory = type_cat_float,
+        ( TypeCategory = type_cat_int
+        ; TypeCategory = type_cat_char
+        ; TypeCategory = type_cat_string
+        ; TypeCategory = type_cat_float
+        ),
         EqvType = Type,
         NeedIntCast = no
     ;
@@ -2408,8 +2428,8 @@
     io::di, io::uo) is det.
 
 filter_requests(FilteredRequests, LoopRequests, !Info, !IO) :-
-    Requests0 = set.to_sorted_list(!.Info ^ requests),
-    !:Info = !.Info ^ requests := set.init,
+    Requests0 = set.to_sorted_list(!.Info ^ hogi_requests),
+    !:Info = !.Info ^ hogi_requests := set.init,
     list.foldl3(filter_requests_2(!.Info), Requests0,
         [], FilteredRequests, [], LoopRequests, !IO).
 
@@ -2418,7 +2438,7 @@
     list(request)::in, list(request)::out, io::di, io::uo) is det.
 
 filter_requests_2(Info, Request, !AcceptedRequests, !LoopRequests, !IO) :-
-    ModuleInfo = Info ^ module_info,
+    ModuleInfo = Info ^ hogi_module_info,
     Request = ho_request(CallingPredProcId, CalledPredProcId, _, _, HOArgs,
         _, _, _, IsUserTypeSpec, Context),
     CalledPredProcId = proc(CalledPredId, _),
@@ -2440,19 +2460,20 @@
         list.cons(Request, !AcceptedRequests)
     ;
         IsUserTypeSpec = no,
-        ( map.search(Info ^ goal_sizes, CalledPredId, GoalSize0) ->
+        ( map.search(Info ^ hogi_goal_sizes, CalledPredId, GoalSize0) ->
             GoalSize = GoalSize0
         ;
             % This can happen for a specialized version.
             GoalSize = 0
         ),
         (
-            GoalSize > Info ^ ho_params ^ size_limit
+            GoalSize > Info ^ hogi_params ^ param_size_limit
         ->
             maybe_write_string(VeryVerbose,
                 "%    not specializing (goal too large).\n", !IO)
         ;
-            higher_order_args_size(HOArgs) > Info ^ ho_params ^ arg_limit
+            higher_order_args_size(HOArgs) >
+                Info ^ hogi_params ^ param_arg_limit
         ->
             % If the arguments are too large, we can end up producing a
             % specialized version with massive numbers of arguments, because
@@ -2465,7 +2486,7 @@
             % To ensure termination of the specialization process, the depth
             % of the higher-order arguments must strictly decrease compared
             % to parents with the same original pred_proc_id.
-            VersionInfoMap = Info ^ version_info,
+            VersionInfoMap = Info ^ hogi_version_info,
             (
                 map.search(VersionInfoMap, CalledPredProcId, CalledVersionInfo)
             ->
@@ -2504,13 +2525,13 @@
     Request = ho_request(CallingPredProcId, CalledPredProcId, _HOArgs,
         _CallArgs, _, _CallerArgTypes, _, _, _, _),
     set.insert(!.PredsToFix, CallingPredProcId, !:PredsToFix),
-    ( map.search(!.Info ^ new_preds, CalledPredProcId, SpecVersions0) ->
+    ( map.search(!.Info ^ hogi_new_preds, CalledPredProcId, SpecVersions0) ->
         (
             % Check that we aren't redoing the same pred.
             % SpecVersions0 are pred_proc_ids of the specialized versions
             % of the current pred.
             set.member(Version, SpecVersions0),
-            version_matches(!.Info ^ ho_params, !.Info ^ module_info,
+            version_matches(!.Info ^ hogi_params, !.Info ^ hogi_module_info,
                 Request, Version, _)
         ->
             true
@@ -2535,10 +2556,10 @@
     CallingPredProcId = Request ^ rq_caller,
     CalledPredProcId = Request ^ rq_callee,
     (
-        map.search(Info ^ new_preds, CalledPredProcId, SpecVersions0),
+        map.search(Info ^ hogi_new_preds, CalledPredProcId, SpecVersions0),
         some [Version] (
             set.member(Version, SpecVersions0),
-            version_matches(Info ^ ho_params, Info ^ module_info,
+            version_matches(Info ^ hogi_params, Info ^ hogi_module_info,
                 Request, Version, _)
         )
     ->
@@ -2558,7 +2579,7 @@
         HOArgs, ArgTypes, TypeInfoLiveness, CallerTVarSet,
         IsUserTypeSpec, Context),
     Caller = proc(CallerPredId, CallerProcId),
-    ModuleInfo0 = !.Info ^ module_info,
+    ModuleInfo0 = !.Info ^ hogi_module_info,
     module_info_pred_proc_info(ModuleInfo0, CalledPredProc,
         PredInfo0, ProcInfo0),
 
@@ -2600,9 +2621,9 @@
     ;
         IsUserTypeSpec = no,
         NewProcId = hlds_pred.initial_proc_id,
-        IdCounter0 = !.Info ^ next_ho_id,
+        IdCounter0 = !.Info ^ hogi_next_id,
         counter.allocate(Id, IdCounter0, IdCounter),
-        !:Info = !.Info ^ next_ho_id := IdCounter,
+        !:Info = !.Info ^ hogi_next_id := IdCounter,
         string.int_to_string(Id, IdStr),
         string.append_list([Name0, "__ho", IdStr], PredName),
         SymName = qualified(PredModule, PredName),
@@ -2645,7 +2666,7 @@
     predicate_table_insert(NewPredInfo1, NewPredId, PredTable0, PredTable),
     module_info_set_predicate_table(PredTable, ModuleInfo0, ModuleInfo1),
 
-    !:Info = !.Info ^ module_info := ModuleInfo1,
+    !:Info = !.Info ^ hogi_module_info := ModuleInfo1,
 
     NewPred = new_pred(proc(NewPredId, NewProcId), CalledPredProc, Caller,
         SymName, HOArgs, CallArgs, ExtraTypeInfoTVars, ArgTypes,
@@ -2654,21 +2675,23 @@
     add_new_pred(CalledPredProc, NewPred, !Info),
 
     create_new_proc(NewPred, ProcInfo0, NewPredInfo1, NewPredInfo, !Info),
-    module_info_set_pred_info(NewPredId, NewPredInfo,
-        !.Info ^ module_info, ModuleInfo),
-    !:Info = !.Info ^ module_info := ModuleInfo.
+    ModuleInfo2 = !.Info ^ hogi_module_info,
+    module_info_set_pred_info(NewPredId, NewPredInfo, ModuleInfo2, ModuleInfo),
+    !:Info = !.Info ^ hogi_module_info := ModuleInfo.
 
 :- pred add_new_pred(pred_proc_id::in, new_pred::in,
     higher_order_global_info::in, higher_order_global_info::out) is det.
 
 add_new_pred(CalledPredProcId, NewPred, !Info) :-
-    ( map.search(!.Info ^ new_preds, CalledPredProcId, SpecVersions0) ->
-        set.insert(SpecVersions0, NewPred, SpecVersions)
+    NewPreds0 = !.Info ^ hogi_new_preds,
+    ( map.search(NewPreds0, CalledPredProcId, SpecVersions0) ->
+        set.insert(SpecVersions0, NewPred, SpecVersions),
+        map.det_update(NewPreds0, CalledPredProcId, SpecVersions, NewPreds)
     ;
-        set.singleton_set(SpecVersions, NewPred)
+        set.singleton_set(SpecVersions, NewPred),
+        map.det_insert(NewPreds0, CalledPredProcId, SpecVersions, NewPreds)
     ),
-    map.set(!.Info ^ new_preds, CalledPredProcId, SpecVersions, NewPreds),
-    !:Info = !.Info ^ new_preds := NewPreds.
+    !:Info = !.Info ^ hogi_new_preds := NewPreds.
 
 :- pred maybe_write_request(bool::in, module_info::in, string::in,
     sym_name::in, arity::in, arity::in, maybe(string)::in,
@@ -2753,15 +2776,18 @@
 
 %-----------------------------------------------------------------------------%
 
+:- type must_recompute
+    --->    must_recompute
+    ;       need_not_recompute.
+
 :- pred fixup_preds(list(pred_proc_id)::in, higher_order_global_info::in,
     higher_order_global_info::out) is det.
 
 fixup_preds(PredProcIds, !Info) :-
-    MustRecompute = no,
-    Requests0 = !.Info ^ requests,
-    list.foldl(fixup_pred(MustRecompute), PredProcIds, !Info),
+    Requests0 = !.Info ^ hogi_requests,
+    list.foldl(fixup_pred(need_not_recompute), PredProcIds, !Info),
     % Any additional requests must have already been denied.
-    !:Info = !.Info ^ requests := Requests0.
+    !:Info = !.Info ^ hogi_requests := Requests0.
 
 :- pred fixup_specialized_versions(list(new_pred)::in,
     higher_order_global_info::in, higher_order_global_info::out) is det.
@@ -2770,12 +2796,11 @@
     NewPredProcIds = list.map(get_np_version_ppid, NewPredList),
     % Reprocess the goals to find any new specializations made
     % possible by the specializations performed in this pass.
-    MustRecompute = yes,
-    list.foldl(fixup_pred(MustRecompute), NewPredProcIds, !Info).
+    list.foldl(fixup_pred(must_recompute), NewPredProcIds, !Info).
 
     % Fixup calls to specialized predicates.
     %
-:- pred fixup_pred(bool::in, pred_proc_id::in,
+:- pred fixup_pred(must_recompute::in, pred_proc_id::in,
     higher_order_global_info::in, higher_order_global_info::out) is det.
 
 fixup_pred(MustRecompute, proc(PredId, ProcId), !GlobalInfo) :-
@@ -2790,7 +2815,7 @@
     higher_order_global_info::out) is det.
 
 create_new_proc(NewPred, !.NewProcInfo, !NewPredInfo, !Info) :-
-    ModuleInfo = !.Info ^ module_info,
+    ModuleInfo = !.Info ^ hogi_module_info,
 
     NewPred = new_pred(NewPredProcId, OldPredProcId, CallerPredProcId, _Name,
         HOArgs0, CallArgs, ExtraTypeInfoTVars0, CallerArgTypes0, _, _, _),
@@ -2906,14 +2931,14 @@
         ArgModes0, ExtraArgModes, HOArgs, !NewProcInfo,
         VarRenaming0, _, PredVars0, PredVars, ConstGoals),
 
-    % XXX the substitutions used to be applied to the typeclass_info_varmap
+    % XXX The substitutions used to be applied to the typeclass_info_varmap
     % here rather than at the XXX above.  Any new entries added in the code
     % between these two points should therefore be transformed as well?
     % The new entries come from HOArgs, which have already had TypeSubn
     % applied, but not TypeRenaming.  Perhaps this is enough?
 
     % Record extra information about this version.
-    VersionInfoMap0 = !.Info ^ version_info,
+    VersionInfoMap0 = !.Info ^ hogi_version_info,
     ArgsDepth = higher_order_args_depth(HOArgs),
 
     ( map.search(VersionInfoMap0, OldPredProcId, OldProcVersionInfo) ->
@@ -2934,7 +2959,7 @@
         PredVars, ParentVersions),
     map.det_insert(VersionInfoMap0, NewPredProcId, VersionInfo,
         VersionInfoMap),
-    !:Info = !.Info ^ version_info := VersionInfoMap,
+    !:Info = !.Info ^ hogi_version_info := VersionInfoMap,
 
     % Fix up the argument vars, types and modes.
     in_mode(InMode),
@@ -2974,7 +2999,7 @@
     % XXX We should apply this substitution to the variable types in any
     % callers of this predicate, which may introduce other opportunities
     % for specialization.
-    %
+
     (
         ExistQVars = []
     ;
@@ -2992,8 +3017,8 @@
                 VarTypes7, VarTypes8),
             proc_info_set_vartypes(VarTypes8, !NewProcInfo)
         ;
-            unexpected(this_file, "create_new_proc: " ++
-                "type_list_subsumes failed")
+            unexpected(this_file,
+                "create_new_proc: type_list_subsumes failed")
         )
     ),
 
@@ -3023,7 +3048,7 @@
     % specialised. If not, unused_args.m can clean them up.
     %
     % Build the initial pred_vars map which records higher-order and
-    % type_info constants for a call to traverse_goal.
+    % type_info constants for a call to traverse_proc_body.
     %
     % Build a var-var renaming from the requesting call's arguments to
     % the headvars of the specialized version.
@@ -3064,8 +3089,8 @@
             NonCurriedArgModes = NonCurriedArgModes0,
             CurriedArgModes1 = CurriedArgModes0
         ;
-            unexpected(this_file, "construct_higher_order_terms/13:" ++
-                "call to list.split_list failed.")
+            unexpected(this_file,
+                "construct_higher_order_terms: list.split_list failed.")
         ),
         proc_info_interface_determinism(CalledProcInfo, ProcDetism),
         GroundInstInfo = higher_order(pred_inst_info(PredOrFunc,
@@ -3086,9 +3111,8 @@
 
     (
         IsConst = no,
-        % Make traverse_goal pretend that the input higher-order
-        % argument is built using the new arguments as its curried
-        % arguments.
+        % Make traverse_proc_body pretend that the input higher-order argument
+        % is built using the new arguments as its curried arguments.
         svmap.det_insert(LVar, constant(ConsId, CurriedHeadVars1),
             !PredVars)
     ;
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.186
diff -u -b -r1.186 hlds_goal.m
--- compiler/hlds_goal.m	10 Jan 2008 04:29:51 -0000	1.186
+++ compiler/hlds_goal.m	15 Jan 2008 03:56:01 -0000
@@ -362,6 +362,10 @@
                 tmvh_state_var_name     :: string
             ).
 
+:- type is_first_disjunct
+    --->    is_first_disjunct
+    ;       is_not_first_disjunct.
+
 %-----------------------------------------------------------------------------%
 %
 % Information for calls
Index: compiler/live_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.134
diff -u -b -r1.134 live_vars.m
--- compiler/live_vars.m	30 Dec 2007 08:23:45 -0000	1.134
+++ compiler/live_vars.m	5 Jan 2008 05:05:46 -0000
@@ -188,9 +188,11 @@
     parallel_stackvars::in, parallel_stackvars::out)
     is det <= stack_alloc_info(T).
 
-build_live_sets_in_goal_2(conj(ConjType, Goals0), conj(ConjType, Goals),
-        GoalInfo0, GoalInfo, ResumeVars0, AllocData,
-        !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars) :-
+build_live_sets_in_goal_2(GoalExpr0, GoalExpr, GoalInfo0, GoalInfo,
+        ResumeVars0, AllocData, !StackAlloc, !Liveness, !NondetLiveness,
+        !ParStackVars) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
     (
         ConjType = plain_conj,
         GoalInfo = GoalInfo0,
@@ -201,67 +203,69 @@
         !.ParStackVars = parallel_stackvars(OuterNonLocals,
             OuterLocalStackVars, OuterAccStackVars0),
 
-        % Since each parallel conjunct may be run in a different Mercury context
-        % to the current context, we must save all the variables that are live
-        % or nonlocal to the parallel conjunction. Nonlocal variables that are
-        % currently free, but are bound inside one of the conjuncts need a
-        % stackslot because they are passed out by reference to that stackslot.
-        % Variables needed on backtracking must be available in a stackslot
-        % past the parallel conjunction as well.
+            % Since each parallel conjunct may be run in a different Mercury
+            % context to the current context, we must save all the variables
+            % that are live or nonlocal to the parallel conjunction. Nonlocal
+            % variables that are currently free, but are bound inside one of
+            % the conjuncts need a stackslot because they are passed out
+            % by reference to that stackslot. Variables needed on backtracking
+            % must be available in a stackslot past the parallel conjunction
+            % as well.
         NonLocals = goal_info_get_code_gen_nonlocals(GoalInfo0),
         LiveSet = set.union_list([NonLocals, !.Liveness, ResumeVars0]),
 
         InnerNonLocals = LiveSet `set.union` OuterNonLocals,
-        InnerParStackVars0 = parallel_stackvars(InnerNonLocals, [], set.init),
+            InnerParStackVars0 =
+                parallel_stackvars(InnerNonLocals, [], set.init),
         build_live_sets_in_par_conj(Goals0, Goals, ResumeVars0, AllocData,
             !StackAlloc, !Liveness, !NondetLiveness,
             InnerParStackVars0, InnerParStackVars),
         InnerParStackVars = parallel_stackvars(_, InnerStackVars, _),
 
         % This is safe but suboptimal.  It causes all variables which need
-        % stack slots in a parallel conjunction to have distinct stack slots.
-        % Variables local to a single conjunct could share stack slots, as
-        % long as the _sets_ of stack slots allocated to different parallel
-        % conjuncts are distinct.
+            % stack slots in a parallel conjunction to have distinct stack
+            % slots. Variables local to a single conjunct could share stack
+            % slots, as long as the _sets_ of stack slots allocated to
+            % different parallel conjuncts are distinct.
         NeedInParConj = need_in_par_conj(InnerNonLocals `set.union`
             set.union_list(InnerStackVars)),
         record_par_conj(NeedInParConj, GoalInfo0, GoalInfo, !StackAlloc),
 
         % All the local variables which needed stack slots in the parallel
         % conjuncts (InnerStackVars) become part of the accumulating set of
-        % variables that have stack slots.  Variables which are not local to
-        % but are needed in the parallel conjunctions also become part of the
-        % accumulating set.
+            % variables that have stack slots.  Variables which are not local
+            % to but are needed in the parallel conjunctions also become part
+            % of the accumulating set.
         OuterAccStackVars = OuterAccStackVars0
             `set.union` set.union_list(InnerStackVars)
             `set.union` (LiveSet `set.difference` OuterNonLocals),
         !:ParStackVars = parallel_stackvars(OuterNonLocals,
             OuterLocalStackVars, OuterAccStackVars)
-    ).
-
-build_live_sets_in_goal_2(disj(Goals0), disj(Goals), GoalInfo, GoalInfo,
+        ),
+        GoalExpr = conj(ConjType, Goals)
+    ;
+        GoalExpr0 = disj(Goals0),
+        build_live_sets_in_disj(Goals0, Goals, GoalInfo0,
         ResumeVars0, AllocData, !StackAlloc, !Liveness, !NondetLiveness,
-        !ParStackVars) :-
-    build_live_sets_in_disj(Goals0, Goals, GoalInfo, ResumeVars0, AllocData,
-        !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars),
+            !ParStackVars),
     (
-        Goals = [First | _],
-        First = hlds_goal(_, FirstGoalInfo),
+            Goals = [FirstGoal | _],
+            FirstGoal = hlds_goal(_, FirstGoalInfo),
         goal_info_get_resume_point(FirstGoalInfo, ResumePoint),
         (
             ResumePoint = resume_point(ResumeVars, _Locs),
             % If we can backtrack into the disjunction, we must protect the
             % stack slots needed by any of its resumption points from being
-            % reused in the following code. The first resumption point's vars
-            % include all the vars needed by all the resumption points.
-            % However, the first disjunct can be orig_only while later
-            % disjuncts are include the stack.
+                % reused in the following code. The first resumption point's
+                % variables include all the variables needed by all the
+                % resumption points. However, the first disjunct can be
+                % orig_only while later disjuncts are include the stack.
 
             % Note that we must check the disjunction's code model, not any
             % disjuncts'; the disjunction as a whole can be model_non
             % without any disjunct being model_non.
             (
-                goal_info_get_code_model(GoalInfo) = model_non,
+                    goal_info_get_code_model(GoalInfo0) = model_non,
                 some [Disjunct] (
                     list.member(Disjunct, Goals),
                     Disjunct = hlds_goal(_, DisjunctGoalInfo),
@@ -276,57 +280,59 @@
                 true
             )
         ;
-            % We can get here if the disjunction is not really a disjunction,
-            % because the first alternative cannot fail and will be committed
-            % to (e.g. in a first-solution context). Simplification should
-            % eliminate such disjunctions, replacing them with the first
-            % disjunct, but until that is done, we must handle them here.
+                % We can get here if the disjunction is not really a
+                % disjunction, because the first alternative cannot fail
+                % and will be committed to (e.g. in a first-solution context).
+                % Simplification should eliminate such disjunctions, replacing
+                % them with the first disjunct, but until that is done,
+                % we must handle them here.
             ResumePoint = no_resume_point
         )
     ;
         Goals = []
-    ).
-
-build_live_sets_in_goal_2(switch(Var, CanFail, Cases0),
-        switch(Var, CanFail, Cases), GoalInfo, GoalInfo, ResumeVars0,
-        AllocData, !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars) :-
+        ),
+        GoalExpr = disj(Goals),
+        GoalInfo = GoalInfo0
+    ;
+        GoalExpr0 = switch(Var, CanFail, Cases0),
     build_live_sets_in_cases(Cases0, Cases, ResumeVars0, AllocData,
-        !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars).
-
-build_live_sets_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
-        if_then_else(Vars, Cond, Then, Else), GoalInfo, GoalInfo,
-        ResumeVars0, AllocData, !StackAlloc,
-        Liveness0, Liveness, NondetLiveness0, NondetLiveness, !ParStackVars) :-
-    build_live_sets_in_goal(Cond0, Cond, ResumeVars0, AllocData, !StackAlloc,
-        Liveness0, LivenessCond, NondetLiveness0, NondetLivenessCond,
-        !ParStackVars),
-    build_live_sets_in_goal(Then0, Then, ResumeVars0, AllocData, !StackAlloc,
-        LivenessCond, _LivenessThen, NondetLivenessCond, NondetLivenessThen,
-        !ParStackVars),
-    build_live_sets_in_goal(Else0, Else, ResumeVars0, AllocData, !StackAlloc,
-        Liveness0, Liveness, NondetLiveness0, NondetLivenessElse,
-        !ParStackVars),
-    set.union(NondetLivenessThen, NondetLivenessElse, NondetLiveness).
-
-build_live_sets_in_goal_2(negation(Goal0), negation(Goal), GoalInfo, GoalInfo,
-        ResumeVars0, AllocData, !StackAlloc, !Liveness, !NondetLiveness,
-        !ParStackVars) :-
+            !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars),
+        GoalExpr = switch(Var, CanFail, Cases),
+        GoalInfo = GoalInfo0
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
+        Liveness0 = !.Liveness,
+        NondetLiveness0 = !.NondetLiveness,
+        build_live_sets_in_goal(Cond0, Cond, ResumeVars0, AllocData,
+            !StackAlloc, Liveness0, LivenessCond,
+            NondetLiveness0, NondetLivenessCond, !ParStackVars),
+        build_live_sets_in_goal(Then0, Then, ResumeVars0, AllocData,
+            !StackAlloc, LivenessCond, _LivenessThen,
+            NondetLivenessCond, NondetLivenessThen, !ParStackVars),
+        build_live_sets_in_goal(Else0, Else, ResumeVars0, AllocData,
+            !StackAlloc, Liveness0, Liveness,
+            NondetLiveness0, NondetLivenessElse, !ParStackVars),
+        set.union(NondetLivenessThen, NondetLivenessElse, NondetLiveness),
+        !:Liveness = Liveness,
+        !:NondetLiveness = NondetLiveness,
+        GoalExpr = if_then_else(Vars, Cond, Then, Else),
+        GoalInfo = GoalInfo0
+    ;
+        GoalExpr0 = negation(Goal0),
     build_live_sets_in_goal(Goal0, Goal, ResumeVars0, AllocData,
-        !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars).
-
-build_live_sets_in_goal_2(scope(Reason, Goal0), scope(Reason, Goal),
-        GoalInfo, GoalInfo, ResumeVars0, AllocData,
-        !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars) :-
+            !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars),
+        GoalExpr = negation(Goal),
+        GoalInfo = GoalInfo0
+    ;
+        GoalExpr0 = scope(Reason, Goal0),
     NondetLiveness0 = !.NondetLiveness,
     build_live_sets_in_goal(Goal0, Goal, ResumeVars0, AllocData,
         !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars),
-
-    % If the "some" goal cannot succeed more than once, then execution cannot
-    % backtrack into the inner goal once control has left it. Therefore the
-    % code following the "some" can reuse any stack slots needed by nondet
-    % code in the inner goal.
-
-    CodeModel = goal_info_get_code_model(GoalInfo),
+        % If the "some" goal cannot succeed more than once, then execution
+        % cannot backtrack into the inner goal once control has left it.
+        % Therefore the code following the scope can reuse any stack slots
+        % needed by nondet code in the inner goal.
+        CodeModel = goal_info_get_code_model(GoalInfo0),
     (
         CodeModel = model_non
     ;
@@ -334,11 +340,12 @@
         ; CodeModel = model_semi
         ),
         !:NondetLiveness = NondetLiveness0
-    ).
-
-build_live_sets_in_goal_2(Goal, Goal, GoalInfo0, GoalInfo, ResumeVars0,
-        AllocData, !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars) :-
-    Goal = generic_call(GenericCall, ArgVars, Modes, _Det),
+        ),
+        GoalExpr = scope(Reason, Goal),
+        GoalInfo = GoalInfo0
+    ;
+        GoalExpr0 = generic_call(GenericCall, ArgVars, Modes, _Det),
+        GoalExpr = GoalExpr0,
     (
         GenericCall = cast(_),
         GoalInfo = GoalInfo0
@@ -353,13 +360,13 @@
         ModuleInfo = AllocData ^ module_info,
         arg_info.partition_generic_call_args(ModuleInfo, ArgVars,
             Types, Modes, _InVars, OutVars, _UnusedVars),
-        build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo, ResumeVars0,
-            AllocData, !StackAlloc, !.Liveness, !NondetLiveness, !ParStackVars)
-    ).
-
-build_live_sets_in_goal_2(Goal, Goal, GoalInfo0, GoalInfo, ResumeVars0,
-        AllocData, !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars) :-
-    Goal = plain_call(PredId, ProcId, ArgVars, Builtin, _, _),
+            build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo,
+                ResumeVars0, AllocData, !StackAlloc, !.Liveness,
+                !NondetLiveness, !ParStackVars)
+        )
+    ;
+        GoalExpr0 = plain_call(PredId, ProcId, ArgVars, Builtin, _, _),
+        GoalExpr = GoalExpr0,
     ModuleInfo = AllocData ^ module_info,
     CallerProcInfo = AllocData ^ proc_info,
     proc_info_get_vartypes(CallerProcInfo, VarTypes),
@@ -374,14 +381,13 @@
         ; Builtin = not_builtin
         ),
         build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo,
-            ResumeVars0, AllocData, !StackAlloc, !.Liveness, !NondetLiveness,
-            !ParStackVars)
-    ).
-
-build_live_sets_in_goal_2(Goal, Goal, GoalInfo, GoalInfo,
-        _ResumeVars0, _AllocData, !StackAlloc, !Liveness, !NondetLiveness,
-        !ParStackVars) :-
-    Goal = unify(_, _, _, Unification, _),
+                ResumeVars0, AllocData, !StackAlloc, !.Liveness,
+                !NondetLiveness, !ParStackVars)
+        )
+    ;
+        GoalExpr0 = unify(_, _, _, Unification, _),
+        GoalExpr = GoalExpr0,
+        GoalInfo = GoalInfo0,
     (
         ( Unification = construct(_, _, _, _, _, _, _)
         ; Unification = deconstruct(_, _, _, _, _, _)
@@ -390,12 +396,13 @@
         )
     ;
         Unification = complicated_unify(_, _, _),
-        unexpected(this_file, "build_live_sets_in_goal_2: complicated_unify")
-    ).
-
-build_live_sets_in_goal_2(Goal, Goal, GoalInfo0, GoalInfo, ResumeVars0,
-        AllocData, !StackAlloc, !Liveness, !NondetLiveness, !ParStackVars) :-
-    Goal = call_foreign_proc(Attributes, PredId, ProcId, Args, _, _, _),
+            unexpected(this_file,
+                "build_live_sets_in_goal_2: complicated_unify")
+        )
+    ;
+        GoalExpr0 = call_foreign_proc(Attributes, PredId, ProcId, Args,
+            _, _, _),
+        GoalExpr = GoalExpr0,
     ModuleInfo = AllocData ^ module_info,
     CallerProcInfo = AllocData ^ proc_info,
     proc_info_get_vartypes(CallerProcInfo, VarTypes),
@@ -415,20 +422,22 @@
     ->
         GoalInfo = GoalInfo0
     ;
-        % The variables which need to be saved onto the stack before the call
-        % are all the variables that are live after the call (except for the
-        % output arguments produced by the call), plus all the variables
-        % that may be needed at an enclosing resumption point.
-
+            % The variables which need to be saved onto the stack before
+            % the call are all the variables that are live after the call
+            % (except for the output arguments produced by the call), plus
+            % all the variables that may be needed at an enclosing resumption
+            % point.
         build_live_sets_in_call(OutVars, GoalInfo0, GoalInfo,
-            ResumeVars0, AllocData, !StackAlloc, !.Liveness, !NondetLiveness,
-            !ParStackVars)
+                ResumeVars0, AllocData, !StackAlloc, !.Liveness,
+                !NondetLiveness, !ParStackVars)
+        )
+    ;
+        GoalExpr0 = shorthand(_),
+        % These should have been expanded out by now.
+        unexpected(this_file,
+            "build_live_sets_in_goal_2: unexpected shorthand")
     ).
 
-build_live_sets_in_goal_2(shorthand(_), _,_,_,_,_,_,_,_,_,_,_,_,_) :-
-    % these should have been expanded out by now
-    unexpected(this_file, "build_live_sets_in_goal_2: unexpected shorthand").
-
 %-----------------------------------------------------------------------------%
 
     % The variables which need to be saved onto the stack, directly or
Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.160
diff -u -b -r1.160 liveness.m
--- compiler/liveness.m	10 Jan 2008 04:29:52 -0000	1.160
+++ compiler/liveness.m	15 Jan 2008 03:56:01 -0000
@@ -237,14 +237,12 @@
     module_info::in, module_info::in, module_info::out) is det.
 
 detect_liveness_preds_parallel_2(PredIds, HLDS0, !HLDS) :-
-    (if
-        list.split_list(1000, PredIds, HeadPredIds, TailPredIds)
-    then
+    ( list.split_list(1000, PredIds, HeadPredIds, TailPredIds) ->
         ( detect_liveness_preds_parallel_3(HeadPredIds, HLDS0, !HLDS)
-        % XXX the following should be a parallel conjunction
+        % XXX The following should be a parallel conjunction.
         , detect_liveness_preds_parallel_2(TailPredIds, HLDS0, !HLDS)
         )
-    else
+    ;
         detect_liveness_preds_parallel_3(PredIds, HLDS0, !HLDS)
     ).
 
@@ -411,8 +409,10 @@
     set(prog_var)::in, set(prog_var)::out, set(prog_var)::in,
     live_info::in) is det.
 
-detect_liveness_in_goal_2(conj(ConjType, Goals0), conj(ConjType, Goals),
-        !Liveness, NonLocals, LiveInfo) :-
+detect_liveness_in_goal_2(GoalExpr0, GoalExpr, !Liveness,
+        NonLocals, LiveInfo) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
     (
         ConjType = plain_conj,
         detect_liveness_in_conj(Goals0, Goals, !Liveness, LiveInfo)
@@ -422,28 +422,26 @@
         detect_liveness_in_par_conj(Goals0, Goals, !.Liveness, NonLocals,
             LiveInfo, Union0, Union),
         set.union(Union, !Liveness)
-    ).
-
-detect_liveness_in_goal_2(disj(Goals0), disj(Goals), !Liveness,
-        NonLocals, LiveInfo) :-
+        ),
+        GoalExpr = conj(ConjType, Goals)
+    ;
+        GoalExpr0 = disj(Goals0),
     set.init(Union0),
     detect_liveness_in_disj(Goals0, Goals, !.Liveness, NonLocals,
         LiveInfo, Union0, Union),
-    set.union(Union, !Liveness).
-
-detect_liveness_in_goal_2(switch(Var, Det, Cases0), switch(Var, Det, Cases),
-        !Liveness, NonLocals, LiveInfo) :-
+        set.union(Union, !Liveness),
+        GoalExpr = disj(Goals)
+    ;
+        GoalExpr0 = switch(Var, Det, Cases0),
     detect_liveness_in_cases(Cases0, Cases, !.Liveness, NonLocals,
-        LiveInfo, !Liveness).
-
-detect_liveness_in_goal_2(negation(Goal0), negation(Goal), !Liveness, _,
-        LiveInfo) :-
-    detect_liveness_in_goal(Goal0, Goal, !Liveness, LiveInfo).
+            LiveInfo, !Liveness),
+        GoalExpr = switch(Var, Det, Cases)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
+        Liveness0 = !.Liveness,
 
-detect_liveness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
-        if_then_else(Vars, Cond, Then, Else),
-        Liveness0, Liveness, NonLocals, LiveInfo) :-
-    detect_liveness_in_goal(Cond0, Cond, Liveness0, LivenessCond, LiveInfo),
+        detect_liveness_in_goal(Cond0, Cond, Liveness0, LivenessCond,
+            LiveInfo),
 
     % If the condition cannot succeed, any variables which become live
     % in the else part should be put in the post-birth set of the then part
@@ -458,7 +456,8 @@
             LivenessCond, LivenessThen, LiveInfo)
     ),
 
-    detect_liveness_in_goal(Else0, Else1, Liveness0, LivenessElse, LiveInfo),
+        detect_liveness_in_goal(Else0, Else1, Liveness0, LivenessElse,
+            LiveInfo),
 
     set.union(LivenessThen, LivenessElse, Liveness),
     set.intersect(Liveness, NonLocals, NonLocalLiveness),
@@ -467,27 +466,34 @@
     set.difference(NonLocalLiveness, LivenessElse, ResidueElse),
 
     add_liveness_after_goal(Then1, ResidueThen, Then),
-    add_liveness_after_goal(Else1, ResidueElse, Else).
-
-detect_liveness_in_goal_2(scope(Reason, Goal0), scope(Reason, Goal),
-        !Liveness, _, LiveInfo) :-
-    detect_liveness_in_goal(Goal0, Goal, !Liveness, LiveInfo).
-
-detect_liveness_in_goal_2(generic_call(_, _, _, _), _, _, _, _, _) :-
-    unexpected(this_file, "higher-order-call in detect_liveness_in_goal_2").
-
-detect_liveness_in_goal_2(plain_call(_, _, _, _, _, _), _, _, _, _, _) :-
-    unexpected(this_file, "call in detect_liveness_in_goal_2").
+        add_liveness_after_goal(Else1, ResidueElse, Else),
 
-detect_liveness_in_goal_2(unify(_, _, _, _, _), _, _, _, _, _) :-
-    unexpected(this_file, "unify in detect_liveness_in_goal_2").
-
-detect_liveness_in_goal_2(call_foreign_proc(_, _, _, _, _, _, _),
-        _, _, _, _, _) :-
-    unexpected(this_file, "foreign_proc in detect_liveness_in_goal_2").
-
-detect_liveness_in_goal_2(shorthand(_), _, _, _, _, _) :-
-    unexpected(this_file, "shorthand in detect_liveness_in_goal_2").
+        !:Liveness = Liveness,
+        GoalExpr = if_then_else(Vars, Cond, Then, Else)
+    ;
+        GoalExpr0 = negation(SubGoal0),
+        detect_liveness_in_goal(SubGoal0, SubGoal, !Liveness, LiveInfo),
+        GoalExpr = negation(SubGoal)
+    ;
+        GoalExpr0 = scope(Reason, SubGoal0),
+        detect_liveness_in_goal(SubGoal0, SubGoal, !Liveness, LiveInfo),
+        GoalExpr = scope(Reason, SubGoal)
+    ;
+        GoalExpr0 = plain_call(_, _, _, _, _, _),
+        unexpected(this_file, "detect_liveness_in_goal_2: plain_call")
+    ;
+        GoalExpr0 = generic_call(_, _, _, _),
+        unexpected(this_file, "detect_liveness_in_goal_2: generic_call")
+    ;
+        GoalExpr0 = call_foreign_proc(_,_,  _, _, _, _, _),
+        unexpected(this_file, "detect_liveness_in_goal_2: call_foreign_proc")
+    ;
+        GoalExpr0 = unify(_, _, _, _, _),
+        unexpected(this_file, "detect_liveness_in_goal_2: unify")
+    ;
+        GoalExpr0 = shorthand(_),
+        unexpected(this_file, "detect_liveness_in_goal_2: shorthand")
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -611,11 +617,14 @@
     hlds_goal_info::in, set(prog_var)::in, set(prog_var)::out,
     set(prog_var)::in, live_info::in) is det.
 
-detect_deadness_in_goal_2(conj(ConjType, Goals0), conj(ConjType, Goals),
-        GoalInfo, !Deadness, Liveness0, LiveInfo) :-
+detect_deadness_in_goal_2(GoalExpr0, GoalExpr, GoalInfo, !Deadness,
+        Liveness0, LiveInfo) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
     (
         ConjType = plain_conj,
-        detect_deadness_in_conj(Goals0, Goals, !Deadness, Liveness0, LiveInfo)
+            detect_deadness_in_conj(Goals0, Goals, !Deadness,
+                Liveness0, LiveInfo)
     ;
         ConjType = parallel_conj,
         liveness.get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
@@ -625,33 +634,30 @@
             CompletedNonLocals, LiveInfo, Union0, Union,
             _CompletedNonLocalUnion),
         !:Deadness = Union
-    ).
-
-detect_deadness_in_goal_2(disj(Goals0), disj(Goals), GoalInfo, !Deadness,
-        Liveness0, LiveInfo) :-
+        ),
+        GoalExpr = conj(ConjType, Goals)
+    ;
+        GoalExpr0 = disj(Goals0),
     set.init(Union0),
     liveness.get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
         _, CompletedNonLocals),
     detect_deadness_in_disj(Goals0, Goals, !.Deadness, Liveness0,
         CompletedNonLocals, LiveInfo, Union0, Union, _),
-    !:Deadness = Union.
-
-detect_deadness_in_goal_2(switch(Var, Det, Cases0), switch(Var, Det, Cases),
-        GoalInfo, !Deadness, Liveness0, LiveInfo) :-
+        !:Deadness = Union,
+        GoalExpr = disj(Goals)
+    ;
+        GoalExpr0 = switch(Var, Det, Cases0),
     set.init(Union0),
     liveness.get_nonlocals_and_typeinfos(LiveInfo, GoalInfo,
         _, CompletedNonLocals),
     detect_deadness_in_cases(Var, Cases0, Cases, !.Deadness, Liveness0,
         CompletedNonLocals, LiveInfo, Union0, Union, _),
-    !:Deadness = Union.
+        !:Deadness = Union,
+        GoalExpr = switch(Var, Det, Cases)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
+        Deadness0 = !.Deadness,
 
-detect_deadness_in_goal_2(negation(Goal0), negation(Goal), _,
-        !Deadness, Liveness0, LiveInfo) :-
-    detect_deadness_in_goal(Goal0, Goal, !Deadness, Liveness0, LiveInfo).
-
-detect_deadness_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
-        if_then_else(Vars, Cond, Then, Else), GoalInfo,
-        Deadness0, Deadness, Liveness0, LiveInfo) :-
     update_liveness_goal(Cond0, LiveInfo, Liveness0, LivenessCond),
 
     detect_deadness_in_goal(Else0, Else1, Deadness0, DeadnessElse,
@@ -695,7 +701,8 @@
         set.intersect(Deadness, CompletedNonLocals,
             CompletedNonLocalDeadness),
         add_branch_pre_deaths(DeadnessCond, Deadness0,
-            CompletedNonLocalDeadness, CondThenInstmapReachable, Cond1, Cond),
+                CompletedNonLocalDeadness, CondThenInstmapReachable,
+                Cond1, Cond),
         add_branch_pre_deaths(DeadnessElse, Deadness0,
             CompletedNonLocalDeadness, ElseInstmapReachable, Else1, Else)
     ;
@@ -706,28 +713,36 @@
             CompletedNonLocalDeadness, yes, Cond1, Cond),
         add_branch_pre_deaths(DeadnessElse, Deadness0,
             CompletedNonLocalDeadness, yes, Else1, Else)
+        ),
+        !:Deadness = Deadness,
+        GoalExpr = if_then_else(Vars, Cond, Then, Else)
+    ;
+        GoalExpr0 = negation(SubGoal0),
+        detect_deadness_in_goal(SubGoal0, SubGoal, !Deadness,
+            Liveness0, LiveInfo),
+        GoalExpr = negation(SubGoal)
+    ;
+        GoalExpr0 = scope(Reason, SubGoal0),
+        detect_deadness_in_goal(SubGoal0, SubGoal, !Deadness,
+            Liveness0, LiveInfo),
+        GoalExpr = scope(Reason, SubGoal)
+    ;
+        GoalExpr0 = plain_call(_, _, _, _, _, _),
+        unexpected(this_file, "detect_deadness_in_goal_2: plain_call")
+    ;
+        GoalExpr0 = generic_call(_, _, _, _),
+        unexpected(this_file, "detect_deadness_in_goal_2: generic_call")
+    ;
+        GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _),
+        unexpected(this_file, "detect_deadness_in_goal_2: call_foreign_proc")
+    ;
+        GoalExpr0 = unify(_, _, _, _, _),
+        unexpected(this_file, "detect_deadness_in_goal_2: unify")
+    ;
+        GoalExpr0 = shorthand(_),
+        unexpected(this_file, "detect_deadness_in_goal_2: shorthand")
     ).
 
-detect_deadness_in_goal_2(scope(Reason, Goal0), scope(Reason, Goal), _,
-        !Deadness, Liveness0, LiveInfo) :-
-    detect_deadness_in_goal(Goal0, Goal, !Deadness, Liveness0, LiveInfo).
-
-detect_deadness_in_goal_2(generic_call(_,_,_,_), _, _, _, _, _, _) :-
-    unexpected(this_file, "higher-order-call in detect_deadness_in_goal_2").
-
-detect_deadness_in_goal_2(plain_call(_,_,_,_,_,_), _, _, _, _, _, _) :-
-    unexpected(this_file, "call in detect_deadness_in_goal_2").
-
-detect_deadness_in_goal_2(unify(_,_,_,_,_), _, _, _, _, _, _) :-
-    unexpected(this_file, "unify in detect_deadness_in_goal_2").
-
-detect_deadness_in_goal_2(call_foreign_proc(_, _, _, _, _, _, _),
-        _, _, _, _, _, _) :-
-    unexpected(this_file, "foreign_proc in detect_deadness_in_goal_2").
-
-detect_deadness_in_goal_2(shorthand(_), _, _, _, _, _, _) :-
-    unexpected(this_file, "shorthand in detect_deadness_in_goal_2").
-
 %-----------------------------------------------------------------------------%
 
 :- pred detect_deadness_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
@@ -912,7 +927,7 @@
     Liveness0 = !.Liveness,
     set.difference(!.Liveness, PreDeaths, !:Liveness),
     set.union(PreBirths, !Liveness),
-    update_liveness_expr(GoalExpr, GoalInfo, LiveInfo, !Liveness),
+    update_liveness_expr(GoalExpr, LiveInfo, !Liveness),
     set.difference(!.Liveness, PostDeaths, !:Liveness),
     set.union(PostBirths, !Liveness),
 
@@ -922,30 +937,36 @@
     set.intersect(NewLiveness0, CompletedNonLocals, NewLiveness),
     set.union(OldLiveness, NewLiveness, !:Liveness).
 
-:- pred update_liveness_expr(hlds_goal_expr::in, hlds_goal_info::in,
-    live_info::in, set(prog_var)::in, set(prog_var)::out) is det.
+:- pred update_liveness_expr(hlds_goal_expr::in, live_info::in,
+    set(prog_var)::in, set(prog_var)::out) is det.
 
-update_liveness_expr(plain_call(_, _, _, _, _, _), _, _, !Liveness).
-update_liveness_expr(generic_call(_, _, _, _), _, _, !Liveness).
-update_liveness_expr(unify(_, _, _, _, _), _, _, !Liveness).
-update_liveness_expr(call_foreign_proc(_, _, _, _, _, _, _), _, _, !Liveness).
-update_liveness_expr(conj(_ConjType, Goals), _, LiveInfo, !Liveness) :-
+update_liveness_expr(GoalExpr, LiveInfo, !Liveness) :-
+    (
+        ( GoalExpr = plain_call(_, _, _, _, _, _)
+        ; GoalExpr = generic_call(_, _, _, _)
+        ; GoalExpr = call_foreign_proc(_, _, _, _, _, _, _)
+        ; GoalExpr = unify(_, _, _, _, _)
+        )
+    ;
+        GoalExpr = conj(_ConjType, Goals),
     % XXX Do parallel conjunctions need special treatment?
-    update_liveness_conj(Goals, LiveInfo, !Liveness).
-update_liveness_expr(disj(Goals), _GoalInfo, LiveInfo, !Liveness) :-
+        update_liveness_conj(Goals, LiveInfo, !Liveness)
+    ;
+        GoalExpr = disj(Goals),
     ( find_reachable_goal(Goals, Goal) ->
         update_liveness_goal(Goal, LiveInfo, !Liveness)
     ;
         true
-    ).
-update_liveness_expr(switch(_, _, Cases), _GoalInfo, LiveInfo, !Liveness) :-
+        )
+    ;
+        GoalExpr = switch(_, _, Cases),
     ( find_reachable_case(Cases, Goal) ->
         update_liveness_goal(Goal, LiveInfo, !Liveness)
     ;
         true
-    ).
-update_liveness_expr(if_then_else(_, Cond, Then, Else), _GoalInfo, LiveInfo,
-        !Liveness) :-
+        )
+    ;
+        GoalExpr = if_then_else(_, Cond, Then, Else),
     Else = hlds_goal(_, ElseGoalInfo),
     ElseInstmapDelta = goal_info_get_instmap_delta(ElseGoalInfo),
     Cond = hlds_goal(_, CondGoalInfo),
@@ -964,13 +985,16 @@
         update_liveness_goal(Then, LiveInfo, !Liveness)
     ;
         true
+        )
+    ;
+        ( GoalExpr = negation(SubGoal)
+        ; GoalExpr = scope(_Reason, SubGoal)
+        ),
+        update_liveness_goal(SubGoal, LiveInfo, !Liveness)
+    ;
+        GoalExpr = shorthand(_),
+        unexpected(this_file, "update_liveness_expr: shorthand")
     ).
-update_liveness_expr(negation(Goal), _, LiveInfo, !Liveness) :-
-    update_liveness_goal(Goal, LiveInfo, !Liveness).
-update_liveness_expr(scope(_, Goal), _, LiveInfo, !Liveness) :-
-    update_liveness_goal(Goal, LiveInfo, !Liveness).
-update_liveness_expr(shorthand(_), _, _, _, _) :-
-    unexpected(this_file, "update_liveness_expr: shorthand").
 
 :- pred update_liveness_conj(list(hlds_goal)::in, live_info::in,
     set(prog_var)::in, set(prog_var)::out) is det.
@@ -1278,8 +1302,10 @@
     set(prog_var)::in, set(prog_var)::out, hlds_goal_info::in,
     live_info::in, set(prog_var)::in) is det.
 
-detect_resume_points_in_goal_2(conj(ConjType, Goals0), conj(ConjType, Goals),
-        !Liveness, _, LiveInfo, ResumeVars0) :-
+detect_resume_points_in_goal_2(GoalExpr0, GoalExpr,
+        !Liveness, GoalInfo0, LiveInfo, ResumeVars0) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
     (
         ConjType = plain_conj,
         detect_resume_points_in_conj(Goals0, Goals, !Liveness,
@@ -1288,11 +1314,11 @@
         ConjType = parallel_conj,
         detect_resume_points_in_par_conj(Goals0, Goals, !Liveness,
             LiveInfo, ResumeVars0)
-    ).
-
-detect_resume_points_in_goal_2(disj(Goals0), disj(Goals), !Liveness, GoalInfo,
-        LiveInfo, ResumeVars0) :-
-    CodeModel = goal_info_get_code_model(GoalInfo),
+        ),
+        GoalExpr = conj(ConjType, Goals)
+    ;
+        GoalExpr0 = disj(Goals0),
+        CodeModel = goal_info_get_code_model(GoalInfo0),
     (
         CodeModel = model_non,
         detect_resume_points_in_non_disj(Goals0, Goals, !Liveness,
@@ -1303,16 +1329,17 @@
         ),
         detect_resume_points_in_pruned_disj(Goals0, Goals, !Liveness,
             LiveInfo, ResumeVars0, _)
-    ).
-
-detect_resume_points_in_goal_2(switch(Var, CF, Cases0), switch(Var, CF, Cases),
-        !Liveness, _, LiveInfo, ResumeVars0) :-
+        ),
+        GoalExpr = disj(Goals)
+    ;
+        GoalExpr0 = switch(Var, CF, Cases0),
     detect_resume_points_in_cases(Cases0, Cases, !Liveness,
-        LiveInfo, ResumeVars0).
+            LiveInfo, ResumeVars0),
+        GoalExpr = switch(Var, CF, Cases)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
+        Liveness0 = !.Liveness,
 
-detect_resume_points_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
-        if_then_else(Vars, Cond, Then, Else), Liveness0, LivenessThen,
-        GoalInfo0, LiveInfo, ResumeVars0) :-
     % Compute the set of variables that may be needed at the start
     % of the else part and attach this set to the condition.
     Else0 = hlds_goal(_ElseExpr0, ElseInfo0),
@@ -1360,30 +1387,29 @@
     CondResume = resume_point(CondResumeVars, CondResumeLocs),
     goal_set_resume_point(CondResume, Cond1, Cond),
 
-    require_equal(LivenessThen, LivenessElse, "if-then-else", LiveInfo).
+        require_equal(LivenessThen, LivenessElse, "if-then-else", LiveInfo),
 
-detect_resume_points_in_goal_2(scope(Reason, Goal0), scope(Reason, Goal),
-        !Liveness, _, LiveInfo, ResumeVars0) :-
-    detect_resume_points_in_goal(Goal0, Goal, !Liveness,
-        LiveInfo, ResumeVars0).
+        !:Liveness = LivenessThen,
+        GoalExpr = if_then_else(Vars, Cond, Then, Else)
+    ;
+        GoalExpr0 = negation(SubGoal0),
+        Liveness0 = !.Liveness,
 
-detect_resume_points_in_goal_2(negation(Goal0), negation(Goal),
-        Liveness0, Liveness, _, LiveInfo, ResumeVars0) :-
-    detect_resume_points_in_goal(Goal0, _, Liveness0, Liveness,
+        detect_resume_points_in_goal(SubGoal0, _, Liveness0, Liveness,
         LiveInfo, ResumeVars0),
     liveness.maybe_complete_with_typeinfos(LiveInfo, Liveness,
         CompletedLiveness),
     % ResumeVars0 should already have been completed.
     set.union(CompletedLiveness, ResumeVars0, ResumeVars1),
-    detect_resume_points_in_goal(Goal0, Goal1, Liveness0, _Liveness,
+        detect_resume_points_in_goal(SubGoal0, SubGoal1, Liveness0, _Liveness,
         LiveInfo, ResumeVars1),
 
     % Figure out which entry labels we need at the resumption point.
     % By minimizing the number of labels we use, we also minimize
     % the amount of data movement code we emit between such labels.
-    ( cannot_stack_flush(Goal1) ->
+        ( cannot_stack_flush(SubGoal1) ->
         ResumeLocs = resume_locs_orig_only
-    ; cannot_fail_before_stack_flush(Goal1) ->
+        ; cannot_fail_before_stack_flush(SubGoal1) ->
         ResumeLocs = resume_locs_stack_only
     ;
         ResumeLocs = resume_locs_stack_and_orig
@@ -1392,24 +1418,27 @@
     % Attach the set of variables alive after the negation
     % as the resume point set of the negated goal.
     Resume = resume_point(ResumeVars1, ResumeLocs),
-    goal_set_resume_point(Resume, Goal1, Goal).
+        goal_set_resume_point(Resume, SubGoal1, SubGoal),
 
-detect_resume_points_in_goal_2(Goal @ generic_call(_, _, _, _), Goal,
-        !Liveness, _, _, _).
-
-detect_resume_points_in_goal_2(Goal @ plain_call(_, _, _, _, _, _), Goal,
-        !Liveness, _, _, _).
-
-detect_resume_points_in_goal_2(Goal @ unify(_, _, _, _, _), Goal,
-        !Liveness, _, _, _).
-
-detect_resume_points_in_goal_2(Goal @ call_foreign_proc(_, _, _, _, _, _, _),
-        Goal, !Liveness, _, _, _).
-
-detect_resume_points_in_goal_2(shorthand(_), _, _, _, _, _, _) :-
+        !:Liveness = Liveness,
+        GoalExpr = negation(SubGoal)
+    ;
+        GoalExpr0 = scope(Reason, SubGoal0),
+        detect_resume_points_in_goal(SubGoal0, SubGoal, !Liveness,
+            LiveInfo, ResumeVars0),
+        GoalExpr = scope(Reason, SubGoal)
+    ;
+        ( GoalExpr0 = generic_call(_, _, _, _)
+        ; GoalExpr0 = plain_call(_, _, _, _, _, _)
+        ; GoalExpr0 = unify(_, _, _, _, _)
+        ; GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
+        ),
+        GoalExpr = GoalExpr0
+    ;
+        GoalExpr0 = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file,
-        "detect_resume_points_in_goal_2: unexpected shorthand").
+        unexpected(this_file, "detect_resume_points_in_goal_2: shorthand")
+    ).
 
 :- pred detect_resume_points_in_conj(list(hlds_goal)::in, list(hlds_goal)::out,
     set(prog_var)::in, set(prog_var)::out,
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.80
diff -u -b -r1.80 ml_call_gen.m
--- compiler/ml_call_gen.m	23 Nov 2007 07:35:12 -0000	1.80
+++ compiler/ml_call_gen.m	19 Jan 2008 22:33:49 -0000
@@ -142,27 +142,34 @@
 % Code for procedure calls
 %
 
+ml_gen_generic_call(GenericCall, ArgVars, ArgModes, Determinism, Context,
+        Decls, Statements, !Info) :-
     % XXX For typeclass method calls, we do some unnecessary
     % boxing/unboxing of the arguments.
-ml_gen_generic_call(higher_order(_, _, _, _) @ GenericCall, ArgVars, ArgModes,
-        Determinism, Context, Decls, Statements, !Info) :-
+    (
+        GenericCall = higher_order(_, _, _, _),
     ml_gen_main_generic_call(GenericCall, ArgVars, ArgModes, Determinism,
-        Context, Decls, Statements, !Info).
-ml_gen_generic_call(class_method(_, _, _, _) @ GenericCall, ArgVars, ArgModes,
-        Determinism, Context, Decls, Statements, !Info) :-
+            Context, Decls, Statements, !Info)
+    ;
+        GenericCall = class_method(_, _, _, _),
     ml_gen_main_generic_call(GenericCall, ArgVars, ArgModes, Determinism,
-        Context, Decls, Statements, !Info).
-ml_gen_generic_call(event_call(_), _ArgVars, _ArgModes, _Determinism, _Context,
-        Decls, Statements, !Info) :-
+            Context, Decls, Statements, !Info)
+    ;
+        GenericCall = event_call(_),
     % XXX For now, we can't generate events from the MLDS backend.
     Decls = [],
-    Statements = [].
-ml_gen_generic_call(cast(_), ArgVars, _ArgModes, _Determinism, Context,
-        Decls, Statements, !Info) :-
-    ml_gen_cast(Context, ArgVars, Decls, Statements, !Info).
+        Statements = []
+    ;
+        GenericCall = cast(_),
+        ml_gen_cast(Context, ArgVars, Decls, Statements, !Info)
+    ).
+
+:- inst main_generic_call
+    --->    higher_order(ground, ground, ground, ground)
+    ;       class_method(ground, ground, ground, ground).
 
-:- pred ml_gen_main_generic_call(generic_call::in, list(prog_var)::in,
-    list(mer_mode)::in, determinism::in, prog_context::in,
+:- pred ml_gen_main_generic_call(generic_call::in(main_generic_call),
+    list(prog_var)::in, list(mer_mode)::in, determinism::in, prog_context::in,
     mlds_defns::out, statements::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
@@ -231,12 +238,6 @@
             MethodFieldId, mlds_generic_type, mlds_generic_type),
         FuncType = mlds_func_type(Params),
         FuncRval = unop(unbox(FuncType), lval(FuncLval))
-    ;
-        GenericCall = event_call(_),
-        unexpected(this_file, "ml_gen_main_generic_call: event_call")
-    ;
-        GenericCall = cast(_),
-        unexpected(this_file, "ml_gen_main_generic_call: cast")
     ),
 
     % Assign the function address rval to a new local variable. This makes
Index: compiler/ml_closure_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_closure_gen.m,v
retrieving revision 1.54
diff -u -b -r1.54 ml_closure_gen.m
--- compiler/ml_closure_gen.m	23 Nov 2007 07:35:12 -0000	1.54
+++ compiler/ml_closure_gen.m	19 Jan 2008 22:42:16 -0000
@@ -64,7 +64,7 @@
 :- type closure_kind
     --->    higher_order_proc_closure
     ;       typeclass_info_closure
-    ;       special_pred.
+    ;       special_pred_closure.
 
     % ml_gen_local_for_output_arg(VarName, Type, ArgNum, Context,
     %   LocalVarDefn):
@@ -288,8 +288,7 @@
     ArgInit = init_obj(CastArgRval).
 
 :- pred ml_gen_maybe_pseudo_type_info_defn(module_info::in,
-    rtti_maybe_pseudo_type_info::in, mlds_defns::in, mlds_defns::out)
-    is det.
+    rtti_maybe_pseudo_type_info::in, mlds_defns::in, mlds_defns::out) is det.
 
 ml_gen_maybe_pseudo_type_info_defn(ModuleInfo, MaybePTI, !Defns) :-
     ml_gen_maybe_pseudo_type_info(ModuleInfo, MaybePTI, _Rval, _Type, !Defns).
@@ -321,16 +320,21 @@
     ).
 
 :- pred ml_gen_pseudo_type_info(module_info::in, rtti_pseudo_type_info::in,
-    mlds_rval::out, mlds_type::out,
-    mlds_defns::in, mlds_defns::out) is det.
+    mlds_rval::out, mlds_type::out, mlds_defns::in, mlds_defns::out) is det.
 
 ml_gen_pseudo_type_info(ModuleInfo, PseudoTypeInfo, Rval, Type, !Defns) :-
-    ( PseudoTypeInfo = type_var(N) ->
+    (
+        PseudoTypeInfo = type_var(N),
         % Type variables are represented just as integers.
         Rval = const(mlconst_int(N)),
         Type = mlds_native_int_type
     ;
-        ( PseudoTypeInfo = plain_arity_zero_pseudo_type_info(RttiTypeCtor0) ->
+        ( PseudoTypeInfo = plain_arity_zero_pseudo_type_info(_)
+        ; PseudoTypeInfo = plain_pseudo_type_info(_, _)
+        ; PseudoTypeInfo = var_arity_pseudo_type_info(_, _)
+        ),
+        (
+            PseudoTypeInfo = plain_arity_zero_pseudo_type_info(RttiTypeCtor0),
             % For zero-arity types, we just generate a reference to the
             % already-existing type_ctor_info.
             RttiName = type_ctor_type_ctor_info,
@@ -339,6 +343,9 @@
             RttiTypeCtor = RttiTypeCtor0,
             RttiId = ctor_rtti_id(RttiTypeCtor, RttiName)
         ;
+            ( PseudoTypeInfo = plain_pseudo_type_info(_, _)
+            ; PseudoTypeInfo = var_arity_pseudo_type_info(_, _)
+            ),
             % For other types, we need to generate a definition of the
             % pseudo_type_info for that type, in the the current module.
             module_info_get_name(ModuleInfo, ModuleName),
@@ -362,11 +369,11 @@
     ).
 
 :- pred ml_gen_type_info(module_info::in, rtti_type_info::in,
-    mlds_rval::out, mlds_type::out,
-    mlds_defns::in, mlds_defns::out) is det.
+    mlds_rval::out, mlds_type::out, mlds_defns::in, mlds_defns::out) is det.
 
 ml_gen_type_info(ModuleInfo, TypeInfo, Rval, Type, !Defns) :-
-    ( TypeInfo = plain_arity_zero_type_info(RttiTypeCtor0) ->
+    (
+        TypeInfo = plain_arity_zero_type_info(RttiTypeCtor0),
         % For zero-arity types, we just generate a reference to the
         % already-existing type_ctor_info.
         RttiName = type_ctor_type_ctor_info,
@@ -374,6 +381,9 @@
         ModuleName = fixup_builtin_module(ModuleName0),
         RttiId = ctor_rtti_id(RttiTypeCtor0, RttiName)
     ;
+        ( TypeInfo = plain_type_info(_, _)
+        ; TypeInfo = var_arity_type_info(_, _)
+        ),
         % For other types, we need to generate a definition of the type_info
         % for that type, in the the current module.
         module_info_get_name(ModuleInfo, ModuleName),
@@ -459,8 +469,8 @@
     % by the second argument.
     %
 :- pred ml_stack_layout_construct_type_param_locn_vector(
-    assoc_list(tvar, set(layout_locn))::in,
-    int::in, list(mlds_initializer)::out) is det.
+    assoc_list(tvar, set(layout_locn))::in, int::in,
+    list(mlds_initializer)::out) is det.
 
 ml_stack_layout_construct_type_param_locn_vector([], _, []).
 ml_stack_layout_construct_type_param_locn_vector([TVar - Locns | TVarLocns],
@@ -719,7 +729,7 @@
 
     % Then insert the `closure_arg' parameter, if needed.
     (
-        ClosureKind = special_pred,
+        ClosureKind = special_pred_closure,
         MaybeClosureA = no,
         WrapperArgs = WrapperArgs1
     ;
@@ -841,8 +851,9 @@
             ClosureKind = typeclass_info_closure,
             Offset = ml_typeclass_info_arg_offset
         ;
-            ClosureKind = special_pred,
-            unexpected(this_file, "ml_gen_closure_wrapper: special_pred")
+            ClosureKind = special_pred_closure,
+            unexpected(this_file,
+                "ml_gen_closure_wrapper: special_pred_closure")
         ),
         ml_gen_closure_field_lvals(ClosureLval1, Offset, 1,
             NumClosureArgs, ClosureArgLvals, !Info)
@@ -951,8 +962,8 @@
         ClosureKind = typeclass_info_closure,
         ClosureActualType = sample_typeclass_info_type
     ;
-        ClosureKind = special_pred,
-        unexpected(this_file, "gen_closure_gc_statement: special_pred")
+        ClosureKind = special_pred_closure,
+        unexpected(this_file, "gen_closure_gc_statement: special_pred_closure")
     ),
     ml_gen_gc_statement(ClosureName, ClosureDeclType,
         ClosureActualType, Context, ClosureGCStatement, !Info).
@@ -1014,14 +1025,15 @@
         ml_gen_var_lval(!.Info, Name, MLDS_Type, VarLval),
         ml_gen_info_get_module_info(!.Info, ModuleInfo),
         mode_to_arg_mode(ModuleInfo, Mode, Type, ArgMode),
-        ( ArgMode = top_in ->
+        (
+            ArgMode = top_in,
             Lval = VarLval,
             CopyOutLvals = CopyOutLvalsTail,
             Defns = DefnsTail
         ;
-            % ( ArgMode = top_out
-            % ; ArgMode = top_unused
-            % ),
+            ( ArgMode = top_out
+            ; ArgMode = top_unused
+            ),
             % Handle output variables.
             ml_gen_info_get_globals(!.Info, Globals),
             CopyOut = get_copy_out_option(Globals, CodeModel),
@@ -1154,8 +1166,9 @@
             raw_target_code(");\n", [])
         ]
     ;
-        ClosureKind = special_pred,
-        unexpected(this_file, "ml_gen_closure_wrapper_gc_decls: special_pred")
+        ClosureKind = special_pred_closure,
+        unexpected(this_file,
+            "ml_gen_closure_wrapper_gc_decls: special_pred_closure")
 
     ),
     TypeParamsGCInit = statement(ml_stmt_atomic(inline_target_code(
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.209
diff -u -b -r1.209 ml_code_gen.m
--- compiler/ml_code_gen.m	31 Dec 2007 10:03:48 -0000	1.209
+++ compiler/ml_code_gen.m	19 Jan 2008 23:19:36 -0000
@@ -881,13 +881,20 @@
 :- func foreign_type_required_imports(compilation_target, hlds_type_defn)
     = list(mlds_import).
 
-foreign_type_required_imports(target_c, _) = [].
-foreign_type_required_imports(target_il, TypeDefn) = Imports :-
-    hlds_data.get_type_defn_body(TypeDefn, Body),
+foreign_type_required_imports(Target, TypeDefn) = Imports :-
     (
-        Body = hlds_foreign_type(
-            foreign_type_body(MaybeIL, _MaybeC, _MaybeJava, _MaybeErlang))
-    ->
+        ( Target = target_c
+        ; Target = target_java
+        ; Target = target_asm
+        ),
+        Imports = []
+    ;
+        Target = target_il,
+        hlds_data.get_type_defn_body(TypeDefn, TypeBody),
+        (
+            TypeBody = hlds_foreign_type(ForeignTypeBody),
+            ForeignTypeBody = foreign_type_body(MaybeIL,
+                _MaybeC, _MaybeJava, _MaybeErlang),
         (
             MaybeIL = yes(Data),
             Data = foreign_type_lang_data(il_type(_, Location, _), _, _)
@@ -899,14 +906,20 @@
             unexpected(this_file, "no IL type")
         )
     ;
+            ( TypeBody = hlds_du_type(_, _, _,_,  _, _, _, _)
+            ; TypeBody = hlds_eqv_type(_)
+            ; TypeBody = hlds_solver_type(_, _)
+            ; TypeBody = hlds_abstract_type(_)
+            ),
         Imports = []
+        )
+    ;
+        Target = target_x86_64,
+        unexpected(this_file, "target x86_64 and --high-level-code")
+    ;
+        Target = target_erlang,
+        unexpected(this_file, "foreign_type_required_imports: target erlang")
     ).
-foreign_type_required_imports(target_java, _) = [].
-foreign_type_required_imports(target_asm, _) = [].
-foreign_type_required_imports(target_x86_64, _) = _ :-
-    unexpected(this_file, "target x86_64 and --high-level-code").
-foreign_type_required_imports(target_erlang, _) = _ :-
-    unexpected(this_file, "foreign_type_required_imports: target erlang").
 
 :- pred ml_gen_defns(module_info::in, mlds_defns::out, io::di, io::uo) is det.
 
@@ -2152,43 +2165,13 @@
     mlds_defns::out, statements::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_goal_expr(switch(Var, CanFail, CasesList), CodeModel, Context,
-        Decls, Statements, !Info) :-
-    ml_gen_switch(Var, CanFail, CasesList, CodeModel, Context,
-        Decls, Statements, !Info).
-
-ml_gen_goal_expr(scope(_, Goal), CodeModel, Context, Decls, Statements,
-        !Info) :-
-    ml_gen_commit(Goal, CodeModel, Context, Decls, Statements, !Info).
-
-ml_gen_goal_expr(if_then_else(_Vars, Cond, Then, Else),
-        CodeModel, Context, Decls, Statements, !Info) :-
-    ml_gen_ite(CodeModel, Cond, Then, Else, Context, Decls, Statements, !Info).
-
-ml_gen_goal_expr(negation(Goal), CodeModel, Context,
-        Decls, Statements, !Info) :-
-    ml_gen_negation(Goal, CodeModel, Context, Decls, Statements, !Info).
-
-ml_gen_goal_expr(conj(_ConjType, Goals), CodeModel, Context,
-        Decls, Statements, !Info) :-
-    % XXX Currently we treat parallel conjunction the same as
-    % sequential conjunction -- parallelism is not yet implemented.
-    ml_gen_conj(Goals, CodeModel, Context, Decls, Statements, !Info).
-
-ml_gen_goal_expr(disj(Goals), CodeModel, Context,
-        Decls, Statements, !Info) :-
-    ml_gen_disj(Goals, CodeModel, Context, Decls, Statements, !Info).
-
-ml_gen_goal_expr(generic_call(GenericCall, Vars, Modes, Detism), CodeModel,
-        Context, Decls, Statements, !Info) :-
-    determinism_to_code_model(Detism, CallCodeModel),
-    expect(unify(CodeModel, CallCodeModel), this_file,
-        "ml_gen_generic_call: code model mismatch"),
-    ml_gen_generic_call(GenericCall, Vars, Modes, Detism, Context,
-        Decls, Statements, !Info).
-
-ml_gen_goal_expr(plain_call(PredId, ProcId, ArgVars, BuiltinState, _, _),
-        CodeModel, Context, Decls, Statements, !Info) :-
+ml_gen_goal_expr(GoalExpr, CodeModel, Context, Decls, Statements, !Info) :-
+    (
+        GoalExpr = unify(_LHS, _RHS, _Mode, Unification, _UnifyContext),
+        ml_gen_unification(Unification, CodeModel, Context, Decls, Statements,
+            !Info)
+    ;
+        GoalExpr = plain_call(PredId, ProcId, ArgVars, BuiltinState, _, _),
     (
         BuiltinState = not_builtin,
         ml_gen_var_list(!.Info, ArgVars, ArgLvals),
@@ -2203,32 +2186,33 @@
         ),
         ml_gen_builtin(PredId, ProcId, ArgVars, CodeModel, Context,
             Decls, Statements, !Info)
-    ).
-
-ml_gen_goal_expr(unify(_LHS, _RHS, _Mode, Unification, _UnifyContext),
-        CodeModel, Context, Decls, Statements, !Info) :-
-    ml_gen_unification(Unification, CodeModel, Context, Decls, Statements,
-        !Info).
-
-ml_gen_goal_expr(call_foreign_proc(Attributes, PredId, ProcId, Args, ExtraArgs,
-        MaybeTraceRuntimeCond, PragmaImpl), CodeModel, OuterContext,
-        Decls, Statements, !Info) :-
+        )
+    ;
+        GoalExpr = generic_call(GenericCall, Vars, Modes, Detism),
+        determinism_to_code_model(Detism, CallCodeModel),
+        expect(unify(CodeModel, CallCodeModel), this_file,
+            "ml_gen_generic_call: code model mismatch"),
+        ml_gen_generic_call(GenericCall, Vars, Modes, Detism, Context,
+            Decls, Statements, !Info)
+    ;
+        GoalExpr = call_foreign_proc(Attributes, PredId, ProcId,
+            Args, ExtraArgs, MaybeTraceRuntimeCond, PragmaImpl),
     (
         PragmaImpl = fc_impl_ordinary(ForeignCode, MaybeContext),
         (
-            MaybeContext = yes(Context)
+                MaybeContext = yes(ContextToUse)
         ;
             MaybeContext = no,
-            Context = OuterContext
+                ContextToUse = Context
         ),
         (
             MaybeTraceRuntimeCond = no,
             ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
                 PredId, ProcId, Args, ExtraArgs, ForeignCode,
-                Context, Decls, Statements, !Info)
+                    ContextToUse, Decls, Statements, !Info)
         ;
             MaybeTraceRuntimeCond = yes(TraceRuntimeCond),
-            ml_gen_trace_runtime_cond(TraceRuntimeCond, Context,
+                ml_gen_trace_runtime_cond(TraceRuntimeCond, ContextToUse,
                 Decls, Statements, !Info)
         )
     ;
@@ -2240,7 +2224,7 @@
         expect(unify(MaybeTraceRuntimeCond, no), this_file,
             "ml_gen_goal_expr: MaybeTraceRuntimeCond"),
         ml_gen_nondet_pragma_foreign_proc(CodeModel, Attributes,
-            PredId, ProcId, Args, OuterContext,
+                PredId, ProcId, Args, Context,
             LocalVarsDecls, LocalVarsContext,
             FirstCode, FirstContext, LaterCode, LaterContext,
             SharedCode, SharedContext, Decls, Statements, !Info)
@@ -2254,12 +2238,35 @@
             Name, "(", Vars, ");"]),
         ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
             PredId, ProcId, Args, ExtraArgs, ForeignCode,
-            OuterContext, Decls, Statements, !Info)
-    ).
-
-ml_gen_goal_expr(shorthand(_), _, _, _, _, !Info) :-
+                Context, Decls, Statements, !Info)
+        )
+    ;
+        GoalExpr = conj(_ConjType, Goals),
+        % XXX Currently we treat parallel conjunction the same as
+        % sequential conjunction -- parallelism is not yet implemented.
+        ml_gen_conj(Goals, CodeModel, Context, Decls, Statements, !Info)
+    ;
+        GoalExpr = disj(Goals),
+        ml_gen_disj(Goals, CodeModel, Context, Decls, Statements, !Info)
+    ;
+        GoalExpr = switch(Var, CanFail, CasesList),
+        ml_gen_switch(Var, CanFail, CasesList, CodeModel, Context,
+            Decls, Statements, !Info)
+    ;
+        GoalExpr = if_then_else(_Vars, Cond, Then, Else),
+        ml_gen_ite(CodeModel, Cond, Then, Else, Context, Decls, Statements,
+            !Info)
+    ;
+        GoalExpr = negation(SubGoal),
+        ml_gen_negation(SubGoal, CodeModel, Context, Decls, Statements, !Info)
+    ;
+        GoalExpr = scope(_, SubGoal),
+        ml_gen_commit(SubGoal, CodeModel, Context, Decls, Statements, !Info)
+    ;
+        GoalExpr = shorthand(_),
     % these should have been expanded out by now
-    unexpected(this_file, "ml_gen_goal_expr: unexpected shorthand").
+        unexpected(this_file, "ml_gen_goal_expr: unexpected shorthand")
+    ).
 
     % ml_foreign creates MLDS code to execute foreign language code.
     %
@@ -2404,13 +2411,12 @@
     (
         CodeModel = model_non,
 
-        % For IL code, we can't call continutations because there is no syntax
-        % for calling managed function pointers in C#.  Instead we have
-        % to call back into IL and make the continuation call in IL. This is
-        % called an "indirect" success continuation call.
-        %
         (
             Target = target_il,
+            % For IL code, we can't call continutations because there is no
+            % syntax for calling managed function pointers in C#. Instead,
+            % we have to call back into IL and make the continuation call
+            % in IL. This is called an "indirect" success continuation call.
             ml_gen_call_current_success_cont_indirectly(Context, CallCont,
                 !Info)
         ;
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.131
diff -u -b -r1.131 ml_code_util.m
--- compiler/ml_code_util.m	16 Jan 2008 08:34:53 -0000	1.131
+++ compiler/ml_code_util.m	19 Jan 2008 22:52:25 -0000
@@ -69,8 +69,7 @@
     mlds_defns::in, statements::in, prog_context::in,
     mlds_defns::out, statements::out) is det.
 
-:- type gen_pred == pred(mlds_defns, statements,
-        ml_gen_info, ml_gen_info).
+:- type gen_pred == pred(mlds_defns, statements, ml_gen_info, ml_gen_info).
 :- inst gen_pred == (pred(out, out, in, out) is det).
 
     % Given closures to generate code for two conjuncts, generate code
@@ -816,8 +815,10 @@
 ml_join_decls(FirstDecls, FirstStatements, RestDecls, RestStatements, Context,
         Decls, Statements) :-
     (
+        some [Name] (
         list.member(mlds_defn(Name, _, _, _), FirstDecls),
         list.member(mlds_defn(Name, _, _, _), RestDecls)
+        )
     ->
         First = ml_gen_block(FirstDecls, FirstStatements, Context),
         Rest = ml_gen_block(RestDecls, RestStatements, Context),
@@ -1049,7 +1050,8 @@
     PredOrFunc = RttiProcId^pred_or_func,
     Detism = RttiProcId^proc_interface_detism,
     determinism_to_code_model(Detism, CodeModel),
-    HeadVarNames = list.map((func(Var - Name) = Result :-
+    HeadVarNames = list.map(
+        (func(Var - Name) = Result :-
             term.var_to_int(Var, N),
             Result = mlds_var_name(Name, yes(N))
         ), HeadVars),
@@ -1881,22 +1883,20 @@
 % Code to handle accurate GC
 %
 
-ml_gen_gc_statement(VarName, Type, Context, GCStatement,
-        !Info) :-
-    ml_gen_gc_statement(VarName, Type, Type, Context,
-        GCStatement, !Info).
+ml_gen_gc_statement(VarName, Type, Context, GCStatement, !Info) :-
+    ml_gen_gc_statement(VarName, Type, Type, Context, GCStatement, !Info).
 
 ml_gen_gc_statement(VarName, DeclType, ActualType, Context,
         GCStatement, !Info) :-
     HowToGetTypeInfo = construct_from_type(ActualType),
-    ml_gen_gc_statement_2(VarName, DeclType, HowToGetTypeInfo,
-        Context, GCStatement, !Info).
+    ml_gen_gc_statement_2(VarName, DeclType, HowToGetTypeInfo, Context,
+        GCStatement, !Info).
 
-ml_gen_gc_statement_with_typeinfo(VarName, DeclType, TypeInfoRval,
-        Context, GCStatement, !Info) :-
+ml_gen_gc_statement_with_typeinfo(VarName, DeclType, TypeInfoRval, Context,
+        GCStatement, !Info) :-
     HowToGetTypeInfo = already_provided(TypeInfoRval),
-    ml_gen_gc_statement_2(VarName, DeclType, HowToGetTypeInfo,
-        Context, GCStatement, !Info).
+    ml_gen_gc_statement_2(VarName, DeclType, HowToGetTypeInfo, Context,
+        GCStatement, !Info).
 
 :- type how_to_get_type_info
     --->    construct_from_type(mer_type)
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.96
diff -u -b -r1.96 ml_elim_nested.m
--- compiler/ml_elim_nested.m	23 Nov 2007 07:35:13 -0000	1.96
+++ compiler/ml_elim_nested.m	19 Jan 2008 23:23:01 -0000
@@ -696,8 +696,7 @@
         EnvPtrTypeName, Context, ArgsToCopy0, CodeToCopyArgs0),
     ModuleName = elim_info_get_module_name(ElimInfo),
     (
-        Arg = mlds_argument(entity_data(var(VarName)), FieldType,
-            GCStatement),
+        Arg = mlds_argument(entity_data(var(VarName)), FieldType, GCStatement),
         ml_should_add_local_data(ElimInfo, var(VarName), GCStatement,
             [], [FuncBody])
     ->
@@ -1730,83 +1729,133 @@
 :- pred fixup_initializer(mlds_initializer::in, mlds_initializer::out,
     elim_info::in, elim_info::out) is det.
 
-fixup_initializer(no_initializer, no_initializer, !Info).
-fixup_initializer(init_obj(Rval0), init_obj(Rval), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_initializer(init_struct(Type, Members0), init_struct(Type, Members),
-        !Info) :-
-    list.map_foldl(fixup_initializer, Members0, Members, !Info).
-fixup_initializer(init_array(Elements0), init_array(Elements), !Info) :-
-    list.map_foldl(fixup_initializer, Elements0, Elements, !Info).
+fixup_initializer(Initializer0, Initializer, !Info) :-
+    (
+        Initializer0 = no_initializer,
+        Initializer = Initializer0
+    ;
+        Initializer0 = init_obj(Rval0),
+        fixup_rval(Rval0, Rval, !Info),
+        Initializer = init_obj(Rval)
+    ;
+        Initializer0 = init_struct(Type, Members0),
+        list.map_foldl(fixup_initializer, Members0, Members, !Info),
+        Initializer = init_struct(Type, Members)
+    ;
+        Initializer0 = init_array(Elements0),
+        list.map_foldl(fixup_initializer, Elements0, Elements, !Info),
+        Initializer = init_array(Elements)
+    ).
 
 :- pred fixup_atomic_stmt(mlds_atomic_statement::in,
     mlds_atomic_statement::out, elim_info::in, elim_info::out) is det.
 
-fixup_atomic_stmt(comment(C), comment(C), !Info).
-fixup_atomic_stmt(assign(Lval0, Rval0), assign(Lval, Rval), !Info) :-
+fixup_atomic_stmt(Atomic0, Atomic, !Info) :-
+    (
+        ( Atomic0 = comment(_)
+        ; Atomic0 = gc_check
+        ),
+        Atomic = Atomic0
+    ;
+        Atomic0 = assign(Lval0, Rval0),
     fixup_lval(Lval0, Lval, !Info),
-    fixup_rval(Rval0, Rval, !Info).
-fixup_atomic_stmt(delete_object(Lval0), delete_object(Lval), !Info) :-
-    fixup_lval(Lval0, Lval, !Info).
-fixup_atomic_stmt(new_object(Target0, MaybeTag, HasSecTag, Type, MaybeSize,
+        fixup_rval(Rval0, Rval, !Info),
+        Atomic = assign(Lval, Rval)
+    ;
+        Atomic0 = delete_object(Lval0),
+        fixup_lval(Lval0, Lval, !Info),
+        Atomic = delete_object(Lval)
+    ;
+        Atomic0 = new_object(Target0, MaybeTag, HasSecTag, Type, MaybeSize,
             MaybeCtorName, Args0, ArgTypes, MayUseAtomic),
-        new_object(Target, MaybeTag, HasSecTag, Type, MaybeSize,
-            MaybeCtorName, Args, ArgTypes, MayUseAtomic), !Info) :-
     fixup_lval(Target0, Target, !Info),
-    fixup_rvals(Args0, Args, !Info).
-fixup_atomic_stmt(gc_check, gc_check, !Info).
-fixup_atomic_stmt(mark_hp(Lval0), mark_hp(Lval), !Info) :-
-    fixup_lval(Lval0, Lval, !Info).
-fixup_atomic_stmt(restore_hp(Rval0), restore_hp(Rval), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_atomic_stmt(trail_op(TrailOp0), trail_op(TrailOp), !Info) :-
-    fixup_trail_op(TrailOp0, TrailOp, !Info).
-fixup_atomic_stmt(inline_target_code(Lang, Components0),
-        inline_target_code(Lang, Components), !Info) :-
+        fixup_rvals(Args0, Args, !Info),
+        Atomic = new_object(Target, MaybeTag, HasSecTag, Type, MaybeSize,
+            MaybeCtorName, Args, ArgTypes, MayUseAtomic)
+    ;
+        Atomic0 = mark_hp(Lval0),
+        fixup_lval(Lval0, Lval, !Info),
+        Atomic = mark_hp(Lval)
+    ;
+        Atomic0 = restore_hp(Rval0),
+        fixup_rval(Rval0, Rval, !Info),
+        Atomic = restore_hp(Rval)
+    ;
+        Atomic0 = trail_op(TrailOp0),
+        fixup_trail_op(TrailOp0, TrailOp, !Info),
+        Atomic = trail_op(TrailOp)
+    ;
+        Atomic0 = inline_target_code(Lang, Components0),
     list.map_foldl(fixup_target_code_component,
-        Components0, Components, !Info).
-fixup_atomic_stmt(outline_foreign_proc(Lang, Vs, Lvals0, Code),
-        outline_foreign_proc(Lang, Vs, Lvals, Code), !Info) :-
-    list.map_foldl(fixup_lval, Lvals0, Lvals, !Info).
+            Components0, Components, !Info),
+        Atomic = inline_target_code(Lang, Components)
+    ;
+        Atomic0 = outline_foreign_proc(Lang, Vs, Lvals0, Code),
+        list.map_foldl(fixup_lval, Lvals0, Lvals, !Info),
+        Atomic = outline_foreign_proc(Lang, Vs, Lvals, Code)
+    ).
 
 :- pred fixup_case_cond(mlds_case_match_cond::in, mlds_case_match_cond::out,
     elim_info::in, elim_info::out) is det.
 
-fixup_case_cond(match_value(Rval0), match_value(Rval), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_case_cond(match_range(Low0, High0), match_range(Low, High), !Info) :-
+fixup_case_cond(Cond0, Cond, !Info) :-
+    (
+        Cond0 = match_value(Rval0),
+        fixup_rval(Rval0, Rval, !Info),
+        Cond = match_value(Rval)
+    ;
+        Cond0 = match_range(Low0, High0),
     fixup_rval(Low0, Low, !Info),
-    fixup_rval(High0, High, !Info).
+        fixup_rval(High0, High, !Info),
+        Cond = match_range(Low, High)
+    ).
 
 :- pred fixup_target_code_component(target_code_component::in,
     target_code_component::out, elim_info::in, elim_info::out) is det.
 
-fixup_target_code_component(raw_target_code(Code, Attrs),
-        raw_target_code(Code, Attrs), !Info).
-fixup_target_code_component(user_target_code(Code, Context, Attrs),
-        user_target_code(Code, Context, Attrs), !Info).
-fixup_target_code_component(target_code_input(Rval0),
-        target_code_input(Rval), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_target_code_component(target_code_output(Lval0),
-        target_code_output(Lval), !Info) :-
-    fixup_lval(Lval0, Lval, !Info).
-fixup_target_code_component(name(Name), name(Name), !Info).
+fixup_target_code_component(Component0, Component, !Info) :-
+    (
+        ( Component0 = raw_target_code(_Code, _Attrs)
+        ; Component0 = user_target_code(_Code, _Context, _Attrs)
+        ; Component0 = name(_Name)
+        ),
+        Component = Component0
+    ;
+        Component0 = target_code_input(Rval0),
+        fixup_rval(Rval0, Rval, !Info),
+        Component = target_code_input(Rval)
+    ;
+        Component0 = target_code_output(Lval0),
+        fixup_lval(Lval0, Lval, !Info),
+        Component = target_code_output(Lval)
+    ).
 
 :- pred fixup_trail_op(trail_op::in, trail_op::out,
     elim_info::in, elim_info::out) is det.
 
-fixup_trail_op(store_ticket(Lval0), store_ticket(Lval), !Info) :-
-    fixup_lval(Lval0, Lval, !Info).
-fixup_trail_op(reset_ticket(Rval0, Reason), reset_ticket(Rval, Reason),
-        !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_trail_op(discard_ticket, discard_ticket, !Info).
-fixup_trail_op(prune_ticket, prune_ticket, !Info).
-fixup_trail_op(mark_ticket_stack(Lval0), mark_ticket_stack(Lval), !Info) :-
-    fixup_lval(Lval0, Lval, !Info).
-fixup_trail_op(prune_tickets_to(Rval0), prune_tickets_to(Rval), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
+fixup_trail_op(Op0, Op, !Info) :-
+    (
+        Op0 = store_ticket(Lval0),
+        fixup_lval(Lval0, Lval, !Info),
+        Op = store_ticket(Lval)
+    ;
+        Op0 = reset_ticket(Rval0, Reason),
+        fixup_rval(Rval0, Rval, !Info),
+        Op = reset_ticket(Rval, Reason)
+    ;
+        ( Op0 = discard_ticket
+        ; Op0 = prune_ticket
+        ),
+        Op = Op0
+    ;
+        Op0 = mark_ticket_stack(Lval0),
+        fixup_lval(Lval0, Lval, !Info),
+        Op = mark_ticket_stack(Lval)
+    ;
+        Op0 = prune_tickets_to(Rval0),
+        fixup_rval(Rval0, Rval, !Info),
+        Op = prune_tickets_to(Rval)
+    ).
 
 :- pred fixup_rvals(list(mlds_rval)::in, list(mlds_rval)::out,
     elim_info::in, elim_info::out) is det.
@@ -1826,19 +1875,34 @@
 :- pred fixup_rval(mlds_rval::in, mlds_rval::out,
     elim_info::in, elim_info::out) is det.
 
-fixup_rval(lval(Lval0), lval(Lval), !Info) :-
-    fixup_lval(Lval0, Lval, !Info).
-fixup_rval(mkword(Tag, Rval0), mkword(Tag, Rval), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_rval(const(Const), const(Const), !Info).
-fixup_rval(unop(Op, Rval0), unop(Op, Rval), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_rval(binop(Op, X0, Y0), binop(Op, X, Y), !Info) :-
-    fixup_rval(X0, X, !Info),
-    fixup_rval(Y0, Y, !Info).
-fixup_rval(mem_addr(Lval0), mem_addr(Lval), !Info) :-
-    fixup_lval(Lval0, Lval, !Info).
-fixup_rval(self(T), self(T), !Info).
+fixup_rval(Rval0, Rval, !Info) :-
+    (
+        Rval0 = lval(Lval0),
+        fixup_lval(Lval0, Lval, !Info),
+        Rval = lval(Lval)
+    ;
+        Rval0 = mem_addr(Lval0),
+        fixup_lval(Lval0, Lval, !Info),
+        Rval = mem_addr(Lval)
+    ;
+        Rval0 = mkword(Tag, BaseRval0),
+        fixup_rval(BaseRval0, BaseRval, !Info),
+        Rval = mkword(Tag, BaseRval)
+    ;
+        Rval0 = unop(UnOp, XRval0),
+        fixup_rval(XRval0, XRval, !Info),
+        Rval = unop(UnOp, XRval)
+    ;
+        Rval0 = binop(BinOp, XRval0, YRval0),
+        fixup_rval(XRval0, XRval, !Info),
+        fixup_rval(YRval0, YRval, !Info),
+        Rval = binop(BinOp, XRval, YRval)
+    ;
+        ( Rval0 = const(_)
+        ; Rval0 = self(_)
+        ),
+        Rval = Rval0
+    ).
 
 :- pred fixup_lvals(list(mlds_lval)::in, list(mlds_lval)::out,
     elim_info::in, elim_info::out) is det.
@@ -1851,14 +1915,22 @@
 :- pred fixup_lval(mlds_lval::in, mlds_lval::out,
     elim_info::in, elim_info::out) is det.
 
-fixup_lval(field(MaybeTag, Rval0, FieldId, FieldType, PtrType),
-        field(MaybeTag, Rval, FieldId, FieldType, PtrType), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_lval(mem_ref(Rval0, Type), mem_ref(Rval, Type), !Info) :-
-    fixup_rval(Rval0, Rval, !Info).
-fixup_lval(global_var_ref(Ref), global_var_ref(Ref), !Info).
-fixup_lval(var(Var0, VarType), VarLval, !Info) :-
-    fixup_var(Var0, VarType, VarLval, !Info).
+fixup_lval(Lval0, Lval, !Info) :-
+    (
+        Lval0 = field(MaybeTag, Rval0, FieldId, FieldType, PtrType),
+        fixup_rval(Rval0, Rval, !Info),
+        Lval = field(MaybeTag, Rval, FieldId, FieldType, PtrType)
+    ;
+        Lval0 = mem_ref(Rval0, Type),
+        fixup_rval(Rval0, Rval, !Info),
+        Lval = mem_ref(Rval, Type)
+    ;
+        Lval0 = global_var_ref(_Ref),
+        Lval = Lval0
+    ;
+        Lval0 = var(Var0, VarType),
+        fixup_var(Var0, VarType, Lval, !Info)
+    ).
 
 % fixup_gc_statements:
 %   Process the trace code in the locals that have been hoisted
@@ -1877,7 +1949,7 @@
     elim_info::in, elim_info::out) is det.
 
 fixup_gc_statements_defns([], !Info).
-fixup_gc_statements_defns([ Defn0 | Defns ], !Info) :-
+fixup_gc_statements_defns([Defn0 | Defns], !Info) :-
     (
         Defn0 = mlds_defn(Name, Context, Flags, DefnBody0),
         DefnBody0 = mlds_data(Type, Init, GCStatement0)
@@ -2062,8 +2134,7 @@
     ; defns_contains_defn(CtorDefns, Name)
     ).
 
-:- pred statements_contains_defn(statements::in, mlds_defn::out)
-    is nondet.
+:- pred statements_contains_defn(statements::in, mlds_defn::out) is nondet.
 
 statements_contains_defn(Statements, Defn) :-
     list.member(Statement, Statements),
@@ -2083,8 +2154,7 @@
 function_body_contains_defn(body_defined_here(Statement), Defn) :-
     statement_contains_defn(Statement, Defn).
 
-:- pred statement_contains_defn(statement::in, mlds_defn::out)
-    is nondet.
+:- pred statement_contains_defn(statement::in, mlds_defn::out) is nondet.
 
 statement_contains_defn(Statement, Defn) :-
     Statement = statement(Stmt, _Context),
@@ -2112,30 +2182,19 @@
         ; default_contains_defn(Default, Defn)
         )
     ;
-        Stmt = ml_stmt_label(_Label),
-        fail
-    ;
-        Stmt = ml_stmt_goto(_),
-        fail
-    ;
-        Stmt = ml_stmt_computed_goto(_Rval, _Labels),
-        fail
-    ;
-        Stmt = ml_stmt_call(_Sig, _Func, _Obj, _Args, _RetLvals, _TailCall),
-        fail
-    ;
-        Stmt = ml_stmt_return(_Rvals),
-        fail
-    ;
-        Stmt = ml_stmt_do_commit(_Ref),
-        fail
-    ;
         Stmt = ml_stmt_try_commit(_Ref, Statement, Handler),
         ( statement_contains_defn(Statement, Defn)
         ; statement_contains_defn(Handler, Defn)
         )
     ;
-        Stmt = ml_stmt_atomic(_AtomicStmt),
+        ( Stmt = ml_stmt_label(_Label)
+        ; Stmt = ml_stmt_goto(_)
+        ; Stmt = ml_stmt_computed_goto(_Rval, _Labels)
+        ; Stmt = ml_stmt_call(_Sig, _Func, _Obj, _Args, _RetLvals, _TailCall)
+        ; Stmt = ml_stmt_return(_Rvals)
+        ; Stmt = ml_stmt_do_commit(_Ref)
+        ; Stmt = ml_stmt_atomic(_AtomicStmt)
+        ),
         fail
     ).
 
@@ -2207,15 +2266,6 @@
         add_unchain_stack_to_default(Default0, Default, !Info),
         Stmt = ml_stmt_switch(Type, Val, Range, Cases, Default)
     ;
-        Stmt0 = ml_stmt_label(_),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_goto(_),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_computed_goto(_Rval, _Labels),
-        Stmt = Stmt0
-    ;
         Stmt0 = ml_stmt_call(_Sig, _Func, _Obj, _Args, RetLvals, CallKind),
         add_unchain_stack_to_call(Stmt0, RetLvals, CallKind, Context,
             Stmt, !Info)
@@ -2223,15 +2273,17 @@
         Stmt0 = ml_stmt_return(_Rvals),
         Stmt = prepend_unchain_frame(Stmt0, Context, !.Info)
     ;
-        Stmt0 = ml_stmt_do_commit(_Ref),
-        Stmt = Stmt0
-    ;
         Stmt0 = ml_stmt_try_commit(Ref, Statement0, Handler0),
         add_unchain_stack_to_statement(Statement0, Statement, !Info),
         add_unchain_stack_to_statement(Handler0, Handler, !Info),
         Stmt = ml_stmt_try_commit(Ref, Statement, Handler)
     ;
-        Stmt0 = ml_stmt_atomic(_AtomicStmt0),
+        ( Stmt0 = ml_stmt_label(_)
+        ; Stmt0 = ml_stmt_goto(_)
+        ; Stmt0 = ml_stmt_computed_goto(_Rval, _Labels)
+        ; Stmt0 = ml_stmt_do_commit(_Ref)
+        ; Stmt0 = ml_stmt_atomic(_AtomicStmt0)
+        ),
         Stmt = Stmt0
     ).
 
Index: compiler/ml_optimize.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_optimize.m,v
retrieving revision 1.53
diff -u -b -r1.53 ml_optimize.m
--- compiler/ml_optimize.m	21 Aug 2007 17:40:32 -0000	1.53
+++ compiler/ml_optimize.m	19 Jan 2008 23:20:36 -0000
@@ -168,27 +168,18 @@
             list.map(optimize_in_case(OptInfo), Cases0),
             optimize_in_default(OptInfo, Default0))
     ;
-        Stmt0 = ml_stmt_do_commit(_),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_return(_),
-        Stmt = Stmt0
-    ;
         Stmt0 = ml_stmt_try_commit(Ref, TryGoal0, HandlerGoal0),
         TryGoal = optimize_in_statement(OptInfo, TryGoal0),
         HandlerGoal = optimize_in_statement(OptInfo, HandlerGoal0),
         Stmt = ml_stmt_try_commit(Ref, TryGoal, HandlerGoal)
     ;
-        Stmt0 = ml_stmt_label(_Label),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_goto(_Label),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_computed_goto(_Rval, _Label),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_atomic(_Atomic),
+        ( Stmt0 = ml_stmt_do_commit(_)
+        ; Stmt0 = ml_stmt_return(_)
+        ; Stmt0 = ml_stmt_label(_Label)
+        ; Stmt0 = ml_stmt_goto(_Label)
+        ; Stmt0 = ml_stmt_computed_goto(_Rval, _Label)
+        ; Stmt0 = ml_stmt_atomic(_Atomic)
+        ),
         Stmt = Stmt0
     ).
 
@@ -222,10 +213,10 @@
         % If we have a self-tailcall, assign to the arguments and
         % then goto the top of the tailcall loop.
     (
-        globals.lookup_bool_option(OptInfo ^ globals,
-            optimize_tailcalls, yes),
-        can_optimize_tailcall(qual(OptInfo ^ module_name, module_qual,
-            OptInfo ^ entity_name), Stmt0)
+        globals.lookup_bool_option(OptInfo ^ globals, optimize_tailcalls, yes),
+        can_optimize_tailcall(
+            qual(OptInfo ^ module_name, module_qual, OptInfo ^ entity_name),
+            Stmt0)
     ->
         CommentStatement = statement(
             ml_stmt_atomic(comment("direct tailcall eliminated")),
@@ -333,7 +324,6 @@
             generate_assign_args(OptInfo, Args, ArgRvals,
                 Statements, TempDefns)
         ;
-
             % Declare a temporary variable, initialized it to the arg,
             % recursively process the remaining args, and then assign the
             % temporary to the parameter:
@@ -876,9 +866,9 @@
     % Invalidated = yes if any of the statements or definitions take
     % the address of the variable, or assign to it; in that case, the
     % transformation should not be performed.
+    %
 :- pred eliminate_var(mlds_var::in, mlds_rval::in,
-    mlds_defns::in, mlds_defns::out,
-    statements::in, statements::out,
+    mlds_defns::in, mlds_defns::out, statements::in, statements::out,
     int::out, bool::out) is det.
 
 eliminate_var(QualVarName, VarRval, !Defns, !Statements, Count, Invalidated) :-
@@ -1148,95 +1138,130 @@
     mlds_switch_default::in, mlds_switch_default::out,
     var_elim_info::in, var_elim_info::out) is det.
 
-eliminate_var_in_default(default_is_unreachable, default_is_unreachable,
-        !VarElimInfo).
-eliminate_var_in_default(default_do_nothing, default_do_nothing,
-        !VarElimInfo).
-eliminate_var_in_default(default_case(Statement0), default_case(Statement),
-        !VarElimInfo) :-
-    eliminate_var_in_statement(Statement0, Statement, !VarElimInfo).
+eliminate_var_in_default(Default0, Default, !VarElimInfo) :-
+    (
+        ( Default0 = default_is_unreachable
+        ; Default0 = default_do_nothing
+        ),
+        Default = Default0
+    ;
+        Default0 = default_case(Statement0),
+        eliminate_var_in_statement(Statement0, Statement, !VarElimInfo),
+        Default = default_case(Statement)
+    ).
 
 :- pred eliminate_var_in_atomic_stmt(
     mlds_atomic_statement::in, mlds_atomic_statement::out,
     var_elim_info::in, var_elim_info::out) is det.
 
-eliminate_var_in_atomic_stmt(comment(C), comment(C), !VarElimInfo).
-eliminate_var_in_atomic_stmt(assign(Lval0, Rval0), assign(Lval, Rval),
-        !VarElimInfo) :-
+eliminate_var_in_atomic_stmt(Stmt0, Stmt, !VarElimInfo) :-
+    (
+        ( Stmt0 = comment(_)
+        ; Stmt0 = gc_check
+        ),
+        Stmt = Stmt0
+    ;
+        Stmt0 = assign(Lval0, Rval0),
     eliminate_var_in_lval(Lval0, Lval, !VarElimInfo),
-    eliminate_var_in_rval(Rval0, Rval, !VarElimInfo).
-eliminate_var_in_atomic_stmt(delete_object(Lval0), delete_object(Lval),
-        !VarElimInfo) :-
-    eliminate_var_in_lval(Lval0, Lval, !VarElimInfo).
-eliminate_var_in_atomic_stmt(new_object(Target0, MaybeTag, HasSecTag, Type,
+        eliminate_var_in_rval(Rval0, Rval, !VarElimInfo),
+        Stmt = assign(Lval, Rval)
+    ;
+        Stmt0 = delete_object(Lval0),
+        eliminate_var_in_lval(Lval0, Lval, !VarElimInfo),
+        Stmt = delete_object(Lval)
+    ;
+        Stmt0 = new_object(Target0, MaybeTag, HasSecTag, Type,
             MaybeSize, MaybeCtorName, Args0, ArgTypes, MayUseAtomic),
-        new_object(Target, MaybeTag, HasSecTag, Type,
-            MaybeSize, MaybeCtorName, Args, ArgTypes, MayUseAtomic),
-        !VarElimInfo) :-
     eliminate_var_in_lval(Target0, Target, !VarElimInfo),
-    eliminate_var_in_rvals(Args0, Args, !VarElimInfo).
-eliminate_var_in_atomic_stmt(gc_check, gc_check, !VarElimInfo).
-eliminate_var_in_atomic_stmt(mark_hp(Lval0), mark_hp(Lval), !VarElimInfo) :-
-    eliminate_var_in_lval(Lval0, Lval, !VarElimInfo).
-eliminate_var_in_atomic_stmt(restore_hp(Rval0), restore_hp(Rval),
-        !VarElimInfo) :-
-    eliminate_var_in_rval(Rval0, Rval, !VarElimInfo).
-eliminate_var_in_atomic_stmt(trail_op(TrailOp0), trail_op(TrailOp),
-        !VarElimInfo) :-
-    eliminate_var_in_trail_op(TrailOp0, TrailOp, !VarElimInfo).
-eliminate_var_in_atomic_stmt(inline_target_code(Lang, Components0),
-        inline_target_code(Lang, Components), !VarElimInfo) :-
+        eliminate_var_in_rvals(Args0, Args, !VarElimInfo),
+        Stmt = new_object(Target, MaybeTag, HasSecTag, Type,
+            MaybeSize, MaybeCtorName, Args, ArgTypes, MayUseAtomic)
+    ;
+        Stmt0 = mark_hp(Lval0),
+        eliminate_var_in_lval(Lval0, Lval, !VarElimInfo),
+        Stmt = mark_hp(Lval)
+    ;
+        Stmt0 = restore_hp(Rval0),
+        eliminate_var_in_rval(Rval0, Rval, !VarElimInfo),
+        Stmt = restore_hp(Rval)
+    ;
+        Stmt0 = trail_op(TrailOp0),
+        eliminate_var_in_trail_op(TrailOp0, TrailOp, !VarElimInfo),
+        Stmt = trail_op(TrailOp)
+    ;
+        Stmt0 = inline_target_code(Lang, Components0),
     list.map_foldl(eliminate_var_in_target_code_component,
-        Components0, Components, !VarElimInfo).
-eliminate_var_in_atomic_stmt(outline_foreign_proc(Lang, Vs, Lvals0, Code),
-        outline_foreign_proc(Lang, Vs, Lvals, Code), !VarElimInfo) :-
-    eliminate_var_in_lvals(Lvals0, Lvals, !VarElimInfo).
+            Components0, Components, !VarElimInfo),
+        Stmt = inline_target_code(Lang, Components)
+    ;
+        Stmt0 = outline_foreign_proc(Lang, Vs, Lvals0, Code),
+        eliminate_var_in_lvals(Lvals0, Lvals, !VarElimInfo),
+        Stmt = outline_foreign_proc(Lang, Vs, Lvals, Code)
+    ).
 
 :- pred eliminate_var_in_case_cond(
     mlds_case_match_cond::in, mlds_case_match_cond::out,
     var_elim_info::in, var_elim_info::out) is det.
 
-eliminate_var_in_case_cond(match_value(Rval0), match_value(Rval),
-        !VarElimInfo) :-
-    eliminate_var_in_rval(Rval0, Rval, !VarElimInfo).
-eliminate_var_in_case_cond(match_range(Low0, High0), match_range(Low, High),
-        !VarElimInfo) :-
+eliminate_var_in_case_cond(Cond0, Cond, !VarElimInfo) :-
+    (
+        Cond0 = match_value(Rval0),
+        eliminate_var_in_rval(Rval0, Rval, !VarElimInfo),
+        Cond = match_value(Rval)
+    ;
+        Cond0 = match_range(Low0, High0),
     eliminate_var_in_rval(Low0, Low, !VarElimInfo),
-    eliminate_var_in_rval(High0, High, !VarElimInfo).
+        eliminate_var_in_rval(High0, High, !VarElimInfo),
+        Cond = match_range(Low, High)
+    ).
 
 :- pred eliminate_var_in_target_code_component(
     target_code_component::in, target_code_component::out,
     var_elim_info::in, var_elim_info::out) is det.
 
-eliminate_var_in_target_code_component(raw_target_code(Code, Attrs),
-        raw_target_code(Code, Attrs), !VarElimInfo).
-eliminate_var_in_target_code_component(user_target_code(Code, Context, Attrs),
-        user_target_code(Code, Context, Attrs), !VarElimInfo).
-eliminate_var_in_target_code_component(target_code_input(Rval0),
-        target_code_input(Rval), !VarElimInfo) :-
-    eliminate_var_in_rval(Rval0, Rval, !VarElimInfo).
-eliminate_var_in_target_code_component(target_code_output(Lval0),
-        target_code_output(Lval), !VarElimInfo) :-
-    eliminate_var_in_lval(Lval0, Lval, !VarElimInfo).
-eliminate_var_in_target_code_component(name(Name), name(Name), !VarElimInfo).
+eliminate_var_in_target_code_component(Component0, Component, !VarElimInfo) :-
+    (
+        ( Component0 = raw_target_code(_Code, _Attrs)
+        ; Component0 = user_target_code(_Code, _Context, _Attrs)
+        ; Component0 = name(_Name)
+        ),
+        Component = Component0
+    ;
+        Component0 = target_code_input(Rval0),
+        eliminate_var_in_rval(Rval0, Rval, !VarElimInfo),
+        Component = target_code_input(Rval)
+    ;
+        Component0 = target_code_output(Lval0),
+        eliminate_var_in_lval(Lval0, Lval, !VarElimInfo),
+        Component = target_code_output(Lval)
+    ).
 
 :- pred eliminate_var_in_trail_op(trail_op::in, trail_op::out,
     var_elim_info::in, var_elim_info::out) is det.
 
-eliminate_var_in_trail_op(store_ticket(Lval0), store_ticket(Lval),
-        !VarElimInfo) :-
-    eliminate_var_in_lval(Lval0, Lval, !VarElimInfo).
-eliminate_var_in_trail_op(reset_ticket(Rval0, Reason),
-        reset_ticket(Rval, Reason), !VarElimInfo) :-
-    eliminate_var_in_rval(Rval0, Rval, !VarElimInfo).
-eliminate_var_in_trail_op(discard_ticket, discard_ticket, !VarElimInfo).
-eliminate_var_in_trail_op(prune_ticket, prune_ticket, !VarElimInfo).
-eliminate_var_in_trail_op(mark_ticket_stack(Lval0), mark_ticket_stack(Lval),
-        !VarElimInfo) :-
-    eliminate_var_in_lval(Lval0, Lval, !VarElimInfo).
-eliminate_var_in_trail_op(prune_tickets_to(Rval0), prune_tickets_to(Rval),
-        !VarElimInfo) :-
-    eliminate_var_in_rval(Rval0, Rval, !VarElimInfo).
+eliminate_var_in_trail_op(Op0, Op, !VarElimInfo) :-
+    (
+        Op0 = store_ticket(Lval0),
+        eliminate_var_in_lval(Lval0, Lval, !VarElimInfo),
+        Op = store_ticket(Lval)
+    ;
+        Op0 = reset_ticket(Rval0, Reason),
+        eliminate_var_in_rval(Rval0, Rval, !VarElimInfo),
+        Op = reset_ticket(Rval, Reason)
+    ;
+        ( Op0 = discard_ticket
+        ; Op0 = prune_ticket
+        ),
+        Op = Op0
+    ;
+        Op0 = mark_ticket_stack(Lval0),
+        eliminate_var_in_lval(Lval0, Lval, !VarElimInfo),
+        Op = mark_ticket_stack(Lval)
+    ;
+        Op0 = prune_tickets_to(Rval0),
+        eliminate_var_in_rval(Rval0, Rval, !VarElimInfo),
+        Op = prune_tickets_to(Rval)
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -1244,6 +1269,8 @@
 
 this_file = "ml_optimize.m".
 
+%-----------------------------------------------------------------------------%
+
 :- end_module ml_optimize.
 
 %-----------------------------------------------------------------------------%
Index: compiler/ml_simplify_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_simplify_switch.m,v
retrieving revision 1.24
diff -u -b -r1.24 ml_simplify_switch.m
--- compiler/ml_simplify_switch.m	23 Nov 2007 07:35:14 -0000	1.24
+++ compiler/ml_simplify_switch.m	19 Jan 2008 23:24:52 -0000
@@ -324,16 +324,15 @@
     mlds_defns::out, statements::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-generate_cases([], _EndLabel, CaseLabelsMap, CaseLabelsMap, [], [], !Info).
-generate_cases([Case | Cases], EndLabel, CaseLabelsMap0,
-        CaseLabelsMap, Decls, Statements, !Info) :-
-    generate_case(Case, EndLabel, CaseLabelsMap0, CaseLabelsMap1,
+generate_cases([], _EndLabel, !CaseLabelsMap, [], [], !Info).
+generate_cases([Case | Cases], EndLabel, !CaseLabelsMap, Decls, Statements,
+        !Info) :-
+    generate_case(Case, EndLabel, !CaseLabelsMap,
         CaseDecls, CaseStatements, !Info),
-    generate_cases(Cases, EndLabel,
-        CaseLabelsMap1, CaseLabelsMap,
-        Decls1, Statements1, !Info),
-    Decls = CaseDecls ++ Decls1,
-    Statements = CaseStatements ++ Statements1.
+    generate_cases(Cases, EndLabel, !CaseLabelsMap,
+        CasesDecls, CasesStatements, !Info),
+    Decls = CaseDecls ++ CasesDecls,
+    Statements = CaseStatements ++ CasesStatements.
 
     % This converts an MLDS switch case into code for a dense switch case,
     % by adding a label at the front and a `goto <EndLabel>' at the end.
Index: compiler/ml_string_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_string_switch.m,v
retrieving revision 1.35
diff -u -b -r1.35 ml_string_switch.m
Index: compiler/ml_tag_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_tag_switch.m,v
retrieving revision 1.26
diff -u -b -r1.26 ml_tag_switch.m
Index: compiler/ml_tailcall.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_tailcall.m,v
retrieving revision 1.47
diff -u -b -r1.47 ml_tailcall.m
--- compiler/ml_tailcall.m	21 Aug 2007 17:40:32 -0000	1.47
+++ compiler/ml_tailcall.m	19 Jan 2008 23:44:35 -0000
@@ -255,15 +255,6 @@
         Default = mark_tailcalls_in_default(Default0, AtTail, Locals),
         Stmt = ml_stmt_switch(Type, Val, Range, Cases, Default)
     ;
-        Stmt0 = ml_stmt_label(_),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_goto(_),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_computed_goto(_, _),
-        Stmt = Stmt0
-    ;
         Stmt0 = ml_stmt_call(Sig, Func, Obj, Args, ReturnLvals, CallKind0),
 
         % Check if we can mark this call as a tail call.
@@ -279,11 +270,11 @@
 
             % The call must not take the address of any local variables
             % or nested functions.
-            check_maybe_rval(Obj, Locals),
-            check_rvals(Args, Locals),
+            check_maybe_rval(Obj, Locals) = will_not_yield_dangling_stack_ref,
+            check_rvals(Args, Locals) = will_not_yield_dangling_stack_ref,
 
             % The call must not be to a function nested within this function.
-            check_rval(Func, Locals)
+            check_rval(Func, Locals) = will_not_yield_dangling_stack_ref
         ->
             % Mark this call as a tail call.
             CallKind = tail_call,
@@ -293,12 +284,6 @@
             Stmt = Stmt0
         )
     ;
-        Stmt0 = ml_stmt_return(_Rvals),
-        Stmt = Stmt0
-    ;
-        Stmt0 = ml_stmt_do_commit(_Ref),
-        Stmt = Stmt0
-    ;
         Stmt0 = ml_stmt_try_commit(Ref, Statement0, Handler0),
         % Both the statement inside a `try_commit' and the handler are in
         % tail call position iff the `try_commit' statement is in a tail call
@@ -307,7 +292,13 @@
         Handler = mark_tailcalls_in_statement(Handler0, AtTail, Locals),
         Stmt = ml_stmt_try_commit(Ref, Statement, Handler)
     ;
-        Stmt0 = ml_stmt_atomic(_),
+        ( Stmt0 = ml_stmt_label(_)
+        ; Stmt0 = ml_stmt_goto(_)
+        ; Stmt0 = ml_stmt_computed_goto(_, _)
+        ; Stmt0 = ml_stmt_return(_Rvals)
+        ; Stmt0 = ml_stmt_do_commit(_Ref)
+        ; Stmt0 = ml_stmt_atomic(_)
+        ),
         Stmt = Stmt0
     ).
 
@@ -330,12 +321,17 @@
 :- func mark_tailcalls_in_default(mlds_switch_default, at_tail, locals) =
     mlds_switch_default.
 
-mark_tailcalls_in_default(default_do_nothing, _, _) = default_do_nothing.
-mark_tailcalls_in_default(default_is_unreachable, _, _) =
-        default_is_unreachable.
-mark_tailcalls_in_default(default_case(Statement0), AtTail, Locals) =
-        default_case(Statement) :-
-    Statement = mark_tailcalls_in_statement(Statement0, AtTail, Locals).
+mark_tailcalls_in_default(Default0, AtTail, Locals) = Default :-
+    (
+        ( Default0 = default_is_unreachable
+        ; Default0 = default_do_nothing
+        ),
+        Default = Default0
+    ;
+        Default0 = default_case(Statement0),
+        Statement = mark_tailcalls_in_statement(Statement0, AtTail, Locals),
+        Default = default_case(Statement)
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -357,80 +353,123 @@
 :- pred match_return_val(mlds_rval::in, mlds_lval::in) is semidet.
 
 match_return_val(lval(Lval), Lval) :-
-    lval_is_local(Lval).
+    lval_is_local(Lval) = is_local.
+
+:- type is_local
+    --->    is_local
+    ;       is_not_local.
 
-:- pred lval_is_local(mlds_lval::in) is semidet.
+:- func lval_is_local(mlds_lval) = is_local.
 
-lval_is_local(var(_, _)) :-
+lval_is_local(Lval) = IsLocal :-
+    (
+        Lval = var(_, _),
     % We just assume it is local. (This assumption is true for the code
     % generated by ml_code_gen.m.)
-    true.
-lval_is_local(field(_Tag, Rval, _Field, _, _)) :-
-    % a field of a local variable is local
-    ( Rval = mem_addr(Lval) ->
-        lval_is_local(Lval)
+        IsLocal = is_local
+    ;
+        Lval = field(_Tag, Rval, _Field, _, _),
+        % A field of a local variable is local.
+        ( Rval = mem_addr(BaseLval) ->
+            IsLocal = lval_is_local(BaseLval)
+        ;
+            IsLocal = is_not_local
+        )
     ;
-        fail
+        ( Lval = mem_ref(_Rval, _Type)
+        ; Lval = global_var_ref(_)
+        ),
+        IsLocal = is_not_local
     ).
-lval_is_local(mem_ref(_Rval, _Type)) :-
-    fail.
 
 %-----------------------------------------------------------------------------%
 
+:- type may_yield_dangling_stack_ref
+    --->    may_yield_dangling_stack_ref
+    ;       will_not_yield_dangling_stack_ref.
+
 % check_rvals:
 % check_maybe_rval:
 % check_rval:
-%   Fail if the specified rval(s) might evaluate to the addresses of
+%   Find out if the specified rval(s) might evaluate to the addresses of
 %   local variables (or fields of local variables) or nested functions.
 
-:- pred check_rvals(list(mlds_rval)::in, locals::in) is semidet.
+:- func check_rvals(list(mlds_rval), locals) = may_yield_dangling_stack_ref.
 
-check_rvals([], _).
-check_rvals([Rval|Rvals], Locals) :-
-    check_rval(Rval, Locals),
-    check_rvals(Rvals, Locals).
+check_rvals([], _) = will_not_yield_dangling_stack_ref.
+check_rvals([Rval | Rvals], Locals) = MayYieldDanglingStackRef :-
+    ( check_rval(Rval, Locals) = may_yield_dangling_stack_ref ->
+        MayYieldDanglingStackRef = may_yield_dangling_stack_ref
+    ;
+        MayYieldDanglingStackRef = check_rvals(Rvals, Locals)
+    ).
 
-:- pred check_maybe_rval(maybe(mlds_rval)::in, locals::in) is semidet.
+:- func check_maybe_rval(maybe(mlds_rval), locals)
+    = may_yield_dangling_stack_ref.
 
-check_maybe_rval(no, _).
-check_maybe_rval(yes(Rval), Locals) :-
-    check_rval(Rval, Locals).
+check_maybe_rval(no, _) = will_not_yield_dangling_stack_ref.
+check_maybe_rval(yes(Rval), Locals) = check_rval(Rval, Locals).
 
-:- pred check_rval(mlds_rval::in, locals::in) is semidet.
+:- func check_rval(mlds_rval, locals) = may_yield_dangling_stack_ref.
 
-check_rval(lval(_Lval), _) :-
+check_rval(Rval, Locals) = MayYieldDanglingStackRef :-
+    (
+        Rval = lval(_Lval),
     % Passing the _value_ of an lval is fine.
-    true.
-check_rval(mkword(_Tag, Rval), Locals) :-
-    check_rval(Rval, Locals).
-check_rval(const(Const), Locals) :-
-    check_const(Const, Locals).
-check_rval(unop(_Op, Rval), Locals) :-
-    check_rval(Rval, Locals).
-check_rval(binop(_Op, X, Y), Locals) :-
-    check_rval(X, Locals),
-    check_rval(Y, Locals).
-check_rval(mem_addr(Lval), Locals) :-
+        MayYieldDanglingStackRef = will_not_yield_dangling_stack_ref
+    ;
+        Rval = mkword(_Tag, SubRval),
+        MayYieldDanglingStackRef = check_rval(SubRval, Locals)
+    ;
+        Rval = const(Const),
+        MayYieldDanglingStackRef = check_const(Const, Locals)
+    ;
+        Rval = unop(_Op, XRval),
+        MayYieldDanglingStackRef = check_rval(XRval, Locals)
+    ;
+        Rval = binop(_Op, XRval, YRval),
+        ( check_rval(XRval, Locals) = may_yield_dangling_stack_ref ->
+            MayYieldDanglingStackRef = may_yield_dangling_stack_ref
+        ;
+            MayYieldDanglingStackRef = check_rval(YRval, Locals)
+        )
+    ;
+        Rval = mem_addr(Lval),
     % Passing the address of an lval is a problem,
     % if that lval names a local variable.
-    check_lval(Lval, Locals).
+        MayYieldDanglingStackRef = check_lval(Lval, Locals)
+    ;
+        Rval = self(_),
+        MayYieldDanglingStackRef = may_yield_dangling_stack_ref
+    ).
 
-    % Fail if the specified lval might be a local variable
+    % Find out if the specified lval might be a local variable
     % (or a field of a local variable).
     %
-:- pred check_lval(mlds_lval::in, locals::in) is semidet.
+:- func check_lval(mlds_lval, locals) = may_yield_dangling_stack_ref.
 
-check_lval(field(_MaybeTag, Rval, _FieldId, _, _), Locals) :-
-    check_rval(Rval, Locals).
-check_lval(mem_ref(_, _), _) :-
-    % We assume that the addresses of local variables are only
-    % ever passed down to other functions, or assigned to,
-    % so a mem_ref lval can never refer to a local variable.
-    true.
-check_lval(var(Var0, _), Locals) :-
-    \+ var_is_local(Var0, Locals).
+check_lval(Lval, Locals) = MayYieldDanglingStackRef :-
+    (
+        Lval = var(Var0, _),
+        ( var_is_local(Var0, Locals) ->
+            MayYieldDanglingStackRef = may_yield_dangling_stack_ref
+        ;
+            MayYieldDanglingStackRef = will_not_yield_dangling_stack_ref
+        )
+    ;
+        Lval = field(_MaybeTag, Rval, _FieldId, _, _),
+        MayYieldDanglingStackRef = check_rval(Rval, Locals)
+    ;
+        ( Lval = mem_ref(_, _)
+        ; Lval = global_var_ref(_)
+        ),
+        % We assume that the addresses of local variables are only ever
+        % passed down to other functions, or assigned to, so a mem_ref lval
+        % can never refer to a local variable.
+        MayYieldDanglingStackRef = will_not_yield_dangling_stack_ref
+    ).
 
-    % Fail if the specified const might be the address of a local variable
+    % Find out if the specified const might be the address of a local variable
     % or nested function.
     %
     % The addresses of local variables are probably not consts, at least
@@ -438,20 +477,28 @@
     % so it might be safe to allow all data_addr_consts here, but currently
     % we just take a conservative approach.
     %
-:- pred check_const(mlds_rval_const::in, locals::in) is semidet.
+:- func check_const(mlds_rval_const, locals) = may_yield_dangling_stack_ref.
 
-check_const(Const, Locals) :-
+check_const(Const, Locals) = MayYieldDanglingStackRef :-
     ( Const = mlconst_code_addr(CodeAddr) ->
-        \+ function_is_local(CodeAddr, Locals)
+        ( function_is_local(CodeAddr, Locals) ->
+            MayYieldDanglingStackRef = may_yield_dangling_stack_ref
+        ;
+            MayYieldDanglingStackRef = will_not_yield_dangling_stack_ref
+        )
     ; Const = mlconst_data_addr(DataAddr) ->
         DataAddr = data_addr(ModuleName, DataName),
         ( DataName = var(VarName) ->
-            \+ var_is_local(qual(ModuleName, module_qual, VarName), Locals)
+            ( var_is_local(qual(ModuleName, module_qual, VarName), Locals) ->
+                MayYieldDanglingStackRef = may_yield_dangling_stack_ref
+            ;
+                MayYieldDanglingStackRef = will_not_yield_dangling_stack_ref
+            )
         ;
-            true
+            MayYieldDanglingStackRef = will_not_yield_dangling_stack_ref
         )
     ;
-        true
+        MayYieldDanglingStackRef = will_not_yield_dangling_stack_ref
     ).
 
     % Check whether the specified variable is defined locally, i.e. in storage
Index: compiler/ml_type_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_type_gen.m,v
retrieving revision 1.73
diff -u -b -r1.73 ml_type_gen.m
--- compiler/ml_type_gen.m	30 Dec 2007 08:23:49 -0000	1.73
+++ compiler/ml_type_gen.m	19 Jan 2008 23:46:15 -0000
@@ -424,11 +424,11 @@
         % otherwise we put it in a separate nested derived class.
         %
         (
-            (all [Ctor] (
+            all [Ctor] (
                 list.member(Ctor, Ctors)
             =>
                 ml_needs_secondary_tag(TagValues, Ctor)
-            ))
+            )
         ->
             TagMembers = TagMembers0,
             TagClassId = BaseClassId
Index: compiler/ml_unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.121
diff -u -b -r1.121 ml_unify_gen.m
--- compiler/ml_unify_gen.m	16 Jan 2008 08:34:53 -0000	1.121
+++ compiler/ml_unify_gen.m	20 Jan 2008 00:01:05 -0000
@@ -1746,76 +1746,87 @@
 :- func ml_gen_tag_test_rval(cons_tag, mer_type, module_info, mlds_rval)
     = mlds_rval.
 
-ml_gen_tag_test_rval(string_tag(String), _, _, Rval) =
-    binop(str_eq, Rval, const(mlconst_string(String))).
-ml_gen_tag_test_rval(float_tag(Float), _, _, Rval) =
-    binop(float_eq, Rval, const(mlconst_float(Float))).
-ml_gen_tag_test_rval(int_tag(Int), _, _, Rval) =
-    binop(eq, Rval, const(mlconst_int(Int))).
-ml_gen_tag_test_rval(foreign_tag(ForeignLang, ForeignVal), _, _, Rval) =
-    binop(eq, Rval, const(mlconst_foreign(ForeignLang, ForeignVal,
-        mlds_native_int_type))).
-ml_gen_tag_test_rval(pred_closure_tag(_, _, _), _, _, _Rval) = _TestRval :-
-    % This should never happen, since the error will be detected
-    % during mode checking.
-    unexpected(this_file, "Attempted higher-order unification").
-ml_gen_tag_test_rval(type_ctor_info_tag(_, _, _), _, _, _) = _ :-
-    unexpected(this_file, "Attempted type_ctor_info unification").
-ml_gen_tag_test_rval(base_typeclass_info_tag(_, _, _), _, _, _) = _ :-
-    unexpected(this_file, "Attempted base_typeclass_info unification").
-ml_gen_tag_test_rval(tabling_info_tag(_, _), _, _, _) = _ :-
-    unexpected(this_file, "Attempted tabling_info unification").
-ml_gen_tag_test_rval(deep_profiling_proc_layout_tag(_, _), _, _, _) = _ :-
-    unexpected(this_file, "Attempted deep_profiling_proc_layout unification").
-ml_gen_tag_test_rval(table_io_decl_tag(_, _), _, _, _) = _ :-
-    unexpected(this_file, "Attempted table_io_decl unification").
-ml_gen_tag_test_rval(no_tag, _, _, _Rval) = const(mlconst_true).
-ml_gen_tag_test_rval(single_functor_tag, _, _, _Rval) = const(mlconst_true).
-ml_gen_tag_test_rval(unshared_tag(UnsharedTag), _, _, Rval) =
-    binop(eq, unop(std_unop(tag), Rval),
-        unop(std_unop(mktag), const(mlconst_int(UnsharedTag)))).
-ml_gen_tag_test_rval(shared_remote_tag(PrimaryTagVal, SecondaryTagVal),
-        VarType, ModuleInfo, Rval) = TagTest :-
-    SecondaryTagField = ml_gen_secondary_tag_rval(PrimaryTagVal, VarType,
+ml_gen_tag_test_rval(Tag, Type, ModuleInfo, Rval) = TagTestRval :-
+    (
+        Tag = string_tag(String),
+        TagTestRval = binop(str_eq, Rval, const(mlconst_string(String)))
+    ;
+        Tag = float_tag(Float),
+        TagTestRval = binop(float_eq, Rval, const(mlconst_float(Float)))
+    ;
+        Tag = int_tag(Int),
+        TagTestRval = binop(eq, Rval, const(mlconst_int(Int)))
+    ;
+        Tag = foreign_tag(ForeignLang, ForeignVal),
+        Const = const(mlconst_foreign(ForeignLang, ForeignVal,
+            mlds_native_int_type)),
+        TagTestRval = binop(eq, Rval, Const)
+    ;
+        ( Tag = pred_closure_tag(_, _, _)
+        ; Tag = type_ctor_info_tag(_, _, _)
+        ; Tag = base_typeclass_info_tag(_, _, _)
+        ; Tag = tabling_info_tag(_, _)
+        ; Tag = deep_profiling_proc_layout_tag(_, _)
+        ; Tag = table_io_decl_tag(_, _)
+        ),
+        unexpected(this_file, "ml_gen_tag_test_rval: bad tag")
+    ;
+        Tag = no_tag,
+        TagTestRval = const(mlconst_true)
+    ;
+        Tag = single_functor_tag,
+        TagTestRval = const(mlconst_true)
+    ;
+        Tag = unshared_tag(UnsharedTagNum),
+        RvalTag = unop(std_unop(tag), Rval),
+        UnsharedTag = unop(std_unop(mktag),
+            const(mlconst_int(UnsharedTagNum))),
+        TagTestRval = binop(eq, RvalTag, UnsharedTag)
+    ;
+        Tag = shared_remote_tag(PrimaryTagNum, SecondaryTagNum),
+        SecondaryTagField = ml_gen_secondary_tag_rval(PrimaryTagNum, Type,
         ModuleInfo, Rval),
-    SecondaryTagTest = binop(eq, SecondaryTagField,
-        const(mlconst_int(SecondaryTagVal))),
+        SecondaryTagTestRval = binop(eq, SecondaryTagField,
+            const(mlconst_int(SecondaryTagNum))),
     module_info_get_globals(ModuleInfo, Globals),
     globals.lookup_int_option(Globals, num_tag_bits, NumTagBits),
     ( NumTagBits = 0 ->
         % No need to test the primary tag.
-        TagTest = SecondaryTagTest
+            TagTestRval = SecondaryTagTestRval
     ;
-        PrimaryTagTest = binop(eq,
-            unop(std_unop(tag), Rval),
-            unop(std_unop(mktag), const(mlconst_int(PrimaryTagVal)))),
-        TagTest = binop(logical_and, PrimaryTagTest, SecondaryTagTest)
-    ).
-ml_gen_tag_test_rval(shared_local_tag(Bits, Num), VarType, ModuleInfo, Rval) =
-        TestRval :-
-    MLDS_VarType = mercury_type_to_mlds_type(ModuleInfo, VarType),
-    TestRval = binop(eq, Rval,
-        unop(cast(MLDS_VarType), mkword(Bits,
-        unop(std_unop(mkbody), const(mlconst_int(Num)))))).
-ml_gen_tag_test_rval(reserved_address_tag(ReservedAddr), VarType, ModuleInfo,
-        Rval) = TestRval :-
-    MLDS_VarType = mercury_type_to_mlds_type(ModuleInfo, VarType),
+            RvalPTag = unop(std_unop(tag), Rval),
+            PrimaryTagRval = unop(std_unop(mktag),
+                const(mlconst_int(PrimaryTagNum))),
+            PrimaryTagTestRval = binop(eq, RvalPTag, PrimaryTagRval),
+            TagTestRval = binop(logical_and,
+                PrimaryTagTestRval, SecondaryTagTestRval)
+        )
+    ;
+        Tag = shared_local_tag(Bits, Num),
+        MLDS_Type = mercury_type_to_mlds_type(ModuleInfo, Type),
+        TagTestRval = binop(eq, Rval,
+            unop(cast(MLDS_Type),
+                mkword(Bits,
+                    unop(std_unop(mkbody), const(mlconst_int(Num))))))
+    ;
+        Tag = reserved_address_tag(ReservedAddr),
+        MLDS_Type = mercury_type_to_mlds_type(ModuleInfo, Type),
     ReservedAddrRval = ml_gen_reserved_address(ModuleInfo, ReservedAddr,
-        MLDS_VarType),
-    TestRval = binop(eq, Rval, ReservedAddrRval).
-ml_gen_tag_test_rval(
-        shared_with_reserved_addresses_tag(ReservedAddrs, ThisTag),
-        VarType, ModuleInfo, Rval) = FinalTestRval :-
+            MLDS_Type),
+        TagTestRval = binop(eq, Rval, ReservedAddrRval)
+    ;
+        Tag = shared_with_reserved_addresses_tag(ReservedAddrs, ThisTag),
     % We first check that the Rval doesn't match any of the ReservedAddrs,
     % and then check that it matches ThisTag.
     CheckReservedAddrs = (func(RA, TestRval0) = TestRval :-
-        EqualRA = ml_gen_tag_test_rval(reserved_address_tag(RA), VarType,
+            EqualRA = ml_gen_tag_test_rval(reserved_address_tag(RA), Type,
             ModuleInfo, Rval),
         TestRval = ml_gen_and(ml_gen_not(EqualRA), TestRval0)
     ),
-    MatchesThisTag = ml_gen_tag_test_rval(ThisTag, VarType, ModuleInfo, Rval),
-    FinalTestRval = list.foldr(CheckReservedAddrs, ReservedAddrs,
-        MatchesThisTag).
+        MatchesThisTag = ml_gen_tag_test_rval(ThisTag, Type, ModuleInfo, Rval),
+        TagTestRval = list.foldr(CheckReservedAddrs, ReservedAddrs,
+            MatchesThisTag)
+    ).
 
     % ml_gen_secondary_tag_rval(PrimaryTag, VarType, ModuleInfo, VarRval):
     %
@@ -1855,11 +1866,7 @@
 ml_gen_hl_tag_field_id(Type, ModuleInfo) = FieldId :-
     FieldName = "data_tag",
     % Figure out the type name and arity.
-    ( type_to_ctor_and_args(Type, TypeCtor0, _) ->
-        TypeCtor = TypeCtor0
-    ;
-        unexpected(this_file, "ml_gen_hl_tag_field_id: invalid type")
-    ),
+    type_to_ctor_and_args_det(Type, TypeCtor, _),
     ml_gen_type_name(TypeCtor, QualifiedTypeName, TypeArity),
     QualifiedTypeName = qual(MLDS_Module, TypeQualKind, TypeName),
 
@@ -1919,7 +1926,7 @@
 
 ml_gen_field_id(Type, Tag, ConsName, ConsArity, FieldName, Globals)
         = FieldId :-
-    ( type_to_ctor_and_args(Type, TypeCtor, _) ->
+    type_to_ctor_and_args_det(Type, TypeCtor, _),
         ml_gen_type_name(TypeCtor, QualTypeName, TypeArity),
         QualTypeName = qual(MLDS_Module, QualKind, TypeName),
         TypeQualifier = mlds_append_class_qualifier(
@@ -1941,10 +1948,7 @@
                 type_qual, Globals, ConsName, ConsArity),
             QualifiedFieldName = qual(FieldQualifier, type_qual, FieldName)
         ),
-        FieldId = named_field(QualifiedFieldName, ClassPtrType)
-    ;
-        unexpected(this_file, "ml_gen_field_id: invalid type")
-    ).
+    FieldId = named_field(QualifiedFieldName, ClassPtrType).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rtti_to_mlds.m,v
retrieving revision 1.82
diff -u -b -r1.82 rtti_to_mlds.m
--- compiler/rtti_to_mlds.m	11 Sep 2007 03:12:33 -0000	1.82
+++ compiler/rtti_to_mlds.m	19 Jan 2008 22:36:35 -0000
@@ -1431,9 +1431,8 @@
     gen_wrapper_func_and_initializer(ModuleInfo, NumExtra, RttiProcLabel,
         typeclass_info_closure, Init, !ExtraDefns).
 
-:- pred gen_init_special_pred(module_info::in, univ::in,
-    mlds_initializer::out, list(mlds_defn)::in, list(mlds_defn)::out)
-    is det.
+:- pred gen_init_special_pred(module_info::in, univ::in, mlds_initializer::out,
+    list(mlds_defn)::in, list(mlds_defn)::out) is det.
 
 gen_init_special_pred(ModuleInfo, RttiProcIdUniv, Init, !ExtraDefns) :-
     % We can't store the address of the special pred procedure directly in the
@@ -1452,7 +1451,7 @@
         ;
             NumExtra = 0,
             gen_wrapper_func_and_initializer(ModuleInfo, NumExtra,
-                RttiProcId, special_pred, Init, !ExtraDefns)
+                RttiProcId, special_pred_closure, Init, !ExtraDefns)
         )
     ;
         unexpected(this_file,
Index: compiler/store_alloc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/store_alloc.m,v
retrieving revision 1.107
diff -u -b -r1.107 store_alloc.m
--- compiler/store_alloc.m	30 Dec 2007 08:23:57 -0000	1.107
+++ compiler/store_alloc.m	5 Jan 2008 05:41:58 -0000
@@ -144,7 +144,7 @@
     set.difference(Liveness0,  PreDeaths, Liveness1),
     set.union(Liveness1, PreBirths, Liveness2),
     store_alloc_in_goal_2(GoalExpr0, GoalExpr, Liveness2, Liveness3,
-        !LastLocns, ResumeVars0, PostDeaths, StoreAllocInfo),
+        !LastLocns, ResumeVars0, StoreAllocInfo),
     set.difference(Liveness3, PostDeaths, Liveness4),
     % If any variables magically become live in the PostBirths,
     % then they have to mundanely become live in a parallel goal,
@@ -174,11 +174,13 @@
     %
 :- pred store_alloc_in_goal_2(hlds_goal_expr::in, hlds_goal_expr::out,
     liveness_info::in, liveness_info::out,
-    last_locns::in, last_locns::out, set(prog_var)::in, set(prog_var)::in,
+    last_locns::in, last_locns::out, set(prog_var)::in,
     store_alloc_info::in) is det.
 
-store_alloc_in_goal_2(conj(ConjType, Goals0), conj(ConjType, Goals),
-        !Liveness, !LastLocns, ResumeVars0, _, StoreAllocInfo) :-
+store_alloc_in_goal_2(GoalExpr0, GoalExpr, !Liveness, !LastLocns,
+        ResumeVars0, StoreAllocInfo) :-
+    (
+        GoalExpr0 = conj(ConjType, Goals0),
     (
         ConjType = plain_conj,
         store_alloc_in_conj(Goals0, Goals, !Liveness, !LastLocns,
@@ -187,32 +189,33 @@
         ConjType = parallel_conj,
         store_alloc_in_par_conj(Goals0, Goals, !Liveness, !LastLocns,
             ResumeVars0, StoreAllocInfo)
-    ).
-
-store_alloc_in_goal_2(disj(Goals0), disj(Goals), !Liveness, !LastLocns,
-        ResumeVars0, _, StoreAllocInfo) :-
+        ),
+        GoalExpr = conj(ConjType, Goals)
+    ;
+        GoalExpr0 = disj(Goals0),
     store_alloc_in_disj(Goals0, Goals, !Liveness,
         !.LastLocns, LastLocnsList, ResumeVars0, StoreAllocInfo),
-    merge_last_locations(LastLocnsList, !:LastLocns).
-
-store_alloc_in_goal_2(negation(Goal0), negation(Goal), !Liveness, !LastLocns,
-        _ResumeVars0, _, StoreAllocInfo) :-
-    Goal0 = hlds_goal(_, GoalInfo0),
-    goal_info_get_resume_point(GoalInfo0, ResumeNot),
+        merge_last_locations(LastLocnsList, !:LastLocns),
+        GoalExpr = disj(Goals)
+    ;
+        GoalExpr0 = negation(SubGoal0),
+        SubGoal0 = hlds_goal(_, SubGoalInfo0),
+        goal_info_get_resume_point(SubGoalInfo0, ResumeNot),
     goal_info_resume_vars_and_loc(ResumeNot, ResumeNotVars, _),
-    store_alloc_in_goal(Goal0, Goal, !Liveness, !.LastLocns, _,
-        ResumeNotVars, StoreAllocInfo).
-
-store_alloc_in_goal_2(switch(Var, Det, Cases0), switch(Var, Det, Cases),
-        !Liveness, !LastLocns, ResumeVars0, _, StoreAllocInfo) :-
+        store_alloc_in_goal(SubGoal0, SubGoal, !Liveness, !.LastLocns, _,
+            ResumeNotVars, StoreAllocInfo),
+        GoalExpr = negation(SubGoal)
+    ;
+        GoalExpr0 = switch(Var, Det, Cases0),
     store_alloc_in_cases(Cases0, Cases, !Liveness,
         !.LastLocns, LastLocnsList, ResumeVars0, StoreAllocInfo),
-    merge_last_locations(LastLocnsList, !:LastLocns).
+        merge_last_locations(LastLocnsList, !:LastLocns),
+        GoalExpr = switch(Var, Det, Cases)
+    ;
+        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
+        Liveness0 = !.Liveness,
+        LastLocns0 = !.LastLocns,
 
-store_alloc_in_goal_2(if_then_else(Vars, Cond0, Then0, Else0),
-        if_then_else(Vars, Cond, Then, Else),
-        Liveness0, Liveness, LastLocns0, LastLocns,
-        ResumeVars0, _, StoreAllocInfo) :-
     Cond0 = hlds_goal(_, CondGoalInfo0),
     goal_info_get_resume_point(CondGoalInfo0, ResumeCond),
     goal_info_resume_vars_and_loc(ResumeCond, ResumeCondVars, _),
@@ -222,28 +225,28 @@
         LastLocnsCond, LastLocnsThen, ResumeVars0, StoreAllocInfo),
     store_alloc_in_goal(Else0, Else, Liveness0, _Liveness2,
         LastLocns0, LastLocnsElse, ResumeVars0, StoreAllocInfo),
-    merge_last_locations([LastLocnsThen, LastLocnsElse], LastLocns).
+        merge_last_locations([LastLocnsThen, LastLocnsElse], LastLocns),
 
-store_alloc_in_goal_2(scope(Remove, Goal0), scope(Remove, Goal),
-        !Liveness, !LastLocns, ResumeVars0, _, StoreAllocInfo) :-
-    store_alloc_in_goal(Goal0, Goal, !Liveness, !LastLocns,
-        ResumeVars0, StoreAllocInfo).
-
-store_alloc_in_goal_2(Goal @ generic_call(_, _, _, _), Goal,
-        !Liveness, !LastLocns, _, _, _).
-
-store_alloc_in_goal_2(Goal @ plain_call(_, _, _, _, _, _), Goal,
-        !Liveness, !LastLocns, _, _, _).
-
-store_alloc_in_goal_2(Goal @ unify(_, _, _, _, _), Goal,
-        !Liveness, !LastLocns, _, _, _).
-
-store_alloc_in_goal_2(Goal @ call_foreign_proc(_, _, _, _, _, _, _), Goal,
-        !Liveness, !LastLocns, _, _, _).
-
-store_alloc_in_goal_2(shorthand(_), _, _, _, _, _, _, _, _) :-
+        !:Liveness = Liveness,
+        !:LastLocns = LastLocns,
+        GoalExpr = if_then_else(Vars, Cond, Then, Else)
+    ;
+        GoalExpr0 = scope(Remove, SubGoal0),
+        store_alloc_in_goal(SubGoal0, SubGoal, !Liveness, !LastLocns,
+            ResumeVars0, StoreAllocInfo),
+        GoalExpr = scope(Remove, SubGoal)
+    ;
+        ( GoalExpr0 = generic_call(_, _, _, _)
+        ; GoalExpr0 = plain_call(_, _, _, _, _, _)
+        ; GoalExpr0 = unify(_, _, _, _, _)
+        ; GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
+        ),
+        GoalExpr = GoalExpr0
+    ;
+        GoalExpr0 = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "store_alloc_in_goal_2: unexpected shorthand").
+        unexpected(this_file, "store_alloc_in_goal_2: shorthand")
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -361,18 +364,17 @@
 
 store_alloc_allocate_storage(LiveVars, StoreAllocInfo, FollowVars,
         !:StoreMap) :-
-
-    % This addresses point 1
+    % This addresses point 1.
     map.keys(FollowVars, FollowKeys),
     store_alloc_remove_nonlive(FollowKeys, LiveVars, FollowVars, !:StoreMap),
 
-    % This addresses points 3 and 4
+    % This addresses points 3 and 4.
     map.keys(!.StoreMap, StoreVars),
     set.init(SeenLvals0),
     store_alloc_handle_conflicts_and_nonreal(StoreVars, 1, N,
         SeenLvals0, SeenLvals, !StoreMap),
 
-    % This addresses point 2
+    % This addresses point 2.
     store_alloc_allocate_extras(LiveVars, N, SeenLvals, StoreAllocInfo,
         !StoreMap).
 
Index: compiler/stratify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stratify.m,v
retrieving revision 1.64
diff -u -b -r1.64 stratify.m
--- compiler/stratify.m	30 Dec 2007 08:23:57 -0000	1.64
+++ compiler/stratify.m	5 Jan 2008 06:29:13 -0000
@@ -157,90 +157,81 @@
     module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
     pred_info_get_procedures(PredInfo, ProcTable),
     map.lookup(ProcTable, ProcId, Proc),
-    proc_info_get_goal(Proc, hlds_goal(GoalExpr, GoalInfo)),
-    first_order_check_goal(GoalExpr, GoalInfo, no, WholeScc,
+    proc_info_get_goal(Proc, Goal),
+    first_order_check_goal(Goal, no, WholeScc,
         PredProcId, Error, !ModuleInfo, !IO),
     first_order_check_scc_2(Remaining, WholeScc, Error, !ModuleInfo, !IO).
 
-:- pred first_order_check_goal(hlds_goal_expr::in, hlds_goal_info::in,
-    bool::in, list(pred_proc_id)::in, pred_proc_id::in, bool::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- pred first_order_check_goal(hlds_goal::in, bool::in, list(pred_proc_id)::in,
+    pred_proc_id::in, bool::in, module_info::in, module_info::out,
+    io::di, io::uo) is det.
 
-first_order_check_goal(conj(_ConjType, Goals), _GoalInfo, Negated, WholeScc,
-        ThisPredProcId, Error, !ModuleInfo, !IO) :-
-    first_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
-        Error, !ModuleInfo, !IO).
-first_order_check_goal(disj(Goals), _GoalInfo, Negated,
-        WholeScc, ThisPredProcId, Error, !ModuleInfo, !IO) :-
-    first_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
-        Error, !ModuleInfo, !IO).
-first_order_check_goal(switch(_Var, _Fail, Cases), _GoalInfo, Negated,
-        WholeScc, ThisPredProcId, Error, !ModuleInfo, !IO) :-
-    first_order_check_case_list(Cases, Negated, WholeScc, ThisPredProcId,
-        Error, !ModuleInfo, !IO).
-first_order_check_goal(if_then_else(_Vars, Cond, Then, Else), _GoalInfo,
-        Negated, WholeScc, ThisPredProcId, Error, !ModuleInfo, !IO) :-
-    Cond = hlds_goal(CondExpr, CInfo),
-    Then = hlds_goal(ThenExpr, TInfo),
-    Else = hlds_goal(ElseExpr, EInfo),
-    first_order_check_goal(CondExpr, CInfo, yes, WholeScc, ThisPredProcId,
-        Error, !ModuleInfo, !IO),
-    first_order_check_goal(ThenExpr, TInfo, Negated, WholeScc, ThisPredProcId,
-        Error, !ModuleInfo, !IO),
-    first_order_check_goal(ElseExpr, EInfo, Negated, WholeScc, ThisPredProcId,
-        Error, !ModuleInfo, !IO).
-first_order_check_goal(scope(_, hlds_goal(GoalExpr, GoalInfo)), _GoalInfo,
-        Negated, WholeScc, ThisPredProcId, Error, !ModuleInfo, !IO) :-
-    first_order_check_goal(GoalExpr, GoalInfo, Negated, WholeScc,
-        ThisPredProcId, Error, !ModuleInfo, !IO).
-first_order_check_goal(negation(hlds_goal(GoalExpr, GoalInfo)), _GoalInfo,
-        _Negated, WholeScc, ThisPredProcId, Error, !ModuleInfo, !IO) :-
-    first_order_check_goal(GoalExpr, GoalInfo, yes, WholeScc, ThisPredProcId,
-        Error, !ModuleInfo, !IO).
-first_order_check_goal(call_foreign_proc(_Attributes, CPred, CProc,
-        _, _, _, _), GoalInfo, Negated, WholeScc, ThisPredProcId, Error,
+first_order_check_goal(Goal, Negated, WholeScc, ThisPredProcId, Error,
         !ModuleInfo, !IO) :-
+    Goal = hlds_goal(GoalExpr, GoalInfo),
     (
-        Negated = yes,
-        list.member(proc(CPred, CProc),  WholeScc)
-    ->
-        Context = goal_info_get_context(GoalInfo),
-        emit_message(ThisPredProcId, Context,
-            "call introduces a non-stratified loop.", Error, !ModuleInfo, !IO)
+        ( GoalExpr = conj(_ConjType, Goals)
+        ; GoalExpr = disj(Goals)
+        ),
+        first_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
+            Error, !ModuleInfo, !IO)
     ;
-        true
-    ).
-first_order_check_goal(unify(_Var, _RHS, _Mode, _Uni, _Context), _GoalInfo,
-        _Negated, _WholeScc, _ThisPredProcId, _, !ModuleInfo, !IO).
-first_order_check_goal(plain_call(CPred, CProc, _Args, _BuiltinState, _UC,
-        _Sym), GInfo, Negated, WholeScc, ThisPredProcId, Error, !ModuleInfo,
-        !IO) :-
+        GoalExpr = switch(_Var, _Fail, Cases),
+        first_order_check_case_list(Cases, Negated, WholeScc, ThisPredProcId,
+            Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = if_then_else(_Vars, Cond, Then, Else),
+        first_order_check_goal(Cond, yes, WholeScc,
+            ThisPredProcId, Error, !ModuleInfo, !IO),
+        first_order_check_goal(Then, Negated, WholeScc,
+            ThisPredProcId, Error, !ModuleInfo, !IO),
+        first_order_check_goal(Else, Negated, WholeScc,
+            ThisPredProcId, Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = negation(SubGoal),
+        first_order_check_goal(SubGoal, yes, WholeScc,
+            ThisPredProcId, Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = scope(_, SubGoal),
+        first_order_check_goal(SubGoal, Negated, WholeScc,
+            ThisPredProcId, Error, !ModuleInfo, !IO)
+    ;
+        ( GoalExpr = plain_call(CPred, CProc, _Args, _BuiltinState, _UC, _Sym)
+        ; GoalExpr = call_foreign_proc(_Attributes, CPred, CProc, _, _, _, _)
+        ),
     Callee = proc(CPred, CProc),
     (
         Negated = yes,
         list.member(Callee, WholeScc)
     ->
-        Context = goal_info_get_context(GInfo),
+            Context = goal_info_get_context(GoalInfo),
         emit_message(ThisPredProcId, Context,
-            "call introduces a non-stratified loop.", Error, !ModuleInfo, !IO)
+                "call introduces a non-stratified loop.", Error,
+                !ModuleInfo, !IO)
     ;
         true
-    ).
-first_order_check_goal(generic_call(_Var, _Vars, _Modes, _Det), _GInfo,
-        _Negated, _WholeScc, _ThisPredProcId, _Error,  !ModuleInfo, !IO).
-first_order_check_goal(shorthand(_), _, _, _, _, _, !ModuleInfo, !IO) :-
+        )
+    ;
+        GoalExpr = generic_call(_Var, _Args, _Modes, _Det)
+        % Do nothing.
+    ;
+        GoalExpr = unify(_LHS, _RHS, _Mode, _Unification, _UnifyContext)
+        % Do nothing.
+    ;
+        GoalExpr = shorthand(_),
     % these should have been expanded out by now
-    unexpected(this_file, "first_order_check_goal: unexpected shorthand").
+        unexpected(this_file, "first_order_check_goal: shorthand")
+    ).
 
 :- pred first_order_check_goal_list(list(hlds_goal)::in, bool::in,
     list(pred_proc_id)::in, pred_proc_id::in, bool::in,
     module_info::in, module_info::out, io::di, io::uo) is det.
 
 first_order_check_goal_list([], _, _, _, _, !ModuleInfo, !IO).
-first_order_check_goal_list([hlds_goal(GoalExpr, GoalInfo) | Goals], Negated,
+first_order_check_goal_list([Goal | Goals], Negated,
         WholeScc, ThisPredProcId, Error, !ModuleInfo, !IO) :-
-    first_order_check_goal(GoalExpr, GoalInfo, Negated, WholeScc,
-        ThisPredProcId, Error, !ModuleInfo, !IO),
+    first_order_check_goal(Goal, Negated, WholeScc, ThisPredProcId,
+        Error, !ModuleInfo, !IO),
     first_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
         Error, !ModuleInfo, !IO).
 
@@ -251,8 +242,8 @@
 first_order_check_case_list([], _, _, _, _, !ModuleInfo, !IO).
 first_order_check_case_list([Case | Goals], Negated, WholeScc, ThisPredProcId,
         Error, !ModuleInfo, !IO) :-
-    Case = case(_, _, hlds_goal(GoalExpr, GoalInfo)),
-    first_order_check_goal(GoalExpr, GoalInfo, Negated, WholeScc,
+    Case = case(_, _, Goal),
+    first_order_check_goal(Goal, Negated, WholeScc,
         ThisPredProcId, Error, !ModuleInfo, !IO),
     first_order_check_case_list(Goals, Negated, WholeScc, ThisPredProcId,
         Error, !ModuleInfo, !IO).
@@ -296,61 +287,49 @@
         ),
         pred_info_get_procedures(PredInfo, ProcTable),
         map.lookup(ProcTable, ProcId, Proc),
-        proc_info_get_goal(Proc, hlds_goal(GoalExpr, GoalInfo)),
-        higher_order_check_goal(GoalExpr, GoalInfo, no, WholeScc,
-            PredProcId, HighOrderLoops, Error, !ModuleInfo, !IO)
+        proc_info_get_goal(Proc, Goal),
+        higher_order_check_goal(Goal, no, WholeScc, PredProcId, HighOrderLoops,
+            Error, !ModuleInfo, !IO)
     ;
         true
     ),
     higher_order_check_scc(Remaining, WholeScc, HOInfo, !ModuleInfo, !IO).
 
-:- pred higher_order_check_goal(hlds_goal_expr::in, hlds_goal_info::in,
-    bool::in, set(pred_proc_id)::in, pred_proc_id::in, bool::in, bool::in,
-    module_info::in, module_info::out, io::di, io::uo) is det.
+:- pred higher_order_check_goal(hlds_goal::in, bool::in, set(pred_proc_id)::in,
+    pred_proc_id::in, bool::in, bool::in, module_info::in, module_info::out,
+    io::di, io::uo) is det.
 
-higher_order_check_goal(conj(_ConjType, Goals), _GoalInfo, Negated, WholeScc,
-        ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO) :-
-    higher_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
-        HighOrderLoops, Error, !ModuleInfo, !IO).
-higher_order_check_goal(disj(Goals), _GoalInfo, Negated, WholeScc,
-        ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO) :-
+higher_order_check_goal(Goal, Negated, WholeScc, ThisPredProcId,
+        HighOrderLoops, Error, !ModuleInfo, !IO) :-
+    Goal = hlds_goal(GoalExpr, GoalInfo),
+    (
+        ( GoalExpr = conj(_ConjType, Goals)
+        ; GoalExpr = disj(Goals)
+        ),
     higher_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
-        HighOrderLoops, Error, !ModuleInfo, !IO).
-higher_order_check_goal(switch(_Var, _Fail, Cases), _GoalInfo, Negated,
-        WholeScc, ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO) :-
+            HighOrderLoops, Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = switch(_Var, _Fail, Cases),
     higher_order_check_case_list(Cases, Negated, WholeScc, ThisPredProcId,
-        HighOrderLoops, Error, !ModuleInfo, !IO).
-higher_order_check_goal(if_then_else(_Vars, Cond, Then, Else), _GoalInfo,
-        Negated, WholeScc, ThisPredProcId, HighOrderLoops, Error,
-        !ModuleInfo, !IO) :-
-    Cond = hlds_goal(CondExpr, CInfo),
-    Then = hlds_goal(ThenExpr, TInfo),
-    Else = hlds_goal(ElseExpr, EInfo),
-    higher_order_check_goal(CondExpr, CInfo, yes, WholeScc, ThisPredProcId,
-        HighOrderLoops, Error, !ModuleInfo, !IO),
-    higher_order_check_goal(ThenExpr, TInfo, Negated, WholeScc, ThisPredProcId,
-        HighOrderLoops, Error, !ModuleInfo, !IO),
-    higher_order_check_goal(ElseExpr, EInfo, Negated, WholeScc, ThisPredProcId,
-        HighOrderLoops, Error, !ModuleInfo, !IO).
-higher_order_check_goal(scope(_, hlds_goal(GoalExpr, GoalInfo)), _GoalInfo,
-        Negated, WholeScc, ThisPredProcId, HighOrderLoops, Error,
-        !ModuleInfo, !IO) :-
-    higher_order_check_goal(GoalExpr, GoalInfo, Negated, WholeScc,
-        ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO).
-higher_order_check_goal(negation(hlds_goal(GoalExpr, GoalInfo)), _GoalInfo,
-        _Negated, WholeScc, ThisPredProcId, HighOrderLoops, Error,
-        !ModuleInfo, !IO) :-
-    higher_order_check_goal(GoalExpr, GoalInfo, yes, WholeScc, ThisPredProcId,
-        HighOrderLoops, Error, !ModuleInfo, !IO).
-higher_order_check_goal(call_foreign_proc(_IsRec, _, _, _, _, _, _), _GoalInfo,
-        _Negated, _WholeScc, _ThisPredProcId, _HighOrderLoops, _,
-        !ModuleInfo, !IO).
-higher_order_check_goal(unify(_Var, _RHS, _Mode, _Uni, _Context), _GoalInfo,
-        _Negated, _WholeScc, _ThisPredProcId, _HighOrderLoops, _Error,
-        !ModuleInfo, !IO).
-higher_order_check_goal(plain_call(_CPred, _CProc, _Args, _Builtin, _UC, Sym),
-        GoalInfo, _Negated, _WholeScc, ThisPredProcId, HighOrderLoops,
-        Error, !ModuleInfo, !IO) :-
+            HighOrderLoops, Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = if_then_else(_Vars, Cond, Then, Else),
+        higher_order_check_goal(Cond, yes, WholeScc,
+            ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO),
+        higher_order_check_goal(Then, Negated, WholeScc,
+            ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO),
+        higher_order_check_goal(Else, Negated, WholeScc,
+            ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = negation(SubGoal),
+        higher_order_check_goal(SubGoal, yes, WholeScc,
+            ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = scope(_, SubGoal),
+        higher_order_check_goal(SubGoal, Negated, WholeScc,
+            ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO)
+    ;
+        GoalExpr = plain_call(_CPred, _CProc, _Args, _Builtin, _UC, Sym),
     (
         % XXX : is this good enough to detect all calls to solutions ?
         HighOrderLoops = yes,
@@ -365,11 +344,9 @@
             Error, !ModuleInfo, !IO)
     ;
         true
-    ).
-
-higher_order_check_goal(generic_call(GenericCall, _Vars, _Modes, _Det),
-        GoalInfo, Negated, _WholeScc, ThisPredProcId, HighOrderLoops,
-        Error, !ModuleInfo, !IO) :-
+        )
+    ;
+        GoalExpr = generic_call(GenericCall, _Vars, _Modes, _Det),
     (
         Negated = yes,
         HighOrderLoops = yes,
@@ -379,23 +356,31 @@
     ->
         Context = goal_info_get_context(GoalInfo),
         ErrorMsg = Msg ++ " call may introduce a non-stratified loop.",
-        emit_message(ThisPredProcId, Context, ErrorMsg, Error, !ModuleInfo,
-            !IO)
+            emit_message(ThisPredProcId, Context, ErrorMsg, Error,
+                !ModuleInfo, !IO)
     ;
         true
+        )
+    ;
+        GoalExpr = call_foreign_proc(_, _, _, _, _, _, _)
+        % Do nothing.
+    ;
+        GoalExpr = unify(_LHS, _RHS, _Mode, _Unification, _UnifyContext)
+        % Do nothing.
+    ;
+        GoalExpr = shorthand(_),
+        % These should have been expanded out by now.
+        unexpected(this_file, "higher_order_check_goal: shorthand")
     ).
-higher_order_check_goal(shorthand(_), _, _, _, _, _, _, _, _, !IO) :-
-    % these should have been expanded out by now
-    unexpected(this_file, "higher_order_check_goal: unexpected shorthand").
 
 :- pred higher_order_check_goal_list(list(hlds_goal)::in, bool::in,
     set(pred_proc_id)::in, pred_proc_id::in, bool::in, bool::in,
     module_info::in, module_info::out, io::di, io::uo) is det.
 
 higher_order_check_goal_list([], _, _, _, _, _, !ModuleInfo, !IO).
-higher_order_check_goal_list([hlds_goal(GoalExpr, GoalInfo) | Goals], Negated,
+higher_order_check_goal_list([Goal | Goals], Negated,
         WholeScc, ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO) :-
-    higher_order_check_goal(GoalExpr, GoalInfo, Negated, WholeScc,
+    higher_order_check_goal(Goal, Negated, WholeScc,
         ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO),
     higher_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
         HighOrderLoops, Error, !ModuleInfo, !IO).
@@ -407,8 +392,8 @@
 higher_order_check_case_list([], _, _, _, _, _, !ModuleInfo, !IO).
 higher_order_check_case_list([Case | Goals], Negated, WholeScc, ThisPredProcId,
         HighOrderLoops, Error, !ModuleInfo, !IO) :-
-    Case = case(_, _, hlds_goal(GoalExpr, GoalInfo)),
-    higher_order_check_goal(GoalExpr, GoalInfo, Negated, WholeScc,
+    Case = case(_, _, Goal),
+    higher_order_check_goal(Goal, Negated, WholeScc,
         ThisPredProcId, HighOrderLoops, Error, !ModuleInfo, !IO),
     higher_order_check_case_list(Goals, Negated, WholeScc, ThisPredProcId,
         HighOrderLoops, Error, !ModuleInfo, !IO).
@@ -631,9 +616,9 @@
         !ProcCalls, !HOInfo, !CallsHO) :-
     map.lookup(ProcTable, ProcId, ProcInfo),
     proc_info_get_argmodes(ProcInfo, ArgModes),
-    proc_info_get_goal(ProcInfo, hlds_goal(GoalExpr, _GoalInfo)),
+    proc_info_get_goal(ProcInfo, Goal),
     PredProcId = proc(PredId, ProcId),
-    check_goal(GoalExpr, Calls, HaveAT, CallsHigherOrder),
+    check_proc_body(Goal, Calls, HaveAT, CallsHigherOrder),
     map.det_insert(!.ProcCalls, PredProcId, Calls, !:ProcCalls),
     higherorder_in_out(ArgTypes, ArgModes, ModuleInfo, HOInOut),
     map.det_insert(!.HOInfo, PredProcId, info(HaveAT, HOInOut), !:HOInfo),
@@ -674,9 +659,9 @@
 higherorder_in_out1([Type | Types], [Mode | Modes], ModuleInfo,
         !HOIn, !HOOut) :-
     (
-        % XXX Will have to use a more general check for higher order constants
-        % in parameters user could hide higher order consts in a data structure
-        % etc..
+        % XXX We should use a more general check for higher order constants
+        % in parameters; users could hide higher order constants in data
+        % structures.
         type_is_higher_order(Type)
     ->
         ( mode_is_input(ModuleInfo, Mode) ->
@@ -694,84 +679,106 @@
     % Return the set of all procedures called in the given goal
     % and all addresses taken in the given goal.
     %
-:- pred check_goal(hlds_goal_expr::in, set(pred_proc_id)::out,
+:- pred check_proc_body(hlds_goal::in, set(pred_proc_id)::out,
     set(pred_proc_id)::out, bool::out) is det.
 
-check_goal(Goal, Calls, TakenAddrs, CallsHO) :-
+check_proc_body(Goal, Calls, TakenAddrs, CallsHO) :-
     set.init(Calls0),
     set.init(TakenAddrs0),
-    check_goal1(Goal, Calls0, Calls, TakenAddrs0, TakenAddrs, no, CallsHO).
+    check_goal(Goal, Calls0, Calls, TakenAddrs0, TakenAddrs, no, CallsHO).
 
-:- pred check_goal1(hlds_goal_expr::in,
+:- pred check_goal(hlds_goal::in,
     set(pred_proc_id)::in, set(pred_proc_id)::out,
     set(pred_proc_id)::in, set(pred_proc_id)::out,
     bool::in, bool::out) is det.
 
-check_goal1(unify(_Var, RHS, _Mode, Unification, _Context), !Calls,
-        !HasAT, !CallsHO) :-
+check_goal(Goal, !Calls, !HasAT, !CallsHO) :-
+    Goal = hlds_goal(GoalExpr, _GoalInfo),
+    (
+        GoalExpr = unify(_Var, RHS, _Mode, Unification, _Context),
     % See if a goal has its address taken.
     (
-        % Currently this code assumes that all procs called in a lambda goal
-        % have addresses taken. This is not always to case, but should be
-        % a suitable approximation for the stratification analysis.
-        RHS = rhs_lambda_goal(_Purity, _PredOrFunc, _EvalMethod, _NonLocals,
-            _Vars, _Modes, _Determinism, hlds_goal(GoalExpr, _GoalInfo))
-    ->
-        get_called_procs(GoalExpr, [], CalledProcs),
+            % Currently this code assumes that all procs called in a lambda
+            % goal have addresses taken. This is not always to case, but
+            % should be a suitable approximation for the stratification
+            % analysis.
+            RHS = rhs_lambda_goal(_Purity, _PredOrFunc, _EvalMethod,
+                _NonLocals, _Vars, _Modes, _Determinism, LambdaGoal),
+            get_called_procs(LambdaGoal, [], CalledProcs),
         set.insert_list(!.HasAT, CalledProcs, !:HasAT)
     ;
-        % Currently when this pass is run the construct/4 case will not happen
-        % as higher order constants have been transformed to lambda goals.
-        % See above.
-        Unification = construct(_Var2, ConsId, _, _, _, _, _)
-    ->
+            RHS = rhs_var(_)
+        ;
+            RHS = rhs_functor(_, _, _)
+        ),
+        (
+            % Currently when this pass is run the construct/4 case will not
+            % happen as higher order constants have been transformed to
+            % lambda goals. See above.
+            Unification = construct(_, ConsId, _, _, _, _, _),
         ( ConsId = pred_const(ShroudedPredProcId, _) ->
             PredProcId = unshroud_pred_proc_id(ShroudedPredProcId),
             set.insert(!.HasAT, PredProcId, !:HasAT)
         ;
+                % Do nothing.
             true
         )
     ;
-        true
-    ).
-check_goal1(plain_call(CPred, CProc, _Args, _Builtin, _UC, _Sym), !Calls,
-        !HasAT, !CallsHO) :-
+            ( Unification = deconstruct(_, _, _, _, _, _)
+            ; Unification = assign(_, _)
+            ; Unification = simple_test(_, _)
+            )
+            % Do nothing.
+        ;
+            Unification = complicated_unify(_, _, _),
+            unexpected(this_file, "check_goal: complicated_unify")
+        )
+    ;
+        GoalExpr = plain_call(CPred, CProc, _Args, _Builtin, _UC, _Sym),
     % Add this call to the call list.
-    set.insert(!.Calls, proc(CPred, CProc), !:Calls).
-check_goal1(generic_call(_Var, _Vars, _Modes, _Det), !Calls, !HasAT, _, yes).
+        set.insert(!.Calls, proc(CPred, CProc), !:Calls)
+    ;
+        GoalExpr = call_foreign_proc(_Attrib, _CPred, _CProc, _, _, _, _)
+        % Do nothing.
+        % XXX If the foreign proc may_call_mercury, then we may be missing
+        % some calls.
+    ;
+        GoalExpr = generic_call(_Var, _Vars, _Modes, _Det),
     % Record that the higher order call was made.
-check_goal1(conj(_ConjType, Goals), !Calls, !HasAT, !CallsHO) :-
-    check_goal_list(Goals, !Calls, !HasAT, !CallsHO).
-check_goal1(disj(Goals), !Calls, !HasAT, !CallsHO) :-
-    check_goal_list(Goals, !Calls, !HasAT, !CallsHO).
-check_goal1(switch(_Var, _Fail, Cases), !Calls, !HasAT, !CallsHO) :-
-    check_case_list(Cases, !Calls, !HasAT, !CallsHO).
-check_goal1(if_then_else(_Vars, Cond, Then, Else), !Calls, !HasAT, !CallsHO) :-
-    Cond = hlds_goal(CondExpr, _),
-    Then = hlds_goal(ThenExpr, _),
-    Else = hlds_goal(ElseExpr, _),
-    check_goal1(CondExpr, !Calls, !HasAT, !CallsHO),
-    check_goal1(ThenExpr, !Calls, !HasAT, !CallsHO),
-    check_goal1(ElseExpr, !Calls, !HasAT, !CallsHO).
-check_goal1(scope(_, hlds_goal(GoalExpr, _)), !Calls, !HasAT, !CallsHO) :-
-    check_goal1(GoalExpr, !Calls, !HasAT, !CallsHO).
-check_goal1(negation(hlds_goal(GoalExpr, _)), !Calls, !HasAT, !CallsHO) :-
-    check_goal1(GoalExpr, !Calls, !HasAT, !CallsHO).
-check_goal1(call_foreign_proc(_Attrib, _CPred, _CProc, _, _, _, _),
-        !Calls, !HasAT, !CallsHO).
-check_goal1(shorthand(_), _, _, _, _, _, _) :-
+        !:CallsHO = yes
+    ;
+        ( GoalExpr = conj(_ConjType, Goals)
+        ; GoalExpr = disj(Goals)
+        ),
+        check_goals(Goals, !Calls, !HasAT, !CallsHO)
+    ;
+        GoalExpr = switch(_Var, _Fail, Cases),
+        check_case_list(Cases, !Calls, !HasAT, !CallsHO)
+    ;
+        GoalExpr = if_then_else(_Vars, Cond, Then, Else),
+        check_goal(Cond, !Calls, !HasAT, !CallsHO),
+        check_goal(Then, !Calls, !HasAT, !CallsHO),
+        check_goal(Else, !Calls, !HasAT, !CallsHO)
+    ;
+        ( GoalExpr = scope(_Reason, SubGoal)
+        ; GoalExpr = negation(SubGoal)
+        ),
+        check_goal(SubGoal, !Calls, !HasAT, !CallsHO)
+    ;
+        GoalExpr = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "check_goal1: unexpected shorthand").
+        unexpected(this_file, "check_goal:  shorthand")
+    ).
 
-:- pred check_goal_list(list(hlds_goal)::in,
+:- pred check_goals(list(hlds_goal)::in,
     set(pred_proc_id)::in, set(pred_proc_id)::out,
     set(pred_proc_id)::in, set(pred_proc_id)::out,
     bool::in, bool::out) is det.
 
-check_goal_list([], !Calls, !HasAT, !CallsHO).
-check_goal_list([hlds_goal(GoalExpr, _) | Goals], !Calls, !HasAT, !CallsHO) :-
-    check_goal1(GoalExpr, !Calls, !HasAT, !CallsHO),
-    check_goal_list(Goals, !Calls, !HasAT, !CallsHO).
+check_goals([], !Calls, !HasAT, !CallsHO).
+check_goals([Goal | Goals], !Calls, !HasAT, !CallsHO) :-
+    check_goal(Goal, !Calls, !HasAT, !CallsHO),
+    check_goals(Goals, !Calls, !HasAT, !CallsHO).
 
 :- pred check_case_list(list(case)::in,
     set(pred_proc_id)::in, set(pred_proc_id)::out,
@@ -780,88 +787,106 @@
 
 check_case_list([], !Calls, !HasAT, !CallsHO).
 check_case_list([Case | Goals], !Calls, !HasAT, !CallsHO) :-
-    Case = case(_, _, hlds_goal(GoalExpr, _)),
-    check_goal1(GoalExpr, !Calls, !HasAT, !CallsHO),
+    Case = case(_, _, Goal),
+    check_goal(Goal, !Calls, !HasAT, !CallsHO),
     check_case_list(Goals, !Calls, !HasAT, !CallsHO).
 
     % This pred returns a list of all the calls in a given set of goals,
     % including calls in unification lambda functions and pred_proc_id's
     % in constructs.
     %
-:- pred get_called_procs(hlds_goal_expr::in,
+:- pred get_called_procs(hlds_goal::in,
     list(pred_proc_id)::in, list(pred_proc_id)::out) is det.
 
-get_called_procs(unify(_Var, RHS, _Mode, Unification, _Context), !Calls) :-
+get_called_procs(Goal, !Calls) :-
+    Goal = hlds_goal(GoalExpr, _),
     (
-        % Currently this code assumes that all procs called in a lambda goal
-        % have addresses taken. This is not always to case, but should be
-        % a suitable approximation for the stratification analysis.
-        RHS = rhs_lambda_goal(_Purity, _PredOrFunc, _EvalMethod, _NonLocals,
-            _Vars, _Modes, _Determinism, hlds_goal(GoalExpr, _GoalInfo))
-    ->
-        get_called_procs(GoalExpr, !Calls)
+        GoalExpr = unify(_Var, RHS, _Mode, Unification, _Context),
+        (
+            % Currently this code assumes that all procs called in a lambda
+            % goal have addresses taken. This is not always to case, but
+            % should be a suitable approximation for the stratification
+            % analysis.
+            RHS = rhs_lambda_goal(_Purity, _PredOrFunc, _EvalMethod,
+                _NonLocals, _Vars, _Modes, _Determinism, LambdaGoal),
+            get_called_procs(LambdaGoal, !Calls)
     ;
-        % Currently when this pass is run the construct/4 case will not happen
-        % as higher order constants have been transformed to lambda goals.
-        % See above.
-        Unification = construct(_Var2, ConsId, _, _, _, _, _)
-    ->
+            RHS = rhs_var(_)
+        ;
+            RHS = rhs_functor(_, _, _)
+        ),
+        (
+            % Currently when this pass is run the construct/4 case will not
+            % happen as higher order constants have been transformed to lambda
+            % goals. See above.
+            Unification = construct(_, ConsId, _, _, _, _, _),
         ( ConsId = pred_const(ShroudedPredProcId, _) ->
             PredProcId = unshroud_pred_proc_id(ShroudedPredProcId),
             !:Calls = [PredProcId | !.Calls]
         ;
+                % Do nothing.
             true
         )
     ;
-        true
-    ).
-
-get_called_procs(plain_call(CPred, CProc, _Args, _Builtin, _UC, _Sym),
-        !Calls) :-
+            ( Unification = deconstruct(_, _, _, _, _, _)
+            ; Unification = assign(_, _)
+            ; Unification = simple_test(_, _)
+            )
+            % Do nothing.
+        ;
+            Unification = complicated_unify(_, _, _),
+            unexpected(this_file, "get_called_procs: complicated_unify")
+        )
+    ;
+        GoalExpr = plain_call(CPred, CProc, _Args, _Builtin, _UC, _Sym),
     % Add this call to the call list.
-    !:Calls = [proc(CPred, CProc) | !.Calls].
-
-get_called_procs(generic_call(_Var, _Vars, _Modes, _Det), !Calls).
-
-get_called_procs(conj(_ConjType, Goals), !Calls) :-
-    check_goal_list(Goals, !Calls).
-get_called_procs(disj(Goals), !Calls) :-
-    check_goal_list(Goals, !Calls).
-get_called_procs(switch(_Var, _Fail, Cases), !Calls) :-
-    check_case_list(Cases, !Calls).
-get_called_procs(if_then_else(_Vars, Cond, Then, Else), !Calls) :-
-    Cond = hlds_goal(CondExpr, _),
-    Then = hlds_goal(ThenExpr, _),
-    Else = hlds_goal(ElseExpr, _),
-    get_called_procs(CondExpr, !Calls),
-    get_called_procs(ThenExpr, !Calls),
-    get_called_procs(ElseExpr, !Calls).
-get_called_procs(scope(_, hlds_goal(GoalExpr, _)), !Calls) :-
-    get_called_procs(GoalExpr, !Calls).
-get_called_procs(negation(hlds_goal(GoalExpr, _)), !Calls) :-
-    get_called_procs(GoalExpr, !Calls).
-get_called_procs(call_foreign_proc(_Attrib, _CPred, _CProc, _, _, _, _),
-        !Calls).
-get_called_procs(shorthand(_), !Calls) :-
+        !:Calls = [proc(CPred, CProc) | !.Calls]
+    ;
+        GoalExpr = call_foreign_proc(_Attrib, _CPred, _CProc, _, _, _, _)
+        % Do nothing.
+    ;
+        GoalExpr = generic_call(_Var, _Vars, _Modes, _Det)
+        % Do nothing.
+    ;
+        ( GoalExpr = conj(_ConjType, Goals)
+        ; GoalExpr = disj(Goals)
+        ),
+        get_called_procs_goals(Goals, !Calls)
+    ;
+        GoalExpr = switch(_Var, _Fail, Cases),
+        get_called_procs_cases(Cases, !Calls)
+    ;
+        GoalExpr = if_then_else(_Vars, Cond, Then, Else),
+        get_called_procs(Cond, !Calls),
+        get_called_procs(Then, !Calls),
+        get_called_procs(Else, !Calls)
+    ;
+        ( GoalExpr = scope(_Reason, SubGoal)
+        ; GoalExpr = negation(SubGoal)
+        ),
+        get_called_procs(SubGoal, !Calls)
+    ;
+        GoalExpr = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "get_called_procs: unexpected shorthand").
+        unexpected(this_file, "get_called_procs: shorthand")
+    ).
 
-:- pred check_goal_list(list(hlds_goal)::in,
+:- pred get_called_procs_goals(list(hlds_goal)::in,
     list(pred_proc_id)::in, list(pred_proc_id)::out) is det.
 
-check_goal_list([], !Calls).
-check_goal_list([hlds_goal(GoalExpr, _) | Goals], !Calls) :-
-    get_called_procs(GoalExpr, !Calls),
-    check_goal_list(Goals, !Calls).
+get_called_procs_goals([], !Calls).
+get_called_procs_goals([Goal | Goals], !Calls) :-
+    get_called_procs(Goal, !Calls),
+    get_called_procs_goals(Goals, !Calls).
 
-:- pred check_case_list(list(case)::in,
+:- pred get_called_procs_cases(list(case)::in,
     list(pred_proc_id)::in, list(pred_proc_id)::out) is det.
 
-check_case_list([], !Calls).
-check_case_list([Case | Goals], !Calls) :-
-    Case = case(_, _, hlds_goal(GoalExpr, _)),
-    get_called_procs(GoalExpr, !Calls),
-    check_case_list(Goals, !Calls).
+get_called_procs_cases([], !Calls).
+get_called_procs_cases([Case | Cases], !Calls) :-
+    Case = case(_, _, Goal),
+    get_called_procs(Goal, !Calls),
+    get_called_procs_cases(Cases, !Calls).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/structure_reuse.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/structure_reuse.m,v
retrieving revision 1.5
diff -u -b -r1.5 structure_reuse.m
--- compiler/structure_reuse.m	31 Jul 2006 08:32:02 -0000	1.5
+++ compiler/structure_reuse.m	11 Jan 2008 18:47:10 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 2006 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
Index: compiler/tabling_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/tabling_analysis.m,v
retrieving revision 1.11
diff -u -b -r1.11 tabling_analysis.m
--- compiler/tabling_analysis.m	30 Dec 2007 08:23:59 -0000	1.11
+++ compiler/tabling_analysis.m	5 Jan 2008 06:49:59 -0000
@@ -230,13 +230,19 @@
     (
         % If none of the procedures calls tabled procedures or is conditional
         % then the SCC cannot call tabled procedures.
-        all [ProcResult] list.member(ProcResult, ProcResults) =>
+        all [ProcResult] (
+            list.member(ProcResult, ProcResults)
+        =>
             ProcResult ^ status = mm_tabled_will_not_call
+        )
     ->
         SCC_Result = mm_tabled_will_not_call
     ;
-        all [ProcResult] list.member(ProcResult, ProcResults) =>
-                ProcResult ^ status \= mm_tabled_may_call,
+        all [ProcResult] (
+            list.member(ProcResult, ProcResults)
+        =>
+            ProcResult ^ status \= mm_tabled_may_call
+        ),
         some [ConditionalResult] (
             list.member(ConditionalResult, ProcResults),
             ConditionalResult ^ status = mm_tabled_conditional
@@ -302,71 +308,75 @@
     mm_tabling_status::out, maybe(analysis_status)::out,
     module_info::in, module_info::out, io::di, io::uo) is det.
 
-check_goal_for_mm_tabling(SCC, VarTypes, hlds_goal(GoalExpr, GoalInfo),
-        Result, MaybeStatus, !ModuleInfo, !IO) :-
-    check_goal_for_mm_tabling_2(SCC, VarTypes, GoalExpr, GoalInfo, Result,
-        MaybeStatus, !ModuleInfo, !IO).
-
-:- pred check_goal_for_mm_tabling_2(scc::in, vartypes::in, hlds_goal_expr::in,
-    hlds_goal_info::in, mm_tabling_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
-
-check_goal_for_mm_tabling_2(_, _, Goal, _, mm_tabled_will_not_call,
-        yes(optimal), !ModuleInfo, !IO) :-
-    Goal = unify(_, _, _, Kind, _),
+check_goal_for_mm_tabling(SCC, VarTypes, Goal, Result, MaybeAnalysisStatus,
+        !ModuleInfo, !IO) :-
+    Goal = hlds_goal(GoalExpr, _GoalInfo),
+    (
+        GoalExpr = unify(_, _, _, Kind, _),
+        Result = mm_tabled_will_not_call,
+        MaybeAnalysisStatus = yes(optimal),
     (
-        Kind = complicated_unify(_, _, _),
-        unexpected(this_file, "complicated unify during mm tabling analysis.")
-    ;
         ( Kind = construct(_, _, _, _, _, _, _)
         ; Kind = deconstruct(_, _, _, _, _, _)
         ; Kind = assign(_, _)
         ; Kind = simple_test(_, _)
         )
-    ).
-check_goal_for_mm_tabling_2(SCC, VarTypes, Goal, _, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    Goal = plain_call(CalleePredId, CalleeProcId, CallArgs, _, _, _),
+        ;
+            Kind = complicated_unify(_, _, _),
+            unexpected(this_file,
+                "complicated unify during mm tabling analysis.")
+        )
+    ;
+        GoalExpr = plain_call(CalleePredId, CalleeProcId, CallArgs, _, _, _),
     CalleePPId = proc(CalleePredId, CalleeProcId),
     check_call_for_mm_tabling(CalleePPId, CallArgs, SCC, VarTypes, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO).
-check_goal_for_mm_tabling_2(_, _VarTypes, Goal, _GoalInfo, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    Goal = generic_call(Details, _Args, _ArgModes, _),
-    check_generic_call_for_mm_tabling(Details, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO).
-check_goal_for_mm_tabling_2(SCC, VarTypes, negation(Goal), _, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    check_goal_for_mm_tabling(SCC, VarTypes, Goal, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO).
-check_goal_for_mm_tabling_2(SCC, VarTypes, Goal, _, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    Goal = scope(_, InnerGoal),
-    check_goal_for_mm_tabling(SCC, VarTypes, InnerGoal, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO).
-check_goal_for_mm_tabling_2(_, _, Goal, _, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO) :-
-    Goal = call_foreign_proc(Attributes, _, _, _, _, _, _),
+            MaybeAnalysisStatus, !ModuleInfo, !IO)
+    ;
+        GoalExpr = generic_call(Details, _Args, _ArgModes, _),
+        (
+            % XXX We should use any results from closure analysis here.
+            Details = higher_order(_Var, _, _, _),
+            Result  = mm_tabled_may_call
+        ;
+            Details = class_method(_, _, _, _),
+            Result  = mm_tabled_may_call
+        ;
+            Details = event_call(_),
+            Result = mm_tabled_will_not_call
+        ;
+            Details = cast(_),
+            Result = mm_tabled_will_not_call
+        ),
+        MaybeAnalysisStatus = yes(optimal)
+    ;
+        GoalExpr = call_foreign_proc(Attributes, _, _, _, _, _, _),
     Result = get_mm_tabling_status_from_attributes(Attributes),
-    MaybeAnalysisStatus = yes(optimal).
-check_goal_for_mm_tabling_2(_, _, shorthand(_), _, _, _, !ModuleInfo, !IO) :-
-    unexpected(this_file,
-        "shorthand goal encountered during mm tabling analysis.").
-check_goal_for_mm_tabling_2(SCC, VarTypes, Goal, _,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
+        MaybeAnalysisStatus = yes(optimal)
+    ;
+        ( GoalExpr = negation(SubGoal)
+        ; GoalExpr = scope(_, SubGoal)
+        ),
+        check_goal_for_mm_tabling(SCC, VarTypes, SubGoal, Result,
+            MaybeAnalysisStatus, !ModuleInfo, !IO)
+    ;
     (
-        Goal = conj(_, Goals)
+            GoalExpr = conj(_, Goals)
     ;
-        Goal = disj(Goals)
+            GoalExpr = disj(Goals)
     ;
-        Goal = if_then_else(_, If, Then, Else),
-        Goals = [If, Then, Else]
+            GoalExpr = if_then_else(_, Cond, Then, Else),
+            Goals = [Cond, Then, Else]
     ;
-        Goal = switch(_, _, Cases),
+            GoalExpr = switch(_, _, Cases),
         Goals = list.map((func(case(_, _, CaseGoal)) = CaseGoal), Cases)
     ),
     check_goals_for_mm_tabling(SCC, VarTypes, Goals, Result,
-        MaybeAnalysisStatus, !ModuleInfo, !IO).
+            MaybeAnalysisStatus, !ModuleInfo, !IO)
+    ;
+        GoalExpr = shorthand(_),
+        unexpected(this_file,
+            "shorthand goal encountered during mm tabling analysis.")
+    ).
 
 :- pred check_goals_for_mm_tabling(scc::in, vartypes::in,
     hlds_goals::in, mm_tabling_status::out, maybe(analysis_status)::out,
@@ -390,9 +400,9 @@
     scc::in, vartypes::in, mm_tabling_status::out, maybe(analysis_status)::out,
     module_info::in, module_info::out, io::di, io::uo) is det.
 
-check_call_for_mm_tabling(CalleePPId @ proc(CalleePredId, _),
-        CallArgs, SCC, VarTypes, Result, MaybeAnalysisStatus, !ModuleInfo,
-        !IO) :-
+check_call_for_mm_tabling(CalleePPId, CallArgs, SCC, VarTypes, Result,
+        MaybeAnalysisStatus, !ModuleInfo, !IO) :-
+    CalleePPId = proc(CalleePredId, _),
     module_info_pred_info(!.ModuleInfo, CalleePredId, CalleePredInfo),
     (
         % Handle (mutually-)recursive calls.
@@ -409,9 +419,9 @@
     ;
         % Handle builtin unify and compare.
         %
-        % NOTE: the type specific unify and compare predicates are just
+        % NOTE: The type specific unify and compare predicates are just
         %       treated as though they were normal predicates.
-        %
+
         ModuleName = pred_info_module(CalleePredInfo),
         any_mercury_builtin_module(ModuleName),
         Name = pred_info_name(CalleePredInfo),
@@ -422,7 +432,6 @@
         special_pred_name_arity(SpecialPredId, GenericPredName,
             _TypeSpecificPredName, Arity),
         Name = GenericPredName
-
     ->
         % XXX user-defined uc
         Result = mm_tabled_may_call,
@@ -453,7 +462,6 @@
         ;
             % Otherwise, the information (if we have any) will be in the
             % mm_tabling_info table.
-            %
             check_call_for_mm_tabling_calls(!.ModuleInfo, VarTypes,
                 CalleePPId, CallArgs, MaybeResult),
             (
@@ -478,36 +486,6 @@
 
 %----------------------------------------------------------------------------%
 %
-% Code for checking generic calls
-%
-
-:- pred check_generic_call_for_mm_tabling(generic_call::in,
-    mm_tabling_status::out, maybe(analysis_status)::out, module_info::in,
-    module_info::out, io::di, io::uo) is det.
-
-check_generic_call_for_mm_tabling(Details, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO) :-
-    (
-        % XXX use results of closure analysis here.
-        Details = higher_order(_Var, _, _, _),
-        Result  = mm_tabled_may_call,
-        MaybeAnalysisStatus = yes(optimal)
-    ;
-        Details = class_method(_, _, _, _),
-        Result  = mm_tabled_may_call,
-        MaybeAnalysisStatus = yes(optimal)
-    ;
-        Details = event_call(_),
-        Result = mm_tabled_will_not_call,
-        MaybeAnalysisStatus = yes(optimal)
-    ;
-        Details = cast(_),
-        Result = mm_tabled_will_not_call,
-        MaybeAnalysisStatus = yes(optimal)
-    ).
-
-%----------------------------------------------------------------------------%
-%
 % Utility procedure for processing goals
 %
 
@@ -552,8 +530,7 @@
     mm_tabling_status::in, mm_tabling_status::out) is det.
 
 combine_mm_tabling_status(mm_tabled_will_not_call, Status, Status).
-combine_mm_tabling_status(mm_tabled_may_call, _,
-        mm_tabled_may_call).
+combine_mm_tabling_status(mm_tabled_may_call, _, mm_tabled_may_call).
 combine_mm_tabling_status(mm_tabled_conditional, mm_tabled_will_not_call,
         mm_tabled_conditional).
 combine_mm_tabling_status(mm_tabled_conditional, mm_tabled_conditional,
@@ -619,24 +596,9 @@
     mm_tabling_status::out, module_info::in, module_info::out, io::di, io::uo)
     is det.
 
-annotate_goal_2(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = conj(ConjType, Conjuncts0),
-    annotate_goal_list(VarTypes, Conjuncts0, Conjuncts, Status, !ModuleInfo,
-        !IO),
-    !:Goal = conj(ConjType, Conjuncts).
-annotate_goal_2(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = plain_call(CalleePredId, CalleeProcId, CallArgs, _, _, _),
-    CalleePPId = proc(CalleePredId, CalleeProcId),
-    annotate_call(CalleePPId, CallArgs, VarTypes, Status, !ModuleInfo, !IO).
-annotate_goal_2(_VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = generic_call(Details, _Args, _Modes, _Detism),
-    annotate_generic_call(Details, Status, !ModuleInfo, !IO).
-annotate_goal_2(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = switch(Var, CanFail, Cases0),
-    annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo, !IO),
-    !:Goal = switch(Var, CanFail, Cases).
-annotate_goal_2(_VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = unify(_, _, _, Kind, _),
+annotate_goal_2(VarTypes, !GoalExpr, Status, !ModuleInfo, !IO) :-
+    (
+        !.GoalExpr = unify(_, _, _, Kind, _),
     (
         Kind = complicated_unify(_, _, _),
         unexpected(this_file, "complicated unify during tabling analysis.")
@@ -647,27 +609,51 @@
         ; Kind = simple_test(_, _)
         )
     ),
-    Status = mm_tabled_will_not_call.
-annotate_goal_2(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = disj(Disjuncts0),
-    annotate_goal_list(VarTypes, Disjuncts0, Disjuncts, Status, !ModuleInfo,
-        !IO),
-    !:Goal = disj(Disjuncts).
-annotate_goal_2(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = negation(NegGoal0),
-    annotate_goal(VarTypes, NegGoal0, NegGoal, Status, !ModuleInfo, !IO),
-    !:Goal = negation(NegGoal).
-annotate_goal_2(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = scope(Reason, InnerGoal0),
-    annotate_goal(VarTypes, InnerGoal0, InnerGoal, Status, !ModuleInfo, !IO),
-    !:Goal = scope(Reason, InnerGoal).
-annotate_goal_2(VarTypes, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = if_then_else(Vars, If0, Then0, Else0),
-    annotate_goal(VarTypes, If0, If, IfStatus, !ModuleInfo, !IO),
+        Status = mm_tabled_will_not_call
+    ;
+        !.GoalExpr = plain_call(CalleePredId, CalleeProcId, CallArgs, _, _, _),
+        CalleePPId = proc(CalleePredId, CalleeProcId),
+        annotate_call(CalleePPId, CallArgs, VarTypes, Status, !ModuleInfo, !IO)
+    ;
+        !.GoalExpr = call_foreign_proc(Attributes, _, _, _, _, _, _),
+        Status = get_mm_tabling_status_from_attributes(Attributes)
+    ;
+        !.GoalExpr = generic_call(GenericCall, _Args, _Modes, _Detism),
+        (
+            % XXX We should use any results from closure analysis here.
+            GenericCall = higher_order(_Var, _, _, _),
+            Status = mm_tabled_may_call
+        ;
+            GenericCall = class_method(_, _, _, _),
+            Status = mm_tabled_may_call
+        ;
+            GenericCall = event_call(_),
+            Status = mm_tabled_will_not_call
+        ;
+            GenericCall = cast(_),
+            Status = mm_tabled_will_not_call
+        )
+    ;
+        !.GoalExpr = conj(ConjType, Conjuncts0),
+        annotate_goal_list(VarTypes, Conjuncts0, Conjuncts, Status,
+            !ModuleInfo, !IO),
+        !:GoalExpr = conj(ConjType, Conjuncts)
+    ;
+        !.GoalExpr = disj(Disjuncts0),
+        annotate_goal_list(VarTypes, Disjuncts0, Disjuncts, Status,
+            !ModuleInfo, !IO),
+        !:GoalExpr = disj(Disjuncts)
+    ;
+        !.GoalExpr = switch(Var, CanFail, Cases0),
+        annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo, !IO),
+        !:GoalExpr = switch(Var, CanFail, Cases)
+    ;
+        !.GoalExpr = if_then_else(Vars, Cond0, Then0, Else0),
+        annotate_goal(VarTypes, Cond0, Cond, CondStatus, !ModuleInfo, !IO),
     annotate_goal(VarTypes, Then0, Then, ThenStatus, !ModuleInfo, !IO),
     annotate_goal(VarTypes, Else0, Else, ElseStatus, !ModuleInfo, !IO),
     (
-        IfStatus   = mm_tabled_will_not_call,
+            CondStatus = mm_tabled_will_not_call,
         ThenStatus = mm_tabled_will_not_call,
         ElseStatus = mm_tabled_will_not_call
     ->
@@ -675,20 +661,27 @@
     ;
         Status = mm_tabled_may_call
     ),
-    !:Goal = if_then_else(Vars, If, Then, Else).
-annotate_goal_2(_, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = call_foreign_proc(Attributes, _, _, _, _, _, _),
-    Status = get_mm_tabling_status_from_attributes(Attributes).
-annotate_goal_2(_, shorthand(_), _, _, _, _, _, _) :-
-    unexpected(this_file, "shorthand goal").
+        !:GoalExpr = if_then_else(Vars, Cond, Then, Else)
+    ;
+        !.GoalExpr = negation(SubGoal0),
+        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo, !IO),
+        !:GoalExpr = negation(SubGoal)
+    ;
+        !.GoalExpr = scope(Reason, SubGoal0),
+        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo, !IO),
+        !:GoalExpr = scope(Reason, SubGoal)
+    ;
+        !.GoalExpr = shorthand(_),
+        unexpected(this_file, "shorthand goal")
+    ).
 
 :- pred annotate_goal_list(vartypes::in, hlds_goals::in, hlds_goals::out,
     mm_tabling_status::out, module_info::in, module_info::out, io::di, io::uo)
     is det.
 
 annotate_goal_list(VarTypes, !Goals, Status, !ModuleInfo, !IO) :-
-    list.map2_foldl2(annotate_goal(VarTypes), !Goals, Statuses, !ModuleInfo,
-        !IO),
+    list.map2_foldl2(annotate_goal(VarTypes), !Goals, Statuses,
+        !ModuleInfo, !IO),
     list.foldl(combine_mm_tabling_status, Statuses, mm_tabled_will_not_call,
         Status).
 
@@ -715,8 +708,8 @@
     mm_tabling_status::out, module_info::in, module_info::out, io::di, io::uo)
     is det.
 
-annotate_call(CalleePPId @ proc(CalleePredId, _), CallArgs, VarTypes, Status,
-        !ModuleInfo, !IO) :-
+annotate_call(CalleePPId, CallArgs, VarTypes, Status, !ModuleInfo, !IO) :-
+    CalleePPId = proc(CalleePredId, _),
     module_info_pred_info(!.ModuleInfo, CalleePredId, CalleePredInfo),
     (
         pred_info_is_builtin(CalleePredInfo)
@@ -751,7 +744,6 @@
             SCC = [],
             search_analysis_status(CalleePPId, Result, AnalysisStatus, SCC,
                 !ModuleInfo, !IO),
-
             (
                 AnalysisStatus = invalid,
                 unexpected(this_file,
@@ -784,25 +776,6 @@
         )
     ).
 
-:- pred annotate_generic_call(generic_call::in, mm_tabling_status::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
-
-annotate_generic_call(GenericCall, Status, !ModuleInfo, !IO) :-
-    (
-        % XXX use results of closure analysis here.
-        GenericCall = higher_order(_Var, _, _, _),
-        Status = mm_tabled_may_call
-    ;
-        GenericCall = class_method(_, _, _, _),
-        Status = mm_tabled_may_call
-    ;
-        GenericCall = event_call(_),
-        Status = mm_tabled_will_not_call
-    ;
-        GenericCall = cast(_),
-        Status = mm_tabled_will_not_call
-    ).
-
 %----------------------------------------------------------------------------%
 %
 % Stuff for intermodule optimization
Index: compiler/term_constr_build.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_build.m,v
retrieving revision 1.19
diff -u -b -r1.19 term_constr_build.m
--- compiler/term_constr_build.m	30 Dec 2007 08:23:59 -0000	1.19
+++ compiler/term_constr_build.m	5 Jan 2008 09:34:10 -0000
@@ -62,6 +62,7 @@
 :- import_module check_hlds.type_util.
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_out.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.lp_rational.
@@ -94,16 +95,14 @@
 
 :- type build_options
     --->    build_options(
-            functor_info    :: functor_info,
                                     % Which norm we are using.
+                bo_functor_info     :: functor_info,
 
-            failure_constrs :: bool,
-                                    % Whether we are propagating failure
-                                    % constraints is enabled.
-
-            arg_size_only   :: bool
-                                    % Whether the `--term2-arg-size-only'
-                                    % is enabled.
+                % Whether propagating failure constraints is enabled.
+                bo_failure_constrs  :: bool,
+
+                % Whether `--term2-arg-size-only' is enabled.
+                bo_arg_size_only    :: bool
     ).
 
 build_options_init(Norm, Failure, ArgSizeOnly) =
@@ -119,52 +118,50 @@
 
 :- type scc_info
     ---> scc_info(
-            scc_ppid       :: pred_proc_id,
-            proc           :: abstract_proc,
-            size_var_map   :: size_var_map,
-            intermod       :: intermod_status,
-            accum_errors   :: term2_errors,
-            non_zero_heads :: list(size_var)
+                si_scc_ppid         :: pred_proc_id,
+                si_proc             :: abstract_proc,
+                si_size_var_map     :: size_var_map,
+                si_intermod         :: intermod_status,
+                si_accum_errors     :: term2_errors,
+                si_non_zero_heads   :: list(size_var)
     ).
 
 %-----------------------------------------------------------------------------%
 
 build_abstract_scc(DepOrder, SCC, Options, Errors, !Module, !IO) :-
-    dependency_graph.get_scc_entry_points(SCC, DepOrder, !.Module,
-        EntryProcs),
+    dependency_graph.get_scc_entry_points(SCC, DepOrder, !.Module, EntryProcs),
     list.foldl3(build_abstract_proc(EntryProcs, Options, SCC, !.Module),
-        SCC, varset.init, Varset, [], AbstractSCC, !IO),
+        SCC, varset.init, SizeVarset, [], AbstractSCC, !IO),
     module_info_preds(!.Module, PredTable0),
     RecordInfo = (pred(Info::in, !.Errors::in, !:Errors::out,
             !.PredTable::in, !:PredTable::out) is det :-
         Info = scc_info(proc(PredId, ProcId), AR0, VarMap, Status,
             ProcErrors, HeadSizeVars),
-        %
+
         % Record the proper size_varset.  Each procedure has a copy.
         % XXX It would be nicer to store one copy per SCC.
         %
         % NOTE: although each procedure in the a SCC shares the same
         % size_varset, they should all have separate size_var_maps.
-        %
-        AR = AR0 ^ varset := Varset,
-        PredInfo0 = !.PredTable ^ det_elem(PredId),
+
+        AR = AR0 ^ ap_size_varset := SizeVarset,
+        map.lookup(!.PredTable, PredId, PredInfo0),
         pred_info_get_procedures(PredInfo0, ProcTable0),
-        ProcInfo0 = ProcTable0 ^ det_elem(ProcId),
+        map.lookup(ProcTable0, ProcId, ProcInfo0),
         some [!TermInfo] (
             proc_info_get_termination2_info(ProcInfo0, !:TermInfo),
             !:TermInfo = !.TermInfo ^ intermod_status := yes(Status),
             !:TermInfo = !.TermInfo ^ abstract_rep    := yes(AR),
             !:TermInfo = !.TermInfo ^ size_var_map    := VarMap,
             !:TermInfo = !.TermInfo ^ head_vars       := HeadSizeVars,
-            %
+
             % If the remainder of the analysis is going to depend upon
-            % higher order constructs then set up the information accordingly.
-            %
+            % higher order constructs, then set up the information accordingly.
             ( analysis_depends_on_ho(AR) ->
                 !:TermInfo = !.TermInfo ^ success_constrs :=
                     yes(polyhedron.universe),
                 HorderErrors = list.map((func(ho_call(Context))
-                    = Context - horder_call), AR ^ ho),
+                    = Context - horder_call), AR ^ ap_ho_calls),
                 list.append(HorderErrors, !Errors)
             ;
                 true
@@ -187,11 +184,13 @@
 
 build_abstract_proc(EntryProcs, Options, SCC, Module, PPId, !SizeVarset,
         !AbstractInfo, !IO) :-
-% XXX For debugging ...
-%   io.write_string("Building procedure: ", !IO),
-%   hlds_out.write_pred_proc_id(Module, PPId, !IO),
-%   io.nl(!IO),
-%   io.flush_output(!IO),
+    trace [io(!DebugIO), compiletime(flag("term_constr_build"))] (
+        io.write_string("Building procedure: ", !DebugIO),
+        hlds_out.write_pred_proc_id(Module, PPId, !DebugIO),
+        io.nl(!DebugIO),
+        io.flush_output(!DebugIO)
+    ),
+
     module_info_pred_proc_info(Module, PPId, PredInfo, ProcInfo),
     pred_info_get_context(PredInfo, Context),
     proc_info_get_vartypes(ProcInfo, VarTypes),
@@ -204,30 +203,25 @@
     % itself. We therefore analyse only the non-pretest parts of such goals.
     Goal = maybe_strip_equality_pretest(Goal0),
 
-    %
     % Allocate one size_var for each real var. in the procedure.
     % Work out which variables have zero size.
-    %
     allocate_sizevars(HeadProgVars, Goal, SizeVarMap, !SizeVarset),
     Zeros = find_zero_size_vars(Module, SizeVarMap, VarTypes),
-    Info0 = init_traversal_info(Module, Options ^ functor_info, PPId,
+    Info0 = init_traversal_info(Module, Options ^ bo_functor_info, PPId,
         Context, VarTypes, Zeros, SizeVarMap, SCC,
-        Options ^ failure_constrs, Options ^ arg_size_only ),
-    %
+        Options ^ bo_failure_constrs, Options ^ bo_arg_size_only ),
+
     % Traverse the HLDS and construct the abstract version of
     % this procedure.
-    %
     build_abstract_goal(Goal, AbstractBody0, Info0, Info),
-    IntermodStatus = Info ^ intermod_status,
+    IntermodStatus = Info ^ tti_intermod_status,
     HeadSizeVars   = prog_vars_to_size_vars(SizeVarMap, HeadProgVars),
     AbstractBody   = simplify_abstract_rep(AbstractBody0),
-    %
+
     % Work out which arguments can be used in termination proofs.
-    % An argument may be used if (a) it is input and (b) it has
-    % non-zero size.
-    %
+    % An argument may be used if (a) it is input and (b) it has non-zero size.
     ChooseArg = (func(Var, Mode) = UseArg :-
-        Type = VarTypes ^ det_elem(Var),
+        map.lookup(VarTypes, Var, Type),
         (
             not zero_size_type(Module, Type),
             mode_util.mode_is_input(Module, Mode)
@@ -237,26 +231,25 @@
             UseArg = no
         )
     ),
-    Inputs = list.map_corresponding(ChooseArg, HeadProgVars,
-        ArgModes0),
-    %
+    Inputs = list.map_corresponding(ChooseArg, HeadProgVars, ArgModes0),
+
     % The size_varset for this procedure is set to rubbish here.
-    % When we complete building this SCC we will set it to
-    % the correct value.
-    %
+    % When we complete building this SCC we will set it to the correct value.
     IsEntryPoint = (list.member(PPId, EntryProcs) -> yes ; no),
-    AbstractProc = abstract_proc(real(PPId), Context, Info ^ recursion,
-        SizeVarMap, HeadSizeVars, Inputs, Zeros, AbstractBody,
-        Info ^ maxcalls, !.SizeVarset, Info ^ ho_info, IsEntryPoint),
+    AbstractProc = abstract_proc(real(PPId), IsEntryPoint, Context,
+        HeadSizeVars, Inputs, AbstractBody, SizeVarMap, !.SizeVarset, Zeros,
+        Info ^ tti_recursion, Info ^ tti_maxcalls, Info ^ tti_ho_info),
 
     ThisProcInfo = scc_info(PPId, AbstractProc, SizeVarMap, IntermodStatus,
-        Info ^ errors, HeadSizeVars),
+        Info ^ tti_errors, HeadSizeVars),
 
-    list.cons(ThisProcInfo, !AbstractInfo).
-% XXX For debugging ...
-%   io.write_string("Abstract proc is:\n", !IO),
-%   dump_abstract_proc(AbstractProc, 0, Module, !IO),
-%   io.nl(!IO).
+    list.cons(ThisProcInfo, !AbstractInfo),
+
+    trace [io(!DebugIO), compiletime(flag("term_constr_build"))] (
+        io.write_string("Abstract proc is:\n", !DebugIO),
+        dump_abstract_proc(AbstractProc, 0, Module, !DebugIO),
+        io.nl(!DebugIO)
+    ).
 
 %------------------------------------------------------------------------------%
 %
@@ -277,57 +270,57 @@
 
 :- type traversal_info
     ---> traversal_info(
-            recursion :: recursion_type,
-                % What type of recursion is present
-                % in the procedure. ie. `none', `direct', `mutual'.
-
-            intermod_status :: intermod_status,
-                % Record whether this procedure is potentially
-                % involved in mutual recursion across module boundaries.
+                % What type of recursion is present in the procedure,
+                % i.e. `none', `direct', `mutual'.
+                tti_recursion                   :: recursion_type,
+
+                % Record whether this procedure is potentially involved
+                % in mutual recursion across module boundaries.
+                tti_intermod_status             :: intermod_status,
 
-            errors :: term2_errors,
                 % Errors encountered while building the AR.
+                tti_errors                      :: term2_errors,
 
-            module_info :: module_info,
                 % The HLDS.
+                tti_module_info                 :: module_info,
 
-            norm :: functor_info,
                 % The norm we are using.
+                tti_norm                        :: functor_info,
 
-            ppid :: pred_proc_id,
                 % The procedure we are currently processing.
+                tti_ppid                        :: pred_proc_id,
 
-            context :: term.context,
                 % The context of the current procedure.
+                tti_context                     :: term.context,
 
-            types :: vartypes,
                 % Types for all prog_vars in the current procedure.
+                tti_vartypes                    :: vartypes,
 
-            zeros :: set(size_var),
-                % size_vars in the current procedure that
-                % are known to have zero size.
+                % size_vars in the current procedure that are known
+                % to have zero size.
+                tti_zeros                       :: set(size_var),
 
-            var_map :: size_var_map,
                 % Map from prog_vars to size_vars.
+                tti_size_var_map                :: size_var_map,
 
-            scc :: list(pred_proc_id),
-                % The procedures in the same SCC of the call
-                % graph as the one we are current traversing.
+                % The procedures in the SCC of the call graph
+                % we are current traversing.
+                tti_scc                         :: list(pred_proc_id),
 
-            maxcalls :: int,
                 % The number of calls in the procedure.
+                tti_maxcalls                    :: int,
 
-            find_fail_constrs :: bool,
                 % If no then do not bother looking for failure constraints.
                 % The `--no-term2-propagate-failure-constraints' options.
+                tti_find_fail_constrs           :: bool,
 
-            ho_info :: list(abstract_ho_call),
                 % Information about any higher-order calls a procedure makes.
                 % XXX Currently unused.
+                tti_ho_info                     :: list(abstract_ho_call),
 
-            arg_analysis_only :: bool
                 % Do we only want to run IR analysis?
                 % The `--term2-arg-size-analysis-only' option.
+                tti_arg_analysis_only           :: bool
         ).
 
 :- func init_traversal_info(module_info, functor_info, pred_proc_id,
@@ -340,35 +333,36 @@
         PPId, Context, Types, Zeros, VarMap, SCC, 0, FailConstrs, [],
         ArgSizeOnly).
 
-:- pred info_increment_maxcalls(traversal_info::in, traversal_info::out) is det.
+:- pred info_increment_maxcalls(traversal_info::in, traversal_info::out)
+    is det.
 
 info_increment_maxcalls(!Info) :-
-    !:Info = !.Info ^ maxcalls := !.Info ^ maxcalls + 1.
+    !:Info = !.Info ^ tti_maxcalls := !.Info ^ tti_maxcalls + 1.
 
 :- pred info_update_errors(term_constr_errors.error::in, traversal_info::in,
     traversal_info::out) is det.
 
 info_update_errors(Error, !Info) :-
-    !:Info = !.Info ^ errors := [Error | !.Info ^ errors].
+    !:Info = !.Info ^ tti_errors := [Error | !.Info ^ tti_errors].
 
-:- pred info_update_recursion(recursion_type::in, traversal_info::in,
-    traversal_info::out) is det.
+:- pred info_update_recursion(recursion_type::in,
+    traversal_info::in, traversal_info::out) is det.
 
 info_update_recursion(RecType, !Info) :-
-    UpdatedRecType = combine_recursion_types(!.Info ^ recursion, RecType),
-    !:Info = !.Info ^ recursion := UpdatedRecType.
+    UpdatedRecType = combine_recursion_types(!.Info ^ tti_recursion, RecType),
+    !:Info = !.Info ^ tti_recursion := UpdatedRecType.
 
-:- pred info_update_ho_info(context::in, traversal_info::in,
-    traversal_info::out) is det.
+:- pred info_update_ho_info(context::in,
+    traversal_info::in, traversal_info::out) is det.
 
 info_update_ho_info(Context, !Info) :-
-    !:Info = !.Info ^ ho_info := [ho_call(Context) | !.Info ^ ho_info].
+    !:Info = !.Info ^ tti_ho_info := [ho_call(Context) | !.Info ^ tti_ho_info].
 
-:- pred set_intermod_status(intermod_status::in, traversal_info::in,
-    traversal_info::out) is det.
+:- pred set_intermod_status(intermod_status::in,
+    traversal_info::in, traversal_info::out) is det.
 
 set_intermod_status(Status, !TraversalInfo) :-
-    !:TraversalInfo = !.TraversalInfo ^ intermod_status := Status.
+    !:TraversalInfo = !.TraversalInfo ^ tti_intermod_status := Status.
 
 %------------------------------------------------------------------------------%
 %
@@ -386,9 +380,9 @@
     Goal = hlds_goal(GoalExpr, GoalInfo),
     build_abstract_goal_2(GoalExpr, GoalInfo, AbstractGoal0, !Info),
     partition_vars(Goal, Locals0, NonLocals0),
-    VarMap = !.Info ^ var_map,
-    Locals = prog_vars_to_size_vars(VarMap, Locals0),
-    NonLocals = prog_vars_to_size_vars(VarMap, NonLocals0),
+    SizeVarMap = !.Info ^ tti_size_var_map,
+    Locals = prog_vars_to_size_vars(SizeVarMap, Locals0),
+    NonLocals = prog_vars_to_size_vars(SizeVarMap, NonLocals0),
     AbstractGoal = update_local_and_nonlocal_vars(AbstractGoal0,
         Locals, NonLocals).
 
@@ -409,20 +403,17 @@
 
 build_abstract_goal_2(GoalExpr, _, AbstractGoal, !Info) :-
     GoalExpr = if_then_else(_, Cond, Then, Else),
-    %
+
     % Reduce the if-then goals to an abstract conjunction.
-    %
     build_abstract_conj([Cond, Then], AbstractSuccessGoal, !Info),
-    %
+
     % Work out a failure constraint for the Cond and then abstract the else
     % branch.  We won't bother do any other simplifications here as the AR
     % simplification pass will sort all of this out.
-    %
     CondFail = find_failure_constraint_for_goal(Cond, !.Info),
-    %
+
     % XXX FIXME - the local/non-local variable sets end up
     % being incorrect here.
-    %
     build_abstract_goal(Else, AbstractElse, !Info),
     AbstractFailureGoal = term_conj([CondFail, AbstractElse], [], []),
     AbstractDisjuncts = [AbstractSuccessGoal, AbstractFailureGoal],
@@ -433,7 +424,7 @@
 
 build_abstract_goal_2(GoalExpr, GoalInfo, AbstractGoal, !Info) :-
     GoalExpr = plain_call(CallPredId, CallProcId, CallArgs, _, _, _),
-    CallSizeArgs = prog_vars_to_size_vars(!.Info ^ var_map, CallArgs),
+    CallSizeArgs = prog_vars_to_size_vars(!.Info ^ tti_size_var_map, CallArgs),
     build_abstract_call(proc(CallPredId, CallProcId), CallSizeArgs,
         GoalInfo, AbstractGoal, !Info).
 
@@ -442,17 +433,14 @@
     build_abstract_unification(Unification, AbstractGoal, !Info).
 
 build_abstract_goal_2(negation(Goal), _GoalInfo, AbstractGoal, !Info) :-
-    %
-    % Event though a negated goal cannot have any output we still
-    % need to check it for calls to non-terminating procedures.
-    %
+    % Event though a negated goal cannot have any output we still need
+    % to check it for calls to non-terminating procedures.
     build_abstract_goal(Goal, _, !Info),
-    %
+
     % Find a failure constraint for the goal if
     % `--term2-propagate-failure-constraints' is enabled,
     % otherwise just use the constraint that all non-zero input vars
     % should be non-negative.
-    %
     AbstractGoal = find_failure_constraint_for_goal(Goal, !.Info).
 
     % XXX Eventually we should provide some facility for specifying the
@@ -460,14 +448,13 @@
     %
 build_abstract_goal_2(GoalExpr, GoalInfo, AbstractGoal, !Info) :-
     GoalExpr = call_foreign_proc(Attrs, PredId, ProcId, Args, ExtraArgs, _, _),
-    %
+
     % Create non-negativity constraints for each non-zero argument
     % in the foreign proc.
-    %
     ForeignArgToVar = (func(ForeignArg) = ForeignArg ^ arg_var),
     ProgVars = list.map(ForeignArgToVar, Args ++ ExtraArgs),
-    SizeVars = prog_vars_to_size_vars(!.Info ^ var_map, ProgVars),
-    Constraints = make_arg_constraints(SizeVars, !.Info ^ zeros),
+    SizeVars = prog_vars_to_size_vars(!.Info ^ tti_size_var_map, ProgVars),
+    Constraints = make_arg_constraints(SizeVars, !.Info ^ tti_zeros),
     (
         (
             get_terminates(Attrs) = proc_terminates
@@ -527,11 +514,12 @@
 
 build_abstract_call(CalleePPId, CallerArgs, GoalInfo, AbstractGoal, !Info) :-
     Context = goal_info_get_context(GoalInfo),
-    ( if    list.member(CalleePPId, !.Info ^ scc)
-      then  build_recursive_call(CalleePPId, CallerArgs, Context,
-            AbstractGoal, !Info)
-      else  build_non_recursive_call(CalleePPId, CallerArgs, Context,
-            AbstractGoal, !Info)
+    ( list.member(CalleePPId, !.Info ^ tti_scc) ->
+        build_recursive_call(CalleePPId, CallerArgs, Context, AbstractGoal,
+            !Info)
+    ;
+        build_non_recursive_call(CalleePPId, CallerArgs, Context, AbstractGoal,
+            !Info)
     ).
 
     % If the call is potentially recursive, we construct an abstract call
@@ -541,11 +529,12 @@
     abstract_goal::out, traversal_info::in, traversal_info::out) is det.
 
 build_recursive_call(CalleePPId, CallerArgs, Context, AbstractGoal, !Info) :-
-    CallerPPId = !.Info ^ ppid,
-    CallerZeros = !.Info ^ zeros,
-    ( if    CallerPPId = CalleePPId
-      then  info_update_recursion(direct_only, !Info)
-      else  info_update_recursion(mutual_only, !Info)
+    CallerPPId = !.Info ^ tti_ppid,
+    CallerZeros = !.Info ^ tti_zeros,
+    ( CallerPPId = CalleePPId ->
+        info_update_recursion(direct_only, !Info)
+    ;
+        info_update_recursion(mutual_only, !Info)
     ),
     CallerArgConstrs = make_arg_constraints(CallerArgs, CallerZeros),
     CallerArgPoly = polyhedron.from_constraints(CallerArgConstrs),
@@ -566,16 +555,15 @@
 
 build_non_recursive_call(CalleePPId, CallerArgs, Context, AbstractGoal,
         !Info) :-
-    ModuleInfo = !.Info ^ module_info,
-    CallerPPId = !.Info ^ ppid,
-    ZeroVars = !.Info ^ zeros,
+    ModuleInfo = !.Info ^ tti_module_info,
+    CallerPPId = !.Info ^ tti_ppid,
+    ZeroVars = !.Info ^ tti_zeros,
     module_info_pred_proc_info(ModuleInfo, CalleePPId, _, CalleeProcInfo),
-    %
+
     % Check the termination status of the callee procedure if we are running a
     % full analysis - ignore it if we are only running the IR analysis.
-    %
     proc_info_get_termination2_info(CalleeProcInfo, CalleeTerm2Info),
-    ArgAnalysisOnly = !.Info ^ arg_analysis_only,
+    ArgAnalysisOnly = !.Info ^ tti_arg_analysis_only,
     (
         ArgAnalysisOnly = no,
         MaybeTermStatus = CalleeTerm2Info ^ term_status,
@@ -583,23 +571,21 @@
             MaybeTermStatus = yes(TermStatus),
             (
                 TermStatus = can_loop(_),
-                Error = Context - can_loop_proc_called(CallerPPId,
-                    CalleePPId),
+                Error = Context - can_loop_proc_called(CallerPPId, CalleePPId),
                 info_update_errors(Error, !Info)
             ;
                 TermStatus = cannot_loop(_)
             )
         ;
             MaybeTermStatus = no,
-            unexpected(this_file, "Callee procedure has no " ++
-                "termination status.")
+            unexpected(this_file,
+                "Callee procedure has no termination status.")
         )
     ;
         ArgAnalysisOnly = yes
     ),
-    %
+
     % Check the arg_size_info for the procedure being called.
-    %
     ArgSizeInfo = CalleeTerm2Info ^ success_constrs,
     (
         ArgSizeInfo = no,
@@ -650,8 +636,7 @@
         build_abstract_disj_acc(Goals, [], AbstractGoals, !Info)
     ;
         Type = switch(SwitchVar, Cases),
-        build_abstract_switch_acc(SwitchVar, Cases, [], AbstractGoals,
-            !Info)
+        build_abstract_switch_acc(SwitchVar, Cases, [], AbstractGoals, !Info)
     ),
     (
         AbstractGoals = [],
@@ -708,22 +693,23 @@
     ->
         AbstractGoal = AbstractGoal0
     ;
-        TypeMap = !.Info ^ types,
-        SizeVarMap  = !.Info ^ var_map,
-        SwitchVarType = TypeMap ^ det_elem(SwitchProgVar),
+        TypeMap = !.Info ^ tti_vartypes,
+        SizeVarMap  = !.Info ^ tti_size_var_map,
+        map.lookup(TypeMap, SwitchProgVar, SwitchVarType),
         SwitchSizeVar = prog_var_to_size_var(SizeVarMap, SwitchProgVar),
         type_to_ctor_and_args_det(SwitchVarType, TypeCtor, _),
-        Size = functor_lower_bound(!.Info ^ norm, TypeCtor, MainConsId,
-            !.Info ^ module_info),
-        ( set.member(SwitchSizeVar, !.Info ^ zeros) ->
+        Size = functor_lower_bound(!.Info ^ tti_norm, TypeCtor, MainConsId,
+            !.Info ^ tti_module_info),
+        ( set.member(SwitchSizeVar, !.Info ^ tti_zeros) ->
             ExtraConstr = []
         ;
             SwitchVarConst = rat(Size),
-            SwitchVarConstr =
                 ( Size = 0 ->
+                SwitchVarConstr =
                     make_var_const_eq_constraint(SwitchSizeVar,
                         SwitchVarConst)
                 ;
+                SwitchVarConstr =
                     make_var_const_gte_constraint(SwitchSizeVar,
                         SwitchVarConst)
                 ),
@@ -764,27 +750,28 @@
     traversal_info::in, traversal_info::out) is det.
 
 build_abstract_unification(Unification, AbstractGoal, !Info) :-
+    (
     Unification = construct(Var, ConsId, ArgVars, Modes, _, _, _),
     build_abstract_decon_or_con_unify(Var, ConsId, ArgVars, Modes,
         Constraints, !Info),
-    AbstractGoal = build_goal_from_unify(Constraints).
-
-build_abstract_unification(Unification, AbstractGoal, !Info) :-
+        AbstractGoal = build_goal_from_unify(Constraints)
+    ;
     Unification = deconstruct(Var, ConsId, ArgVars, Modes, _, _),
     build_abstract_decon_or_con_unify(Var, ConsId, ArgVars, Modes,
         Constraints, !Info),
-    AbstractGoal = build_goal_from_unify(Constraints).
-
-build_abstract_unification(assign(LVar, RVar), AbstractGoal, !Info) :-
+        AbstractGoal = build_goal_from_unify(Constraints)
+    ;
+        Unification = assign(LVar, RVar),
     build_abstract_simple_or_assign_unify(LVar, RVar, Constraints, !Info),
-    AbstractGoal = build_goal_from_unify(Constraints).
-
-build_abstract_unification(simple_test(LVar, RVar), AbstractGoal, !Info) :-
+        AbstractGoal = build_goal_from_unify(Constraints)
+    ;
+        Unification = simple_test(LVar, RVar),
     build_abstract_simple_or_assign_unify(LVar, RVar, Constraints, !Info),
-    AbstractGoal = build_goal_from_unify(Constraints).
-
-build_abstract_unification(complicated_unify(_, _, _), _, _, _) :-
-    unexpected(this_file, "complicated_unify/3 in termination analysis.").
+        AbstractGoal = build_goal_from_unify(Constraints)
+    ;
+        Unification = complicated_unify(_, _, _),
+        unexpected(this_file, "complicated_unify/3 in termination analysis.")
+    ).
 
     % Used for deconstruction and construction unifications.  e.g. for a
     % unification of the form: X = f(U, V, W), if the norm counts the
@@ -797,45 +784,46 @@
 
 build_abstract_decon_or_con_unify(Var, ConsId, ArgVars, Modes, Constraints,
         !Info) :-
-    VarTypes = !.Info ^ types,
-    Type = VarTypes ^ det_elem(Var),
+    VarTypes = !.Info ^ tti_vartypes,
+    map.lookup(VarTypes, Var, Type),
     (
         not type_is_higher_order(Type),
         type_to_ctor_and_args(Type, TypeCtor, _)
     ->
-        Norm   = !.Info ^ norm,
-        ModuleInfo = !.Info ^ module_info,
-        Zeros  = !.Info ^ zeros,
-        %
+        Norm   = !.Info ^ tti_norm,
+        ModuleInfo = !.Info ^ tti_module_info,
+        Zeros  = !.Info ^ tti_zeros,
+
         % We need to strip out any typeinfo related variables before
         % measuring the size of the term; otherwise functor_norm will
         % raise a software error if we are using the `num-data-elems'
         % norm and the term has existential typeclass constraints.
-        %
+
         strip_typeinfos_from_args_and_modes(VarTypes, ArgVars, FixedArgs,
             Modes, FixedModes),
 
         functor_norm(Norm, TypeCtor, ConsId, ModuleInfo, Constant,
             FixedArgs, CountedVars, FixedModes, _),
-        %
+
         % The constraint from this unification is:
         %
         %      |Var| = Constant + sum(CountedVars)
         %
         % |Var| is just the size_var corresponding to Var.  The
         % value of `Constant' will depend upon the norm being used.
-        %
-        SizeVar = prog_var_to_size_var(!.Info ^ var_map, Var),
-        ( if    set.member(SizeVar, Zeros)
-          then  FirstTerm = []
-          else  FirstTerm = [SizeVar - one]
+
+        SizeVar = prog_var_to_size_var(!.Info ^ tti_size_var_map, Var),
+        ( set.member(SizeVar, Zeros) ->
+            FirstTerm = []
+        ;
+            FirstTerm = [SizeVar - one]
         ),
         AddTerms = (func(Var1, Terms0) = Terms1 :-
-            SizeVar1 = prog_var_to_size_var(
-                !.Info ^ var_map, Var1),
-            ( if    set.member(SizeVar1, Zeros)
-              then  Terms1 = Terms0
-              else  Terms1 = [SizeVar1 - (-one) | Terms0]
+            SizeVar1 = prog_var_to_size_var(!.Info ^ tti_size_var_map, Var1),
+            ( set.member(SizeVar1, Zeros) ->
+                Terms1 = Terms0
+            ;
+                Terms1 = [SizeVar1 - (-one) | Terms0]
             )
         ),
         Terms = list.foldl(AddTerms, CountedVars, FirstTerm),
@@ -843,10 +831,10 @@
         ( is_false(Constraint) ->
             unexpected(this_file, "false constraint from unification.")
         ;
-            SizeVars0 = prog_vars_to_size_vars(!.Info ^ var_map,
+            SizeVars0 = prog_vars_to_size_vars(!.Info ^ tti_size_var_map,
                 ArgVars),
             SizeVars1 = [SizeVar | SizeVars0],
-            SizeVars  = list.filter(isnt(is_zero_size_var(!.Info ^ zeros)),
+            SizeVars  = list.filter(isnt(is_zero_size_var(!.Info ^ tti_zeros)),
                 SizeVars1)
         ),
         NonNegConstraints = list.map(make_nonneg_constr, SizeVars),
@@ -865,8 +853,8 @@
     ( strip_typeinfos_from_args_and_modes_2(VarTypes, !Args, !Modes) ->
         true
     ;
-        unexpected(this_file, "unequal length lists in " ++
-           "strip_type_infso_and_modes/5")
+        unexpected(this_file,
+            "unequal length lists in strip_type_infso_and_modes/5")
     ).
 
 :- pred strip_typeinfos_from_args_and_modes_2(vartypes::in,
@@ -874,10 +862,10 @@
     list(uni_mode)::in, list(uni_mode)::out) is semidet.
 
 strip_typeinfos_from_args_and_modes_2(_, [], [], [], []).
-strip_typeinfos_from_args_and_modes_2(VarTypes, [ Arg | !.Args ], !:Args,
-        [ Mode | !.Modes ], !:Modes) :-
+strip_typeinfos_from_args_and_modes_2(VarTypes, [Arg | !.Args], !:Args,
+        [Mode | !.Modes], !:Modes) :-
     strip_typeinfos_from_args_and_modes_2(VarTypes, !Args, !Modes),
-    Type = VarTypes ^ det_elem(Arg),
+    map.lookup(VarTypes, Arg, Type),
     ( is_introduced_type_info_type(Type) ->
         true
     ;
@@ -891,10 +879,10 @@
 :- pred build_abstract_simple_or_assign_unify(prog_var::in, prog_var::in,
     constraints::out, traversal_info::in, traversal_info::out) is det.
 
-build_abstract_simple_or_assign_unify(LeftProgVar, RightProgVar,
-        Constraints, !Info) :-
-    SizeVarMap = !.Info ^ var_map,
-    Zeros = !.Info ^ zeros,
+build_abstract_simple_or_assign_unify(LeftProgVar, RightProgVar, Constraints,
+        !Info) :-
+    SizeVarMap = !.Info ^ tti_size_var_map,
+    Zeros = !.Info ^ tti_zeros,
     LeftSizeVar = prog_var_to_size_var(SizeVarMap, LeftProgVar),
     RightSizeVar = prog_var_to_size_var(SizeVarMap, RightProgVar),
     (
@@ -904,12 +892,12 @@
         Constraints = []    % `true' constraint.
     ;
         (set.member(LeftSizeVar, Zeros)
-        ; set.member(RightSizeVar, Zeros))
+        ; set.member(RightSizeVar, Zeros)
+        )
     ->
         unexpected(this_file, "zero unified with non-zero.")
     ;
         % Create non-negativity constraints.
-        %
         NonNegConstrs = list.map(make_nonneg_constr,
             [LeftSizeVar, RightSizeVar]),
         Terms = [LeftSizeVar - one, RightSizeVar - (-one)],
@@ -925,9 +913,10 @@
 
 build_goal_from_unify(Constraints) = term_primitive(Polyhedron, [], []) :-
     Polyhedron = polyhedron.from_constraints(Constraints),
-    ( if    polyhedron.is_empty(Polyhedron)
-      then  unexpected(this_file, "empty polyhedron from unification.")
-      else  true
+    ( polyhedron.is_empty(Polyhedron) ->
+        unexpected(this_file, "empty polyhedron from unification.")
+    ;
+        true
     ).
 
 %------------------------------------------------------------------------------%
@@ -935,8 +924,7 @@
     % Because quantification returns a conservative estimate of nonlocal
     % vars, this returns a list of local vars that may omit some of the
     % real local vars.  This shouldn't be a problem as everything but
-    % the head_vars will be projected out at the end of each iteration
-    % anyway.
+    % the head_vars will be projected out at the end of each iteration anyway.
     %
 :- func local_vars(hlds_goal) = prog_vars.
 
@@ -975,8 +963,8 @@
 
 allocate_sizevars(HeadProgVars, Goal, SizeVarMap, !SizeVarset) :-
     fill_var_to_sizevar_map(Goal, !SizeVarset, SizeVarMap0),
-    possibly_fix_sizevar_map(HeadProgVars, !SizeVarset, SizeVarMap0,
-        SizeVarMap).
+    possibly_fix_sizevar_map(HeadProgVars, !SizeVarset,
+        SizeVarMap0, SizeVarMap).
 
 :- pred fill_var_to_sizevar_map(hlds_goal::in,
     size_varset::in, size_varset::out, size_var_map::out) is det.
@@ -994,9 +982,9 @@
 
 possibly_fix_sizevar_map([], !SizeVarset, !SizeVarMap).
 possibly_fix_sizevar_map([ProgVar | ProgVars], !SizeVarset, !SizeVarMap) :-
-    ( if    map.search(!.SizeVarMap, ProgVar, _)
-      then  possibly_fix_sizevar_map(ProgVars, !SizeVarset, !SizeVarMap)
-      else
+    ( map.search(!.SizeVarMap, ProgVar, _) ->
+        possibly_fix_sizevar_map(ProgVars, !SizeVarset, !SizeVarMap)
+    ;
             svvarset.new_var(SizeVar, !SizeVarset),
             svmap.set(ProgVar, SizeVar, !SizeVarMap),
             possibly_fix_sizevar_map(ProgVars, !SizeVarset, !SizeVarMap)
@@ -1031,17 +1019,17 @@
 
 find_failure_constraint_for_goal(Goal, Info) = AbstractGoal :-
     (
-        Info ^ find_fail_constrs = yes,
+        Info ^ tti_find_fail_constrs = yes,
         find_failure_constraint_for_goal_2(Goal, Info, AbstractGoal0)
     ->
         AbstractGoal = AbstractGoal0
     ;
         NonLocalProgVars0 = goal_info_get_nonlocals(Goal ^ hlds_goal_info),
         NonLocalProgVars = set.to_sorted_list(NonLocalProgVars0),
-        NonLocalSizeVars = prog_vars_to_size_vars(Info ^ var_map,
+        NonLocalSizeVars = prog_vars_to_size_vars(Info ^ tti_size_var_map,
             NonLocalProgVars),
         Constraints = make_arg_constraints(NonLocalSizeVars,
-            Info ^ zeros),
+            Info ^ tti_zeros),
         FailPoly = polyhedron.from_constraints(Constraints),
         AbstractGoal = term_primitive(FailPoly, [], [])
     ).
@@ -1055,10 +1043,10 @@
 find_failure_constraint_for_goal_2(hlds_goal(GoalExpr, _), Info,
         AbstractGoal) :-
     GoalExpr = plain_call(PredId, ProcId, CallArgs, _, _, _),
-    CallSizeArgs0 = prog_vars_to_size_vars(Info ^ var_map, CallArgs),
-    CallSizeArgs = list.filter(isnt(is_zero_size_var(Info ^ zeros)),
+    CallSizeArgs0 = prog_vars_to_size_vars(Info ^ tti_size_var_map, CallArgs),
+    CallSizeArgs = list.filter(isnt(is_zero_size_var(Info ^ tti_zeros)),
         CallSizeArgs0),
-    ModuleInfo = Info ^ module_info,
+    ModuleInfo = Info ^ tti_module_info,
     module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo),
     proc_info_get_termination2_info(ProcInfo, TermInfo),
     MaybeFailureConstrs = TermInfo ^ failure_constrs,
@@ -1098,15 +1086,11 @@
 
 find_deconstruct_fail_bound(unify(_, _, _, Kind, _), Info, Polyhedron) :-
     Kind = deconstruct(Var, ConsId, _, _, can_fail, _),
-    Type = Info ^ types ^ det_elem(Var),
+    map.lookup(Info ^ tti_vartypes, Var, Type),
     prog_type.type_to_ctor_and_args(Type, TypeCtor, _),
-    ModuleInfo = Info ^ module_info,
+    ModuleInfo = Info ^ tti_module_info,
     type_util.type_constructors(ModuleInfo, Type, Constructors0),
-    ( if    ConsId = cons(ConsName0, ConsArity0)
-      then  ConsName = ConsName0, ConsArity = ConsArity0
-      else  unexpected(this_file,
-                "find_deconstruct_fail_bound/3: non cons cons_id.")
-    ),
+    ( ConsId = cons(ConsName, ConsArity) ->
     FindComplement = (pred(Ctor::in) is semidet :-
         Ctor = ctor(_, _, SymName, Args, _),
         list.length(Args, Arity),
@@ -1115,9 +1099,13 @@
             Arity   = ConsArity
         )
     ),
-    list.filter(FindComplement, Constructors0, Constructors),
-    SizeVar = prog_var_to_size_var(Info ^ var_map, Var),
-    bounds_on_var(Info ^ norm, ModuleInfo, TypeCtor, SizeVar,
+        list.filter(FindComplement, Constructors0, Constructors)
+    ;
+        unexpected(this_file,
+            "find_deconstruct_fail_bound/3: non cons cons_id.")
+    ),
+    SizeVar = prog_var_to_size_var(Info ^ tti_size_var_map, Var),
+    bounds_on_var(Info ^ tti_norm, ModuleInfo, TypeCtor, SizeVar,
         Constructors, Polyhedron).
 
     % Given a variable, its type and a list of constructors to which
@@ -1130,29 +1118,31 @@
 bounds_on_var(Norm, ModuleInfo, TypeCtor, Var, Constructors, Polyhedron) :-
     CtorSizes = list.map(lower_bound(Norm, ModuleInfo, TypeCtor),
         Constructors),
-    %
+
     % Split constructors into those that have zero size and
     % those that have non-zero size.
-    %
     list.filter((pred(V::in) is semidet :- V = 0), CtorSizes,
         ZeroSizeCtors, NonZeroSizeCtors),
     (
-        ZeroSizeCtors = [], NonZeroSizeCtors = []
-    ->
-        unexpected(this_file, "bounds_on_var/6: " ++
-            "no other constructors for type.")
+        NonZeroSizeCtors = [],
+        (
+            ZeroSizeCtors = [],
+            unexpected(this_file,
+                "bounds_on_var/6: no other constructors for type.")
     ;
-        ZeroSizeCtors = [_|_], NonZeroSizeCtors = []
-    ->
+            ZeroSizeCtors = [_ | _],
         Constraints = [constraint([Var - one], (=), zero)]
+        )
     ;
+        NonZeroSizeCtors = [C | Cs],
         upper_bound_constraints(Norm, ModuleInfo, Var, TypeCtor,
             Constructors, UpperBoundConstr),
-
-        ( ZeroSizeCtors = [], NonZeroSizeCtors = [C | Cs] ->
+        (
+            ZeroSizeCtors = [],
             LowerBound = list.foldl(int.min, Cs, C),
             LowerBoundConstr = [constraint([Var - one], (>=), rat(LowerBound))]
         ;
+            ZeroSizeCtors = [_ | _],
             LowerBoundConstr = [constraint([Var - one], (>=), zero)]
         ),
         Constraints = LowerBoundConstr ++ UpperBoundConstr
@@ -1176,28 +1166,30 @@
     type_ctor::in, list(constructor)::in, constraints::out) is det.
 
 upper_bound_constraints(Norm, Module, Var, TypeCtor, Ctors, Constraints) :-
-    %
     % If all the arguments of a functor are zero sized then we can give
     % an upper bound on its size.  If we have a set of such functors
-    % then the upper bound is the maximum of the individual upper
-    % bounds.
+    % then the upper bound is the maximum of the individual upper bounds.
     %
     % XXX We could extend this to include functors can only have a
     % finite size but I'm not sure that it's worth it.
-    %
+
     FindUpperBound = (pred(Ctor::in, !.B::in, !:B::out) is semidet :-
         Ctor = ctor(_, _, SymName, Args, _),
-        all [Arg] (list.member(Arg, Args) =>
-                zero_size_type(Module, Arg ^ arg_type)),
+        all [Arg] (
+            list.member(Arg, Args)
+        =>
+            zero_size_type(Module, Arg ^ arg_type)
+        ),
         Arity = list.length(Args),
         ConsId = cons(SymName, Arity),
         Bound = functor_lower_bound(Norm, TypeCtor, ConsId, Module),
         ( if Bound > !.B then !:B = Bound else true )
     ),
     ( list.foldl(FindUpperBound, Ctors, 0, Bound0) ->
-        ( if    Bound0 = 0
-          then  unexpected(this_file, "zero upper bound.")
-          else  Constraints = [constraint([Var - one], (=<), rat(Bound0))]
+        ( Bound0 = 0 ->
+            unexpected(this_file, "zero upper bound.")
+        ;
+            Constraints = [constraint([Var - one], (=<), rat(Bound0))]
         )
     ;
         Constraints = []
Index: compiler/term_constr_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_data.m,v
retrieving revision 1.9
diff -u -b -r1.9 term_constr_data.m
--- compiler/term_constr_data.m	23 Nov 2007 07:35:27 -0000	1.9
+++ compiler/term_constr_data.m	5 Jan 2008 09:34:20 -0000
@@ -147,7 +147,8 @@
     % The widening strategy used in the fixpoint calculation.
     % (At present there is only one but we may add others in the future).
     %
-:- type widening ---> after_fixed_cutoff(int).
+:- type widening
+    --->    after_fixed_cutoff(int).
 
     % The result of the argument size analysis.
     %
@@ -156,8 +157,8 @@
     % termination2_info structure.
     %
 :- type arg_size_result 
-    --->    ok      
-    ;       error(term2_errors).
+    --->    arg_size_ok
+    ;       arg_size_error(term2_errors).
 
 %-----------------------------------------------------------------------------%
 %
@@ -183,50 +184,50 @@
     % This is the main reason that we try a eliminate, as much as
     % possible, dependencies between the AR and the HLDS.
     %
-:- type abstract_ppid ---> real(pred_proc_id).
+:- type abstract_ppid
+    --->    real(pred_proc_id).
 
 :- type abstract_proc  
     ---> abstract_proc(
-        ppid :: abstract_ppid,
             % The procedure that this is an abstraction of.     
+                ap_ppid             :: abstract_ppid,
 
-        context :: prog_context,
-            % The context of the procedure.
-    
-        recursion :: recursion_type,
-            % The type of recursion present in the procedure.
+                % Is this procedure called from outside the SCC?
+                ap_is_entry         :: bool,
 
-        size_var_map :: size_var_map,
-            % Map from prog_vars to size_vars for the procedure.
+                % The context of the procedure.
+                ap_context          :: prog_context,
         
-        head_vars :: head_vars,
             % The procedure's arguments (as size_vars).     
+                ap_head_vars        :: head_vars,
 
-        inputs :: list(bool),
             % `yes' if the corresponding argument can be used
             % as part of a termination proof, `no' otherwise.
+                ap_inputs           :: list(bool),
     
-        zeros :: zero_vars,
-            % The size_vars that have zero size.
-
-        body :: abstract_goal,
             % An abstraction of the body of the procedure. 
+                ap_body             :: abstract_goal,
         
-        calls :: int,
-            % The number of calls made in the body of the
-            % procedure.  This is useful for short-circuiting
-            % pass 2.
-         
-        varset :: size_varset,
-            % The varset from which the size_vars were
-            % allocated.  The linear solver needs this.
-
-        ho :: list(abstract_ho_call),
-            % A list of higher-order calls made by the 
-            % procedure.  XXX Currently not used.
+                % Map from prog_vars to size_vars for the procedure.
+                ap_size_var_map     :: size_var_map,
             
-        is_entry :: bool
-            % Is this procedure called from outside the SCC?
+                % The varset from which the size_vars were allocated.
+                % The linear solver needs this.
+                ap_size_varset      :: size_varset,
+
+                % The size_vars that have zero size.
+                ap_zeros            :: zero_vars,
+
+                % The type of recursion present in the procedure.
+                ap_recursion        :: recursion_type,
+
+                % The number of calls made in the body of the procedure.
+                % This is useful for short-circuiting pass 2.
+                ap_num_calls        :: int,
+
+                % A list of higher-order calls made by the procedure.
+                % XXX Currently not used.
+                ap_ho_calls         :: list(abstract_ho_call)
     ).
 
     % This is like an error message (and is treated as such
@@ -235,7 +236,8 @@
     % In particular higher-order constructs will not always be errors
     % (ie. when we can analyse them properly).  
     %
-:- type abstract_ho_call ---> ho_call(prog_context).
+:- type abstract_ho_call
+    --->    ho_call(prog_context).
 
     % NOTE: the AR's notion of local/non-local variables may not
     % correspond directly to that in the HLDS because of various
@@ -299,12 +301,9 @@
     %
 :- type recursion_type
     --->    none        % Procedure is not recursive.
-    
     ;       direct_only % Only recursion is self-calls.
-    
     ;       mutual_only % Only recursion is calls to other procs
                         % in the same SCC.
-
     ;       both.       % Both types of recursion.
 
 %-----------------------------------------------------------------------------%
@@ -348,7 +347,7 @@
 
     % Returns the size_varset for this given SCC. 
     %
-:- func varset_from_abstract_scc(abstract_scc) = size_varset.
+:- func size_varset_from_abstract_scc(abstract_scc) = size_varset.
 
     % Succeeds iff the results of the analysis depend upon the 
     % values of some higher-order variables.
@@ -429,17 +428,17 @@
 scc_contains_recursion([]) :-
     unexpected(this_file, "empty SCC.").
 scc_contains_recursion([Proc | _]) :-
-    Proc ^ recursion \= none. 
+    Proc ^ ap_recursion \= none.
 
 proc_is_recursive(Proc) :-
-    not Proc ^ recursion = none.
+    not Proc ^ ap_recursion = none.
 
-varset_from_abstract_scc([]) = _ :-
+size_varset_from_abstract_scc([]) = _ :-
     unexpected(this_file, "empty SCC.").
-varset_from_abstract_scc([Proc | _]) = Proc ^ varset.
+size_varset_from_abstract_scc([Proc | _]) = Proc ^ ap_size_varset.
 
 analysis_depends_on_ho(Proc) :-
-    list.is_not_empty(Proc ^ ho).
+    list.is_not_empty(Proc ^ ap_ho_calls).
 
 %-----------------------------------------------------------------------------%
 %
@@ -449,48 +448,55 @@
 % XXX We should keep running the simplifications until we arrive at a
 % fixpoint.
 
-simplify_abstract_rep(Goal0) = Goal :- simplify_abstract_rep(Goal0, Goal).
+simplify_abstract_rep(Goal0) = Goal :-
+    simplify_abstract_rep(Goal0, Goal).
 
 :- pred simplify_abstract_rep(abstract_goal::in, abstract_goal::out) is det.
 
-simplify_abstract_rep(term_disj(!.Disjuncts, _Size0, Locals, NonLocals),
-        Goal) :-
+simplify_abstract_rep(Goal0, Goal) :-
+    (
+        Goal0 = term_disj(Disjuncts0, _Size0, Locals, NonLocals),
     % Begin by simplifying each disjunct.
-
-    list.map(simplify_abstract_rep, !Disjuncts),
+        list.map(simplify_abstract_rep, Disjuncts0, Disjuncts),
     ( 
-        !.Disjuncts = [] ,
+            Disjuncts = [] ,
         Goal = term_primitive(polyhedron.universe, [], [])
     ;
-        !.Disjuncts = [Disjunct] ,
+            Disjuncts = [Disjunct] ,
         % We need to merge the set of locals with the locals from the 
         % disjunct otherwise we will end up throwing away the locals
         % from the enclosing goal.
-        %
         Goal = update_local_and_nonlocal_vars(Disjunct, Locals, NonLocals)
     ;   
-        !.Disjuncts = [_, _ | _] ,
-        Size = list.length(!.Disjuncts),
-        Goal = term_disj(!.Disjuncts, Size, Locals, NonLocals) 
-    ).
-
-simplify_abstract_rep(term_conj(!.Conjuncts, Locals, NonLocals), Goal) :-
+            Disjuncts = [_, _ | _] ,
+            Size = list.length(Disjuncts),
+            Goal = term_disj(Disjuncts, Size, Locals, NonLocals)
+        )
+    ;
+        Goal0 = term_conj(Conjuncts0, Locals, NonLocals),
+        some [!Conjuncts] (
+            !:Conjuncts = Conjuncts0,
     list.map(simplify_abstract_rep, !Conjuncts),
     list.filter(isnt(is_empty_primitive), !Conjuncts),
     flatten_conjuncts(!Conjuncts),
     list.filter(isnt(is_empty_conj), !Conjuncts),
-    ( !.Conjuncts = [Conjunct] ->
+            Conjuncts = !.Conjuncts
+        ),
+        ( Conjuncts = [Conjunct] ->
         % The local/non-local var sets need to be updated for similar
         % reasons as we do with disjunctions.
-
-        Goal = update_local_and_nonlocal_vars(Conjunct, Locals, NonLocals) 
+            Goal = update_local_and_nonlocal_vars(Conjunct, Locals,
+                NonLocals)
+        ;
+            Goal = term_conj(Conjuncts, Locals, NonLocals)
+        )
     ; 
-        Goal = term_conj(!.Conjuncts, Locals, NonLocals)
+        ( Goal0 = term_primitive(_, _, _)
+        ; Goal0 = term_call(_, _, _, _, _, _, _)
+        ),
+        Goal = Goal0
     ).
 
-simplify_abstract_rep(Goal @ term_primitive(_,_,_),      Goal).
-simplify_abstract_rep(Goal @ term_call(_,_,_,_,_,_,_), Goal).
-
     % Given a conjuntion of abstract goals take the intersection
     % of all consecutive primitive goals in the list of abstract goals.
     % 
@@ -516,14 +522,14 @@
 flatten_conjuncts([], []).
 flatten_conjuncts([Goal], [Goal]).
 flatten_conjuncts(Goals0 @ [_, _ | _], Goals) :-
-    flatten_conjuncts_2(Goals0, [], Goals1),
-    Goals = list.reverse(Goals1).
+    flatten_conjuncts_2(Goals0, [], RevGoals),
+    Goals = list.reverse(RevGoals).
 
 :- pred flatten_conjuncts_2(abstract_goals::in, abstract_goals::in,
     abstract_goals::out) is det.
 
-flatten_conjuncts_2([], !Goals).
-flatten_conjuncts_2([Goal0 | Goals0], !Goals) :-
+flatten_conjuncts_2([], !RevGoals).
+flatten_conjuncts_2([Goal0 | Goals0], !RevGoals) :-
     ( Goal0 = term_primitive(_, _, _) ->
         list.takewhile(is_primitive, Goals0, Primitives, NextNonPrimitive),
         (
@@ -533,12 +539,12 @@
             Primitives = [_ | _],
             NewPrimitive = list.foldl(combine_primitives, Primitives, Goal0)
         ),
-        list.cons(NewPrimitive, !Goals)
+        list.cons(NewPrimitive, !RevGoals)
     ;
-        list.cons(Goal0, !Goals),
+        list.cons(Goal0, !RevGoals),
         NextNonPrimitive = Goals0
     ),
-    flatten_conjuncts_2(NextNonPrimitive, !Goals).
+    flatten_conjuncts_2(NextNonPrimitive, !RevGoals).
 
     % Test whether an abstract goal is a primtive.
     %
@@ -558,8 +564,8 @@
         NonLocals = NonLocalsA ++ NonLocalsB,
         Goal = term_primitive(Poly, Locals, NonLocals)
     ;
-        unexpected(this_file, "intersect_primitives called with "
-            ++ "non-primitive goals.")
+        unexpected(this_file,
+            "intersect_primitives called with non-primitive goals.")
     ).     
 
     % We end up with `empty' primitives by abstracting unifications
@@ -630,24 +636,27 @@
     dump_abstract_scc(SCC, 0, Module, !IO).
 
 dump_abstract_scc(SCC, Indent, Module, !IO) :-
-    list.foldl((pred(Proc::in, !.IO::di, !:IO::uo) is det :-
+    list.foldl(
+        (pred(Proc::in, !.IO::di, !:IO::uo) is det :-
             dump_abstract_proc(Proc, Indent, Module, !IO)
         ), SCC, !IO).
 
 dump_abstract_proc(Proc, Indent, Module, !IO) :-
-    Proc = abstract_proc(AbstractPPId, _, _, _, HeadVars, _, _,
-        Body, _, Varset, _, _),
+    AbstractPPId = Proc ^ ap_ppid,
+    HeadVars = Proc ^ ap_head_vars,
+    Body = Proc ^ ap_body,
+    SizeVarSet = Proc ^ ap_size_varset,
     indent_line(Indent, !IO),
     AbstractPPId = real(PPId),
     hlds_out.write_pred_proc_id(Module, PPId, !IO),
     io.write_string(" : [", !IO),
     WriteHeadVars = (pred(Var::in, !.IO::di, !:IO::uo) is det :-
-        varset.lookup_name(Varset, Var, VarName),
+        varset.lookup_name(SizeVarSet, Var, VarName),
         io.format(VarName ++ "[%d]", [i(term.var_id(Var))], !IO)
     ),
     io.write_list(HeadVars, ", ", WriteHeadVars, !IO), 
     io.write_string(" ] :- \n", !IO),
-    dump_abstract_goal(Module, Varset, Indent + 1, Body, !IO).
+    dump_abstract_goal(Module, SizeVarSet, Indent + 1, Body, !IO).
 
 :- func recursion_type_to_string(recursion_type) = string.
 
@@ -783,9 +792,10 @@
 :- pred indent_line(int::in, io::di, io::uo) is det.
 
 indent_line(N, !IO) :- 
-    ( if    N > 0
-      then  io.write_string("  ", !IO), indent_line(N - 1, !IO)
-      else  true    
+    ( N > 0 ->
+        io.write_string("  ", !IO), indent_line(N - 1, !IO)
+    ;
+        true
     ).
 
 %-----------------------------------------------------------------------------%
Index: compiler/term_constr_fixpoint.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_fixpoint.m,v
retrieving revision 1.7
diff -u -b -r1.7 term_constr_fixpoint.m
--- compiler/term_constr_fixpoint.m	23 Nov 2007 07:35:27 -0000	1.7
+++ compiler/term_constr_fixpoint.m	5 Jan 2008 09:20:09 -0000
@@ -72,18 +72,18 @@
 :- import_module term.
 :- import_module varset.
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- type fixpoint_options 
     ---> fixpoint_options(
-        widening :: widening,
-        max_size :: int
+                fo_widening :: widening,
+                fo_max_size :: int
     ).
 
 fixpoint_options_init(Widening, MaxMatrixSize) = 
     fixpoint_options(Widening, MaxMatrixSize).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 %
 % Perform the fixpoint calculation on the AR.
 %
@@ -93,21 +93,21 @@
     %
 :- type iteration_info 
     ---> iteration_info(
-         pred_proc_id, 
-         arg_size_poly :: polyhedron, 
-         change_flag   :: bool
+                 ii_ppid            :: pred_proc_id,
+                 ii_arg_size_poly   :: polyhedron,
+                 ii_change_flag     :: bool
     ).
 
 :- type iteration_infos == list(iteration_info).
 
 do_fixpoint_calculation(Options, SCC, Iteration, [], !ModuleInfo, !IO) :-
     AbstractSCC = get_abstract_scc(!.ModuleInfo, SCC),  
-    %
-    % Carry out one iteration of fixpoint computation.  We need to
-    % do this for all SCCs at least once in order to obtain the argument
-    % size constraints for non-recursive procedures.  We could do that
-    % during the build phase for non-recursive procedures (and in fact used
-    % to) but the code ends up being a horrible mess.
+
+    % Carry out one iteration of fixpoint computation. We need to do this
+    % for all SCCs at least once in order to obtain the argument size
+    % constraints for non-recursive procedures. We could do that during
+    % the build phase for non-recursive procedures (and in fact used to)
+    % but the code ends up being a horrible mess.
     %
     list.foldl2(traverse_abstract_proc(Iteration, Options, !.ModuleInfo), 
         AbstractSCC, [], IterationInfos, !IO),
@@ -127,11 +127,11 @@
         % 
         ( 
             list.member(OneInfo, IterationInfos), 
-            polyhedron.is_empty(OneInfo ^ arg_size_poly)
+            polyhedron.is_empty(OneInfo ^ ii_arg_size_poly)
         ->
             ChangePoly = (func(Info0) = Info :-
                 Identity = polyhedron.universe,
-                Info = Info0 ^ arg_size_poly := Identity 
+                Info = Info0 ^ ii_arg_size_poly := Identity
             ),
             list.foldl(update_size_info, list.map(ChangePoly, IterationInfos),
                 !ModuleInfo)
@@ -143,7 +143,7 @@
 :- func or_flags(iteration_infos) = bool.
 
 or_flags([]) = no. 
-or_flags([Info | Infos]) = bool.or(Info ^ change_flag, or_flags(Infos)).
+or_flags([Info | Infos]) = bool.or(Info ^ ii_change_flag, or_flags(Infos)).
 
 :- pred update_size_info(iteration_info::in, module_info::in, module_info::out)
     is det.
@@ -152,75 +152,68 @@
     Info = iteration_info(PPId, Poly, _),
     update_arg_size_info(PPId, Poly, !ModuleInfo).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred traverse_abstract_proc(int::in, fixpoint_options::in,
-    module_info::in, abstract_proc::in, iteration_infos::in,
-    iteration_infos::out, io::di, io::uo) is det.
+    module_info::in, abstract_proc::in,
+    iteration_infos::in, iteration_infos::out, io::di, io::uo) is det.
 
-traverse_abstract_proc(Iteration, Options, ModuleInfo, Proc, !IterationInfo,
-        !IO) :-
-    WideningInfo = Options ^ widening,
-    MaxMatrixSize = Options ^ max_size,
-    AbstractPPId = Proc ^ ppid,
+traverse_abstract_proc(Iteration, Options, ModuleInfo, Proc,
+        !IterationInfo, !IO) :-
+    WideningInfo = Options ^ fo_widening,
+    MaxMatrixSize = Options ^ fo_max_size,
+    AbstractPPId = Proc ^ ap_ppid,
     AbstractPPId = real(PPId),
-    Varset = Proc ^ varset,
-    Zeros  = Proc ^ zeros,
-    HeadVars = Proc ^ head_vars,    
-    % 
+    SizeVarSet = Proc ^ ap_size_varset,
+    Zeros  = Proc ^ ap_zeros,
+    HeadVars = Proc ^ ap_head_vars,
+
     % Print out the debugging traces.
-    %
     maybe_write_trace(io.write(PPId), !IO),
     maybe_write_trace(io.write_string(": "), !IO),
     maybe_write_trace(hlds_out.write_pred_proc_id(ModuleInfo, PPId), !IO),
     maybe_write_trace(io.write_string(" "), !IO),
-    maybe_write_trace(write_size_vars(Varset, HeadVars), !IO),
+    maybe_write_trace(write_size_vars(SizeVarSet, HeadVars), !IO),
     maybe_write_trace(io.format("\nIteration %d:\n", [i(Iteration)]), !IO),
-    %   
+
     % Begin by traversing the procedure and calculating the
     % IR approximation for this iteration.  
-    %
-    Info = init_fixpoint_info(ModuleInfo, Varset, PPId, MaxMatrixSize,
+
+    Info = init_fixpoint_info(ModuleInfo, SizeVarSet, PPId, MaxMatrixSize,
         HeadVars, Zeros),
 
     some [!Polyhedron] (    
-        traverse_abstract_goal(Info, Proc ^ body, polyhedron.universe, 
+        traverse_abstract_goal(Info, Proc ^ ap_body, polyhedron.universe,
             !:Polyhedron),
-        polyhedron.optimize(Varset, !Polyhedron),
-        %
+        polyhedron.optimize(SizeVarSet, !Polyhedron),
+
         % XXX Bug workaround - the build pass sometimes stuffs up
         % the local variable set for if-then-elses.
         % (See comments in term_constr_build.m). 
-        %
         BugConstrs0 = polyhedron.constraints(!.Polyhedron),
         ConstrVarsSet = get_vars_from_constraints(BugConstrs0),
         HeadVarSet = set.from_list(HeadVars),
         BadVarsSet = set.difference(ConstrVarsSet, HeadVarSet),
         BadVars = set.to_sorted_list(BadVarsSet),
-        !:Polyhedron = polyhedron.project(BadVars, Varset, !.Polyhedron),
-        polyhedron.optimize(Varset, !Polyhedron),
-        %   
+        !:Polyhedron = polyhedron.project(BadVars, SizeVarSet, !.Polyhedron),
+        polyhedron.optimize(SizeVarSet, !Polyhedron),
         % XXX End of bug workaround.    
+
         % Print out the polyhedron obtained during this iteration.
-        %
-        maybe_write_trace(polyhedron.write_polyhedron(!.Polyhedron, Varset),
-            !IO),
+        maybe_write_trace(
+            polyhedron.write_polyhedron(!.Polyhedron, SizeVarSet), !IO),
         maybe_write_trace(io.nl, !IO),
-        %       
-        % Look up the constraints obtained during the previous
-        % iteration.
-        %
+
+        % Look up the constraints obtained during the previous iteration.
         ArgSizeInfo = lookup_proc_constr_arg_size_info(ModuleInfo, PPId),
-        %
+
         % NOTE: `!.Polyhedron' is the set of constraints obtained by
         % *this* iteration.  `OldPolyhedron' is the set of constraints
-        % obtained by the *previous* iteration -- which may in fact
-        % be `empty' (false).
-        %
+        % obtained by the *previous* iteration -- which may in fact be `empty'
+        % (i.e. false).
         (
             % If there were no constraints for the procedure then
             % we are at the beginning of the analysis.
-            %
             ArgSizeInfo = no,
             OldPolyhedron = polyhedron.empty
         ;
@@ -228,17 +221,21 @@
             OldPolyhedron = SizeInfo
         ),
         ( polyhedron.is_empty(!.Polyhedron) ->
-            ( if    polyhedron.is_empty(OldPolyhedron)
-              then  ChangeFlag = no 
-              else  unexpected(this_file, "old polyhedron is empty.")
+            ( polyhedron.is_empty(OldPolyhedron) ->
+                ChangeFlag = no
+            ;
+                unexpected(this_file, "old polyhedron is empty.")
             )
         ;
             % If the procedure is not recursive then we need only perform one
-            % pass over the AR - subsequent iterations will yield the same result.
-            %
-            ( if       Proc ^ recursion = none then ChangeFlag = no
-              else if  polyhedron.is_empty(OldPolyhedron) then ChangeFlag = yes
-              else     test_fixpoint_and_perhaps_widen(WideningInfo, Varset, 
+            % pass over the AR - subsequent iterations will yield the same
+            % result.
+            ( Proc ^ ap_recursion = none ->
+                ChangeFlag = no
+            ; polyhedron.is_empty(OldPolyhedron) ->
+                ChangeFlag = yes
+            ;
+                test_fixpoint_and_perhaps_widen(WideningInfo, SizeVarSet,
                            Iteration, OldPolyhedron, !Polyhedron, ChangeFlag)
             )
         ),
@@ -246,7 +243,7 @@
     ),
     list.cons(ThisIterationInfo, !IterationInfo).
     
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- type fixpoint_info 
     ---> fixpoint_info(
@@ -261,42 +258,43 @@
 :- func init_fixpoint_info(module_info, size_varset, pred_proc_id, int, 
     head_vars, zero_vars) = fixpoint_info.
 
-init_fixpoint_info(ModuleInfo, Varset, PPId, MaxMatrixSize, HeadVars, Zeros) = 
-    fixpoint_info(ModuleInfo, Varset, PPId, MaxMatrixSize, HeadVars, Zeros).
+init_fixpoint_info(ModuleInfo, SizeVarSet, PPId, MaxMatrixSize, HeadVars,
+        Zeros) =
+    fixpoint_info(ModuleInfo, SizeVarSet, PPId, MaxMatrixSize, HeadVars,
+        Zeros).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred traverse_abstract_goal(fixpoint_info::in, abstract_goal::in,
     polyhedron::in, polyhedron::out) is det.
 
-traverse_abstract_goal(Info, term_disj(Goals, _Size, Locals, _),
-        !Polyhedron) :- 
-    %
+traverse_abstract_goal(Info, Goal, !Polyhedron) :-
+    (
+        Goal = term_disj(Goals, _Size, Locals, _),
     % There are number of possible improvements that should be made here:
     %
     %   - Take the intersection each disjunct with the constraints
     %     before the disjunction and compute the convex hull of that.
     %     This is more accurate but slower.  (XXX There is some code for this
-    %     in term_constr_data.m but it needs to be moved here).  To do
-    %     this you need to add the constraints that occur to 
-    %     left of the disjunctions to `PriorConstraints'.
-    %   
-    %   - Try computing the convex hull of large disjunctions
-    %     pairwise rather than linearly.  There is code to do this
-    %     below but we currently don't use it.
-    %
+        %   in term_constr_data.m but it needs to be moved here). To do this
+        %   you need to add the constraints that occur to left of the
+        %   disjunctions to `PriorConstraints'.
+        %
+        % - Try computing the convex hull of large disjunctions pairwise
+        %   rather than linearly. There is code to do this below but we
+        %   currently don't use it.
+
     PriorConstraints = polyhedron.universe,
     traverse_abstract_disj_linearly(Goals, Locals, Info, PriorConstraints,
         Polyhedron0),
-    post_process_abstract_goal(Locals, Info, Polyhedron0, !Polyhedron).
-
-traverse_abstract_goal(Info, term_conj(Goals, Locals, _), !Polyhedron) :- 
+        post_process_abstract_goal(Locals, Info, Polyhedron0, !Polyhedron)
+    ;
+        Goal = term_conj(Goals, Locals, _),
     list.foldl(traverse_abstract_goal(Info), Goals, polyhedron.universe,
         Polyhedron0),
-    post_process_abstract_goal(Locals, Info, Polyhedron0, !Polyhedron).
-
-traverse_abstract_goal(Info, AbstractGoal, !Polyhedron) :- 
-    AbstractGoal = term_call(CallPPId0, _, CallVars, CallZeros, Locals, _,
+        post_process_abstract_goal(Locals, Info, Polyhedron0, !Polyhedron)
+    ;
+        Goal = term_call(CallPPId0, _, CallVars, CallZeros, Locals, _,
         CallArgsPoly),
     CallPPId0 = real(CallPPId),
     module_info_pred_proc_info(Info ^ module_info, CallPPId, _, 
@@ -311,7 +309,10 @@
         ( polyhedron.is_empty(SizeInfo) ->
             !:Polyhedron = polyhedron.empty
         ;
-            ( not polyhedron.is_universe(SizeInfo) ->
+                ( polyhedron.is_universe(SizeInfo) ->
+                    true
+                    % Constraint store += true
+                ;
                 HeadVars = CallTerm2Info ^ head_vars,
                 SubstMap = create_var_substitution(CallVars, 
                     HeadVars),
@@ -319,34 +320,30 @@
                     SubstMap, SizeInfo), 
                 Polyhedron1 = intersection(Polyhedron0, 
                     CallArgsPoly),
-                % 
-                % Set any zero_vars in the constraints
-                % to zero (ie. delete the terms).  We need
-                % to do this when polymorphic arguments
-                % are zero sized.
-                %
-                Polyhedron2 = polyhedron.zero_vars(CallZeros,
-                    Polyhedron1),
+                    % Set any zero_vars in the constraints to zero
+                    % (i.e. delete the terms). We need to do this
+                    % when polymorphic arguments are zero sized.
+                    Polyhedron2 = polyhedron.zero_vars(CallZeros, Polyhedron1),
                 post_process_abstract_goal(Locals, Info, 
                     Polyhedron2, !Polyhedron)
-            ;
-                true    % Constraint store += true  
             )
         )
+        )
+    ;
+        Goal = term_primitive(Poly, Locals, _),
+        post_process_abstract_goal(Locals, Info, Poly, !Polyhedron)
     ).
 
-traverse_abstract_goal(Info, term_primitive(Poly, Locals, _), !Polyhedron) :- 
-    post_process_abstract_goal(Locals, Info, Poly, !Polyhedron).
-
 %------------------------------------------------------------------------------%
 
 :- pred post_process_abstract_goal(size_vars::in, fixpoint_info::in,
     polyhedron::in, polyhedron::in, polyhedron::out) is det.
 
 post_process_abstract_goal(Locals, Info, GoalPolyhedron0, !Polyhedron) :- 
-    ( if    polyhedron.is_empty(GoalPolyhedron0)
-      then  GoalPolyhedron = polyhedron.empty
-      else  GoalPolyhedron = polyhedron.project(Locals, Info ^ varset, 
+    ( polyhedron.is_empty(GoalPolyhedron0) ->
+        GoalPolyhedron = polyhedron.empty
+    ;
+        GoalPolyhedron = polyhedron.project(Locals, Info ^ varset,
             GoalPolyhedron0)
     ),  
     polyhedron.intersection(GoalPolyhedron, !Polyhedron).
@@ -362,8 +359,7 @@
     %  ((((empty \/ A ) \/ B ) \/ C ) \/ D)
     %
 :- pred traverse_abstract_disj_linearly(abstract_goals::in,
-    size_vars::in, fixpoint_info::in, polyhedron::in, polyhedron::out)
-    is det.
+    size_vars::in, fixpoint_info::in, polyhedron::in, polyhedron::out) is det.
 
 traverse_abstract_disj_linearly(Goals, Locals, Info, !Polyhedron) :-
     list.foldl(traverse_abstract_disj_linearly_2(Info, Locals),
@@ -371,14 +367,13 @@
     polyhedron.intersection(ConvexUnion, !Polyhedron).
 
 :- pred traverse_abstract_disj_linearly_2(fixpoint_info::in,
-    size_vars::in, abstract_goal::in, polyhedron::in, polyhedron::out)
-    is det.
+    size_vars::in, abstract_goal::in, polyhedron::in, polyhedron::out) is det.
 
 traverse_abstract_disj_linearly_2(Info, Locals, Goal, !Polyhedron) :-
-    Varset = Info ^ varset,
+    SizeVarSet = Info ^ varset,
     traverse_abstract_goal(Info, Goal, polyhedron.universe, Polyhedron0),
-    Polyhedron1 = polyhedron.project(Locals, Varset, Polyhedron0),
-    polyhedron.convex_union(Varset, yes(Info ^ max_matrix_size),
+    Polyhedron1 = polyhedron.project(Locals, SizeVarSet, Polyhedron0),
+    polyhedron.convex_union(SizeVarSet, yes(Info ^ max_matrix_size),
         Polyhedron1, !Polyhedron).
 
     % This version computes the convex hull pairwise. That is
@@ -390,24 +385,20 @@
     fixpoint_info::in, polyhedron::in, polyhedron::out) is det.
  
 traverse_abstract_disj_pairwise(Goals, Locals, Info, !Polyhedron) :-
-    Varset = Info ^ varset,
+    SizeVarSet = Info ^ varset,
     % XXX at the moment, could be !.Poly...
     PolyToLeft = polyhedron.universe,
-    %
-    % First convert the list of goals into their corresponding
-    % polyhedra
-    %
+
+    % First convert the list of goals into their corresponding polyhedra.
     ToPoly = (func(Goal) = Poly :-
         traverse_abstract_goal(Info, Goal, PolyToLeft, Poly0),
-        Poly = polyhedron.project(Locals, Varset, Poly0)
+        Poly = polyhedron.project(Locals, SizeVarSet, Poly0)
     ),
     Polyhedra0 = list.map(ToPoly, Goals),
-    %
+
     % Now pairwise convex hull them.
-    %
     HullOp = (func(A, B) = C :-
-        polyhedron.convex_union(Varset, yes(Info ^ max_matrix_size),
-            A, B, C)
+        polyhedron.convex_union(SizeVarSet, yes(Info ^ max_matrix_size), A, B, C)
     ),
     ConvexUnion = pairwise_map(HullOp, [ polyhedron.empty | Polyhedra0]),
     polyhedron.intersection(ConvexUnion, !Polyhedron).
@@ -440,30 +431,26 @@
 :- pred test_fixpoint_and_perhaps_widen(widening::in, size_varset::in, int::in, 
     polyhedron::in, polyhedron::in, polyhedron::out, bool::out) is det.
 
-test_fixpoint_and_perhaps_widen(after_fixed_cutoff(Threshold), Varset, 
+test_fixpoint_and_perhaps_widen(after_fixed_cutoff(Threshold), SizeVarSet,
         Iteration, OldPoly, NewPoly, ResultPoly, ChangeFlag) :- 
     ( Iteration > Threshold ->
-        ResultPoly = widen(OldPoly, NewPoly, Varset)
+        ResultPoly = widen(OldPoly, NewPoly, SizeVarSet)
     ;
         ResultPoly = NewPoly
     ),
-    ChangeFlag = test_fixpoint(NewPoly, OldPoly, Varset).
+    ChangeFlag = test_fixpoint(NewPoly, OldPoly, SizeVarSet).
 
 :- func test_fixpoint(polyhedron, polyhedron, size_varset) = bool. 
 
-test_fixpoint(NewPoly, OldPoly, Varset) = ChangeFlag :-
-    %
+test_fixpoint(NewPoly, OldPoly, SizeVarSet) = ChangeFlag :-
     % Constraints from this iteration.
-    %
     NewConstraints = polyhedron.non_false_constraints(NewPoly),
-    %
     % Constraints from previous iteration.
-    %
     OldConstraints = polyhedron.non_false_constraints(OldPoly), 
     (
         some [OldConstraint] (
             list.member(OldConstraint, OldConstraints),
-            not entailed(Varset, NewConstraints, OldConstraint)
+            not entailed(SizeVarSet, NewConstraints, OldConstraint)
         )
     ->
         ChangeFlag = yes
Index: compiler/term_constr_initial.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_initial.m,v
retrieving revision 1.23
diff -u -b -r1.23 term_constr_initial.m
--- compiler/term_constr_initial.m	23 Nov 2007 07:35:27 -0000	1.23
+++ compiler/term_constr_initial.m	5 Jan 2008 10:18:59 -0000
@@ -306,7 +306,7 @@
             % each procedure.
             %
             ( check_marker(Markers, marker_terminates) ->
-                TermStatus = cannot_loop(pragma_supplied),
+                TermStatus = cannot_loop(term_reason_pragma_supplied),
                 change_procs_constr_termination_info(ProcIds, yes, TermStatus,
                     !ProcTable),
                 ArgSizeInfo = polyhedron.universe,
@@ -336,7 +336,7 @@
                 )
             ->
                 change_procs_constr_termination_info(ProcIds, yes,
-                    cannot_loop(pragma_supplied), !ProcTable)
+                    cannot_loop(term_reason_pragma_supplied), !ProcTable)
             ;
                 change_procs_constr_termination_info(ProcIds, no,
                     can_loop([]), !ProcTable)
@@ -464,7 +464,7 @@
     ),
     Polyhedron  = polyhedron.from_constraints(Constrs),
     ArgSizeInfo = Polyhedron,
-    Termination = cannot_loop(builtin).
+    Termination = cannot_loop(term_reason_builtin).
 special_pred_id_to_termination(spec_pred_index, HeadProgVars, ModuleInfo,
         VarTypes, ArgSize, Termination, SizeVarMap, HeadSizeVars) :-
     NumToDrop = list.length(HeadProgVars) - 2,
@@ -494,7 +494,7 @@
     Constraints = create_nonneg_constraints(SizeVarMap, Zeros),
     Polyhedron = polyhedron.from_constraints(Constraints),
     ArgSize = Polyhedron,
-    Termination = cannot_loop(builtin),
+    Termination = cannot_loop(term_reason_builtin),
     HeadSizeVars = prog_vars_to_size_vars(SizeVarMap, HeadProgVars).
 
     % Set the termination information for builtin
@@ -530,7 +530,8 @@
     some [!TermInfo] (
         proc_info_get_termination2_info(ProcInfo0, !:TermInfo),
         !:TermInfo = !.TermInfo ^ success_constrs := ArgSizeInfo,
-        !:TermInfo = !.TermInfo ^ term_status := yes(cannot_loop(builtin)),
+        !:TermInfo = !.TermInfo ^ term_status :=
+            yes(cannot_loop(term_reason_builtin)),
         !:TermInfo = !.TermInfo ^ intermod_status :=
             yes(not_mutually_recursive),
         !:TermInfo = !.TermInfo ^ size_var_map := SizeVarMap,
@@ -548,10 +549,8 @@
     (
         HeadVars = [HVar1, HVar2],
         (
-            (
-                PredName = "unsafe_type_cast"
-            ;
-                PredName = "unsafe_promise_unique"
+            ( PredName = "unsafe_type_cast"
+            ; PredName = "unsafe_promise_unique"
             )
         ->
             SizeVar1 = prog_var_to_size_var(SizeVarMap, HVar1),
Index: compiler/term_constr_main.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_main.m,v
retrieving revision 1.15
diff -u -b -r1.15 term_constr_main.m
--- compiler/term_constr_main.m	23 Nov 2007 07:35:27 -0000	1.15
+++ compiler/term_constr_main.m	5 Jan 2008 10:03:53 -0000
@@ -102,17 +102,21 @@
     % terminating?  This is useful for debugging purposes.
     %
 :- type term_reason
-    --->    builtin             % procedure was a builtin.
+    --->    term_reason_builtin
+            % Procedure was a builtin.
 
-    ;       pragma_supplied     % procedure has pragma terminates decl.
+    ;       term_reason_pragma_supplied
+            % Procedure has pragma terminates decl.
 
-    ;       foreign_supplied    % procedure has foreign code attribute.
+    ;       term_reason_foreign_supplied
+            % Procedure has foreign code attribute.
 
-    ;       import_supplied     % This procedure was imported and its
-                                % termination status was read in from a .opt
-                                % or .trans_opt file.
+    ;       term_reason_import_supplied
+            % This procedure was imported and its termination status
+            % was read in from a .opt or .trans_opt file.
 
-    ;       analysis.           % Termination info. was derived via analysis.
+    ;       term_reason_analysis.
+            % Termination info. was derived via analysis.
 
     % Whether a procedure may be involved in mutual recursion
     % across module boundaries.
@@ -233,43 +237,43 @@
 
 :- type termination2_info
     --->    term2_info(
-            size_var_map :: size_var_map,
                 % Map between prog_vars and size_vars for this procedure.
+                size_var_map        :: size_var_map,
 
-            head_vars :: size_vars,
                 % These are the size variables that occur in argument
                 % size constraints.  For procedures that are imported
                 % via a `.opt' or `.trans_opt' file we set these during
                 % the initial pass, for procedures in the module we are
                 % analysing, pass 1 sets it.
+                head_vars           :: size_vars,
 
-            import_success :: maybe(pragma_constr_arg_size_info),
-            import_failure :: maybe(pragma_constr_arg_size_info),
                 % Arg size info. imported from another module via a
                 % `.opt' or `.trans_opt' file.  Pass 0  needs to convert
                 % these to the proper form.  These particular fields are
                 % of no use after that.
+                import_success      :: maybe(pragma_constr_arg_size_info),
+                import_failure      :: maybe(pragma_constr_arg_size_info),
 
-            success_constrs :: maybe(constr_arg_size_info),
                 % The interargument size relationships
                 % (expressed as convex constraints)
                 % obtained during pass 1.
+                success_constrs     :: maybe(constr_arg_size_info),
 
+                % Failure constraints for predicates that can fail
+                % (set by pass 1).
             failure_constrs :: maybe(constr_arg_size_info),
-                % Failure constraints for predicates that
-                % can fail (set by pass 1).
 
-            term_status :: maybe(constr_termination_info),
                 % The termination status of the procedure as determined
                 % by pass 2.
+                term_status         :: maybe(constr_termination_info),
 
+                % Is this procedure (possibly) involved in mutual recursion
+                % across module boundaries? Set by pass 1.
             intermod_status :: maybe(intermod_status),
-                % Is this procedure (possibly) involved in mutual
-                % recursion across module boundaries? Set by pass 1.
 
+                % The abstract representation of this proc.
+                % Set by term_constr_build.m.
             abstract_rep :: maybe(abstract_proc)
-                % The abstract representation of this
-                % proc. Set by term_constr_build.m.
         ).
 
 term2_info_init = term2_info(map.init, [], no, no, no, no, no, no, no).
@@ -280,54 +284,46 @@
 %
 
 term_constr_main.pass(!ModuleInfo, !IO) :-
-    %
     % Get options required by the build pass.
     % These are:
     %   - which norm we are using.
     %   - whether we are propagating failure constraints.
-    %
     globals.io_get_termination2_norm(Norm, !IO),
     FunctorInfo = set_functor_info(Norm, !.ModuleInfo),
     globals.io_lookup_bool_option(propagate_failure_constrs, Fail, !IO),
     globals.io_lookup_bool_option(arg_size_analysis_only, ArgSizeOnly,
         !IO),
     BuildOptions = build_options_init(FunctorInfo, Fail, ArgSizeOnly),
-    %
+
     % Get options required by the fixpoint pass.
     % These are:
     %   - what cutoff value we are using
     %   - the maximum allowable matrix size
     %     (this is also used in pass 2).
-    %
     globals.io_lookup_int_option(term2_maximum_matrix_size, MaxSize, !IO),
     globals.io_lookup_int_option(widening_limit, CutOff, !IO),
-    %
-    % NOTE: we may eventually allow other types of widening.
-    %
+
+    % NOTE: We may eventually allow other types of widening.
     Widening = after_fixed_cutoff(CutOff),
     FixpointOptions = fixpoint_options_init(Widening, MaxSize),
-    %
+
     % Get options required by pass 2.
     % Currently this is just the maximum matrix size.
-    %
     Pass2Options = pass2_options_init(MaxSize),
-    %
+
     % Setup termination information for builtins and compiler generated
     % predicates.  Setup information from termination pragmas and
     % foreign proc attributes.
-    %
     term_constr_initial.preprocess_module(!ModuleInfo, !IO),
-    %
+
     % Analyse the module per SCC in bottom-up fashion.
-    %
     module_info_ensure_dependency_info(!ModuleInfo),
     module_info_dependency_info(!.ModuleInfo, DepInfo),
     hlds_dependency_info_get_dependency_ordering(DepInfo, SCCs),
     list.foldl2(analyse_scc(SCCs, BuildOptions, FixpointOptions, Pass2Options),
         SCCs, !ModuleInfo, !IO),
-    %
+
     % Write termination2_info pragmas to `.opt' and `.trans_opt' files.
-    %
     maybe_make_optimization_interface(!.ModuleInfo, !IO).
 
 %----------------------------------------------------------------------------%
@@ -354,11 +350,10 @@
     % what (if any) additional information the user has supplied.
     %
     % For Mercury procedures:
-    % If the procedure is marked as terminating/non-terminating, we
-    % still carry out steps (1) and (2).  If a procedure has been
-    % supplied with an argument size constraint we carry out steps (1)
-    % and (3).  If both have been supplied we do not carry out any
-    % steps.
+    % If the procedure is marked as terminating/non-terminating, we still
+    % carry out steps (1) and (2). If a procedure has been supplied with
+    % an argument size constraint we carry out steps (1) and (3). If both
+    % have been supplied we do not carry out any steps.
     %
     % The usual caveats regarding the termination pragmas and mutual
     % recursion apply (see the reference manual).
@@ -492,14 +487,12 @@
   (
       OptFileRes = ok(OptFile),
       io.set_output_stream(OptFile, OldStream, !IO),
-        list.foldl(output_pred_termination2_info(ModuleInfo), PredIds,
-          !IO),
+      list.foldl(output_pred_termination2_info(ModuleInfo), PredIds, !IO),
       io.set_output_stream(OldStream, _, !IO),
       io.close_output(OptFile, !IO),
       maybe_write_string(Verbose, " done.\n", !IO)
   ;
       OptFileRes = error(IOError),
-          % failed to open the .opt file for processing
       maybe_write_string(Verbose, " failed!\n", !IO),
       io.error_message(IOError, IOErrorMessage),
       io.write_strings(["Error opening file `",
@@ -547,7 +540,7 @@
     io::di, io::uo) is det.
 
 make_opt_int_procs(_PredId, [], _, _, _, _, !IO).
-make_opt_int_procs(PredId, [ ProcId | ProcIds ], ProcTable,
+make_opt_int_procs(PredId, [ProcId | ProcIds], ProcTable,
         PredOrFunc, SymName, Context, !IO) :-
     ProcInfo = ProcTable ^ det_elem(ProcId),
     proc_info_get_termination2_info(ProcInfo, TermInfo),
@@ -571,9 +564,8 @@
 %       also be changed so that it can parse the resulting pragma
 %       termination2_info declarations.
 
-output_pragma_termination2_info(PredOrFunc, SymName, ModeList,
-        Context, MaybeSuccess, MaybeFailure, MaybeTermination,
-        HeadVars, !IO) :-
+output_pragma_termination2_info(PredOrFunc, SymName, ModeList, Context,
+        MaybeSuccess, MaybeFailure, MaybeTermination, HeadVars, !IO) :-
     io.write_string(":- pragma termination2_info(", !IO),
     (
         PredOrFunc = pf_predicate,
@@ -604,8 +596,7 @@
 :- pred output_maybe_constr_arg_size_info(map(size_var, int)::in,
     maybe(constr_arg_size_info)::in, io::di, io::uo) is det.
 
-output_maybe_constr_arg_size_info(VarToVarIdMap,
-        MaybeArgSizeConstrs, !IO) :-
+output_maybe_constr_arg_size_info(VarToVarIdMap, MaybeArgSizeConstrs, !IO) :-
     (
         MaybeArgSizeConstrs = no,
         io.write_string("not_set", !IO)
@@ -653,8 +644,7 @@
     proc_info_get_termination2_info(ProcInfo, TermInfo),
     TermInfo ^ success_constrs = yes(_).
 
-    % Succeeds iff the termination status of a the given
-    % procedure has been set.
+    % Succeeds iff the termination status of the given procedure has been set.
     %
 :- pred has_term_info(module_info::in, pred_proc_id::in) is semidet.
 
Index: compiler/term_constr_pass2.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_pass2.m,v
retrieving revision 1.10
diff -u -b -r1.10 term_constr_pass2.m
--- compiler/term_constr_pass2.m	23 Nov 2007 07:35:28 -0000	1.10
+++ compiler/term_constr_pass2.m	5 Jan 2008 10:16:16 -0000
@@ -91,43 +91,40 @@
     % Each edge in the call-graph represents a single call site.
     %
 :- type edge
-    --->    edge(
-                head        :: abstract_ppid,
+    --->    term_cg_edge(
                             % The procedure that is making the call.
+                tcge_caller         :: abstract_ppid,
 
-                zeros       :: set(size_var),
-                            % Variables in the procedure known to have
-                            % zero size.
-
-                head_args   :: size_vars,
-                            % The size_vars that correspond to the
-                            % variables in the head of the procedure.
-
-                label       :: polyhedron,
-                            % The constraints that occur between the
-                            % head of the procedure and the call.
-
-                callee      :: abstract_ppid,
-                            % The callee procedure.
-
-                call_args   :: size_vars
-                            % The size_vars that correspond to the
-                            % variables in the procedure call.
+                % The procedure being called.
+                tcge_callee         :: abstract_ppid,
+
+                % The size_vars that correspond to the variables in the head
+                % of the procedure.
+                tcge_head_args      :: size_vars,
+
+                % The size_vars that correspond to the variables
+                % in the procedure call.
+                tcge_call_args      :: size_vars,
+
+                % Variables in the procedure known to have zero size.
+                tcge_zeros          :: set(size_var),
+
+                % The constraints that occur between the head of the procedure
+                % and the call.
+                tcge_label          :: polyhedron
             ).
 
 :- type edges == list(edge).
 
 :- type cycle
-    --->    cycle(
-                nodes       :: list(abstract_ppid),
-                            % A list of every procedure involved in
-                            % this cycle.
+    --->    term_cg_cycle(
+                % A list of every procedure involved in this cycle.
+                tcgc_nodes          :: list(abstract_ppid),
 
-                edges       :: list(edge)
                             % A list of edges involved in this cycle.
-                            % Note: It is not ordered.  This allows
-                            % us to decide (later) on where we want
-                            % the cycle to start.
+                % Note: The list is not ordered. This allows us to decide
+                % (later) on where we want the cycle to start.
+                tcgc_edges          :: list(edge)
             ).
 
 :- type cycles == list(cycle).
@@ -137,27 +134,27 @@
     % around the cycle conjoining all the labels (constraints) as we go.
     %
 :- type cycle_set
-    --->    c_set(
-                start    :: abstract_ppid,
-                c_cycles :: list(edge)
+    --->    term_cg_cycle_set(
+                tcgcs_start     :: abstract_ppid,
+                tcgcs_cycles    :: list(edge)
             ).
 
 %-----------------------------------------------------------------------------%
 
-prove_termination_in_scc(_, [], _, cannot_loop(analysis), !IO).
-prove_termination_in_scc(Options, SCC0 @ [_|_], ModuleInfo, Result, !IO) :-
+prove_termination_in_scc(_, [], _, cannot_loop(term_reason_analysis), !IO).
+prove_termination_in_scc(Options, SCC0 @ [_ | _], ModuleInfo, Result, !IO) :-
     AbstractSCC = get_abstract_scc(ModuleInfo, SCC0),
     % XXX Pass 1 should really set this up.
     SCC = list.map((func(A) = real(A)), SCC0),
     ( scc_contains_recursion(AbstractSCC) ->
-        Varset = varset_from_abstract_scc(AbstractSCC),
+        SizeVarSet = size_varset_from_abstract_scc(AbstractSCC),
         Edges  = label_edges_in_scc(AbstractSCC, ModuleInfo,
             Options ^ max_matrix_size),
         Cycles    = find_elementary_cycles_in_scc(SCC, Edges),
         CycleSets = partition_cycles(SCC, Cycles),
-        prove_termination(CycleSets, AbstractSCC, Varset, Result)
+        prove_termination(CycleSets, AbstractSCC, SizeVarSet, Result)
     ;
-        Result = cannot_loop(analysis)
+        Result = cannot_loop(term_reason_analysis)
     ).
 
 %-----------------------------------------------------------------------------%
@@ -177,7 +174,7 @@
 label_edges_in_scc(Procs, ModuleInfo, MaxMatrixSize) = Edges :-
     FindEdges = (pred(Proc::in, !.Edges::in, !:Edges::out) is det :-
         find_edges_in_goal(Proc, Procs, ModuleInfo, MaxMatrixSize,
-            Proc ^ body, 1, _, polyhedron.universe, _, [],
+            Proc ^ ap_body, 1, _, polyhedron.universe, _, [],
             ProcEdges, yes, _),
         list.append(ProcEdges, !Edges)
     ),
@@ -195,16 +192,15 @@
     bool::out) is det.
 
 find_edges_in_goal(Proc, AbstractSCC, ModuleInfo, MaxMatrixSize,
-        AbstractGoal, !Calls, !Polyhedron, !Edges, !Continue) :-
-    AbstractGoal = term_disj(Goals, _, Locals, _),
+        Goal, !Calls, !Polyhedron, !Edges, !Continue) :-
+    (
+        Goal = term_disj(Goals, _, Locals, _),
     (
         !.Continue = yes,
-        %
-        % XXX We may be able to prove termination in more cases
-        % if we pass in !.Polyhedron instead of
-        % of polyhedron.universe ... although I don't think
-        % it is a major concern at the moment.
-        %
+
+            % XXX We may be able to prove termination in more cases if we pass
+            % it !.Polyhedron instead of of polyhedron.universe ... although
+            % I don't think it is a major concern at the moment.
         find_edges_in_disj(Proc, AbstractSCC, ModuleInfo,
             MaxMatrixSize, polyhedron.universe, Goals, !Calls,
             [], DisjConstrs0, [], Edges1, !Continue),
@@ -212,66 +208,58 @@
         list.append(Edges2, !Edges),
         (
             !.Continue = yes,
-            Varset = Proc ^ varset,
-            DisjConstrs = polyhedron.project_all(Varset, Locals,
+                SizeVarSet = Proc ^ ap_size_varset,
+                DisjConstrs = polyhedron.project_all(SizeVarSet, Locals,
                 DisjConstrs0),
             Constrs2 = list.foldl(
-                polyhedron.convex_union(Varset,
-                    yes(MaxMatrixSize)), DisjConstrs,
-                    polyhedron.empty),
+                    polyhedron.convex_union(SizeVarSet, yes(MaxMatrixSize)),
+                    DisjConstrs, polyhedron.empty),
             polyhedron.intersection(Constrs2, !Polyhedron)
         ;
             !.Continue = no
         )
     ;
         !.Continue = no
-    ).
-
-find_edges_in_goal(Proc, AbstractSCC, ModuleInfo, MaxMatrixSize,
-        AbstractGoal, !Calls, !Polyhedron, !Edges, !Continue) :-
-    AbstractGoal = term_conj(Goals, Locals, _),
+        )
+    ;
+        Goal = term_conj(Goals, Locals, _),
     (
         !.Continue = yes,
-        list.foldl4(find_edges_in_goal(Proc, AbstractSCC, ModuleInfo,
+            list.foldl4(
+                find_edges_in_goal(Proc, AbstractSCC, ModuleInfo,
                 MaxMatrixSize),
             Goals, !Calls, !Polyhedron, !Edges, !Continue),
         (
-            !.Continue = yes,
-                polyhedron.project(Locals, Proc ^ varset, !Polyhedron)
+                !.Continue = yes, polyhedron.project(Locals,
+                    Proc ^ ap_size_varset, !Polyhedron)
         ;
             !.Continue = no
         )
     ;
         !.Continue = no
-    ).
-
-find_edges_in_goal(Proc, _AbstractSCC, ModuleInfo, _,
-        term_call(CallPPId0, _, CallVars, ZeroVars, _, _, _),
-        !Calls, !Polyhedron, !Edges, !Continue) :-
-    %
-    % Having found a call we now need to construct a label for that
-    % edge and then continue looking for more edges.
-    %
-    Edge = edge(Proc ^ ppid, Proc ^ zeros, Proc ^ head_vars, !.Polyhedron,
-        CallPPId0, CallVars),
+        )
+    ;
+        Goal = term_call(CallPPId0, _, CallVars, ZeroVars, _, _, _),
+        % Having found a call we now need to construct a label for that edge
+        % and then continue looking for more edges.
+        Edge = term_cg_edge(Proc ^ ap_ppid, CallPPId0,
+            Proc ^ ap_head_vars, CallVars, Proc ^ ap_zeros, !.Polyhedron),
     list.cons(Edge, !Edges),
-    %
-    % Update the call count and maybe stop processing if that was
-    % the last call.
-    %
+
+        % Update the call count and maybe stop processing
+        % if that was the last call.
     !:Calls = !.Calls + 1,
-    ( if    !.Calls > Proc ^ calls
-      then  !:Continue = no
-      else  true
+        ( !.Calls > Proc ^ ap_num_calls ->
+            !:Continue = no
+        ;
+            true
     ),
-
     (
         !.Continue = no
     ;
         !.Continue = yes,
         CallPPId0 = real(CallPPId),
-        module_info_pred_proc_info(ModuleInfo, CallPPId,  _,
-            CallProcInfo),
+            module_info_pred_proc_info(ModuleInfo, CallPPId,  _, CallProcInfo),
         proc_info_get_termination2_info(CallProcInfo, CallTermInfo),
         MaybeArgSizeInfo = CallTermInfo ^ success_constrs,
         (
@@ -279,11 +267,9 @@
             unexpected(this_file, "Proc with no arg size info in pass 2.")
         ;
             MaybeArgSizeInfo = yes(ArgSizePolyhedron0),
-            %
-            % If the polyhedron is universe then
-            % there's no point running the substitution.
-            %
             ( polyhedron.is_universe(ArgSizePolyhedron0) ->
+                    % If the polyhedron is universe then there is no point
+                    % in running the substitution.
                 true
             ;
                 MaybeCallProc = CallTermInfo ^ abstract_rep,
@@ -295,7 +281,7 @@
                     unexpected(this_file,
                         "No abstract representation for proc.")
                 ),
-                HeadVars = CallProc ^ head_vars,
+                    HeadVars = CallProc ^ ap_head_vars,
                 Subst = map.from_corresponding_lists(HeadVars, CallVars),
                 Eqns0 = non_false_constraints( ArgSizePolyhedron0),
                 Eqns1 = substitute_size_vars(Eqns0, Subst),
@@ -304,22 +290,21 @@
                 polyhedron.intersection(ArgSizePolyhedron, !Polyhedron)
             )
         )
-    ).
-
-find_edges_in_goal(_, _, _, _, AbstractGoal, !Calls, !Polyhedron, !Edges,
-        !Continue) :-
-    AbstractGoal = term_primitive(Primitive, _, _),
+        )
+    ;
+        Goal = term_primitive(Primitive, _, _),
     (
         !.Continue = yes,
         polyhedron.intersection(Primitive, !Polyhedron)
     ;
         !.Continue = no
+        )
     ).
 
-:- pred find_edges_in_disj(abstract_proc::in, abstract_scc::in, module_info::in,
-    int::in, polyhedron::in, abstract_goals::in, int::in, int::out,
-    polyhedra::in, polyhedra::out, edges::in, edges::out, bool::in,
-    bool::out) is det.
+:- pred find_edges_in_disj(abstract_proc::in, abstract_scc::in,
+    module_info::in, int::in, polyhedron::in, abstract_goals::in,
+    int::in, int::out, polyhedra::in, polyhedra::out, edges::in, edges::out,
+    bool::in, bool::out) is det.
 
 find_edges_in_disj(_, _, _, _, _, [], !Calls, !DisjConstrs, !Edges, !Continue).
 find_edges_in_disj(Proc, AbstractSCC, ModuleInfo, MaxMatrixSize, TopPoly,
@@ -327,11 +312,10 @@
     find_edges_in_goal(Proc, AbstractSCC, ModuleInfo, MaxMatrixSize, Disj,
         !Calls, TopPoly, Constrs, !Edges, !Continue),
     list.cons(Constrs, !DisjConstrs),
-    %
-    % This is why it is important that after numbering the
-    % calls in the AR we don't change anything around; otherwise
-    % this short-circuiting will not work correctly.
-    %
+
+    % This is why it is important that after numbering the calls in the AR
+    % we don't change anything around; otherwise this short-circuiting
+    % will not work correctly.
     (
         !.Continue = yes,
         find_edges_in_disj(Proc, AbstractSCC, ModuleInfo,
@@ -344,7 +328,9 @@
 :- func fix_edges(polyhedron, edge) = edge.
 
 fix_edges(Poly, Edge0) = Edge :-
-    Edge = Edge0 ^ label := polyhedron.intersection(Poly, Edge0 ^ label).
+    Label0 = Edge0 ^ tcge_label,
+    Label = polyhedron.intersection(Poly, Label0),
+    Edge = Edge0 ^ tcge_label := Label.
 
 %-----------------------------------------------------------------------------%
 %
@@ -359,25 +345,21 @@
 :- func find_elementary_cycles_in_scc(list(abstract_ppid), edges) = cycles.
 
 find_elementary_cycles_in_scc(SCC, Edges0) = Cycles :-
-    %
     % Get any self-loops for each procedure.
-    %
     list.filter_map(direct_call, Edges0, Cycles0, Edges),
-    %
+
     % Find larger elementary cycles in what is left.
-    %
     Cycles1 = find_cycles(SCC, Edges),
     Cycles = Cycles0 ++ Cycles1.
 
-    % Succeeds iff Edge is an edge that represents
-    % a directly recursive call (a self-loop in
-    % the pseudograph)
+    % Succeeds iff Edge is an edge that represents a directly recursive call
+    % (a self-loop in the pseudograph)
     %
 :- pred direct_call(edge::in, cycle::out) is semidet.
 
 direct_call(Edge, Cycle) :-
-    Edge ^ head = Edge ^ callee,
-    Cycle = cycle([Edge ^ head], [Edge]).
+    Edge ^ tcge_caller = Edge ^ tcge_callee,
+    Cycle = term_cg_cycle([Edge ^ tcge_caller], [Edge]).
 
 :- func find_cycles(list(abstract_ppid), edges) = cycles.
 
@@ -393,7 +375,8 @@
 partition_edges([], _) = map.init.
 partition_edges([ProcId | SCC], Edges0) = Map :-
     Map0 = partition_edges(SCC, Edges0),
-    Edges = list.filter((pred(Edge::in) is semidet :- ProcId = Edge ^ head),
+    Edges = list.filter(
+        (pred(Edge::in) is semidet :- ProcId = Edge ^ tcge_caller),
         Edges0),
     Map = map.det_insert(Map0, ProcId, Edges).
 
@@ -419,18 +402,18 @@
     cycles::in, cycles::out) is det.
 
 search_for_cycles_3(Start, SoFar, Map, Visited, Edge, !Cycles) :-
-    ( Start = Edge ^ callee ->
-        Cycle = cycle([Edge ^ head | Visited], [Edge | SoFar]),
+    ( Start = Edge ^ tcge_callee ->
+        Cycle = term_cg_cycle([Edge ^ tcge_caller | Visited], [Edge | SoFar]),
         list.cons(Cycle, !Cycles)
     ;
-        ( MoreEdges0 = Map ^ elem(Edge ^ callee) ->
+        ( MoreEdges0 = Map ^ elem(Edge ^ tcge_callee) ->
             NotVisited = (pred(E::in) is semidet :-
-                not list.member(E ^ head, Visited)
+                not list.member(E ^ tcge_caller, Visited)
             ),
             MoreEdges = list.filter(NotVisited, MoreEdges0),
             list.foldl(
                 search_for_cycles_3(Start, [Edge | SoFar], Map,
-                    [Edge ^ head | Visited]),
+                    [Edge ^ tcge_caller | Visited]),
                 MoreEdges, !Cycles)
         ;
             true
@@ -454,7 +437,7 @@
         CycleSets = CycleSets0
     ;
         PEdges = [_ | _],
-        CycleSets = [c_set(Proc, PEdges) | CycleSets0]
+        CycleSets = [term_cg_cycle_set(Proc, PEdges) | CycleSets0]
     ).
 
 :- func get_proc_from_abstract_scc(list(abstract_proc), abstract_ppid)
@@ -462,8 +445,8 @@
 
 get_proc_from_abstract_scc([], _) = _ :-
     unexpected(this_file, "Cannot find proc.").
-get_proc_from_abstract_scc([ Proc | Procs ], PPId) =
-    ( Proc ^ ppid = PPId ->
+get_proc_from_abstract_scc([Proc | Procs], PPId) =
+    ( Proc ^ ap_ppid = PPId ->
         Proc
     ;
         get_proc_from_abstract_scc(Procs, PPId)
@@ -480,12 +463,12 @@
 :- pred prove_termination(list(cycle_set)::in, abstract_scc::in,
     size_varset::in, constr_termination_info::out) is det.
 
-prove_termination(Cycles, AbstractSCC, Varset, Result) :-
-    ( total_sum_decrease(AbstractSCC, Varset, Cycles) ->
-        Result = cannot_loop(analysis)
+prove_termination(Cycles, AbstractSCC, SizeVarSet, Result) :-
+    ( total_sum_decrease(AbstractSCC, SizeVarSet, Cycles) ->
+        Result = cannot_loop(term_reason_analysis)
     ;
-        % NOTE: the context here will never be used, in any
-        % case it's not clear what it should be.
+        % NOTE: The context here will never be used, in any case
+        % it is not clear what it should be.
         Error = term.context_init - cond_not_satisfied,
         Result = can_loop([Error])
     ).
@@ -494,19 +477,20 @@
     list(cycle_set)::in) is semidet.
 
 total_sum_decrease(_, _, []).
-total_sum_decrease(AbstractSCC, Varset, [c_set(Start, Loops) | Cycles]):-
-    total_sum_decrease_2(AbstractSCC, Varset, Start, Loops),
-    total_sum_decrease(AbstractSCC, Varset, Cycles).
+total_sum_decrease(AbstractSCC, SizeVarSet, [CycleSet | CycleSets]):-
+    CycleSet = term_cg_cycle_set(Start, Loops),
+    total_sum_decrease_2(AbstractSCC, SizeVarSet, Start, Loops),
+    total_sum_decrease(AbstractSCC, SizeVarSet, CycleSets).
 
 :- pred total_sum_decrease_2(abstract_scc::in, size_varset::in,
     abstract_ppid::in, list(edge)::in) is semidet.
 
 total_sum_decrease_2(_, _, _, []).
-total_sum_decrease_2(AbstractSCC, Varset, PPId, Loops @ [_|_]) :-
+total_sum_decrease_2(AbstractSCC, SizeVarSet, PPId, Loops @ [_ | _]) :-
     all [Loop] (
         list.member(Loop, Loops)
     =>
-        strict_decrease_around_loop(AbstractSCC, Varset, PPId, Loop)
+        strict_decrease_around_loop(AbstractSCC, SizeVarSet, PPId, Loop)
     ).
 
     % Succeeds iff there is strict decrease in the sum of *all*
@@ -515,34 +499,37 @@
 :- pred strict_decrease_around_loop(abstract_scc::in, size_varset::in,
     abstract_ppid::in, edge::in) is semidet.
 
-strict_decrease_around_loop(AbstractSCC, Varset, PPId, Loop) :-
-    ( if    (PPId \= Loop ^ head ; PPId \= Loop ^ callee)
-      then  unexpected(this_file, "Badly formed loop.")
-      else  true
+strict_decrease_around_loop(AbstractSCC, SizeVarSet, PPId, Loop) :-
+    (
+        ( PPId \= Loop ^ tcge_caller
+        ; PPId \= Loop ^ tcge_callee
+        )
+    ->
+        unexpected(this_file, "Badly formed loop.")
+    ;
+        true
     ),
     IsActive = (func(Var::in, Input::in) = (Var::out) is semidet :-
         Input = yes
     ),
     Proc = get_proc_from_abstract_scc(AbstractSCC, PPId),
-    Inputs = Proc ^ inputs,
-    HeadArgs = list.filter_map_corresponding(IsActive, Loop ^ head_args,
+    Inputs = Proc ^ ap_inputs,
+    HeadArgs = list.filter_map_corresponding(IsActive, Loop ^ tcge_head_args,
         Inputs),
-    CallArgs = list.filter_map_corresponding(IsActive, Loop ^ call_args,
+    CallArgs = list.filter_map_corresponding(IsActive, Loop ^ tcge_call_args,
         Inputs),
     Terms = make_coeffs(HeadArgs, -one) ++ make_coeffs(CallArgs, one),
-    %
-    % NOTE: if you examine the condition it may contain less
-    % variables than you expect.  This is because if the same
-    % argument occurs in the head and the call they will cancel
-    % each other out.
-    %
+
+    % NOTE: If you examine the condition it may contain fewer variables
+    % than you expect. This is because if the same argument occurs in the head
+    % and the call they will cancel each other out.
     Condition = constraint(Terms, (=<), -one),
-    Label = polyhedron.non_false_constraints(Loop ^ label),
-    entailed(Varset, Label, Condition).
+    Label = polyhedron.non_false_constraints(Loop ^ tcge_label),
+    entailed(SizeVarSet, Label, Condition).
 
 :- pred cycle_contains_proc(abstract_ppid::in, cycle::in) is semidet.
 
-cycle_contains_proc(PPId, cycle(Nodes, _)) :- list.member(PPId, Nodes).
+cycle_contains_proc(PPId, term_cg_cycle(Nodes, _)) :- list.member(PPId, Nodes).
 
     % XXX Fix this name.
     %
@@ -561,52 +548,54 @@
 
 :- func collapse_cycle(abstract_ppid, cycle) = edge.
 
-collapse_cycle(_, cycle(_, [])) = _ :-
-    unexpected(this_file, "Trying to collapse a cycle with no edges.").
-collapse_cycle(_, cycle(_, [Edge])) = Edge.
-collapse_cycle(StartPPId, cycle(_, Edges0 @ [_,_|_])) = CollapsedCycle :-
+collapse_cycle(StartPPId, Cycle) = CollapsedCycle :-
+    Cycle = term_cg_cycle(_, Edges0),
+    (
+        Edges0 = [],
+        unexpected(this_file, "Trying to collapse a cycle with no edges.")
+    ;
+        Edges0 = [Edge],
+        CollapsedCycle = Edge
+    ;
+        Edges0 = [_, _ | _],
     order_nodes(StartPPId, Edges0, Edges),
     (
-        Edges = [StartEdge0 | Rest0],
-        StartEdge = StartEdge0,
-        Rest = Rest0
+            Edges = [StartEdge | Rest],
+            StartEdge = term_cg_edge(_, _, HeadVars, CallVars0,
+                Zeros0, Polyhedron0),
+            collapse_cycle_2(Rest, Zeros0, Zeros, CallVars0, CallVars,
+                Polyhedron0, Polyhedron),
+            CollapsedCycle = term_cg_edge(StartPPId, StartPPId,
+                HeadVars, CallVars, Zeros, Polyhedron)
     ;
         Edges = [],
         unexpected(this_file, "Error while collapsing cycles.")
-    ),
-    StartEdge = edge(_, Zeros0, HeadVars, Polyhedron0, _, CallVars0),
-    collapse_cycle_2(Rest, Zeros0, Zeros, CallVars0, CallVars, Polyhedron0,
-        Polyhedron),
-    CollapsedCycle = edge(StartPPId, Zeros, HeadVars, Polyhedron,
-        StartPPId, CallVars).
+        )
+    ).
 
 :- pred collapse_cycle_2(edges::in, zero_vars::in, zero_vars::out,
     size_vars::in, size_vars::out, polyhedron::in, polyhedron::out) is det.
 
 collapse_cycle_2([], !Zeros, !CallVars, !Polyhedron).
 collapse_cycle_2([Edge | Edges], !Zeros, !CallVars, !Polyhedron) :-
-    set.union(Edge ^ zeros, !Zeros),
-    HeadVars = Edge ^ head_args,
+    set.union(Edge ^ tcge_zeros, !Zeros),
+    HeadVars = Edge ^ tcge_head_args,
     Subst0 = assoc_list.from_corresponding_lists(HeadVars, !.CallVars),
     bimap.set_from_assoc_list(Subst0, bimap.init, Subst),
-    %
-    % We now need to substitute variables from the call to *this*
-    % predicate for head variables in both the constraints from the
-    % body of the predicate and also into the variables in the
-    % calls to the next predicate.
-    %
-    % While it might be easier to put equality constraints
-    % between the caller's arguments and the callee's head
-    % arguments the substitution is in some ways more desirable
-    % as we can detect some neutral arguments more directly.
-    %
-    !:CallVars = list.map(subst_size_var(Subst), Edge ^ call_args),
-    %
-    % These should be non-false, so throw an exception if they
-    % are not.
-    %
+
+    % We now need to substitute variables from the call to *this* predicate
+    % for head variables in both the constraints from the body of the predicate
+    % and also into the variables in the calls to the next predicate.
+    %
+    % While it might be easier to put equality constraints between
+    % the caller's arguments and the callee's head arguments,
+    % the substitution is in some ways more desirable as we can detect
+    % some neutral arguments more directly.
+    !:CallVars = list.map(subst_size_var(Subst), Edge ^ tcge_call_args),
+
+    % These should be non-false, so throw an exception if they are not.
     Constraints0 = polyhedron.non_false_constraints(!.Polyhedron),
-    Constraints1 = polyhedron.non_false_constraints(Edge ^ label),
+    Constraints1 = polyhedron.non_false_constraints(Edge ^ tcge_label),
     Constraints2 = list.map(subst_size_var_eqn(Subst), Constraints1),
     Constraints3 = Constraints0 ++ Constraints2,
     !:Polyhedron = polyhedron.from_constraints(Constraints3),
@@ -617,17 +606,17 @@
 order_nodes(StartPPId, Edges0, [Edge | Edges]) :-
     EdgeMap = build_edge_map(Edges0),
     Edge = EdgeMap ^ det_elem(StartPPId),
-    order_nodes_2(StartPPId, Edge ^ callee, EdgeMap, Edges).
+    order_nodes_2(StartPPId, Edge ^ tcge_callee, EdgeMap, Edges).
 
 :- pred order_nodes_2(abstract_ppid::in, abstract_ppid::in,
     map(abstract_ppid, edge)::in, edges::out) is det.
 
 order_nodes_2(StartPPId, CurrPPId, Map, Edges) :-
-    ( if    StartPPId = CurrPPId
-      then  Edges = []
-      else
-            Edge = Map ^ det_elem(CurrPPId),
-            order_nodes_2(StartPPId, Edge ^ callee, Map, Edges0),
+    ( StartPPId = CurrPPId ->
+        Edges = []
+    ;
+        map.lookup(Map, CurrPPId, Edge),
+        order_nodes_2(StartPPId, Edge ^ tcge_callee, Map, Edges0),
             Edges = [Edge | Edges0]
     ).
 
@@ -635,7 +624,7 @@
 
 build_edge_map([]) = map.init.
 build_edge_map([Edge | Edges]) =
-    map.det_insert(build_edge_map(Edges), Edge ^ head, Edge).
+    map.det_insert(build_edge_map(Edges), Edge ^ tcge_caller, Edge).
 
 :- func subst_size_var_eqn(bimap(size_var, size_var), constraint)
     = constraint.
@@ -663,18 +652,19 @@
     io::di, io::uo) is det.
 
 write_cycles([], _, _, !IO).
-write_cycles([Cycle | Cycles], ModuleInfo, Varset, !IO) :-
+write_cycles([Cycle | Cycles], ModuleInfo, SizeVarSet, !IO) :-
     io.write_string("Cycle in SCC:\n", !IO),
-    write_cycle(Cycle ^ nodes, ModuleInfo, !IO),
-    io.write_list(Cycle ^ edges, "\n", write_edge(ModuleInfo, Varset), !IO),
+    write_cycle(Cycle ^ tcgc_nodes, ModuleInfo, !IO),
+    io.write_list(Cycle ^ tcgc_edges, "\n",
+        write_edge(ModuleInfo, SizeVarSet), !IO),
     io.nl(!IO),
-    write_cycles(Cycles, ModuleInfo, Varset, !IO).
+    write_cycles(Cycles, ModuleInfo, SizeVarSet, !IO).
 
 :- pred write_cycle(list(abstract_ppid)::in, module_info::in, io::di, io::uo)
     is det.
 
 write_cycle([], _, !IO).
-write_cycle([ Proc | Procs ], ModuleInfo, !IO) :-
+write_cycle([Proc | Procs], ModuleInfo, !IO) :-
     io.write_string("\t- ", !IO),
     Proc = real(PredProcId),
     hlds_out.write_pred_proc_id(ModuleInfo, PredProcId, !IO),
@@ -684,20 +674,20 @@
 :- pred write_edge(module_info::in, size_varset::in, edge::in,
     io::di, io::uo) is det.
 
-write_edge(ModuleInfo, Varset, Edge, !IO) :-
+write_edge(ModuleInfo, SizeVarSet, Edge, !IO) :-
     io.write_string("Edge is:\n\tHead: ", !IO),
-    Edge ^ head = real(PredProcId),
+    Edge ^ tcge_caller = real(PredProcId),
     hlds_out.write_pred_proc_id(ModuleInfo, PredProcId, !IO),
     io.write_string(" : ", !IO),
-    write_size_vars(Varset, Edge ^ head_args, !IO),
+    write_size_vars(SizeVarSet, Edge ^ tcge_head_args, !IO),
     io.write_string(" :- \n", !IO),
     io.write_string("\tConstraints are:  \n", !IO),
-    write_polyhedron(Edge ^ label, Varset, !IO),
+    write_polyhedron(Edge ^ tcge_label, SizeVarSet, !IO),
     io.write_string("\n\tCall is:  ", !IO),
-    Edge ^ callee = real(CallPredProcId),
+    Edge ^ tcge_callee = real(CallPredProcId),
     hlds_out.write_pred_proc_id(ModuleInfo, CallPredProcId, !IO),
     io.write_string(" : ", !IO),
-    write_size_vars(Varset, Edge ^ call_args, !IO),
+    write_size_vars(SizeVarSet, Edge ^ tcge_call_args, !IO),
     io.write_string(" :- \n", !IO),
     io.nl(!IO).
 
Index: compiler/term_constr_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_util.m,v
retrieving revision 1.12
diff -u -b -r1.12 term_constr_util.m
--- compiler/term_constr_util.m	23 Nov 2007 07:35:28 -0000	1.12
+++ compiler/term_constr_util.m	5 Jan 2008 10:16:27 -0000
@@ -291,7 +291,7 @@
 
 add_context_to_constr_termination_info(no, _, no).
 add_context_to_constr_termination_info(yes(cannot_loop(_)), _,
-        yes(cannot_loop(import_supplied))).
+        yes(cannot_loop(term_reason_import_supplied))).
 add_context_to_constr_termination_info(yes(can_loop(_)), Context,
         yes(can_loop([Context - imported_pred]))).
 
Index: compiler/term_pass1.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_pass1.m,v
retrieving revision 1.38
diff -u -b -r1.38 term_pass1.m
--- compiler/term_pass1.m	30 Dec 2007 08:23:59 -0000	1.38
+++ compiler/term_pass1.m	5 Jan 2008 08:08:39 -0000
@@ -193,13 +193,13 @@
     (
         Result1 = error(_),
         Result = Result1,
-        %
+
         % The error does not necessarily mean that this SCC is nonterminating.
         % We need to check that the remainder of this SCC does not make any
         % nonterminating calls otherwise we might get a software error during
         % pass 2.
         % (See below for details).
-        % 
+
         list.foldl3(check_proc_non_term_calls, PPIds, [],
             OtherTermErrors, !ModuleInfo, !IO),
         list.append(OtherTermErrors, !TermErrors)
@@ -318,24 +318,11 @@
 
 check_goal_non_term_calls(PPId, VarTypes, Goal, !Errors, !ModuleInfo, !IO) :-
     Goal = hlds_goal(GoalExpr, GoalInfo),
-    check_goal_expr_non_term_calls(PPId, VarTypes, GoalExpr, GoalInfo,
-        !Errors, !ModuleInfo, !IO).
-
-:- pred check_goal_expr_non_term_calls(pred_proc_id::in,
-    vartypes::in, hlds_goal_expr::in, hlds_goal_info::in,
-    termination_error_contexts::in, termination_error_contexts::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
-
-check_goal_expr_non_term_calls(PPId, VarTypes, Goal, _, !Errors,
-        !ModuleInfo, !IO):-
-    ( Goal = conj(_, Goals)
-    ; Goal = disj(Goals)
-    ),
-    list.foldl3(check_goal_non_term_calls(PPId, VarTypes), Goals,
-        !Errors, !ModuleInfo, !IO).
-check_goal_expr_non_term_calls(PPId, VarTypes, Goal, GoalInfo,
-       !Errors, !ModuleInfo, !IO) :-
-    Goal = plain_call(CallPredId, CallProcId, Args, _, _, _),
+    (
+        GoalExpr = unify(_, _, _, _, _)
+        % Do nothing.
+    ;
+        GoalExpr = plain_call(CallPredId, CallProcId, Args, _, _, _),
     CallPPId = proc(CallPredId, CallProcId),
     module_info_pred_proc_info(!.ModuleInfo, CallPPId, _, ProcInfo),
     proc_info_get_maybe_termination_info(ProcInfo, TerminationInfo),
@@ -343,7 +330,8 @@
     (
         TerminationInfo = yes(can_loop(_)),
         CanLoopError = can_loop_proc_called(PPId, CallPPId),
-        CanLoopErrorContext = termination_error_context(CanLoopError, Context),
+            CanLoopErrorContext =
+                termination_error_context(CanLoopError, Context),
         list.cons(CanLoopErrorContext, !Errors)
     ;
         ( TerminationInfo = yes(cannot_loop(_))
@@ -352,47 +340,47 @@
     ),
     ( horder_vars(Args, VarTypes) ->
         HigherOrderError = horder_args(PPId, CallPPId),
-        HigherOrderErrorContext = termination_error_context(HigherOrderError,
-            Context),
+            HigherOrderErrorContext =
+                termination_error_context(HigherOrderError, Context),
         list.cons(HigherOrderErrorContext, !Errors)
     ;
         true
-    ).
-check_goal_expr_non_term_calls(_, _, Goal, GoalInfo, !Errors, !ModuleInfo,
-        !IO) :-
-    % XXX Use closure analysis results here.
-    Goal = generic_call(_, _, _, _),
+        )
+    ;
+        GoalExpr = call_foreign_proc(_, _, _, _, _, _, _)
+        % XXX This looks incomplete - juliensf.
+    ;
+        GoalExpr = generic_call(_, _, _, _),
+        % XXX We should use any results from closure analysis here.
     Context = goal_info_get_context(GoalInfo),
     Error = termination_error_context(horder_call, Context),
-    list.cons(Error, !Errors).
-check_goal_expr_non_term_calls(PPId, VarTypes, Goal, _, !Errors, !ModuleInfo,
-        !IO) :-
-    Goal = switch(_, _, Cases),
+        list.cons(Error, !Errors)
+    ;
+        ( GoalExpr = conj(_, Goals)
+        ; GoalExpr = disj(Goals)
+        ),
+        list.foldl3(check_goal_non_term_calls(PPId, VarTypes), Goals,
+            !Errors, !ModuleInfo, !IO)
+    ;
+        GoalExpr = switch(_, _, Cases),
     list.foldl3(check_cases_non_term_calls(PPId, VarTypes), Cases,
-        !Errors, !ModuleInfo, !IO).
-check_goal_expr_non_term_calls(_, _, unify(_, _, _, _, _), _, !Errors,
-        !ModuleInfo, !IO).
-check_goal_expr_non_term_calls(PPId, VarTypes, negation(Goal), _,
-        !Errors, !ModuleInfo, !IO) :-
-    check_goal_non_term_calls(PPId, VarTypes, Goal, !Errors, !ModuleInfo,
-        !IO).
-check_goal_expr_non_term_calls(PPId, VarTypes, Goal, _, !Errors, !ModuleInfo,
-        !IO) :-
-    Goal = scope(_, ScopeGoal),
-    check_goal_non_term_calls(PPId, VarTypes, ScopeGoal, !Errors, !ModuleInfo,
-        !IO).
-check_goal_expr_non_term_calls(PPId, VarTypes, Goal, _, !Errors, !ModuleInfo,
-        !IO) :-
-    Goal = if_then_else(_, Cond, Then, Else),
+            !Errors, !ModuleInfo, !IO)
+    ;
+        GoalExpr = if_then_else(_, Cond, Then, Else),
     Goals = [Cond, Then, Else],
     list.foldl3(check_goal_non_term_calls(PPId, VarTypes), Goals,
-        !Errors, !ModuleInfo, !IO).
-check_goal_expr_non_term_calls(_, _, Goal, _, !Errors, !ModuleInfo, !IO) :-
-    % XXX This looks incomplete - juliensf.
-    Goal = call_foreign_proc(_, _, _, _, _, _, _).
-check_goal_expr_non_term_calls(_, _, shorthand(_), _, _, _, _, _, _, _) :-
+            !Errors, !ModuleInfo, !IO)
+    ;
+        ( GoalExpr = negation(SubGoal)
+        ; GoalExpr = scope(_, SubGoal)
+        ),
+        check_goal_non_term_calls(PPId, VarTypes, SubGoal,
+            !Errors, !ModuleInfo, !IO)
+    ;
+        GoalExpr = shorthand(_),
     unexpected(this_file,
-        "shorthand goal encountered during termination analysis.").
+            "shorthand goal encountered during termination analysis.")
+    ).
 
 :- pred check_cases_non_term_calls(
     pred_proc_id::in, vartypes::in, case::in,
@@ -412,9 +400,7 @@
     maybe(list(pair(pred_proc_id, int)))::out, io::di, io::uo) is det.
 
 solve_equations(Paths, PPIds, Result, !IO) :-
-    (
-        convert_equations(Paths, Varset, Equations, Objective, PPVars)
-    ->
+    ( convert_equations(Paths, Varset, Equations, Objective, PPVars) ->
         map.values(PPVars, AllVars0),
         list.sort_and_remove_dups(AllVars0, AllVars),
         lp_solve(Equations, min, Objective, Varset, AllVars, Soln, !IO),
@@ -456,8 +442,8 @@
     Eqn = eqn(Coeffs, (>=), FloatGamma),
     pred_proc_var(ThisPPId, ThisVar, !Varset, !PPVars),
     Coeffs = [ThisVar - 1.0 | RestCoeffs],
-    Convert = (pred(PPId::in, Coeff::out, !.VS::in, !:VS::out, !.PPV::in,
-            !:PPV::out) is det :-
+    Convert = (pred(PPId::in, Coeff::out, !.VS::in, !:VS::out,
+            !.PPV::in, !:PPV::out) is det :-
         pred_proc_var(PPId, Var, !VS, !PPV),
         Coeff = Var - (-1.0)
     ),
Index: compiler/term_traversal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_traversal.m,v
retrieving revision 1.58
diff -u -b -r1.58 term_traversal.m
--- compiler/term_traversal.m	30 Dec 2007 08:24:00 -0000	1.58
+++ compiler/term_traversal.m	5 Jan 2008 08:00:37 -0000
@@ -133,14 +133,8 @@
     ;
         true
     ),
-    traverse_goal_2(GoalExpr, GoalInfo, Params, !Info, !ModuleInfo, !IO).
-
-:- pred traverse_goal_2(hlds_goal_expr::in, hlds_goal_info::in,
-    traversal_params::in, traversal_info::in, traversal_info::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
-
-traverse_goal_2(Goal, _GoalInfo, Params, !Info, !ModuleInfo, !IO) :-
-    Goal = unify(_Var, _RHS, _UniMode, Unification, _Context),
+    (
+        GoalExpr = unify(_Var, _RHS, _UniMode, Unification, _Context),
     (
         Unification = construct(OutVar, ConsId, Args, Modes, _, _, _),
         (
@@ -177,106 +171,10 @@
         Unification = simple_test(_InVar1, _InVar2)
     ;
         Unification = complicated_unify(_, _, _),
-        unexpected(this_file, "traverse_goal_2/5: complicated unify.")
-    ).
-
-traverse_goal_2(conj(_, Goals), _, Params, !Info, !ModuleInfo, !IO) :-
-    list.reverse(Goals, RevGoals),
-    traverse_conj(RevGoals, Params, !Info, !ModuleInfo, !IO).
-
-traverse_goal_2(switch(_, _, Cases), _, Params, !Info, !ModuleInfo, !IO) :-
-    traverse_switch(Cases, Params, !Info, !ModuleInfo, !IO).
-
-traverse_goal_2(disj(Goals), _, Params, !Info, !ModuleInfo, !IO) :-
-    traverse_disj(Goals, Params, !Info, !ModuleInfo, !IO).
-
-traverse_goal_2(negation(Goal), _, Params, !Info, !ModuleInfo, !IO) :-
-    % The negated goal will not affect the argument sizes since it cannot bind
-    % any active variables.  However, we must traverse it during pass 1 to
-    % ensure that it does not call any non-terminating procedures.  Pass 2
-    % relies on pass 1 having done this.
-    traverse_goal(Goal, Params, !Info, !ModuleInfo, !IO).
-
-traverse_goal_2(scope(_, Goal), _GoalInfo, Params, !Info, !ModuleInfo, !IO) :-
-    traverse_goal(Goal, Params, !Info, !ModuleInfo, !IO).
-
-traverse_goal_2(Goal, _, Params, !Info, !ModuleInfo, !IO) :-
-    Goal = if_then_else(_, Cond, Then, Else),
-    traverse_conj([Then, Cond], Params, !.Info, CondThenInfo, !ModuleInfo,
-        !IO),
-    traverse_goal(Else, Params, !.Info, ElseInfo, !ModuleInfo, !IO),
-    combine_paths(CondThenInfo, ElseInfo, Params, !:Info).
-
-traverse_goal_2(Goal, GoalInfo, Params, !Info, !ModuleInfo, !IO) :-
-    Goal = call_foreign_proc(Attributes, CallPredId, CallProcId, Args,
-        _, _, _),
-    module_info_pred_proc_info(!.ModuleInfo, CallPredId, CallProcId, _,
-        CallProcInfo),
-    proc_info_get_argmodes(CallProcInfo, CallArgModes),
-    ArgVars = list.map(foreign_arg_var, Args),
-    partition_call_args(!.ModuleInfo, CallArgModes, ArgVars, _InVars, OutVars),
-    Context = goal_info_get_context(GoalInfo),
-
-    ( is_termination_known(!.ModuleInfo, proc(CallPredId, CallProcId)) ->
-        error_if_intersect(OutVars, Context, pragma_foreign_code, !Info)
-    ;
-        ( attributes_imply_termination(Attributes) ->
-            error_if_intersect(OutVars, Context, pragma_foreign_code, !Info)
-        ;
-            add_error(Context, does_not_term_pragma(CallPredId), Params, !Info)
-        )
-    ).
-            
-traverse_goal_2(Goal, GoalInfo, Params, !Info, !ModuleInfo, !IO) :-
-    Goal = generic_call(Details, Args, ArgModes, _),
-    Context = goal_info_get_context(GoalInfo),
-    (
-        Details = higher_order(Var, _, _, _),
-        ClosureValueMap = goal_info_get_ho_values(GoalInfo),
-        %
-        % If closure analysis has identified a set of values this higher-order
-        % variable can take, then we can check if they terminate.  We cannot
-        % anything about the size of the arguments of the higher-order call,
-        % so we assume that they are unbounded.
-        %
-        ( ClosureValues0 = ClosureValueMap ^ elem(Var) ->
-            ClosureValues = set.to_sorted_list(ClosureValues0),
-            % XXX intermod
-            list.filter(pred_proc_id_terminates(!.ModuleInfo), ClosureValues,
-                Terminating, NonTerminating),
-            ( 
-                NonTerminating = [],
-                partition_call_args(!.ModuleInfo, ArgModes, Args,
-                    _InVars, OutVars),
-                params_get_ppid(Params, PPId),
-                Error = ho_inf_termination_const(PPId, Terminating),
-                error_if_intersect(OutVars, Context, Error, !Info)
-            ;
-                NonTerminating = [_ | _],
-                % XXX We should tell the user what the
-                % non-terminating closures are.
-                add_error(Context, horder_call, Params, !Info)
-            )
-        ;
-            add_error(Context, horder_call, Params, !Info)      
+            unexpected(this_file, "traverse_goal: complicated unify.")
         )
     ;
-        Details = class_method(_, _, _, _),
-        %
-        % For class method calls, we could probably analyse further than this,
-        % since we know that the method being called must come from one of the
-        % instance declarations, and we could potentially (globally) analyse
-        % these.
-        %
-        add_error(Context, method_call, Params, !Info)
-    ;
-        Details = event_call(_)
-    ;
-        Details = cast(_)
-    ).
-
-traverse_goal_2(Goal, GoalInfo, Params, !Info, !ModuleInfo, !IO) :-
-    Goal = plain_call(CallPredId, CallProcId, Args, _, _, _),
+        GoalExpr = plain_call(CallPredId, CallProcId, Args, _, _, _),
     Context = goal_info_get_context(GoalInfo),
     params_get_ppid(Params, PPId),
     CallPPId = proc(CallPredId, CallProcId),
@@ -290,7 +188,7 @@
 
     partition_call_args(!.ModuleInfo, CallArgModes, Args, InVars, OutVars),
 
-    % Handle existing paths
+        % Handle existing paths.
     (
         CallArgSizeInfo = yes(finite(CallGamma, OutputSuppliers)),
         remove_unused_args(InVars, Args, OutputSuppliers, UsedInVars),
@@ -302,8 +200,8 @@
     ;
         CallArgSizeInfo = no,
         % We should get to this point only in pass 1.  In pass 2,
-        % OutputSuppliersMap will be empty, which will lead to a runtime abort
-        % in map.lookup.
+            % OutputSuppliersMap will be empty, which will lead to
+            % a runtime abort in map.lookup.
         params_get_output_suppliers(Params, OutputSuppliersMap),
         map.lookup(OutputSuppliersMap, CallPPId, OutputSuppliers),
         remove_unused_args(InVars, Args, OutputSuppliers, UsedInVars),
@@ -311,9 +209,7 @@
     ),
 
     % Did we call a non-terminating procedure?
-    (
-        CallTerminationInfo = yes(can_loop(_))
-    ->
+        ( CallTerminationInfo = yes(can_loop(_)) ->
         called_can_loop(Context, can_loop_proc_called(PPId, CallPPId),
             Params, !Info)
     ;
@@ -340,18 +236,111 @@
         % We should get to this point only in pass 2, and then
         % only if this call is to a procedure in the current SCC.
         % In pass 1, RecInputSuppliersMap will be empty.
-        %
         compute_rec_start_vars(Args, RecInputSuppliers, Bag),
         PathStart = yes(CallPPId - Context),
         NewPath = path_info(PPId, PathStart, 0, [], Bag),
         add_path(NewPath, !Info)
     ;
         true
-    ).
+        )
+    ;
+        GoalExpr = call_foreign_proc(Attributes, CallPredId, CallProcId, Args,
+            _, _, _),
+        module_info_pred_proc_info(!.ModuleInfo, CallPredId, CallProcId, _,
+            CallProcInfo),
+        proc_info_get_argmodes(CallProcInfo, CallArgModes),
+        ArgVars = list.map(foreign_arg_var, Args),
+        partition_call_args(!.ModuleInfo, CallArgModes, ArgVars,
+            _InVars, OutVars),
+        Context = goal_info_get_context(GoalInfo),
 
-traverse_goal_2(shorthand(_), _, _, _, _, _, _, _, _) :-
+        ( is_termination_known(!.ModuleInfo, proc(CallPredId, CallProcId)) ->
+            error_if_intersect(OutVars, Context, pragma_foreign_code, !Info)
+        ;
+            ( attributes_imply_termination(Attributes) ->
+                error_if_intersect(OutVars, Context, pragma_foreign_code,
+                    !Info)
+            ;
+                add_error(Context, does_not_term_pragma(CallPredId), Params,
+                    !Info)
+            )
+        )
+    ;
+        GoalExpr = generic_call(Details, Args, ArgModes, _),
+        Context = goal_info_get_context(GoalInfo),
+        (
+            Details = higher_order(Var, _, _, _),
+            ClosureValueMap = goal_info_get_ho_values(GoalInfo),
+
+            % If closure analysis has identified a set of values this
+            % higher-order variable can take, then we can check if they all
+            % terminate. We cannot find out anything about the sizes of the
+            % arguments of the higher-order call, so we assume that they are
+            % unbounded.
+            ( map.search(ClosureValueMap, Var, ClosureValues0) ->
+                ClosureValues = set.to_sorted_list(ClosureValues0),
+                % XXX intermod
+                list.filter(pred_proc_id_terminates(!.ModuleInfo),
+                    ClosureValues, Terminating, NonTerminating),
+                ( 
+                    NonTerminating = [],
+                    partition_call_args(!.ModuleInfo, ArgModes, Args,
+                        _InVars, OutVars),
+                    params_get_ppid(Params, PPId),
+                    Error = ho_inf_termination_const(PPId, Terminating),
+                    error_if_intersect(OutVars, Context, Error, !Info)
+                ;
+                    NonTerminating = [_ | _],
+                    % XXX We should tell the user what the
+                    % non-terminating closures are.
+                    add_error(Context, horder_call, Params, !Info)
+                )
+            ;
+                add_error(Context, horder_call, Params, !Info)      
+            )
+        ;
+            Details = class_method(_, _, _, _),
+            % For class method calls, we could probably analyse further
+            % than this, since we know that the method being called must
+            % come from one of the instance declarations, and we could
+            % potentially (globally) analyse these.
+            add_error(Context, method_call, Params, !Info)
+        ;
+            Details = event_call(_)
+        ;
+            Details = cast(_)
+        )
+    ;
+        GoalExpr = conj(_, Goals),
+        list.reverse(Goals, RevGoals),
+        traverse_conj(RevGoals, Params, !Info, !ModuleInfo, !IO)
+    ;
+        GoalExpr = disj(Goals),
+        traverse_disj(Goals, Params, !Info, !ModuleInfo, !IO)
+    ;
+        GoalExpr = switch(_, _, Cases),
+        traverse_switch(Cases, Params, !Info, !ModuleInfo, !IO)
+    ;
+        GoalExpr = if_then_else(_, Cond, Then, Else),
+        traverse_conj([Then, Cond], Params, !.Info, CondThenInfo,
+            !ModuleInfo, !IO),
+        traverse_goal(Else, Params, !.Info, ElseInfo, !ModuleInfo, !IO),
+        combine_paths(CondThenInfo, ElseInfo, Params, !:Info)
+    ;
+        GoalExpr = negation(SubGoal),
+        % The negated goal will not affect the argument sizes since
+        % it cannot bind any active variables. However, we must traverse it
+        % during pass 1 to ensure that it does not call any non-terminating
+        % procedures. Pass 2 relies on pass 1 having done this.
+        traverse_goal(SubGoal, Params, !Info, !ModuleInfo, !IO)
+    ;
+        GoalExpr = scope(_, SubGoal),
+        traverse_goal(SubGoal, Params, !Info, !ModuleInfo, !IO)
+    ;
+        GoalExpr = shorthand(_),
     % These should have been expanded out by now.
-    unexpected(this_file, "traverse_goal_2/5: shorthand goal.").
+        unexpected(this_file, "traverse_goal_2/5: shorthand goal.")
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -609,29 +598,29 @@
 
 :- type traversal_params
     --->    traversal_params(
-                functor_info :: functor_info,
+                term_trav_functor_info      :: functor_info,
                 
-                ppid :: pred_proc_id,
                 % The procedure we are tracing through.
+                term_trav_ppid              :: pred_proc_id,
                 
-                context :: prog_context,
                 % The context of the procedure.
+                term_trav_context           :: prog_context,
                 
-                vartypes :: vartypes,
+                term_trav_vartypes          :: vartypes,
                 
-                output_suppliers :: map(pred_proc_id, list(bool)),
                 % Output suppliers of each procedure.
                 % Empty during pass 2.
+                term_trav_output_suppliers  :: map(pred_proc_id, list(bool)),
                     
-                rec_input_supplier  :: map(pred_proc_id, list(bool)),
                 % Recursive input suppliers of each procedure.
                 % Empty during pass 1.
+                term_trav_rec_input_supplier :: map(pred_proc_id, list(bool)),
                 
-                max_errors :: int,
                 % Maximum number of errors to gather.
+                term_trav_max_errors        :: int,
                 
-                max_paths :: int
                 % Maximum number of paths to analyze.
+                term_trav_max_paths         :: int
         ).
 
 init_traversal_params(FunctorInfo, PredProcId, Context, VarTypes,
@@ -656,14 +645,14 @@
 :- pred params_get_max_errors(traversal_params::in, int::out) is det.
 :- pred params_get_max_paths(traversal_params::in, int::out) is det.
 
-params_get_functor_info(Params, Params ^ functor_info).
-params_get_ppid(Params, Params ^ ppid).
-params_get_context(Params, Params ^ context).
-params_get_var_types(Params, Params ^ vartypes).
-params_get_output_suppliers(Params, Params ^ output_suppliers).
-params_get_rec_input_suppliers(Params, Params ^ rec_input_supplier).
-params_get_max_errors(Params, Params ^ max_errors).
-params_get_max_paths(Params, Params ^ max_paths).
+params_get_functor_info(Params, Params ^ term_trav_functor_info).
+params_get_ppid(Params, Params ^ term_trav_ppid).
+params_get_context(Params, Params ^ term_trav_context).
+params_get_var_types(Params, Params ^ term_trav_vartypes).
+params_get_output_suppliers(Params, Params ^ term_trav_output_suppliers).
+params_get_rec_input_suppliers(Params, Params ^ term_trav_rec_input_supplier).
+params_get_max_errors(Params, Params ^ term_trav_max_errors).
+params_get_max_paths(Params, Params ^ term_trav_max_paths).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/trailing_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trailing_analysis.m,v
retrieving revision 1.29
diff -u -b -r1.29 trailing_analysis.m
--- compiler/trailing_analysis.m	30 Dec 2007 08:24:00 -0000	1.29
+++ compiler/trailing_analysis.m	5 Jan 2008 07:51:35 -0000
@@ -153,6 +153,7 @@
     ;
         UseTrail = no
     ).
+
 %----------------------------------------------------------------------------%
 %
 % Perform trail usage analysis on a SCC
@@ -174,24 +175,20 @@
 
 process_scc(Debug, Pass1Only, SCC, !ModuleInfo, !IO) :-
     check_procs_for_trail_mods(SCC, ProcResults, !ModuleInfo, !IO),
-    %
+
     % The `Results' above are the results of analysing each individual
     % procedure in the SCC - we now have to combine them in a meaningful way.
-    %
     combine_individual_proc_results(ProcResults,
         TrailingStatus, MaybeAnalysisStatus),
-    %
-    % Print out debugging information.
-    %
+
     (
         Debug = yes,
         dump_trail_usage_debug_info(!.ModuleInfo, SCC, TrailingStatus, !IO)
     ;
         Debug = no
     ),
-    %
+
     % Update the trailing_info with information about this SCC.
-    %
     module_info_get_trailing_info(!.ModuleInfo, TrailingInfo0),
     Update = (pred(PPId::in, Info0::in, Info::out) is det :-
         Info = Info0 ^ elem(PPId) :=
@@ -199,9 +196,8 @@
     ),
     list.foldl(Update, SCC, TrailingInfo0, TrailingInfo),
     module_info_set_trailing_info(TrailingInfo, !ModuleInfo),
-    %
-    % Record the analysis results for the intermodule analysis
-    %
+
+    % Record the analysis results for the intermodule analysis.
     globals.io_lookup_bool_option(make_analysis_registry,
         MakeAnalysisRegistry, !IO),
     (
@@ -246,13 +242,19 @@
     (
         % If none of the procedures modifies the trail or is conditional then
         % the SCC cannot modify the trail.
-        all [ProcResult] list.member(ProcResult, ProcResults) =>
+        all [ProcResult] (
+            list.member(ProcResult, ProcResults)
+        =>
             ProcResult ^ status = trail_will_not_modify
+        )
     ->
         SCC_Result = trail_will_not_modify
     ;
-        all [EResult] list.member(EResult, ProcResults) =>
-                EResult ^ status \= trail_may_modify,
+        all [EResult] (
+            list.member(EResult, ProcResults)
+        =>
+            EResult ^ status \= trail_may_modify
+        ),
         some [CResult] (
             list.member(CResult, ProcResults),
             CResult ^ status = trail_conditional
@@ -306,19 +308,13 @@
     trailing_status::out, maybe(analysis_status)::out,
     module_info::in, module_info::out, io::di, io::uo) is det.
 
-check_goal_for_trail_mods(SCC, VarTypes, hlds_goal(GoalExpr, GoalInfo),
-        Result, MaybeStatus, !ModuleInfo, !IO) :-
-    check_goal_for_trail_mods_2(SCC, VarTypes, GoalExpr, GoalInfo,
-        Result, MaybeStatus, !ModuleInfo, !IO).
-
-:- pred check_goal_for_trail_mods_2(scc::in,
-    vartypes::in, hlds_goal_expr::in, hlds_goal_info::in,
-    trailing_status::out, maybe(analysis_status)::out,
-    module_info::in, module_info::out, io::di, io::uo) is det.
-
-check_goal_for_trail_mods_2(_, _, GoalExpr, _, trail_will_not_modify,
-        yes(optimal), !ModuleInfo, !IO) :-
+check_goal_for_trail_mods(SCC, VarTypes, Goal, Result, MaybeAnalysisStatus,
+        !ModuleInfo, !IO) :-
+    Goal = hlds_goal(GoalExpr, GoalInfo),
+    (
     GoalExpr = unify(_, _, _, Kind, _),
+        Result = trail_will_not_modify,
+        MaybeAnalysisStatus = yes(optimal),
     (
         ( Kind = construct(_, _, _, _, _, _, _)
         ; Kind = deconstruct(_, _, _, _, _, _)
@@ -327,10 +323,10 @@
         )
     ;
         Kind = complicated_unify(_, _, _),
-        unexpected(this_file, "complicated unify during trail usage analysis.")
-    ).
-check_goal_for_trail_mods_2(SCC, VarTypes, GoalExpr, _,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
+            unexpected(this_file,
+                "complicated unify during trail usage analysis.")
+        )
+    ;
     GoalExpr = plain_call(CallPredId, CallProcId, CallArgs, _, _, _),
     CallPPId = proc(CallPredId, CallProcId),
     module_info_pred_info(!.ModuleInfo, CallPredId, CallPredInfo),
@@ -361,8 +357,9 @@
         ),
         special_pred_name_arity(SpecialPredId, Name, _, Arity)
     ->
-        % XXX We should examine the argument types of calls to builtin.unify/2
-        % and builtin.compare/3 and then make a decision based on those.
+            % XXX We should examine the argument types of calls to
+            % builtin.unify/2 and builtin.compare/3 and then make a decision
+            % based on those.
         Result = trail_may_modify,
         MaybeAnalysisStatus = yes(optimal)
     ;
@@ -378,9 +375,9 @@
             Intermod = yes,
             pred_info_is_imported(CallPredInfo)
         ->
-            % With --intermodule-analysis use check_call_2 to look up results
-            % for locally defined procedures, otherwise we use the intermodule
-            % analysis framework.
+                % With --intermodule-analysis use check_call_2 to look up
+                % results for locally defined procedures, otherwise we use
+                % the intermodule analysis framework.
             search_analysis_status(CallPPId, Result0, AnalysisStatus, SCC,
                 !ModuleInfo, !IO),
             (
@@ -401,8 +398,8 @@
                     MaybeAnalysisStatus))
             ;
                 MaybeResult = no,
-                % If we do not have any information about the callee procedure
-                % then assume that it modifies the trail.
+                    % If we do not have any information about the callee
+                    % procedure then assume that it modifies the trail.
                 Result = trail_may_modify,
                 (
                     Intermod = yes,
@@ -413,10 +410,8 @@
                 )
             )
         )
-    ).
-
-check_goal_for_trail_mods_2(_, _VarTypes, GoalExpr, _GoalInfo,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
+        )
+    ;
     GoalExpr = generic_call(Details, _Args, _ArgModes, _),
     (
         % XXX Use results of closure analysis to handle this.
@@ -434,42 +429,28 @@
         ),
         Result  = trail_will_not_modify,
         MaybeAnalysisStatus = yes(optimal)
-    ).
-check_goal_for_trail_mods_2(SCC, VarTypes, negation(Goal), _,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    check_goal_for_trail_mods(SCC, VarTypes, Goal, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO).
-check_goal_for_trail_mods_2(SCC, VarTypes, GoalExpr, OuterGoalInfo,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    GoalExpr = scope(_, InnerGoal),
-    check_goal_for_trail_mods(SCC, VarTypes, InnerGoal, Result0,
-        MaybeAnalysisStatus, !ModuleInfo, !IO),
-    InnerGoal = hlds_goal(_, InnerGoalInfo),
-    InnerCodeModel = goal_info_get_code_model(InnerGoalInfo),
-    OuterCodeModel = goal_info_get_code_model(OuterGoalInfo),
-    %
-    % `trail_conditional' scope goals (of the type that require extra trailing
-    % code) will have there status changed to `trail_may_modify'.
-    % See the comment in the clause that handles if-then-elses below
-    % for the reason why.
-    %
-    Result = scope_implies_trail_mod(InnerCodeModel, OuterCodeModel, Result0).
-check_goal_for_trail_mods_2(_, _, GoalExpr, _, Result, MaybeAnalysisStatus,
-        !ModuleInfo, !IO) :-
+        )
+    ;
     GoalExpr = call_foreign_proc(Attributes, _, _, _, _, _, _),
     Result = attributes_imply_trail_mod(Attributes),
-    MaybeAnalysisStatus = yes(optimal).
-check_goal_for_trail_mods_2(_, _, shorthand(_), _, _, _, !ModuleInfo, !IO) :-
-    unexpected(this_file,
-        "shorthand goal encountered during trail usage analysis.").
-check_goal_for_trail_mods_2(SCC, VarTypes, GoalExpr, _,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
+        MaybeAnalysisStatus = yes(optimal)
+    ;
+        GoalExpr = conj(_ConjType, Goals),
+        check_goals_for_trail_mods(SCC, VarTypes, Goals,
+            Result, MaybeAnalysisStatus, !ModuleInfo, !IO)
+    ;
+        GoalExpr = disj(Goals),
+        check_goals_for_trail_mods(SCC, VarTypes, Goals,
+            _Result0, MaybeAnalysisStatus, !ModuleInfo, !IO),
+        % XXX Currently we have to put trailing code around disjunctions.
+        % If we introduce trail specialisation, it may be possible to omit it.
+        Result = trail_may_modify
+    ;
     GoalExpr = switch(_, _, Cases),
     CaseGoals = list.map((func(case(_, _, CaseGoal)) = CaseGoal), Cases),
     check_goals_for_trail_mods(SCC, VarTypes, CaseGoals,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO).
-check_goal_for_trail_mods_2(SCC, VarTypes, GoalExpr, _,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
+            Result, MaybeAnalysisStatus, !ModuleInfo, !IO)
+    ;
     GoalExpr = if_then_else(_, Cond, Then, Else),
     check_goals_for_trail_mods(SCC, VarTypes, [Cond, Then, Else],
         Result0, MaybeAnalysisStatus, !ModuleInfo, !IO),
@@ -478,40 +459,52 @@
         % and is not model_non then we can omit the trailing ops around
         % the condition.
         % 
-        % NOTE: any changes here may need to be relected in the clause
-        % of add_trail_ops.goal_expr_add_trail_ops that handles if_then_elses.
-        %
+            % NOTE: any changes here may need to be reflected in the handling
+            % of if_then-elses in add_trail_ops.m.
+
         Result0 = trail_will_not_modify,
         Cond = hlds_goal(_CondGoalExpr, CondGoalInfo),
         goal_info_get_code_model(CondGoalInfo) \= model_non
     -> 
         Result = trail_will_not_modify
     ;
-        % If the condition modifies the trail, is model_non or both then
-        % we need to emit trailing ops around the conditoin.  If the
+            % If the condition modifies the trail, is model_non or both,
+            % then we need to emit trailing ops around the conditoin. If the
         % if-then-else has status `trail_conditional' then we also need
         % to emit the trail ops because we cannot be sure that calls to
         % builtin.{unify,compare} won't call user-defined equality or
         % comparison predicates that modify the trail.
         % 
-        % NOTE: conditional procedures whose status is changed here are
-        % candidates for generating specialized versions that omit
+            % NOTE: Conditional procedures whose status is changed here
+            % are candidates for generating specialized versions that omit
         % the trailing code.
-        %
+
         Result = trail_may_modify
+        )
+    ;
+        GoalExpr = negation(SubGoal),
+        check_goal_for_trail_mods(SCC, VarTypes, SubGoal, Result,
+            MaybeAnalysisStatus, !ModuleInfo, !IO)
+    ;
+        GoalExpr = scope(_, InnerGoal),
+        OuterGoalInfo = GoalInfo,
+        check_goal_for_trail_mods(SCC, VarTypes, InnerGoal, Result0,
+            MaybeAnalysisStatus, !ModuleInfo, !IO),
+        InnerGoal = hlds_goal(_, InnerGoalInfo),
+        InnerCodeModel = goal_info_get_code_model(InnerGoalInfo),
+        OuterCodeModel = goal_info_get_code_model(OuterGoalInfo),
+
+        % `trail_conditional' scope goals (of the type that require extra
+        % trailing code) will have their status changed to `trail_may_modify'.
+        % See the comment in the code handling if-then-elses above for
+        % the reason why.
+        Result = scope_implies_trail_mod(InnerCodeModel, OuterCodeModel,
+            Result0)
+    ;
+        GoalExpr = shorthand(_),
+        unexpected(this_file,
+            "shorthand goal encountered during trail usage analysis.")
     ).
-check_goal_for_trail_mods_2(SCC, VarTypes, conj(_, Goals), _,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    check_goals_for_trail_mods(SCC, VarTypes, Goals,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO).
-check_goal_for_trail_mods_2(SCC, VarTypes, disj(Goals), _,
-        Result, MaybeAnalysisStatus, !ModuleInfo, !IO) :-
-    check_goals_for_trail_mods(SCC, VarTypes, Goals,
-        _Result0, MaybeAnalysisStatus, !ModuleInfo, !IO),
-    % XXX Currently we have to put trailing code around disjunctions.
-    %     If we introduce trail specialisation it may be possible to
-    %     omit it.
-    Result = trail_may_modify.
 
 :- pred check_goals_for_trail_mods(scc::in, vartypes::in,
     hlds_goals::in, trailing_status::out, maybe(analysis_status)::out,
@@ -595,6 +588,7 @@
 %
 % Further code to handle higher-order variables
 %
+
     % Extract those procedures whose trailing_status has been set to
     % `conditional'.  Fails if one of the procedures in the set
     % is known to modify the trail or if the trailing status is not
@@ -629,7 +623,7 @@
 :- pred combine_trailing_status(trailing_status::in, trailing_status::in,
     trailing_status::out) is det.
 
-combine_trailing_status(trail_will_not_modify, Y, Y).
+combine_trailing_status(trail_will_not_modify, Status, Status).
 combine_trailing_status(trail_may_modify, _, trail_may_modify).
 combine_trailing_status(trail_conditional, trail_will_not_modify,
     trail_conditional).
@@ -687,10 +681,9 @@
             MaybeResult = yes(CalleeTrailingInfo)
         ;
             CalleeTrailingStatus = trail_conditional,
-            %
-            % This is a call to a polymorphic procedure.  We need to make
-            % sure that none of the types involved has a user-defined
-            % equality or comparison predicate that modifies the trail.
+            % This is a call to a polymorphic procedure. We need to make sure
+            % that none of the types involved has a user-defined equality
+            % or comparison predicate that modifies the trail.
             % XXX Need to handle higher-order args here as well.
             MaybeResult = yes(proc_trailing_info(TrailingStatus,
                 AnalysisStatus)),
@@ -756,7 +749,8 @@
 check_type(ModuleInfo, Type) = Status :-
     (
         ( is_solver_type(ModuleInfo, Type)
-        ; is_existq_type(ModuleInfo, Type))
+        ; is_existq_type(ModuleInfo, Type)
+        )
      ->
         % XXX At the moment we just assume that existential
         % types and solver types may modify the trail.
@@ -768,48 +762,42 @@
 
 :- func check_type_2(module_info, mer_type, type_category) = trailing_status.
 
-check_type_2(_, _, type_cat_int) = trail_will_not_modify.
-check_type_2(_, _, type_cat_char) = trail_will_not_modify.
-check_type_2(_, _, type_cat_string) = trail_will_not_modify.
-check_type_2(_, _, type_cat_float) = trail_will_not_modify.
-check_type_2(_, _, type_cat_higher_order) = trail_will_not_modify.
-check_type_2(_, _, type_cat_type_info) = trail_will_not_modify.
-check_type_2(_, _, type_cat_type_ctor_info) = trail_will_not_modify.
-check_type_2(_, _, type_cat_typeclass_info) = trail_will_not_modify.
-check_type_2(_, _, type_cat_base_typeclass_info) = trail_will_not_modify.
-check_type_2(_, _, type_cat_void) = trail_will_not_modify.
-check_type_2(_, _, type_cat_dummy) = trail_will_not_modify.
-
-check_type_2(_, _, type_cat_variable) = trail_conditional.
-
-check_type_2(ModuleInfo, Type, type_cat_tuple) =
-    check_user_type(ModuleInfo, Type).
-check_type_2(ModuleInfo, Type, type_cat_enum) =
-    check_user_type(ModuleInfo, Type).
-check_type_2(ModuleInfo, Type, type_cat_foreign_enum) =
-    check_user_type(ModuleInfo, Type).
-check_type_2(ModuleInfo, Type, type_cat_user_ctor) =
-    check_user_type(ModuleInfo, Type).
-
-:- func check_user_type(module_info, mer_type) = trailing_status.
-
-check_user_type(ModuleInfo, Type) = Status :-
-    ( type_to_ctor_and_args(Type, _TypeCtor, Args) ->
+check_type_2(ModuleInfo, Type, TypeCat) = Status :-
+    (
+        ( TypeCat = type_cat_int
+        ; TypeCat = type_cat_char
+        ; TypeCat = type_cat_string
+        ; TypeCat = type_cat_float
+        ; TypeCat = type_cat_higher_order
+        ; TypeCat = type_cat_type_info
+        ; TypeCat = type_cat_type_ctor_info
+        ; TypeCat = type_cat_typeclass_info
+        ; TypeCat = type_cat_base_typeclass_info
+        ; TypeCat = type_cat_void
+        ; TypeCat = type_cat_dummy
+        ),
+        Status = trail_will_not_modify
+    ;
+        TypeCat = type_cat_variable,
+        Status = trail_conditional
+    ;
+        ( TypeCat = type_cat_tuple
+        ; TypeCat = type_cat_enum
+        ; TypeCat = type_cat_foreign_enum
+        ; TypeCat = type_cat_user_ctor
+        ),
+        type_to_ctor_and_args_det(Type, _TypeCtor, Args),
         (
             type_has_user_defined_equality_pred(ModuleInfo, Type,
                 _UnifyCompare)
         ->
-            % XXX We can do better than this by examining
-            % what these preds actually do.  Something
-            % similar needs to be sorted out for termination
-            % analysis as well, so we'll wait until that is
-            % done.
+            % XXX We can do better than this by examining what these preds
+            % actually do. Something similar needs to be sorted out for
+            % termination analysis as well, so we'll wait until that is done.
             Status = trail_may_modify
         ;
             Status = check_types(ModuleInfo, Args)
         )
-    ;
-        unexpected(this_file, "Unable to get ctor and args.")
     ).
 
 %----------------------------------------------------------------------------%
@@ -858,13 +846,23 @@
     hlds_goal_expr::in, hlds_goal_expr::out, trailing_status::out,
     module_info::in, module_info::out, io::di, io::uo) is det.
 
-annotate_goal_2(VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = conj(ConjType, Conjuncts0),
-    annotate_goal_list(VarTypes, Conjuncts0, Conjuncts, Status, !ModuleInfo,
-        !IO),
-    !:Goal = conj(ConjType, Conjuncts).
-annotate_goal_2(VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = plain_call(CallPredId, CallProcId, CallArgs, _, _, _),
+annotate_goal_2(VarTypes, GoalInfo, !GoalExpr, Status, !ModuleInfo, !IO) :-
+    (
+        !.GoalExpr = unify(_, _, _, Kind, _),
+        (
+            ( Kind = construct(_, _, _, _, _, _, _)
+            ; Kind = deconstruct(_, _, _, _, _, _)
+            ; Kind = assign(_, _)
+            ; Kind = simple_test(_, _)
+            )
+        ;
+            Kind = complicated_unify(_, _, _),
+            unexpected(this_file,
+                "complicated unify during trail usage analysis.")
+        ),
+        Status = trail_will_not_modify
+    ;
+        !.GoalExpr = plain_call(CallPredId, CallProcId, CallArgs, _, _, _),
     CallPPId = proc(CallPredId, CallProcId),
     module_info_pred_info(!.ModuleInfo, CallPredId, CallPredInfo),
     (
@@ -890,15 +888,16 @@
     ->
         Status = Status0
     ;
-        globals.io_lookup_bool_option(intermodule_analysis, IntermodAnalysis,
-            !IO),
+            globals.io_lookup_bool_option(intermodule_analysis,
+                IntermodAnalysis, !IO),
         (
             IntermodAnalysis = yes,
             pred_info_is_imported(CallPredInfo)
         ->
-            % NOTE: we set the value of SCC to a dummy value here.  This is OK
-            % because it only needs a meaningful value when building the
-            % analysis files; it won't be used when compiling to target code.
+                % NOTE: we set the value of SCC to a dummy value here.
+                % This is OK because it only needs a meaningful value
+                % when building the analysis files; it won't be used
+                % when compiling to target code.
             SCC = [],
             search_analysis_status(CallPPId, Result, AnalysisStatus, SCC,
                 !ModuleInfo, !IO),
@@ -926,59 +925,42 @@
             % This time around we will be checking recursive calls as well.
             check_call(!.ModuleInfo, VarTypes, CallPPId, CallArgs, Status)
         )
-    ).
-annotate_goal_2(_VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    % XXX Use closure analysis results here.
-    !.Goal = generic_call(Details, _, _, _),
+        )
+    ;
+        !.GoalExpr = call_foreign_proc(Attributes, _, _, _, _, _, _),
+        Status = attributes_imply_trail_mod(Attributes)
+    ;
+        % XXX We should use any results from closure analysis here.
+        !.GoalExpr = generic_call(GenericCall, _, _, _),
     (
-        Details = higher_order(_, _, _, _),
+            GenericCall = higher_order(_, _, _, _),
         Status = trail_may_modify
     ;
-        Details = class_method(_, _, _, _),
+            GenericCall = class_method(_, _, _, _),
         Status = trail_may_modify
     ;
-        Details = event_call(_),
+            GenericCall = event_call(_),
         Status = trail_will_not_modify
     ;
-        Details = cast(_),
+            GenericCall = cast(_),
         Status = trail_will_not_modify
-    ).
-annotate_goal_2(VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = switch(Var, CanFail, Cases0),
-    annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo, !IO),
-    !:Goal = switch(Var, CanFail, Cases).
-annotate_goal_2(_VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = unify(_, _, _, Kind, _),
-    (
-        ( Kind = construct(_, _, _, _, _, _, _)
-        ; Kind = deconstruct(_, _, _, _, _, _)
-        ; Kind = assign(_, _)
-        ; Kind = simple_test(_, _)
         )
     ;
-        Kind = complicated_unify(_, _, _),
-        unexpected(this_file, "complicated unify during trail usage analysis.")
-    ),
-    Status = trail_will_not_modify.
-annotate_goal_2(VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = disj(Disjuncts0),
+        !.GoalExpr = conj(ConjType, Conjuncts0),
+        annotate_goal_list(VarTypes, Conjuncts0, Conjuncts, Status,
+            !ModuleInfo, !IO),
+        !:GoalExpr = conj(ConjType, Conjuncts)
+    ;
+        !.GoalExpr = disj(Disjuncts0),
     annotate_goal_list(VarTypes, Disjuncts0, Disjuncts, Status,
         !ModuleInfo, !IO),
-    !:Goal = disj(Disjuncts).
-annotate_goal_2(VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = negation(NegGoal0),
-    annotate_goal(VarTypes, NegGoal0, NegGoal, Status, !ModuleInfo, !IO),
-    !:Goal = negation(NegGoal).
-annotate_goal_2(VarTypes, OuterGoalInfo, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = scope(Reason, InnerGoal0),
-    annotate_goal(VarTypes, InnerGoal0, InnerGoal, Status0, !ModuleInfo, !IO),
-    InnerGoal = hlds_goal(_, InnerGoalInfo),
-    InnerCodeModel = goal_info_get_code_model(InnerGoalInfo),
-    OuterCodeModel = goal_info_get_code_model(OuterGoalInfo),
-    Status = scope_implies_trail_mod(InnerCodeModel, OuterCodeModel, Status0),
-    !:Goal = scope(Reason, InnerGoal).
-annotate_goal_2(VarTypes, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = if_then_else(Vars, If0, Then0, Else0),
+        !:GoalExpr = disj(Disjuncts)
+    ;
+        !.GoalExpr = switch(Var, CanFail, Cases0),
+        annotate_cases(VarTypes, Cases0, Cases, Status, !ModuleInfo, !IO),
+        !:GoalExpr = switch(Var, CanFail, Cases)
+    ;
+        !.GoalExpr = if_then_else(Vars, If0, Then0, Else0),
     annotate_goal(VarTypes, If0, If, IfStatus, !ModuleInfo, !IO),
     annotate_goal(VarTypes, Then0, Then, ThenStatus, !ModuleInfo, !IO),
     annotate_goal(VarTypes, Else0, Else, ElseStatus, !ModuleInfo, !IO),
@@ -991,12 +973,26 @@
     ;
         Status = trail_may_modify
     ),
-    !:Goal = if_then_else(Vars, If, Then, Else).
-annotate_goal_2(_, _, !Goal, Status, !ModuleInfo, !IO) :-
-    !.Goal = call_foreign_proc(Attributes, _, _, _, _, _, _),
-    Status = attributes_imply_trail_mod(Attributes).
-annotate_goal_2(_, _, shorthand(_), _, _, _, _, _, _) :-
-    unexpected(this_file, "shorthand goal").
+        !:GoalExpr = if_then_else(Vars, If, Then, Else)
+    ;
+        !.GoalExpr = negation(SubGoal0),
+        annotate_goal(VarTypes, SubGoal0, SubGoal, Status, !ModuleInfo, !IO),
+        !:GoalExpr = negation(SubGoal)
+    ;
+        !.GoalExpr = scope(Reason, InnerGoal0),
+        OuterGoalInfo = GoalInfo,
+        annotate_goal(VarTypes, InnerGoal0, InnerGoal, Status0,
+            !ModuleInfo, !IO),
+        InnerGoal = hlds_goal(_, InnerGoalInfo),
+        InnerCodeModel = goal_info_get_code_model(InnerGoalInfo),
+        OuterCodeModel = goal_info_get_code_model(OuterGoalInfo),
+        Status = scope_implies_trail_mod(InnerCodeModel, OuterCodeModel,
+            Status0),
+        !:GoalExpr = scope(Reason, InnerGoal)
+    ;
+        !.GoalExpr = shorthand(_),
+        unexpected(this_file, "shorthand goal")
+    ).
 
 :- pred annotate_goal_list(vartypes::in, hlds_goals::in,
     hlds_goals::out, trailing_status::out, module_info::in,
@@ -1123,6 +1119,7 @@
     --->    trailing_analysis_answer(trailing_status).
 
 :- func analysis_name = string.
+
 analysis_name = "trail_usage".
 
 :- instance analysis(any_call, trailing_analysis_answer) where [
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/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