[m-rev.] Re: Changes to goal_path representation.

Paul Bone pbone at csse.unimelb.edu.au
Thu Sep 4 14:14:01 AEST 2008


On Mon, Sep 01, 2008 at 10:41:21PM +1000, Paul Bone wrote:
> 
> For review by anyone,
> 
> Please let me know if you think the names for the new goal_rep
> predicates in program_representation.m are okay.
> 
> I've bootchecked in asm_fast.gc and asm_fast.gc.decldebug, and
> asm_fast.gc.rbmm is running at the moment.
> 
> Estimated time taken: 3
> Branches: main
> 
> Store goal paths as a reverse-sorted list rather than a cord.  This ensures
> they are safe for use as keys in maps since their semantic and structual
> representations are the same.  Goal paths are now an abstract type, make it
> easy to change their representation in the future.
> 
> Modules in the program representation, and procedures in the module
> representation are now stored in maps.
> 

After some feedback from Zoltan I've updated the diff to use
clearer function and procedure names for the goal path procedures.

Index: browser/declarative_tree.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_tree.m,v
retrieving revision 1.58
diff -u -r1.58 declarative_tree.m
--- browser/declarative_tree.m	28 Aug 2008 10:26:14 -0000	1.58
+++ browser/declarative_tree.m	3 Sep 2008 05:09:36 -0000
@@ -910,8 +910,9 @@
     HeadVars = ProcDefnRep ^ pdr_head_vars,
     GoalRep = ProcDefnRep ^ pdr_goal,
     is_traced_grade(AllTraced),
-    MaybePrims = make_primitive_list(Store, [goal_and_path(GoalRep, empty)],
-        Contour, StartPath, ArgNum, TotalArgs, HeadVars, AllTraced, []),
+    MaybePrims = make_primitive_list(Store, 
+        [goal_and_path(GoalRep, empty_goal_path)], Contour, StartPath, ArgNum,
+        TotalArgs, HeadVars, AllTraced, []),
     (
         MaybePrims = yes(primitive_list_and_var(Primitives, Var,
             MaybeClosure)),
@@ -1246,7 +1247,7 @@
             Primitives0)
     ;
         GoalExpr = scope_rep(InnerGoal, MaybeCut),
-        InnerPath = cord.snoc(Path, step_scope(MaybeCut)),
+        InnerPath = goal_path_add_at_end(Path, step_scope(MaybeCut)),
         InnerAndPath = goal_and_path(InnerGoal, InnerPath),
         MaybePrims = make_primitive_list(Store, [InnerAndPath | GoalPaths],
             Contour, MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced,
@@ -1278,8 +1279,8 @@
             ),
             DisjPathStr = get_goal_path_from_label_layout(Label),
             goal_path_from_string_det(DisjPathStr, DisjPath),
-            cord.split_last(DisjPath, DisjInitialPath, DisjLastStep),
-            cord.equal(DisjInitialPath, Path),
+            goal_path_remove_last(DisjPath, DisjInitialPath, DisjLastStep),
+            DisjInitialPath = Path,
             DisjLastStep = step_disj(N)
         ->
             list.index1_det(Disjs, N, Disj),
@@ -1298,8 +1299,8 @@
             ContourHeadNode = node_switch(_, Label),
             ArmPathStr = get_goal_path_from_label_layout(Label),
             goal_path_from_string_det(ArmPathStr, ArmPath),
-            cord.split_last(ArmPath, ArmInitialPath, ArmLastStep),
-            cord.equal(ArmInitialPath, Path),
+            goal_path_remove_last(ArmPath, ArmInitialPath, ArmLastStep),
+            ArmInitialPath = Path,
             ArmLastStep = step_switch(N, _)
         ->
             list.index1_det(Cases, N, Case),
@@ -1319,11 +1320,11 @@
             ContourHeadNode = node_cond(_, Label, _),
             CondPathStr = get_goal_path_from_label_layout(Label),
             goal_path_from_string_det(CondPathStr, CondPath),
-            cord.split_last(CondPath, CondInitialPath, CondLastStep),
-            cord.equal(CondInitialPath, Path),
+            goal_path_remove_last(CondPath, CondInitialPath, CondLastStep),
+            CondInitialPath = Path,
             CondLastStep = step_ite_cond
         ->
-            ThenPath = cord.snoc(Path, step_ite_then),
+            ThenPath = goal_path_add_at_end(Path, step_ite_then),
             CondAndPath = goal_and_path(Cond, CondPath),
             ThenAndPath = goal_and_path(Then, ThenPath),
             MaybePrims = make_primitive_list(Store,
@@ -1336,11 +1337,11 @@
             CondNode = node_cond(_, Label, _),
             CondPathStr = get_goal_path_from_label_layout(Label),
             goal_path_from_string_det(CondPathStr, CondPath),
-            cord.split_last(CondPath, CondInitialPath, CondLastStep),
-            cord.equal(CondInitialPath, Path),
+            goal_path_remove_last(CondPath, CondInitialPath, CondLastStep),
+            CondInitialPath = Path,
             CondLastStep = step_ite_cond
         ->
-            ElsePath = cord.snoc(Path, step_ite_else),
+            ElsePath = goal_path_add_at_end(Path, step_ite_else),
             ElseAndPath = goal_and_path(Else, ElsePath),
             MaybePrims = make_primitive_list(Store, [ElseAndPath | GoalPaths],
                 ContourTail, MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced,
@@ -1364,7 +1365,7 @@
         ->
             % The end of the primitive list is somewhere inside
             % NegGoal.
-            NegPath = cord.snoc(Path, step_neg),
+            NegPath = goal_path_add_at_end(Path, step_neg),
             NegAndPath = goal_and_path(NegGoal, NegPath),
             MaybePrims = make_primitive_list(Store, [NegAndPath], ContourTail,
                 MaybeEnd, ArgNum, TotalArgs, HeadVars, AllTraced, Primitives0)
@@ -1800,7 +1801,7 @@
 add_paths_to_conjuncts([], _, _, []).
 add_paths_to_conjuncts([Goal | Goals], ParentPath, N,
         [goal_and_path(Goal, Path) | GoalAndPaths]) :-
-    Path = cord.snoc(ParentPath, step_conj(N)),
+    Path = goal_path_add_at_end(ParentPath, step_conj(N)),
     add_paths_to_conjuncts(Goals, ParentPath, N + 1, GoalAndPaths).
 
 %-----------------------------------------------------------------------------%
Index: compiler/build_mode_constraints.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/build_mode_constraints.m,v
retrieving revision 1.31
diff -u -r1.31 build_mode_constraints.m
--- compiler/build_mode_constraints.m	27 Feb 2008 07:23:02 -0000	1.31
+++ compiler/build_mode_constraints.m	31 Aug 2008 00:35:19 -0000
@@ -285,7 +285,8 @@
     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, empty, _, !VarInfo).
+    prog_var_at_path(ProgVarset, PredId, HeadVar, empty_goal_path, _,
+        !VarInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -374,7 +375,7 @@
         % Temporarily form the disjunction implied by the goal path
         % annotations.
         MainGoal = disj(Goals),
-        HeadGoalPath = empty,
+        HeadGoalPath = empty_goal_path,
         Nonlocals = proc_arg_vector_to_set(HeadVars),
         add_goal_expr_constraints(ModuleInfo, ProgVarset, PredId, MainGoal,
             Context, HeadGoalPath, Nonlocals, !VarInfo, !Constraints)
@@ -683,7 +684,8 @@
     % 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, empty)),
+        list.map(list.map(
+                lookup_prog_var_at_path(VarMap, PredId, empty_goal_path)),
             HeadVarsList),
 
     % Make the constraints for each declaration.
