[m-rev.] for review: representing goal paths using cords

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Nov 12 13:20:33 AEDT 2007


Change the representation of goal paths to use cords of steps instead of lists
of steps. With the list of steps representation, we always had to worry about
whether the list was reversed or not, since the usual operations on goal paths
operate mostly on the last step, not the first. With cords, this concern
disappears.

mdbcomp/program_representation.m:
	Make the change mentioned above.

	Standardize some utility operations on goal paths, now that the
	reversed/unreversed distinction is gone.

	Add some new utility operations.

library/cord.m:
	Add operations to get the first and last elements of a cord,
	to split the last element from a cord, and to test whether a cord
	is empty.

browser/*.m:
compiler/*.m:
mdbcomp/*.m:
slice/*.m:
	Conform to the change to program_representation.m.

compiler/unneeded_code.m:
	Add some debugging infrastructure I used to track down a bug I
	accidentally inserted while making this module use cords.

compiler/options.m:
	Add the options controlling the infrastructure in unneeded_code.m.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
Index: browser/declarative_tree.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_tree.m,v
retrieving revision 1.52
diff -u -r1.52 declarative_tree.m
--- browser/declarative_tree.m	27 Sep 2007 07:28:14 -0000	1.52
+++ browser/declarative_tree.m	8 Nov 2007 10:38:23 -0000
@@ -64,6 +64,7 @@
 
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module cord.
 :- import_module deconstruct.
 :- import_module exception.
 :- import_module int.
@@ -340,8 +341,7 @@
     % accumulators which should initially be zero.  RecordDups keeps track
     % of whether the final node was a FAIL or EXCP. This should be `no'
     % initially.  DupFactor keeps track of how many times the nodes before
-    % the last REDO could have been duplicated and should initially be
-    % zero.
+    % the last REDO could have been duplicated and should initially be zero.
     %
 :- pred trace_weight(weighting_heuristic::in, wrap(S)::in, edt_node(R)::in,
     int::in, int::out, bool::in, int::in, int::in, int::out)
@@ -876,7 +876,7 @@
     ),
     ProcDefnRep = proc_defn_rep(HeadVars, GoalRep),
     is_traced_grade(AllTraced),
-    MaybePrims = make_primitive_list(Store, [goal_and_path(GoalRep, [])],
+    MaybePrims = make_primitive_list(Store, [goal_and_path(GoalRep, empty)],
         Contour, StartPath, ArgNum, TotalArgs, HeadVars, AllTraced, []),
     (
         MaybePrims = yes(primitive_list_and_var(Primitives, Var,
@@ -973,7 +973,7 @@
     CallPrecId = CallNode ^ call_preceding,
     CallAtom = get_trace_call_atom(CallNode),
     CallPathStr = get_goal_path_from_maybe_label(CallNode ^ call_return_label),
-    path_from_string_det(CallPathStr, CallPath),
+    goal_path_from_string_det(CallPathStr, CallPath),
     StartLoc = parent_goal(CallId, CallNode),
     absolute_arg_num(ArgPos, CallAtom, ArgNum),
     TotalArgs = length(CallAtom ^ atom_args),
@@ -1172,11 +1172,10 @@
 :- pred contour_at_end_path(assoc_list(R, trace_node(R))::in,
     maybe(goal_path)::in) is semidet.
 
-contour_at_end_path(
-        [_ - node_call(_, _, _, _, _, _, MaybeReturnLabel, _, _, _)],
-        yes(EndPath)) :-
+contour_at_end_path([_ - Node], yes(EndPath)) :-
+    Node = node_call(_, _, _, _, _, _, MaybeReturnLabel, _, _, _),
     CallPathStr = get_goal_path_from_maybe_label(MaybeReturnLabel),
-    path_from_string_det(CallPathStr, CallPath),
+    goal_path_from_string_det(CallPathStr, CallPath),
     CallPath = EndPath.
 
 :- pred next_goal_generates_internal_event(list(goal_and_path)::in) is semidet.
@@ -1185,16 +1184,15 @@
     goal_generates_internal_event(NextGoal) = yes.
 
     % match_goal_to_contour_event(Store, Goal, Path, GoalPaths, Contour,
-    %   MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced, Primitives)
+    %   MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced, Primitives0)
     %   = MaybePrims:
     %
     % Matches the given goal_rep to the first event in the contour for
     % all goal_reps except atomic goal reps which need to be handled
     % differently depending on whether everything is traced (AllTraced).
-    % Returns the list of Primitives appended to the list of
-    % primitive goals along the remaining contour.  If it cannot match
-    % a higher order call to a contour event and AllTraced is no, then
-    % no is returned.
+    % Returns Primitives0 appended to the end of the list of primitive goals
+    % along the remaining contour. If it cannot match a higher order call
+    % to a contour event and AllTraced is no, then it returns "no".
     %
 :- func match_goal_to_contour_event(S, goal_rep, goal_path, goal_and_path_list,
     assoc_list(R, trace_node(R)), maybe(goal_path), int, int,
@@ -1211,7 +1209,7 @@
             Primitives0)
     ;
         Goal = scope_rep(InnerGoal, MaybeCut),
-        InnerPath = list.append(Path, [step_scope(MaybeCut)]),
+        InnerPath = cord.snoc(Path, step_scope(MaybeCut)),
         InnerAndPath = goal_and_path(InnerGoal, InnerPath),
         MaybePrims = make_primitive_list(Store, [InnerAndPath | GoalPaths],
             Contour, MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced,
@@ -1242,9 +1240,10 @@
                 ContourHeadNode = node_later_disj(_, Label, _)
             ),
             DisjPathStr = get_goal_path_from_label_layout(Label),
-            path_from_string_det(DisjPathStr, DisjPath),
-            list.append(Path, PathTail, DisjPath),
-            PathTail = [step_disj(N)]
+            goal_path_from_string_det(DisjPathStr, DisjPath),
+            cord.split_last(DisjPath, DisjInitialPath, DisjLastStep),
+            cord.equal(DisjInitialPath, Path),
+            DisjLastStep = step_disj(N)
         ->
             list.index1_det(Disjs, N, Disj),
             DisjAndPath = goal_and_path(Disj, DisjPath),
@@ -1261,9 +1260,10 @@
             Contour = [_ - ContourHeadNode | ContourTail],
             ContourHeadNode = node_switch(_, Label),
             ArmPathStr = get_goal_path_from_label_layout(Label),
-            path_from_string_det(ArmPathStr, ArmPath),
-            list.append(Path, PathTail, ArmPath),
-            PathTail = [step_switch(N, _)]
+            goal_path_from_string_det(ArmPathStr, ArmPath),
+            cord.split_last(ArmPath, ArmInitialPath, ArmLastStep),
+            cord.equal(ArmInitialPath, Path),
+            ArmLastStep = step_switch(N, _)
         ->
             list.index1_det(Cases, N, Case),
             Case = case_rep(_ConsId, _ConsIdArity, Arm),
@@ -1281,11 +1281,12 @@
             Contour = [_ - ContourHeadNode | ContourTail],
             ContourHeadNode = node_cond(_, Label, _),
             CondPathStr = get_goal_path_from_label_layout(Label),
-            path_from_string_det(CondPathStr, CondPath),
-            list.append(Path, PathTail, CondPath),
-            PathTail = [step_ite_cond]
+            goal_path_from_string_det(CondPathStr, CondPath),
+            cord.split_last(CondPath, CondInitialPath, CondLastStep),
+            cord.equal(CondInitialPath, Path),
+            CondLastStep = step_ite_cond
         ->
-            ThenPath = list.append(Path, [step_ite_then]),
+            ThenPath = cord.snoc(Path, step_ite_then),
             CondAndPath = goal_and_path(Cond, CondPath),
             ThenAndPath = goal_and_path(Then, ThenPath),
             MaybePrims = make_primitive_list(Store,
@@ -1297,11 +1298,12 @@
             cond_node_from_id(Store, ElseCondId, CondNode),
             CondNode = node_cond(_, Label, _),
             CondPathStr = get_goal_path_from_label_layout(Label),
-            path_from_string_det(CondPathStr, CondPath),
-            list.append(Path, PathTail, CondPath),
-            PathTail = [step_ite_cond]
+            goal_path_from_string_det(CondPathStr, CondPath),
+            cord.split_last(CondPath, CondInitialPath, CondLastStep),
+            cord.equal(CondInitialPath, Path),
+            CondLastStep = step_ite_cond
         ->
-            ElsePath = list.append(Path, [step_ite_else]),
+            ElsePath = cord.snoc(Path, step_ite_else),
             ElseAndPath = goal_and_path(Else, ElsePath),
             MaybePrims = make_primitive_list(Store, [ElseAndPath | GoalPaths],
                 ContourTail, MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced,
@@ -1325,7 +1327,7 @@
         ->
             % The end of the primitive list is somewhere inside
             % NegGoal.
-            NegPath = list.append(Path, [step_neg]),
+            NegPath = cord.snoc(Path, step_neg),
             NegAndPath = goal_and_path(NegGoal, NegPath),
             MaybePrims = make_primitive_list(Store, [NegAndPath], ContourTail,
                 MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced, Primitives0)
@@ -1384,7 +1386,7 @@
                 MaybeReturnLabel, _, _, _),
             Atom = get_trace_call_atom(ContourHeadNode),
             CallPathStr = get_goal_path_from_maybe_label( MaybeReturnLabel),
-            path_from_string_det(CallPathStr, CallPath),
+            goal_path_from_string_det(CallPathStr, CallPath),
             CallPath = EndPath
         ->
             (
@@ -1750,7 +1752,7 @@
 add_paths_to_conjuncts([], _, _, []).
 add_paths_to_conjuncts([Goal | Goals], ParentPath, N,
         [goal_and_path(Goal, Path) | GoalAndPaths]) :-
-    Path = ParentPath ++ [step_conj(N)],
+    Path = cord.snoc(ParentPath, step_conj(N)),
     add_paths_to_conjuncts(Goals, ParentPath, N + 1, GoalAndPaths).
 
 %-----------------------------------------------------------------------------%
@@ -1876,9 +1878,8 @@
 calls_arguments_are_all_ground(Store, CallId) :-
     call_node_from_id(Store, CallId, Call),
     Args = Call ^ call_atom_args,
-    %
+
     % XXX The following won't work for partially instantiated arguments.
-    %
     all [Arg] (
         list.member(Arg, Args)
     =>
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/build_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/build_mode_constraints.m,v
retrieving revision 1.27
diff -u -r1.27 build_mode_constraints.m
--- compiler/build_mode_constraints.m	7 Aug 2007 07:09:46 -0000	1.27
+++ compiler/build_mode_constraints.m	6 Nov 2007 12:17:40 -0000
@@ -205,6 +205,7 @@
 :- import_module libs.compiler_util.
 
 :- import_module bool.
+:- import_module cord.
 :- import_module map.
 :- import_module maybe.
 :- import_module multi_map.
@@ -284,7 +285,7 @@
     mc_var_info::in, mc_var_info::out) is det.
 
 add_mc_var_for_pred_head(ProgVarset, PredId, HeadVar, !VarInfo) :-
-    prog_var_at_path(ProgVarset, PredId, HeadVar, [], _, !VarInfo).
+    prog_var_at_path(ProgVarset, PredId, HeadVar, empty, _, !VarInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -366,7 +367,7 @@
         % Temporarily form the disjunction implied by the goal path
         % annotations.
         MainGoal = disj(Goals),
-        HeadGoalPath = [],
+        HeadGoalPath = empty,
         Nonlocals = proc_arg_vector_to_set(HeadVars),
         add_goal_expr_constraints(ModuleInfo, ProgVarset, PredId, MainGoal,
             Context, HeadGoalPath, Nonlocals, !VarInfo, !Constraints)
@@ -674,7 +675,7 @@
     % the proposition that it is produced at the empty goal path (ie
     % that it is produced by a call to the predicate).
     HeadVarsMCVars =
-        list.map(list.map(lookup_prog_var_at_path(VarMap, PredId, [])),
+        list.map(list.map(lookup_prog_var_at_path(VarMap, PredId, empty)),
             HeadVarsList),
 
     % Make the constraints for each declaration.
@@ -694,7 +695,7 @@
     proc_info_get_varset(ProcInfo, ProgVarset),
     proc_info_get_context(ProcInfo, Context),
 
-    prog_vars_at_path(ProgVarset, PredId, Args, [], ArgsAtHead, !VarInfo),
+    prog_vars_at_path(ProgVarset, PredId, Args, empty, ArgsAtHead, !VarInfo),
 
     DeclConstraints = mode_decl_constraints(ModuleInfo, ArgsAtHead, Decl),
 
@@ -767,7 +768,7 @@
 
 add_call_headvar_constraints(ProgVarset, Context, GoalPath, CallerPredId,
         CallArgs, CalleePredId, CalleeHeadVars, !VarInfo, !Constraints) :-
-    prog_vars_at_path(ProgVarset, CalleePredId, CalleeHeadVars, [],
+    prog_vars_at_path(ProgVarset, CalleePredId, CalleeHeadVars, empty,
         HeadVarsAtHead, !VarInfo),
     prog_vars_at_path(ProgVarset, CallerPredId, CallArgs, GoalPath,
         CallArgsHere, !VarInfo),
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.66
diff -u -r1.66 deep_profiling.m
--- compiler/deep_profiling.m	10 Oct 2007 14:35:25 -0000	1.66
+++ compiler/deep_profiling.m	7 Nov 2007 00:52:52 -0000
@@ -51,6 +51,7 @@
 
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module cord.
 :- import_module counter.
 :- import_module int.
 :- import_module list.
@@ -550,7 +551,7 @@
             counter.init(0), [], !.VarSet, !.VarTypes, FileName, MaybeRecInfo)
     ),
 
-    deep_prof_transform_goal([], Goal0, TransformedGoal, _,
+    deep_prof_transform_goal(empty, Goal0, TransformedGoal, _,
         DeepInfo0, DeepInfo),
 
     Vars = DeepInfo ^ deep_varset,
@@ -646,7 +647,7 @@
             FileName, MaybeRecInfo)
     ),
 
-    deep_prof_transform_goal([], Goal0, TransformedGoal, _,
+    deep_prof_transform_goal(empty, Goal0, TransformedGoal, _,
         DeepInfo0, DeepInfo),
 
     Vars = DeepInfo ^ deep_varset,
@@ -760,7 +761,7 @@
             counter.init(0), [], !.VarSet, !.VarTypes, FileName, MaybeRecInfo)
     ),
 
-    deep_prof_transform_goal([], Goal0, TransformedGoal, _,
+    deep_prof_transform_goal(empty, Goal0, TransformedGoal, _,
         DeepInfo0, DeepInfo),
 
     Vars = DeepInfo ^ deep_varset,
@@ -885,7 +886,7 @@
         counter.init(0), [], VarSet1, VarTypes1,
         FileName, MaybeRecInfo),
 
-    deep_prof_transform_goal([], Goal0, TransformedGoal, _,
+    deep_prof_transform_goal(empty, Goal0, TransformedGoal, _,
         DeepInfo0, DeepInfo),
 
     VarSet = DeepInfo ^ deep_varset,
@@ -990,18 +991,18 @@
         Goal = hlds_goal(GoalExpr, GoalInfo)
     ;
         GoalExpr0 = negation(SubGoal0),
-        deep_prof_transform_goal([step_neg | Path], SubGoal0, SubGoal,
+        deep_prof_transform_goal(cord.snoc(Path, step_neg), SubGoal0, SubGoal,
             AddedImpurity, !DeepInfo),
         add_impurity_if_needed(AddedImpurity, GoalInfo0, GoalInfo),
         GoalExpr = negation(SubGoal),
         Goal = hlds_goal(GoalExpr, GoalInfo)
     ;
         GoalExpr0 = if_then_else(IVars, Cond0, Then0, Else0),
-        deep_prof_transform_goal([step_ite_cond | Path], Cond0, Cond,
+        deep_prof_transform_goal(cord.snoc(Path, step_ite_cond), Cond0, Cond,
             AddedImpurityC, !DeepInfo),
-        deep_prof_transform_goal([step_ite_then | Path], Then0, Then,
+        deep_prof_transform_goal(cord.snoc(Path, step_ite_then), Then0, Then,
             AddedImpurityT, !DeepInfo),
-        deep_prof_transform_goal([step_ite_else | Path], Else0, Else,
+        deep_prof_transform_goal(cord.snoc(Path, step_ite_else), Else0, Else,
             AddedImpurityE, !DeepInfo),
         (
             ( AddedImpurityC = yes
@@ -1043,7 +1044,7 @@
                 AddForceCommit = yes
             )
         ),
-        deep_prof_transform_goal([step_scope(MaybeCut) | Path],
+        deep_prof_transform_goal(cord.snoc(Path, step_scope(MaybeCut)),
             SubGoal0, SubGoal, AddedImpurity, !DeepInfo),
         add_impurity_if_needed(AddedImpurity, GoalInfo0, GoalInfo),
         (
@@ -1068,7 +1069,7 @@
 deep_prof_transform_conj(N, Path, [Goal0 | Goals0], [Goal | Goals],
         AddedImpurity, !DeepInfo) :-
     N1 = N + 1,
-    deep_prof_transform_goal([step_conj(N1) | Path], Goal0, Goal,
+    deep_prof_transform_goal(cord.snoc(Path, step_conj(N1)), Goal0, Goal,
         AddedImpurityFirst, !DeepInfo),
     deep_prof_transform_conj(N1, Path, Goals0, Goals, AddedImpurityLater,
         !DeepInfo),
@@ -1082,7 +1083,7 @@
 deep_prof_transform_disj(N, Path, [Goal0 | Goals0], [Goal | Goals],
         AddedImpurity, !DeepInfo) :-
     N1 = N + 1,
-    deep_prof_transform_goal([step_disj(N1) | Path], Goal0, Goal,
+    deep_prof_transform_goal(cord.snoc(Path, step_disj(N1)), Goal0, Goal,
         AddedImpurityFirst, !DeepInfo),
     deep_prof_transform_disj(N1, Path, Goals0, Goals, AddedImpurityLater,
         !DeepInfo),
@@ -1096,7 +1097,7 @@
 deep_prof_transform_switch(MaybeNumCases, N, Path, [case(Id, Goal0) | Goals0],
         [case(Id, Goal) | Goals], AddedImpurity, !DeepInfo) :-
     N1 = N + 1,
-    deep_prof_transform_goal([step_switch(N1, MaybeNumCases) | Path],
+    deep_prof_transform_goal(cord.snoc(Path, step_switch(N1, MaybeNumCases)),
         Goal0, Goal, AddedImpurityFirst, !DeepInfo),
     deep_prof_transform_switch(MaybeNumCases, N1, Path, Goals0, Goals,
         AddedImpurityLater, !DeepInfo),
Index: compiler/goal_path.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_path.m,v
retrieving revision 1.44
diff -u -r1.44 goal_path.m
--- compiler/goal_path.m	7 Aug 2007 07:09:53 -0000	1.44
+++ compiler/goal_path.m	6 Nov 2007 12:19:19 -0000
@@ -67,6 +67,7 @@
 :- import_module mdbcomp.program_representation.
 :- import_module parse_tree.prog_data.
 
+:- import_module cord.
 :- import_module int.
 :- import_module list.
 :- import_module map.
@@ -102,12 +103,13 @@
 
 fill_slots_in_clause(SlotInfo, Clause0, Clause, ClauseNum, ClauseNum + 1) :-
     Clause0 = clause(ProcIds, Goal0, Lang, Context),
-    fill_goal_slots([step_disj(ClauseNum)], SlotInfo, Goal0, Goal),
+    fill_goal_slots(cord.singleton(step_disj(ClauseNum)), SlotInfo,
+        Goal0, Goal),
     Clause = clause(ProcIds, Goal, Lang, Context).
 
 fill_goal_path_slots_in_goal(Goal0, VarTypes, ModuleInfo, Goal) :-
     SlotInfo = slot_info(VarTypes, ModuleInfo, no),
-    fill_goal_slots([], SlotInfo, Goal0, Goal).
+    fill_goal_slots(empty, SlotInfo, Goal0, Goal).
 
 :- pred fill_goal_slots(goal_path::in, slot_info::in,
     hlds_goal::in, hlds_goal::out) is det.
@@ -117,7 +119,9 @@
     OmitModeEquivPrefix = SlotInfo ^ omit_mode_equiv_prefix,
     (
         OmitModeEquivPrefix = yes,
-        list.takewhile(mode_equiv_step, Path0, _, Path)
+        PathSteps0 = cord.list(Path0),
+        list.takewhile(mode_equiv_step, PathSteps0, _, PathSteps),
+        Path = cord.from_list(PathSteps)
     ;
         OmitModeEquivPrefix = no,
         Path = Path0
@@ -160,7 +164,8 @@
         Goal = switch(Var, CanFail, Cases)
     ;
         Goal0 = negation(SubGoal0),
-        fill_goal_slots([step_neg | Path0], SlotInfo, SubGoal0, SubGoal),
+        fill_goal_slots(cord.snoc(Path0, step_neg), SlotInfo,
+            SubGoal0, SubGoal),
         Goal = negation(SubGoal)
     ;
         Goal0 = scope(Reason, SubGoal0),
@@ -172,14 +177,17 @@
         ;
             MaybeCut = scope_is_cut
         ),
-        fill_goal_slots([step_scope(MaybeCut) | Path0], SlotInfo,
+        fill_goal_slots(cord.snoc(Path0, step_scope(MaybeCut)), SlotInfo,
             SubGoal0, SubGoal),
         Goal = scope(Reason, SubGoal)
     ;
         Goal0 = if_then_else(A, Cond0, Then0, Else0),
-        fill_goal_slots([step_ite_cond | Path0], SlotInfo, Cond0, Cond),
-        fill_goal_slots([step_ite_then | Path0], SlotInfo, Then0, Then),
-        fill_goal_slots([step_ite_else | Path0], SlotInfo, Else0, Else),
+        fill_goal_slots(cord.snoc(Path0, step_ite_cond), SlotInfo,
+            Cond0, Cond),
+        fill_goal_slots(cord.snoc(Path0, step_ite_then), SlotInfo,
+            Then0, Then),
+        fill_goal_slots(cord.snoc(Path0, step_ite_else), SlotInfo,
+            Else0, Else),
         Goal = if_then_else(A, Cond, Then, Else)
     ;
         Goal0 = unify(LHS, RHS0, Mode, Kind, Context),
@@ -211,7 +219,7 @@
 fill_conj_slots(_, _, _, [], []).
 fill_conj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_slots([step_conj(N1) | Path0], SlotInfo, Goal0, Goal),
+    fill_goal_slots(cord.snoc(Path0, step_conj(N1)), SlotInfo, Goal0, Goal),
     fill_conj_slots(Path0, N1, SlotInfo, Goals0, Goals).
 
 :- pred fill_disj_slots(goal_path::in, int::in, slot_info::in,
@@ -220,7 +228,7 @@
 fill_disj_slots(_, _, _, [], []).
 fill_disj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_slots([step_disj(N1) | Path0], SlotInfo, Goal0, Goal),
+    fill_goal_slots(cord.snoc(Path0, step_disj(N1)), SlotInfo, Goal0, Goal),
     fill_disj_slots(Path0, N1, SlotInfo, Goals0, Goals).
 
 :- pred fill_switch_slots(goal_path::in, int::in, maybe(int)::in,
@@ -230,8 +238,8 @@
 fill_switch_slots(Path0, N0, MaybeNumFunctors, SlotInfo,
         [case(ConsId, Goal0) | Cases0], [case(ConsId, Goal) | Cases]) :-
     N1 = N0 + 1,
-    fill_goal_slots([step_switch(N1, MaybeNumFunctors) | Path0], SlotInfo,
-        Goal0, Goal),
+    fill_goal_slots(cord.snoc(Path0, step_switch(N1, MaybeNumFunctors)),
+        SlotInfo, Goal0, Goal),
     fill_switch_slots(Path0, N1, MaybeNumFunctors, SlotInfo, Cases0, Cases).
 
 %-----------------------------------------------------------------------------%
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.311
diff -u -r1.311 handle_options.m
--- compiler/handle_options.m	6 Nov 2007 05:25:08 -0000	1.311
+++ compiler/handle_options.m	8 Nov 2007 06:17:06 -0000
@@ -985,6 +985,15 @@
             true
         ),
 
+        globals.lookup_accumulating_option(!.Globals,
+            unneeded_code_debug_pred_name, DebugUnneededCodePredNames),
+        (
+            DebugUnneededCodePredNames = []
+        ;
+            DebugUnneededCodePredNames = [_ | _],
+            globals.set_option(unneeded_code_debug, bool(yes), !Globals)
+        ),
+
         globals.lookup_accumulating_option(!.Globals, debug_opt_pred_id,
             DebugOptPredIdStrs),
         globals.lookup_accumulating_option(!.Globals, debug_opt_pred_name,
Index: compiler/hlds_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_data.m,v
retrieving revision 1.117
diff -u -r1.117 hlds_data.m
--- compiler/hlds_data.m	25 Sep 2007 04:56:38 -0000	1.117
+++ compiler/hlds_data.m	6 Nov 2007 12:30:57 -0000
@@ -37,6 +37,7 @@
 :- import_module libs.compiler_util.
 :- import_module parse_tree.prog_type_subst.
 
+:- import_module cord.
 :- import_module int.
 :- import_module svmap.
 :- import_module svmulti_map.
@@ -1090,7 +1091,7 @@
 make_head_hlds_constraints(ClassTable, TVarSet, ProgConstraints,
         Constraints) :-
     ProgConstraints = constraints(UnivConstraints, ExistConstraints),
-    GoalPath = [],
+    GoalPath = empty,
     make_hlds_constraint_list(UnivConstraints, assumed, GoalPath,
         AssumedConstraints),
     make_hlds_constraint_list(ExistConstraints, unproven, GoalPath,
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.182
diff -u -r1.182 hlds_goal.m
--- compiler/hlds_goal.m	28 Sep 2007 03:17:11 -0000	1.182
+++ compiler/hlds_goal.m	7 Nov 2007 01:00:34 -0000
@@ -1497,6 +1497,7 @@
 :- import_module parse_tree.prog_type.
 
 :- import_module assoc_list.
+:- import_module cord.
 :- import_module map.
 :- import_module string.
 :- import_module svmap.
@@ -1641,8 +1642,10 @@
     set.init(NonLocals),
     term.context_init(Context),
     set.init(Features),
+    GoalPath = empty,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, purity_pure,
-        Features, [], no_code_gen_info, hlds_goal_extra_info_init(Context)).
+        Features, GoalPath, no_code_gen_info,
+        hlds_goal_extra_info_init(Context)).
 
 :- pragma inline(goal_info_init/2).
 
@@ -1651,19 +1654,25 @@
     instmap_delta_init_unreachable(InstMapDelta),
     set.init(NonLocals),
     set.init(Features),
+    GoalPath = empty,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, purity_pure,
-        Features, [], no_code_gen_info, hlds_goal_extra_info_init(Context)).
+        Features, GoalPath, no_code_gen_info,
+        hlds_goal_extra_info_init(Context)).
 
 goal_info_init(NonLocals, InstMapDelta, Detism, Purity, GoalInfo) :-
     set.init(Features),
     term.context_init(Context),
+    GoalPath = empty,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, Purity,
-        Features, [], no_code_gen_info, hlds_goal_extra_info_init(Context)).
+        Features, GoalPath, no_code_gen_info,
+        hlds_goal_extra_info_init(Context)).
 
 goal_info_init(NonLocals, InstMapDelta, Detism, Purity, Context, GoalInfo) :-
     set.init(Features),
+    GoalPath = empty,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, Purity,
-        Features, [], no_code_gen_info, hlds_goal_extra_info_init(Context)).
+        Features, GoalPath, no_code_gen_info,
+        hlds_goal_extra_info_init(Context)).
 
 :- func hlds_goal_extra_info_init(term.context) = hlds_goal_extra_info.
 
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.436
diff -u -r1.436 hlds_out.m
--- compiler/hlds_out.m	28 Sep 2007 06:47:12 -0000	1.436
+++ compiler/hlds_out.m	7 Nov 2007 00:56:37 -0000
@@ -271,6 +271,7 @@
 :- import_module parse_tree.prog_util.
 
 :- import_module assoc_list.
+:- import_module cord.
 :- import_module getopt_io.
 :- import_module int.
 :- import_module map.
@@ -278,8 +279,8 @@
 :- import_module pair.
 :- import_module set.
 :- import_module string.
-:- import_module term_io.
 :- import_module table_builtin.
+:- import_module term_io.
 :- import_module varset.
 
 %-----------------------------------------------------------------------------%
@@ -1241,14 +1242,13 @@
     ),
     ( string.contains_char(Verbose, 'P') ->
         Path = goal_info_get_goal_path(GoalInfo),
-        (
-            Path = [_ | _],
+        ( is_empty(Path) ->
+            true
+        ;
             write_indent(Indent, !IO),
             io.write_string("% goal path: ", !IO),
             io.write_string(goal_path_to_string(Path), !IO),
             io.write_string("\n", !IO)
-        ;
-            Path = []
         )
     ;
         true
Index: compiler/mode_constraint_robdd.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_constraint_robdd.m,v
retrieving revision 1.12
diff -u -r1.12 mode_constraint_robdd.m
--- compiler/mode_constraint_robdd.m	6 Jan 2007 10:56:15 -0000	1.12
+++ compiler/mode_constraint_robdd.m	6 Nov 2007 12:32:05 -0000
@@ -152,6 +152,7 @@
 
 :- import_module bimap.
 :- import_module bool.
+:- import_module cord.
 :- import_module list.
 :- import_module map.
 :- import_module require.
@@ -163,24 +164,27 @@
 :- import_module term.
 :- import_module varset.
 
-:- type mc_type ---> mc_type.
+:- type mc_type
+    --->    mc_type.
 
-:- type mode_constraint_info --->
-    mode_constraint_info(
-        varset      :: varset(mc_type),
-        varmap      :: mode_constraint_varmap,
-        pred_id     :: pred_id,
-        lambda_path :: lambda_path,
-        min_vars    :: map(pred_id, mode_constraint_var),
-        max_vars    :: map(pred_id, mode_constraint_var),
-        input_nodes :: sparse_bitset(prog_var),
-        zero_var    :: robdd_var,
-                % A var that is always zero.
-        simple_constraints :: bool
-                % Are we using the simplified constraint model.
-    ).
+:- type mode_constraint_info
+    --->    mode_constraint_info(
+                varset              :: varset(mc_type),
+                varmap              :: mode_constraint_varmap,
+                pred_id             :: pred_id,
+                lambda_path         :: lambda_path,
+                min_vars            :: map(pred_id, mode_constraint_var),
+                max_vars            :: map(pred_id, mode_constraint_var),
+                input_nodes         :: sparse_bitset(prog_var),
+                zero_var            :: robdd_var,
+                                    % A var that is always zero.
+                simple_constraints  :: bool
+                                    % Are we using the simplified constraint
+                                    % model.
+            ).
 
-:- type threshold ---> threshold(mode_constraint_var).
+:- type threshold
+    --->    threshold(mode_constraint_var).
 
 init_mode_constraint_info(Simple) = Info :-
     VarSet0 = varset.init,
@@ -221,17 +225,16 @@
         ;
             varset.new_var(Info0 ^ varset, RobddVar, NewVarSet),
             bimap.set(Info0 ^ varmap, Key, RobddVar, NewVarMap),
-            Info = (Info0 ^ varset := NewVarSet)
-                ^ varmap := NewVarMap
+            Info = (Info0 ^ varset := NewVarSet) ^ varmap := NewVarMap
         )
     ).
 
 mode_constraint_var(Info, RepVar) = bimap.lookup(Info ^ varmap, Key) :-
     Key = key(RepVar, Info ^ pred_id, Info ^ lambda_path).
 
-enter_lambda_goal(GoalPath) -->
-    LambdaPath0 =^ lambda_path,
-    ^ lambda_path := stack.push(LambdaPath0, GoalPath).
+enter_lambda_goal(GoalPath, !Info) :-
+    LambdaPath0 = !.Info ^ lambda_path,
+    !:Info = !.Info ^ lambda_path := stack.push(LambdaPath0, GoalPath).
 
 leave_lambda_goal -->
     LambdaPath0 =^ lambda_path,
@@ -240,10 +243,10 @@
 
 :- type prog_var_and_level
     --->    prog_var_and_level(
-            prog_var,
-            pred_id,
-            lambda_path
-        ).
+                prog_var,
+                pred_id,
+                lambda_path
+            ).
 
 get_prog_var_level(Var, prog_var_and_level(Var, PredId, LambdaPath)) -->
     PredId =^ pred_id,
@@ -335,51 +338,51 @@
 :- pred dump_mode_constraint_var(prog_varset::in, rep_var::in,
     io::di, io::uo) is det.
 
-dump_mode_constraint_var(VarSet, in(V)) -->
-    { varset.lookup_name(VarSet, V, Name) },
-    io.write_string(Name),
-    io.write_string("_in").
-dump_mode_constraint_var(VarSet, out(V)) -->
-    { varset.lookup_name(VarSet, V, Name) },
-    io.write_string(Name),
-    io.write_string("_out").
-dump_mode_constraint_var(VarSet, V `at` Path0) -->
-    { varset.lookup_name(VarSet, V, Name) },
-    io.write_string(Name),
-    io.write_char('_'),
-    { list.reverse(Path0, Path) },
-    list.foldl(dump_goal_path_step, Path).
+dump_mode_constraint_var(VarSet, in(V), !IO) :-
+    varset.lookup_name(VarSet, V, Name),
+    io.write_string(Name, !IO),
+    io.write_string("_in", !IO).
+dump_mode_constraint_var(VarSet, out(V), !IO) :-
+    varset.lookup_name(VarSet, V, Name),
+    io.write_string(Name, !IO),
+    io.write_string("_out", !IO).
+dump_mode_constraint_var(VarSet, V `at` Path, !IO) :-
+    varset.lookup_name(VarSet, V, Name),
+    io.write_string(Name, !IO),
+    io.write_char('_', !IO),
+    PathSteps = cord.list(Path),
+    list.foldl(dump_goal_path_step, PathSteps, !IO).
 
 :- pred dump_goal_path_step(goal_path_step::in, io::di, io::uo) is det.
 
-dump_goal_path_step(step_conj(N)) -->
-    io.write_char('c'),
-    io.write_int(N).
-dump_goal_path_step(step_disj(N)) -->
-    io.write_char('d'),
-    io.write_int(N).
-dump_goal_path_step(step_switch(N, _)) -->
-    io.write_char('s'),
-    io.write_int(N).
-dump_goal_path_step(step_ite_cond) -->
-    io.write_char('c').
-dump_goal_path_step(step_ite_then) -->
-    io.write_char('t').
-dump_goal_path_step(step_ite_else) -->
-    io.write_char('e').
-dump_goal_path_step(step_neg) -->
-    io.write_char('n').
-dump_goal_path_step(step_scope(_)) -->
-    io.write_char('q').
-dump_goal_path_step(step_first) -->
-    io.write_char('f').
-dump_goal_path_step(step_later) -->
-    io.write_char('l').
-
-robdd_to_dot(Constraint, ProgVarSet, Info, FileName) -->
-    robdd_to_dot(Constraint ^ robdd, P, FileName),
-    { VarMap = Info ^ varmap },
-    { P = (pred(RobddVar::in, di, uo) is det -->
+dump_goal_path_step(step_conj(N), !IO) :-
+    io.write_char('c', !IO),
+    io.write_int(N, !IO).
+dump_goal_path_step(step_disj(N), !IO) :-
+    io.write_char('d', !IO),
+    io.write_int(N, !IO).
+dump_goal_path_step(step_switch(N, _), !IO) :-
+    io.write_char('s', !IO),
+    io.write_int(N, !IO).
+dump_goal_path_step(step_ite_cond, !IO) :-
+    io.write_char('c', !IO).
+dump_goal_path_step(step_ite_then, !IO) :-
+    io.write_char('t', !IO).
+dump_goal_path_step(step_ite_else, !IO) :-
+    io.write_char('e', !IO).
+dump_goal_path_step(step_neg, !IO) :-
+    io.write_char('n', !IO).
+dump_goal_path_step(step_scope(_), !IO) :-
+    io.write_char('q', !IO).
+dump_goal_path_step(step_first, !IO) :-
+    io.write_char('f', !IO).
+dump_goal_path_step(step_later, !IO) :-
+    io.write_char('l', !IO).
+
+robdd_to_dot(Constraint, ProgVarSet, Info, FileName, !IO) :-
+    robdd_to_dot(Constraint ^ robdd, P, FileName, !IO),
+    VarMap = Info ^ varmap,
+    P = (pred(RobddVar::in, di, uo) is det -->
         { bimap.reverse_lookup(VarMap, key(RepVar, PredId, LambdaPath),
             RobddVar) },
         dump_mode_constraint_var(ProgVarSet, RepVar),
@@ -391,7 +394,7 @@
         io.write_string(" ("),
         io.write_int(term.var_to_int(RobddVar)),
         io.write_string(")")
-    )}.
+    ).
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.42
diff -u -r1.42 mode_constraints.m
--- compiler/mode_constraints.m	7 Aug 2007 07:09:59 -0000	1.42
+++ compiler/mode_constraints.m	6 Nov 2007 12:56:35 -0000
@@ -80,6 +80,7 @@
 
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module cord.
 :- import_module list.
 :- import_module map.
 :- import_module maybe.
@@ -377,7 +378,7 @@
         ( pred(V::in, S0::in, S::out) is det :-
             mode_constraint_var(in(V), _, S0, S1),
             mode_constraint_var(out(V), _, S1, S2),
-            mode_constraint_var(V `at` [], _, S2, S)
+            mode_constraint_var(V `at` empty, _, S2, S)
         ), InstGraph, HeadVars, !MCI),
 
     ( pred_info_is_imported(PredInfo0) ->
@@ -506,7 +507,7 @@
             ( pred(V::in, in, out) is det -->
                 mode_constraint_var(in(V), _),
                 mode_constraint_var(out(V), _),
-                mode_constraint_var(V `at` [], _)
+                mode_constraint_var(V `at` empty, _)
             ), InstGraph, LambdaHeadVars), !NRInfo),
 
     % Number variables within the lambda goal.
@@ -1035,7 +1036,7 @@
     list.map(pred(clause(_, Goal, _, _)::in, Goal::out) is det, Clauses,
         Goals),
     DisjGoal = disj(Goals),
-    EmptyGoalPath = [],
+    EmptyGoalPath = empty,
     AtomicGoals0 = set.init,
     Info0 = goal_constraints_info(ModuleInfo, SCC, InstGraph, HeadVars,
         VarSet0, AtomicGoals0, !.ConstraintInfo, HOModes0, map.init),
@@ -1073,35 +1074,40 @@
     mode_constraint_info::in, mode_constraint_info::out) is det.
 
 input_output_constraints(HeadVars, InstGraph, V, Node, !Constraint, !MCI) :-
-    % For each node V not reachable from an argument node, add
-    %   Vin = 0
+    % For each node V not reachable from an argument node, add Vin = 0.
     inst_graph.top_level_node(InstGraph, V, TopLevel),
     mode_constraint_var(in(V), V_in, !MCI),
     mode_constraint_var(out(V), V_out, !MCI),
-    mode_constraint_var(V `at` [], V_, !MCI),
+    mode_constraint_var(V `at` empty, V_, !MCI),
     ( TopLevel `list.member` HeadVars ->
         % For each variable V in the instantiation graph, add
-        %   (Vout = Vin + V), ~(Vin * V)
+        %   (Vout = Vin + V), ~(Vin * V).
         !:Constraint = !.Constraint ^ io_constraint(V_in, V_out, V_)
     ;
         !:Constraint = !.Constraint ^ not_var(V_in) ^ eq_vars(V_out, V_)
     ),
 
     % For each node V in the graph with child f with child W, add
-    %   Wout -> Vout, Win -> Vin
+    %   Wout -> Vout, Win -> Vin.
     Node = node(Functors, _),
     map.values(Functors, Children0),
     list.condense(Children0, Children),
-    list.foldl2((pred(W::in, Cs0::in, Cs::out, S0::in, S::out) is det :-
-            ( W = V ->
-                Cs = Cs0,
-                S = S0
-            ;
-                mode_constraint_var(in(W), W_in, S0, S1),
-                mode_constraint_var(out(W), W_out, S1, S),
-                Cs = Cs0 ^ imp_vars(W_out, V_out) ^ imp_vars(W_in, V_in)
-            )
-        ), Children, !Constraint, !MCI).
+    list.foldl2(add_in_and_out_implications(V, V_in, V_out), Children,
+        !Constraint, !MCI).
+
+:- pred add_in_and_out_implications(prog_var::in,
+    mode_constraint_var::in, mode_constraint_var::in, prog_var::in,
+    mode_constraint::in, mode_constraint::out,
+    mode_constraint_info::in, mode_constraint_info::out) is det.
+
+add_in_and_out_implications(V, V_in, V_out, W, !Cs, !Info) :-
+    ( W = V ->
+        true
+    ;
+        mode_constraint_var(in(W), W_in, !Info),
+        mode_constraint_var(out(W), W_out, !Info),
+        !:Cs = !.Cs ^ imp_vars(W_out, V_out) ^ imp_vars(W_in, V_in)
+    ).
 
 :- type can_succeed == bool.
 
@@ -1696,7 +1702,7 @@
         ),
     Accumulator =
         (pred((V - W)::in, C0::in, C::out, S0::in, S::out) is det :-
-            get_var(PredId, V `at` [], V_, S0, S1),
+            get_var(PredId, V `at` empty, V_, S0, S1),
             get_var(W `at` GoalPath, Wgp, S1, S2),
             get_var(PredId, in(V), Vin, S2, S3),
             get_var(out(W), Wout, S3, S),
@@ -1792,7 +1798,9 @@
         inst_graph.reachable(InstGraph, NonLocal, V),
         \+ (
             RepVar = _ `at` GoalPath1,
-            list.remove_suffix(GoalPath1, GoalPath, [_|_])
+            GoalPathSteps = cord.list(GoalPath),
+            GoalPathSteps1 = cord.list(GoalPath1),
+            list.remove_suffix(GoalPathSteps1, GoalPathSteps, [_ | _])
         )
     ).
 
Index: compiler/mode_ordering.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_ordering.m,v
retrieving revision 1.24
diff -u -r1.24 mode_ordering.m
--- compiler/mode_ordering.m	7 Sep 2007 15:08:17 -0000	1.24
+++ compiler/mode_ordering.m	7 Nov 2007 01:35:53 -0000
@@ -63,6 +63,7 @@
 :- import_module parse_tree.prog_data.
 
 :- import_module assoc_list.
+:- import_module cord.
 :- import_module digraph.
 :- import_module pair.
 :- import_module set.
@@ -414,7 +415,9 @@
     GoalMap = list.foldl((func(G, GM) = map.det_insert(GM, Index, G) :-
         (
             G = hlds_goal(_, GI),
-            goal_info_get_goal_path(GI) = [step_conj(Index0) | _]
+            GoalPath = goal_info_get_goal_path(GI),
+            cord.get_last(GoalPath, LastStep),
+            LastStep = step_conj(Index0)
         ->
             Index = Index0
         ;
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.601
diff -u -r1.601 options.m
--- compiler/options.m	8 Nov 2007 05:00:17 -0000	1.601
+++ compiler/options.m	8 Nov 2007 06:17:06 -0000
@@ -548,6 +548,8 @@
     ;       higher_order_arg_limit
     ;       unneeded_code
     ;       unneeded_code_copy_limit
+    ;       unneeded_code_debug
+    ;       unneeded_code_debug_pred_name
     ;       type_specialization
     ;       user_guided_type_specialization
     ;       introduce_accumulators
@@ -1370,6 +1372,8 @@
     higher_order_arg_limit              -   int(10),
     unneeded_code                       -   bool(no),
     unneeded_code_copy_limit            -   int(10),
+    unneeded_code_debug                 -   bool(no),
+    unneeded_code_debug_pred_name       -   accumulating([]),
     type_specialization                 -   bool(no),
     user_guided_type_specialization     -   bool(no),
     introduce_accumulators              -   bool(no),
@@ -2120,6 +2124,8 @@
 long_option("higher-order-arg-limit",   higher_order_arg_limit).
 long_option("unneeded-code",        unneeded_code).
 long_option("unneeded-code-copy-limit", unneeded_code_copy_limit).
+long_option("unneeded-code-debug",  unneeded_code_debug).
+long_option("unneeded-code-debug-pred-name",  unneeded_code_debug_pred_name).
 long_option("type-specialization",  type_specialization).
 long_option("type-specialisation",  type_specialization).
 long_option("user-guided-type-specialization",
@@ -4411,6 +4417,12 @@
         "\tnot needed. A value of zero forbids goal movement and allows",
         "\tonly goal deletion; a value of one prevents any increase in the",
         "\tsize of the code.",
+%       "--unneeded-code-debug",
+%       "\tPrint progress messages during the unneeded code elimination",
+%       "\tpasses.",
+%       "--unneeded-code-debug-pred-name <predname>",
+%       "\tPrint the definition of <predname> at the start of each pass",
+%       "\tof the unneeded code elimination algorithm.",
         "--introduce-accumulators",
         "\tAttempt to introduce accumulating variables into",
         "\tprocedures, so as to make them tail recursive.",
Index: compiler/ordering_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ordering_mode_constraints.m,v
retrieving revision 1.16
diff -u -r1.16 ordering_mode_constraints.m
--- compiler/ordering_mode_constraints.m	7 Aug 2007 07:10:01 -0000	1.16
+++ compiler/ordering_mode_constraints.m	7 Nov 2007 00:56:08 -0000
@@ -116,10 +116,11 @@
 
 :- import_module bimap.
 :- import_module bool.
+:- import_module cord.
 :- import_module int.
-:- import_module multi_map.
 :- import_module map.
 :- import_module maybe.
+:- import_module multi_map.
 :- import_module pair.
 :- import_module string.
 :- import_module svset.
@@ -583,7 +584,9 @@
     %
 :- pred get_position_in_conj(mc_rep_var::in, conjunct_id::out) is semidet.
 
-get_position_in_conj(_ProgVar `in` _PredId `at` [step_conj(N) | _], N).
+get_position_in_conj(_ProgVar `in` _PredId `at` GoalPath, N) :-
+    cord.get_last(GoalPath, LastStep),
+    LastStep = step_conj(N).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.321
diff -u -r1.321 polymorphism.m
--- compiler/polymorphism.m	20 Aug 2007 03:36:04 -0000	1.321
+++ compiler/polymorphism.m	7 Nov 2007 00:52:28 -0000
@@ -404,6 +404,7 @@
 
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module cord.
 :- import_module int.
 :- import_module map.
 :- import_module pair.
@@ -1008,7 +1009,7 @@
         ActualExistConstraints) :-
     list.length(ExistConstraints, NumExistConstraints),
     (
-        search_hlds_constraint_list(ConstraintMap, unproven, [],
+        search_hlds_constraint_list(ConstraintMap, unproven, empty,
             NumExistConstraints, ActualExistConstraints0)
     ->
         ActualExistConstraints = ActualExistConstraints0
Index: compiler/rbmm.condition_renaming.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rbmm.condition_renaming.m,v
retrieving revision 1.5
diff -u -r1.5 rbmm.condition_renaming.m
--- compiler/rbmm.condition_renaming.m	23 Jul 2007 05:06:13 -0000	1.5
+++ compiler/rbmm.condition_renaming.m	7 Nov 2007 01:14:39 -0000
@@ -127,6 +127,7 @@
 :- import_module transform_hlds.rbmm.points_to_graph.
 :- import_module transform_hlds.smm_common.
 
+:- import_module cord.
 :- import_module int.
 :- import_module list.
 :- import_module pair.
@@ -430,32 +431,35 @@
     set(string)::in, goal_path_regions_table::in,
     goal_path_regions_table::out) is det.
 
-record_non_local_regions([], _, _, !NonLocalRegionProc).
 record_non_local_regions(Path, Created, Removed, !NonLocalRegionProc) :-
-    Path = [Step | Steps],
-    ( Step = step_ite_else ->
-        % The current NonLocalRegions are attached to the goal path to
-        % the corresponding condition.
-        PathToCond = [step_ite_cond | Steps],
-        ( map.search(!.NonLocalRegionProc, PathToCond, NonLocalRegions0) ->
-            set.union(NonLocalRegions0, Created, NonLocalRegions1),
-            set.difference(NonLocalRegions1, Removed, NonLocalRegions)
+    ( cord.split_last(Path, InitialPath, LastStep) ->
+        ( LastStep = step_ite_else ->
+            % The current NonLocalRegions are attached to the goal path to
+            % the corresponding condition.
+            PathToCond = cord.snoc(InitialPath, step_ite_cond),
+            ( map.search(!.NonLocalRegionProc, PathToCond, NonLocalRegions0) ->
+                set.union(NonLocalRegions0, Created, NonLocalRegions1),
+                set.difference(NonLocalRegions1, Removed, NonLocalRegions)
+            ;
+                set.difference(Created, Removed, NonLocalRegions)
+            ),
+            % Only record if some non-local region(s) exist.
+            ( set.empty(NonLocalRegions) ->
+                true
+            ;
+                svmap.set(PathToCond, NonLocalRegions, !NonLocalRegionProc)
+            )
         ;
-            set.difference(Created, Removed, NonLocalRegions)
-        ),
-        % Only record if some non-local region(s) exist.
-        ( set.empty(NonLocalRegions) ->
             true
-        ;
-            svmap.set(PathToCond, NonLocalRegions, !NonLocalRegionProc)
-        )
+        ),
+
+        % Need to update the non-local sets of outer if-then-elses of this one,
+        % if any.
+        record_non_local_regions(InitialPath, Created, Removed,
+            !NonLocalRegionProc)
     ;
         true
-    ),
-
-    % Need to update the non-local sets of outer if-then-elses of this one,
-    % if any.
-    record_non_local_regions(Steps, Created, Removed, !NonLocalRegionProc).
+    ).
 
 :- pred collect_non_local_regions_in_ite_compound_goal(rpt_graph::in,
     pp_region_set_table::in, pp_region_set_table::in,
@@ -605,26 +609,29 @@
 :- pred record_regions_created_in_condition(goal_path::in, set(string)::in,
     goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
-record_regions_created_in_condition([], _, !InCondRegionsProc).
 record_regions_created_in_condition(Path, Created, !InCondRegionsProc) :-
-    Path = [Step | Steps],
-    ( Step = step_ite_cond  ->
-        ( map.search(!.InCondRegionsProc, Path, InCondRegions0) ->
-            set.union(InCondRegions0, Created, InCondRegions)
+    ( cord.split_last(Path, InitialPath, LastStep) ->
+        ( LastStep = step_ite_cond  ->
+            ( map.search(!.InCondRegionsProc, Path, InCondRegions0) ->
+                set.union(InCondRegions0, Created, InCondRegions)
+            ;
+                InCondRegions = Created
+            ),
+            % Only record if some regions are actually created inside
+            % the condition.
+            ( set.empty(InCondRegions) ->
+                true
+            ;
+                svmap.set(Path, InCondRegions, !InCondRegionsProc)
+            )
         ;
-            InCondRegions = Created
-        ),
-        % Only record if the some region(s) is actually created inside
-        % the condition.
-        ( set.empty(InCondRegions) ->
             true
-        ;
-            svmap.set(Path, InCondRegions, !InCondRegionsProc)
-        )
+        ),
+        record_regions_created_in_condition(InitialPath, Created,
+            !InCondRegionsProc)
     ;
         true
-    ),
-    record_regions_created_in_condition(Steps, Created, !InCondRegionsProc).
+    ).
 
 :- pred collect_regions_created_in_condition_compound_goal(rpt_graph::in,
     pp_region_set_table::in, pp_region_set_table::in,
@@ -967,9 +974,9 @@
         !IteRenamingProc).
 
     % This predicate receives a goal path (to some goal) and returns
-    % the subpath to the closest condition containing the goal. It also
-    % returns the number of conditions that contain the goal.
-    % If the goal is in no condition, the output path is empty.
+    % the subpath to the closest condition containing the goal (if any);
+    % if the goal is not in in any condition, the output path is empty.
+    % It also returns the number of conditions that contain the goal.
     % e.g., ( if
     %           ( if
     %               goal
@@ -978,14 +985,19 @@
     %
 :- pred get_closest_condition_in_goal_path(goal_path::in,
     goal_path::out, int::in, int::out) is det.
-get_closest_condition_in_goal_path([], [], !HowMany).
-get_closest_condition_in_goal_path([Step | Steps], PathToCond, !HowMany) :-
-    ( Step = step_ite_cond ->
-        PathToCond = [Step | Steps],
-        get_closest_condition_in_goal_path(Steps, _, !.HowMany, HowMany),
-        !:HowMany = HowMany + 1
+
+get_closest_condition_in_goal_path(Path, PathToCond, !HowMany) :-
+    ( cord.split_last(Path, InitialPath, LastStep) ->
+        ( LastStep = step_ite_cond ->
+            PathToCond = Path,
+            get_closest_condition_in_goal_path(InitialPath, _, !HowMany),
+            !:HowMany = !.HowMany + 1
+        ;
+            get_closest_condition_in_goal_path(InitialPath, PathToCond,
+                !HowMany)
+        )
     ;
-        get_closest_condition_in_goal_path(Steps, PathToCond, !HowMany)
+        PathToCond = empty
     ).
 
 %-----------------------------------------------------------------------------%
@@ -1022,18 +1034,18 @@
 
 collect_ite_annotation_region_names(ExecPaths, Graph, IteRenamingProc,
         PathToCond, RenamedRegions, !IteAnnotationProc) :-
-    (
-        PathToCond = [],
-        unexpected(this_file,
-            "collect_ite_annotation_region_set: empty path to condition.")
-    ;
-        PathToCond = [_ | Steps],
-        PathToThen = [step_ite_then | Steps],
+    ( cord.split_last(PathToCond, InitialSteps, LastStep) ->
+        expect(unify(LastStep, step_ite_cond), this_file,
+            "collect_ite_annotation_region_names: not step_ite_cond"),
+        PathToThen = cord.snoc(InitialSteps, step_ite_then),
         get_closest_condition_in_goal_path(PathToCond, _, 0, HowMany),
         list.foldl(
             collect_ite_annotation_exec_path(Graph, IteRenamingProc,
                 PathToThen, RenamedRegions, HowMany),
             ExecPaths, !IteAnnotationProc)
+    ;
+        unexpected(this_file,
+            "collect_ite_annotation_region_set: empty path to condition.")
     ).
 
 :- pred collect_ite_annotation_exec_path(rpt_graph::in,
@@ -1046,7 +1058,9 @@
         RenamedRegions, HowMany,
         [ProgPoint - _ | ProgPoint_Goals], !IteAnnotationProc) :-
     ProgPoint = pp(_, GoalPath),
-    ( list.append(_, PathToThen, GoalPath) ->
+    PathToThenSteps = cord.list(PathToThen),
+    GoalPathSteps = cord.list(GoalPath),
+    ( list.append(_, PathToThenSteps, GoalPathSteps) ->
         % This is the first goal in the corresponding then branch, we need
         % to introduce reverse renaming at this point.
         set.fold(
Index: compiler/smm_common.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/smm_common.m,v
retrieving revision 1.3
diff -u -r1.3 smm_common.m
--- compiler/smm_common.m	7 Aug 2007 07:10:05 -0000	1.3
+++ compiler/smm_common.m	7 Nov 2007 00:57:36 -0000
@@ -76,6 +76,7 @@
 :- import_module parse_tree.prog_out.
 
 :- import_module bool.
+:- import_module cord.
 :- import_module int.
 :- import_module map.
 
@@ -144,11 +145,10 @@
 	ProgPoint = pp(Context, GoalPath).
 
 dump_program_point(pp(Context, GoalPath), !IO):- 
-    % context
     prog_out.write_context(Context, !IO), 
     io.write_string("--", !IO),
-    % goal path
-    list.foldl(dump_goal_path_step, GoalPath, !IO).
+    GoalPathSteps = cord.list(GoalPath),
+    list.foldl(dump_goal_path_step, GoalPathSteps, !IO).
 
 :- pred dump_goal_path_step(goal_path_step::in, io::di, io::uo) is det.
 
Index: compiler/trace_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trace_gen.m,v
retrieving revision 1.19
diff -u -r1.19 trace_gen.m
--- compiler/trace_gen.m	7 Aug 2007 07:10:07 -0000	1.19
+++ compiler/trace_gen.m	7 Nov 2007 00:59:38 -0000
@@ -256,6 +256,7 @@
 :- import_module parse_tree.prog_type.
 
 :- import_module bool.
+:- import_module cord.
 :- import_module int.
 :- import_module list.
 :- import_module string.
@@ -684,9 +685,9 @@
     (
         MaybeTraceInfo = yes(TraceInfo),
         Goal = hlds_goal(_, GoalInfo),
-        Path = goal_info_get_goal_path(GoalInfo),
+        GoalPath = goal_info_get_goal_path(GoalInfo),
         (
-            Path = [LastStep | _],
+            cord.get_last(GoalPath, LastStep),
             (
                 LastStep = step_switch(_, _),
                 PortPrime = port_switch
@@ -733,7 +734,7 @@
             ;
                 HideEvent = no
             ),
-            generate_event_code(Port, port_info_internal(Path, PreDeaths),
+            generate_event_code(Port, port_info_internal(GoalPath, PreDeaths),
                 yes(TraceInfo), Context, HideEvent, no, _, _, Code, !CI)
         ;
             Code = empty
@@ -834,7 +835,7 @@
     (
         PortInfo = port_info_external,
         LiveVars = LiveVars0,
-        Path = []
+        Path = empty
     ;
         PortInfo = port_info_internal(Path, PreDeaths),
         ResumeVars = code_info.current_resume_point_vars(!.CI),
@@ -851,9 +852,9 @@
         PortInfo = port_info_nondet_foreign_proc,
         LiveVars = [],
         ( Port = port_nondet_foreign_proc_first ->
-            Path = [step_first]
+            Path = cord.singleton(step_first)
         ; Port = port_nondet_foreign_proc_later ->
-            Path = [step_later]
+            Path = cord.singleton(step_later)
         ;
             unexpected(this_file,
                 "generate_event_code: bad nondet foreign_proc port")
Index: compiler/tupling.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/tupling.m,v
retrieving revision 1.40
diff -u -r1.40 tupling.m
--- compiler/tupling.m	10 Oct 2007 14:35:27 -0000	1.40
+++ compiler/tupling.m	7 Nov 2007 01:36:12 -0000
@@ -126,6 +126,7 @@
 
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module cord.
 :- import_module counter.
 :- import_module digraph.
 :- import_module float.
@@ -1911,11 +1912,14 @@
     float::out) is det.
 
 get_disjunct_relative_frequency(ProcCounts, GoalPath, RelFreq) :-
-    ( GoalPath  = [step_disj(Num) | GoalPathRest] ->
+    (
+        cord.split_last(GoalPath, InitialSteps, LastStep),
+        LastStep = step_disj(Num)
+    ->
         get_path_only_count(ProcCounts,
-            [step_disj(Num) | GoalPathRest], DisjCount),
+            cord.snoc(InitialSteps, step_disj(Num)), DisjCount),
         get_path_only_count(ProcCounts,
-            [step_disj(1) | GoalPathRest], FirstDisjCount),
+            cord.snoc(InitialSteps, step_disj(1)), FirstDisjCount),
         ( FirstDisjCount = 0 ->
             RelFreq = 0.0
         ;
@@ -1958,8 +1962,9 @@
 
 :- pred case_in_switch(goal_path::in, path_port::in) is semidet.
 
-case_in_switch([step_switch(_, _) | Prefix],
-    path_only([step_switch(_, _) | Prefix])).
+case_in_switch(GoalPath, path_only(GoalPath)) :-
+    cord.get_last(GoalPath, LastStep),
+    LastStep = step_switch(_, _).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/unneeded_code.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unneeded_code.m,v
retrieving revision 1.43
diff -u -r1.43 unneeded_code.m
--- compiler/unneeded_code.m	7 Aug 2007 07:10:09 -0000	1.43
+++ compiler/unneeded_code.m	7 Nov 2007 14:29:50 -0000
@@ -5,10 +5,10 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
-% 
+%
 % File: unneeded_code.m.
 % Author: zs.
-% 
+%
 % This module implements two related source-to-source transforms,
 % both of which focus on goals that produce some variables, where these
 % variables are not always required by the following computation.
@@ -53,7 +53,7 @@
 % the semantics options explicitly permit the change in the operational
 % semantics, which will usually be an improvement (e.g. avoiding an infinite
 % loop or an unnecessary exception).
-% 
+%
 %-----------------------------------------------------------------------------%
 
 :- module transform_hlds.unneeded_code.
@@ -91,12 +91,14 @@
 
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module cord.
 :- import_module int.
 :- import_module list.
 :- import_module map.
 :- import_module maybe.
 :- import_module pair.
 :- import_module set.
+:- import_module string.
 :- import_module svmap.
 
 %-----------------------------------------------------------------------------%
@@ -225,20 +227,20 @@
         VeryVerbose = yes,
         io.write_string("% Removing dead code in ", !IO),
         hlds_out.write_pred_proc_id_pair(!.ModuleInfo, PredId, ProcId, !IO),
-        io.write_string(": ", !IO),
+        io.write_string(" ...\n", !IO),
         pre_process_proc(!ProcInfo),
-        process_proc(!ProcInfo, !ModuleInfo, Successful),
+        process_proc(!ProcInfo, !ModuleInfo, PredId, 1, Successful),
         (
             Successful = yes,
-            io.write_string("done.\n", !IO)
+            io.write_string("% done.\n", !IO)
         ;
             Successful = no,
-            io.write_string("none found.\n", !IO)
+            io.write_string("% none found.\n", !IO)
         )
     ;
         VeryVerbose = no,
         pre_process_proc(!ProcInfo),
-        process_proc(!ProcInfo, !ModuleInfo, _)
+        process_proc(!ProcInfo, !ModuleInfo, PredId, 1, _)
     ).
 
 :- pred pre_process_proc(proc_info::in, proc_info::out) is det.
@@ -246,13 +248,13 @@
 pre_process_proc(!ProcInfo) :-
     proc_info_get_headvars(!.ProcInfo, HeadVars),
     proc_info_get_goal(!.ProcInfo, Goal0),
-    proc_info_get_varset(!.ProcInfo, Varset0),
+    proc_info_get_varset(!.ProcInfo, VarSet0),
     proc_info_get_vartypes(!.ProcInfo, VarTypes0),
     proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
     implicitly_quantify_clause_body(HeadVars, _Warnings, Goal0, Goal,
-        Varset0, Varset, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
+        VarSet0, VarSet, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
     proc_info_set_goal(Goal, !ProcInfo),
-    proc_info_set_varset(Varset, !ProcInfo),
+    proc_info_set_varset(VarSet, !ProcInfo),
     proc_info_set_vartypes(VarTypes, !ProcInfo),
     proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo).
 
@@ -284,18 +286,19 @@
 
 :- type option_values
     --->    option_values(
-                fully_strict    ::  bool,
-                reorder_conj    ::  bool,
-                copy_limit      ::  int
+                fully_strict    :: bool,
+                reorder_conj    :: bool,
+                copy_limit      :: int,
+                debug           :: bool
             ).
 
 :- pred process_proc(proc_info::in, proc_info::out,
-    module_info::in, module_info::out, bool::out) is det.
+    module_info::in, module_info::out, pred_id::in, int::in, bool::out) is det.
 
-process_proc(!ProcInfo, !ModuleInfo, Successful) :-
+process_proc(!ProcInfo, !ModuleInfo, PredId, Pass, Successful) :-
     fill_goal_path_slots(!.ModuleInfo, !ProcInfo),
     proc_info_get_goal(!.ProcInfo, Goal0),
-    proc_info_get_varset(!.ProcInfo, Varset0),
+    proc_info_get_varset(!.ProcInfo, VarSet0),
     proc_info_get_vartypes(!.ProcInfo, VarTypes0),
     proc_info_get_initial_instmap(!.ProcInfo, !.ModuleInfo, InitInstMap),
     Goal0 = hlds_goal(_, GoalInfo0),
@@ -312,7 +315,35 @@
     globals.lookup_bool_option(Globals, reorder_conj, ReorderConj),
     globals.lookup_bool_option(Globals, fully_strict, FullyStrict),
     globals.lookup_int_option(Globals, unneeded_code_copy_limit, Limit),
-    Options = option_values(FullyStrict, ReorderConj, Limit),
+    globals.lookup_bool_option(Globals, unneeded_code_debug, Debug),
+    Options = option_values(FullyStrict, ReorderConj, Limit, Debug),
+    (
+        Debug = no
+    ;
+        Debug = yes,
+        trace [io(!IO)] (
+            module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
+            PredName = pred_info_name(PredInfo),
+            globals.lookup_accumulating_option(Globals,
+                unneeded_code_debug_pred_name, DebugPredNames),
+            (
+                DebugPredNames = [],
+                io.format("%% Starting unneededed code pass %d\n",
+                    [i(Pass)], !IO)
+            ;
+                DebugPredNames = [_ | _],
+                ( list.member(PredName, DebugPredNames) ->
+                    io.format("%% Starting unneededed code pass %d\n",
+                        [i(Pass)], !IO),
+                    AppendVarNums = yes,
+                    hlds_out.write_goal(Goal0, !.ModuleInfo, VarSet0,
+                        AppendVarNums, 0, ".\n", !IO)
+                ;
+                    true
+                )
+            )
+        )
+    ),
     process_goal(Goal0, Goal1, InitInstMap, FinalInstMap, VarTypes0,
         !.ModuleInfo, Options, WhereNeededMap1, _, map.init, RefinedGoals1,
         no, Changed),
@@ -327,15 +358,19 @@
         proc_info_get_inst_varset(!.ProcInfo, InstVarSet),
         proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
         implicitly_quantify_clause_body(HeadVars, _Warnings,
-            Goal2, Goal3, Varset0, Varset, VarTypes0, VarTypes,
+            Goal2, Goal3, VarSet0, VarSet, VarTypes0, VarTypes,
             RttiVarMaps0, RttiVarMaps),
         recompute_instmap_delta(no, Goal3, Goal, VarTypes, InstVarSet,
             InitInstMap, !ModuleInfo),
         proc_info_set_goal(Goal, !ProcInfo),
-        proc_info_set_varset(Varset, !ProcInfo),
+        proc_info_set_varset(VarSet, !ProcInfo),
         proc_info_set_vartypes(VarTypes, !ProcInfo),
         proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo),
-        process_proc(!ProcInfo, !ModuleInfo, _),
+        ( Pass > 3 ->
+            true
+        ;
+            process_proc(!ProcInfo, !ModuleInfo, PredId, Pass + 1, _)
+        ),
         Successful = yes
     ;
         Changed = no,
@@ -363,7 +398,21 @@
         list.foldl(insert_branch_into_refined_goals(Goal0), BranchList,
             !RefinedGoals),
         Goal = true_goal,
-        !:Changed = yes
+        !:Changed = yes,
+
+        Debug = Options ^ debug,
+        (
+            Debug = no
+        ;
+            Debug = yes,
+            Goal0 = hlds_goal(_GoalExpr0, GoalInfo0),
+            GoalPath0 = goal_info_get_goal_path(GoalInfo0),
+            GoalPathStr0 = goal_path_to_string(GoalPath0),
+            trace [io(!IO)] (
+                io.format("unneeded code at goal path %s\n", [s(GoalPathStr0)],
+                    !IO)
+            )
+        )
     ),
     undemand_virgin_outputs(Goal0, ModuleInfo, InitInstMap, !WhereNeededMap),
     ( goal_get_purity(Goal) = purity_impure ->
@@ -620,8 +669,8 @@
         (
             Cases0 = [case(_, hlds_goal(_, FirstCaseGoalInfo)) | _],
             FirstCaseGoalPath = goal_info_get_goal_path(FirstCaseGoalInfo),
-            FirstCaseGoalPath = [SwitchStep | _],
-            SwitchStep = step_switch(_, MaybeNumAltPrime)
+            cord.get_last(FirstCaseGoalPath, FirstCaseLastStep),
+            FirstCaseLastStep = step_switch(_, MaybeNumAltPrime)
         ->
             MaybeNumAlt = MaybeNumAltPrime
         ;
@@ -1050,7 +1099,7 @@
 
 where_needed_branches_upper_bound(CurrentPath, BranchesA, BranchesB,
         WhereNeeded) :-
-    % should select smaller map to convert to list
+    % Should select smaller map to convert to list.
     map.to_assoc_list(BranchesA, BranchesList),
     where_needed_branches_upper_bound_2(CurrentPath,
         BranchesList, BranchesB, WhereNeeded).
@@ -1070,13 +1119,14 @@
         ( branch_point_is_complete(BranchAlts, Alts) ->
             (
                 get_parent_branch_point(GoalPath,
-                    ParentGoalPath, ParentGoalPathStep,
+                    ParentGoalInitialPath, ParentGoalPathStep,
                     ParentBranchAlt, ParentBranchNum),
-                \+ list.remove_suffix(CurrentPath,
-                    [ParentGoalPathStep | ParentGoalPath], _)
+                ParentGoalPath = cord.snoc(ParentGoalInitialPath,
+                    ParentGoalPathStep),
+                \+ goal_path_inside(ParentGoalPath, CurrentPath)
             ->
                 map.delete(Branches0, BranchPoint, Branches1),
-                ParentBranchPoint = branch_point(ParentGoalPath,
+                ParentBranchPoint = branch_point(ParentGoalInitialPath,
                     ParentBranchAlt),
                 set.singleton_set(ParentAlts, ParentBranchNum),
                 where_needed_branches_upper_bound_2(CurrentPath,
@@ -1099,25 +1149,27 @@
 :- pred get_parent_branch_point(goal_path::in, goal_path::out,
     goal_path_step::out, branch_alts::out, int::out) is semidet.
 
-get_parent_branch_point([First | Rest], Parent, ParentStep,
+get_parent_branch_point(GoalPath, ParentPath, ParentStep,
         BranchAlt, BranchNum) :-
-    ( First = step_switch(Arm, MaybeNumAlts) ->
-        Parent = Rest,
-        ParentStep = First,
+    cord.split_last(GoalPath, InitialPath, LastStep),
+    ( LastStep = step_switch(Arm, MaybeNumAlts) ->
+        ParentPath = InitialPath,
+        ParentStep = LastStep,
         BranchAlt = alt_switch(MaybeNumAlts),
         BranchNum = Arm
-    ; First = step_ite_then ->
-        Parent = Rest,
-        ParentStep = First,
+    ; LastStep = step_ite_then ->
+        ParentPath = InitialPath,
+        ParentStep = LastStep,
         BranchAlt = alt_ite,
         BranchNum = 1
-    ; First = step_ite_else ->
-        Parent = Rest,
-        ParentStep = First,
+    ; LastStep = step_ite_else ->
+        ParentPath = InitialPath,
+        ParentStep = LastStep,
         BranchAlt = alt_ite,
         BranchNum = 2
     ;
-        get_parent_branch_point(Rest, Parent, ParentStep, BranchAlt, BranchNum)
+        get_parent_branch_point(InitialPath, ParentPath, ParentStep,
+            BranchAlt, BranchNum)
     ).
 
 :- pred branch_point_is_complete(branch_alts::in, set(int)::in) is semidet.
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/cord.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/cord.m,v
retrieving revision 1.9
diff -u -r1.9 cord.m
--- library/cord.m	10 Sep 2007 04:42:36 -0000	1.9
+++ library/cord.m	7 Nov 2007 03:01:48 -0000
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+% vim: ft=mercury ts=4 sw=4 et
 %---------------------------------------------------------------------------%
 % Copyright (C) 2002-2007 The University of Melbourne.
 % This file may only be copied under the terms of the GNU Library General
@@ -55,6 +55,10 @@
     %
 :- func empty = cord(T).
 
+    % Succeed iff the given cord is empty.
+    %
+:- pred is_empty(cord(T)::in) is semidet.
+
     % list(singleton(X)) = [X]
     %
 :- func singleton(T) = cord(T).
@@ -86,6 +90,23 @@
     %
 :- pred head_tail(cord(T)::in, T::out, cord(T)::out) is semidet.
 
+    %     split_last(C0, C, X)  =>  list(C0) = C ++ [X].
+    % not split_last(C0, _, _)  =>  C0 = empty
+    % An O(n) operation, although traversing an entire cord with
+    % split_last/3 gives O(1) amortized cost for each call.
+    %
+:- pred split_last(cord(T)::in, cord(T)::out, T::out) is semidet.
+
+    %     get_first(C0, X)  =>  some [C]: list(C0) = [X] ++ C.
+    % not get_first(C0, _)  =>  C0 = empty
+    %
+:- pred get_first(cord(T)::in, T::out) is semidet.
+
+    %     get_last(C0, X)  =>  some [C]: list(C0) = C ++ [X].
+    % not get_last(C0, _)  =>  C0 = empty
+    %
+:- pred get_last(cord(T)::in, T::out) is semidet.
+
     % length(C) = list.length(list(C))
     % An O(n) operation.
     %
@@ -120,6 +141,7 @@
 :- implementation.
 
 :- import_module int.
+:- import_module require.
 
     % We impose the following invariants to ensure we have a unique
     % representation for the empty cord (this makes the implementation
@@ -141,6 +163,10 @@
 
 %-----------------------------------------------------------------------------%
 
+is_empty(nil).
+
+%-----------------------------------------------------------------------------%
+
 singleton(X) = leaf(X).
 
 %-----------------------------------------------------------------------------%
@@ -175,15 +201,83 @@
 
 %-----------------------------------------------------------------------------%
 
-head_tail(leaf(X),          X, nil ).
-head_tail(leaves([X | Xs]), X, C   ) :-
+head_tail(leaf(X),          X, nil).
+head_tail(leaves([X | Xs]), X, C  ) :-
     C = ( if Xs = [] then nil else leaves(Xs) ).
-head_tail(branch(CA0, CB),  X, C   ) :-
+head_tail(branch(CA0, CB),  X, C  ) :-
     head_tail(CA0, X, CA),
     C = CA ++ CB.
 
 %-----------------------------------------------------------------------------%
 
+split_last(leaf(X),         nil, X).
+split_last(leaves(Xs0),     C,   X) :-
+    split_list_last(Xs0, C, X).
+split_last(branch(CA, CB0), C,   X) :-
+    split_last(CB0, CB, X),
+    C = CA ++ CB.
+
+    % split_list_last(Xs0, C, X):
+    %
+    % Given a nonempty list Xs0, returns its last element as X and all the
+    % elements before it as the cord C. This has a similar effect to
+    %
+    %   list.split_last(Xs0, Xs, X),
+    %   C = ( if Xs = [] then nil else leaves(Xs) ).
+    %
+    % but while repeatedly taking the last element of a list is an O(n^2)
+    % operation (since a list is a right stick), we return C as a left stick,
+    % on which repeatedly taking the last element of a list is an O(n)
+    % operation. This ensures O(1) amortized cost for each call to
+    % split_last/3 when an entire cord is traversed with that predicate.
+    % 
+:- pred split_list_last(list(T)::in, cord(T)::out, T::out) is det.
+
+split_list_last([], _, _) :-
+    % This violates the invariant that an empty cord is represented by nil,
+    % not by leaves([]).
+    error("cord.m: split_list_last finds []").
+split_list_last([H | T], InitialCord, Last) :-
+    (
+        T = [],
+        InitialCord = nil,
+        Last = H
+    ;
+        T = [TH | TT],
+        split_list_last_2(leaf(H), TH, TT, InitialCord, Last)
+    ).
+
+:- pred split_list_last_2(cord(T)::in, T::in, list(T)::in,
+    cord(T)::out, T::out) is det.
+
+split_list_last_2(BeforeCord, H, T, InitialCord, Last) :-
+    (
+        T = [],
+        InitialCord = BeforeCord,
+        Last = H
+    ;
+        T = [TH | TT],
+        split_list_last_2(BeforeCord ++ leaf(H), TH, TT, InitialCord, Last)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+get_first(leaf(X),         X).
+get_first(leaves(Xs),      X) :-
+    Xs = [X | _].
+get_first(branch(CA, _CB), X) :-
+    get_first(CA, X).
+
+%-----------------------------------------------------------------------------%
+
+get_last(leaf(X),         X).
+get_last(leaves(Xs),      X) :-
+    list.last(Xs, X).
+get_last(branch(_CA, CB), X) :-
+    get_last(CB, X).
+
+%-----------------------------------------------------------------------------%
+
 length(C) = foldl(func(_, N) = N + 1, C, 0).
 
 %-----------------------------------------------------------------------------%
cvs diff: Diffing mdbcomp
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.26
diff -u -r1.26 program_representation.m
--- mdbcomp/program_representation.m	31 Oct 2007 12:13:58 -0000	1.26
+++ mdbcomp/program_representation.m	8 Nov 2007 10:47:45 -0000
@@ -40,6 +40,7 @@
 
 :- import_module bool.
 :- import_module char.
+:- import_module cord.
 :- import_module io.
 :- import_module list.
 :- import_module maybe.
@@ -285,15 +286,17 @@
 % the second number won't be present.)
 %
 % The goal_path type gives the sequence of steps from the root to the given
-% goal *in reverse order*, so that the step closest to the root is last.
-% (Keeping the list in reverse order makes the common operations constant-time
-% instead of linear in the length of the list.)
+% goal. We use a cord instead of a list because most operations on goal paths
+% focus on the last element, not the first.
+%
+% NOTE: Comparing two cords for equality should be done by calling cord.equal,
+% not by unifying them directly.
 
-:- type goal_path == list(goal_path_step).
+:- type goal_path == cord(goal_path_step).
 
 :- type goal_path_string == string.
 
-:- type goal_path_step 
+:- type goal_path_step
     --->    step_conj(int)
     ;       step_disj(int)
     ;       step_switch(int, maybe(int))
@@ -310,27 +313,36 @@
     --->    scope_is_cut
     ;       scope_is_no_cut.
 
-    % No reversing of the goal path steps is done by this predicate.
+    % goal_path_inside(PathA, PathB):
+    %
+    % Succeed if PathB denotes a goal *inside* the goal denoted by PathA.
+    % (It considers a goal to be inside itself.)
     %
-:- pred path_from_string_det(string::in, goal_path::out) is det.
+:- pred goal_path_inside(goal_path::in, goal_path::in) is semidet.
 
-    % This reverses the steps before converting them to a string.
+    % Converts a string to a goal path, failing if the string is not a valid
+    % goal path.
     %
-:- func goal_path_to_string(goal_path) = string.
+:- pred goal_path_from_string(string::in, goal_path::out) is semidet.
 
-    % This leaves the steps in the order in which they appear in goal_path;
-    % if the steps are reversed in the goal_path (as usual), the end result
-    % will be reversed too.
+    % Converts a string to a goal path, aborting if the string is not a valid
+    % goal path.
     %
-:- func string_from_path(goal_path) = string.
+:- pred goal_path_from_string_det(string::in, goal_path::out) is det.
 
-    % No reversing of the goal path steps is done by this predicate.
+    % Converts a string to a goal path step, failing if the string is not
+    % a valid goal path step.
     %
-:- pred path_from_string(string::in, goal_path::out) is semidet.
+:- pred goal_path_step_from_string(string::in, goal_path_step::out) is semidet.
 
-:- pred path_step_from_string(string::in, goal_path_step::out) is semidet.
+    % Convert the goal path to its string representation. The resulting string
+    % is guaranteed to be acceptable to path_from_string_det.
+    %
+:- func goal_path_to_string(goal_path) = string.
 
-:- pred is_path_separator(char::in) is semidet.
+    % Is this character the one that ends each goal path step?
+    %
+:- pred is_goal_path_separator(char::in) is semidet.
 
     % User-visible head variables are represented by a number from 1..N,
     % where N is the user-visible arity.
@@ -354,9 +366,10 @@
 
     % A particular subterm within a term is represented by a term_path.
     % This is the list of argument positions that need to be followed
-    % in order to travel from the root to the subterm. In contrast to
-    % goal_paths, this list is in top-down order.
-:- type term_path ==    list(int).
+    % in order to travel from the root to the subterm. This list is in
+    % top-down order (i.e. the argument number in the top function symbol
+    % is first).
+:- type term_path == list(int).
 
     % Returns type_of(_ : proc_defn_rep), for use in C code.
     %
@@ -492,7 +505,7 @@
         SymModuleName = string_to_sym_name(ModuleName),
         non_traced_mercury_builtin_module(SymModuleName)
     ;
-        % The debugger cannot handle calls to polymorphic builtins that 
+        % The debugger cannot handle calls to polymorphic builtins that
         % do not take a type_info argument, so such calls are not traced.
         SymModuleName = string_to_sym_name(ModuleName),
         no_type_info_builtin(SymModuleName, PredName, Arity)
@@ -546,29 +559,35 @@
 
 %-----------------------------------------------------------------------------%
 
-path_from_string_det(GoalPathStr, GoalPath) :-
-    ( path_from_string(GoalPathStr, GoalPathPrime) ->
+goal_path_inside(PathA, PathB) :-
+    StepsA = cord.list(PathA),
+    StepsB = cord.list(PathB),
+    list.append(StepsA, _, StepsB).
+
+goal_path_from_string_det(GoalPathStr, GoalPath) :-
+    ( goal_path_from_string(GoalPathStr, GoalPathPrime) ->
         GoalPath = GoalPathPrime
     ;
         error("path_from_string_det: path_from_string failed")
     ).
 
-path_from_string(GoalPathStr, GoalPath) :-
-    StepStrs = string.words_separator(is_path_separator, GoalPathStr),
-    list.map(path_step_from_string, StepStrs, GoalPath).
+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 = cord.from_list(Steps).
 
-path_step_from_string(String, Step) :-
+goal_path_step_from_string(String, Step) :-
     string.first_char(String, First, Rest),
-    path_step_from_string_2(First, Rest, Step).
+    goal_path_step_from_string_2(First, Rest, Step).
 
-:- pred path_step_from_string_2(char::in, string::in, goal_path_step::out)
+:- pred goal_path_step_from_string_2(char::in, string::in, goal_path_step::out)
     is semidet.
 
-path_step_from_string_2('c', NStr, step_conj(N)) :-
+goal_path_step_from_string_2('c', NStr, step_conj(N)) :-
     string.to_int(NStr, N).
-path_step_from_string_2('d', NStr, step_disj(N)) :-
+goal_path_step_from_string_2('d', NStr, step_disj(N)) :-
     string.to_int(NStr, N).
-path_step_from_string_2('s', Str, step_switch(N, MaybeM)) :-
+goal_path_step_from_string_2('s', Str, step_switch(N, MaybeM)) :-
     string.words_separator(unify('-'), Str) = [NStr, MStr],
     string.to_int(NStr, N),
     % "na" is short for "not applicable"
@@ -578,23 +597,21 @@
         string.to_int(MStr, M),
         MaybeM = yes(M)
     ).
-path_step_from_string_2('?', "", step_ite_cond).
-path_step_from_string_2('t', "", step_ite_then).
-path_step_from_string_2('e', "", step_ite_else).
-path_step_from_string_2('~', "", step_neg).
-path_step_from_string_2('q', "!", step_scope(scope_is_cut)).
-path_step_from_string_2('q', "", step_scope(scope_is_no_cut)).
-path_step_from_string_2('f', "", step_first).
-path_step_from_string_2('l', "", step_later).
-
-is_path_separator(';').
-
-goal_path_to_string(GoalPath) =
-    string.append_list(list.map(goal_path_step_to_string,
-        list.reverse(GoalPath))).
-
-string_from_path(GoalPath) =
-    string.append_list(list.map(goal_path_step_to_string, GoalPath)).
+goal_path_step_from_string_2('?', "", step_ite_cond).
+goal_path_step_from_string_2('t', "", step_ite_then).
+goal_path_step_from_string_2('e', "", step_ite_else).
+goal_path_step_from_string_2('~', "", step_neg).
+goal_path_step_from_string_2('q', "!", step_scope(scope_is_cut)).
+goal_path_step_from_string_2('q', "", step_scope(scope_is_no_cut)).
+goal_path_step_from_string_2('f', "", step_first).
+goal_path_step_from_string_2('l', "", step_later).
+
+is_goal_path_separator(';').
+
+goal_path_to_string(GoalPath) = GoalPathStr :-
+    Steps = cord.list(GoalPath),
+    StepStrs = list.map(goal_path_step_to_string, Steps),
+    string.append_list(StepStrs, GoalPathStr).
 
 :- func goal_path_step_to_string(goal_path_step) = string.
 
@@ -699,7 +716,7 @@
 #if defined(MR_HAVE_SYS_STAT_H) && \
     defined(MR_HAVE_STAT) && \
     defined(MR_HAVE_OPEN)
-    
+
     struct  stat statbuf;
 
     if (stat(FileName, &statbuf) != 0) {
Index: mdbcomp/rtti_access.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/rtti_access.m,v
retrieving revision 1.11
diff -u -r1.11 rtti_access.m
--- mdbcomp/rtti_access.m	12 Sep 2007 06:21:14 -0000	1.11
+++ mdbcomp/rtti_access.m	7 Nov 2007 12:41:22 -0000
@@ -222,11 +222,7 @@
 get_path_port_from_label_layout(Label) = PathPort :-
     Port = get_port_from_label_layout(Label),
     GoalPathStr = get_goal_path_from_label_layout(Label),
-    ( path_from_string(GoalPathStr, ValidGoalPath) ->
-        GoalPath = ValidGoalPath
-    ;
-        error("get_path_port_from_label_layout: invalid goal path")
-    ),
+    goal_path_from_string_det(GoalPathStr, GoalPath),
     PathPort = make_path_port(GoalPath, Port).
 
 %-----------------------------------------------------------------------------%
Index: mdbcomp/slice_and_dice.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/slice_and_dice.m,v
retrieving revision 1.15
diff -u -r1.15 slice_and_dice.m
--- mdbcomp/slice_and_dice.m	31 Jul 2007 05:48:20 -0000	1.15
+++ mdbcomp/slice_and_dice.m	7 Nov 2007 12:42:27 -0000
@@ -906,12 +906,12 @@
 
 format_path_port(port_only(Port)) = Str :-
     mdbcomp.trace_counts.string_to_trace_port(Str, Port).
-format_path_port(path_only(Path)) = "<" ++ string_from_path(Path) ++ ">".
+format_path_port(path_only(Path)) = "<" ++ goal_path_to_string(Path) ++ ">".
 format_path_port(port_and_path(Port, Path)) =
     format_path_port(port_only(Port)) ++ " " ++
         format_path_port(path_only(Path)).
 
 :- func format_context(string, int) = string.
 
-format_context(FileName, LineNumber) =
-        FileName ++ ":" ++ int_to_string(LineNumber).
+format_context(FileName, LineNumber) = Str :-
+    Str = FileName ++ ":" ++ int_to_string(LineNumber).
Index: mdbcomp/trace_counts.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/trace_counts.m,v
retrieving revision 1.21
diff -u -r1.21 trace_counts.m
--- mdbcomp/trace_counts.m	2 May 2007 02:16:00 -0000	1.21
+++ mdbcomp/trace_counts.m	7 Nov 2007 12:43:10 -0000
@@ -711,7 +711,7 @@
     string.suffix(String, ">"),
     string.length(String, Length),
     string.substring(String, 1, Length-2, SubString),
-    path_from_string(SubString, Path).
+    goal_path_from_string(SubString, Path).
 
     % This function should be kept in sync with the MR_named_count_port array
     % in runtime/mercury_trace_base.c.
@@ -902,7 +902,7 @@
 write_path_port_count(path_only(Path),
         line_no_and_count(LineNo, ExecCount, NumTests), !IO) :-
     io.write_strings([
-        "<", string_from_path(Path), "> ",
+        "<", goal_path_to_string(Path), "> ",
         int_to_string(LineNo), " ",
         int_to_string(ExecCount), " ",
         int_to_string(NumTests), "\n"], !IO).
@@ -910,7 +910,7 @@
         line_no_and_count(LineNo, ExecCount, NumTests), !IO) :-
     string_to_trace_port(PortStr, Port),
     io.write_strings([
-        PortStr, " <", string_from_path(Path), "> ",
+        PortStr, " <", goal_path_to_string(Path), "> ",
         int_to_string(LineNo), " ",
         int_to_string(ExecCount), " ",
         int_to_string(NumTests), "\n"], !IO).
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
Index: slice/mcov.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/slice/mcov.m,v
retrieving revision 1.5
diff -u -r1.5 mcov.m
--- slice/mcov.m	19 Jan 2007 07:05:06 -0000	1.5
+++ slice/mcov.m	7 Nov 2007 12:55:06 -0000
@@ -338,10 +338,10 @@
     string_to_trace_port(PortStr, Port),
     io.write_string(PortStr, !IO).
 write_path_port_for_user(path_only(Path), !IO) :-
-    io.write_strings(["<", string_from_path(Path), ">"], !IO).
+    io.write_strings(["<", goal_path_to_string(Path), ">"], !IO).
 write_path_port_for_user(port_and_path(Port, Path), !IO) :-
     string_to_trace_port(PortStr, Port),
-    io.write_strings([PortStr, " <", string_from_path(Path), ">"], !IO).
+    io.write_strings([PortStr, " <", goal_path_to_string(Path), ">"], !IO).
 
 %-----------------------------------------------------------------------------%
 
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list