[m-rev.] for post-commit diff: detect push opportunities

Zoltan Somogyi zs at csse.unimelb.edu.au
Wed Jan 19 05:15:39 AEDT 2011


For review by Paul.

BTW, does anyone know why I keep getting the diff to test_atomic_include.h?
It is an automatically generated file that is intentionally committed,
whose committed version differs from the version generated on taura.

Zoltan.

deep_profiler/mdprof_db.automatic_parallelism.m:
	Detect places where a costly goal could be pushed next to another
	costly goal inside an earlier conjunct. We don't yet do anything
	with this information.

library/list.m:
	Add some more arity variants of map_foldl for
	mdprof_db.automatic_parallelism.m. Put these and the existing variants
	into a logical order.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
Index: boehm_gc/libatomic_ops/tests/test_atomic_include.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/boehm_gc/libatomic_ops/tests/test_atomic_include.h,v
retrieving revision 1.1.1.1
diff -u -b -r1.1.1.1 test_atomic_include.h
--- boehm_gc/libatomic_ops/tests/test_atomic_include.h	23 Feb 2010 06:28:40 -0000	1.1.1.1
+++ boehm_gc/libatomic_ops/tests/test_atomic_include.h	18 Jan 2011 00:11:08 -0000
@@ -5,15 +5,6 @@
  * see doc/COPYING for details.
  */
 
-void test_atomic(void);
-void test_atomic_release(void);
-void test_atomic_acquire(void);
-void test_atomic_read(void);
-void test_atomic_write(void);
-void test_atomic_full(void);
-void test_atomic_release_write(void);
-void test_atomic_acquire_read(void);
-
 /* Some basic sanity tests.  These do not test the barrier semantics. */
 
 #undef TA_assert
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing deep_profiler
Index: deep_profiler/mdprof_fb.automatic_parallelism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_fb.automatic_parallelism.m,v
retrieving revision 1.29
diff -u -b -r1.29 mdprof_fb.automatic_parallelism.m
--- deep_profiler/mdprof_fb.automatic_parallelism.m	18 Jan 2011 05:01:28 -0000	1.29
+++ deep_profiler/mdprof_fb.automatic_parallelism.m	18 Jan 2011 17:47:06 -0000
@@ -117,8 +117,8 @@
         RootParallelism, RootCliquePtr, ConjunctionsMap, Messages),
 
     map.to_assoc_list(ConjunctionsMap, ConjunctionsAssocList0),
-    map_values_only(convert_candidate_par_conjunctions_proc(
-            pard_goal_detail_to_pard_goal),
+    assoc_list.map_values_only(
+        convert_candidate_par_conjunctions_proc(pard_goal_detail_to_pard_goal),
         ConjunctionsAssocList0, ConjunctionsAssocList),
     CandidateParallelConjunctions =
         feedback_data_candidate_parallel_conjunctions(Params,
@@ -620,8 +620,8 @@
 
                 % Gather call site information.
                 proc_dynamic_paired_call_site_slots(Deep, PDPtr, Slots),
-                foldl(build_dynamic_call_site_cost_and_callee_map(Deep), Slots,
-                    map.init, CallSitesMap),
+                list.foldl(build_dynamic_call_site_cost_and_callee_map(Deep),
+                    Slots, map.init, CallSitesMap),
 
                 % Gather information about the procedure.
                 deep_lookup_pd_own(Deep, PDPtr, Own),
@@ -634,7 +634,7 @@
                     % Build coverage annotation.
                     coverage_point_arrays_to_list(PS ^ ps_coverage_point_infos,
                         CoveragePointsArray, CoveragePoints),
-                    foldl2(add_coverage_point_to_map,
+                    list.foldl2(add_coverage_point_to_map,
                         CoveragePoints, map.init, SolnsCoveragePointMap,
                         map.init, BranchCoveragePointMap),
                     goal_annotate_with_coverage(ProcLabel, Goal, Own,
@@ -654,7 +654,8 @@
                         ProcLabel),
                     goal_to_pard_goal(Info, [], Goal, PardGoal, !Messages),
                     goal_get_conjunctions_worth_parallelising(Info,
-                        [], PardGoal, _, Candidates0, MessagesA),
+                        [], PardGoal, _, CandidatesCord0, _Singles, MessagesA),
+                    Candidates0 = cord.list(CandidatesCord0),
                     !:Messages = !.Messages ++ MessagesA,
                     (
                         SeenDuplicateInstantiation =
@@ -713,131 +714,174 @@
 :- pred goal_get_conjunctions_worth_parallelising(
     implicit_parallelism_info::in, list(goal_path_step)::in,
     pard_goal_detail::in, pard_goal_detail::out,
-    list(candidate_par_conjunction(pard_goal_detail))::out,
-    cord(message)::out) is det.
+    cord(candidate_par_conjunction(pard_goal_detail))::out,
+    cord(pard_goal_detail)::out, cord(message)::out) is det.
 
 goal_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
-        !Goal, Candidates, Messages) :-
+        !Goal, Candidates, Singles, Messages) :-
     % XXX: This predicate should return a list of costly goals within compund
     % goals that next to which it might be desirable to push later goals to
     % allow parallelisation within a branch of a compound goal.