@@ -703,7 +705,8 @@
     proc_info_get_varset(ProcInfo, ProgVarset),
     proc_info_get_context(ProcInfo, Context),
 
-    prog_vars_at_path(ProgVarset, PredId, Args, empty, ArgsAtHead, !VarInfo),
+    prog_vars_at_path(ProgVarset, PredId, Args, empty_goal_path, ArgsAtHead, 
+        !VarInfo),
 
     DeclConstraints = mode_decl_constraints(ModuleInfo, ArgsAtHead, Decl),
 
@@ -776,7 +779,7 @@
 
 add_call_headvar_constraints(ProgVarset, Context, GoalPath, CallerPredId,
         CallArgs, CalleePredId, CalleeHeadVars, !VarInfo, !Constraints) :-
-    prog_vars_at_path(ProgVarset, CalleePredId, CalleeHeadVars, empty,
+    prog_vars_at_path(ProgVarset, CalleePredId, CalleeHeadVars, empty_goal_path,
         HeadVarsAtHead, !VarInfo),
     prog_vars_at_path(ProgVarset, CallerPredId, CallArgs, GoalPath,
         CallArgsHere, !VarInfo),
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.76
diff -u -r1.76 deep_profiling.m
--- compiler/deep_profiling.m	25 Aug 2008 06:01:51 -0000	1.76
+++ compiler/deep_profiling.m	3 Sep 2008 04:39:15 -0000
@@ -540,7 +540,7 @@
             counter.init(0), [], !.VarInfo, FileName, MaybeRecInfo),
 
         % This call transforms the goals of the procedure.
-        deep_prof_transform_goal(empty, Goal0, Goal1, _,
+        deep_prof_transform_goal(empty_goal_path, Goal0, Goal1, _,
             DeepInfo0, DeepInfo),
         !:VarInfo = DeepInfo ^ deep_varinfos,
         CallSites = DeepInfo ^ deep_call_sites,
@@ -613,8 +613,13 @@
     proc_info_set_goal(Goal, !ProcInfo),
     record_hlds_proc_static(ProcStatic, ExcpVars, !ProcInfo).
 
-% Wrap the procedure body in the deep profiling port goals.
 
+    % Wrap the procedure body in the deep profiling port goals.
+    %
+    % When modifing this transformation be sure to modify original_root/3 in
+    % deep_profiler/program_represetntation_utils.m which must be able to undo
+    % this transformation.
+    %
 :- pred build_det_proc_body(module_info::in, prog_var::in, prog_var::in,
     prog_var::in, maybe(prog_var)::in, hlds_goal_info::in, hlds_goal::in,
     hlds_goal::in, hlds_goal::out) is det.
@@ -650,6 +655,11 @@
     ]),
     Goal = hlds_goal(GoalExpr, GoalInfo).
 
+    % Wrap the goal for a semidet procedure,
+    %
+    % If changing this transformation be sure to change original_root/3 in
+    % deep_profiler/program_represenentation_utils.m.
+    %
 :- pred build_semi_proc_body(module_info::in, prog_var::in, prog_var::in,
     prog_var::in, maybe(prog_var)::in, hlds_goal_info::in, hlds_goal::in,
     hlds_goal::in, hlds_goal::out) is det.
@@ -818,7 +828,7 @@
         counter.init(0), [], VarInfo1,
         FileName, MaybeRecInfo),
 
