[m-rev.] for review: goal_path representation

Zoltan Somogyi zs at csse.unimelb.edu.au
Wed Sep 21 19:47:46 AEST 2011


For review by anyone.

Zoltan.

Change the types that represent forward and reverse goal paths from being
wrappers around lists of steps, to being full discriminated union types.
This is meant to accomplish two objectives.

First, since taking the wrappers off and putting them back on is inconvenient,
code often dealt with naked lists of steps, with the meaning of those steps
sometimes being unclear.

Second, in a future change I intend to change the way the debugger represents
goal paths from being strings to being statically allocated terms of the
reverse_goal_path type. This should have two benefits. One is reduced memory
consumption, since two different goal path strings cannot share memory
but two different reverse goal paths can share the memory containing their
common tail (the goal paths steps near the root). The other is that the
declarative debugger won't need to do any conversion from string to structure,
and should therefore be faster.

Having the compiler generate static terms of the reverse_goal_path type into
the .c files it generates for every Mercury program being compiled with
debugging requires it to have access to the definition of that type and all
its components. The best way to do this is to put all those types into a new
builtin module in the library (a debugging equivalent of e.g.
profiling_builtin.m). We cannot put the definition of the list type into
that module without causing considerable backward incompatibilities.

mdbcomp/mdbcomp.goal_path.m:
	Make the change described above.

	Add some more predicates implementing abstract operations on goal
	paths.

browser/declarative_tree.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/hlds_goal.m:
compiler/introduce_parallelism.m:
compiler/mode_ordering.m:
compiler/push_goals_together.m:
compiler/rbmm.condition_renaming.m:
compiler/trace_gen.m:
compiler/tupling.m:
compiler/unneeded_code.m:
deep_profiler/autopar_costs.m:
deep_profiler/autopar_reports.m:
deep_profiler/autopar_search_callgraph.m:
deep_profiler/autopar_search_goals.m:
deep_profiler/create_report.m:
deep_profiler/message.m:
deep_profiler/program_representation_utils.m:
deep_profiler/read_profile.m:
deep_profiler/recursion_patterns.m:
deep_profiler/var_use_analysis.m:
	Conform to the change in representation. In some cases, remove
	predicates whose only job was to manipulate wrappers. In others,
	replace concrete operations on lists of steps with abstract operations
	on goal paths.

compiler/mode_constraints.m:
	Comment out some code that I do not understand, which I think never
	worked (not surprising, since the whole module has never been
	operational).

mdbcomp/slice_and_dice.m:
	Since this diff changes the types representing goal paths, it also
	changes their default ordering, as implemented by builtin.compare.
	When ordering slices and dices by goal paths, make the ordering
	explicitly work on the forward goal path, since ordering by the
	reverse goal path (the actual data being used) gives nonintuitive
	results.

library/list.m:
	Speed up some code.

mdbcomp/feedback.automatic_parallelism.m:
	Fix some formatting.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