-    GoalExpr0 = !.Goal ^ goal_expr_rep,
-    Coverage = !.Goal ^ goal_annotation ^ pgd_coverage,
+    !.Goal = goal_rep(GoalExpr0, DetismRep, Annotation0),
+    Coverage = Annotation0 ^ pgd_coverage,
     get_coverage_before_det(Coverage, Calls),
     (
         (
             GoalExpr0 = conj_rep(Conjs0),
-            list.map3_foldl(
-                conj_get_conjunctions_worth_parallelising(Info,
-                    RevGoalPathSteps),
-                Conjs0, Conjs, Candidatess, Messagess, 1, _),
-            conj_build_candidate_conjunctions(Info, RevGoalPathSteps, Conjs,
-                MaybeCost, MessagesB, MaybeCandidate),
+            conj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+                Conjs0, Conjs, 1, [], SinglesSoFar, [], RevSingleCands,
+                cord.empty, CandidatesBelow, cord.empty, MessagesBelow),
+            GoalExpr = conj_rep(Conjs),
+            list.reverse(RevSingleCands, SingleCands),
             (
-                MaybeCost = yes(Cost)
+                SingleCands = [],
+                Candidates = CandidatesBelow,
+                Singles = cord.from_list(SinglesSoFar),
+                Messages = MessagesBelow,
+                Cost = Annotation0 ^ pgd_cost
+            ;
+                SingleCands = [_],
+                % XXX finish this _SinglesSoFar
+                Candidates = CandidatesBelow,
+                Singles = cord.from_list(SinglesSoFar),
+                Messages = MessagesBelow,
+                Cost = Annotation0 ^ pgd_cost
             ;
-                MaybeCost = no,
-                Cost = !.Goal ^ goal_annotation ^ pgd_cost
-            ),
-            GoalExpr = conj_rep(Conjs),
-            Messages = cord_list_to_cord(Messagess) ++ MessagesB,
+                SingleCands = [_, _ | _],
+                assoc_list.keys(SingleCands, CostlyIndexes),
+                conj_build_candidate_conjunctions(Info, RevGoalPathSteps, Conjs,
+                    CostlyIndexes, MessagesThisLevel, MaybeCandidate),
+                Messages = MessagesBelow ++ MessagesThisLevel,
             (
                 MaybeCandidate = yes(Candidate),
-                Candidates = [Candidate | condense(Candidatess)]
+                    Candidates = cord.cons(Candidate, CandidatesBelow),
+                    ExecMetrics = Candidate ^ cpc_par_exec_metrics,
+                    Cost = call_goal_cost(ExecMetrics ^ pem_num_calls,
+                        ExecMetrics ^ pem_par_time),
+                    % We could parallelize this conjunction. Trying to push
+                    % a goal after it next to a costly goal inside it
+                    % would require pushing that following goal into
+                    % a conjunct of a parallel conjunction.
+                    % Due to our current prohibition on reordering, that costly
+                    % goal would have to be inside the last parallel conjunct.
+                    % That would require replacing Candidate with another
+                    % candidate that includes the following goal. While that is
+                    % in theory doable, it is not doable *here*, since at this
+                    % point we don't know anything about any costly
+                    % following goal; it probably does not even exist.
+                    Singles = cord.empty
             ;
                 MaybeCandidate = no,
-                Candidates = condense(Candidatess)
+                    Candidates = CandidatesBelow,
+                    Singles = cord.from_list(SinglesSoFar),
+                    Cost = Annotation0 ^ pgd_cost
+                )
             )
         ;
             GoalExpr0 = disj_rep(Disjs0),
-            list.map3_foldl(
+            list.map_foldl4(
                 disj_get_conjunctions_worth_parallelising(Info,
                     RevGoalPathSteps),
-                Disjs0, Disjs, Candidatess, Messagess, 1, _),
+                Disjs0, Disjs, 1, _, cord.empty, Candidates,
+                cord.empty, Singles, cord.empty, Messages),
             disj_calc_cost(Disjs, Calls, Cost),
-            GoalExpr = disj_rep(Disjs),
-            Messages = cord_list_to_cord(Messagess),
-            Candidates = condense(Candidatess)
+            GoalExpr = disj_rep(Disjs)
         ;
             GoalExpr0 = switch_rep(Var, CanFail, Cases0),
-            list.map3_foldl(
+            list.map_foldl4(
                 switch_case_get_conjunctions_worth_parallelising(Info,
                     RevGoalPathSteps),
-                Cases0, Cases, Candidatess, Messagess, 1, _),
+                Cases0, Cases, 1, _, cord.empty, Candidates,
+                cord.empty, Singles, cord.empty, Messages),
             switch_calc_cost(Cases, Calls, Cost),
-            GoalExpr = switch_rep(Var, CanFail, Cases),
-            Messages = cord_list_to_cord(Messagess),
-            Candidates = condense(Candidatess)
+            GoalExpr = switch_rep(Var, CanFail, Cases)
         ;
             GoalExpr0 = ite_rep(Cond0, Then0, Else0),
             ite_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
-                Cond0, Cond, Then0, Then, Else0, Else, Candidates, Messages),
+                Cond0, Cond, Then0, Then, Else0, Else,
+                Candidates, Singles, Messages),
             ite_calc_cost(Cond, Then, Else, Cost),
             GoalExpr = ite_rep(Cond, Then, Else)
         ;
             GoalExpr0 = scope_rep(SubGoal0, MaybeCut),
             RevSubGoalPathSteps = [step_scope(MaybeCut) | RevGoalPathSteps],
             goal_get_conjunctions_worth_parallelising(Info,
-                RevSubGoalPathSteps, SubGoal0, SubGoal, Candidates, Messages),
+                RevSubGoalPathSteps, SubGoal0, SubGoal,
+                Candidates, Singles, Messages),
             Cost = SubGoal ^ goal_annotation ^ pgd_cost,
             GoalExpr = scope_rep(SubGoal, MaybeCut)
         ;
             GoalExpr0 = negation_rep(SubGoal0),
             RevSubGoalPathSteps = [step_neg | RevGoalPathSteps],
+            % We ignore _Singles here because you cannot push goals
+            % after a negation into the negation.
             goal_get_conjunctions_worth_parallelising(Info,
-                RevSubGoalPathSteps, SubGoal0, SubGoal, Candidates, Messages),
+                RevSubGoalPathSteps, SubGoal0, SubGoal,
+                Candidates, _Singles, Messages),
+            Singles = cord.empty,
             Cost = SubGoal ^ goal_annotation ^ pgd_cost,
             GoalExpr = negation_rep(SubGoal)
         ),
-        !Goal ^ goal_annotation ^ pgd_cost := Cost
+        Annotation = Annotation0 ^ pgd_cost := Cost
     ;
         GoalExpr0 = atomic_goal_rep(_, _, _, _),
+        identify_costly_goal(Annotation0, Costly),
+        (
+            Costly = is_costly_atomic_goal,
+            Singles = cord.singleton(!.Goal)
+        ;
+            Costly = is_costly_compound_goal,
+            unexpected($module, $pred, "atomic goal is costly compound")
+        ;
+            Costly = is_not_costly_goal,
+            Singles = cord.empty
+        ),
+        Candidates = cord.empty,
         Messages = cord.empty,