-    deep_prof_transform_goal(empty, Goal0, TransformedGoal, _,
+    deep_prof_transform_goal(empty_goal_path, Goal0, TransformedGoal, _,
         DeepInfo0, DeepInfo),
 
     VarInfo = DeepInfo ^ deep_varinfos,
@@ -923,19 +933,19 @@
         Goal = hlds_goal(GoalExpr, GoalInfo)
     ;
         GoalExpr0 = negation(SubGoal0),
-        deep_prof_transform_goal(cord.snoc(Path, step_neg), SubGoal0, SubGoal,
-            AddedImpurity, !DeepInfo),
+        deep_prof_transform_goal(goal_path_add_at_end(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(cord.snoc(Path, step_ite_cond), Cond0, Cond,
-            AddedImpurityC, !DeepInfo),
-        deep_prof_transform_goal(cord.snoc(Path, step_ite_then), Then0, Then,
-            AddedImpurityT, !DeepInfo),
-        deep_prof_transform_goal(cord.snoc(Path, step_ite_else), Else0, Else,
-            AddedImpurityE, !DeepInfo),
+        deep_prof_transform_goal(goal_path_add_at_end(Path, step_ite_cond), 
+            Cond0, Cond, AddedImpurityC, !DeepInfo),
+        deep_prof_transform_goal(goal_path_add_at_end(Path, step_ite_then), 
+            Then0, Then, AddedImpurityT, !DeepInfo),
+        deep_prof_transform_goal(goal_path_add_at_end(Path, step_ite_else), 
+            Else0, Else, AddedImpurityE, !DeepInfo),
         (
             ( AddedImpurityC = yes
             ; AddedImpurityT = yes
@@ -976,7 +986,7 @@
                 AddForceCommit = yes
             )
         ),
-        deep_prof_transform_goal(cord.snoc(Path, step_scope(MaybeCut)),
+        deep_prof_transform_goal(goal_path_add_at_end(Path, step_scope(MaybeCut)),
             SubGoal0, SubGoal, AddedImpurity, !DeepInfo),
         add_impurity_if_needed(AddedImpurity, GoalInfo0, GoalInfo),
         (
@@ -1002,8 +1012,8 @@
 deep_prof_transform_conj(N, ConjType, Path, [Goal0 | Goals0], Goals,
         AddedImpurity, !DeepInfo) :-
     N1 = N + 1,
-    deep_prof_transform_goal(cord.snoc(Path, step_conj(N1)), Goal0, Goal,
-        AddedImpurityFirst, !DeepInfo),
+    deep_prof_transform_goal(goal_path_add_at_end(Path, step_conj(N1)), 
+        Goal0, Goal, AddedImpurityFirst, !DeepInfo),
     deep_prof_transform_conj(N1, ConjType, Path, Goals0,
         TailGoals, AddedImpurityLater, !DeepInfo),
     Goal = hlds_goal(GoalExpr, _),
@@ -1025,8 +1035,8 @@
 deep_prof_transform_disj(N, Path, [Goal0 | Goals0], [Goal | Goals],
         AddedImpurity, !DeepInfo) :-
     N1 = N + 1,
-    deep_prof_transform_goal(cord.snoc(Path, step_disj(N1)), Goal0, Goal,
-        AddedImpurityFirst, !DeepInfo),
+    deep_prof_transform_goal(goal_path_add_at_end(Path, step_disj(N1)), 
+        Goal0, Goal, AddedImpurityFirst, !DeepInfo),
     deep_prof_transform_disj(N1, Path, Goals0, Goals, AddedImpurityLater,
         !DeepInfo),
     bool.or(AddedImpurityFirst, AddedImpurityLater, AddedImpurity).
@@ -1040,7 +1050,8 @@
         [Case0 | Cases0], [Case | Cases], AddedImpurity, !DeepInfo) :-
     N1 = N + 1,
     Case0 = case(MainConsId, OtherConsIds, Goal0),
-    deep_prof_transform_goal(cord.snoc(Path, step_switch(N1, MaybeNumCases)),
+    deep_prof_transform_goal(
+        goal_path_add_at_end(Path, step_switch(N1, MaybeNumCases)),
         Goal0, Goal, AddedImpurityFirst, !DeepInfo),
     Case = case(MainConsId, OtherConsIds, Goal),
     deep_prof_transform_switch(MaybeNumCases, N1, Path, Cases0, Cases,
@@ -1940,7 +1951,7 @@
     ;
         CoverageProfilingOptions ^ cpo_use_2pass = no
     ),
-    coverage_prof_second_pass_goal(cord.empty, !Goal,
+    coverage_prof_second_pass_goal(empty_goal_path, !Goal,
         coverage_after_known, _, CoverageInfo0, CoverageInfo, _),
     CoverageInfo ^ ci_coverage_points = CoveragePointsMap,
     CoverageInfo ^ ci_var_info = !:VarInfo,
@@ -2193,7 +2204,7 @@
         GoalExpr1 = switch(Var, SwitchCanFail, Cases)
     ;
         GoalExpr0 = negation(NegGoal0),
-        coverage_prof_second_pass_goal(snoc(Path, step_neg),
+        coverage_prof_second_pass_goal(goal_path_add_at_end(Path, step_neg),
             NegGoal0, NegGoal, CoverageAfterKnown, NextCoverageAfterKnown,
             !Info, AddedImpurityInner),
         GoalExpr1 = negation(NegGoal)
@@ -2204,7 +2215,8 @@
         ;
             ScopeCut = scope_is_cut
         ),
-        coverage_prof_second_pass_goal(snoc(Path, step_scope(ScopeCut)),
+        coverage_prof_second_pass_goal(
+            goal_path_add_at_end(Path, step_scope(ScopeCut)),
             ScopeGoal0, ScopeGoal,
             CoverageAfterKnown, NextCoverageAfterKnown, !Info,
             AddedImpurityInner),
@@ -2260,8 +2272,9 @@
         CoverageAfterKnown0, NextCoverageAfterKnown, !Info, AddedImpurity) :-
     coverage_prof_second_pass_conj(Path, Pos+1, ConjType, Goals0, Goals1,
         CoverageAfterKnown0, CoverageAfterKnown, !Info, AddedImpurityTail),
-    coverage_prof_second_pass_goal(snoc(Path, step_conj(Pos)), Goal0, Goal1,
-        CoverageAfterKnown, NextCoverageAfterKnown, !Info, AddedImpurityHead),
+    coverage_prof_second_pass_goal(goal_path_add_at_end(Path, step_conj(Pos)), 
+        Goal0, Goal1, CoverageAfterKnown, NextCoverageAfterKnown, !Info, 
+        AddedImpurityHead),
     (
         Goal1 = hlds_goal(conj(plain_conj, ConjGoals), _),
         ConjType = plain_conj
@@ -2293,7 +2306,7 @@
         AddedImpurityTail),
 
     % Transform this goal and optionally add a coverage point before it.
-    DisjPath = snoc(Path, step_disj(Pos)),
+    DisjPath = goal_path_add_at_end(Path, step_disj(Pos)),
     coverage_prof_second_pass_goal(DisjPath, Goal0, Goal1,
         coverage_after_unknown, NextCoverageAfterKnown, !Info,
         AddedImpurityHead0),
@@ -2350,7 +2363,7 @@
         CoverageAfterHeadKnown = coverage_after_unknown
     ),
 
-    SwitchPath = snoc(Path, step_disj(Pos)),
+    SwitchPath = goal_path_add_at_end(Path, step_disj(Pos)),
     coverage_prof_second_pass_goal(SwitchPath, Goal0, Goal1,
         CoverageAfterHeadKnown, NextCoverageAfterKnown0, !Info,
         AddedImpurityHead0),
@@ -2483,13 +2496,13 @@
     ),
 
     % Transform Else branch,
-    coverage_prof_second_pass_goal(snoc(Path, step_ite_else), Else0, Else1,
-        CoverageAfterElseKnown, CoverageBeforeElseKnown1, !Info,
+    coverage_prof_second_pass_goal(goal_path_add_at_end(Path, step_ite_else), 
+        Else0, Else1, CoverageAfterElseKnown, CoverageBeforeElseKnown1, !Info,
         AddedImpurityElseGoal),
 
     % Transform Then branch.
-    coverage_prof_second_pass_goal(snoc(Path, step_ite_then), Then0, Then1,
-        CoverageAfterThenKnown, CoverageBeforeThenKnown1, !Info,
+    coverage_prof_second_pass_goal(goal_path_add_at_end(Path, step_ite_then), 
+        Then0, Then1, CoverageAfterThenKnown, CoverageBeforeThenKnown1, !Info,
         AddedImpurityThenGoal),
 
     % Gather information and decide what coverage points to insert.
@@ -2511,7 +2524,8 @@
         (
             CoverageBeforeThenKnown1 = coverage_after_unknown,
 
-            InsertCPThen = yes(coverage_point_info(snoc(Path, step_ite_then),
+            InsertCPThen = yes(coverage_point_info(
+                goal_path_add_at_end(Path, step_ite_then),
                 cp_type_branch_arm))
         ;
             CoverageBeforeThenKnown1 = coverage_after_known,
@@ -2521,7 +2535,8 @@
         (
             CoverageBeforeElseKnown1 = coverage_after_unknown,
 
-            InsertCPElse = yes(coverage_point_info(snoc(Path, step_ite_else),
+            InsertCPElse = yes(coverage_point_info(
+                goal_path_add_at_end(Path, step_ite_else),
                 cp_type_branch_arm))
         ;
             CoverageBeforeElseKnown1 = coverage_after_known,
@@ -2557,7 +2572,7 @@
     % Transform Cond branch.
     coverage_after_known_branch(CoverageBeforeThenKnown,
         CoverageBeforeElseKnown, CoverageKnownAfterCond),
-    coverage_prof_second_pass_goal(snoc(Path, step_ite_cond),
+    coverage_prof_second_pass_goal(goal_path_add_at_end(Path, step_ite_cond),
         Cond0, Cond, CoverageKnownAfterCond, NextCoverageAfterKnown, !Info,
         AddedImpurityCond),
 
Index: compiler/goal_path.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_path.m,v
retrieving revision 1.50
diff -u -r1.50 goal_path.m
--- compiler/goal_path.m	27 Feb 2008 07:23:05 -0000	1.50
+++ compiler/goal_path.m	3 Sep 2008 06:45:27 -0000
@@ -103,13 +103,13 @@
 
 fill_slots_in_clause(SlotInfo, Clause0, Clause, ClauseNum, ClauseNum + 1) :-
     Clause0 = clause(ProcIds, Goal0, Lang, Context),
-    fill_goal_slots(cord.singleton(step_disj(ClauseNum)), SlotInfo,
+    fill_goal_slots(singleton_goal_path(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(empty, SlotInfo, Goal0, Goal).
+    fill_goal_slots(empty_goal_path, SlotInfo, Goal0, Goal).
 
 :- pred fill_goal_slots(goal_path::in, slot_info::in,
     hlds_goal::in, hlds_goal::out) is det.
@@ -119,9 +119,9 @@
     OmitModeEquivPrefix = SlotInfo ^ slot_info_omit_mode_equiv_prefix,
     (
         OmitModeEquivPrefix = yes,
-        PathSteps0 = cord.list(Path0),
+        PathSteps0 = goal_path_to_list(Path0),
         list.takewhile(mode_equiv_step, PathSteps0, _, PathSteps),
-        Path = cord.from_list(PathSteps)
+        Path = list_to_goal_path(PathSteps)
     ;
         OmitModeEquivPrefix = no,
         Path = Path0
@@ -164,7 +164,7 @@
         GoalExpr = switch(Var, CanFail, Cases)
     ;
         GoalExpr0 = negation(SubGoal0),
-        fill_goal_slots(cord.snoc(Path0, step_neg), SlotInfo,
+        fill_goal_slots(goal_path_add_at_end(Path0, step_neg), SlotInfo,
             SubGoal0, SubGoal),
         GoalExpr = negation(SubGoal)
     ;
@@ -177,16 +177,16 @@
         ;
             MaybeCut = scope_is_cut
         ),
-        fill_goal_slots(cord.snoc(Path0, step_scope(MaybeCut)), SlotInfo,
-            SubGoal0, SubGoal),
+        fill_goal_slots(goal_path_add_at_end(Path0, step_scope(MaybeCut)),
+            SlotInfo, SubGoal0, SubGoal),
         GoalExpr = scope(Reason, SubGoal)
     ;
         GoalExpr0 = if_then_else(A, Cond0, Then0, Else0),
-        fill_goal_slots(cord.snoc(Path0, step_ite_cond), SlotInfo,
+        fill_goal_slots(goal_path_add_at_end(Path0, step_ite_cond), SlotInfo,
             Cond0, Cond),
-        fill_goal_slots(cord.snoc(Path0, step_ite_then), SlotInfo,
+        fill_goal_slots(goal_path_add_at_end(Path0, step_ite_then), SlotInfo,
             Then0, Then),
-        fill_goal_slots(cord.snoc(Path0, step_ite_else), SlotInfo,
+        fill_goal_slots(goal_path_add_at_end(Path0, step_ite_else), SlotInfo,
             Else0, Else),
         GoalExpr = if_then_else(A, Cond, Then, Else)
     ;
@@ -215,8 +215,8 @@
         (
             ShortHand0 = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
                 MainGoal0, OrElseGoals0),
-            fill_goal_slots(cord.snoc(Path0, step_atomic_main), SlotInfo,
-                MainGoal0, MainGoal),
+            fill_goal_slots(goal_path_add_at_end(Path0, step_atomic_main), 
+                SlotInfo, MainGoal0, MainGoal),
             fill_orelse_slots(Path0, 0, SlotInfo, OrElseGoals0, OrElseGoals),
             ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
                 MainGoal, OrElseGoals)
@@ -234,7 +234,8 @@
 fill_conj_slots(_, _, _, [], []).
 fill_conj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_slots(cord.snoc(Path0, step_conj(N1)), SlotInfo, Goal0, Goal),
+    fill_goal_slots(goal_path_add_at_end(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,
@@ -243,7 +244,8 @@
 fill_disj_slots(_, _, _, [], []).
 fill_disj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_slots(cord.snoc(Path0, step_disj(N1)), SlotInfo, Goal0, Goal),
+    fill_goal_slots(goal_path_add_at_end(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,
@@ -254,8 +256,8 @@
         [Case0 | Cases0], [Case | Cases]) :-
     Case0 = case(MainConsId, OtherConsIds, Goal0),
     N1 = N0 + 1,
-    fill_goal_slots(cord.snoc(Path0, step_switch(N1, MaybeNumFunctors)),
-        SlotInfo, Goal0, Goal),
+    CasePath = goal_path_add_at_end(Path0, step_switch(N1, MaybeNumFunctors)),
+    fill_goal_slots(CasePath, SlotInfo, Goal0, Goal),
     Case = case(MainConsId, OtherConsIds, Goal),
     fill_switch_slots(Path0, N1, MaybeNumFunctors, SlotInfo, Cases0, Cases).
 
@@ -265,8 +267,8 @@
 fill_orelse_slots(_, _, _, [], []).
 fill_orelse_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
     N1 = N0 + 1,
-    fill_goal_slots(cord.snoc(Path0, step_atomic_orelse(N1)), SlotInfo,
-        Goal0, Goal),
+    fill_goal_slots(goal_path_add_at_end(Path0, step_atomic_orelse(N1)),
+        SlotInfo, Goal0, Goal),
     fill_orelse_slots(Path0, N1, SlotInfo, Goals0, Goals).
 
 %-----------------------------------------------------------------------------%
Index: compiler/hlds_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_data.m,v
retrieving revision 1.121
diff -u -r1.121 hlds_data.m
--- compiler/hlds_data.m	11 Feb 2008 21:25:54 -0000	1.121
+++ compiler/hlds_data.m	31 Aug 2008 00:35:19 -0000
@@ -1137,7 +1137,7 @@
 make_head_hlds_constraints(ClassTable, TVarSet, ProgConstraints,
         Constraints) :-
     ProgConstraints = constraints(UnivConstraints, ExistConstraints),
-    GoalPath = empty,
+    GoalPath = empty_goal_path,
     make_hlds_constraint_list(UnivConstraints, assumed, GoalPath,
         AssumedConstraints),
     make_hlds_constraint_list(ExistConstraints, unproven, GoalPath,
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.194
diff -u -r1.194 hlds_goal.m
--- compiler/hlds_goal.m	29 Jul 2008 23:57:57 -0000	1.194
+++ compiler/hlds_goal.m	31 Aug 2008 00:35:19 -0000
@@ -1767,7 +1767,7 @@
     set.init(NonLocals),
     term.context_init(Context),
     set.init(Features),
-    GoalPath = empty,
+    GoalPath = empty_goal_path,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, purity_pure,
         Features, GoalPath, no_code_gen_info,
         hlds_goal_extra_info_init(Context)).
@@ -1779,7 +1779,7 @@
     instmap_delta_init_unreachable(InstMapDelta),
     set.init(NonLocals),
     set.init(Features),
-    GoalPath = empty,
+    GoalPath = empty_goal_path,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, purity_pure,
         Features, GoalPath, no_code_gen_info,
         hlds_goal_extra_info_init(Context)).
@@ -1787,14 +1787,14 @@
 goal_info_init(NonLocals, InstMapDelta, Detism, Purity, GoalInfo) :-
     set.init(Features),
     term.context_init(Context),
-    GoalPath = empty,
+    GoalPath = empty_goal_path,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, Purity,
         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,
+    GoalPath = empty_goal_path,
     GoalInfo = goal_info(Detism, InstMapDelta, NonLocals, Purity,
         Features, GoalPath, no_code_gen_info,
         hlds_goal_extra_info_init(Context)).
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.453
diff -u -r1.453 hlds_out.m
--- compiler/hlds_out.m	29 Jul 2008 23:57:57 -0000	1.453
+++ compiler/hlds_out.m	31 Aug 2008 00:35:19 -0000
@@ -1282,7 +1282,7 @@
     ),
     ( string.contains_char(Verbose, 'P') ->
         Path = goal_info_get_goal_path(GoalInfo),
-        ( is_empty(Path) ->
+        ( Path = empty_goal_path ->
             true
         ;
             write_indent(Indent, !IO),
Index: compiler/mode_constraint_robdd.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_constraint_robdd.m,v
retrieving revision 1.14
diff -u -r1.14 mode_constraint_robdd.m
--- compiler/mode_constraint_robdd.m	27 Feb 2008 07:23:10 -0000	1.14
+++ compiler/mode_constraint_robdd.m	3 Sep 2008 06:46:34 -0000
@@ -350,7 +350,7 @@
     varset.lookup_name(VarSet, V, Name),
     io.write_string(Name, !IO),
     io.write_char('_', !IO),
-    PathSteps = cord.list(Path),
+    PathSteps = goal_path_to_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.
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.48
diff -u -r1.48 mode_constraints.m
--- compiler/mode_constraints.m	21 Jul 2008 03:10:11 -0000	1.48
+++ compiler/mode_constraints.m	3 Sep 2008 06:48:01 -0000
@@ -378,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` empty, _, S2, S)
+            mode_constraint_var(V `at` empty_goal_path, _, S2, S)
         ), InstGraph, HeadVars, !MCI),
 
     ( pred_info_is_imported(PredInfo0) ->
@@ -515,7 +515,7 @@
             ( pred(V::in, in, out) is det -->
                 mode_constraint_var(in(V), _),
                 mode_constraint_var(out(V), _),
-                mode_constraint_var(V `at` empty, _)
+                mode_constraint_var(V `at` empty_goal_path, _)
             ), InstGraph, LambdaHeadVars), !NRInfo),
 
     % Number variables within the lambda goal.
@@ -1046,7 +1046,7 @@
     list.map(pred(clause(_, Goal, _, _)::in, Goal::out) is det, Clauses,
         Goals),
     DisjGoal = disj(Goals),
-    EmptyGoalPath = empty,
+    EmptyGoalPath = empty_goal_path,
     AtomicGoals0 = set.init,
     Info0 = goal_constraints_info(ModuleInfo, SCC, InstGraph, HeadVars,
         VarSet0, AtomicGoals0, !.ConstraintInfo, HOModes0, map.init),
@@ -1088,7 +1088,7 @@
     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` empty, V_, !MCI),
+    mode_constraint_var(V `at` empty_goal_path, V_, !MCI),
     ( TopLevel `list.member` HeadVars ->
         % For each variable V in the instantiation graph, add
         %   (Vout = Vin + V), ~(Vin * V).
@@ -1732,7 +1732,7 @@
         ),
     Accumulator =
         (pred((V - W)::in, C0::in, C::out, S0::in, S::out) is det :-
-            get_var(PredId, V `at` empty, V_, S0, S1),
+            get_var(PredId, V `at` empty_goal_path, 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),
@@ -1828,8 +1828,8 @@
         inst_graph.reachable(InstGraph, NonLocal, V),
         \+ (
             RepVar = _ `at` GoalPath1,
-            GoalPathSteps = cord.list(GoalPath),
-            GoalPathSteps1 = cord.list(GoalPath1),
+            GoalPathSteps = goal_path_to_list(GoalPath),
+            GoalPathSteps1 = goal_path_to_list(GoalPath1),
             list.remove_suffix(GoalPathSteps1, GoalPathSteps, [_ | _])
         )
     ).
Index: compiler/mode_ordering.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_ordering.m,v
retrieving revision 1.27
diff -u -r1.27 mode_ordering.m
--- compiler/mode_ordering.m	27 Feb 2008 07:23:10 -0000	1.27
+++ compiler/mode_ordering.m	3 Sep 2008 05:01:49 -0000
@@ -423,7 +423,7 @@
         (
             G = hlds_goal(_, GI),
             GoalPath = goal_info_get_goal_path(GI),
-            cord.get_last(GoalPath, LastStep),
+            LastStep = goal_path_get_last(GoalPath),
             LastStep = step_conj(Index0)
         ->
             Index = Index0
Index: compiler/ordering_mode_constraints.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ordering_mode_constraints.m,v
retrieving revision 1.18
diff -u -r1.18 ordering_mode_constraints.m
--- compiler/ordering_mode_constraints.m	27 Feb 2008 07:23:12 -0000	1.18
+++ compiler/ordering_mode_constraints.m	3 Sep 2008 05:02:19 -0000
@@ -585,7 +585,7 @@
 :- pred get_position_in_conj(mc_rep_var::in, conjunct_id::out) is semidet.
 
 get_position_in_conj(_ProgVar `in` _PredId `at` GoalPath, N) :-
-    cord.get_last(GoalPath, LastStep),
+    LastStep = goal_path_get_last(GoalPath),
     LastStep = step_conj(N).
 
 %-----------------------------------------------------------------------------%
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.334
diff -u -r1.334 polymorphism.m
--- compiler/polymorphism.m	26 May 2008 03:10:46 -0000	1.334
+++ compiler/polymorphism.m	31 Aug 2008 00:35:19 -0000
@@ -1027,7 +1027,7 @@
         ActualExistConstraints) :-
     list.length(ExistConstraints, NumExistConstraints),
     (
-        search_hlds_constraint_list(ConstraintMap, unproven, empty,
+        search_hlds_constraint_list(ConstraintMap, unproven, empty_goal_path,
             NumExistConstraints, ActualExistConstraints0)
     ->
         ActualExistConstraints = ActualExistConstraints0
Index: compiler/rbmm.condition_renaming.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rbmm.condition_renaming.m,v
retrieving revision 1.9
diff -u -r1.9 rbmm.condition_renaming.m
--- compiler/rbmm.condition_renaming.m	8 Apr 2008 20:12:17 -0000	1.9
+++ compiler/rbmm.condition_renaming.m	3 Sep 2008 06:50:09 -0000
@@ -447,11 +447,11 @@
     goal_path_regions_table::out) is det.
 
 record_non_local_regions(Path, Created, Removed, !NonLocalRegionProc) :-
-    ( cord.split_last(Path, InitialPath, LastStep) ->
+    ( goal_path_remove_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),
+            PathToCond = goal_path_add_at_end(InitialPath, step_ite_cond),
             ( map.search(!.NonLocalRegionProc, PathToCond, NonLocalRegions0) ->
                 set.union(NonLocalRegions0, Created, NonLocalRegions1),
                 set.difference(NonLocalRegions1, Removed, NonLocalRegions)
@@ -628,7 +628,7 @@
     goal_path_regions_table::in, goal_path_regions_table::out) is det.
 
 record_regions_created_in_condition(Path, Created, !InCondRegionsProc) :-
-    ( cord.split_last(Path, InitialPath, LastStep) ->
+    ( goal_path_remove_last(Path, InitialPath, LastStep) ->
         ( LastStep = step_ite_cond  ->
             ( map.search(!.InCondRegionsProc, Path, InCondRegions0) ->
                 set.union(InCondRegions0, Created, InCondRegions)
@@ -1008,7 +1008,7 @@
     goal_path::out, int::in, int::out) is det.
 
 get_closest_condition_in_goal_path(Path, PathToCond, !HowMany) :-
-    ( cord.split_last(Path, InitialPath, LastStep) ->
+    ( goal_path_remove_last(Path, InitialPath, LastStep) ->
         ( LastStep = step_ite_cond ->
             PathToCond = Path,
             get_closest_condition_in_goal_path(InitialPath, _, !HowMany),
@@ -1018,7 +1018,7 @@
                 !HowMany)
         )
     ;
-        PathToCond = empty
+        PathToCond = empty_goal_path
     ).
 
 %-----------------------------------------------------------------------------%
@@ -1058,10 +1058,10 @@
 
 collect_ite_annotation_region_names(ExecPaths, Graph, PathToCond,
         RenamedRegions, !IteRenamingProc, !IteAnnotationProc) :-
-    ( cord.split_last(PathToCond, InitialSteps, LastStep) ->
+    ( goal_path_remove_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),
+        PathToThen = goal_path_add_at_end(InitialSteps, step_ite_then),
         get_closest_condition_in_goal_path(PathToCond, _, 0, HowMany),
         list.foldl2(
             collect_ite_annotation_exec_path(Graph, PathToThen,
@@ -1100,8 +1100,8 @@
         HowMany, PrevPoint, [ProgPoint - _ | ProgPoint_Goals],
         !IteRenamingProc, !IteAnnotationProc) :-
     ProgPoint = pp(_, GoalPath),
-    PathToThenSteps = cord.list(PathToThen),
-    GoalPathSteps = cord.list(GoalPath),
+    PathToThenSteps = goal_path_to_list(PathToThen),
+    GoalPathSteps = goal_path_to_list(GoalPath),
     ( list.append(PathToThenSteps, FromThenSteps, GoalPathSteps) ->
         ( list.member(step_ite_cond, FromThenSteps) ->
             % We cannot introduce reverse renaming in the condition of
Index: compiler/smm_common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/smm_common.m,v
retrieving revision 1.5
diff -u -r1.5 smm_common.m
--- compiler/smm_common.m	27 Feb 2008 07:23:14 -0000	1.5
+++ compiler/smm_common.m	3 Sep 2008 07:07:29 -0000
@@ -147,7 +147,7 @@
 dump_program_point(pp(Context, GoalPath), !IO):- 
     prog_out.write_context(Context, !IO), 
     io.write_string("--", !IO),
-    GoalPathSteps = cord.list(GoalPath),
+    GoalPathSteps = goal_path_to_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/mercury1/repository/mercury/compiler/trace_gen.m,v
retrieving revision 1.24
diff -u -r1.24 trace_gen.m
--- compiler/trace_gen.m	2 Jun 2008 02:33:36 -0000	1.24
+++ compiler/trace_gen.m	3 Sep 2008 05:04:08 -0000
@@ -686,7 +686,7 @@
         Goal = hlds_goal(_, GoalInfo),
         GoalPath = goal_info_get_goal_path(GoalInfo),
         (
-            cord.get_last(GoalPath, LastStep),
+            LastStep = goal_path_get_last(GoalPath),
             (
                 LastStep = step_switch(_, _),
                 PortPrime = port_switch
@@ -834,7 +834,7 @@
     (
         PortInfo = port_info_external,
         LiveVars = LiveVars0,
-        Path = empty
+        Path = empty_goal_path
     ;
         PortInfo = port_info_internal(Path, PreDeaths),
         ResumeVars = current_resume_point_vars(!.CI),
@@ -851,9 +851,9 @@
         PortInfo = port_info_nondet_foreign_proc,
         LiveVars = [],
         ( Port = port_nondet_foreign_proc_first ->
-            Path = cord.singleton(step_first)
+            Path = singleton_goal_path(step_first)
         ; Port = port_nondet_foreign_proc_later ->
-            Path = cord.singleton(step_later)
+            Path = singleton_goal_path(step_later)
         ;
             unexpected(this_file,
                 "generate_event_code: bad nondet foreign_proc port")
Index: compiler/tupling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/tupling.m,v
retrieving revision 1.45
diff -u -r1.45 tupling.m
--- compiler/tupling.m	27 Feb 2008 07:23:16 -0000	1.45
+++ compiler/tupling.m	3 Sep 2008 05:11:35 -0000
@@ -1922,13 +1922,13 @@
 
 get_disjunct_relative_frequency(ProcCounts, GoalPath, RelFreq) :-
     (
-        cord.split_last(GoalPath, InitialSteps, LastStep),
+        goal_path_remove_last(GoalPath, InitialSteps, LastStep),
         LastStep = step_disj(Num)
     ->
         get_path_only_count(ProcCounts,
-            cord.snoc(InitialSteps, step_disj(Num)), DisjCount),
+            goal_path_add_at_end(InitialSteps, step_disj(Num)), DisjCount),
         get_path_only_count(ProcCounts,
-            cord.snoc(InitialSteps, step_disj(1)), FirstDisjCount),
+            goal_path_add_at_end(InitialSteps, step_disj(1)), FirstDisjCount),
         ( FirstDisjCount = 0 ->
             RelFreq = 0.0
         ;
@@ -1972,7 +1972,7 @@
 :- pred case_in_switch(goal_path::in, path_port::in) is semidet.
 
 case_in_switch(GoalPath, path_only(GoalPath)) :-
-    cord.get_last(GoalPath, LastStep),
+    LastStep = goal_path_get_last(GoalPath),
     LastStep = step_switch(_, _).
 
 %-----------------------------------------------------------------------------%
Index: compiler/unneeded_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unneeded_code.m,v
retrieving revision 1.47
diff -u -r1.47 unneeded_code.m
--- compiler/unneeded_code.m	27 Feb 2008 07:23:16 -0000	1.47
+++ compiler/unneeded_code.m	3 Sep 2008 05:05:33 -0000
@@ -669,7 +669,7 @@
         (
             Cases0 = [case(_, _, hlds_goal(_, FirstCaseGoalInfo)) | _],
             FirstCaseGoalPath = goal_info_get_goal_path(FirstCaseGoalInfo),
-            cord.get_last(FirstCaseGoalPath, FirstCaseLastStep),
+            FirstCaseLastStep = goal_path_get_last(FirstCaseGoalPath),
             FirstCaseLastStep = step_switch(_, MaybeNumAltPrime)
         ->
             MaybeNumAlt = MaybeNumAltPrime
@@ -1125,7 +1125,7 @@
                 get_parent_branch_point(GoalPath,
                     ParentGoalInitialPath, ParentGoalPathStep,
                     ParentBranchAlt, ParentBranchNum),
-                ParentGoalPath = cord.snoc(ParentGoalInitialPath,
+                ParentGoalPath = goal_path_add_at_end(ParentGoalInitialPath,
                     ParentGoalPathStep),
                 \+ goal_path_inside(ParentGoalPath, CurrentPath)
             ->
@@ -1155,7 +1155,7 @@
 
 get_parent_branch_point(GoalPath, ParentPath, ParentStep,
         BranchAlt, BranchNum) :-
-    cord.split_last(GoalPath, InitialPath, LastStep),
+    goal_path_remove_last(GoalPath, InitialPath, LastStep),
     (
         LastStep = step_switch(Arm, MaybeNumAlts),
         ParentPath = InitialPath,
Index: deep_profiler/mdprof_procrep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/mdprof_procrep.m,v
retrieving revision 1.5
diff -u -r1.5 mdprof_procrep.m
--- deep_profiler/mdprof_procrep.m	28 Aug 2008 10:26:14 -0000	1.5
+++ deep_profiler/mdprof_procrep.m	31 Aug 2008 02:34:50 -0000
@@ -38,6 +38,7 @@
 :- import_module cord.
 :- import_module int.
 :- import_module list.
+:- import_module map.
 :- import_module maybe.
 :- import_module require.
 :- import_module string.
@@ -66,24 +67,24 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred print_selected_modules(list(module_rep)::in, maybe(list(string))::in,
+:- pred print_selected_modules(module_map::in, maybe(list(string))::in,
     io::di, io::uo) is det.
 
-print_selected_modules([], _, !IO).
-print_selected_modules([ModuleRep | ModuleReps], MaybeModules, !IO) :-
-    ModuleRep = module_rep(ModuleName, _StringTable, _ProcReps),
+print_selected_modules(ModuleReps, MaybeModules, !IO) :-
     (
         MaybeModules = no,
-        print_module(ModuleRep, !IO)
+        map.foldl((pred(_::in, ModuleRep::in, IO0::di, IO::uo) is det :-
+                print_module(ModuleRep, IO0, IO)
+            ), ModuleReps, !IO)
     ;
         MaybeModules = yes(Modules),
-        ( list.member(ModuleName, Modules) ->
-            print_module(ModuleRep, !IO)
-        ;
-            true
-        )
-    ),
-    print_selected_modules(ModuleReps, MaybeModules, !IO).
+        list.foldl((pred(ModuleName::in, IO0::di, IO::uo) is det :-
+            ( map.search(ModuleReps, ModuleName, ModuleRep) ->
+                print_module(ModuleRep, IO0, IO)
+            ;
+                IO = IO0
+            )), Modules, !IO)
+    ).
 
 :- pred print_module(module_rep::in, io::di, io::uo) is det.
 
Index: deep_profiler/program_representation_utils.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/program_representation_utils.m,v
retrieving revision 1.1
diff -u -r1.1 program_representation_utils.m
--- deep_profiler/program_representation_utils.m	28 Aug 2008 10:26:14 -0000	1.1
+++ deep_profiler/program_representation_utils.m	31 Aug 2008 01:53:44 -0000
@@ -55,15 +55,18 @@
 :- import_module bool.
 :- import_module int.
 :- import_module list.
+:- import_module map.
 :- import_module maybe.
 
 %----------------------------------------------------------------------------%
 
 print_module_to_strings(ModuleRep, Strings) :-
     ModuleRep = module_rep(ModuleName, _StringTable, ProcReps),
-    list.map(print_proc_to_strings, ProcReps, ProcStrings),
+    map.foldl((pred(_::in, ProcRep::in, Str0::in, Str::out) is det :-
+            print_proc_to_strings(ProcRep, Str1),
+            Str = Str0 ++ Str1), ProcReps, cord.empty, ProcStrings),
     Strings = cord.cons(string.format("Module %s\n", [s(ModuleName)]), 
-        cord_list_to_cord(ProcStrings)).
+        ProcStrings).
 
 print_proc_to_strings(ProcRep, Strings) :-
     ProcRep = proc_rep(ProcLabel, ProcDefnRep),
@@ -428,8 +431,6 @@
 
 %----------------------------------------------------------------------------%
 
-% TODO: It'd be nice if this predicate had some sort of indexes or binary tree
-% to use to speed up it's search.
 progrep_search_proc(ProgRep, ProcLabel, ProcRep) :-
     % XXX: what's the difference between these two module fields? which should
     % I be using.
@@ -446,21 +447,7 @@
 
 progrep_search_module(ProgRep, ModuleName, ModuleRep) :-
    ProgRep = prog_rep(ModuleReps),
-   modulerep_list_search_module(ModuleReps, ModuleName, ModuleRep).
-
-    % Search for a module within a list of module representations.
-    %
-:- pred modulerep_list_search_module(list(module_rep)::in, string::in,
-    module_rep::out) is semidet.
-
-modulerep_list_search_module([], _, _) :- fail.
-modulerep_list_search_module([ModuleRep0 | ModuleReps], ModuleName, ModuleRep)
-        :-
-    ( ModuleRep0 ^ mr_name = ModuleName ->
-        ModuleRep = ModuleRep0
-    ;
-        modulerep_list_search_module(ModuleReps, ModuleName, ModuleRep)
-    ).
+   map.search(ModuleReps, ModuleName, ModuleRep).
 
     % Search for a procedure within a module representation.
     %
@@ -468,20 +455,7 @@
     proc_rep::out) is semidet.
 
 modulerep_search_proc(ModuleRep, ProcLabel, ProcRep) :-
-    procrep_list_search_proc(ModuleRep ^ mr_procs, ProcLabel, ProcRep).
-
-    % Search for a procedure within a list of procedure representations.
-    %
-:- pred procrep_list_search_proc(list(proc_rep)::in, string_proc_label::in,
-    proc_rep::out) is semidet.
-
-procrep_list_search_proc([], _, _) :- fail.
-procrep_list_search_proc([ProcRep0 | ProcReps], ProcLabel, ProcRep) :-
-    ( ProcRep0 ^ pr_id = ProcLabel ->
-        ProcRep = ProcRep0
-    ;
-        procrep_list_search_proc(ProcReps, ProcLabel, ProcRep)
-    ).
+    map.search(ModuleRep ^ mr_procs, ProcLabel, ProcRep).
 
 %----------------------------------------------------------------------------%
 
Index: library/list.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.174
diff -u -r1.174 list.m
--- library/list.m	11 Aug 2008 05:36:55 -0000	1.174
+++ library/list.m	31 Aug 2008 00:35:19 -0000
@@ -340,7 +340,10 @@
     % `Reverse' is a list containing the same elements as `List'
     % but in reverse order.
     %
-:- pred list.reverse(list(T)::in, list(T)::out) is det.
+:- pred list.reverse(list(T), list(T)).
+:- mode list.reverse(in, out) is det.
+:- mode list.reverse(out, in) is det.
+
 :- func list.reverse(list(T)) = list(T).
 
     % list.perm(List0, List):
@@ -1721,7 +1724,13 @@
 
 %-----------------------------------------------------------------------------%
 
-list.reverse(L0, L) :-
+    % reverse(A, B) <=> reverse(B, A).
+:- pragma promise_equivalent_clauses(list.reverse/2).
+
+list.reverse(L0::in, L::out) :-
+    list.reverse_2(L0, [], L).
+
+list.reverse(L::out, L0::in) :-
     list.reverse_2(L0, [], L).
 
 :- pred list.reverse_2(list(T)::in, list(T)::in, list(T)::out) is det.
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.35
diff -u -r1.35 program_representation.m
--- mdbcomp/program_representation.m	28 Aug 2008 10:26:15 -0000	1.35
+++ mdbcomp/program_representation.m	3 Sep 2008 06:42:11 -0000
@@ -40,9 +40,9 @@
 
 :- import_module bool.
 :- import_module char.
-:- import_module cord.
 :- import_module io.
 :- import_module list.
+:- import_module map.
 :- import_module maybe.
 :- import_module unit.
 :- import_module type_desc.
@@ -54,20 +54,32 @@
 
 :- type prog_rep(GoalAnnotation)
     --->    prog_rep(
-                list(module_rep(GoalAnnotation))
+                module_map(GoalAnnotation)
             ).
 
 :- type prog_rep == prog_rep(unit).
 
+    % A map of module names to module representations.
+    %
+:- type module_map(GoalAnnotation) ==
+    map(string, module_rep(GoalAnnotation)).
+:- type module_map == module_map(unit).
+
 :- type module_rep(GoalAnnotation)
     --->    module_rep(
                 mr_name         :: string,          % The module name.
                 mr_string_table :: string_table,
-                mr_procs        :: list(proc_rep(GoalAnnotation))
+                mr_procs        :: proc_map(GoalAnnotation)
             ).
 
 :- type module_rep == module_rep(unit).
 
+    % A map of proc names to proc_reps.
+    %
+:- type proc_map(GoalAnnotation) ==
+    map(string_proc_label, proc_rep(GoalAnnotation)).
+:- type proc_map == proc_map(unit).
+
 :- type proc_rep(GoalAnnotation)
     --->    proc_rep(
                 pr_id           :: string_proc_label,
@@ -381,10 +393,11 @@
 % 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.
+% The goal_path type is safe for use in maps and sets.  However compare/3 and
+% unify/2 are faster for goal_path_string.
+%
 
-:- type goal_path == cord(goal_path_step).
+:- type goal_path.
 
 :- type goal_path_string == string.
 
@@ -406,6 +419,44 @@
 :- type maybe_cut
     --->    scope_is_cut
     ;       scope_is_no_cut.
+    
+    % The empty goal path.
+    %
+:- func empty_goal_path = goal_path.
+
+    % A singleton goal path.
+    %
+:- func singleton_goal_path(goal_path_step) = goal_path.
+
+    % Append a goal path step onto the end of a goal path.
+    %
+:- func goal_path_add_at_end(goal_path, goal_path_step) = goal_path.
+
+    % Remove the last item from the goal path.  This fails if the goal path is
+    % empty.
+    %
+:- func goal_path_remove_last(goal_path) = goal_path is semidet.
+
+    % Remove the last item from the goal path, returning it and the new 
+    % goal path.
+    %
+:- pred goal_path_remove_last(goal_path::in, goal_path::out,
+    goal_path_step::out) is semidet.
+
+    % Get the last item from the goal path.  This fails if the goal path is
+    % empty
+    %
+:- func goal_path_get_last(goal_path) = goal_path_step is semidet.
+
+    % Return the goal path represented as a list, with the outer most goal path
+    % step at the head of the list.
+    %
+:- func goal_path_to_list(goal_path) = list(goal_path_step).
+
+    % Build a goal path from the given list of goal steps.  The outer most goal
+    % step should be at the head of the list.
+    %
+:- func list_to_goal_path(list(goal_path_step)) = goal_path.
 
     % goal_path_inside(PathA, PathB):
     %
@@ -687,10 +738,57 @@
 
 %-----------------------------------------------------------------------------%
 
+    % Goal paths are stored as a list in reverse order, that is the inner most
+    % goal path step is at the head of the list.
+    %
+:- type goal_path
+    --->    goal_path(
+                gp_steps    :: list(goal_path_step)
+            ).
+
+empty_goal_path = goal_path([]).
+
+singleton_goal_path(Step) = goal_path([Step]).
+
 goal_path_inside(PathA, PathB) :-
-    StepsA = cord.list(PathA),
-    StepsB = cord.list(PathB),
-    list.append(StepsA, _, StepsB).
+    list.append(_, PathA ^ gp_steps, PathB ^ gp_steps).
+
+goal_path_add_at_end(GoalPath0, GoalPathStep) = GoalPath :-
+    goal_path_snoc(GoalPath, GoalPath0, GoalPathStep).
+
+goal_path_remove_last(GoalPath0) = GoalPath :-
+    goal_path_snoc(GoalPath0, GoalPath, _).
+
+goal_path_remove_last(GoalPath0, GoalPath, GoalPathStep) :-
+    goal_path_snoc(GoalPath0, GoalPath, GoalPathStep).
+
+goal_path_get_last(GoalPath) = Step :-
+    goal_path_snoc(GoalPath, _, Step).
+
+    % goal_path_snoc(GP, GP0, GPS) <=> GP = GP0 ++ [GPS].
+    %
+:- pred goal_path_snoc(goal_path, goal_path, goal_path_step).
+:- mode goal_path_snoc(in, out, out) is semidet.
+:- mode goal_path_snoc(out, in, in) is det.
+
+goal_path_snoc(GoalPath, GoalPath0, GoalPathStep) :-
+    GoalPath0 = goal_path(Steps0),
+    Steps = [ GoalPathStep | Steps0 ],
+    GoalPath = goal_path(Steps).
+
+goal_path_to_list(GoalPath) = List :-
+    goal_path_list(GoalPath, List).
+
+list_to_goal_path(List) = GoalPath :-
+    goal_path_list(GoalPath, List).
+
+:- pred goal_path_list(goal_path, list(goal_path_step)).
+:- mode goal_path_list(in, out) is det.
+:- mode goal_path_list(out, in) is det.
+
+goal_path_list(GoalPath, StepsList) :-
+    GoalPath = goal_path(RevSteps),
+    reverse(RevSteps, StepsList).
 
 goal_path_from_string_det(GoalPathStr, GoalPath) :-
     ( goal_path_from_string(GoalPathStr, GoalPathPrime) ->
@@ -701,8 +799,9 @@
 
 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).
+    list.map(goal_path_step_from_string, StepStrs, Steps0),
+    list.reverse(Steps0, Steps),
+    GoalPath = goal_path(Steps).
 
 goal_path_step_from_string(String, Step) :-
     string.first_char(String, First, Rest),
@@ -740,7 +839,8 @@
 is_goal_path_separator(';').
 
 goal_path_to_string(GoalPath) = GoalPathStr :-
-    Steps = cord.list(GoalPath),
+    Steps0 = GoalPath ^ gp_steps,
+    list.reverse(Steps0, Steps),
     StepStrs = list.map(goal_path_step_to_string, Steps),
     string.append_list(StepStrs, GoalPathStr).
 
@@ -914,12 +1014,11 @@
                 !:Pos = 0,
                 read_line(ByteCode, Line, !Pos),
                 Line = procrep_id_string,
-                read_module_reps(ByteCode, [], RevModuleReps, !Pos),
+                read_module_reps(ByteCode, map.init, ModuleReps, !Pos),
                 ByteCode = bytecode(_, Size),
                 !.Pos = Size
             )
         ->
-            list.reverse(RevModuleReps, ModuleReps),
             Result = ok(prog_rep(ModuleReps))
         ;
             Msg = FileName ++ ": is not a valid program representation file",
@@ -934,10 +1033,10 @@
 procrep_id_string = "Mercury deep profiler procrep version 3\n".
 
 :- pred read_module_reps(bytecode::in,
-    list(module_rep(unit))::in, list(module_rep(unit))::out,
+    module_map(unit)::in, module_map(unit)::out,
     int::in, int::out) is semidet.
 
-read_module_reps(ByteCode, !RevModuleReps, !Pos) :-
+read_module_reps(ByteCode, !ModuleReps, !Pos) :-
     read_byte(ByteCode, MoreByte, !Pos),
     is_more_modules(MoreByte, MoreModules),
     (
@@ -945,8 +1044,8 @@
     ;
         MoreModules = next_module,
         read_module_rep(ByteCode, ModuleRep, !Pos),
-        !:RevModuleReps = [ModuleRep | !.RevModuleReps],
-        read_module_reps(ByteCode, !RevModuleReps, !Pos)
+        svmap.det_insert(ModuleRep ^ mr_name, ModuleRep, !ModuleReps),
+        read_module_reps(ByteCode, !ModuleReps, !Pos)
     ).
 
 :- pred read_module_rep(bytecode::in, module_rep(unit)::out, int::in, int::out)
@@ -955,15 +1054,14 @@
 read_module_rep(ByteCode, ModuleRep, !Pos) :-
     read_len_string(ByteCode, ModuleName, !Pos),
     read_string_table(ByteCode, StringTable, !Pos),
-    read_proc_reps(ByteCode, StringTable, [], RevProcReps, !Pos),
-    list.reverse(RevProcReps, ProcReps),
+    read_proc_reps(ByteCode, StringTable, map.init, ProcReps, !Pos),
     ModuleRep = module_rep(ModuleName, StringTable, ProcReps).
 
 :- pred read_proc_reps(bytecode::in, string_table::in,
-    list(proc_rep(unit))::in, list(proc_rep(unit))::out, int::in, int::out) 
+    proc_map(unit)::in, proc_map(unit)::out, int::in, int::out) 
     is semidet.
 
-read_proc_reps(ByteCode, StringTable, !RevProcReps, !Pos) :-
+read_proc_reps(ByteCode, StringTable, !ProcReps, !Pos) :-
     read_byte(ByteCode, MoreByte, !Pos),
     is_more_procs(MoreByte, MoreProcs),
     (
@@ -971,8 +1069,8 @@
     ;
         MoreProcs = next_proc,
         read_proc_rep(ByteCode, StringTable, ProcRep, !Pos),
-        !:RevProcReps = [ProcRep | !.RevProcReps],
-        read_proc_reps(ByteCode, StringTable, !RevProcReps, !Pos)
+        svmap.det_insert(ProcRep ^ pr_id, ProcRep, !ProcReps), 
+        read_proc_reps(ByteCode, StringTable, !ProcReps, !Pos)
     ).
 
 :- pred read_proc_rep(bytecode::in, string_table::in, proc_rep(unit)::out,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20080904/86d19e2a/attachment.sig>


More information about the reviews mailing list