Index: browser/declarative_tree.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_tree.m,v
retrieving revision 1.66
diff -u -b -r1.66 declarative_tree.m
--- browser/declarative_tree.m	10 May 2011 04:12:24 -0000	1.66
+++ browser/declarative_tree.m	19 Sep 2011 09:10:05 -0000
@@ -915,7 +915,7 @@
     GoalRep = ProcDefnRep ^ pdr_goal,
     is_traced_grade(AllTraced),
     MaybePrims = make_primitive_list(Store,
-        [goal_and_path(GoalRep, rgp([]))], Contour, StartPath, ArgNum,
+        [goal_and_path(GoalRep, rgp_nil)], Contour, StartPath, ArgNum,
         TotalArgs, HeadVars, AllTraced, []),
     (
         MaybePrims = yes(primitive_list_and_var(Primitives, Var,
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/goal_path.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_path.m,v
retrieving revision 1.62
diff -u -b -r1.62 goal_path.m
--- compiler/goal_path.m	23 May 2011 05:08:03 -0000	1.62
+++ compiler/goal_path.m	19 Sep 2011 09:58:59 -0000
@@ -125,7 +125,7 @@
     proc_info_get_goal(!.Proc, Goal0),
     proc_info_get_vartypes(!.Proc, VarTypes),
     SlotInfo = slot_info(ModuleInfo, VarTypes),
-    fill_goal_path_slots([], SlotInfo, Goal0, Goal),
+    fill_goal_path_slots(rgp_nil, SlotInfo, Goal0, Goal),
     proc_info_set_goal(Goal, !Proc).
 
 %-----------------------------------------------------------------------------%
@@ -180,9 +180,9 @@
         ModuleInfo = SlotInfo ^ slot_info_module_info,
         map.lookup(VarTypes, Var, Type),
         ( switch_type_num_functors(ModuleInfo, Type, NumFunctors) ->
-            MaybeNumFunctors = yes(NumFunctors)
+            MaybeNumFunctors = known_num_functors_in_type(NumFunctors)
         ;
-            MaybeNumFunctors = no
+            MaybeNumFunctors = unknown_num_functors_in_type
         ),
         fill_switch_id_slots(SlotInfo, GoalId, 0, MaybeNumFunctors, !GoalNum,
             !ContainingGoalMap, Cases0, Cases),
@@ -273,7 +273,7 @@
         Goals0, Goals).
 
 :- pred fill_switch_id_slots(slot_info::in, goal_id::in,
-    int::in, maybe(int)::in, int::in, int::out,
+    int::in, maybe_switch_num_functors::in, int::in, int::out,
     containing_goal_map::in, containing_goal_map::out,
     list(case)::in, list(case)::out) is det.
 
@@ -306,19 +306,19 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred fill_goal_path_slots(list(goal_path_step)::in, slot_info::in,
+:- pred fill_goal_path_slots(reverse_goal_path::in, slot_info::in,
     hlds_goal::in, hlds_goal::out) is det.
 
-fill_goal_path_slots(RevSteps0, SlotInfo, Goal0, Goal) :-
+fill_goal_path_slots(RevPath0, SlotInfo, Goal0, Goal) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
-    goal_info_set_reverse_goal_path(rgp(RevSteps0), GoalInfo0, GoalInfo),
+    goal_info_set_reverse_goal_path(RevPath0, GoalInfo0, GoalInfo),
     (
         GoalExpr0 = conj(ConjType, Goals0),
-        fill_conj_path_slots(RevSteps0, 0, SlotInfo, Goals0, Goals),
+        fill_conj_path_slots(RevPath0, 0, SlotInfo, Goals0, Goals),
         GoalExpr = conj(ConjType, Goals)
     ;
         GoalExpr0 = disj(Goals0),
-        fill_disj_path_slots(RevSteps0, 0, SlotInfo, Goals0, Goals),
+        fill_disj_path_slots(RevPath0, 0, SlotInfo, Goals0, Goals),
         GoalExpr = disj(Goals)
     ;
         GoalExpr0 = switch(Var, CanFail, Cases0),
@@ -326,17 +326,17 @@
         ModuleInfo = SlotInfo ^ slot_info_module_info,
         map.lookup(VarTypes, Var, Type),
         ( switch_type_num_functors(ModuleInfo, Type, NumFunctors) ->
-            MaybeNumFunctors = yes(NumFunctors)
+            MaybeNumFunctors = known_num_functors_in_type(NumFunctors)
         ;
-            MaybeNumFunctors = no
+            MaybeNumFunctors = unknown_num_functors_in_type
         ),
-        fill_switch_path_slots(RevSteps0, 0, MaybeNumFunctors, SlotInfo,
+        fill_switch_path_slots(RevPath0, 0, MaybeNumFunctors, SlotInfo,
             Cases0, Cases),
         GoalExpr = switch(Var, CanFail, Cases)
     ;
         GoalExpr0 = negation(SubGoal0),
-        fill_goal_path_slots([step_neg | RevSteps0], SlotInfo,
-            SubGoal0, SubGoal),
+        RevPath = rgp_cons(RevPath0, step_neg),
+        fill_goal_path_slots(RevPath, SlotInfo, SubGoal0, SubGoal),
         GoalExpr = negation(SubGoal)
     ;
         GoalExpr0 = scope(Reason, SubGoal0),
@@ -351,24 +351,24 @@
         ;
             MaybeCut = scope_is_cut
         ),
-        fill_goal_path_slots([step_scope(MaybeCut) | RevSteps0], SlotInfo,
-            SubGoal0, SubGoal),
+        RevPath = rgp_cons(RevPath0, step_scope(MaybeCut)),
+        fill_goal_path_slots(RevPath, SlotInfo, SubGoal0, SubGoal),
         GoalExpr = scope(Reason, SubGoal)
     ;
         GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
-        fill_goal_path_slots([step_ite_cond | RevSteps0], SlotInfo,
-            Cond0, Cond),
-        fill_goal_path_slots([step_ite_then | RevSteps0], SlotInfo,
-            Then0, Then),
-        fill_goal_path_slots([step_ite_else | RevSteps0], SlotInfo,
-            Else0, Else),
+        RevPathCond = rgp_cons(RevPath0, step_ite_cond),
+        RevPathThen = rgp_cons(RevPath0, step_ite_then),
+        RevPathElse = rgp_cons(RevPath0, step_ite_else),
+        fill_goal_path_slots(RevPathCond, SlotInfo, Cond0, Cond),
+        fill_goal_path_slots(RevPathThen, SlotInfo, Then0, Then),
+        fill_goal_path_slots(RevPathElse, SlotInfo, Else0, Else),
         GoalExpr = if_then_else(Vars, Cond, Then, Else)
     ;
         GoalExpr0 = unify(LHS, RHS0, Mode, Kind, Context),
         (
             RHS0 = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
                 NonLocals, QuantVars, LambdaModes, Detism, LambdaGoal0),
-            fill_goal_path_slots(RevSteps0, SlotInfo, LambdaGoal0, LambdaGoal),
+            fill_goal_path_slots(RevPath0, SlotInfo, LambdaGoal0, LambdaGoal),
             RHS = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
                 NonLocals, QuantVars, LambdaModes, Detism, LambdaGoal)
         ;
@@ -389,15 +389,16 @@
         (
             ShortHand0 = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
                 MainGoal0, OrElseGoals0, OrElseInners),
-            fill_goal_path_slots([step_atomic_main | RevSteps0], SlotInfo,
-                MainGoal0, MainGoal),
-            fill_orelse_path_slots(RevSteps0, 0, SlotInfo,
+            RevPathMain = rgp_cons(RevPath0, step_atomic_main),
+            fill_goal_path_slots(RevPathMain, SlotInfo, MainGoal0, MainGoal),
+            fill_orelse_path_slots(RevPath0, 0, SlotInfo,
                 OrElseGoals0, OrElseGoals),
             ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
                 MainGoal, OrElseGoals, OrElseInners)
         ;
             ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
-            fill_goal_path_slots(RevSteps0, SlotInfo, SubGoal0, SubGoal),
+            RevPath = rgp_cons(RevPath0, step_try),
+            fill_goal_path_slots(RevPath, SlotInfo, SubGoal0, SubGoal),
             ShortHand = try_goal(MaybeIO, ResultVar, SubGoal)
         ;
             ShortHand0 = bi_implication(_, _),
@@ -408,53 +409,53 @@
     ),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
-:- pred fill_conj_path_slots(list(goal_path_step)::in, int::in, slot_info::in,
+:- pred fill_conj_path_slots(reverse_goal_path::in, int::in, slot_info::in,
     list(hlds_goal)::in, list(hlds_goal)::out) is det.
 
 fill_conj_path_slots(_, _, _, [], []).
-fill_conj_path_slots(RevSteps0, N0, SlotInfo,
+fill_conj_path_slots(RevPath0, N0, SlotInfo,
         [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_path_slots([step_conj(N1) | RevSteps0], SlotInfo, 
+    fill_goal_path_slots(rgp_cons(RevPath0, step_conj(N1)), SlotInfo, 
         Goal0, Goal),
-    fill_conj_path_slots(RevSteps0, N1, SlotInfo, Goals0, Goals).
+    fill_conj_path_slots(RevPath0, N1, SlotInfo, Goals0, Goals).
 
-:- pred fill_disj_path_slots(list(goal_path_step)::in, int::in, slot_info::in,
+:- pred fill_disj_path_slots(reverse_goal_path::in, int::in, slot_info::in,
     list(hlds_goal)::in, list(hlds_goal)::out) is det.
 
 fill_disj_path_slots(_, _, _, [], []).
-fill_disj_path_slots(RevSteps0, N0, SlotInfo,
+fill_disj_path_slots(RevPath0, N0, SlotInfo,
         [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_path_slots([step_disj(N1) | RevSteps0], SlotInfo, 
+    fill_goal_path_slots(rgp_cons(RevPath0, step_disj(N1)), SlotInfo, 
         Goal0, Goal),
-    fill_disj_path_slots(RevSteps0, N1, SlotInfo, Goals0, Goals).
+    fill_disj_path_slots(RevPath0, N1, SlotInfo, Goals0, Goals).
 
-:- pred fill_switch_path_slots(list(goal_path_step)::in,
-    int::in, maybe(int)::in, slot_info::in,
+:- pred fill_switch_path_slots(reverse_goal_path::in,
+    int::in, maybe_switch_num_functors::in, slot_info::in,
     list(case)::in, list(case)::out) is det.
 
 fill_switch_path_slots(_, _, _, _, [], []).
-fill_switch_path_slots(RevSteps0, N0, MaybeNumFunctors, SlotInfo,
+fill_switch_path_slots(RevPath0, N0, MaybeNumFunctors, SlotInfo,
         [Case0 | Cases0], [Case | Cases]) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     N1 = N0 + 1,
-    fill_goal_path_slots([step_switch(N1, MaybeNumFunctors) | RevSteps0],
+    fill_goal_path_slots(rgp_cons(RevPath0, step_switch(N1, MaybeNumFunctors)),
         SlotInfo, Goal0, Goal),
     Case = case(MainConsId, OtherConsIds, Goal),
-    fill_switch_path_slots(RevSteps0, N1, MaybeNumFunctors, SlotInfo,
+    fill_switch_path_slots(RevPath0, N1, MaybeNumFunctors, SlotInfo,
         Cases0, Cases).
 
-:- pred fill_orelse_path_slots(list(goal_path_step)::in, int::in,
+:- pred fill_orelse_path_slots(reverse_goal_path::in, int::in,
     slot_info::in, list(hlds_goal)::in, list(hlds_goal)::out) is det.
 
 fill_orelse_path_slots(_, _, _, [], []).
-fill_orelse_path_slots(RevSteps0, N0, SlotInfo,
+fill_orelse_path_slots(RevPath0, N0, SlotInfo,
         [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_path_slots([step_atomic_orelse(N1) | RevSteps0], SlotInfo,
+    fill_goal_path_slots(rgp_cons(RevPath0, step_atomic_orelse(N1)), SlotInfo,
         Goal0, Goal),
-    fill_orelse_path_slots(RevSteps0, N1, SlotInfo, Goals0, Goals).
+    fill_orelse_path_slots(RevPath0, N1, SlotInfo, Goals0, Goals).
 
 %-----------------------------------------------------------------------------%
 :- end_module hlds.goal_path.
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.189
diff -u -b -r1.189 goal_util.m
--- compiler/goal_util.m	13 Sep 2011 06:07:13 -0000	1.189
+++ compiler/goal_util.m	19 Sep 2011 09:41:20 -0000
@@ -1888,29 +1888,12 @@
 
 maybe_transform_goal_at_goal_path(TransformP, TargetGoalPath,
         Goal0, MaybeGoal) :-
-    TargetGoalPath = fgp(TargetGoalSteps),
-    maybe_transform_goal_at_goal_path_2(TransformP,
-        TargetGoalSteps, Goal0, MaybeGoal).
-
-maybe_transform_goal_at_goal_path_with_instmap(TransformP, TargetGoalPath,
-        InstMap, Goal0, MaybeGoal) :-
-    TargetGoalPath = fgp(TargetGoalSteps),
-    maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-        TargetGoalSteps, InstMap, Goal0, MaybeGoal).
-
-:- pred maybe_transform_goal_at_goal_path_2(
-    pred(hlds_goal, maybe_error(hlds_goal))::in(pred(in, out) is det),
-    list(goal_path_step)::in, hlds_goal::in, maybe_transformed_goal::out)
-    is det.
-
-maybe_transform_goal_at_goal_path_2(TransformP, TargetGoalSteps,
-        Goal0, MaybeGoal) :-
     (
-        TargetGoalSteps = [],
+        TargetGoalPath = fgp_nil,
         TransformP(Goal0, MaybeGoal0),
         maybe_error_to_maybe_transformed_goal(MaybeGoal0, MaybeGoal)
     ;
-        TargetGoalSteps = [FirstStep | LaterSteps],
+        TargetGoalPath = fgp_cons(FirstStep, LaterPath),
         GoalExpr0 = Goal0 ^ hlds_goal_expr,  
         (
             ( GoalExpr0 = unify(_, _, _, _, _) 
@@ -1926,7 +1909,7 @@
                 FirstStep = step_conj(ConjNum),
                 list.index1(Conjs0, ConjNum, Conj0)
             ->
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     Conj0, MaybeConj),
                 (
                     MaybeConj = ok(Conj),
@@ -1948,7 +1931,7 @@
                 FirstStep = step_disj(DisjNum),
                 list.index1(Disjs0, DisjNum, Disj0)
             ->
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     Disj0, MaybeDisj),
                 (
                     MaybeDisj = ok(Disj),
@@ -1971,7 +1954,7 @@
                 list.index1(Cases0, CaseNum, Case0)
             ->
                 CaseGoal0 = Case0 ^ case_goal,
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     CaseGoal0, MaybeCaseGoal),
                 (
                     MaybeCaseGoal = ok(CaseGoal),
@@ -1991,7 +1974,7 @@
         ;
             GoalExpr0 = negation(SubGoal0),
             ( FirstStep = step_neg ->
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     SubGoal0, MaybeSubGoal),
                 (
                     MaybeSubGoal = ok(SubGoal),
@@ -2008,7 +1991,7 @@
         ;
             GoalExpr0 = scope(Reason, SubGoal0),
             ( FirstStep = step_scope(_MaybeCut) ->
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     SubGoal0, MaybeSubGoal),
                 (
                     MaybeSubGoal = ok(SubGoal),
@@ -2026,7 +2009,7 @@
         ;
             GoalExpr0 = if_then_else(ExistVars, Cond0, Then0, Else0),
             ( FirstStep = step_ite_cond ->
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     Cond0, MaybeCond),
                 (
                     MaybeCond = ok(Cond),
@@ -2039,7 +2022,7 @@
                     MaybeGoal = MaybeCond 
                 )
             ; FirstStep = step_ite_then ->
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     Then0, MaybeThen),
                 (
                     MaybeThen = ok(Then),
@@ -2052,7 +2035,7 @@
                     MaybeGoal = MaybeThen 
                 )
             ; FirstStep = step_ite_else ->
-                maybe_transform_goal_at_goal_path_2(TransformP, LaterSteps,
+                maybe_transform_goal_at_goal_path(TransformP, LaterPath,
                     Else0, MaybeElse),
                 (
                     MaybeElse = ok(Else),
@@ -2073,20 +2056,14 @@
         )
     ).
 
-:- pred maybe_transform_goal_at_goal_path_with_instmap_2(
-    pred(instmap, hlds_goal, maybe_error(hlds_goal))::
-        in(pred(in, in, out) is det), 
-    list(goal_path_step)::in, instmap::in, hlds_goal::in,
-    maybe_transformed_goal::out) is det. 
-
-maybe_transform_goal_at_goal_path_with_instmap_2(TransformP, TargetGoalSteps,
+maybe_transform_goal_at_goal_path_with_instmap(TransformP, TargetGoalPath,
         Instmap0, Goal0, MaybeGoal) :-
     (
-        TargetGoalSteps = [],
+        TargetGoalPath = fgp_nil,
         TransformP(Instmap0, Goal0, MaybeGoal0),
         maybe_error_to_maybe_transformed_goal(MaybeGoal0, MaybeGoal)
     ;
-        TargetGoalSteps = [FirstStep | LaterSteps],
+        TargetGoalPath = fgp_cons(FirstStep, LaterPath),
         GoalExpr0 = Goal0 ^ hlds_goal_expr,  
         (
             ( GoalExpr0 = unify(_, _, _, _, _) 
@@ -2108,8 +2085,8 @@
                     HeadConjs),
                 foldl(apply_instmap_delta_sv, HeadInstdeltas, 
                     Instmap0, Instmap),
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP, 
-                    LaterSteps, Instmap, Conj0, MaybeConj),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP, 
+                    LaterPath, Instmap, Conj0, MaybeConj),
                 (
                     MaybeConj = ok(Conj),
                     list.det_replace_nth(Conjs0, ConjNum, Conj, Conjs),
@@ -2130,8 +2107,8 @@
                 FirstStep = step_disj(DisjNum),
                 list.index1(Disjs0, DisjNum, Disj0)
             ->
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-                    LaterSteps, Instmap0, Disj0, MaybeDisj),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP,
+                    LaterPath, Instmap0, Disj0, MaybeDisj),
                 (
                     MaybeDisj = ok(Disj),
                     list.det_replace_nth(Disjs0, DisjNum, Disj, Disjs),
@@ -2152,8 +2129,8 @@
                 list.index1(Cases0, CaseNum, Case0)
             ->
                 CaseGoal0 = Case0 ^ case_goal,
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-                    LaterSteps, Instmap0, CaseGoal0, MaybeCaseGoal),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP,
+                    LaterPath, Instmap0, CaseGoal0, MaybeCaseGoal),
                 (
                     MaybeCaseGoal = ok(CaseGoal),
                     Case = Case0 ^ case_goal := CaseGoal,
@@ -2172,8 +2149,8 @@
         ;
             GoalExpr0 = negation(SubGoal0),
             ( FirstStep = step_neg ->
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-                    LaterSteps, Instmap0, SubGoal0, MaybeSubGoal),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP,
+                    LaterPath, Instmap0, SubGoal0, MaybeSubGoal),
                 (
                     MaybeSubGoal = ok(SubGoal),
                     GoalExpr = negation(SubGoal),
@@ -2190,8 +2167,8 @@
         ;
             GoalExpr0 = scope(Reason, SubGoal0),
             ( FirstStep = step_scope(_MaybeCut) ->
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-                    LaterSteps, Instmap0, SubGoal0, MaybeSubGoal),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP,
+                    LaterPath, Instmap0, SubGoal0, MaybeSubGoal),
                 (
                     MaybeSubGoal = ok(SubGoal),
                     GoalExpr = scope(Reason, SubGoal),
@@ -2208,8 +2185,8 @@
         ;
             GoalExpr0 = if_then_else(ExistVars, Cond0, Then0, Else0),
             ( FirstStep = step_ite_cond ->
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-                    LaterSteps, Instmap0, Cond0, MaybeCond),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP,
+                    LaterPath, Instmap0, Cond0, MaybeCond),
                 (
                     MaybeCond = ok(Cond),
                     GoalExpr = if_then_else(ExistVars, Cond, Then0, Else0),
@@ -2224,8 +2201,8 @@
                 apply_instmap_delta_sv(
                     goal_info_get_instmap_delta(Cond0 ^ hlds_goal_info),
                     Instmap0, Instmap),
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-                    LaterSteps, Instmap, Then0, MaybeThen),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP,
+                    LaterPath, Instmap, Then0, MaybeThen),
                 (
                     MaybeThen = ok(Then),
                     GoalExpr = if_then_else(ExistVars, Cond0, Then, Else0),
@@ -2237,8 +2214,8 @@
                     MaybeGoal = MaybeThen
                 )
             ; FirstStep = step_ite_else ->
-                maybe_transform_goal_at_goal_path_with_instmap_2(TransformP,
-                    LaterSteps, Instmap0, Else0, MaybeElse),
+                maybe_transform_goal_at_goal_path_with_instmap(TransformP,
+                    LaterPath, Instmap0, Else0, MaybeElse),
                 (
                     MaybeElse = ok(Else),
                     GoalExpr = if_then_else(ExistVars, Cond0, Then0, Else),
@@ -2311,5 +2288,5 @@
     TransformP(Goal1, Goal).
 
 %-----------------------------------------------------------------------------%
-:- end_module goal_util.
+:- end_module hlds.goal_util.
 %-----------------------------------------------------------------------------%
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.230
diff -u -b -r1.230 hlds_goal.m
--- compiler/hlds_goal.m	13 Sep 2011 06:07:14 -0000	1.230
+++ compiler/hlds_goal.m	19 Sep 2011 09:41:47 -0000
@@ -2066,7 +2066,7 @@
 
 hlds_goal_extra_info_init(Context) = ExtraInfo :-
     HO_Values = map.init,
-    ExtraInfo = extra_goal_info(Context, rgp([]), HO_Values, no, no, no, no).
+    ExtraInfo = extra_goal_info(Context, rgp_nil, HO_Values, no, no, no, no).
 
 :- func ctgc_goal_info_init = ctgc_goal_info.
 
Index: compiler/introduce_parallelism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/introduce_parallelism.m,v
retrieving revision 1.4
diff -u -b -r1.4 introduce_parallelism.m
--- compiler/introduce_parallelism.m	3 May 2011 04:34:55 -0000	1.4
+++ compiler/introduce_parallelism.m	19 Sep 2011 10:01:49 -0000
@@ -614,25 +614,25 @@
     candidate_par_conjunction::in, comparison_result::out) is det.
 
 compare_candidate_par_conjunctions(CPCA, CPCB, Result) :-
-    goal_path_from_string_det(CPCA ^ cpc_goal_path, fgp(StepsA)),
-    goal_path_from_string_det(CPCB ^ cpc_goal_path, fgp(StepsB)),
-    compare_goal_paths(StepsA, StepsB, Result).
+    goal_path_from_string_det(CPCA ^ cpc_goal_path, PathA),
+    goal_path_from_string_det(CPCB ^ cpc_goal_path, PathB),
+    compare_goal_paths(PathA, PathB, Result).
 
-:- pred compare_goal_paths(list(goal_path_step)::in, list(goal_path_step)::in,
+:- pred compare_goal_paths(forward_goal_path::in, forward_goal_path::in,
     comparison_result::out) is det.
 
-compare_goal_paths(StepsA, StepsB, Result) :-
+compare_goal_paths(PathA, PathB, Result) :-
     (
-        StepsA = [FirstStepA | LaterStepsA],
+        PathA = fgp_cons(FirstStepA, LaterPathA),
         (
-            StepsB = [FirstStepB | LaterStepsB],
+            PathB = fgp_cons(FirstStepB, LaterPathB),
             compare(Result0, FirstStepA, FirstStepB),
             % Reverse the ordering here so that later goals are sorted before
             % earlier ones. This way parallelisations are placed inside later
             % goals first.
             (
                 Result0 = (=),
-                compare_goal_paths(LaterStepsA, LaterStepsB, Result)
+                compare_goal_paths(LaterPathA, LaterPathB, Result)
             ;
                 Result0 = (<),
                 Result = (>)
@@ -641,19 +641,19 @@
                 Result = (<)
             )
         ;
-            StepsB = [],
-            % StepsA is longer than StepsB. Make A 'less than' B so that
+            PathB = fgp_nil,
+            % PathA is longer than PathB. Make A 'less than' B so that
             % deeper parallelisations are inserted first.
             Result = (<)
         )
     ;
-        StepsA = [],
+        PathA = fgp_nil,
         (
-            StepsB = [_ | _],
+            PathB = fgp_cons(_, _),
             % B is 'less than' A, see above.
             Result = (>)
         ;
-            StepsB = [],
+            PathB = fgp_nil,
             % Both goal paths are empty.
             Result = (=)
         )
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.65
diff -u -b -r1.65 mode_constraints.m
--- compiler/mode_constraints.m	16 Aug 2011 03:26:32 -0000	1.65
+++ compiler/mode_constraints.m	19 Sep 2011 09:18:21 -0000
@@ -1820,7 +1820,7 @@
     set_of_progvar::in, goal_id::in, set(goal_id)::in, inst_graph::in,
     rep_var::in) is semidet.
 
-keep_var(ForwardGoalPathMap, NonLocals, GoalVars, GoalId, AtomicGoals,
+keep_var(_ForwardGoalPathMap, NonLocals, GoalVars, _GoalId, AtomicGoals,
         InstGraph, RepVar) :-
     (
         RepVar = _V `at` RepGoalId,
@@ -1836,16 +1836,20 @@
         =>
         (
             list.member(NonLocal, NonLocals),
-            inst_graph.reachable(InstGraph, NonLocal, V),
-            \+ (
-                RepVar = _ `at` RepGoalId,
-                % XXX What higher level operation is being implemented here?
-                map.lookup(ForwardGoalPathMap, GoalId, GoalPath),
-                map.lookup(ForwardGoalPathMap, RepGoalId, RepGoalPath),
-                GoalPath = fgp(GoalPathSteps),
-                RepGoalPath = fgp(RepGoalPathSteps),
-                list.remove_suffix(RepGoalPathSteps, GoalPathSteps, [_ | _])
-            )
+            inst_graph.reachable(InstGraph, NonLocal, V)
+            % The call to list.remove_suffix is equivalent to:
+            % list.append([_ | _], GoalPathSteps, RepGoalPathSteps)
+            % I (zs) do not see how that can possibly make sense,
+            % which is why I have disabled this test.
+%           \+ (
+%               RepVar = _ `at` RepGoalId,
+%               % XXX What higher level operation is being implemented here?
+%               map.lookup(ForwardGoalPathMap, GoalId, GoalPath),
+%               map.lookup(ForwardGoalPathMap, RepGoalId, RepGoalPath),
+%               GoalPath = fgp(GoalPathSteps),
+%               RepGoalPath = fgp(RepGoalPathSteps),
+%               list.remove_suffix(RepGoalPathSteps, GoalPathSteps, [_ | _])
+%           )
         )
     ).
 
Index: compiler/mode_ordering.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_ordering.m,v
retrieving revision 1.38
diff -u -b -r1.38 mode_ordering.m
--- compiler/mode_ordering.m	16 Aug 2011 03:26:32 -0000	1.38
+++ compiler/mode_ordering.m	19 Sep 2011 09:19:16 -0000
@@ -429,9 +429,8 @@
         G = hlds_goal(_, GI),
         GoalId = goal_info_get_goal_id(GI),
         map.lookup(ForwardGoalPathMap, GoalId, GoalPath),
-        GoalPath = fgp(GoalSteps),
         (
-            list.last(GoalSteps, LastStep),
+            goal_path_get_last(GoalPath, LastStep),
             LastStep = step_conj(Index0)
         ->
             Index = Index0
Index: compiler/push_goals_together.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/push_goals_together.m,v
retrieving revision 1.8
diff -u -b -r1.8 push_goals_together.m
--- compiler/push_goals_together.m	10 May 2011 04:12:26 -0000	1.8
+++ compiler/push_goals_together.m	19 Sep 2011 10:38:19 -0000
@@ -161,8 +161,7 @@
 do_one_push(PushGoal, PushInfo, Result, !Goal) :-
     PushGoal = push_goal(GoalPathStr, _Lo, _Hi, _PushedInto),
     ( goal_path_from_string(GoalPathStr, GoalPath) ->
-        GoalPath = fgp(GoalPathSteps),
-        do_push_in_goal(GoalPathSteps, PushGoal, PushInfo, Result, !Goal)
+        do_push_in_goal(GoalPath, PushGoal, PushInfo, Result, !Goal)
     ;
         Result = push_failed,
         trace [compiletime(flag("debug_push_goals")), io(!IO)] (
@@ -172,18 +171,18 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred do_push_in_goal(list(goal_path_step)::in, push_goal::in, push_info::in,
+:- pred do_push_in_goal(forward_goal_path::in, push_goal::in, push_info::in,
     push_result::out, hlds_goal::in, hlds_goal::out) is det.
 
-do_push_in_goal([], PushGoal, PushInfo, Result, !Goal) :-
+do_push_in_goal(fgp_nil, PushGoal, PushInfo, Result, !Goal) :-
     % We have arrives at the goal in which the push should take place.
     perform_push_transform(PushGoal, PushInfo, Result, !Goal).
-do_push_in_goal([Step | Steps], PushGoal, PushInfo, Result, !Goal) :-
+do_push_in_goal(fgp_cons(Step, Path), PushGoal, PushInfo, Result, !Goal) :-
     !.Goal = hlds_goal(GoalExpr0, GoalInfo0),
     (
         Step = step_conj(N),
         ( GoalExpr0 = conj(ConjType, Goals0) ->
-            do_push_in_goals(N, Steps, PushGoal, PushInfo, Result,
+            do_push_in_goals(N, Path, PushGoal, PushInfo, Result,
                 Goals0, Goals),
             GoalExpr = conj(ConjType, Goals),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
@@ -196,7 +195,7 @@
     ;
         Step = step_disj(N),
         ( GoalExpr0 = disj(Goals0) ->
-            do_push_in_goals(N, Steps, PushGoal, PushInfo, Result,
+            do_push_in_goals(N, Path, PushGoal, PushInfo, Result,
                 Goals0, Goals),
             GoalExpr = disj(Goals),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
@@ -209,7 +208,7 @@
     ;
         Step = step_switch(N, _),
         ( GoalExpr0 = switch(Var, CanFail, Cases0) ->
-            do_push_in_cases(N, Steps, PushGoal, PushInfo, Result,
+            do_push_in_cases(N, Path, PushGoal, PushInfo, Result,
                 Cases0, Cases),
             GoalExpr = switch(Var, CanFail, Cases),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
@@ -222,7 +221,7 @@
     ;
         Step = step_ite_cond,
         ( GoalExpr0 = if_then_else(Vars0, Cond0, Then0, Else0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result, Cond0, Cond),
+            do_push_in_goal(Path, PushGoal, PushInfo, Result, Cond0, Cond),
             GoalExpr = if_then_else(Vars0, Cond, Then0, Else0),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
         ;
@@ -234,7 +233,7 @@
     ;
         Step = step_ite_then,
         ( GoalExpr0 = if_then_else(Vars0, Cond0, Then0, Else0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result, Then0, Then),
+            do_push_in_goal(Path, PushGoal, PushInfo, Result, Then0, Then),
             GoalExpr = if_then_else(Vars0, Cond0, Then, Else0),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
         ;
@@ -246,7 +245,7 @@
     ;
         Step = step_ite_else,
         ( GoalExpr0 = if_then_else(Vars0, Cond0, Then0, Else0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result, Else0, Else),
+            do_push_in_goal(Path, PushGoal, PushInfo, Result, Else0, Else),
             GoalExpr = if_then_else(Vars0, Cond0, Then0, Else),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
         ;
@@ -258,7 +257,7 @@
     ;
         Step = step_neg,
         ( GoalExpr0 = negation(SubGoal0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result,
+            do_push_in_goal(Path, PushGoal, PushInfo, Result,
                 SubGoal0, SubGoal),
             GoalExpr = negation(SubGoal),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
@@ -271,7 +270,7 @@
     ;
         Step = step_scope(_),
         ( GoalExpr0 = scope(Reason, SubGoal0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result,
+            do_push_in_goal(Path, PushGoal, PushInfo, Result,
                 SubGoal0, SubGoal),
             GoalExpr = scope(Reason, SubGoal),
             !:Goal = hlds_goal(GoalExpr, GoalInfo0)
@@ -295,42 +294,42 @@
         )
     ).
 
-:- pred do_push_in_goals(int::in, list(goal_path_step)::in, push_goal::in,
+:- pred do_push_in_goals(int::in, forward_goal_path::in, push_goal::in,
     push_info::in, push_result::out,
     list(hlds_goal)::in, list(hlds_goal)::out) is det.
 
-do_push_in_goals(_N, _Steps, _PushGoal, _PushInfo, push_failed, [], []) :-
+do_push_in_goals(_N, _Path, _PushGoal, _PushInfo, push_failed, [], []) :-
     trace [compiletime(flag("debug_push_goals")), io(!IO)] (
         io.write_string("push_failed: couldn't find indicated disjunct\n", !IO)
     ).
-do_push_in_goals(N, Steps, PushGoal, PushInfo, Result,
+do_push_in_goals(N, Path, PushGoal, PushInfo, Result,
         [Goal0 | Goals0], [Goal | Goals]) :-
     ( N = 1 ->
-        do_push_in_goal(Steps, PushGoal, PushInfo, Result, Goal0, Goal),
+        do_push_in_goal(Path, PushGoal, PushInfo, Result, Goal0, Goal),
         Goals = Goals0
     ;
         Goal = Goal0,
-        do_push_in_goals(N - 1, Steps, PushGoal, PushInfo, Result,
+        do_push_in_goals(N - 1, Path, PushGoal, PushInfo, Result,
             Goals0, Goals)
     ).
 
-:- pred do_push_in_cases(int::in, list(goal_path_step)::in, push_goal::in,
+:- pred do_push_in_cases(int::in, forward_goal_path::in, push_goal::in,
     push_info::in, push_result::out, list(case)::in, list(case)::out) is det.
 
-do_push_in_cases(_N, _Steps, _PushGoal, _PushInfo, push_failed, [], []) :-
+do_push_in_cases(_N, _Path, _PushGoal, _PushInfo, push_failed, [], []) :-
     trace [compiletime(flag("debug_push_goals")), io(!IO)] (
         io.write_string("push_failed: couldn't find indicated case\n", !IO)
     ).
-do_push_in_cases(N, Steps, PushGoal, PushInfo, Result,
+do_push_in_cases(N, Path, PushGoal, PushInfo, Result,
         [Case0 | Cases0], [Case | Cases]) :-
     ( N = 1 ->
         Case0 = case(MainConsId, OtherConsIds, Goal0),
-        do_push_in_goal(Steps, PushGoal, PushInfo, Result, Goal0, Goal),
+        do_push_in_goal(Path, PushGoal, PushInfo, Result, Goal0, Goal),
         Case = case(MainConsId, OtherConsIds, Goal),
         Cases = Cases0
     ;
         Case = Case0,
-        do_push_in_cases(N - 1, Steps, PushGoal, PushInfo, Result,
+        do_push_in_cases(N - 1, Path, PushGoal, PushInfo, Result,
             Cases0, Cases)
     ).
 
@@ -347,13 +346,13 @@
         GoalExpr0 = conj(plain_conj, Conjuncts),
         find_lo_hi_goals(PushInfo, Conjuncts, Lo, Hi, 1, Before0, LoHi, After,
             pushable),
-        find_relative_paths(GoalPath, PushedInto, RelGoalSteps),
-        RelGoalSteps = [HeadRelGoalSteps | TailRelGoalSteps],
-        HeadRelGoalSteps = [step_conj(PushConjNum) | HeadRestRelSteps],
+        find_relative_paths(GoalPath, PushedInto, RelGoalPaths),
+        RelGoalPaths = [HeadRelGoalPath | TailRelGoalPaths],
+        HeadRelGoalPath = fgp_cons(step_conj(PushConjNum), HeadRestRelPath),
         list.map(maybe_steps_after(step_conj(PushConjNum)),
-            TailRelGoalSteps, TailRestRelSteps),
+            TailRelGoalPaths, TailRestRelPaths),
         list.index1(Before0, PushConjNum, PushIntoGoal0),
-        push_into_goal(LoHi, HeadRestRelSteps, TailRestRelSteps,
+        push_into_goal(LoHi, HeadRestRelPath, TailRestRelPaths,
             PushIntoGoal0, PushIntoGoal, pushable),
         % If PushConjNum specifies a conjunct that is NOT the last conjunct
         % before Lo, then this transformation reorders the code.
@@ -565,11 +564,11 @@
 
 %-----------------------------------------------------------------------------%
 
-    % push_into_goal(LoHi, HeadSteps, TailSteps, Goal0, Goal, Pushable):
+    % push_into_goal(LoHi, HeadPath, TailPaths, Goal0, Goal, Pushable):
     %
     % Push the goals LoHi into Goal0, putting them at the ends of the
     % (possibly implicit) conjunctions holding the expensive goals indicated
-    % by the goal paths [HeadSteps | TailSteps], which are all relative to
+    % by the goal paths [HeadPath | TailPaths], which are all relative to
     % Goal0, and at the ends of the branches that are alternatives to these.
     %
     % Return Pushable = pushable if the transformation was successful.
@@ -578,7 +577,7 @@
     % The returned goal will need to have its nonlocal sets and instmap deltas
     % recomputed.
     %
-    % For example, if HeadSteps and TailSteps together specified the two
+    % For example, if HeadPath and TailPaths together specified the two
     % expensive goals in the original goal below,
     %
     %   ( Cond ->
@@ -613,18 +612,18 @@
     %   )
     %
 :- pred push_into_goal(list(hlds_goal)::in,
-    list(goal_path_step)::in, list(list(goal_path_step))::in,
+    forward_goal_path::in, list(forward_goal_path)::in,
     hlds_goal::in, hlds_goal::out, maybe_pushable::out) is det.
 
-push_into_goal(LoHi, HeadSteps, TailSteps, Goal0, Goal, Pushable) :-
+push_into_goal(LoHi, HeadPath, TailPaths, Goal0, Goal, Pushable) :-
     Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
     (
-        HeadSteps = [],
-        expect(unify(TailSteps, []), $module, "TailSteps != []"),
+        HeadPath = fgp_nil,
+        expect(unify(TailPaths, []), $module, "TailSteps != []"),
         add_goals_at_end(LoHi, Goal0, Goal),
         Pushable = pushable
     ;
-        HeadSteps = [FirstHeadStep | LaterHeadSteps],
+        HeadPath = fgp_cons(FirstHeadStep, LaterHeadPath),
         (
             ( GoalExpr0 = unify(_, _, _, _, _)
             ; GoalExpr0 = plain_call(_, _, _, _, _, _)
@@ -639,9 +638,9 @@
                 % If the expensive goal is a conjunct in this conjunction,
                 % then put LoHi at the end of this conjunction.
                 FirstHeadStep = step_conj(_),
-                LaterHeadSteps = []
+                LaterHeadPath = fgp_nil
             ->
-                expect(unify(TailSteps, []), $module, "TailSteps != []"),
+                expect(unify(TailPaths, []), $module, "TailSteps != []"),
                 add_goals_at_end(LoHi, Goal0, Goal),
                 Pushable = pushable
             ;
@@ -652,8 +651,8 @@
                 % would be a mode error.
                 %
                 FirstHeadStep = step_conj(ConjNum),
-                list.map(maybe_steps_after(step_conj(ConjNum)), TailSteps,
-                    LaterTailSteps),
+                list.map(maybe_steps_after(step_conj(ConjNum)), TailPaths,
+                    LaterTailPaths),
                 list.index1(Conjuncts0, ConjNum, SelectedConjunct0),
 
                 % If ConjNum specifies a conjunct that is NOT the last
@@ -666,7 +665,7 @@
                 list.length(Conjuncts0, Length),
                 ConjNum = Length
             ->
-                push_into_goal(LoHi, LaterHeadSteps, LaterTailSteps,
+                push_into_goal(LoHi, LaterHeadPath, LaterTailPaths,
                     SelectedConjunct0, SelectedConjunct, Pushable),
                 list.det_replace_nth(Conjuncts0, ConjNum, SelectedConjunct,
                     Conjuncts),
@@ -679,11 +678,11 @@
         ;
             GoalExpr0 = disj(Disjuncts0),
             (
-                build_disj_steps_map([HeadSteps | TailSteps], map.init,
-                    StepMap)
+                build_disj_paths_map([HeadPath | TailPaths],
+                    map.init, PathsMap)
             ->
-                map.to_assoc_list(StepMap, StepList),
-                push_into_disjuncts(LoHi, StepList, 1, Disjuncts0, Disjuncts,
+                map.to_assoc_list(PathsMap, PathsList),
+                push_into_disjuncts(LoHi, PathsList, 1, Disjuncts0, Disjuncts,
                     Pushable),
                 GoalExpr = disj(Disjuncts),
                 Goal = hlds_goal(GoalExpr, GoalInfo0)
@@ -694,11 +693,11 @@
         ;
             GoalExpr0 = switch(Var, CanFail, Cases0),
             (
-                build_switch_steps_map([HeadSteps | TailSteps], map.init,
-                    StepMap)
+                build_switch_paths_map([HeadPath | TailPaths],
+                    map.init, PathsMap)
             ->
-                map.to_assoc_list(StepMap, StepList),
-                push_into_cases(LoHi, StepList, 1, Cases0, Cases, Pushable),
+                map.to_assoc_list(PathsMap, PathsList),
+                push_into_cases(LoHi, PathsList, 1, Cases0, Cases, Pushable),
                 GoalExpr = switch(Var, CanFail, Cases),
                 Goal = hlds_goal(GoalExpr, GoalInfo0)
             ;
@@ -708,25 +707,25 @@
         ;
             GoalExpr0 = if_then_else(Vars, Cond, Then0, Else0),
             (
-                build_ite_steps_map([HeadSteps | TailSteps],
-                    ThenSteps, ElseSteps)
+                build_ite_paths_map([HeadPath | TailPaths],
+                    ThenPaths, ElsePaths)
             ->
                 (
-                    ThenSteps = [],
+                    ThenPaths = [],
                     add_goals_at_end(LoHi, Then0, Then),
                     ThenPushable = pushable
                 ;
-                    ThenSteps = [ThenStepsHead | ThenStepsTail],
-                    push_into_goal(LoHi, ThenStepsHead, ThenStepsTail,
+                    ThenPaths = [ThenPathsHead | ThenPathsTail],
+                    push_into_goal(LoHi, ThenPathsHead, ThenPathsTail,
                         Then0, Then, ThenPushable)
                 ),
                 (
-                    ElseSteps = [],
+                    ElsePaths = [],
                     add_goals_at_end(LoHi, Else0, Else),
                     ElsePushable = pushable
                 ;
-                    ElseSteps = [ElseStepsHead | ElseStepsTail],
-                    push_into_goal(LoHi, ElseStepsHead, ElseStepsTail,
+                    ElsePaths = [ElsePathsHead | ElsePathsTail],
+                    push_into_goal(LoHi, ElsePathsHead, ElsePathsTail,
                         Else0, Else, ElsePushable)
                 ),
                 (
@@ -746,7 +745,8 @@
             )
         ;
             GoalExpr0 = negation(_SubGoal0),
-            % Pushing goals into a negation changes the meaning of the program.
+            % Pushing goals into a negation would change the meaning of the
+            % program, so we do not do it.
             Goal = Goal0,
             Pushable = not_pushable
         ;
@@ -757,11 +757,11 @@
             (
                 Detism = SubDetism,
                 maybe_steps_after(step_scope(scope_is_no_cut),
-                    HeadSteps, HeadStepsAfter),
+                    HeadPath, HeadPathAfter),
                 list.map(maybe_steps_after(step_scope(scope_is_no_cut)),
-                    TailSteps, TailStepsAfter)
+                    TailPaths, TailPathsAfter)
             ->
-                push_into_goal(LoHi, HeadStepsAfter, TailStepsAfter,
+                push_into_goal(LoHi, HeadPathAfter, TailPathsAfter,
                     SubGoal0, SubGoal, Pushable),
                 GoalExpr = scope(Reason, SubGoal),
                 Goal = hlds_goal(GoalExpr, GoalInfo0)
@@ -785,7 +785,7 @@
     ).
 
 :- pred push_into_case(list(hlds_goal)::in,
-    list(goal_path_step)::in, list(list(goal_path_step))::in,
+    forward_goal_path::in, list(forward_goal_path)::in,
     case::in, case::out, maybe_pushable::out) is det.
 
 push_into_case(LoHi, HeadSteps, TailSteps, Case0, Case, Pushable) :-
@@ -794,35 +794,35 @@
     Case = case(MainConsId, OtherConsIds, Goal).
 
 :- pred push_into_disjuncts(list(hlds_goal)::in,
-    assoc_list(int, one_or_more(list(goal_path_step)))::in,
+    assoc_list(int, one_or_more(forward_goal_path))::in,
     int::in, list(hlds_goal)::in, list(hlds_goal)::out, maybe_pushable::out)
     is det.
 
-push_into_disjuncts(_LoHi, DisjStepList, _Cur, [], [], Pushable) :-
+push_into_disjuncts(_LoHi, DisjPathList, _Cur, [], [], Pushable) :-
     (
-        DisjStepList = [],
+        DisjPathList = [],
         Pushable = pushable
     ;
-        DisjStepList = [_ | _],
+        DisjPathList = [_ | _],
         Pushable = not_pushable
     ).
-push_into_disjuncts(LoHi, StepList, Cur, [HeadDisjunct0 | TailDisjuncts0],
+push_into_disjuncts(LoHi, PathList, Cur, [HeadDisjunct0 | TailDisjuncts0],
         [HeadDisjunct | TailDisjuncts], Pushable) :-
     (
-        StepList = [],
+        PathList = [],
         add_goals_at_end(LoHi, HeadDisjunct0, HeadDisjunct),
         list.map(add_goals_at_end(LoHi), TailDisjuncts0, TailDisjuncts),
         Pushable = pushable
     ;
-        StepList = [StepListHead | StepListTail],
+        PathList = [PathListHead | PathListTail],
         (
-            StepListHead = StepListHeadNum - one_or_more(One, More),
-            ( StepListHeadNum = Cur ->
+            PathListHead = PathListHeadNum - one_or_more(One, More),
+            ( PathListHeadNum = Cur ->
                 push_into_goal(LoHi, One, More, HeadDisjunct0, HeadDisjunct,
                     GoalPushable),
                 (
                     GoalPushable = pushable,
-                    push_into_disjuncts(LoHi, StepListTail, Cur + 1,
+                    push_into_disjuncts(LoHi, PathListTail, Cur + 1,
                         TailDisjuncts0, TailDisjuncts, Pushable)
                 ;
                     GoalPushable = not_pushable,
@@ -831,41 +831,41 @@
                 )
             ;
                 add_goals_at_end(LoHi, HeadDisjunct0, HeadDisjunct),
-                push_into_disjuncts(LoHi, StepList, Cur + 1,
+                push_into_disjuncts(LoHi, PathList, Cur + 1,
                     TailDisjuncts0, TailDisjuncts, Pushable)
             )
         )
     ).
 
 :- pred push_into_cases(list(hlds_goal)::in,
-    assoc_list(int, one_or_more(list(goal_path_step)))::in,
+    assoc_list(int, one_or_more(forward_goal_path))::in,
     int::in, list(case)::in, list(case)::out, maybe_pushable::out) is det.
 
-push_into_cases(_LoHi, StepList, _Cur, [], [], Pushable) :-
+push_into_cases(_LoHi, PathList, _Cur, [], [], Pushable) :-
     (
-        StepList = [],
+        PathList = [],
         Pushable = pushable
     ;
-        StepList = [_ | _],
+        PathList = [_ | _],
         Pushable = not_pushable
     ).
-push_into_cases(LoHi, StepList, Cur, [HeadCase0 | TailCases0],
+push_into_cases(LoHi, PathList, Cur, [HeadCase0 | TailCases0],
         [HeadCase | TailCases], Pushable) :-
     (
-        StepList = [],
+        PathList = [],
         add_goals_at_end_of_case(LoHi, HeadCase0, HeadCase),
         list.map(add_goals_at_end_of_case(LoHi), TailCases0, TailCases),
         Pushable = pushable
     ;
-        StepList = [StepListHead | StepListTail],
+        PathList = [PathListHead | PathListTail],
         (
-            StepListHead = StepListHeadNum - one_or_more(One, More),
-            ( StepListHeadNum = Cur ->
+            PathListHead = PathListHeadNum - one_or_more(One, More),
+            ( PathListHeadNum = Cur ->
                 push_into_case(LoHi, One, More, HeadCase0, HeadCase,
                     GoalPushable),
                 (
                     GoalPushable = pushable,
-                    push_into_cases(LoHi, StepListTail, Cur + 1,
+                    push_into_cases(LoHi, PathListTail, Cur + 1,
                         TailCases0, TailCases, Pushable)
                 ;
                     GoalPushable = not_pushable,
@@ -874,7 +874,7 @@
                 )
             ;
                 add_goals_at_end_of_case(LoHi, HeadCase0, HeadCase),
-                push_into_cases(LoHi, StepList, Cur + 1,
+                push_into_cases(LoHi, PathList, Cur + 1,
                     TailCases0, TailCases, Pushable)
             )
         )
@@ -882,48 +882,49 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred build_disj_steps_map(list(list(goal_path_step))::in,
-    map(int, one_or_more(list(goal_path_step)))::in,
-    map(int, one_or_more(list(goal_path_step)))::out) is semidet.
-
-build_disj_steps_map([], !DisjStepMap).
-build_disj_steps_map([Head | Tail], !DisjStepMap) :-
-    Head = [step_disj(N) | HeadSteps],
-    ( map.search(!.DisjStepMap, N, one_or_more(One, More)) ->
-        map.det_update(N, one_or_more(HeadSteps, [One | More]), !DisjStepMap)
-    ;
-        map.det_insert(N, one_or_more(HeadSteps, []), !DisjStepMap)
-    ),
-    build_disj_steps_map(Tail, !DisjStepMap).
-
-:- pred build_switch_steps_map(list(list(goal_path_step))::in,
-    map(int, one_or_more(list(goal_path_step)))::in,
-    map(int, one_or_more(list(goal_path_step)))::out) is semidet.
-
-build_switch_steps_map([], !DisjStepMap).
-build_switch_steps_map([Head | Tail], !DisjStepMap) :-
-    Head = [step_switch(N, _) | HeadSteps],
-    ( map.search(!.DisjStepMap, N, one_or_more(One, More)) ->
-        map.det_update(N, one_or_more(HeadSteps, [One | More]), !DisjStepMap)
-    ;
-        map.det_insert(N, one_or_more(HeadSteps, []), !DisjStepMap)
-    ),
-    build_switch_steps_map(Tail, !DisjStepMap).
-
-:- pred build_ite_steps_map(list(list(goal_path_step))::in,
-    list(list(goal_path_step))::out, list(list(goal_path_step))::out)
-    is semidet.
-
-build_ite_steps_map([], [], []).
-build_ite_steps_map([Head | Tail], ThenSteps, ElseSteps) :-
-    build_ite_steps_map(Tail, ThenStepsTail, ElseStepsTail),
-    Head = [HeadFirstStep | HeadSteps],
+:- pred build_disj_paths_map(list(forward_goal_path)::in,
+    map(int, one_or_more(forward_goal_path))::in,
+    map(int, one_or_more(forward_goal_path))::out) is semidet.
+
+build_disj_paths_map([], !DisjPathsMap).
+build_disj_paths_map([Head | Tail], !DisjPathsMap) :-
+    Head = fgp_cons(step_disj(N), HeadLaterPath),
+    ( map.search(!.DisjPathsMap, N, one_or_more(One, More)) ->
+        map.det_update(N, one_or_more(HeadLaterPath, [One | More]),
+            !DisjPathsMap)
+    ;
+        map.det_insert(N, one_or_more(HeadLaterPath, []), !DisjPathsMap)
+    ),
+    build_disj_paths_map(Tail, !DisjPathsMap).
+
+:- pred build_switch_paths_map(list(forward_goal_path)::in,
+    map(int, one_or_more(forward_goal_path))::in,
+    map(int, one_or_more(forward_goal_path))::out) is semidet.
+
+build_switch_paths_map([], !DisjPathsMap).
+build_switch_paths_map([Head | Tail], !DisjPathsMap) :-
+    Head = fgp_cons(step_switch(N, _), HeadLaterPath),
+    ( map.search(!.DisjPathsMap, N, one_or_more(One, More)) ->
+        map.det_update(N, one_or_more(HeadLaterPath, [One | More]),
+            !DisjPathsMap)
+    ;
+        map.det_insert(N, one_or_more(HeadLaterPath, []), !DisjPathsMap)
+    ),
+    build_switch_paths_map(Tail, !DisjPathsMap).
+
+:- pred build_ite_paths_map(list(forward_goal_path)::in,
+    list(forward_goal_path)::out, list(forward_goal_path)::out) is semidet.
+
+build_ite_paths_map([], [], []).
+build_ite_paths_map([Head | Tail], ThenPaths, ElsePaths) :-
+    build_ite_paths_map(Tail, ThenPathsTail, ElsePathsTail),
+    Head = fgp_cons(HeadFirstStep, HeadLaterPath),
     ( HeadFirstStep = step_ite_then ->
-        ThenSteps = [HeadSteps | ThenStepsTail],
-        ElseSteps = ElseStepsTail
+        ThenPaths = [HeadLaterPath | ThenPathsTail],
+        ElsePaths = ElsePathsTail
     ; HeadFirstStep = step_ite_then ->
-        ThenSteps = ThenStepsTail,
-        ElseSteps = [HeadSteps | ElseStepsTail]
+        ThenPaths = ThenPathsTail,
+        ElsePaths = [HeadLaterPath | ElsePathsTail]
     ;
         fail
     ).
@@ -952,21 +953,19 @@
 %-----------------------------------------------------------------------------%
 
 :- pred find_relative_paths(forward_goal_path::in, list(goal_path_string)::in,
-    list(list(goal_path_step))::out) is semidet.
+    list(forward_goal_path)::out) is semidet.
 
 find_relative_paths(_GoalPath, [], []).
 find_relative_paths(GoalPath, [HeadStr | TailStrs],
-        [HeadRelSteps | TailRelSteps]) :-
+        [HeadRelPath | TailRelPaths]) :-
     goal_path_from_string(HeadStr, HeadGoalPath),
-    GoalPath = fgp(GoalPathSteps),
-    HeadGoalPath = fgp(HeadGoalPathSteps),
-    list.append(GoalPathSteps, HeadRelSteps, HeadGoalPathSteps),
-    find_relative_paths(GoalPath, TailStrs, TailRelSteps).
+    goal_path_inside_relative(GoalPath, HeadGoalPath, HeadRelPath),
+    find_relative_paths(GoalPath, TailStrs, TailRelPaths).
 
 :- pred maybe_steps_after(goal_path_step::in,
-    list(goal_path_step)::in, list(goal_path_step)::out) is semidet.
+    forward_goal_path::in, forward_goal_path::out) is semidet.
 
-maybe_steps_after(Step, [Step | Tail], Tail).
+maybe_steps_after(Step, fgp_cons(Step, Tail), Tail).
 
 %-----------------------------------------------------------------------------%
 
@@ -974,3 +973,5 @@
     --->    one_or_more(T, list(T)).
 
 %-----------------------------------------------------------------------------%
+:- end_module transform_hlds.implicit_parallelism.push_goals_together.
+%-----------------------------------------------------------------------------%
Index: compiler/rbmm.condition_renaming.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.condition_renaming.m,v
retrieving revision 1.19
diff -u -b -r1.19 rbmm.condition_renaming.m
--- compiler/rbmm.condition_renaming.m	23 May 2011 05:08:10 -0000	1.19
+++ compiler/rbmm.condition_renaming.m	19 Sep 2011 09:34:50 -0000
@@ -445,16 +445,17 @@
     set(string)::in,
     goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-record_non_local_regions(Path, Created, Removed, !NonLocalRegionProc) :-
-    Path = rgp(RevSteps),
+record_non_local_regions(RevPath, Created, Removed, !NonLocalRegionProc) :-
     (
-        RevSteps = [LastStep | RevInitialSteps],
-        InitialPath = rgp(RevInitialSteps),
+        RevPath = rgp_cons(RevInitialPath, LastStep),
         ( LastStep = step_ite_else ->
             % The current NonLocalRegions are attached to the goal path
             % to the corresponding condition.
-            PathToCond = rgp([step_ite_cond | RevInitialSteps]),
-            ( map.search(!.NonLocalRegionProc, PathToCond, NonLocalRegions0) ->
+            RevPathToCond = rgp_cons(RevInitialPath, step_ite_cond),
+            (
+                map.search(!.NonLocalRegionProc, RevPathToCond,
+                    NonLocalRegions0)
+            ->
                 set.union(NonLocalRegions0, Created, NonLocalRegions1),
                 set.difference(NonLocalRegions1, Removed, NonLocalRegions)
             ;
@@ -464,7 +465,7 @@
             ( set.empty(NonLocalRegions) ->
                 true
             ;
-                map.set(PathToCond, NonLocalRegions, !NonLocalRegionProc)
+                map.set(RevPathToCond, NonLocalRegions, !NonLocalRegionProc)
             )
         ;
             true
@@ -472,10 +473,10 @@
 
         % Need to update the non-local sets of outer if-then-elses of this one,
         % if any.
-        record_non_local_regions(InitialPath, Created, Removed,
+        record_non_local_regions(RevInitialPath, Created, Removed,
             !NonLocalRegionProc)
     ;
-        RevSteps = []
+        RevPath = rgp_nil
     ).
 
 :- pred collect_non_local_regions_in_ite_compound_goal(rpt_graph::in,
@@ -630,13 +631,11 @@
     set(string)::in, goal_path_regions_table::in,
     goal_path_regions_table::out) is det.
 
-record_regions_created_in_condition(Path, Created, !InCondRegionsProc) :-
-    Path = rgp(RevSteps),
+record_regions_created_in_condition(RevPath, Created, !InCondRegionsProc) :-
     (
-        RevSteps = [LastStep | RevInitialSteps],
-        InitialPath = rgp(RevInitialSteps),
+        RevPath = rgp_cons(RevInitialPath, LastStep),
         ( LastStep = step_ite_cond  ->
-            ( map.search(!.InCondRegionsProc, Path, InCondRegions0) ->
+            ( map.search(!.InCondRegionsProc, RevPath, InCondRegions0) ->
                 set.union(InCondRegions0, Created, InCondRegions)
             ;
                 InCondRegions = Created
@@ -646,15 +645,15 @@
             ( set.empty(InCondRegions) ->
                 true
             ;
-                map.set(Path, InCondRegions, !InCondRegionsProc)
+                map.set(RevPath, InCondRegions, !InCondRegionsProc)
             )
         ;
             true
         ),
-        record_regions_created_in_condition(InitialPath, Created,
+        record_regions_created_in_condition(RevInitialPath, Created,
             !InCondRegionsProc)
     ;
-        RevSteps = []
+        RevPath = rgp_nil
     ).
 
 :- pred collect_regions_created_in_condition_compound_goal(rpt_graph::in,
@@ -1001,22 +1000,20 @@
 :- pred get_closest_condition_in_goal_path(reverse_goal_path::in,
     reverse_goal_path::out, int::in, int::out) is det.
 
-get_closest_condition_in_goal_path(Path, PathToCond, !HowMany) :-
-    Path = rgp(RevSteps),
+get_closest_condition_in_goal_path(RevPath, RevPathToCond, !HowMany) :-
     (
-        RevSteps = [LastStep | RevInitialSteps],
-        InitialPath = rgp(RevInitialSteps),
+        RevPath = rgp_cons(RevInitialPath, LastStep),
         ( LastStep = step_ite_cond ->
-            PathToCond = Path,
-            get_closest_condition_in_goal_path(InitialPath, _, !HowMany),
+            RevPathToCond = RevPath,
+            get_closest_condition_in_goal_path(RevInitialPath, _, !HowMany),
             !:HowMany = !.HowMany + 1
         ;
-            get_closest_condition_in_goal_path(InitialPath, PathToCond,
+            get_closest_condition_in_goal_path(RevInitialPath, RevPathToCond,
                 !HowMany)
         )
     ;
-        RevSteps = [],
-        PathToCond = rgp([])
+        RevPath = rgp_nil,
+        RevPathToCond = rgp_nil
     ).
 
 %-----------------------------------------------------------------------------%
@@ -1052,21 +1049,20 @@
     renaming_proc::in, renaming_proc::out,
     renaming_annotation_proc::in, renaming_annotation_proc::out) is det.
 
-collect_ite_annotation_region_names(ExecPaths, Graph, PathToCond,
+collect_ite_annotation_region_names(ExecPaths, Graph, RevPathToCond,
         RenamedRegions, !IteRenamingProc, !IteAnnotationProc) :-
-    PathToCond = rgp(RevPathToCondSteps),
     (
-        RevPathToCondSteps = [LastStep | RevInitialSteps],
+        RevPathToCond = rgp_cons(RevInitialPath, LastStep),
         expect(unify(LastStep, step_ite_cond), $module, $pred,
             "not step_ite_cond"),
-        PathToThen = rgp([step_ite_then | RevInitialSteps]),
-        get_closest_condition_in_goal_path(PathToCond, _, 0, HowMany),
+        RevPathToThen = rgp_cons(RevInitialPath, step_ite_then),
+        get_closest_condition_in_goal_path(RevPathToCond, _, 0, HowMany),
         list.foldl2(
-            collect_ite_annotation_exec_path(Graph, PathToThen, RenamedRegions,
-                HowMany),
+            collect_ite_annotation_exec_path(Graph, RevPathToThen,
+                RenamedRegions, HowMany),
             ExecPaths, !IteRenamingProc, !IteAnnotationProc)
     ;
-        RevPathToCondSteps = [],
+        RevPathToCond = rgp_nil,
         unexpected($module, $pred, "empty path to condition")
     ).
 
@@ -1095,13 +1091,13 @@
 
 collect_ite_annotation_exec_path_2(_, _, _, _, _, [], !IteRenamingProc,
         !IteAnnotationProc).
-collect_ite_annotation_exec_path_2(Graph, PathToThen,
+collect_ite_annotation_exec_path_2(Graph, RevPathToThen,
         RenamedRegions, HowMany, PrevPoint, [ProgPoint - _ | ProgPointGoals],
         !IteRenamingProc, !IteAnnotationProc) :-
     ProgPoint = pp(_, RevGoalPath),
-    RevGoalPath = rgp(RevGoalPathSteps),
+    reverse_goal_path_to_steps(RevGoalPath, RevGoalPathSteps),
     list.reverse(RevGoalPathSteps, GoalPathSteps),
-    PathToThen = rgp(RevPathToThenSteps),
+    reverse_goal_path_to_steps(RevPathToThen, RevPathToThenSteps),
     list.reverse(RevPathToThenSteps, PathToThenSteps),
     ( list.append(PathToThenSteps, FromThenSteps, GoalPathSteps) ->
         ( list.member(step_ite_cond, FromThenSteps) ->
@@ -1113,7 +1109,7 @@
             ;
                 true
             ),
-            collect_ite_annotation_exec_path_2(Graph, PathToThen,
+            collect_ite_annotation_exec_path_2(Graph, RevPathToThen,
                 RenamedRegions, HowMany, ProgPoint, ProgPointGoals,
                 !IteRenamingProc, !IteAnnotationProc)
         ;
@@ -1126,11 +1122,19 @@
                 RenamedRegions, !IteAnnotationProc)
         )
     ;
-        collect_ite_annotation_exec_path_2(Graph, PathToThen,
+        collect_ite_annotation_exec_path_2(Graph, RevPathToThen,
             RenamedRegions, HowMany, ProgPoint, ProgPointGoals,
             !IteRenamingProc, !IteAnnotationProc)
     ).
 
+:- pred reverse_goal_path_to_steps(reverse_goal_path::in,
+    list(goal_path_step)::out) is det.
+
+reverse_goal_path_to_steps(rgp_nil, []).
+reverse_goal_path_to_steps(rgp_cons(EarlierPath, LaterStep),
+        [LaterStep | EarlierSteps]) :-
+    reverse_goal_path_to_steps(EarlierPath, EarlierSteps).
+
     % The reverse renaming annotation is in the form: R = R_ite_HowMany.
     % The annotation is attached to the program point but actually means
     % to be added before the program point.
Index: compiler/trace_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trace_gen.m,v
retrieving revision 1.40
diff -u -b -r1.40 trace_gen.m
--- compiler/trace_gen.m	16 Aug 2011 03:26:34 -0000	1.40
+++ compiler/trace_gen.m	19 Sep 2011 09:35:59 -0000
@@ -1018,7 +1018,7 @@
     (
         PortInfo = port_info_external,
         LiveVars = LiveVars0,
-        Path = fgp([]),
+        Path = fgp_nil,
         TailRecResetCode = empty
     ;
         PortInfo = port_info_tailrec_call(Path, ArgsInfos),
Index: compiler/tupling.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/tupling.m,v
retrieving revision 1.65
diff -u -b -r1.65 tupling.m
--- compiler/tupling.m	31 Aug 2011 07:59:35 -0000	1.65
+++ compiler/tupling.m	19 Sep 2011 10:40:54 -0000
@@ -1951,15 +1951,14 @@
 
 get_disjunct_relative_frequency(ProcCounts, ReverseGoalPathMap,
         GoalId, RelFreq) :-
-    map.lookup(ReverseGoalPathMap, GoalId, GoalPath),
-    GoalPath = rgp(RevGoalSteps),
+    map.lookup(ReverseGoalPathMap, GoalId, RevGoalPath),
     (
-        RevGoalSteps = [LastStep | PrevSteps],
+        RevGoalPath = rgp_cons(RevPrevGoalPath, LastStep),
         LastStep = step_disj(_)
     ->
-        FirstDisjGoalPath = rgp([step_disj(1) | PrevSteps]),
-        get_path_only_count(ProcCounts, GoalPath, DisjCount),
-        get_path_only_count(ProcCounts, FirstDisjGoalPath, FirstDisjCount),
+        RevFirstDisjGoalPath = rgp_cons(RevPrevGoalPath, step_disj(1)),
+        get_path_only_count(ProcCounts, RevGoalPath, DisjCount),
+        get_path_only_count(ProcCounts, RevFirstDisjGoalPath, FirstDisjCount),
         ( FirstDisjCount = 0 ->
             RelFreq = 0.0
         ;
@@ -2003,7 +2002,7 @@
 :- pred case_in_switch(reverse_goal_path::in, path_port::in) is semidet.
 
 case_in_switch(GoalPath, path_only(GoalPath)) :-
-    GoalPath = rgp([LastStep | _]),
+    GoalPath = rgp_cons(_, LastStep),
     LastStep = step_switch(_, _).
 
 %-----------------------------------------------------------------------------%
Index: compiler/unneeded_code.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unneeded_code.m,v
retrieving revision 1.63
diff -u -b -r1.63 unneeded_code.m
--- compiler/unneeded_code.m	16 Aug 2011 03:26:34 -0000	1.63
+++ compiler/unneeded_code.m	19 Sep 2011 10:37:55 -0000
@@ -124,7 +124,7 @@
             % If-then-elses always have two alternatives: the then branch
             % (numbered 1) and the else branch (numbered 2).
 
-    ;       alt_switch(maybe(int)).
+    ;       alt_switch(maybe_switch_num_functors).
             % The number of alternatives in a switch is equal to the number of
             % function symbols in the type of the switched-on variable. This
             % number is given by the argument integer, if present; if the
@@ -1223,7 +1223,8 @@
 branch_point_is_complete(alt_ite, Alts) :-
     set.count(Alts, NumAlts),
     NumAlts = 2.
-branch_point_is_complete(alt_switch(yes(NumFunctors)), Alts) :-
+branch_point_is_complete(alt_switch(known_num_functors_in_type(NumFunctors)),
+        Alts) :-
     set.count(Alts, NumAlts),
     NumAlts = NumFunctors.
 
cvs diff: Diffing compiler/notes
cvs diff: Diffing deep_profiler
Index: deep_profiler/autopar_costs.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_costs.m,v
retrieving revision 1.2
diff -u -b -r1.2 autopar_costs.m
--- deep_profiler/autopar_costs.m	3 May 2011 04:35:00 -0000	1.2
+++ deep_profiler/autopar_costs.m	19 Sep 2011 10:48:26 -0000
@@ -47,7 +47,7 @@
 %-----------------------------------------------------------------------------%
 
 :- pred atomic_goal_build_use_map(atomic_goal_rep::in,
-    list(goal_path_step)::in, implicit_parallelism_info::in,
+    reverse_goal_path::in, implicit_parallelism_info::in,
     var_use_type::in, var_rep::in,
     map(var_rep, lazy(var_use_info))::in,
     map(var_rep, lazy(var_use_info))::out) is det.
@@ -150,7 +150,7 @@
 
 %-----------------------------------------------------------------------------%
 
-atomic_goal_build_use_map(AtomicGoal, RevGoalPathSteps, Info, VarUseType, Var,
+atomic_goal_build_use_map(AtomicGoal, RevGoalPath, Info, VarUseType, Var,
         !Map) :-
     atomic_goal_is_call(AtomicGoal, IsCall),
     (
@@ -168,17 +168,16 @@
     ;
         IsCall = atomic_goal_is_call(Args),
         LazyUse = delay(
-            (func) = compute_var_use_lazy(Info, RevGoalPathSteps, Var,
+            (func) = compute_var_use_lazy(Info, RevGoalPath, Var,
                 Args, VarUseType))
     ),
     map.det_insert(Var, LazyUse, !Map).
 
-:- func compute_var_use_lazy(implicit_parallelism_info, list(goal_path_step),
+:- func compute_var_use_lazy(implicit_parallelism_info, reverse_goal_path,
     var_rep, list(var_rep), var_use_type) = var_use_info.
 
-compute_var_use_lazy(Info, RevGoalPathSteps, Var, Args, VarUseType) = Use :-
+compute_var_use_lazy(Info, RevGoalPath, Var, Args, VarUseType) = Use :-
     CliquePtr = Info ^ ipi_clique,
-    RevGoalPath = rgp(RevGoalPathSteps),
     map.lookup(Info ^ ipi_call_sites, RevGoalPath, CostAndCallee),
     (
         cost_and_callees_is_recursive(CliquePtr, CostAndCallee),
Index: deep_profiler/autopar_reports.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_reports.m,v
retrieving revision 1.2
diff -u -b -r1.2 autopar_reports.m
--- deep_profiler/autopar_reports.m	16 Apr 2011 03:13:04 -0000	1.2
+++ deep_profiler/autopar_reports.m	19 Sep 2011 10:51:28 -0000
@@ -241,26 +241,26 @@
         Header2Str),
     Header3 = cord.singleton(Header2Str),
 
-    ( rev_goal_path_from_string(GoalPathString, RevGoalPath) ->
-        RevGoalPath = rgp(RevGoalPathSteps)
+    ( rev_goal_path_from_string(GoalPathString, RevGoalPathPrime) ->
+        RevGoalPath = RevGoalPathPrime
     ;
         unexpected($module, $pred, "couldn't parse goal path")
     ),
     some [!ConjNum] (
         !:ConjNum = FirstConjNum,
-        format_sequential_conjunction(VarTable, 4, RevGoalPathSteps,
+        format_sequential_conjunction(VarTable, 4, RevGoalPath,
             GoalsBefore, GoalsBeforeCost, !.ConjNum, ReportGoalsBefore0),
         ReportGoalsBefore = indent(3) ++ singleton("Goals before:\n") ++
             ReportGoalsBefore0,
 
         !:ConjNum = !.ConjNum + length(GoalsBefore),
-        format_parallel_conjunction(VarTable, 4, RevGoalPathSteps,
+        format_parallel_conjunction(VarTable, 4, RevGoalPath,
             !.ConjNum, Conjs, ReportParConj0),
         ReportParConj = indent(3) ++ singleton("Parallel conjunction:\n") ++
             ReportParConj0,
 
         !:ConjNum = !.ConjNum + 1,
-        format_sequential_conjunction(VarTable, 4, RevGoalPathSteps,
+        format_sequential_conjunction(VarTable, 4, RevGoalPath,
             GoalsAfter, GoalsAfterCost, !.ConjNum, ReportGoalsAfter0),
         ReportGoalsAfter = indent(3) ++ singleton("Goals after:\n") ++
             ReportGoalsAfter0
@@ -269,25 +269,25 @@
         ++ ReportParConj ++ nl ++ ReportGoalsAfter ++ nl.
 
 :- pred format_parallel_conjunction(var_table::in, int::in,
-    list(goal_path_step)::in, int::in,
+    reverse_goal_path::in, int::in,
     list(seq_conj(pard_goal))::in, cord(string)::out) is det.
 
-format_parallel_conjunction(VarTable, Indent, RevGoalPathSteps, ConjNum, Conjs,
+format_parallel_conjunction(VarTable, Indent, RevGoalPath, ConjNum, Conjs,
         !:Report) :-
     IndentStr = indent(Indent),
     !:Report = IndentStr ++ singleton("(\n"),
     format_parallel_conjuncts(VarTable, Indent,
-        [step_conj(ConjNum) | RevGoalPathSteps], 1, Conjs, !Report).
+        rgp_cons(RevGoalPath, step_conj(ConjNum)), 1, Conjs, !Report).
 
 :- pred format_parallel_conjuncts(var_table::in, int::in,
-    list(goal_path_step)::in, int::in, list(seq_conj(pard_goal))::in,
+    reverse_goal_path::in, int::in, list(seq_conj(pard_goal))::in,
     cord(string)::in, cord(string)::out) is det.
 
-format_parallel_conjuncts(_VarTable, Indent, _RevGoalPathSteps, _ConjNum0,
+format_parallel_conjuncts(_VarTable, Indent, _RevGoalPath, _ConjNum0,
         [], !Report) :-
     IndentStr = indent(Indent),
     !:Report = snoc(!.Report ++ IndentStr, ")\n").
-format_parallel_conjuncts(VarTable, Indent, RevGoalPathSteps, ConjNum0,
+format_parallel_conjuncts(VarTable, Indent, RevGoalPath, ConjNum0,
         [Conj | Conjs], !Report) :-
     Conj = seq_conj(Goals),
     (
@@ -295,12 +295,12 @@
         unexpected($module, $pred, "empty conjunct in parallel conjunction")
     ;
         Goals = [Goal | GoalsTail],
-        RevInnerGoalPathSteps = [step_conj(ConjNum0) | RevGoalPathSteps],
+        RevInnerGoalPath = rgp_cons(RevGoalPath, step_conj(ConjNum0)),
         (
             GoalsTail = [],
             % A singleton conjunction gets printed as a single goal.
             print_goal_to_strings(print_goal_info(id, VarTable), Indent + 1,
-                RevInnerGoalPathSteps, Goal, ConjReport)
+                RevInnerGoalPath, Goal, ConjReport)
         ;
             GoalsTail = [_ | _],
             Cost = foldl(
@@ -308,7 +308,7 @@
                     Acc + GoalI ^ goal_annotation ^ pga_cost_percall),
                 Goals, 0.0),
             format_sequential_conjunction(VarTable, Indent + 1,
-                RevInnerGoalPathSteps, Goals, Cost, 1, ConjReport)
+                RevInnerGoalPath, Goals, Cost, 1, ConjReport)
         )
     ),
     !:Report = !.Report ++ ConjReport,
@@ -319,21 +319,21 @@
         !:Report = snoc(!.Report ++ indent(Indent), "&\n")
     ),
     ConjNum = ConjNum0 + 1,
-    format_parallel_conjuncts(VarTable, Indent, RevGoalPathSteps, ConjNum,
+    format_parallel_conjuncts(VarTable, Indent, RevGoalPath, ConjNum,
         Conjs, !Report).
 
 :- pred format_sequential_conjunction(var_table::in, int::in,
-    list(goal_path_step)::in, list(pard_goal)::in, float::in, int::in,
+    reverse_goal_path::in, list(pard_goal)::in, float::in, int::in,
     cord(string)::out) is det.
 
-format_sequential_conjunction(VarTable, Indent, RevGoalPathSteps, Goals, Cost,
+format_sequential_conjunction(VarTable, Indent, RevGoalPath, Goals, Cost,
         FirstConjNum, !:Report) :-
     !:Report = empty,
     ( FirstConjNum = 1 ->
         !:Report = !.Report ++
             indent(Indent) ++
             singleton(format("%% conjunction: %s",
-                [s(rev_goal_path_to_string(rgp(RevGoalPathSteps)))])) ++
+                [s(rev_goal_path_to_string(RevGoalPath))])) ++
             nl_indent(Indent) ++
             singleton(format("%% Cost: %s",
                 [s(two_decimal_fraction(Cost))])) ++
@@ -341,18 +341,18 @@
     ;
         true
     ),
-    format_sequential_conjuncts(VarTable, Indent, RevGoalPathSteps, Goals,
+    format_sequential_conjuncts(VarTable, Indent, RevGoalPath, Goals,
         FirstConjNum, _, !Report).
 
 :- pred format_sequential_conjuncts(var_table::in, int::in,
-    list(goal_path_step)::in, list(pard_goal)::in, int::in, int::out,
+    reverse_goal_path::in, list(pard_goal)::in, int::in, int::out,
     cord(string)::in, cord(string)::out) is det.
 
 format_sequential_conjuncts(_, _, _, [], !ConjNum, !Report).
-format_sequential_conjuncts(VarTable, Indent, RevGoalPathSteps, [Conj | Conjs],
+format_sequential_conjuncts(VarTable, Indent, RevGoalPath, [Conj | Conjs],
         !ConjNum, !Report) :-
     print_goal_to_strings(print_goal_info(id, VarTable), Indent,
-        [step_conj(!.ConjNum) | RevGoalPathSteps], Conj, ConjReport),
+        rgp_cons(RevGoalPath, step_conj(!.ConjNum)), Conj, ConjReport),
     !:Report = !.Report ++ ConjReport,
     !:ConjNum = !.ConjNum + 1,
     (
@@ -360,7 +360,7 @@
     ;
         Conjs = [_ | _],
         !:Report = !.Report ++ indent(Indent) ++ singleton(",\n"),
-        format_sequential_conjuncts(VarTable, Indent, RevGoalPathSteps, Conjs,
+        format_sequential_conjuncts(VarTable, Indent, RevGoalPath, Conjs,
             !ConjNum, !Report)
     ).
 
Index: deep_profiler/autopar_search_callgraph.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_search_callgraph.m,v
retrieving revision 1.6
diff -u -b -r1.6 autopar_search_callgraph.m
--- deep_profiler/autopar_search_callgraph.m	6 May 2011 05:03:27 -0000	1.6
+++ deep_profiler/autopar_search_callgraph.m	19 Sep 2011 11:51:17 -0000
@@ -400,8 +400,8 @@
         RevGoalPath \= RevConjGoalPath,
         rev_goal_path_inside_relative(RevConjGoalPath, RevGoalPath,
             RevRelativePath),
-        RevRelativePath = rgp(RevRelativePathSteps),
-        list.last(RevRelativePathSteps, Step),
+        rgp_to_fgp(RevRelativePath, RelativePath),
+        RelativePath = fgp_cons(Step, _),
         Step = step_conj(ConjNum),
         ConjNum > FirstConjunct,
         ConjNum =< FirstConjunct + Length
@@ -608,10 +608,10 @@
                     CliquePtr, CallSitesMap, RecursiveCallSiteCostMap,
                     ContainingGoalMap, CoverageArray, InstMapArray,
                     RecursionType, VarTable, ProcLabel),
-                goal_to_pard_goal(Info, [], Goal, PardGoal, !Messages),
+                goal_to_pard_goal(Info, rgp_nil, Goal, PardGoal, !Messages),
                 goal_get_conjunctions_worth_parallelising(Info,
-                    [], PardGoal, _, CandidatesCord0, PushesCord, _Singles,
-                    MessagesA),
+                    rgp_nil, PardGoal, _, CandidatesCord0, PushesCord,
+                    _Singles, MessagesA),
                 Candidates0 = cord.list(CandidatesCord0),
                 Pushes = cord.list(PushesCord),
                 !:Messages = !.Messages ++ MessagesA,
Index: deep_profiler/autopar_search_goals.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_search_goals.m,v
retrieving revision 1.4
diff -u -b -r1.4 autopar_search_goals.m
--- deep_profiler/autopar_search_goals.m	10 May 2011 04:12:27 -0000	1.4
+++ deep_profiler/autopar_search_goals.m	19 Sep 2011 11:57:54 -0000
@@ -26,12 +26,11 @@
 :- import_module message.
 
 :- import_module cord.
-:- import_module list.
 
 %-----------------------------------------------------------------------------%
 
 :- pred goal_get_conjunctions_worth_parallelising(
-    implicit_parallelism_info::in, list(goal_path_step)::in,
+    implicit_parallelism_info::in, reverse_goal_path::in,
     pard_goal_detail::in, pard_goal_detail::out,
     cord(candidate_par_conjunction(pard_goal_detail))::out,
     cord(push_goal)::out, cord(pard_goal_detail)::out, cord(message)::out)
@@ -40,7 +39,7 @@
     % Transform a goal in a conjunction into a pard_goal.
     %
 :- pred goal_to_pard_goal(implicit_parallelism_info::in,
-    list(goal_path_step)::in, goal_rep(goal_id)::in,
+    reverse_goal_path::in, goal_rep(goal_id)::in,
     pard_goal_detail::out, cord(message)::in, cord(message)::out) is det.
 
     % Check if it is appropriate to parallelise this call. That is it must be
@@ -70,6 +69,7 @@
 :- import_module int.
 :- import_module io.
 :- import_module lazy.
+:- import_module list.
 :- import_module map.
 :- import_module maybe.
 :- import_module pair.
@@ -79,7 +79,7 @@
 
 %----------------------------------------------------------------------------%
 
-goal_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+goal_get_conjunctions_worth_parallelising(Info, RevGoalPath,
         !Goal, Candidates, Pushes, Singles, Messages) :-
     !.Goal = goal_rep(GoalExpr0, DetismRep, Annotation0),
     Coverage = Annotation0 ^ pgd_coverage,
@@ -87,7 +87,7 @@
     (
         (
             GoalExpr0 = conj_rep(Conjs0),
-            conj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+            conj_get_conjunctions_worth_parallelising(Info, RevGoalPath,
                 Conjs0, Conjs, 1, [], SinglesSoFar, [], RevSingleCands,
                 cord.empty, CandidatesBelow, cord.empty, PushesBelow,
                 cord.empty, MessagesBelow),
@@ -102,7 +102,7 @@
                 Cost = Annotation0 ^ pgd_cost
             ;
                 SingleCands = [CostlyIndex - SinglesBefore],
-                push_and_build_candidate_conjunctions(Info, RevGoalPathSteps,
+                push_and_build_candidate_conjunctions(Info, RevGoalPath,
                     Conjs, CostlyIndex, SinglesBefore,
                     MessagesThisLevel, CandidatesThisLevel),
                 (
@@ -129,7 +129,7 @@
             ;
                 SingleCands = [_, _ | _],
                 assoc_list.keys(SingleCands, CostlyIndexes),
-                build_candidate_conjunction(Info, RevGoalPathSteps,
+                build_candidate_conjunction(Info, RevGoalPath,
                     Conjs, CostlyIndexes, MessagesThisLevel, MaybeCandidate),
                 Pushes = PushesBelow,
                 Messages = MessagesBelow ++ MessagesThisLevel,
@@ -164,8 +164,7 @@
         ;
             GoalExpr0 = disj_rep(Disjs0),
             list.map_foldl5(
-                disj_get_conjunctions_worth_parallelising(Info,
-                    RevGoalPathSteps),
+                disj_get_conjunctions_worth_parallelising(Info, RevGoalPath),
                 Disjs0, Disjs, 1, _, cord.empty, Candidates,
                 cord.empty, Pushes, cord.empty, Singles,
                 cord.empty, Messages),
@@ -175,7 +174,7 @@
             GoalExpr0 = switch_rep(Var, CanFail, Cases0),
             list.map_foldl5(
                 switch_case_get_conjunctions_worth_parallelising(Info,
-                    RevGoalPathSteps),
+                    RevGoalPath),
                 Cases0, Cases, 1, _, cord.empty, Candidates,
                 cord.empty, Pushes, cord.empty, Singles,
                 cord.empty, Messages),
@@ -183,26 +182,26 @@
             GoalExpr = switch_rep(Var, CanFail, Cases)
         ;
             GoalExpr0 = ite_rep(Cond0, Then0, Else0),
-            ite_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+            ite_get_conjunctions_worth_parallelising(Info, RevGoalPath,
                 Cond0, Cond, Then0, Then, Else0, Else,
                 Candidates, Pushes, Singles, Messages),
             ite_calc_cost(Cond, Then, Else, Cost),
             GoalExpr = ite_rep(Cond, Then, Else)
         ;
             GoalExpr0 = scope_rep(SubGoal0, MaybeCut),
-            RevSubGoalPathSteps = [step_scope(MaybeCut) | RevGoalPathSteps],
+            RevSubGoalPath = rgp_cons(RevGoalPath, step_scope(MaybeCut)),
             goal_get_conjunctions_worth_parallelising(Info,
-                RevSubGoalPathSteps, SubGoal0, SubGoal,
+                RevSubGoalPath, SubGoal0, SubGoal,
                 Candidates, Pushes, Singles, Messages),
             Cost = SubGoal ^ goal_annotation ^ pgd_cost,
             GoalExpr = scope_rep(SubGoal, MaybeCut)
         ;
             GoalExpr0 = negation_rep(SubGoal0),
-            RevSubGoalPathSteps = [step_neg | RevGoalPathSteps],
+            RevSubGoalPath = rgp_cons(RevGoalPath, step_neg),
             % We ignore _Singles here because you cannot push goals
             % after a negation into the negation.
             goal_get_conjunctions_worth_parallelising(Info,
-                RevSubGoalPathSteps, SubGoal0, SubGoal,
+                RevSubGoalPath, SubGoal0, SubGoal,
                 Candidates, Pushes, _Singles, Messages),
             Singles = cord.empty,
             Cost = SubGoal ^ goal_annotation ^ pgd_cost,
@@ -228,7 +227,7 @@
     !:Goal = goal_rep(GoalExpr, DetismRep, Annotation).
 
 :- pred disj_get_conjunctions_worth_parallelising(
-    implicit_parallelism_info::in, list(goal_path_step)::in,
+    implicit_parallelism_info::in, reverse_goal_path::in,
     pard_goal_detail::in, pard_goal_detail::out,
     int::in, int::out,
     cord(candidate_par_conjunction(pard_goal_detail))::in,
@@ -237,10 +236,10 @@
     cord(pard_goal_detail)::in, cord(pard_goal_detail)::out,
     cord(message)::in, cord(message)::out) is det.
 
-disj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+disj_get_conjunctions_worth_parallelising(Info, RevGoalPath,
         !Disj, !DisjNum, !Candidates, !Pushes, !Singles, !Messages) :-
-    RevDisjGoalPathSteps = [step_disj(!.DisjNum) | RevGoalPathSteps],
-    goal_get_conjunctions_worth_parallelising(Info, RevDisjGoalPathSteps,
+    RevDisjGoalPath= rgp_cons(RevGoalPath, step_disj(!.DisjNum)),
+    goal_get_conjunctions_worth_parallelising(Info, RevDisjGoalPath,
         !Disj, Candidates, Pushes, Singles, Messages),
     !:Candidates = !.Candidates ++ Candidates,
     !:Pushes = !.Pushes ++ Pushes,
@@ -249,7 +248,7 @@
     !:DisjNum = !.DisjNum + 1.
 
 :- pred switch_case_get_conjunctions_worth_parallelising(
-    implicit_parallelism_info::in, list(goal_path_step)::in,
+    implicit_parallelism_info::in, reverse_goal_path::in,
     case_rep(pard_goal_detail_annotation)::in,
     case_rep(pard_goal_detail_annotation)::out,
     int::in, int::out,
@@ -259,11 +258,12 @@
     cord(pard_goal_detail)::in, cord(pard_goal_detail)::out,
     cord(message)::in, cord(message)::out) is det.
 
-switch_case_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps, !Case,
+switch_case_get_conjunctions_worth_parallelising(Info, RevGoalPath, !Case,
         !CaseNum, !Candidates, !Pushes, !Singles, !Messages) :-
     !.Case = case_rep(MainConsIdRep, OtherConsIdReps, Goal0),
-    RevCaseGoalPathSteps = [step_switch(!.CaseNum, no) | RevGoalPathSteps],
-    goal_get_conjunctions_worth_parallelising(Info, RevCaseGoalPathSteps,
+    RevArmPath = rgp_cons(RevGoalPath,
+        step_switch(!.CaseNum, unknown_num_functors_in_type)),
+    goal_get_conjunctions_worth_parallelising(Info, RevArmPath,
         Goal0, Goal, Candidates, Pushes, Singles, Messages),
     !:Case = case_rep(MainConsIdRep, OtherConsIdReps, Goal),
     !:Candidates = !.Candidates ++ Candidates,
@@ -273,7 +273,7 @@
     !:CaseNum = !.CaseNum + 1.
 
 :- pred ite_get_conjunctions_worth_parallelising(
-    implicit_parallelism_info::in,  list(goal_path_step)::in,
+    implicit_parallelism_info::in, reverse_goal_path::in,
     pard_goal_detail::in, pard_goal_detail::out,
     pard_goal_detail::in, pard_goal_detail::out,
     pard_goal_detail::in, pard_goal_detail::out,
@@ -281,18 +281,18 @@
     cord(push_goal)::out, cord(pard_goal_detail)::out,
     cord(message)::out) is det.
 
-ite_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+ite_get_conjunctions_worth_parallelising(Info, RevGoalPath,
         !Cond, !Then, !Else, Candidates, Pushes, Singles, Messages) :-
-    RevCondGoalPathSteps = [step_ite_cond | RevGoalPathSteps],
-    RevThenGoalPathSteps = [step_ite_then | RevGoalPathSteps],
-    RevElseGoalPathSteps = [step_ite_else | RevGoalPathSteps],
+    RevCondGoalPath = rgp_cons(RevGoalPath, step_ite_cond),
+    RevThenGoalPath = rgp_cons(RevGoalPath, step_ite_then),
+    RevElseGoalPath = rgp_cons(RevGoalPath, step_ite_else),
     % We ignore _CondSingles here because you cannot push goals
     % following an if-then-else into the condition.
-    goal_get_conjunctions_worth_parallelising(Info, RevCondGoalPathSteps,
+    goal_get_conjunctions_worth_parallelising(Info, RevCondGoalPath,
         !Cond, CondCandidates, CondPushes, _CondSingles, CondMessages),
-    goal_get_conjunctions_worth_parallelising(Info, RevThenGoalPathSteps,
+    goal_get_conjunctions_worth_parallelising(Info, RevThenGoalPath,
         !Then, ThenCandidates, ThenPushes, ThenSingles, ThenMessages),
-    goal_get_conjunctions_worth_parallelising(Info, RevElseGoalPathSteps,
+    goal_get_conjunctions_worth_parallelising(Info, RevElseGoalPath,
         !Else, ElseCandidates, ElsePushes, ElseSingles, ElseMessages),
     Candidates = CondCandidates ++ ThenCandidates ++ ElseCandidates,
     Pushes = CondPushes ++ ThenPushes ++ ElsePushes,
@@ -300,7 +300,7 @@
     Messages = CondMessages ++ ThenMessages ++ ElseMessages.
 
 :- pred conj_get_conjunctions_worth_parallelising(
-    implicit_parallelism_info::in, list(goal_path_step)::in,
+    implicit_parallelism_info::in, reverse_goal_path::in,
     list(pard_goal_detail)::in, list(pard_goal_detail)::out, int::in,
     list(pard_goal_detail)::in, list(pard_goal_detail)::out,
     assoc_list(int, list(pard_goal_detail))::in,
@@ -310,14 +310,14 @@
     cord(push_goal)::in, cord(push_goal)::out,
     cord(message)::in, cord(message)::out) is det.
 
-conj_get_conjunctions_worth_parallelising(_Info, _RevGoalPathSteps,
+conj_get_conjunctions_worth_parallelising(_Info, _RevGoalPath,
         [], [], _ConjNum, !SinglesSoFar, !RevSingleCands,
         !CandidatesBelow, !Pushes, !MessagesBelow).
-conj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+conj_get_conjunctions_worth_parallelising(Info, RevGoalPath,
         [Conj0 | Conjs0], [Conj | Conjs], ConjNum, SinglesSoFar0, SinglesSoFar,
         !RevSingleCands, !CandidatesBelow, !Pushes, !MessagesBelow) :-
-    RevConjGoalPathSteps = [step_conj(ConjNum) | RevGoalPathSteps],
-    goal_get_conjunctions_worth_parallelising(Info, RevConjGoalPathSteps,
+    RevConjGoalPath = rgp_cons(RevGoalPath, step_conj(ConjNum)),
+    goal_get_conjunctions_worth_parallelising(Info, RevConjGoalPath,
         Conj0, Conj, Candidates, Pushes, SinglesCord, Messages),
     Singles = cord.list(SinglesCord),
     !:CandidatesBelow = !.CandidatesBelow ++ Candidates,
@@ -362,7 +362,7 @@
             SinglesSoFar1 = Singles
         )
     ),
-    conj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+    conj_get_conjunctions_worth_parallelising(Info, RevGoalPath,
         Conjs0, Conjs, ConjNum + 1, SinglesSoFar1, SinglesSoFar,
         !RevSingleCands, !CandidatesBelow, !Pushes, !MessagesBelow).
 
@@ -380,21 +380,21 @@
     % can yield a speedup.
     %
 :- pred build_candidate_conjunction(implicit_parallelism_info::in,
-    list(goal_path_step)::in, list(pard_goal_detail)::in, list(int)::in,
+    reverse_goal_path::in, list(pard_goal_detail)::in, list(int)::in,
     cord(message)::out,
     maybe(candidate_par_conjunction(pard_goal_detail))::out) is det.
 
-build_candidate_conjunction(Info, RevGoalPathSteps, Conjs, CostlyGoalsIndexes,
+build_candidate_conjunction(Info, RevGoalPath, Conjs, CostlyGoalsIndexes,
         !:Messages, MaybeCandidate) :-
     ProcLabel = Info ^ ipi_proc_label,
     !:Messages = cord.empty,
     NumCostlyGoals = list.length(CostlyGoalsIndexes),
-    Location = pl_goal(ProcLabel, rgp(RevGoalPathSteps)),
+    Location = pl_goal(ProcLabel, RevGoalPath),
     append_message(Location,
         info_found_conjs_above_callsite_threshold(NumCostlyGoals),
         !Messages),
 
-    pardgoals_build_candidate_conjunction(Info, Location, RevGoalPathSteps, no,
+    pardgoals_build_candidate_conjunction(Info, Location, RevGoalPath, no,
         Conjs, MaybeCandidate, !Messages),
     (
         MaybeCandidate = yes(_Candidate),
@@ -412,17 +412,17 @@
     % conjunctions in parallel can yield a speedup.
     %
 :- pred push_and_build_candidate_conjunctions(implicit_parallelism_info::in,
-    list(goal_path_step)::in, list(pard_goal_detail)::in, int::in,
+    reverse_goal_path::in, list(pard_goal_detail)::in, int::in,
     list(pard_goal_detail)::in, cord(message)::out,
     list(candidate_par_conjunction(pard_goal_detail))::out) is det.
 
-push_and_build_candidate_conjunctions(_Info, _RevGoalPathSteps, _Conjs,
+push_and_build_candidate_conjunctions(_Info, _RevGoalPath, _Conjs,
         _CostlyIndex, [], cord.empty, []).
-push_and_build_candidate_conjunctions(Info, RevGoalPathSteps, Conjs,
+push_and_build_candidate_conjunctions(Info, RevGoalPath, Conjs,
         CostlyIndex, [Single | Singles], Messages, Candidates) :-
-    push_and_build_candidate_conjunction(Info, RevGoalPathSteps, Conjs,
+    push_and_build_candidate_conjunction(Info, RevGoalPath, Conjs,
         CostlyIndex, Single, HeadMessages, MaybeHeadCandidate),
-    push_and_build_candidate_conjunctions(Info, RevGoalPathSteps, Conjs,
+    push_and_build_candidate_conjunctions(Info, RevGoalPath, Conjs,
         CostlyIndex, Singles, TailMessages, TailCandidates),
     Messages = HeadMessages ++ TailMessages,
     (
@@ -434,58 +434,55 @@
     ).
 
 :- pred push_and_build_candidate_conjunction(implicit_parallelism_info::in,
-    list(goal_path_step)::in, list(pard_goal_detail)::in, int::in,
+    reverse_goal_path::in, list(pard_goal_detail)::in, int::in,
     pard_goal_detail::in, cord(message)::out,
     maybe(candidate_par_conjunction(pard_goal_detail))::out) is det.
 
-push_and_build_candidate_conjunction(Info, RevGoalPathSteps, Conjs,
+push_and_build_candidate_conjunction(Info, RevGoalPath, Conjs,
         CostlyIndex, Single, !:Messages, MaybeCandidate) :-
     SingleRevPath = Single ^ goal_annotation ^ pgd_original_path,
-    SingleRevPath = rgp(SingleRevSteps),
-    list.reverse(SingleRevSteps, SingleSteps),
-    list.reverse(RevGoalPathSteps, GoalPathSteps),
-    (
-        goal_path_inside_relative(fgp(GoalPathSteps), fgp(SingleSteps),
-            RelativePath),
-        RelativePath = fgp(RelativeSteps),
-        RelativeSteps = [step_conj(RelConjStep) | TailRelativeSteps],
+    rgp_to_fgp(SingleRevPath, SinglePath),
+    rgp_to_fgp(RevGoalPath, GoalPath),
+    (
+        goal_path_inside_relative(GoalPath, SinglePath, RelativePath),
+        RelativePath = fgp_cons(step_conj(RelConjStep), TailRelativePath),
         RelConjStep < CostlyIndex,
         list.take(CostlyIndex, Conjs, ConjsUptoCostly),
         list.drop(RelConjStep - 1, ConjsUptoCostly,
             [GoalToPushInto | GoalsToPush])
     ->
-        RevPushGoalPathSteps = [step_conj(RelConjStep) | RevGoalPathSteps],
-        push_goals_create_candidate(Info, RevPushGoalPathSteps,
-            TailRelativeSteps, GoalToPushInto, GoalsToPush,
-            RevCandidateGoalPathSteps, CandidateConjs),
+        RevPushGoalPath = rgp_cons(RevGoalPath, step_conj(RelConjStep)),
+        push_goals_create_candidate(Info, RevPushGoalPath,
+            TailRelativePath, GoalToPushInto, GoalsToPush,
+            RevCandidateGoalPath, CandidateConjs),
 
         ProcLabel = Info ^ ipi_proc_label,
         !:Messages = cord.empty,
         % XXX Location is a lie
-        Location = pl_goal(ProcLabel, rgp(RevGoalPathSteps)),
+        Location = pl_goal(ProcLabel, RevGoalPath),
         append_message(Location,
             info_found_pushed_conjs_above_callsite_threshold,
             !Messages),
 
         (
-            list.split_last(RelativeSteps, MostRelativeSteps,
+            goal_path_remove_last(RelativePath, MostRelativePath,
                 LastRelativeStep),
             LastRelativeStep = step_conj(_)
         ->
             % We push GoalsToPush into the existing conjunction
             % containing Single.
-            PushGoalSteps = MostRelativeSteps
+            PushGoalPath = MostRelativePath
         ;
             % We push GoalsToPush next to Single in a newly created
             % conjunction.
-            PushGoalSteps = RelativeSteps
+            PushGoalPath = RelativePath
         ),
 
-        PushGoal = push_goal(rev_goal_path_to_string(rgp(RevGoalPathSteps)),
+        PushGoal = push_goal(rev_goal_path_to_string(RevGoalPath),
             RelConjStep + 1, CostlyIndex,
-            [goal_path_to_string(fgp(PushGoalSteps))]),
+            [goal_path_to_string(PushGoalPath)]),
         pardgoals_build_candidate_conjunction(Info, Location,
-            RevCandidateGoalPathSteps, yes(PushGoal), CandidateConjs,
+            RevCandidateGoalPath, yes(PushGoal), CandidateConjs,
             MaybeCandidate, !Messages),
         (
             MaybeCandidate = yes(_),
@@ -532,32 +529,31 @@
     ).
 
 :- pred push_goals_create_candidate(implicit_parallelism_info::in,
-    list(goal_path_step)::in, list(goal_path_step)::in,
+    reverse_goal_path::in, forward_goal_path::in,
     pard_goal_detail::in, list(pard_goal_detail)::in,
-    list(goal_path_step)::out, list(pard_goal_detail)::out) is det.
+    reverse_goal_path::out, list(pard_goal_detail)::out) is det.
 
-push_goals_create_candidate(Info, RevCurPathSteps,
-        [], GoalToPushInto, GoalsToPush0,
-        RevCandidateGoalPathSteps, CandidateConjs) :-
-    RevCandidateGoalPathSteps = RevCurPathSteps,
+push_goals_create_candidate(Info, RevCurPath, fgp_nil,
+        GoalToPushInto, GoalsToPush0, RevCandidateGoalPath, CandidateConjs) :-
+    RevCandidateGoalPath = RevCurPath,
     % The pushed goals will have different costs in this context, in particular
     % the number of times they're called varies, This affects the per-call
     % costs of recursive calls.
     Calls = goal_cost_get_calls(GoalToPushInto ^ goal_annotation ^ pgd_cost),
     map(fix_goal_counts(Info, Calls), GoalsToPush0, GoalsToPush),
     CandidateConjs = [GoalToPushInto | GoalsToPush].
-push_goals_create_candidate(Info, RevCurPathSteps,
-        [HeadRelStep | TailRelSteps], GoalToPushInto, GoalsToPush0,
-        RevCandidateGoalPathSteps, CandidateConjs) :-
+push_goals_create_candidate(Info, RevCurPath,
+        fgp_cons(FirstRelStep, TailRelPath),
+        GoalToPushInto, GoalsToPush0, RevCandidateGoalPath, CandidateConjs) :-
     GoalToPushInto = goal_rep(GoalExpr, _, _),
     (
-        HeadRelStep = step_conj(N),
+        FirstRelStep = step_conj(N),
         ( GoalExpr = conj_rep(Goals) ->
             (
-                TailRelSteps = [],
+                TailRelPath = fgp_nil,
                 % Conjoin GoalsToPush not with just the expensive goal,
                 % but with the whole conjunction containing it.
-                RevCandidateGoalPathSteps = RevCurPathSteps,
+                RevCandidateGoalPath = RevCurPath,
                 % The pushed goals will have different costs in this context,
                 % in particular the number of times they're called varies, This
                 % affects the per-call costs of recursive calls.
@@ -566,13 +562,13 @@
                 map(fix_goal_counts(Info, Calls), GoalsToPush0, GoalsToPush),
                 CandidateConjs = Goals ++ GoalsToPush
             ;
-                TailRelSteps = [_ | _],
+                TailRelPath = fgp_cons(_, _),
                 list.det_drop(N - 1, Goals, Tail),
                 ( Tail = [SubGoal] ->
                     push_goals_create_candidate(Info,
-                        [HeadRelStep | RevCurPathSteps],
-                        TailRelSteps, SubGoal, GoalsToPush0,
-                        RevCandidateGoalPathSteps, CandidateConjs)
+                        rgp_cons(RevCurPath, FirstRelStep),
+                        TailRelPath, SubGoal, GoalsToPush0,
+                        RevCandidateGoalPath, CandidateConjs)
                 ;
                     % We can't push goals into the non-last conjunct without
                     % re-ordering, which is currently not supported.  By
@@ -582,7 +578,7 @@
                     % single expensive goal from within the conjunction and
                     % therefore possibly finding other single expensive goals
                     % later in this conjunction.
-                    RevCandidateGoalPathSteps = RevCurPathSteps,
+                    RevCandidateGoalPath = RevCurPath,
                     Cost = GoalToPushInto ^ goal_annotation ^ pgd_cost,
                     Calls = goal_cost_get_calls(Cost),
                     map(fix_goal_counts(Info, Calls), GoalsToPush0,
@@ -594,75 +590,80 @@
             unexpected($module, $pred, "not conj")
         )
     ;
-        HeadRelStep = step_disj(N),
+        FirstRelStep = step_disj(N),
         ( GoalExpr = disj_rep(Goals) ->
             list.det_index1(Goals, N, SubGoal),
-            push_goals_create_candidate(Info, [HeadRelStep | RevCurPathSteps],
-                TailRelSteps, SubGoal, GoalsToPush0,
-                RevCandidateGoalPathSteps, CandidateConjs)
+            push_goals_create_candidate(Info,
+                rgp_cons(RevCurPath, FirstRelStep),
+                TailRelPath, SubGoal, GoalsToPush0,
+                RevCandidateGoalPath, CandidateConjs)
         ;
             unexpected($module, $pred, "not disj")
         )
     ;
-        HeadRelStep = step_switch(N, _),
+        FirstRelStep = step_switch(N, _),
         ( GoalExpr = switch_rep(_, _, Cases) ->
             list.det_index1(Cases, N, Case),
             Case = case_rep(_, _, SubGoal),
-            push_goals_create_candidate(Info, [HeadRelStep | RevCurPathSteps],
-                TailRelSteps, SubGoal, GoalsToPush0,
-                RevCandidateGoalPathSteps, CandidateConjs)
+            push_goals_create_candidate(Info,
+                rgp_cons(RevCurPath, FirstRelStep),
+                TailRelPath, SubGoal, GoalsToPush0,
+                RevCandidateGoalPath, CandidateConjs)
         ;
             unexpected($module, $pred, "not switch")
         )
     ;
-        HeadRelStep = step_ite_then,
+        FirstRelStep = step_ite_then,
         ( GoalExpr = ite_rep(_, Then, _) ->
-            push_goals_create_candidate(Info, [HeadRelStep | RevCurPathSteps],
-                TailRelSteps, Then, GoalsToPush0,
-                RevCandidateGoalPathSteps, CandidateConjs)
+            push_goals_create_candidate(Info,
+                rgp_cons(RevCurPath, FirstRelStep),
+                TailRelPath, Then, GoalsToPush0,
+                RevCandidateGoalPath, CandidateConjs)
         ;
             unexpected($module, $pred, "not ite_then")
         )
     ;
-        HeadRelStep = step_ite_else,
+        FirstRelStep = step_ite_else,
         ( GoalExpr = ite_rep(_, _, Else) ->
-            push_goals_create_candidate(Info, [HeadRelStep | RevCurPathSteps],
-                TailRelSteps, Else, GoalsToPush0,
-                RevCandidateGoalPathSteps, CandidateConjs)
+            push_goals_create_candidate(Info,
+                rgp_cons(RevCurPath, FirstRelStep),
+                TailRelPath, Else, GoalsToPush0,
+                RevCandidateGoalPath, CandidateConjs)
         ;
             unexpected($module, $pred, "not ite_else")
         )
     ;
-        HeadRelStep = step_ite_cond,
+        FirstRelStep = step_ite_cond,
         % We cannot push into a condition.
         unexpected($module, $pred, "ite_cond")
     ;
-        HeadRelStep = step_neg,
+        FirstRelStep = step_neg,
         % We cannot push into a negated goal.
         unexpected($module, $pred, "neg")
     ;
-        HeadRelStep = step_scope(_),
+        FirstRelStep = step_scope(_),
         ( GoalExpr = scope_rep(SubGoal, _) ->
-            push_goals_create_candidate(Info, [HeadRelStep | RevCurPathSteps],
-                TailRelSteps, SubGoal, GoalsToPush0,
-                RevCandidateGoalPathSteps, CandidateConjs)
+            push_goals_create_candidate(Info,
+                rgp_cons(RevCurPath, FirstRelStep),
+                TailRelPath, SubGoal, GoalsToPush0,
+                RevCandidateGoalPath, CandidateConjs)
         ;
             unexpected($module, $pred, "not scope")
         )
     ;
-        HeadRelStep = step_lambda,
+        FirstRelStep = step_lambda,
         % These should not exist in a profiled program.
         unexpected($module, $pred, "lambda")
     ;
-        HeadRelStep = step_try,
+        FirstRelStep = step_try,
         % These should not exist in a profiled program.
         unexpected($module, $pred, "try")
     ;
-        HeadRelStep = step_atomic_main,
+        FirstRelStep = step_atomic_main,
         % These should not exist in a profiled program.
         unexpected($module, $pred, "atomic_main")
     ;
-        HeadRelStep = step_atomic_orelse(_),
+        FirstRelStep = step_atomic_orelse(_),
         % These should not exist in a profiled program.
         unexpected($module, $pred, "atomic_orelse")
     ).
@@ -698,12 +699,12 @@
     !Goal ^ goal_annotation ^ pgd_cost_above_threshold := AboveThreshold.
 
 :- pred pardgoals_build_candidate_conjunction(implicit_parallelism_info::in,
-    program_location::in, list(goal_path_step)::in,
+    program_location::in, reverse_goal_path::in,
     maybe(push_goal)::in, list(pard_goal_detail)::in,
     maybe(candidate_par_conjunction(pard_goal_detail))::out,
     cord(message)::in, cord(message)::out) is det.
 
-pardgoals_build_candidate_conjunction(Info, Location, RevGoalPathSteps,
+pardgoals_build_candidate_conjunction(Info, Location, RevGoalPath,
         MaybePushGoal, Goals, MaybeCandidate, !Messages) :-
     % Setting up the first parallel conjunct is a different algorithm to the
     % latter ones, at this point we have the option of moving goals from before
@@ -727,7 +728,7 @@
         GoalsBeforeCost = goal_cost_get_percall(GoalsBeforeCost0),
         conj_calc_cost(GoalsAfter, Calls, GoalsAfterCost0),
         GoalsAfterCost = goal_cost_get_percall(GoalsAfterCost0),
-        RevGoalPathString = rev_goal_path_to_string(rgp(RevGoalPathSteps)),
+        RevGoalPathString = rev_goal_path_to_string(RevGoalPath),
         Candidate = candidate_par_conjunction(RevGoalPathString, MaybePushGoal,
             FirstConjNum, IsDependent, GoalsBefore, GoalsBeforeCost, ParConjs,
             GoalsAfter, GoalsAfterCost, Metrics),
@@ -779,7 +780,7 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_to_pard_goal(Info, RevGoalPathSteps, !Goal, !Messages) :-
+goal_to_pard_goal(Info, RevGoalPath, !Goal, !Messages) :-
     !.Goal = goal_rep(GoalExpr0, Detism, GoalId),
     InstMapInfo = get_goal_attribute_det(Info ^ ipi_inst_map_array, GoalId),
     Coverage = get_goal_attribute_det(Info ^ ipi_coverage_array, GoalId),
@@ -787,41 +788,42 @@
     (
         (
             GoalExpr0 = conj_rep(Conjs0),
-            list.map_foldl2(conj_to_pard_goals(Info, RevGoalPathSteps),
+            list.map_foldl2(conj_to_pard_goals(Info, RevGoalPath),
                 Conjs0, Conjs, 1, _, !Messages),
             conj_calc_cost(Conjs, Before, Cost),
             GoalExpr = conj_rep(Conjs)
         ;
             GoalExpr0 = disj_rep(Disjs0),
-            list.map_foldl2(disj_to_pard_goals(Info, RevGoalPathSteps),
+            list.map_foldl2(disj_to_pard_goals(Info, RevGoalPath),
                 Disjs0, Disjs, 1, _, !Messages),
             disj_calc_cost(Disjs, Before, Cost),
             GoalExpr = disj_rep(Disjs)
         ;
             GoalExpr0 = switch_rep(Var, CanFail, Cases0),
-            list.map_foldl2(case_to_pard_goal(Info, RevGoalPathSteps),
+            list.map_foldl2(case_to_pard_goal(Info, RevGoalPath),
                 Cases0, Cases, 1, _, !Messages),
             switch_calc_cost(Cases, Before, Cost),
             GoalExpr = switch_rep(Var, CanFail, Cases)
         ;
             GoalExpr0 = ite_rep(Cond0, Then0, Else0),
-            goal_to_pard_goal(Info, [step_ite_cond | RevGoalPathSteps],
+            goal_to_pard_goal(Info, rgp_cons(RevGoalPath, step_ite_cond),
                 Cond0, Cond, !Messages),
-            goal_to_pard_goal(Info, [step_ite_then | RevGoalPathSteps],
+            goal_to_pard_goal(Info, rgp_cons(RevGoalPath, step_ite_then),
                 Then0, Then, !Messages),
-            goal_to_pard_goal(Info, [step_ite_else | RevGoalPathSteps],
+            goal_to_pard_goal(Info, rgp_cons(RevGoalPath, step_ite_else),
                 Else0, Else, !Messages),
             ite_calc_cost(Cond, Then, Else, Cost),
             GoalExpr = ite_rep(Cond, Then, Else)
         ;
             GoalExpr0 = negation_rep(SubGoal0),
-            goal_to_pard_goal(Info, [step_neg | RevGoalPathSteps],
+            goal_to_pard_goal(Info, rgp_cons(RevGoalPath, step_neg),
                 SubGoal0, SubGoal, !Messages),
             Cost = SubGoal ^ goal_annotation ^ pgd_cost,
             GoalExpr = negation_rep(SubGoal)
         ;
             GoalExpr0 = scope_rep(SubGoal0, MaybeCut),
-            goal_to_pard_goal(Info, [step_scope(MaybeCut) | RevGoalPathSteps],
+            goal_to_pard_goal(Info,
+                rgp_cons(RevGoalPath, step_scope(MaybeCut)),
                 SubGoal0, SubGoal, !Messages),
             Cost = SubGoal ^ goal_annotation ^ pgd_cost,
             GoalExpr = scope_rep(SubGoal, MaybeCut)
@@ -830,29 +832,29 @@
 
         BoundVars = to_sorted_list(InstMapInfo ^ im_bound_vars),
         list.foldl(
-            goal_build_use_map(!.Goal, RevGoalPathSteps, Cost, Info,
+            goal_build_use_map(!.Goal, RevGoalPath, Cost, Info,
                 var_use_production),
             BoundVars, map.init, ProductionUseMap),
         ConsumedVars = to_sorted_list(InstMapInfo ^ im_consumed_vars),
         list.foldl(
-            goal_build_use_map(!.Goal, RevGoalPathSteps, Cost, Info,
+            goal_build_use_map(!.Goal, RevGoalPath, Cost, Info,
                 var_use_consumption),
             ConsumedVars, map.init, ConsumptionUseMap)
     ;
         GoalExpr0 = atomic_goal_rep(Context, Line, BoundVars, AtomicGoal),
         GoalExpr = atomic_goal_rep(Context, Line, BoundVars, AtomicGoal),
-        atomic_pard_goal_type(Info, RevGoalPathSteps, AtomicGoal, InstMapInfo,
+        atomic_pard_goal_type(Info, RevGoalPath, AtomicGoal, InstMapInfo,
             PardGoalType, Messages),
-        atomic_pard_goal_cost(Info, RevGoalPathSteps, Coverage, AtomicGoal,
+        atomic_pard_goal_cost(Info, RevGoalPath, Coverage, AtomicGoal,
             Cost),
 
         list.foldl(
-            atomic_goal_build_use_map(AtomicGoal, RevGoalPathSteps, Info,
+            atomic_goal_build_use_map(AtomicGoal, RevGoalPath, Info,
                 var_use_production),
             BoundVars, map.init, ProductionUseMap),
         ConsumedVars = to_sorted_list(InstMapInfo ^ im_consumed_vars),
         list.foldl(
-            atomic_goal_build_use_map(AtomicGoal, RevGoalPathSteps, Info,
+            atomic_goal_build_use_map(AtomicGoal, RevGoalPath, Info,
                 var_use_consumption),
             ConsumedVars, map.init, ConsumptionUseMap),
 
@@ -870,26 +872,26 @@
         CostAboveThreshold = cost_not_above_par_threshold
     ),
     PardGoalAnnotation = pard_goal_detail(PardGoalType, InstMapInfo,
-        rgp(RevGoalPathSteps), Coverage, Cost, CostAboveThreshold,
+        RevGoalPath, Coverage, Cost, CostAboveThreshold,
         ProductionUseMap, ConsumptionUseMap),
     !:Goal = goal_rep(GoalExpr, Detism, PardGoalAnnotation).
 
 :- pred goal_build_use_map(goal_rep(goal_id)::in,
-    list(goal_path_step)::in, goal_cost_csq::in, implicit_parallelism_info::in,
+    reverse_goal_path::in, goal_cost_csq::in, implicit_parallelism_info::in,
     var_use_type::in, var_rep::in,
     map(var_rep, lazy(var_use_info))::in,
     map(var_rep, lazy(var_use_info))::out) is det.
 
-goal_build_use_map(Goal, RevGoalPathSteps, Cost, Info, VarUseType, Var, !Map) :-
-    LazyUse = delay((func) = compute_goal_var_use_lazy(Goal, RevGoalPathSteps,
+goal_build_use_map(Goal, RevGoalPath, Cost, Info, VarUseType, Var, !Map) :-
+    LazyUse = delay((func) = compute_goal_var_use_lazy(Goal, RevGoalPath,
         Cost, Info, VarUseType, Var)),
     map.det_insert(Var, LazyUse, !Map).
 
-:- func compute_goal_var_use_lazy(goal_rep(goal_id), list(goal_path_step),
+:- func compute_goal_var_use_lazy(goal_rep(goal_id), reverse_goal_path,
     goal_cost_csq, implicit_parallelism_info, var_use_type, var_rep)
     = var_use_info.
 
-compute_goal_var_use_lazy(Goal, RevGoalPathSteps, Cost, Info, VarUseType, Var)
+compute_goal_var_use_lazy(Goal, RevGoalPath, Cost, Info, VarUseType, Var)
         = Use :-
     Info = implicit_parallelism_info(Deep, _ProgRep, _Params, CliquePtr,
         CallSiteMap, RecursiveCallSiteMap, ContainingGoalMap, CoverageArray,
@@ -906,7 +908,7 @@
             VarUseType),
         var_first_use(CliquePtr, CallSiteMap, RecursiveCallSiteMap,
             ContainingGoalMap, CoverageArray, RecursionType, RecDepth, Goal,
-            rgp(RevGoalPathSteps), CostPercall, Var, VarUseOptions, Use)
+            RevGoalPath, CostPercall, Var, VarUseOptions, Use)
     ;
         ( RecursionType = rt_divide_and_conquer(_, _)
         ; RecursionType = rt_mutual_recursion(_)
@@ -926,44 +928,45 @@
     ).
 
 :- pred conj_to_pard_goals(implicit_parallelism_info::in,
-    list(goal_path_step)::in, goal_rep(goal_id)::in,
+    reverse_goal_path::in, goal_rep(goal_id)::in,
     pard_goal_detail::out, int::in, int::out,
     cord(message)::in, cord(message)::out) is det.
 
-conj_to_pard_goals(Info, RevGoalPathSteps, !Goal, !ConjNum, !Messages) :-
-    goal_to_pard_goal(Info, [step_conj(!.ConjNum) | RevGoalPathSteps],
+conj_to_pard_goals(Info, RevGoalPath, !Goal, !ConjNum, !Messages) :-
+    goal_to_pard_goal(Info, rgp_cons(RevGoalPath, step_conj(!.ConjNum)),
         !Goal, !Messages),
     !:ConjNum = !.ConjNum + 1.
 
 :- pred disj_to_pard_goals(implicit_parallelism_info::in,
-    list(goal_path_step)::in, goal_rep(goal_id)::in,
+    reverse_goal_path::in, goal_rep(goal_id)::in,
     pard_goal_detail::out, int::in, int::out,
     cord(message)::in, cord(message)::out) is det.
 
-disj_to_pard_goals(Info, RevGoalPathSteps, !Goal, !DisjNum, !Messages) :-
-    goal_to_pard_goal(Info, [step_disj(!.DisjNum) | RevGoalPathSteps],
+disj_to_pard_goals(Info, RevGoalPath, !Goal, !DisjNum, !Messages) :-
+    goal_to_pard_goal(Info, rgp_cons(RevGoalPath, step_disj(!.DisjNum)),
         !Goal, !Messages),
     !:DisjNum = !.DisjNum + 1.
 
 :- pred case_to_pard_goal(implicit_parallelism_info::in,
-    list(goal_path_step)::in, case_rep(goal_id)::in,
+    reverse_goal_path::in, case_rep(goal_id)::in,
     case_rep(pard_goal_detail_annotation)::out, int::in, int::out,
     cord(message)::in, cord(message)::out) is det.
 
-case_to_pard_goal(Info, RevGoalPathSteps, !Case, !CaseNum, !Messages) :-
+case_to_pard_goal(Info, RevGoalPath, !Case, !CaseNum, !Messages) :-
     !.Case = case_rep(ConsId, OtherConsId, Goal0),
-    goal_to_pard_goal(Info, [step_switch(!.CaseNum, no) | RevGoalPathSteps],
-        Goal0, Goal, !Messages),
+    RevArmPath = rgp_cons(RevGoalPath,
+        step_switch(!.CaseNum, unknown_num_functors_in_type)),
+    goal_to_pard_goal(Info, RevArmPath, Goal0, Goal, !Messages),
     !:CaseNum = !.CaseNum + 1,
     !:Case = case_rep(ConsId, OtherConsId, Goal).
 
 %-----------------------------------------------------------------------------%
 
 :- pred atomic_pard_goal_type(implicit_parallelism_info::in,
-    list(goal_path_step)::in, atomic_goal_rep::in, inst_map_info::in,
+    reverse_goal_path::in, atomic_goal_rep::in, inst_map_info::in,
     pard_goal_type::out, cord(message)::out) is det.
 
-atomic_pard_goal_type(Info, RevGoalPathSteps, AtomicGoal, InstMapInfo,
+atomic_pard_goal_type(Info, RevGoalPath, AtomicGoal, InstMapInfo,
         GoalType, !:Messages) :-
     !:Messages = cord.empty,
     InstMapBefore = InstMapInfo ^ im_before,
@@ -975,17 +978,17 @@
     ;
         IsCall = atomic_goal_is_call(Args),
         % Lookup var use information.
-        map.lookup(Info ^ ipi_call_sites, rgp(RevGoalPathSteps), CallSite),
+        map.lookup(Info ^ ipi_call_sites, RevGoalPath, CallSite),
         list.map_foldl(compute_var_modes(InstMapBefore, InstMapAfter),
             Args, VarsAndModes, 0, _),
         GoalType = pgt_call(VarsAndModes, CallSite)
     ).
 
 :- pred atomic_pard_goal_cost(implicit_parallelism_info::in,
-    list(goal_path_step)::in, coverage_info::in, atomic_goal_rep::in,
+    reverse_goal_path::in, coverage_info::in, atomic_goal_rep::in,
     goal_cost_csq::out) is det.
 
-atomic_pard_goal_cost(Info, RevGoalPathSteps, Coverage, AtomicGoal, Cost) :-
+atomic_pard_goal_cost(Info, RevGoalPath, Coverage, AtomicGoal, Cost) :-
     atomic_goal_is_call(AtomicGoal, IsCall),
     (
         IsCall = atomic_goal_is_trivial,
@@ -993,7 +996,6 @@
         Cost = atomic_goal_cost(Calls)
     ;
         IsCall = atomic_goal_is_call(_),
-        RevGoalPath = rgp(RevGoalPathSteps),
         map.lookup(Info ^ ipi_call_sites, RevGoalPath, CallSite),
         (
             cost_and_callees_is_recursive(Info ^ ipi_clique, CallSite),
Index: deep_profiler/create_report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/create_report.m,v
retrieving revision 1.35
diff -u -b -r1.35 create_report.m
--- deep_profiler/create_report.m	3 May 2011 04:35:00 -0000	1.35
+++ deep_profiler/create_report.m	19 Sep 2011 10:46:55 -0000
@@ -1598,7 +1598,7 @@
         UnQualRefinedName = "mercury_runtime",
         QualRefinedName = "mercury_runtime",
         SlotNumber = -1,
-        RevGoalPath = rgp([]),
+        RevGoalPath = rgp_nil,
         MaybeCalleeDesc = no
     ),
     CallSiteDesc = call_site_desc(CSSPtr, ContainingPSPtr,
Index: deep_profiler/message.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/message.m,v
retrieving revision 1.16
diff -u -b -r1.16 message.m
--- deep_profiler/message.m	27 Jan 2011 08:03:53 -0000	1.16
+++ deep_profiler/message.m	19 Sep 2011 10:46:34 -0000
@@ -226,12 +226,11 @@
     ;
         Location = pl_goal(ProcLabel, RevGoalPath),
         location_to_string(Level, pl_proc(ProcLabel), FirstLine),
-        RevGoalPath = rgp(RevGoalSteps),
         (
-            RevGoalSteps = [],
+            RevGoalPath = rgp_nil,
             GoalPathString = singleton("Root goal")
         ;
-            RevGoalSteps = [_ | _],
+            RevGoalPath = rgp_cons(_, _),
             GoalPathString = singleton("Goal: ") ++
                 singleton(rev_goal_path_to_string(RevGoalPath))
         ),
Index: deep_profiler/program_representation_utils.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/program_representation_utils.m,v
retrieving revision 1.35
diff -u -b -r1.35 program_representation_utils.m
--- deep_profiler/program_representation_utils.m	6 May 2011 05:03:28 -0000	1.35
+++ deep_profiler/program_representation_utils.m	19 Sep 2011 10:59:27 -0000
@@ -59,13 +59,13 @@
                 pgi_var_table               :: var_table
             ).
 
-    % print_goal_to_strings(Lookup, VarTable, Indent, RevGoalPathSteps, Goal,
+    % print_goal_to_strings(Lookup, VarTable, Indent, RevGoalPath, Goal,
     %   Strings):
     %
     % Print a goal (recursively) to a string representation.
     %
 :- pred print_goal_to_strings(print_goal_info(T, GoalAnn)::in, int::in,
-    list(goal_path_step)::in, goal_rep(T)::in, cord(string)::out) is det
+    reverse_goal_path::in, goal_rep(T)::in, cord(string)::out) is det
     <= goal_annotation(GoalAnn).
 
 %----------------------------------------------------------------------------%
@@ -249,8 +249,8 @@
     ProcLabelString = DetismString ++ cord.singleton(" ") ++
         cord.singleton(ProcLabelString0),
     print_args_to_strings(print_head_var, VarTable, ArgVarReps, ArgsString),
-    print_goal_to_strings(print_goal_info(Lookup, VarTable), 1, [], GoalRep,
-        GoalString),
+    print_goal_to_strings(print_goal_info(Lookup, VarTable), 1, rgp_nil,
+        GoalRep, GoalString),
     Strings = ProcLabelString ++ ArgsString ++ cord.singleton(" :-\n") ++
         GoalString ++ nl.
 
@@ -276,16 +276,16 @@
 
 %-----------------------------------------------------------------------------%
 
-print_goal_to_strings(Info, Indent, RevGoalPathSteps, GoalRep, Strings) :-
+print_goal_to_strings(Info, Indent, RevGoalPath, GoalRep, Strings) :-
     GoalRep = goal_rep(GoalExprRep, DetismRep, AnnotationKey),
     VarTable = Info ^ pgi_var_table,
     (
         GoalExprRep = conj_rep(ConjGoalReps),
-        print_conj_to_strings(Info, Indent, RevGoalPathSteps,
+        print_conj_to_strings(Info, Indent, RevGoalPath,
             ConjGoalReps, ExprString)
     ;
         GoalExprRep = disj_rep(DisjGoalReps),
-        print_disj_to_strings(Info, Indent, RevGoalPathSteps, 1, DisjGoalReps,
+        print_disj_to_strings(Info, Indent, RevGoalPath, 1, DisjGoalReps,
             no, DisjString),
         ExprString = indent(Indent) ++
             cord.singleton("(\n") ++ DisjString ++ indent(Indent) ++
@@ -295,21 +295,21 @@
         lookup_var_name(VarTable, SwitchVarRep, SwitchVarName),
         string.format("%s switch on %s\n",
             [s(string(CanFail)), s(SwitchVarName)], SwitchOnString),
-        print_switch_to_strings(Info, Indent + 1, RevGoalPathSteps, 1,
+        print_switch_to_strings(Info, Indent + 1, RevGoalPath, 1,
             CasesRep, no, SwitchString),
         ExprString = indent(Indent) ++ cord.singleton(SwitchOnString) ++
             indent(Indent) ++ cord.singleton("(\n") ++ SwitchString ++
             indent(Indent) ++ cord.singleton(")\n")
     ;
         GoalExprRep = ite_rep(CondRep, ThenRep, ElseRep),
-        RevGoalPathStepsCond = [step_ite_cond | RevGoalPathSteps],
-        RevGoalPathStepsThen = [step_ite_then | RevGoalPathSteps],
-        RevGoalPathStepsElse = [step_ite_else | RevGoalPathSteps],
-        print_goal_to_strings(Info, Indent + 1, RevGoalPathStepsCond,
+        RevGoalPathCond = rgp_cons(RevGoalPath, step_ite_cond),
+        RevGoalPathThen = rgp_cons(RevGoalPath, step_ite_then),
+        RevGoalPathElse = rgp_cons(RevGoalPath, step_ite_else),
+        print_goal_to_strings(Info, Indent + 1, RevGoalPathCond,
             CondRep, CondString),
-        print_goal_to_strings(Info, Indent + 1, RevGoalPathStepsThen,
+        print_goal_to_strings(Info, Indent + 1, RevGoalPathThen,
             ThenRep, ThenString),
-        print_goal_to_strings(Info, Indent + 1, RevGoalPathStepsElse,
+        print_goal_to_strings(Info, Indent + 1, RevGoalPathElse,
             ElseRep, ElseString),
         IndentString = indent(Indent),
         ExprString = IndentString ++ cord.singleton("(\n") ++ CondString ++
@@ -318,8 +318,8 @@
             IndentString ++ cord.singleton(")\n")
     ;
         GoalExprRep = negation_rep(SubGoalRep),
-        RevSubGoalPathSteps = [step_neg | RevGoalPathSteps],
-        print_goal_to_strings(Info, Indent + 1, RevSubGoalPathSteps,
+        RevSubGoalPath = rgp_cons(RevGoalPath, step_neg),
+        print_goal_to_strings(Info, Indent + 1, RevSubGoalPath,
             SubGoalRep, SubGoalString),
         ExprString = indent(Indent) ++ cord.singleton("not (\n") ++
             SubGoalString ++ indent(Indent) ++ cord.singleton(")\n")
@@ -332,8 +332,8 @@
             MaybeCut = scope_is_no_cut,
             CutString = cord.empty
         ),
-        RevSubGoalPathSteps = [step_scope(MaybeCut) | RevGoalPathSteps],
-        print_goal_to_strings(Info, Indent + 1, RevSubGoalPathSteps,
+        RevSubGoalPath = rgp_cons(RevGoalPath, step_scope(MaybeCut)),
+        print_goal_to_strings(Info, Indent + 1, RevSubGoalPath,
             SubGoalRep, SubGoalString),
         ExprString = indent(Indent) ++ cord.singleton("scope") ++ CutString ++
             cord.singleton(" (\n") ++
@@ -366,7 +366,7 @@
         GoalAnnotationLines = foldr(++, GoalAnnotationLines1, empty)
     ),
 
-    GoalPathString0 = rev_goal_path_to_string(rgp(RevGoalPathSteps)),
+    GoalPathString0 = rev_goal_path_to_string(RevGoalPath),
     ( GoalPathString0 = "" ->
         GoalPathString = "root goal"
     ;
@@ -381,37 +381,35 @@
         ++ ExprString.
 
 :- pred print_conj_to_strings(print_goal_info(T, GoalAnn)::in, int::in,
-    list(goal_path_step)::in, list(goal_rep(T))::in,
-    cord(string)::out) is det
+    reverse_goal_path::in, list(goal_rep(T))::in, cord(string)::out) is det
     <= goal_annotation(GoalAnn).
 
-print_conj_to_strings(Info, Indent, RevGoalPathSteps, GoalReps, Strings) :-
+print_conj_to_strings(Info, Indent, RevGoalPath, GoalReps, Strings) :-
     (
         GoalReps = [],
         Strings = cord.snoc(indent(Indent), "true\n")
     ;
         GoalReps = [_ | _],
-        print_conj_to_strings_2(Info, Indent, RevGoalPathSteps, 1, GoalReps,
+        print_conj_to_strings_2(Info, Indent, RevGoalPath, 1, GoalReps,
             Strings)
     ).
 
 :- pred print_conj_to_strings_2(print_goal_info(T, GoalAnn)::in, int::in,
-    list(goal_path_step)::in, int::in, list(goal_rep(T))::in,
-    cord(string)::out)
+    reverse_goal_path::in, int::in, list(goal_rep(T))::in, cord(string)::out)
     is det <= goal_annotation(GoalAnn).
 
 print_conj_to_strings_2(_, _Indent, _, _, [], cord.empty).
-print_conj_to_strings_2(Info, Indent, RevGoalPathSteps, ConjNum,
+print_conj_to_strings_2(Info, Indent, RevGoalPath, ConjNum,
         [GoalRep | GoalReps], Strings) :-
     % We use the absence of a separator to denote conjunction.
     %
     % We could try to append the comma at the end of each goal that is
     % not last in a conjunction, but that would be significant work,
     % and (at least for now) there is no real need for it.
-    RevSubGoalPathSteps = [step_conj(ConjNum) | RevGoalPathSteps],
-    print_goal_to_strings(Info, Indent, RevSubGoalPathSteps, GoalRep,
+    RevSubGoalPath = rgp_cons(RevGoalPath, step_conj(ConjNum)),
+    print_goal_to_strings(Info, Indent, RevSubGoalPath, GoalRep,
         HeadGoalString),
-    print_conj_to_strings_2(Info, Indent, RevGoalPathSteps, ConjNum + 1,
+    print_conj_to_strings_2(Info, Indent, RevGoalPath, ConjNum + 1,
         GoalReps, TailGoalsString),
     (
         GoalReps = [],
@@ -423,12 +421,12 @@
     Strings = HeadGoalString ++ Separator ++ TailGoalsString.
 
 :- pred print_disj_to_strings(print_goal_info(T, GoalAnn)::in, int::in,
-    list(goal_path_step)::in, int::in, list(goal_rep(T))::in, bool::in,
+    reverse_goal_path::in, int::in, list(goal_rep(T))::in, bool::in,
     cord(string)::out)
     is det <= goal_annotation(GoalAnn).
 
 print_disj_to_strings(_, _Indent, _, _, [], _PrintSemi, cord.empty).
-print_disj_to_strings(Info, Indent, RevGoalPathSteps, DisjNum,
+print_disj_to_strings(Info, Indent, RevGoalPath, DisjNum,
         [GoalRep | GoalReps], PrintSemi, Strings) :-
     (
         PrintSemi = no,
@@ -437,20 +435,20 @@
         PrintSemi = yes,
         DelimString = indent(Indent) ++ cord.singleton(";\n")
     ),
-    RevSubGoalPathSteps = [step_disj(DisjNum) | RevGoalPathSteps],
-    print_goal_to_strings(Info, Indent + 1, RevSubGoalPathSteps, GoalRep,
+    RevSubGoalPath = rgp_cons(RevGoalPath, step_disj(DisjNum)),
+    print_goal_to_strings(Info, Indent + 1, RevSubGoalPath, GoalRep,
         HeadGoalString),
-    print_disj_to_strings(Info, Indent, RevGoalPathSteps, DisjNum + 1,
+    print_disj_to_strings(Info, Indent, RevGoalPath, DisjNum + 1,
         GoalReps, yes, TailGoalsString),
     Strings = DelimString ++ HeadGoalString ++ TailGoalsString.
 
 :- pred print_switch_to_strings(print_goal_info(T, GoalAnn)::in, int::in,
-    list(goal_path_step)::in, int::in, list(case_rep(T))::in, bool::in,
+    reverse_goal_path::in, int::in, list(case_rep(T))::in, bool::in,
     cord(string)::out) is det
     <= goal_annotation(GoalAnn).
 
 print_switch_to_strings(_, _Indent, _, _, [], _PrintSemi, cord.empty).
-print_switch_to_strings(Info, Indent, RevGoalPathSteps, CaseNum,
+print_switch_to_strings(Info, Indent, RevGoalPath, CaseNum,
         [CaseRep | CaseReps], PrintSemi, Strings) :-
     (
         PrintSemi = no,
@@ -464,10 +462,11 @@
         ConsIdArityString),
     list.map(print_cons_id_and_arity_to_strings(Indent + 1),
         OtherConsIdArityRep, OtherConsIdArityStrings),
-    RevSubGoalPathSteps = [step_switch(CaseNum, no) | RevGoalPathSteps],
-    print_goal_to_strings(Info, Indent + 1, RevSubGoalPathSteps,
+    RevSubGoalPath = rgp_cons(RevGoalPath,
+        step_switch(CaseNum, unknown_num_functors_in_type)),
+    print_goal_to_strings(Info, Indent + 1, RevSubGoalPath,
         GoalRep, HeadGoalString),
-    print_switch_to_strings(Info, Indent, RevGoalPathSteps, CaseNum + 1,
+    print_switch_to_strings(Info, Indent, RevGoalPath, CaseNum + 1,
         CaseReps, yes, TailCasesStrings),
     Strings = DelimString ++ ConsIdArityString ++
         cord_list_to_cord(OtherConsIdArityStrings) ++ HeadGoalString ++
@@ -785,19 +784,20 @@
 
 label_case(ParentGoalId, !Case, !CaseNum, !Counter, !Map) :-
     !.Case = case_rep(MainConsId, OtherConsIds, Goal0),
-    label_goal_wrapper((func(N) = step_switch(N, no)), ParentGoalId,
-            Goal0, Goal, !CaseNum, !Counter, !Map),
+    label_goal_wrapper(
+        (func(N) = step_switch(N, unknown_num_functors_in_type)),
+        ParentGoalId, Goal0, Goal, !CaseNum, !Counter, !Map),
     !:Case = case_rep(MainConsId, OtherConsIds, Goal).
 
 %----------------------------------------------------------------------------%
 
 :- type inst_map
     --->    inst_map(
-                im_inst_map         :: map(var_rep, inst_rep),
                     % The actual inst map.
+                im_inst_map         :: map(var_rep, inst_rep),
 
-                im_var_dep_map      :: map(var_rep, set(var_rep))
                     % A tree describing dependencies between bound variables.
+                im_var_dep_map      :: map(var_rep, set(var_rep))
             ).
 
 initial_inst_map(ProcDefn) = InstMap :-
Index: deep_profiler/read_profile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/read_profile.m,v
retrieving revision 1.37
diff -u -b -r1.37 read_profile.m
--- deep_profiler/read_profile.m	6 May 2011 15:19:33 -0000	1.37
+++ deep_profiler/read_profile.m	19 Sep 2011 10:59:59 -0000
@@ -210,7 +210,7 @@
             array.init(MaxCSS + 1,
                 call_site_static(
                     make_dummy_psptr, -1,
-                    normal_call_and_callee(make_dummy_psptr, ""), -1, rgp([])
+                    normal_call_and_callee(make_dummy_psptr, ""), -1, rgp_nil
                 )),
             array.init(MaxPS + 1,
                 proc_static(dummy_proc_id, "", "", "", "", "", -1, no,
Index: deep_profiler/recursion_patterns.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/recursion_patterns.m,v
retrieving revision 1.16
diff -u -b -r1.16 recursion_patterns.m
--- deep_profiler/recursion_patterns.m	26 Jun 2011 16:56:41 -0000	1.16
+++ deep_profiler/recursion_patterns.m	19 Sep 2011 11:05:47 -0000
@@ -127,7 +127,7 @@
         foldl(build_dynamic_call_site_cost_and_callee_map(Deep),
             Slots, map.init, CallSitesMap),
         Info = recursion_analysis_info(ThisClique, CallSitesMap, CoverageArray),
-        goal_recursion_data(Info, [], Goal, RecursionData),
+        goal_recursion_data(Info, rgp_nil, Goal, RecursionData),
         recursion_data_to_recursion_type(ParentCalls, TotalCalls,
             RecursionData, RecursionType),
         MaybeRecursionType = ok(RecursionType)
@@ -293,10 +293,10 @@
     % that may eventually lead to Goal.
     %
 :- pred goal_recursion_data(recursion_analysis_info::in,
-    list(goal_path_step)::in, goal_rep(goal_id)::in, recursion_data::out)
+    reverse_goal_path::in, goal_rep(goal_id)::in, recursion_data::out)
     is det.
 
-goal_recursion_data(Info, RevGoalPathSteps, GoalRep, !:RecursionData) :-
+goal_recursion_data(Info, RevGoalPath, GoalRep, !:RecursionData) :-
     GoalRep = goal_rep(GoalExpr, Detism, GoalId),
     CoverageInfo = get_goal_attribute_det(Info ^ rai_coverage_info, GoalId),
     ( get_coverage_before(CoverageInfo, CallsPrime) ->
@@ -309,19 +309,19 @@
     ;
         (
             GoalExpr = conj_rep(Conjs),
-            conj_recursion_data(Info, RevGoalPathSteps, 1, Conjs,
+            conj_recursion_data(Info, RevGoalPath, 1, Conjs,
                 !:RecursionData)
         ;
             GoalExpr = disj_rep(Disjs),
-            disj_recursion_data(Info, RevGoalPathSteps, 1, Disjs,
+            disj_recursion_data(Info, RevGoalPath, 1, Disjs,
                 !:RecursionData)
         ;
             GoalExpr = switch_rep(_, _, Cases),
-            switch_recursion_data(Info, RevGoalPathSteps, 1, Cases,
+            switch_recursion_data(Info, RevGoalPath, 1, Cases,
                 float(Calls), Calls, !:RecursionData)
         ;
             GoalExpr = ite_rep(Cond, Then, Else),
-            ite_recursion_data(Info, RevGoalPathSteps, Cond, Then, Else,
+            ite_recursion_data(Info, RevGoalPath, Cond, Then, Else,
                 Calls, !:RecursionData)
         ;
             (
@@ -331,11 +331,11 @@
                 GoalExpr = scope_rep(SubGoal, MaybeCut),
                 GoalPathStep = step_scope(MaybeCut)
             ),
-            goal_recursion_data(Info, [GoalPathStep | RevGoalPathSteps],
+            goal_recursion_data(Info, rgp_cons(RevGoalPath, GoalPathStep),
                 SubGoal, !:RecursionData)
         ;
             GoalExpr = atomic_goal_rep(_, _, _, AtomicGoalRep),
-            atomic_goal_recursion_data(Info, RevGoalPathSteps, AtomicGoalRep,
+            atomic_goal_recursion_data(Info, RevGoalPath, AtomicGoalRep,
                 !:RecursionData)
         )
     ),
@@ -356,15 +356,15 @@
     ).
 
 :- pred conj_recursion_data(recursion_analysis_info::in,
-    list(goal_path_step)::in, int::in, list(goal_rep(goal_id))::in,
+    reverse_goal_path::in, int::in, list(goal_rep(goal_id))::in,
     recursion_data::out) is det.
 
 conj_recursion_data(_, _, _, [], simple_recursion_data(0.0, 0)).
-    % An empty conjunction is true, there is exactly one trivial path
-    % through it with 0 recursive calls.
-conj_recursion_data(Info, RevGoalPathSteps, ConjNum, [Conj | Conjs],
+    % An empty conjunction represents "true", so there is
+    % exactly one trivial path through it with 0 recursive calls.
+conj_recursion_data(Info, RevGoalPath, ConjNum, [Conj | Conjs],
         RecursionData) :-
-    goal_recursion_data(Info, [step_conj(ConjNum) | RevGoalPathSteps], Conj,
+    goal_recursion_data(Info, rgp_cons(RevGoalPath, step_conj(ConjNum)), Conj,
         ConjRecursionData),
     (
         ConjRecursionData = proc_dead_code,
@@ -375,7 +375,7 @@
     ;
         ConjRecursionData = recursion_data(_, _, _),
 
-        conj_recursion_data(Info, RevGoalPathSteps, ConjNum + 1, Conjs,
+        conj_recursion_data(Info, RevGoalPath, ConjNum + 1, Conjs,
             ConjsRecursionData0),
         CanFail = detism_get_can_fail(Conj ^ goal_detism_rep),
         (
@@ -405,15 +405,15 @@
     ).
 
 :- pred disj_recursion_data(recursion_analysis_info::in,
-    list(goal_path_step)::in, int::in, list(goal_rep(goal_id))::in,
+    reverse_goal_path::in, int::in, list(goal_rep(goal_id))::in,
     recursion_data::out) is det.
 
 disj_recursion_data(_, _, _, [], simple_recursion_data(0.0, 0)).
-disj_recursion_data(Info, RevGoalPathSteps, DisjNum,
-        [Disj | Disjs], RecursionData) :-
+disj_recursion_data(Info, RevGoalPath, DisjNum, [Disj | Disjs],
+        RecursionData) :-
     % Handle only semidet and committed-choice disjunctions, which cannot be
     % re-entered once a disjunct succeeds.
-    goal_recursion_data(Info, [step_disj(DisjNum) | RevGoalPathSteps], Disj,
+    goal_recursion_data(Info, rgp_cons(RevGoalPath, step_disj(DisjNum)), Disj,
         DisjRecursionData),
     (
         DisjRecursionData = proc_dead_code,
@@ -430,7 +430,7 @@
 
         % The code can branch here, either it tries the next disjuct, which we
         % represent as DisjsRecursionData, ...
-        disj_recursion_data(Info, RevGoalPathSteps, DisjNum + 1, Disjs,
+        disj_recursion_data(Info, RevGoalPath, DisjNum + 1, Disjs,
             DisjsRecursionData0),
         recursion_data_and_probability(DisjFailureProb, DisjsRecursionData0,
             DisjsRecursionData),
@@ -451,9 +451,7 @@
     is det.
 
 success_probability_from_coverage(Coverage, SuccessProb) :-
-    (
-        get_coverage_before_and_after(Coverage, Before, After)
-    ->
+    ( get_coverage_before_and_after(Coverage, Before, After) ->
         ( After > Before ->
             % Nondet code can overflow this probability.
             SuccessProb = certain
@@ -465,17 +463,17 @@
     ).
 
 :- pred ite_recursion_data(recursion_analysis_info::in,
-    list(goal_path_step)::in,
+    reverse_goal_path::in,
     goal_rep(goal_id)::in, goal_rep(goal_id)::in, goal_rep(goal_id)::in,
     int::in, recursion_data::out) is det.
 
-ite_recursion_data(Info, RevGoalPathSteps, Cond, Then, Else, Calls,
+ite_recursion_data(Info, RevGoalPath, Cond, Then, Else, Calls,
         !:RecursionData) :-
-    goal_recursion_data(Info, [step_ite_cond | RevGoalPathSteps], Cond,
+    goal_recursion_data(Info, rgp_cons(RevGoalPath, step_ite_cond), Cond,
         CondRecursionData),
-    goal_recursion_data(Info, [step_ite_then | RevGoalPathSteps], Then,
+    goal_recursion_data(Info, rgp_cons(RevGoalPath, step_ite_then), Then,
         ThenRecursionData0),
-    goal_recursion_data(Info, [step_ite_else | RevGoalPathSteps], Else,
+    goal_recursion_data(Info, rgp_cons(RevGoalPath, step_ite_else), Else,
         ElseRecursionData0),
 
     % Adjust the probabilities of executing the then and else branches.
@@ -503,7 +501,7 @@
     merge_recursion_data_sequence(CondRecursionData, !RecursionData).
 
 :- pred switch_recursion_data(recursion_analysis_info::in,
-    list(goal_path_step)::in, int::in, list(case_rep(goal_id))::in,
+    reverse_goal_path::in, int::in, list(case_rep(goal_id))::in,
     float::in, int::in, recursion_data::out) is det.
 
 switch_recursion_data(_, _, _, [], TotalCalls, CallsRemaining,
@@ -512,11 +510,12 @@
     FailProb = probable(float(CallsRemaining) / TotalCalls),
     RecursionData0 = simple_recursion_data(0.0, 0),
     recursion_data_and_probability(FailProb, RecursionData0, RecursionData).
-switch_recursion_data(Info, RevGoalPathSteps, CaseNum, [Case | Cases],
+switch_recursion_data(Info, RevGoalPath, CaseNum, [Case | Cases],
         TotalCalls, CallsRemaining, RecursionData) :-
     Case = case_rep(_, _, Goal),
-    goal_recursion_data(Info, [step_switch(CaseNum, no) | RevGoalPathSteps],
-        Goal, CaseRecursionData0),
+    RevArmPath = rgp_cons(RevGoalPath,
+        step_switch(CaseNum, unknown_num_functors_in_type)),
+    goal_recursion_data(Info, RevArmPath, Goal, CaseRecursionData0),
     CoverageInfo = get_goal_attribute_det(Info ^ rai_coverage_info,
         Goal ^ goal_annotation),
     ( get_coverage_before(CoverageInfo, CallsPrime) ->
@@ -527,16 +526,15 @@
     CaseProb = probable(float(Calls) / TotalCalls),
     recursion_data_and_probability(CaseProb, CaseRecursionData0,
         CaseRecursionData),
-    switch_recursion_data(Info, RevGoalPathSteps, CaseNum+1,
+    switch_recursion_data(Info, RevGoalPath, CaseNum+1,
         Cases, TotalCalls, CallsRemaining - Calls, CasesRecursionData),
     merge_recursion_data_after_branch(CaseRecursionData, CasesRecursionData,
         RecursionData).
 
 :- pred atomic_goal_recursion_data(recursion_analysis_info::in,
-    list(goal_path_step)::in, atomic_goal_rep::in, recursion_data::out) is det.
+    reverse_goal_path::in, atomic_goal_rep::in, recursion_data::out) is det.
 
-atomic_goal_recursion_data(Info, RevGoalPathSteps, AtomicGoal, RecursionData)
-        :-
+atomic_goal_recursion_data(Info, RevGoalPath, AtomicGoal, RecursionData) :-
     (
         % All these things have trivial cost except for foreign code whose cost
         % is unknown (which because it doesn't contribute to the cost of the
@@ -561,7 +559,7 @@
 
         % Get the cost of the call.
         Info = recursion_analysis_info(ThisClique, CallSiteMap, _),
-        map.lookup(CallSiteMap, rgp(RevGoalPathSteps), CostAndCallees),
+        map.lookup(CallSiteMap, RevGoalPath, CostAndCallees),
         ( cost_and_callees_is_recursive(ThisClique, CostAndCallees) ->
             % Cost will be 1.0 for for each call to recursive calls but we
             % calculate this later.
Index: deep_profiler/var_use_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/var_use_analysis.m,v
retrieving revision 1.16
diff -u -b -r1.16 var_use_analysis.m
--- deep_profiler/var_use_analysis.m	6 May 2011 05:03:28 -0000	1.16
+++ deep_profiler/var_use_analysis.m	19 Sep 2011 11:26:52 -0000
@@ -259,7 +259,8 @@
                 VarUseInfo),
             MaybeVarUseInfo = ok(VarUseInfo)
         ; member(CalleePDPtr, CallStack0) ->
-            % Return a first use time of 1.0, this is used by the formula below.
+            % Return a first use time of 1.0. This is used by the formula
+            % below.
             MaybeVarUseInfo = ok(var_use_info(1.0, Cost,
                 VarUseOptions ^ vuo_var_use_type))
         ;
@@ -296,14 +297,14 @@
                     ; RecursionType = rt_errors(_)
                     ),
                     MaybeVarUseInfo = error(
-                        "Cannot compute var use on a recursive call site for an"
-                        ++ " unknown recursion type")
+                        "Cannot compute var use on a recursive call site "
+                        ++ "for an unknown recursion type")
                 )
             ;
                 MaybeDepth = no,
                 MaybeVarUseInfo = error(
-                    "Cannot compute var use on a recursive call site for an"
-                    ++ " unknown recursion depth")
+                    "Cannot compute var use on a recursive call site "
+                    ++ "for an unknown recursion depth")
             )
         )
     ).
@@ -412,7 +413,8 @@
     maybe_error(var_use_info)::out) is det.
 
 proc_dynamic_recursive_var_use_info(CliquePtr, PDPtr, ArgNum,
-        RecursionType, Depth, _Cost, CallStack, VarUseOptions, MaybeVarUseInfo) :-
+        RecursionType, Depth, _Cost, CallStack, VarUseOptions,
+        MaybeVarUseInfo) :-
     prepare_for_proc_var_first_use(CliquePtr, PDPtr, ArgNum, RecursionType,
         Depth, VarUseOptions, Info),
     (
@@ -667,12 +669,11 @@
     % follow call the calls seen during profiling and aggregate their variable
     % use information based on how often they are called from that call site.
     %
-:- pred goal_var_first_use(list(goal_path_step)::in, goal_rep(goal_id)::in,
+:- pred goal_var_first_use(reverse_goal_path::in, goal_rep(goal_id)::in,
     var_first_use_static_info::in(var_first_use_static_info), float::in,
     float::out, found_first_use::out) is det.
 
-goal_var_first_use(RevGoalPathSteps, Goal, StaticInfo, !CostSoFar,
-        FoundFirstUse) :-
+goal_var_first_use(RevGoalPath, Goal, StaticInfo, !CostSoFar, FoundFirstUse) :-
     Goal = goal_rep(GoalExpr, Detism, _),
     CoverageArray = StaticInfo ^ fui_coverage_array,
     Coverage = get_goal_attribute_det(CoverageArray, Goal ^ goal_annotation),
@@ -697,19 +698,19 @@
     ;
         (
             GoalExpr = conj_rep(Conjuncts),
-            conj_var_first_use(RevGoalPathSteps, 1, Conjuncts, StaticInfo,
+            conj_var_first_use(RevGoalPath, 1, Conjuncts, StaticInfo,
                 !CostSoFar, FoundFirstUse)
         ;
             GoalExpr = disj_rep(Disjuncts),
-            disj_var_first_use(RevGoalPathSteps, Disjuncts, Detism, StaticInfo,
+            disj_var_first_use(RevGoalPath, Disjuncts, Detism, StaticInfo,
                 !CostSoFar, FoundFirstUse)
         ;
             GoalExpr = switch_rep(SwitchedOnVar, _CanFail, Cases),
-            switch_var_first_use(RevGoalPathSteps, SwitchedOnVar, Cases,
+            switch_var_first_use(RevGoalPath, SwitchedOnVar, Cases,
                 StaticInfo, !CostSoFar, FoundFirstUse)
         ;
             GoalExpr = ite_rep(Cond, Then, Else),
-            ite_var_first_use(RevGoalPathSteps, Cond, Then, Else, StaticInfo,
+            ite_var_first_use(RevGoalPath, Cond, Then, Else, StaticInfo,
                 !CostSoFar, FoundFirstUse)
         ;
             (
@@ -719,8 +720,8 @@
                 GoalExpr = scope_rep(SubGoal, ScopeIsCut),
                 GoalPathStep = step_scope(ScopeIsCut)
             ),
-            RevSubGoalPathSteps = [GoalPathStep | RevGoalPathSteps],
-            goal_var_first_use(RevSubGoalPathSteps, SubGoal, StaticInfo,
+            RevSubGoalPath = rgp_cons(RevGoalPath, GoalPathStep),
+            goal_var_first_use(RevSubGoalPath, SubGoal, StaticInfo,
                 !CostSoFar, FoundFirstUse)
         ;
             GoalExpr = atomic_goal_rep(_, _, BoundVars, AtomicGoal),
@@ -729,7 +730,7 @@
                 ; AtomicGoal = higher_order_call_rep(_, _)
                 ; AtomicGoal = method_call_rep(_, _, _)
                 ),
-                call_var_first_use(AtomicGoal, BoundVars, rgp(RevGoalPathSteps),
+                call_var_first_use(AtomicGoal, BoundVars, RevGoalPath,
                     StaticInfo, FoundFirstUse, !CostSoFar)
             ;
                 ( AtomicGoal = unify_construct_rep(_, _, _)
@@ -751,7 +752,7 @@
     ),
     trace [compile_time(flag("debug_first_var_use")), io(!IO)] (
         io.format("Trace: goal_var_first_use: %s\n",
-            [s(rev_goal_path_to_string(rgp(RevGoalPathSteps)))], !IO)
+            [s(rev_goal_path_to_string(RevGoalPath))], !IO)
     ).
 
 :- inst atomic_goal_rep_call
@@ -786,7 +787,7 @@
     ),
     !:CostSoFar = !.CostSoFar + Cost,
 
-    % Determine if the variable we're searching for uses of is involved with
+    % Determine if the variable we are searching for uses of is involved with
     % this call.
     (
         AtomicGoal = plain_call_rep(_, _, Args),
@@ -952,45 +953,47 @@
     % time from the end of the goal. Similarly with other goal types that have
     % an execution order, namely disjunctions and if-then-elses.
     %
-:- pred conj_var_first_use(list(goal_path_step)::in, int::in,
+:- pred conj_var_first_use(reverse_goal_path::in, int::in,
     list(goal_rep(goal_id))::in,
     var_first_use_static_info::in(var_first_use_static_info),
     float::in, float::out, found_first_use::out) is det.
 
 conj_var_first_use(_, _, [], _, !Cost, have_not_found_first_use).
-conj_var_first_use(RevGoalPathSteps, ConjNum, [Conj | Conjs], StaticInfo,
+conj_var_first_use(RevGoalPath, ConjNum, [Conj | Conjs], StaticInfo,
         !CostSoFar, FoundFirstUse) :-
-    goal_var_first_use([step_conj(ConjNum) | RevGoalPathSteps], Conj,
+    goal_var_first_use(rgp_cons(RevGoalPath, step_conj(ConjNum)), Conj,
         StaticInfo, !CostSoFar, HeadFoundFirstUse),
     (
-        % XXX: if a variable is bound more than once, because it's used with
-        % partial instantiation then we want to use the last time it is bound.
-        % Instmaps can be used to track this. This is relevant when searching
-        % for the producer of a variable.
+        % If a variable is bound more than once, then we want to use
+        % the last time it is bound, since all of the earlier bindings
+        % must have only partially instantiated it. Instmaps can be used
+        % to track this. This is relevant when searching for the producer
+        % of a variable.
+        % XXX: For now, we assume that no variable is bound more than once.
         HeadFoundFirstUse = found_first_use(_),
         FoundFirstUse = HeadFoundFirstUse
     ;
         HeadFoundFirstUse = have_not_found_first_use,
-        conj_var_first_use(RevGoalPathSteps, ConjNum + 1, Conjs, StaticInfo,
+        conj_var_first_use(RevGoalPath, ConjNum + 1, Conjs, StaticInfo,
             !CostSoFar, TailFoundFirstUse),
         FoundFirstUse = TailFoundFirstUse
     ).
 
-:- pred disj_var_first_use(list(goal_path_step)::in,
+:- pred disj_var_first_use(reverse_goal_path::in,
     list(goal_rep(goal_id))::in, detism_rep::in,
     var_first_use_static_info::in(var_first_use_static_info),
     float::in, float::out, found_first_use::out) is det.
 
-disj_var_first_use(RevGoalPathSteps, Disjuncts, Detism, StaticInfo,
+disj_var_first_use(RevGoalPath, Disjuncts, Detism, StaticInfo,
         !CostSoFar, FoundFirstUse) :-
     % We cannot handle nondet/multi disjunctions. So we use pessimistic
     % defaults for FoundFirstUse if this disjunction is nondet or multi.
     % For calculating the cost of the disjunction, assume that is is a semidet
     % disjunction. Doing this will find the incorrect cost for the
-    % disjunction, however disjunctions occur rarely, this is not likely to
-    % drametically effect anything.
+    % disjunction. However disjunctions occur rarely, so this is not likely
+    % to dramatically affect anything.
     CostBeforeDisjunction = !.CostSoFar,
-    disj_var_first_use_2(RevGoalPathSteps, 1, Disjuncts, StaticInfo,
+    disj_var_first_use_2(RevGoalPath, 1, Disjuncts, StaticInfo,
         !CostSoFar, FoundFirstUse0),
     CostAfterDisjunction = !.CostSoFar,
     (
@@ -1011,19 +1014,19 @@
         FoundFirstUse = FoundFirstUse0
     ).
 
-:- pred disj_var_first_use_2(list(goal_path_step)::in, int::in,
+:- pred disj_var_first_use_2(reverse_goal_path::in, int::in,
     list(goal_rep(goal_id))::in,
     var_first_use_static_info::in(var_first_use_static_info),
     float::in, float::out, found_first_use::out) is det.
 
 disj_var_first_use_2(_, _, [], _, !CostSoFar, have_not_found_first_use).
-disj_var_first_use_2(RevGoalPathSteps, DisjNum, [Disj | Disjs], StaticInfo,
+disj_var_first_use_2(RevGoalPath, DisjNum, [Disj | Disjs], StaticInfo,
         !CostSoFar, FoundFirstUse) :-
     VarUseType = StaticInfo ^ fui_var_use_opts ^ vuo_var_use_type,
     CoverageArray = StaticInfo ^ fui_coverage_array,
-    goal_var_first_use([step_disj(DisjNum) | RevGoalPathSteps], Disj,
+    goal_var_first_use(rgp_cons(RevGoalPath, step_disj(DisjNum)), Disj,
         StaticInfo, !CostSoFar, HeadFoundFirstUse),
-    disj_var_first_use_2(RevGoalPathSteps, DisjNum + 1, Disjs, StaticInfo,
+    disj_var_first_use_2(RevGoalPath, DisjNum + 1, Disjs, StaticInfo,
         !CostSoFar, TailFoundFirstUse),
     (
         HeadFoundFirstUse = have_not_found_first_use,
@@ -1042,15 +1045,15 @@
         TailFoundFirstUse = found_first_use(TailCost),
         (
             VarUseType = var_use_consumption,
-            % The variable is probably consumed in the first disjunct even if
-            % it fails. This is also the pessimistic default.
+            % The variable is probably consumed in the first disjunct
+            % even if it fails. This is also the pessimistic default.
             Cost = HeadCost
         ;
             ( VarUseType = var_use_production
             ; VarUseType = var_use_other
             ),
-            % Use a weighted average to reflect the likely success of the first
-            % disjunct.
+            % Use a weighted average to reflect the likely success
+            % of the first disjunct.
             DisjCoverage =
                 get_goal_attribute_det(CoverageArray, Disj ^ goal_annotation),
             ( get_coverage_before(DisjCoverage, HeadCount) ->
@@ -1079,14 +1082,14 @@
         FoundFirstUse = found_first_use(Cost)
     ).
 
-:- pred switch_var_first_use(list(goal_path_step)::in, var_rep::in,
+:- pred switch_var_first_use(reverse_goal_path::in, var_rep::in,
     list(case_rep(goal_id))::in,
     var_first_use_static_info::in(var_first_use_static_info),
     float::in, float::out, found_first_use::out) is det.
 
-switch_var_first_use(RevGoalPathSteps, SwitchedOnVar, Cases, StaticInfo,
+switch_var_first_use(RevGoalPath, SwitchedOnVar, Cases, StaticInfo,
         CostBeforeSwitch, CostAfterSwitch, FoundFirstUse) :-
-    switch_var_first_use_2(RevGoalPathSteps, 1, StaticInfo, Cases, CaseWeights,
+    switch_var_first_use_2(RevGoalPath, 1, StaticInfo, Cases, CaseWeights,
         CostBeforeSwitch, CostCases, FoundFirstUseCases),
     weighted_average(CaseWeights, CostCases, CostAfterSwitch),
     Var = StaticInfo ^ fui_var,
@@ -1115,32 +1118,34 @@
         )
     ).
 
-:- pred switch_var_first_use_2(list(goal_path_step)::in, int::in,
+:- pred switch_var_first_use_2(reverse_goal_path::in, int::in,
     var_first_use_static_info::in(var_first_use_static_info),
     list(case_rep(goal_id))::in, list(float)::out, float::in,
     list(float)::out, list(found_first_use)::out) is det.
 
 switch_var_first_use_2(_, _, _, [], [], _, [], []).
-switch_var_first_use_2(RevGoalPathSteps, CaseNum, StaticInfo, [Case | Cases],
+switch_var_first_use_2(RevGoalPath, CaseNum, StaticInfo, [Case | Cases],
         [Weight | Weights], Cost0, [Cost | Costs],
         [FoundFirstUse | FoundFirstUses]) :-
-    switch_var_first_use_2(RevGoalPathSteps, CaseNum + 1, StaticInfo,
+    switch_var_first_use_2(RevGoalPath, CaseNum + 1, StaticInfo,
         Cases, Weights, Cost0, Costs, FoundFirstUses),
     Case = case_rep(_, _, Goal),
-    goal_var_first_use([step_switch(CaseNum, no) | RevGoalPathSteps],
-        Goal, StaticInfo, Cost0, Cost, FoundFirstUse),
+    RevArmPath = rgp_cons(RevGoalPath,
+        step_switch(CaseNum, unknown_num_functors_in_type)),
+    goal_var_first_use(RevArmPath, Goal, StaticInfo, Cost0, Cost,
+        FoundFirstUse),
     Coverage = get_goal_attribute_det(StaticInfo ^ fui_coverage_array,
         Goal ^ goal_annotation),
     get_coverage_before_det(Coverage, BeforeCount),
     Weight = float(BeforeCount).
 
-:- pred ite_var_first_use(list(goal_path_step)::in,
+:- pred ite_var_first_use(reverse_goal_path::in,
     goal_rep(goal_id)::in, goal_rep(goal_id)::in, goal_rep(goal_id)::in,
     var_first_use_static_info::in(var_first_use_static_info),
     float::in, float::out, found_first_use::out)
     is det.
 
-ite_var_first_use(RevGoalPathSteps, Cond, Then, Else, StaticInfo,
+ite_var_first_use(RevGoalPath, Cond, Then, Else, StaticInfo,
         !CostSoFar, FoundFirstUse) :-
     CoverageArray = StaticInfo ^ fui_coverage_array,
     ThenCoverage =
@@ -1150,16 +1155,16 @@
         get_goal_attribute_det(CoverageArray, Else ^ goal_annotation),
     get_coverage_before_det(ElseCoverage, CountBeforeElse),
     Weights = [float(CountBeforeThen), float(CountBeforeElse)],
-    RevCondGoalPathSteps = [step_ite_cond | RevGoalPathSteps],
-    RevThenGoalPathSteps = [step_ite_then | RevGoalPathSteps],
-    RevElseGoalPathSteps = [step_ite_else | RevGoalPathSteps],
+    RevCondGoalPath = rgp_cons(RevGoalPath, step_ite_cond),
+    RevThenGoalPath = rgp_cons(RevGoalPath, step_ite_then),
+    RevElseGoalPath = rgp_cons(RevGoalPath, step_ite_else),
     VarUseType = StaticInfo ^ fui_var_use_opts ^ vuo_var_use_type,
     CostBeforeITE = !.CostSoFar,
-    goal_var_first_use(RevCondGoalPathSteps, Cond, StaticInfo,
+    goal_var_first_use(RevCondGoalPath, Cond, StaticInfo,
         CostBeforeITE, CostAfterCond, CondFoundFirstUse),
-    goal_var_first_use(RevThenGoalPathSteps, Then, StaticInfo,
+    goal_var_first_use(RevThenGoalPath, Then, StaticInfo,
         CostAfterCond, CostAfterThen, ThenFoundFirstUse),
-    goal_var_first_use(RevElseGoalPathSteps, Else, StaticInfo,
+    goal_var_first_use(RevElseGoalPath, Else, StaticInfo,
         CostAfterCond, CostAfterElse, ElseFoundFirstUse),
     weighted_average(Weights, [CostAfterThen, CostAfterElse], CostAfterITE),
     !:CostSoFar = CostAfterITE,
@@ -1211,7 +1216,7 @@
 %
 
 :- type recursive_calls_list ==
-    assoc_list(list(goal_path_step), float).
+    assoc_list(forward_goal_path, float).
 
 :- pred build_recursive_call_sites_list(
     map(reverse_goal_path, cs_cost_csq)::in,
@@ -1220,10 +1225,9 @@
 build_recursive_call_sites_list(Map, List) :-
     List0 = to_assoc_list(Map),
     list.map(
-        (pred((RevGoalPath - Cost)::in, (GoalPathSteps - Calls)::out) is det :-
+        (pred((RevGoalPath - Cost)::in, (GoalPath - Calls)::out) is det :-
             Calls = cs_cost_get_calls(Cost),
-            RevGoalPath = rgp(RevGoalPathSteps),
-            reverse(GoalPathSteps, RevGoalPathSteps)
+            rgp_to_fgp(RevGoalPath, GoalPath)
         ), List0, List).
 
 :- pred filter_recursive_call_sites(goal_path_step::in,
@@ -1231,7 +1235,7 @@
 
 filter_recursive_call_sites(GoalPathStep, !RecCallSites) :-
     filter_map((pred((GP0 - Coverage)::in, (GP - Coverage)::out) is semidet :-
-            GP0 = [GoalPathStep | GP]
+            GP0 = fgp_cons(GoalPathStep, GP)
         ), !RecCallSites).
 
     % rec_goal_var_first_use(Goal, RecCalls, Info, FoundFirstUse, !CostSoFar).
@@ -1408,8 +1412,8 @@
     found_first_use::out, float::in, float::out) is det.
 
 rec_disj_var_first_use_2([], _, _, _, have_not_found_first_use, !CostSoFar).
-rec_disj_var_first_use_2([Disj | Disjs], DisjNum, RecCalls, Info, FoundFirstUse,
-        !CostSoFar) :-
+rec_disj_var_first_use_2([Disj | Disjs], DisjNum, RecCalls, Info,
+        FoundFirstUse, !CostSoFar) :-
     filter_recursive_call_sites(step_disj(DisjNum), RecCalls, DisjRecCalls),
     rec_goal_var_first_use(Disj, DisjRecCalls, Info, DisjFoundFirstUse,
         !CostSoFar),
@@ -1494,8 +1498,9 @@
         CasesRecProbs),
     Goal = Case ^ cr_case_goal,
     GoalId = Goal ^ goal_annotation,
-    filter_recursive_call_sites(step_switch(CaseNum, no), RecCalls,
-        CaseRecCalls),
+    filter_recursive_call_sites(
+        step_switch(CaseNum, unknown_num_functors_in_type),
+        RecCalls, CaseRecCalls),
     rec_goal_var_first_use(Goal, CaseRecCalls, Info, FoundFirstUse,
         CostBeforeSwitch, CaseCostAfter),
     Coverage = get_goal_attribute_det(Info ^ fui_coverage_array, GoalId),
@@ -1666,7 +1671,8 @@
         SuccessProb = probable(float(After) / float(Before)),
         ConjsProb = and(SuccessProb, ConjsProb0),
 
-        filter_recursive_call_sites(step_conj(ConjNum), RecCalls, ConjRecCalls),
+        filter_recursive_call_sites(step_conj(ConjNum),
+            RecCalls, ConjRecCalls),
         goal_rec_prob(Conj, ConjRecCalls, Info, ConjProb, !ProbArray),
         Prob = or(ConjProb, ConjsProb)
     ).
@@ -1691,7 +1697,8 @@
         FailureProb = probable(float(Before - After) / float(Before)),
         DisjsProb = and(FailureProb, DisjsProb0),
 
-        filter_recursive_call_sites(step_disj(DisjNum), RecCalls, DisjRecCalls),
+        filter_recursive_call_sites(step_disj(DisjNum),
+            RecCalls, DisjRecCalls),
         goal_rec_prob(Disj, DisjRecCalls, Info, DisjProb, !ProbArray),
         Prob = or(DisjProb, DisjsProb)
     ).
@@ -1720,8 +1727,9 @@
         Probs0, Weights0, !ProbArray),
 
     Case = case_rep(_, _, Goal),
-    filter_recursive_call_sites(step_switch(CaseNum, no), RecCalls,
-        CaseRecCalls),
+    filter_recursive_call_sites(
+        step_switch(CaseNum, unknown_num_functors_in_type),
+        RecCalls, CaseRecCalls),
     goal_rec_prob(Goal, CaseRecCalls, Info, Prob, !ProbArray),
     Goal = goal_rep(_, _, GoalId),
     Coverage = get_goal_attribute_det(Info ^ fui_coverage_array, GoalId),
@@ -1767,7 +1775,7 @@
 goal_var_first_use_wrapper(CliquePtr, CallStack, ContainingGoalMap,
         CoverageArray, CallSiteMap, RecursiveCallSiteMap, RT, CurDepth, Goal,
         ProcCost, Var, VarUseOptions, VarUseInfo) :-
-    goal_var_first_use([], Goal,
+    goal_var_first_use(rgp_nil, Goal,
         var_first_use_static_info(CliquePtr, CallSiteMap, RecursiveCallSiteMap,
             ContainingGoalMap, CoverageArray, Var, VarUseOptions, CallStack,
             RT, CurDepth, no_recursion_info),
@@ -1779,8 +1787,7 @@
 var_first_use(CliquePtr, CallSiteMap, RecursiveCallSiteMap, ContainingGoalMap,
         CoverageArray, RT, CurDepth, Goal, RevGoalPath, Cost, Var,
         VarUseOptions, VarUseInfo) :-
-    RevGoalPath = rgp(RevGoalPathSteps),
-    goal_var_first_use(RevGoalPathSteps, Goal,
+    goal_var_first_use(RevGoalPath, Goal,
         var_first_use_static_info(CliquePtr, CallSiteMap, RecursiveCallSiteMap,
             ContainingGoalMap, CoverageArray, Var, VarUseOptions, set.init, RT,
             CurDepth, no_recursion_info),
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/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/list.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.202
diff -u -b -r1.202 list.m
--- library/list.m	10 May 2011 04:12:28 -0000	1.202
+++ library/list.m	19 Sep 2011 08:09:53 -0000
@@ -2313,8 +2313,8 @@
         AllButLast = [],
         Last = H
     ;
-        T = [_ | _],
-        list.split_last(T, AllButLastTail, Last),
+        T = [TH | TT],
+        list.split_last_det_2(TH, TT, AllButLastTail, Last),
         AllButLast = [H | AllButLastTail]
     ).
 
cvs diff: Diffing mdbcomp
Index: mdbcomp/feedback.automatic_parallelism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/feedback.automatic_parallelism.m,v
retrieving revision 1.17
diff -u -b -r1.17 feedback.automatic_parallelism.m
--- mdbcomp/feedback.automatic_parallelism.m	3 May 2011 04:35:01 -0000	1.17
+++ mdbcomp/feedback.automatic_parallelism.m	19 Sep 2011 10:12:51 -0000
@@ -164,15 +164,15 @@
     % This is where a goal may be pushed into the arms of a branching goal that
     % occurs before it in the same conjunction.  It can allow the pushed goal
     % to be parallelised against goals in one or more branches without
-    % parallelising the whole branch goal (whose per-call cost may be two
-    % small).
+    % parallelising the whole branch goal (whose per-call cost may be
+    % too small).
     %
 :- type push_goal
     --->    push_goal(
                 % The goal path of the conjunction in which the push is done.
                 pg_goal_path    :: goal_path_string,
 
-                % The range of conjuncts to push, (inclusive)
+                % The range of conjuncts to push (inclusive).
                 pg_pushee_lo    :: int,
                 pg_pushee_hi    :: int,
 
Index: mdbcomp/mdbcomp.goal_path.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/mdbcomp.goal_path.m,v
retrieving revision 1.6
diff -u -b -r1.6 mdbcomp.goal_path.m
--- mdbcomp/mdbcomp.goal_path.m	3 May 2011 04:35:01 -0000	1.6
+++ mdbcomp/mdbcomp.goal_path.m	19 Sep 2011 09:49:16 -0000
@@ -54,7 +54,6 @@
 :- import_module array.
 :- import_module bimap.
 :- import_module char.
-:- import_module list.
 :- import_module map.
 :- import_module maybe.
 
@@ -66,17 +65,19 @@
 :- pred is_valid_goal_id(goal_id::in) is semidet.
 
 :- type forward_goal_path
-    --->    fgp(list(goal_path_step)).
+    --->    fgp_nil
+    ;       fgp_cons(goal_path_step, forward_goal_path).
 
 :- type reverse_goal_path
-    --->    rgp(list(goal_path_step)).
+    --->    rgp_nil
+    ;       rgp_cons(reverse_goal_path, goal_path_step).
 
 :- type goal_path_string == string.
 
 :- type goal_path_step
     --->    step_conj(int)
     ;       step_disj(int)
-    ;       step_switch(int, maybe(int))
+    ;       step_switch(int, maybe_switch_num_functors)
     ;       step_ite_cond
     ;       step_ite_then
     ;       step_ite_else
@@ -87,6 +88,12 @@
     ;       step_atomic_main
     ;       step_atomic_orelse(int).
 
+    % The number of functors in the type of the switched-on variable, if known.
+    %
+:- type maybe_switch_num_functors
+    --->    unknown_num_functors_in_type
+    ;       known_num_functors_in_type(int).
+
     % Does the scope goal have a different determinism inside than outside?
 :- type maybe_cut
     --->    scope_is_cut
@@ -169,6 +176,11 @@
     %
 :- pred is_goal_path_separator(char::in) is semidet.
 
+    % Convert one kind of goal path into the other.
+    %
+:- pred rgp_to_fgp(reverse_goal_path::in, forward_goal_path::out) is det.
+:- pred fgp_to_rgp(forward_goal_path::in, reverse_goal_path::out) is det.
+
     % goal_path_inside(PathA, PathB):
     %
     % Succeed if PathB denotes a goal *inside* the goal denoted by PathA.
@@ -301,6 +313,7 @@
 :- import_module assoc_list.
 :- import_module cord.
 :- import_module int.
+:- import_module list.
 :- import_module pair.
 :- import_module require.
 :- import_module string.
@@ -310,43 +323,57 @@
 
 whole_body_goal_id = goal_id(0).
 
-goal_path_add_at_end(GoalPath0, GoalPathStep) = GoalPath :-
-    GoalPath0 = fgp(Steps0),
-    Steps = Steps0 ++ [GoalPathStep],
-    GoalPath = fgp(Steps).
-
-rev_goal_path_add_at_end(GoalPath0, GoalPathStep) = GoalPath :-
-    GoalPath0 = rgp(Steps0),
-    Steps = [GoalPathStep | Steps0],
-    GoalPath = rgp(Steps).
-
-goal_path_remove_last(GoalPath0, GoalPath, LastStep) :-
-    GoalPath0 = fgp(Steps0),
-    list.split_last(Steps0, Steps, LastStep),
-    GoalPath = fgp(Steps).
-
-goal_path_get_last(GoalPath, LastStep) :-
-    goal_path_remove_last(GoalPath, _, LastStep).
-
-rev_goal_path_remove_last(GoalPath0, GoalPath, LastStep) :-
-    GoalPath0 = rgp(Steps0),
-    Steps0 = [LastStep | Steps],
-    GoalPath = rgp(Steps).
-
-rev_goal_path_get_last(GoalPath, LastStep) :-
-    rev_goal_path_remove_last(GoalPath, _, LastStep).
-
-goal_path_inside_relative(PathA, PathB, RelativePath) :-
-    PathA = fgp(StepsA),
-    PathB = fgp(StepsB),
-    list.append(StepsA, RelativeSteps, StepsB),
-    RelativePath = fgp(RelativeSteps).
-
-rev_goal_path_inside_relative(RevPathA, RevPathB, RevRelative) :-
-    RevPathA = rgp(RevStepsA),
-    RevPathB = rgp(RevStepsB),
-    list.remove_suffix(RevStepsB, RevStepsA, RevRelativeSteps),
-    RevRelative = rgp(RevRelativeSteps).
+goal_path_add_at_end(fgp_nil, NewStep) = fgp_cons(NewStep, fgp_nil).
+goal_path_add_at_end(fgp_cons(OldStep, GoalPath0), NewStep) =
+        fgp_cons(OldStep, GoalPath) :-
+    GoalPath = goal_path_add_at_end(GoalPath0, NewStep).
+
+rev_goal_path_add_at_end(GoalPath0, NewStep) = GoalPath :-
+    GoalPath = rgp_cons(GoalPath0, NewStep).
+
+goal_path_remove_last(fgp_cons(HeadStep, TailSteps),
+        AllButLastGoalPath, LastStep) :-
+    goal_path_remove_last_loop(HeadStep, TailSteps,
+        AllButLastGoalPath, LastStep).
+
+:- pred goal_path_remove_last_loop(goal_path_step::in, forward_goal_path::in,
+    forward_goal_path::out, goal_path_step::out) is det.
+
+goal_path_remove_last_loop(Head, fgp_nil, fgp_nil, Head).
+goal_path_remove_last_loop(Head, fgp_cons(TailHead, TailTail),
+        AllButLastGoalPath, LastStep) :-
+    goal_path_remove_last_loop(TailHead, TailTail,
+        AllButLastGoalPath0, LastStep),
+    AllButLastGoalPath = fgp_cons(Head, AllButLastGoalPath0).
+
+goal_path_get_last(fgp_cons(HeadStep, TailSteps), LastStep) :-
+    goal_path_last_loop(HeadStep, TailSteps, LastStep).
+
+:- pred goal_path_last_loop(goal_path_step::in, forward_goal_path::in,
+    goal_path_step::out) is det.
+
+goal_path_last_loop(Head, fgp_nil, Head).
+goal_path_last_loop(_Head, fgp_cons(TailHead, TailTail), LastStep) :-
+    goal_path_last_loop(TailHead, TailTail, LastStep).
+
+rev_goal_path_remove_last(rgp_cons(GoalPath, LastStep), GoalPath, LastStep).
+
+rev_goal_path_get_last(rgp_cons(_, LastStep), LastStep).
+
+goal_path_inside_relative(fgp_nil, PathB, PathB).
+goal_path_inside_relative(fgp_cons(StepA, PathA), fgp_cons(StepB, PathB),
+        RelativePath) :-
+    StepA = StepB,
+    goal_path_inside_relative(PathA, PathB, RelativePath).
+
+rev_goal_path_inside_relative(RevPathA, RevPathB, RevRelativePath) :-
+    % XXX It would be more efficient if we could do this test
+    % without having to translate twice the part of RevPathB that
+    % goal_path_inside_relative returns but does not test.
+    rgp_to_fgp(RevPathA, PathA),
+    rgp_to_fgp(RevPathB, PathB),
+    goal_path_inside_relative(PathA, PathB, RelativePath),
+    fgp_to_rgp(RelativePath, RevRelativePath).
 
 goal_path_inside(PathA, PathB) :-
     goal_path_inside_relative(PathA, PathB, _).
@@ -356,8 +383,15 @@
 
 goal_path_from_string(GoalPathStr, GoalPath) :-
     StepStrs = string.words_separator(is_goal_path_separator, GoalPathStr),
-    list.map(goal_path_step_from_string, StepStrs, Steps),
-    GoalPath = fgp(Steps).
+    goal_path_from_strings(StepStrs, GoalPath).
+
+:- pred goal_path_from_strings(list(string)::in, forward_goal_path::out)
+    is semidet.
+
+goal_path_from_strings([], fgp_nil).
+goal_path_from_strings([Str | Strs], fgp_cons(HeadStep, LaterSteps)) :-
+    goal_path_step_from_string(Str, HeadStep),
+    goal_path_from_strings(Strs, LaterSteps).
 
 goal_path_from_string_det(GoalPathStr, GoalPath) :-
     ( goal_path_from_string(GoalPathStr, GoalPathPrime) ->
@@ -368,9 +402,16 @@
 
 rev_goal_path_from_string(GoalPathStr, GoalPath) :-
     StepStrs = string.words_separator(is_goal_path_separator, GoalPathStr),
-    list.map(goal_path_step_from_string, StepStrs, Steps),
-    list.reverse(Steps, RevSteps),
-    GoalPath = rgp(RevSteps).
+    list.reverse(StepStrs, RevStepStrs),
+    rev_goal_path_from_rev_strings(RevStepStrs, GoalPath).
+
+:- pred rev_goal_path_from_rev_strings(list(string)::in,
+    reverse_goal_path::out) is semidet.
+
+rev_goal_path_from_rev_strings([], rgp_nil).
+rev_goal_path_from_rev_strings([Str | Strs], rgp_cons(HeadSteps, TailStep)) :-
+    rev_goal_path_from_rev_strings(Strs, HeadSteps),
+    goal_path_step_from_string(Str, TailStep).
 
 rev_goal_path_from_string_det(GoalPathStr, GoalPath) :-
     ( rev_goal_path_from_string(GoalPathStr, GoalPathPrime) ->
@@ -395,10 +436,10 @@
     string.to_int(NStr, N),
     % "na" is short for "not applicable"
     ( MStr = "na" ->
-        MaybeM = no
+        MaybeM = unknown_num_functors_in_type
     ;
         string.to_int(MStr, M),
-        MaybeM = yes(M)
+        MaybeM = known_num_functors_in_type(M)
     ).
 goal_path_step_from_string_2('?', "", step_ite_cond).
 goal_path_step_from_string_2('t', "", step_ite_then).
@@ -415,24 +456,36 @@
 is_goal_path_separator(';').
 
 goal_path_to_string(GoalPath) = GoalPathStr :-
-    GoalPath = fgp(Steps),
-    StepStrs = list.map(goal_path_step_to_string, Steps),
+    StepStrs = goal_path_to_strings(GoalPath),
     string.append_list(StepStrs, GoalPathStr).
 
+:- func goal_path_to_strings(forward_goal_path) = list(string).
+
+goal_path_to_strings(fgp_nil) = [].
+goal_path_to_strings(fgp_cons(Step, Steps)) = [Str | Strs] :-
+    Str = goal_path_step_to_string(Step),
+    Strs = goal_path_to_strings(Steps).
+
 rev_goal_path_to_string(GoalPath) = GoalPathStr :-
-    GoalPath = rgp(RevSteps),
-    list.reverse(RevSteps, Steps),
-    StepStrs = list.map(goal_path_step_to_string, Steps),
+    RevStepStrs = rev_goal_path_to_strings(GoalPath),
+    list.reverse(RevStepStrs, StepStrs),
     string.append_list(StepStrs, GoalPathStr).
 
+:- func rev_goal_path_to_strings(reverse_goal_path) = list(string).
+
+rev_goal_path_to_strings(rgp_nil) = [].
+rev_goal_path_to_strings(rgp_cons(Steps, Step)) = [Str | Strs] :-
+    Str = goal_path_step_to_string(Step),
+    Strs = rev_goal_path_to_strings(Steps).
+
 :- func goal_path_step_to_string(goal_path_step) = string.
 
 goal_path_step_to_string(step_conj(N)) = "c" ++ int_to_string(N) ++ ";".
 goal_path_step_to_string(step_disj(N)) = "d" ++ int_to_string(N) ++ ";".
-goal_path_step_to_string(step_switch(N, yes(M))) = "s" ++ int_to_string(N)
-    ++ "-" ++ int_to_string(M) ++ ";".
-goal_path_step_to_string(step_switch(N, no)) = "s" ++ int_to_string(N)
-    ++ "-na;".      % short for "not applicable"
+goal_path_step_to_string(step_switch(N, known_num_functors_in_type(M))) =
+    "s" ++ int_to_string(N) ++ "-" ++ int_to_string(M) ++ ";".
+goal_path_step_to_string(step_switch(N, unknown_num_functors_in_type)) =
+    "s" ++ int_to_string(N) ++ "-na;".      % short for "not applicable"
 goal_path_step_to_string(step_ite_cond) = "?;".
 goal_path_step_to_string(step_ite_then) = "t;".
 goal_path_step_to_string(step_ite_else) = "e;".
@@ -445,8 +498,11 @@
 goal_path_step_to_string(step_atomic_orelse(N)) =
     "o" ++ int_to_string(N) ++ ";".
 
-rev_goal_path_remove_type_info(rgp(Steps0), rgp(Steps)) :-
-    map(goal_path_step_remove_type_info, Steps0, Steps).
+rev_goal_path_remove_type_info(rgp_nil, rgp_nil).
+rev_goal_path_remove_type_info(rgp_cons(Steps0, Step0),
+        rgp_cons(Steps, Step)) :-
+    goal_path_step_remove_type_info(Step0, Step),
+    rev_goal_path_remove_type_info(Steps0, Steps).
 
 :- pred goal_path_step_remove_type_info(goal_path_step::in,
     goal_path_step::out) is det.
@@ -467,7 +523,7 @@
         )
     ;
         !.Step = step_switch(N, _),
-        !:Step = step_switch(N, no)
+        !:Step = step_switch(N, unknown_num_functors_in_type)
     ).
 
 %-----------------------------------------------------------------------------%
@@ -482,38 +538,45 @@
     ).
 
 goal_id_to_forward_path(ContainingGoalMap, GoalId) = GoalPath :-
-    StepsCord = goal_id_to_steps(ContainingGoalMap, GoalId),
-    Steps = cord.list(StepsCord),
-    GoalPath = fgp(Steps).
+    RevGoalPath = goal_id_to_reverse_path(ContainingGoalMap, GoalId),
+    rgp_to_fgp(RevGoalPath, GoalPath).
 
 goal_id_to_reverse_path(ContainingGoalMap, GoalId) = GoalPath :-
-    StepsCord = goal_id_to_steps(ContainingGoalMap, GoalId),
-    Steps = cord.list(StepsCord),
-    list.reverse(Steps, RevSteps),
-    GoalPath = rgp(RevSteps).
-
-:- func goal_id_to_steps(containing_goal_map, goal_id) =
-    cord(goal_path_step).
-
-goal_id_to_steps(ContainingGoalMap, GoalId) = Steps :-
     map.lookup(ContainingGoalMap, GoalId, ContainingGoal),
     (
         ContainingGoal = whole_body_goal,
-        Steps = cord.empty
+        GoalPath = rgp_nil
     ;
         ContainingGoal = containing_goal(ParentGoalId, LastStep),
-        EarlierSteps = goal_id_to_steps(ContainingGoalMap, ParentGoalId),
-        Steps = cord.snoc(EarlierSteps, LastStep)
+        EarlierPath = goal_id_to_reverse_path(ContainingGoalMap, ParentGoalId),
+        GoalPath = rgp_cons(EarlierPath, LastStep)
     ).
 
 create_forward_goal_path_map(ContainingGoalMap) = ForwardGoalPathMap :-
     ReverseGoalPathMap = create_reverse_goal_path_map(ContainingGoalMap),
     map.map_values_only(rgp_to_fgp, ReverseGoalPathMap, ForwardGoalPathMap).
 
-:- pred rgp_to_fgp(reverse_goal_path::in, forward_goal_path::out) is det.
+rgp_to_fgp(ReverseGoalPath, ForwardGoalPath) :-
+    rgp_to_fgp_2(ReverseGoalPath, fgp_nil, ForwardGoalPath).
+
+:- pred rgp_to_fgp_2(reverse_goal_path::in,
+    forward_goal_path::in, forward_goal_path::out) is det.
 
-rgp_to_fgp(rgp(RevSteps), fgp(Steps)) :-
-    list.reverse(RevSteps, Steps).
+rgp_to_fgp_2(rgp_nil, !ForwardGoalPath).
+rgp_to_fgp_2(rgp_cons(EarlierSteps, LastStep), !ForwardGoalPath) :-
+    !:ForwardGoalPath = fgp_cons(LastStep, !.ForwardGoalPath),
+    rgp_to_fgp_2(EarlierSteps, !ForwardGoalPath).
+
+fgp_to_rgp(ForwardGoalPath, ReverseGoalPath) :-
+    fgp_to_rgp_2(ForwardGoalPath, rgp_nil, ReverseGoalPath).
+
+:- pred fgp_to_rgp_2(forward_goal_path::in,
+    reverse_goal_path::in, reverse_goal_path::out) is det.
+
+fgp_to_rgp_2(fgp_nil, !ReverseGoalPath).
+fgp_to_rgp_2(fgp_cons(FirstStep, LaterSteps), !ReverseGoalPath) :-
+    !:ReverseGoalPath = rgp_cons(!.ReverseGoalPath, FirstStep),
+    fgp_to_rgp_2(LaterSteps, !ReverseGoalPath).
 
 create_reverse_goal_path_map(ContainingGoalMap) = ReverseGoalPathMap :-
     map.to_assoc_list(ContainingGoalMap, ContainingGoalList),
@@ -530,14 +593,12 @@
     Head = GoalId - ContainingGoal,
     (
         ContainingGoal = whole_body_goal,
-        GoalReversePath = rgp([])
+        GoalReversePath = rgp_nil
     ;
         ContainingGoal = containing_goal(ContainingGoalId, Step),
         map.lookup(!.ReverseGoalPathMap, ContainingGoalId,
             ContainingGoalReversePath),
-        ContainingGoalReversePath = rgp(ContainingGoalReverseSteps),
-        GoalReverseSteps = [Step | ContainingGoalReverseSteps],
-        GoalReversePath = rgp(GoalReverseSteps)
+        GoalReversePath = rgp_cons(ContainingGoalReversePath, Step)
     ),
     map.det_insert(GoalId, GoalReversePath, !ReverseGoalPathMap),
     create_reverse_goal_path_map_2(Tail, !ReverseGoalPathMap).
@@ -557,14 +618,12 @@
     Head = GoalId - ContainingGoal,
     (
         ContainingGoal = whole_body_goal,
-        GoalReversePath = rgp([])
+        GoalReversePath = rgp_nil
     ;
         ContainingGoal = containing_goal(ContainingGoalId, Step),
         bimap.lookup(!.ReverseGoalPathBiMap, ContainingGoalId,
             ContainingGoalReversePath),
-        ContainingGoalReversePath = rgp(ContainingGoalReverseSteps),
-        GoalReverseSteps = [Step | ContainingGoalReverseSteps],
-        GoalReversePath = rgp(GoalReverseSteps)
+        GoalReversePath = rgp_cons(ContainingGoalReversePath, Step)
     ),
     bimap.det_insert(GoalId, GoalReversePath, !ReverseGoalPathBiMap),
     create_reverse_goal_path_bimap_2(Tail, !ReverseGoalPathBiMap).
Index: mdbcomp/slice_and_dice.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/slice_and_dice.m,v
retrieving revision 1.19
diff -u -b -r1.19 slice_and_dice.m
--- mdbcomp/slice_and_dice.m	3 May 2011 04:35:01 -0000	1.19
+++ mdbcomp/slice_and_dice.m	19 Sep 2011 15:42:39 -0000
@@ -455,12 +455,82 @@
     slice_label_count::in, slice_label_count::in,
     builtin.comparison_result::out) is det.
 
-slice_label_count_compare(SortStr, LabelCount1, LabelCount2, Result) :-
+slice_label_count_compare(SortStr, LabelCountA, LabelCountB, Result) :-
     ( SortStr = "" ->
-        builtin.compare(Result, LabelCount1, LabelCount2)
+        LabelCountA = slice_label_count(ProcLabelA, PathPortA, CountsA),
+        LabelCountB = slice_label_count(ProcLabelB, PathPortB, CountsB),
+        builtin.compare(ProcLabelResult, ProcLabelA, ProcLabelB),
+        (
+            ProcLabelResult = (<),
+            Result = (<)
+        ;
+            ProcLabelResult = (=),
+            compare_path_ports(PathPortA, PathPortB, PathPortResult),
+            (
+                PathPortResult = (<),
+                Result = (<)
+            ;
+                PathPortResult = (=),
+                builtin.compare(Result, CountsA, CountsB)
+            ;
+                PathPortResult = (>),
+                Result = (>)
+            )
+        ;
+            ProcLabelResult = (>),
+            Result = (>)
+        )
     ;
         slice_exec_count_compare(SortStr,
-            LabelCount1 ^ slc_counts, LabelCount2 ^ slc_counts, Result)
+            LabelCountA ^ slc_counts, LabelCountB ^ slc_counts, Result)
+    ).
+
+:- pred compare_path_ports(path_port::in, path_port::in,
+    builtin.comparison_result::out) is det.
+
+compare_path_ports(PathPortA, PathPortB, Result) :-
+    (
+        % Handle the case where PathPortA and PathPortB have the same
+        % functor.
+        (
+            PathPortA = port_only(PortA),
+            PathPortB = port_only(PortB),
+            require_det (
+                builtin.compare(ResultPrime, PortA, PortB)
+            )
+        ;
+            PathPortA = path_only(RevPathA),
+            PathPortB = path_only(RevPathB),
+            require_det (
+                rgp_to_fgp(RevPathA, PathA),
+                rgp_to_fgp(RevPathB, PathB),
+                builtin.compare(ResultPrime, PathA, PathB)
+            )
+        ;
+            PathPortA = port_and_path(PortA, RevPathA),
+            PathPortB = port_and_path(PortB, RevPathB),
+            require_det (
+                builtin.compare(PortResult, PortA, PortB),
+                (
+                    PortResult = (<),
+                    ResultPrime = (<)
+                ;
+                    PortResult = (=),
+                    rgp_to_fgp(RevPathA, PathA),
+                    rgp_to_fgp(RevPathB, PathB),
+                    builtin.compare(ResultPrime, PathA, PathB)
+                ;
+                    PortResult = (>),
+                    ResultPrime = (>)
+                )
+            )
+        )
+    ->
+        Result = ResultPrime
+    ;
+        % Handle the case where PathPortA and PathPortB have different
+        % functors.
+        builtin.compare(Result, PathPortA, PathPortB)
     ).
 
 :- pred slice_exec_count_compare(string::in,
@@ -468,9 +538,7 @@
     builtin.comparison_result::out) is det.
 
 slice_exec_count_compare(SortStr, ExecCount1, ExecCount2, Result) :-
-    (
-        string.first_char(SortStr, C, Rest)
-    ->
+    ( string.first_char(SortStr, C, Rest) ->
         ( C = 'c' ->
             builtin.compare(Result0, ExecCount1 ^ slice_count,
                 ExecCount2 ^ slice_count)
@@ -650,12 +718,34 @@
     dice_label_count::in, dice_label_count::in,
     builtin.comparison_result::out) is det.
 
-dice_label_count_compare(SortStr, LabelCount1, LabelCount2, Result) :-
+dice_label_count_compare(SortStr, LabelCountA, LabelCountB, Result) :-
     ( SortStr = "" ->
-        builtin.compare(Result, LabelCount1, LabelCount2)
+        LabelCountA = dice_label_count(ProcLabelA, PathPortA, CountsA),
+        LabelCountB = dice_label_count(ProcLabelB, PathPortB, CountsB),
+        builtin.compare(ProcLabelResult, ProcLabelA, ProcLabelB),
+        (
+            ProcLabelResult = (<),
+            Result = (<)
+        ;
+            ProcLabelResult = (=),
+            compare_path_ports(PathPortA, PathPortB, PathPortResult),
+            (
+                PathPortResult = (<),
+                Result = (<)
+            ;
+                PathPortResult = (=),
+                builtin.compare(Result, CountsA, CountsB)
+            ;
+                PathPortResult = (>),
+                Result = (>)
+            )
+        ;
+            ProcLabelResult = (>),
+            Result = (>)
+        )
     ;
         dice_exec_count_compare(SortStr,
-            LabelCount1 ^ dlc_counts, LabelCount2 ^ dlc_counts, Result)
+            LabelCountA ^ dlc_counts, LabelCountB ^ dlc_counts, Result)
     ).
 
 :- pred dice_exec_count_compare(string::in,
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/lazy_list
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list