-        Candidates = [],
-        GoalExpr = GoalExpr0
+        GoalExpr = GoalExpr0,
+        Annotation = Annotation0
     ),
-    !Goal ^ goal_expr_rep := GoalExpr.
-
-:- pred conj_get_conjunctions_worth_parallelising(
-    implicit_parallelism_info::in, list(goal_path_step)::in,
-    pard_goal_detail::in, pard_goal_detail::out,
-    list(candidate_par_conjunction(pard_goal_detail))::out,
-    cord(message)::out, int::in, int::out) is det.
-
-conj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
-        !Conj, Candidates, Messages, !ConjNum) :-
-    RevConjGoalPathSteps = [step_conj(!.ConjNum) | RevGoalPathSteps],
-    goal_get_conjunctions_worth_parallelising(Info, RevConjGoalPathSteps,
-        !Conj, Candidates, Messages),
-    !:ConjNum = !.ConjNum + 1.
+    !:Goal = goal_rep(GoalExpr, DetismRep, Annotation).
 
 :- pred disj_get_conjunctions_worth_parallelising(
     implicit_parallelism_info::in, list(goal_path_step)::in,
     pard_goal_detail::in, pard_goal_detail::out,
-    list(candidate_par_conjunction(pard_goal_detail))::out,
-    cord(message)::out, int::in, int::out) is det.
+    int::in, int::out,
+    cord(candidate_par_conjunction(pard_goal_detail))::in,
+    cord(candidate_par_conjunction(pard_goal_detail))::out,
+    cord(pard_goal_detail)::in, cord(pard_goal_detail)::out,
+    cord(message)::in, cord(message)::out) is det.
 
 disj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
-        !Disj, Candidates, Messages, !DisjNum) :-
+        !Disj, !DisjNum, !Candidates, !Singles, !Messages) :-
     RevDisjGoalPathSteps = [step_disj(!.DisjNum) | RevGoalPathSteps],
     goal_get_conjunctions_worth_parallelising(Info, RevDisjGoalPathSteps,
-        !Disj, Candidates, Messages),
+        !Disj, Candidates, Singles, Messages),
+    !:Candidates = !.Candidates ++ Candidates,
+    !:Singles = !.Singles ++ Singles,
+    !:Messages = !.Messages ++ Messages,
     !:DisjNum = !.DisjNum + 1.
 
 :- pred switch_case_get_conjunctions_worth_parallelising(
     implicit_parallelism_info::in, list(goal_path_step)::in,
     case_rep(pard_goal_detail_annotation)::in,
     case_rep(pard_goal_detail_annotation)::out,
-    list(candidate_par_conjunction(pard_goal_detail))::out,
-    cord(message)::out, int::in, int::out) is det.
+    int::in, int::out,
+    cord(candidate_par_conjunction(pard_goal_detail))::in,
+    cord(candidate_par_conjunction(pard_goal_detail))::out,
+    cord(pard_goal_detail)::in, cord(pard_goal_detail)::out,
+    cord(message)::in, cord(message)::out) is det.
 
 switch_case_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps, !Case,
-        Candidates, Messages, !CaseNum) :-
-    Goal0 = !.Case ^ cr_case_goal,
+        !CaseNum, !Candidates, !Singles, !Messages) :-
+    !.Case = case_rep(MainConsIdRep, OtherConsIdReps, Goal0),
     RevCaseGoalPathSteps = [step_switch(!.CaseNum, no) | RevGoalPathSteps],
     goal_get_conjunctions_worth_parallelising(Info, RevCaseGoalPathSteps,
-        Goal0, Goal, Candidates, Messages),
-    !Case ^ cr_case_goal := Goal,
+        Goal0, Goal, Candidates, Singles, Messages),
+    !:Case = case_rep(MainConsIdRep, OtherConsIdReps, Goal),
+    !:Candidates = !.Candidates ++ Candidates,
+    !:Singles = !.Singles ++ Singles,
+    !:Messages = !.Messages ++ Messages,
     !:CaseNum = !.CaseNum + 1.
 
 :- pred ite_get_conjunctions_worth_parallelising(
@@ -845,46 +889,95 @@
     pard_goal_detail::in, pard_goal_detail::out,
     pard_goal_detail::in, pard_goal_detail::out,
     pard_goal_detail::in, pard_goal_detail::out,
-    list(candidate_par_conjunction(pard_goal_detail))::out, cord(message)::out)
-    is det.
+    cord(candidate_par_conjunction(pard_goal_detail))::out,
+    cord(pard_goal_detail)::out,  cord(message)::out) is det.
 
 ite_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
-        !Cond, !Then, !Else, Candidates, Messages) :-
+        !Cond, !Then, !Else, Candidates, Singles, Messages) :-
     RevCondGoalPathSteps = [step_ite_cond | RevGoalPathSteps],
     RevThenGoalPathSteps = [step_ite_then | RevGoalPathSteps],
     RevElseGoalPathSteps = [step_ite_else | RevGoalPathSteps],
+    % We ignore _CondSingles here because you cannot push goals
+    % following an if-then-else into the condition.
     goal_get_conjunctions_worth_parallelising(Info, RevCondGoalPathSteps,
-        !Cond, CondCandidates, CondMessages),
+        !Cond, CondCandidates, _CondSingles, CondMessages),
     goal_get_conjunctions_worth_parallelising(Info, RevThenGoalPathSteps,
-        !Then, ThenCandidates, ThenMessages),
+        !Then, ThenCandidates, ThenSingles, ThenMessages),
     goal_get_conjunctions_worth_parallelising(Info, RevElseGoalPathSteps,
-        !Else, ElseCandidates, ElseMessages),
+        !Else, ElseCandidates, ElseSingles, ElseMessages),
     Candidates = CondCandidates ++ ThenCandidates ++ ElseCandidates,
+    Singles = ThenSingles ++ ElseSingles,
     Messages = CondMessages ++ ThenMessages ++ ElseMessages.
 
-    % At the end of every conjunction, we call this predicate to check
-    % the list of calls we have found and make any parallelisation decisions.
+:- pred conj_get_conjunctions_worth_parallelising(
+    implicit_parallelism_info::in, list(goal_path_step)::in,
+    list(pard_goal_detail)::in, list(pard_goal_detail)::out, int::in,
+    list(pard_goal_detail)::in, list(pard_goal_detail)::out,
+    assoc_list(int, list(pard_goal_detail))::in,
+    assoc_list(int, list(pard_goal_detail))::out,
+    cord(candidate_par_conjunction(pard_goal_detail))::in,
+    cord(candidate_par_conjunction(pard_goal_detail))::out,
+    cord(message)::in, cord(message)::out) is det.
+
+conj_get_conjunctions_worth_parallelising(_Info, _RevGoalPathSteps,
+        [], [], _ConjNum, !SinglesSoFar, !RevSingleCands,
+        !CandidatesBelow, !MessagesBelow).
+conj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+        [Conj0 | Conjs0], [Conj | Conjs], ConjNum, SinglesSoFar0, SinglesSoFar,
+        !RevSingleCands, !CandidatesBelow, !MessagesBelow) :-
+    RevConjGoalPathSteps = [step_conj(ConjNum) | RevGoalPathSteps],
+    goal_get_conjunctions_worth_parallelising(Info, RevConjGoalPathSteps,
+        Conj0, Conj, Candidates, SinglesCord, Messages),
+    Singles = cord.list(SinglesCord),
+    !:CandidatesBelow = !.CandidatesBelow ++ Candidates,
+    !:MessagesBelow = !.MessagesBelow ++ Messages,
+    identify_costly_goal(Conj ^ goal_annotation, Costly),
+    (
+        ( Costly = is_costly_atomic_goal
+        ; Costly = is_costly_compound_goal
+        ),
+        !:RevSingleCands = [ConjNum - SinglesSoFar0 | !.RevSingleCands],
+        SinglesSoFar1 = Singles
+    ;
+        Costly = is_not_costly_goal,
+        (
+            SinglesSoFar0 = [],
+            Singles = [],
+            SinglesSoFar1 = []
+        ;
+            SinglesSoFar0 = [_ | _],
+            Singles = [],
+            SinglesSoFar1 = SinglesSoFar0
+        ;
+            SinglesSoFar0 = [],
+            Singles = [_ | _],
+            SinglesSoFar1 = Singles
+        ;
+            SinglesSoFar0 = [_ | _],
+            Singles = [_ | _],
+            % XXX choose between SinglesSoFar0 and Singles, either on max cost
+            % or total cost.
+            SinglesSoFar1 = Singles
+        )
+    ),
+    conj_get_conjunctions_worth_parallelising(Info, RevGoalPathSteps,
+        Conjs0, Conjs, ConjNum + 1, SinglesSoFar1, SinglesSoFar,
+        !RevSingleCands, !CandidatesBelow, !MessagesBelow).
+
+    % Given a predicate with two or more costly goals (identified by
+    % CostlyGoalsIndexes), check whether executing the conjunction in parallel
+    % can yield a speedup.
     %
 :- pred conj_build_candidate_conjunctions(implicit_parallelism_info::in,
-    list(goal_path_step)::in, list(pard_goal_detail)::in,
-    maybe(goal_cost_csq)::out, cord(message)::out,
+    list(goal_path_step)::in, list(pard_goal_detail)::in, list(int)::in,
+    cord(message)::out,
     maybe(candidate_par_conjunction(pard_goal_detail))::out) is det.
 
-conj_build_candidate_conjunctions(Info, RevGoalPathSteps, Conjs, MaybeCost,
-        Messages, MaybeCandidate) :-
+conj_build_candidate_conjunctions(Info, RevGoalPathSteps, Conjs,
+        CostlyGoalsIndexes, !:Messages, MaybeCandidate) :-
     ProcLabel = Info ^ ipi_proc_label,
-    some [!Messages]
-    (
         !:Messages = cord.empty,
-
-        % Preprocess the conjunction to find the costly calls and where they
-        % are.
-        identify_costly_goals(Conjs, 1, CostlyGoalsIndexes),
         NumCostlyGoals = length(CostlyGoalsIndexes),
-        ( NumCostlyGoals < 2 ->
-            MaybeCost = no,
-            MaybeCandidate = no
-        ;
             Location = pl_goal(ProcLabel, rgp(RevGoalPathSteps)),
             append_message(Location,
                 info_found_conjs_above_callsite_threshold(NumCostlyGoals),
@@ -893,36 +986,12 @@
             pardgoals_build_candidate_conjunction(Info, Location,
                 RevGoalPathSteps, Conjs, MaybeCandidate, !Messages),
             (
-                MaybeCandidate = yes(Candidate),
+        MaybeCandidate = yes(_Candidate),
                 append_message(Location,
                     info_found_n_conjunctions_with_positive_speedup(1),
-                    !Messages),
-                ExecMetrics = Candidate ^ cpc_par_exec_metrics,
-                MaybeCost = yes(call_goal_cost(ExecMetrics ^ pem_num_calls,
-                    ExecMetrics ^ pem_par_time))
-            ;
-                MaybeCandidate = no,
-                MaybeCost = no
-            )
-        ),
-        Messages = !.Messages
-    ).
-
-:- pred identify_costly_goals(list(pard_goal_detail)::in, int::in,
-    list(int)::out) is det.
-
-identify_costly_goals([], _, []).
-identify_costly_goals([Goal | Goals], Index, Indexes) :-
-    identify_costly_goals(Goals, Index + 1, Indexes0),
-    identify_costly_goal(Goal, Costly),
-    (
-        ( Costly = is_costly_atomic_goal
-        ; Costly = is_costly_compound_goal
-        ),
-        Indexes = [Index | Indexes0]
+            !Messages)
     ;
-        Costly = is_not_costly_goal,
-        Indexes = Indexes0
+        MaybeCandidate = no
     ).
 
 :- pred pardgoals_build_candidate_conjunction(implicit_parallelism_info::in,
@@ -1137,7 +1206,8 @@
                 non_empty_list,
                 ground,
                 non_empty_list,
-                ground).
+                ground
+            ).
 
 :- pred preprocess_conjunction(list(pard_goal_detail)::in,
     maybe(goals_for_parallelisation)::out(maybe(goals_for_parallelisation)),
@@ -1273,7 +1343,7 @@
     list(goal_group(goal_classification))::out) is det.
 
 preprocess_conjunction_into_groups(Index, Goal, !RevGoalGroups) :-
-    identify_costly_goal(Goal, Costly),
+    identify_costly_goal(Goal ^ goal_annotation, Costly),
     (
         ( Costly = is_costly_atomic_goal
         ; Costly = is_costly_compound_goal
@@ -2669,13 +2739,14 @@
     ;       is_costly_atomic_goal
     ;       is_costly_compound_goal.
 
-:- pred identify_costly_goal(pard_goal_detail::in, is_costly_goal::out) is det.
+:- pred identify_costly_goal(pard_goal_detail_annotation::in,
+    is_costly_goal::out) is det.
 
-identify_costly_goal(Goal, Costly) :-
-    CostAboveThreshold = Goal ^ goal_annotation ^ pgd_cost_above_threshold,
+identify_costly_goal(Annotation, Costly) :-
+    CostAboveThreshold = Annotation ^ pgd_cost_above_threshold,
     (
         CostAboveThreshold = cost_above_par_threshold,
-        GoalType = Goal ^ goal_annotation ^ pgd_pg_type,
+        GoalType = Annotation ^ pgd_pg_type,
         (
             GoalType = pgt_call(_, _),
             Costly = is_costly_atomic_goal
@@ -2684,8 +2755,8 @@
             unexpected($module, $pred, "pgt_other_atomic_goal is never costly")
         ;
             GoalType = pgt_non_atomic_goal,
-            % TODO: distinguish between compound goals with one branch that is
-            % costly, and compound goals where all branches are costly.
+            % TODO: distinguish between compound goals with one costly branch,
+            % and compound goals where all branches are costly.
             % TODO: Provide information about how many costly goals are within
             % the goal so that we can try to parallelise each of those against
             % an outer costly goal.
@@ -2696,6 +2767,23 @@
         Costly = is_not_costly_goal
     ).
 
+:- pred identify_costly_goals(list(pard_goal_detail)::in, int::in,
+    list(int)::out) is det.
+
+identify_costly_goals([], _, []).
+identify_costly_goals([Goal | Goals], Index, Indexes) :-
+    identify_costly_goals(Goals, Index + 1, Indexes0),
+    identify_costly_goal(Goal ^ goal_annotation, Costly),
+    (
+        ( Costly = is_costly_atomic_goal
+        ; Costly = is_costly_compound_goal
+        ),
+        Indexes = [Index | Indexes0]
+    ;
+        Costly = is_not_costly_goal,
+        Indexes = Indexes0
+    ).
+
 :- pred var_get_mode(inst_map::in, inst_map::in, var_rep::in,
     var_mode_rep::out) is det.
 
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/list.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.200
diff -u -b -r1.200 list.m
--- library/list.m	22 Nov 2010 06:02:14 -0000	1.200
+++ library/list.m	18 Jan 2011 17:02:25 -0000
@@ -1123,56 +1123,6 @@
 :- mode list.map_foldl(pred(in, out, di, uo) is cc_multi, in, out, di, uo)
     is cc_multi.
 
-    % Same as list.map_foldl, but with two mapped outputs.
-    %
-:- pred list.map2_foldl(pred(L, M, N, A, A), list(L), list(M), list(N),
-    A, A).
-:- mode list.map2_foldl(pred(in, out, out, in, out) is det, in, out, out,
-    in, out) is det.
-:- mode list.map2_foldl(pred(in, out, out, mdi, muo) is det, in, out, out,
-    mdi, muo) is det.
-:- mode list.map2_foldl(pred(in, out, out, di, uo) is det, in, out, out,
-    di, uo) is det.
-:- mode list.map2_foldl(pred(in, out, out, in, out) is semidet, in, out, out,
-    in, out) is semidet.
-:- mode list.map2_foldl(pred(in, out, out, mdi, muo) is semidet, in, out, out,
-    mdi, muo) is semidet.
-:- mode list.map2_foldl(pred(in, out, out, di, uo) is semidet, in, out, out,
-    di, uo) is semidet.
-:- mode list.map2_foldl(pred(in, out, out, in, out) is nondet, in, out, out,
-    in, out) is nondet.
-:- mode list.map2_foldl(pred(in, out, out, mdi, muo) is nondet, in, out, out,
-    mdi, muo) is nondet.
-:- mode list.map2_foldl(pred(in, out, out, in, out) is cc_multi, in, out, out,
-    in, out) is cc_multi.
-:- mode list.map2_foldl(pred(in, out, out, di, uo) is cc_multi, in, out, out,
-    di, uo) is cc_multi.
-
-    % Same as list.map2_foldl, but with three mapped outputs.
-    %
-:- pred list.map3_foldl(pred(L, M, N, O, A, A), list(L), list(M), list(N),
-    list(O), A, A).
-:- mode list.map3_foldl(pred(in, out, out, out, in, out) is det, in, out, out,
-    out, in, out) is det.
-:- mode list.map3_foldl(pred(in, out, out, out, mdi, muo) is det, in, out, out,
-    out, mdi, muo) is det.
-:- mode list.map3_foldl(pred(in, out, out, out, di, uo) is det, in, out, out,
-    out, di, uo) is det.
-:- mode list.map3_foldl(pred(in, out, out, out, in, out) is semidet, in, out, 
-    out, out, in, out) is semidet.
-:- mode list.map3_foldl(pred(in, out, out, out, mdi, muo) is semidet, in, out,
-    out, out, mdi, muo) is semidet.
-:- mode list.map3_foldl(pred(in, out, out, out, di, uo) is semidet, in, out, 
-    out, out, di, uo) is semidet.
-:- mode list.map3_foldl(pred(in, out, out, out, in, out) is nondet, in, out, 
-    out, out, in, out) is nondet.
-:- mode list.map3_foldl(pred(in, out, out, out, mdi, muo) is nondet, in, out,
-    out, out, mdi, muo) is nondet.
-:- mode list.map3_foldl(pred(in, out, out, out, in, out) is cc_multi, in, out, 
-    out, out, in, out) is cc_multi.
-:- mode list.map3_foldl(pred(in, out, out, out, di, uo) is cc_multi, in, out, 
-    out, out, di, uo) is cc_multi.
-
     % Same as list.map_foldl, but with two accumulators.
     %
 :- pred list.map_foldl2(pred(L, M, A, A, B, B), list(L), list(M), A, A, B, B).
@@ -1199,24 +1149,6 @@
 :- mode list.map_foldl2(pred(in, out, in, out, in, out) is nondet,
     in, out, in, out, in, out) is nondet.
 
-    % Same as list.map_foldl, but with two mapped outputs and two
-    % accumulators.
-    %
-:- pred list.map2_foldl2(pred(L, M, N, A, A, B, B), list(L), list(M), list(N),
-    A, A, B, B).
-:- mode list.map2_foldl2(pred(in, out, out, in, out, di, uo) is det,
-    in, out, out, in, out, di, uo) is det.
-:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is det,
-    in, out, out, in, out, in, out) is det.
-:- mode list.map2_foldl2(pred(in, out, out, in, out, di, uo) is cc_multi,
-    in, out, out, in, out, di, uo) is cc_multi.
-:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is cc_multi,
-    in, out, out, in, out, in, out) is cc_multi.
-:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is semidet,
-    in, out, out, in, out, in, out) is semidet.
-:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is nondet,
-    in, out, out, in, out, in, out) is nondet.
-
     % Same as list.map_foldl, but with three accumulators.
     %
 :- pred list.map_foldl3(pred(L, M, A, A, B, B, C, C), list(L), list(M),
@@ -1234,30 +1166,6 @@
 :- mode list.map_foldl3(pred(in, out, in, out, in, out, in, out) is nondet,
     in, out, in, out, in, out, in, out) is nondet.
 
-    % Same as list.map_foldl, but with two mapped outputs and three
-    % accumulators.
-    %
-:- pred list.map2_foldl3(pred(L, M, N, A, A, B, B, C, C),
-    list(L), list(M), list(N), A, A, B, B, C, C).
-:- mode list.map2_foldl3(
-    pred(in, out, out, in, out, in, out, in, out) is det,
-    in, out, out, in, out, in, out, in, out) is det.
-:- mode list.map2_foldl3(
-    pred(in, out, out, in, out, in, out, di, uo) is det,
-    in, out, out, in, out, in, out, di, uo) is det.
-:- mode list.map2_foldl3(
-    pred(in, out, out, in, out, in, out, in, out) is cc_multi,
-    in, out, out, in, out, in, out, in, out) is cc_multi.
-:- mode list.map2_foldl3(
-    pred(in, out, out, in, out, in, out, di, uo) is cc_multi,
-    in, out, out, in, out, in, out, di, uo) is cc_multi.
-:- mode list.map2_foldl3(
-    pred(in, out, out, in, out, in, out, in, out) is semidet,
-    in, out, out, in, out, in, out, in, out) is semidet.
-:- mode list.map2_foldl3(
-    pred(in, out, out, in, out, in, out, in, out) is nondet,
-    in, out, out, in, out, in, out, in, out) is nondet.
-
     % Same as list.map_foldl, but with four accumulators.
     %
 :- pred list.map_foldl4(pred(L, M, A, A, B, B, C, C, D, D), list(L), list(M),
@@ -1331,6 +1239,165 @@
     in, out, in, out, in, out, in, out, in, out, in, out, in, out)
     is nondet.
 
+    % Same as list.map_foldl, but with two mapped outputs.
+    %
+:- pred list.map2_foldl(pred(L, M, N, A, A), list(L), list(M), list(N),
+    A, A).
+:- mode list.map2_foldl(pred(in, out, out, in, out) is det, in, out, out,
+    in, out) is det.
+:- mode list.map2_foldl(pred(in, out, out, mdi, muo) is det, in, out, out,
+    mdi, muo) is det.
+:- mode list.map2_foldl(pred(in, out, out, di, uo) is det, in, out, out,
+    di, uo) is det.
+:- mode list.map2_foldl(pred(in, out, out, in, out) is semidet, in, out, out,
+    in, out) is semidet.
+:- mode list.map2_foldl(pred(in, out, out, mdi, muo) is semidet, in, out, out,
+    mdi, muo) is semidet.
+:- mode list.map2_foldl(pred(in, out, out, di, uo) is semidet, in, out, out,
+    di, uo) is semidet.
+:- mode list.map2_foldl(pred(in, out, out, in, out) is nondet, in, out, out,
+    in, out) is nondet.
+:- mode list.map2_foldl(pred(in, out, out, mdi, muo) is nondet, in, out, out,
+    mdi, muo) is nondet.
+:- mode list.map2_foldl(pred(in, out, out, in, out) is cc_multi, in, out, out,
+    in, out) is cc_multi.
+:- mode list.map2_foldl(pred(in, out, out, di, uo) is cc_multi, in, out, out,
+    di, uo) is cc_multi.
+
+    % Same as list.map_foldl, but with two mapped outputs and two
+    % accumulators.
+    %
+:- pred list.map2_foldl2(pred(L, M, N, A, A, B, B), list(L), list(M), list(N),
+    A, A, B, B).
+:- mode list.map2_foldl2(pred(in, out, out, in, out, di, uo) is det,
+    in, out, out, in, out, di, uo) is det.
+:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is det,
+    in, out, out, in, out, in, out) is det.
+:- mode list.map2_foldl2(pred(in, out, out, in, out, di, uo) is cc_multi,
+    in, out, out, in, out, di, uo) is cc_multi.
+:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is cc_multi,
+    in, out, out, in, out, in, out) is cc_multi.
+:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is semidet,
+    in, out, out, in, out, in, out) is semidet.
+:- mode list.map2_foldl2(pred(in, out, out, in, out, in, out) is nondet,
+    in, out, out, in, out, in, out) is nondet.
+
+    % Same as list.map_foldl, but with two mapped outputs and three
+    % accumulators.
+    %
+:- pred list.map2_foldl3(pred(L, M, N, A, A, B, B, C, C),
+    list(L), list(M), list(N), A, A, B, B, C, C).
+:- mode list.map2_foldl3(
+    pred(in, out, out, in, out, in, out, in, out) is det,
+    in, out, out, in, out, in, out, in, out) is det.
+:- mode list.map2_foldl3(
+    pred(in, out, out, in, out, in, out, di, uo) is det,
+    in, out, out, in, out, in, out, di, uo) is det.
+:- mode list.map2_foldl3(
+    pred(in, out, out, in, out, in, out, in, out) is cc_multi,
+    in, out, out, in, out, in, out, in, out) is cc_multi.
+:- mode list.map2_foldl3(
+    pred(in, out, out, in, out, in, out, di, uo) is cc_multi,
+    in, out, out, in, out, in, out, di, uo) is cc_multi.
+:- mode list.map2_foldl3(
+    pred(in, out, out, in, out, in, out, in, out) is semidet,
+    in, out, out, in, out, in, out, in, out) is semidet.
+:- mode list.map2_foldl3(
+    pred(in, out, out, in, out, in, out, in, out) is nondet,
+    in, out, out, in, out, in, out, in, out) is nondet.
+
+    % Same as list.map_foldl, but with two mapped outputs and four
+    % accumulators.
+    %
+:- pred list.map2_foldl4(pred(L, M, N, A, A, B, B, C, C, D, D),
+    list(L), list(M), list(N), A, A, B, B, C, C, D, D).
+:- mode list.map2_foldl4(
+    pred(in, out, out, in, out, in, out, in, out, in, out) is det,
+    in, out, out, in, out, in, out, in, out, in, out) is det.
+:- mode list.map2_foldl4(
+    pred(in, out, out, in, out, in, out, in, out, di, uo) is det,
+    in, out, out, in, out, in, out, in, out, di, uo) is det.
+:- mode list.map2_foldl4(
+    pred(in, out, out, in, out, in, out, in, out, in, out) is cc_multi,
+    in, out, out, in, out, in, out, in, out, in, out) is cc_multi.
+:- mode list.map2_foldl4(
+    pred(in, out, out, in, out, in, out, in, out, di, uo) is cc_multi,
+    in, out, out, in, out, in, out, in, out, di, uo) is cc_multi.
+:- mode list.map2_foldl4(
+    pred(in, out, out, in, out, in, out, in, out, in, out) is semidet,
+    in, out, out, in, out, in, out, in, out, in, out) is semidet.
+:- mode list.map2_foldl4(
+    pred(in, out, out, in, out, in, out, in, out, in, out) is nondet,
+    in, out, out, in, out, in, out, in, out, in, out) is nondet.
+
+    % Same as list.map_foldl, but with three mapped outputs.
+    %
+:- pred list.map3_foldl(pred(L, M, N, O, A, A), list(L), list(M), list(N),
+    list(O), A, A).
+:- mode list.map3_foldl(pred(in, out, out, out, in, out) is det, in, out, out,
+    out, in, out) is det.
+:- mode list.map3_foldl(pred(in, out, out, out, mdi, muo) is det, in, out, out,
+    out, mdi, muo) is det.
+:- mode list.map3_foldl(pred(in, out, out, out, di, uo) is det, in, out, out,
+    out, di, uo) is det.
+:- mode list.map3_foldl(pred(in, out, out, out, in, out) is semidet, in, out, 
+    out, out, in, out) is semidet.
+:- mode list.map3_foldl(pred(in, out, out, out, mdi, muo) is semidet, in, out,
+    out, out, mdi, muo) is semidet.
+:- mode list.map3_foldl(pred(in, out, out, out, di, uo) is semidet, in, out, 
+    out, out, di, uo) is semidet.
+:- mode list.map3_foldl(pred(in, out, out, out, in, out) is nondet, in, out, 
+    out, out, in, out) is nondet.
+:- mode list.map3_foldl(pred(in, out, out, out, mdi, muo) is nondet, in, out,
+    out, out, mdi, muo) is nondet.
+:- mode list.map3_foldl(pred(in, out, out, out, in, out) is cc_multi, in, out, 
+    out, out, in, out) is cc_multi.
+:- mode list.map3_foldl(pred(in, out, out, out, di, uo) is cc_multi, in, out, 
+    out, out, di, uo) is cc_multi.
+
+    % Same as list.map_foldl, but with three mapped outputs and two
+    % accumulators.
+    %
+:- pred list.map3_foldl2(pred(L, M, N, O, A, A, B, B), list(L),
+    list(M), list(N), list(O), A, A, B, B).
+:- mode list.map3_foldl2(pred(in, out, out, out, in, out, di, uo) is det,
+    in, out, out, out, in, out, di, uo) is det.
+:- mode list.map3_foldl2(pred(in, out, out, out, in, out, in, out) is det,
+    in, out, out, out, in, out, in, out) is det.
+:- mode list.map3_foldl2(pred(in, out, out, out, in, out, di, uo) is cc_multi,
+    in, out, out, out, in, out, di, uo) is cc_multi.
+:- mode list.map3_foldl2(pred(in, out, out, out, in, out, in, out) is cc_multi,
+    in, out, out, out, in, out, in, out) is cc_multi.
+:- mode list.map3_foldl2(pred(in, out, out, out, in, out, in, out) is semidet,
+    in, out, out, out, in, out, in, out) is semidet.
+:- mode list.map3_foldl2(pred(in, out, out, out, in, out, in, out) is nondet,
+    in, out, out, out, in, out, in, out) is nondet.
+
+    % Same as list.map_foldl, but with four mapped outputs.
+    %
+:- pred list.map4_foldl(pred(L, M, N, O, P, A, A), list(L), list(M), list(N),
+    list(O), list(P), A, A).
+:- mode list.map4_foldl(pred(in, out, out, out, out, in, out) is det,
+    in, out, out, out, out, in, out) is det.
+:- mode list.map4_foldl(pred(in, out, out, out, out, mdi, muo) is det,
+    in, out, out, out, out, mdi, muo) is det.
+:- mode list.map4_foldl(pred(in, out, out, out, out, di, uo) is det,
+    in, out, out, out, out, di, uo) is det.
+:- mode list.map4_foldl(pred(in, out, out, out, out, in, out) is semidet,
+    in, out, out, out, out, in, out) is semidet.
+:- mode list.map4_foldl(pred(in, out, out, out, out, mdi, muo) is semidet,
+    in, out, out, out, out, mdi, muo) is semidet.
+:- mode list.map4_foldl(pred(in, out, out, out, out, di, uo) is semidet,
+    in, out, out, out, out, di, uo) is semidet.
+:- mode list.map4_foldl(pred(in, out, out, out, out, in, out) is nondet,
+    in, out, out, out, out, in, out) is nondet.
+:- mode list.map4_foldl(pred(in, out, out, out, out, mdi, muo) is nondet,
+    in, out, out, out, out, mdi, muo) is nondet.
+:- mode list.map4_foldl(pred(in, out, out, out, out, in, out) is cc_multi,
+    in, out, out, out, out, in, out) is cc_multi.
+:- mode list.map4_foldl(pred(in, out, out, out, out, di, uo) is cc_multi,
+    in, out, out, out, out, di, uo) is cc_multi.
+
     % list.filter_map_foldl(Transformer, List, TrueList, Start, End):
     % Takes a predicate with one input argument, one output argument and an
     % accumulator. It is called with each element of List. If a call succeeds,
@@ -2487,36 +2554,16 @@
     P(H0, H, !A),
     list.map_foldl(P, T0, T, !A).
 
-list.map2_foldl(_, [], [], [], !A).
-list.map2_foldl(P, [H0 | T0], [H1 | T1], [H2 | T2], !A) :-
-    P(H0, H1, H2, !A),
-    list.map2_foldl(P, T0, T1, T2, !A).
-
-list.map3_foldl(_, [], [], [], [], !A).
-list.map3_foldl(P, [H0 | T0], [H1 | T1], [H2 | T2], [H3 | T3], !A) :-
-    P(H0, H1, H2, H3, !A),
-    list.map3_foldl(P, T0, T1, T2, T3, !A).
-
 list.map_foldl2(_, [], [], !A, !B).
 list.map_foldl2(P, [H0 | T0], [H | T], !A, !B) :-
     P(H0, H, !A, !B),
     list.map_foldl2(P, T0, T, !A, !B).
 
-list.map2_foldl2(_, [], [], [], !A, !B).
-list.map2_foldl2(P, [H0 | T0], [H1 | T1], [H2 | T2], !A, !B) :-
-    P(H0, H1, H2, !A, !B),
-    list.map2_foldl2(P, T0, T1, T2, !A, !B).
-
 list.map_foldl3(_, [], [], !A, !B, !C).
 list.map_foldl3(P, [H0 | T0], [H | T], !A, !B, !C) :-
     P(H0, H, !A, !B, !C),
     list.map_foldl3(P, T0, T, !A, !B, !C).
 
-list.map2_foldl3(_, [], [], [], !A, !B, !C).
-list.map2_foldl3(P, [H0 | T0], [H1 | T1], [H2 | T2], !A, !B, !C) :-
-    P(H0, H1, H2, !A, !B, !C),
-    list.map2_foldl3(P, T0, T1, T2, !A, !B, !C).
-
 list.map_foldl4(_, [], [], !A, !B, !C, !D).
 list.map_foldl4(P, [H0 | T0], [H | T], !A, !B, !C, !D) :-
     P(H0, H, !A, !B, !C, !D),
@@ -2532,6 +2579,41 @@
     P(H0, H, !A, !B, !C, !D, !E, !F),
     list.map_foldl6(P, T0, T, !A, !B, !C, !D, !E, !F).
 
+list.map2_foldl(_, [], [], [], !A).
+list.map2_foldl(P, [H0 | T0], [H1 | T1], [H2 | T2], !A) :-
+    P(H0, H1, H2, !A),
+    list.map2_foldl(P, T0, T1, T2, !A).
+
+list.map2_foldl2(_, [], [], [], !A, !B).
+list.map2_foldl2(P, [H0 | T0], [H1 | T1], [H2 | T2], !A, !B) :-
+    P(H0, H1, H2, !A, !B),
+    list.map2_foldl2(P, T0, T1, T2, !A, !B).
+
+list.map2_foldl3(_, [], [], [], !A, !B, !C).
+list.map2_foldl3(P, [H0 | T0], [H1 | T1], [H2 | T2], !A, !B, !C) :-
+    P(H0, H1, H2, !A, !B, !C),
+    list.map2_foldl3(P, T0, T1, T2, !A, !B, !C).
+
+list.map2_foldl4(_, [], [], [], !A, !B, !C, !D).
+list.map2_foldl4(P, [H0 | T0], [H1 | T1], [H2 | T2], !A, !B, !C, !D) :-
+    P(H0, H1, H2, !A, !B, !C, !D),
+    list.map2_foldl4(P, T0, T1, T2, !A, !B, !C, !D).
+
+list.map3_foldl(_, [], [], [], [], !A).
+list.map3_foldl(P, [H0 | T0], [H1 | T1], [H2 | T2], [H3 | T3], !A) :-
+    P(H0, H1, H2, H3, !A),
+    list.map3_foldl(P, T0, T1, T2, T3, !A).
+
+list.map3_foldl2(_, [], [], [], [], !A, !B).
+list.map3_foldl2(P, [H0 | T0], [H1 | T1], [H2 | T2], [H3 | T3], !A, !B) :-
+    P(H0, H1, H2, H3, !A, !B),
+    list.map3_foldl2(P, T0, T1, T2, T3, !A, !B).
+
+list.map4_foldl(_, [], [], [], [], [], !A).
+list.map4_foldl(P, [H0 | T0], [H1 | T1], [H2 | T2], [H3 | T3], [H4 | T4], !A) :-
+    P(H0, H1, H2, H3, H4, !A),
+    list.map4_foldl(P, T0, T1, T2, T3, T4, !A).
+
 list.filter_map_foldl(_, [], [], !A).
 list.filter_map_foldl(P, [X | Xs], True, !A) :-
     ( P(X, Y, !A) ->
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list