[m-rev.] diff: implicit_parallelism.m breakup

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Jan 4 15:59:54 AEDT 2011


I already discussed the idea with Paul in person, and the implementation is
straighforward, so there is nothing left to review.

Zoltan.

Remove Jerome Tannier's old implicit parallelization transformation, since it
is obsolete, (due to the compiler aborts it generates) not useful even as
a baseline for comparisons, and a maintenance burden.

Divide the remainder of implicit_parallelism.m into two submodules.

compiler/implicit_parallelism.m:
	Make this file a package containing no code.

	Add a comment about where to find Jerome's code.

compiler/introduce_parallism.m:
	The rest of implicit_parallelism.m from a week ago.

compiler/push_goals_together.m:
	The transformation I recently added to implicit_parallelism.m.

compiler/options.m:
	Remove the option calling for Jerome's transformation.

compiler/mercury_compile_middle_passes.m:
	Conform to the changes above.

compiler/follow_code.m:
	Remove some obsolete imports.

compiler/notes/compiler_design.html:
	Document the new modules, as well as implicit_parallelism.m
	(which should have already been listed, but wasn't.)

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/follow_code.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/follow_code.m,v
retrieving revision 1.102
diff -u -b -r1.102 follow_code.m
--- compiler/follow_code.m	3 Jan 2011 06:25:39 -0000	1.102
+++ compiler/follow_code.m	4 Jan 2011 04:42:49 -0000
@@ -51,8 +51,6 @@
 :- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.quantification.
-:- import_module libs.globals.
-:- import_module libs.options.
 :- import_module parse_tree.prog_data.
 
 :- import_module bool.
Index: compiler/implicit_parallelism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/implicit_parallelism.m,v
retrieving revision 1.28
diff -u -b -r1.28 implicit_parallelism.m
--- compiler/implicit_parallelism.m	3 Jan 2011 06:25:40 -0000	1.28
+++ compiler/implicit_parallelism.m	4 Jan 2011 04:33:49 -0000
@@ -7,2541 +7,20 @@
 %-----------------------------------------------------------------------------%
 %
 % File: implicit_parallelism.m.
-% Authors: tannier, pbone.
 %
-% This module uses deep profiling feedback information generated by
-% mdprof_feedback to introduce parallel conjunctions where it could be
-% worthwhile (implicit parallelism). It deals with both independent and
-% dependent parallelism.
+% This package holds the modules that the compiler uses to automatically
+% (implicitly) add parallelism to originally sequential code.
+%
+% The compiler does not support Jerome Tannier's old implicit parallelisation
+% transformation anymore. If you want to know what it did, look at the CVS
+% repository's record for versions of this module prior to the start of 2011.
 %
 %-----------------------------------------------------------------------------%
 
 :- module transform_hlds.implicit_parallelism.
 :- interface.
 
-:- import_module hlds.hlds_module.
-
-:- import_module io.
-
-%-----------------------------------------------------------------------------%
-
-    % apply_implicit_parallelism_transformation(!ModuleInfo, !IO)
-    %
-    % Apply the implicit parallelism transformation using the specified
-    % feedback file.
-    %
-:- pred apply_implicit_parallelism_transformation(
-    module_info::in, module_info::out, io::di, io::uo) is det.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-:- import_module check_hlds.mode_util.
-:- import_module hlds.goal_util.
-:- import_module hlds.hlds_goal.
-:- import_module hlds.hlds_pred.
-:- import_module hlds.hlds_rtti.
-:- import_module hlds.instmap.
-:- import_module hlds.pred_table.
-:- import_module hlds.quantification.
-:- import_module libs.globals.
-:- import_module libs.options.
-:- import_module ll_backend.
-:- import_module ll_backend.prog_rep.
-:- import_module ll_backend.stack_layout.
-:- import_module mdbcomp.feedback.
-:- import_module mdbcomp.feedback.automatic_parallelism.
-:- import_module mdbcomp.prim_data.
-:- import_module mdbcomp.program_representation.
-:- import_module parse_tree.error_util.
-:- import_module parse_tree.prog_data.
-:- import_module transform_hlds.dep_par_conj.
-
-:- import_module assoc_list.
-:- import_module bool.
-:- import_module counter.
-:- import_module int.
-:- import_module list.
-:- import_module map.
-:- import_module maybe.
-:- import_module pair.
-:- import_module require.
-:- import_module set.
-:- import_module string.
-:- import_module svmap.
-:- import_module term.
-:- import_module varset.
-
-%-----------------------------------------------------------------------------%
-
-apply_implicit_parallelism_transformation(!ModuleInfo, !IO) :-
-    module_info_get_globals(!.ModuleInfo, Globals),
-    lookup_bool_option(Globals, old_implicit_parallelism,
-        UseOldImplicitParallelism),
-    (
-        UseOldImplicitParallelism = yes,
-        apply_old_implicit_parallelism_transformation(!.ModuleInfo,
-            MaybeModuleInfo),
-        (
-            MaybeModuleInfo = ok(!:ModuleInfo)
-        ;
-            MaybeModuleInfo = error(Error),
-            sorry($module,
-                "The old implicit parallelism code is not supported: "
-                ++ Error)
-        )
-    ;
-        UseOldImplicitParallelism = no,
-        io_get_maybe_source_file_map(MaybeSourceFileMap, !IO),
-        (
-            MaybeSourceFileMap = yes(SourceFileMap)
-        ;
-            MaybeSourceFileMap = no,
-            unexpected($module, $pred,
-                "could not retrieve the source file map")
-        ),
-        apply_new_implicit_parallelism_transformation(SourceFileMap, Specs,
-            !ModuleInfo),
-        write_error_specs(Specs, Globals, 0, _, 0, NumErrors, !IO),
-        module_info_incr_num_errors(NumErrors, !ModuleInfo)
-    ).
-
-%-----------------------------------------------------------------------------%
-
-    % This type is used to track whether parallelism has been introduced by a
-    % predicate.
-    %
-:- type introduced_parallelism
-    --->    have_not_introduced_parallelism
-    ;       introduced_parallelism.
-
-:- pred apply_new_implicit_parallelism_transformation(source_file_map::in,
-    list(error_spec)::out, module_info::in, module_info::out) is det.
-
-apply_new_implicit_parallelism_transformation(SourceFileMap, Specs,
-        !ModuleInfo) :-
-    module_info_get_globals(!.ModuleInfo, Globals0),
-    globals.get_maybe_feedback_info(Globals0, MaybeFeedbackInfo),
-    module_info_get_name(!.ModuleInfo, ModuleName),
-    (
-        yes(FeedbackInfo) = MaybeFeedbackInfo,
-        get_implicit_parallelism_feedback(ModuleName, FeedbackInfo,
-            ParallelismInfo)
-    ->
-        % Retrieve and process predicates.
-        module_info_get_valid_predids(PredIds, !ModuleInfo),
-        module_info_get_predicate_table(!.ModuleInfo, PredTable0),
-        predicate_table_get_preds(PredTable0, PredMap0),
-        list.foldl4(maybe_parallelise_pred(ParallelismInfo),
-            PredIds, PredMap0, PredMap,
-            have_not_introduced_parallelism, AnyPredIntroducedParallelism,
-            !ModuleInfo, [], Specs),
-        (
-            AnyPredIntroducedParallelism = have_not_introduced_parallelism
-        ;
-            AnyPredIntroducedParallelism = introduced_parallelism,
-            predicate_table_set_preds(PredMap, PredTable0, PredTable),
-            module_info_set_predicate_table(PredTable, !ModuleInfo),
-            module_info_set_contains_par_conj(!ModuleInfo)
-        )
-    ;
-        map.lookup(SourceFileMap, ModuleName, ModuleFilename),
-        Context = context(ModuleFilename, 1),
-        Pieces = [words("Implicit parallelism was requested but the"),
-            words("feedback file does not the candidate parallel"),
-            words("conjunctions feedback information.")],
-        Specs = [error_spec(severity_error, phase_auto_parallelism,
-            [simple_msg(Context, [always(Pieces)])])]
-    ).
-
-    % Information retrieved from the feedback system to be used for
-    % parallelising this module.
-    %
-:- type parallelism_info
-    --->    parallelism_info(
-                pi_parameters           :: candidate_par_conjunctions_params,
-
-                % A map of candidate parallel conjunctions in this module
-                % indexed by their procedure.
-                pi_cpc_map              :: module_candidate_par_conjs_map
-            ).
-
-:- type intra_module_proc_label
-    --->    intra_module_proc_label(
-                im_pred_name            :: string,
-                im_arity                :: int,
-                im_pred_or_func         :: pred_or_func,
-                im_mode                 :: int
-            ).
-
-:- type candidate_par_conjunction == candidate_par_conjunction(pard_goal).
-
-:- type seq_conj == seq_conj(pard_goal).
-
-    % A map of the candidate parallel conjunctions indexed by the procedure
-    % label for a given module.
-    %
-:- type module_candidate_par_conjs_map
-    == map(intra_module_proc_label, candidate_par_conjunctions_proc).
-
-:- pred get_implicit_parallelism_feedback(module_name::in, feedback_info::in,
-    parallelism_info::out) is semidet.
-
-get_implicit_parallelism_feedback(ModuleName, FeedbackInfo, ParallelismInfo) :-
-    FeedbackData =
-        feedback_data_candidate_parallel_conjunctions(_, _),
-    get_feedback_data(FeedbackInfo, FeedbackData),
-    FeedbackData =
-        feedback_data_candidate_parallel_conjunctions(Parameters, AssocList),
-    make_module_candidate_par_conjs_map(ModuleName, AssocList,
-        CandidateParConjsMap),
-    ParallelismInfo = parallelism_info(Parameters, CandidateParConjsMap).
-
-:- pred make_module_candidate_par_conjs_map(module_name::in,
-    assoc_list(string_proc_label, candidate_par_conjunctions_proc)::in,
-    module_candidate_par_conjs_map::out) is det.
-
-make_module_candidate_par_conjs_map(ModuleName,
-        CandidateParConjsAssocList0, CandidateParConjsMap) :-
-    ModuleNameStr = sym_name_to_string(ModuleName),
-    list.filter_map(cpc_proc_is_in_module(ModuleNameStr),
-        CandidateParConjsAssocList0, CandidateParConjsAssocList),
-    CandidateParConjsMap = map.from_assoc_list(CandidateParConjsAssocList).
-
-:- pred cpc_proc_is_in_module(string::in,
-    pair(string_proc_label, candidate_par_conjunctions_proc)::in,
-    pair(intra_module_proc_label, candidate_par_conjunctions_proc)::out)
-    is semidet.
-
-cpc_proc_is_in_module(ModuleName, ProcLabel - CPC, IMProcLabel - CPC) :-
-    (
-        ProcLabel = str_ordinary_proc_label(PredOrFunc, _, DefModule, Name,
-            Arity, Mode)
-    ;
-        ProcLabel = str_special_proc_label(_, _, DefModule, Name, Arity, Mode),
-        PredOrFunc = pf_predicate
-    ),
-    ModuleName = DefModule,
-    IMProcLabel = intra_module_proc_label(Name, Arity, PredOrFunc, Mode).
-
-%-----------------------------------------------------------------------------%
-
-:- pred maybe_parallelise_pred(parallelism_info::in,
-    pred_id::in, pred_table::in, pred_table::out,
-    introduced_parallelism::in, introduced_parallelism::out,
-    module_info::in, module_info::out, 
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-maybe_parallelise_pred(ParallelismInfo, PredId, !PredTable,
-        !AnyPredIntroducedParallelism, !ModuleInfo, !Specs) :-
-    map.lookup(!.PredTable, PredId, PredInfo0),
-    ProcIds = pred_info_non_imported_procids(PredInfo0),
-    pred_info_get_procedures(PredInfo0, ProcTable0),
-    list.foldl4(maybe_parallelise_proc(ParallelismInfo, PredInfo0, PredId),
-        ProcIds, ProcTable0, ProcTable,
-        have_not_introduced_parallelism, AnyProcIntroducedParallelism,
-        !ModuleInfo, !Specs),
-    (
-        AnyProcIntroducedParallelism = have_not_introduced_parallelism
-    ;
-        AnyProcIntroducedParallelism = introduced_parallelism,
-        !:AnyPredIntroducedParallelism = introduced_parallelism,
-        pred_info_set_procedures(ProcTable, PredInfo0, PredInfo),
-        svmap.det_update(PredId, PredInfo, !PredTable)
-    ).
-
-:- pred maybe_parallelise_proc(parallelism_info::in,
-    pred_info::in, pred_id::in, proc_id::in, proc_table::in, proc_table::out,
-    introduced_parallelism::in, introduced_parallelism::out,
-    module_info::in, module_info::out, 
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-maybe_parallelise_proc(ParallelismInfo, PredInfo, _PredId, ProcId,
-        !ProcTable, !AnyProcIntroducedParallelism, !ModuleInfo, !Specs) :-
-    map.lookup(!.ProcTable, ProcId, ProcInfo0),
-
-    % Lookup the Candidate Parallel Conjunction (CPC) Map for this procedure.
-    Name = pred_info_name(PredInfo),
-    Arity = pred_info_orig_arity(PredInfo),
-    PredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    Mode = proc_id_to_int(ProcId),
-    IMProcLabel = intra_module_proc_label(Name, Arity, PredOrFunc, Mode),
-    CPCMap = ParallelismInfo ^ pi_cpc_map,
-    ( map.search(CPCMap, IMProcLabel, CPCProc) ->
-        proc_info_get_has_parallel_conj(ProcInfo0, HasParallelConj),
-        (
-            HasParallelConj = yes,
-            Spec = report_already_parallelised(PredInfo),
-            !:Specs = [Spec | !.Specs]
-        ;
-            HasParallelConj = no,
-            parallelise_proc(CPCProc, PredInfo, ProcInfo0, ProcInfo,
-                ProcIntroducedParallelism, !ModuleInfo, !Specs),
-            (
-                ProcIntroducedParallelism = have_not_introduced_parallelism
-            ;
-                ProcIntroducedParallelism = introduced_parallelism,
-                !:AnyProcIntroducedParallelism = introduced_parallelism,
-                svmap.det_update(ProcId, ProcInfo, !ProcTable)
-            )
-        )
-    ;
-        true
-    ).
-
-:- pred parallelise_proc(candidate_par_conjunctions_proc::in,
-    pred_info::in, proc_info::in, proc_info::out,
-    introduced_parallelism::out,
-    module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-parallelise_proc(CPCProc, PredInfo, !ProcInfo,
-        IntroducedParallelism, !ModuleInfo, !Specs) :-
-    CPCProc = candidate_par_conjunctions_proc(VarTable, PushGoals,
-        CPCs0),
-    (
-        PushGoals = []
-    ;
-        PushGoals = [_ | _],
-        push_goals_in_proc(PushGoals, _Result, !ProcInfo, !ModuleInfo)
-    ),
-
-    proc_info_get_goal(!.ProcInfo, Goal0),
-    Context = goal_info_get_context(Goal0 ^ hlds_goal_info),
-    term.context_file(Context, FileName),
-    proc_info_get_vartypes(!.ProcInfo, VarTypes),
-    % VarNumRep is not used by goal_to_goal_rep, var_num_1_byte
-    % is an arbitrary value. XXX zs: I don't think this is true.
-    VarNumRep = var_num_1_byte,
-    proc_info_get_headvars(!.ProcInfo, HeadVars),
-    proc_info_get_varset(!.ProcInfo, VarSet),
-    compute_var_number_map(HeadVars, VarSet, [], Goal0, VarNumMap),
-    ProgRepInfo = prog_rep_info(FileName, VarTypes, VarNumMap,
-        VarNumRep, !.ModuleInfo),
-    proc_info_get_initial_instmap(!.ProcInfo, !.ModuleInfo, Instmap),
-
-    % Sort the candidate parallelisations so that we introduce
-    % parallelisations in an order that allows us to continue to insert
-    % parallelisations even as the goal tree changes. In particular,
-    % insert deeper parallelisations before shallower ones, and later
-    % ones before earlier ones.
-    list.sort_and_remove_dups(compare_candidate_par_conjunctions, CPCs0, CPCs),
-    list.foldl3(
-        maybe_parallelise_goal(PredInfo, ProgRepInfo, VarTable, Instmap),
-        CPCs, Goal0, Goal,
-        have_not_introduced_parallelism, IntroducedParallelism, !Specs),
-    (
-        IntroducedParallelism = introduced_parallelism,
-        % In the future we'll specialise the procedure for parallelism,
-        % We don't do that now so simply replace the procedure's body.
-        proc_info_set_goal(Goal, !ProcInfo),
-        proc_info_set_has_parallel_conj(yes, !ProcInfo)
-    ;
-        IntroducedParallelism = have_not_introduced_parallelism
-    ).
-
-:- pred compare_candidate_par_conjunctions(candidate_par_conjunction::in,
-    candidate_par_conjunction::in, comparison_result::out) is det.
-
-compare_candidate_par_conjunctions(CPCA, CPCB, Result) :-
-    goal_path_from_string_det(CPCA ^ cpc_goal_path, fgp(StepsA)),
-    goal_path_from_string_det(CPCB ^ cpc_goal_path, fgp(StepsB)),
-    compare_goal_paths(StepsA, StepsB, Result).
-
-:- pred compare_goal_paths(list(goal_path_step)::in, list(goal_path_step)::in,
-    comparison_result::out) is det.
-
-compare_goal_paths(StepsA, StepsB, Result) :-
-    (
-        StepsA = [FirstStepA | LaterStepsA],
-        (
-            StepsB = [FirstStepB | LaterStepsB],
-            compare(Result0, FirstStepA, FirstStepB),
-            % Reverse the ordering here so that later goals are sorted before
-            % earlier ones. This way parallelisations are placed inside later
-            % goals first.
-            (
-                Result0 = (=),
-                compare_goal_paths(LaterStepsA, LaterStepsB, Result)
-            ;
-                Result0 = (<),
-                Result = (>)
-            ;
-                Result0 = (>),
-                Result = (<)
-            )
-        ;
-            StepsB = [],
-            % StepsA is longer than StepsB. Make A 'less than' B so that
-            % deeper parallelisations are inserted first.
-            Result = (<)
-        )
-    ;
-        StepsA = [],
-        (
-            StepsB = [_ | _],
-            % B is 'less than' A, see above.
-            Result = (>)
-        ;
-            StepsB = [],
-            % Both goal paths are empty.
-            Result = (=)
-        )
-    ).
-
-%-----------------------------------------------------------------------------%
-
-:- type push_info
-    --->    push_info(
-                pi_rtti_varmaps         ::  rtti_varmaps
-            ).
-
-:- type push_result
-    --->    push_failed
-    ;       push_succeeded.
-
-    % push_goals_in_proc(PushGoals, OverallResult, !ProcInfo, !ModuleInfo):
-    %
-    % The expensive goals in a procedure are not always in the same
-    % conjunction. However, in some cases, the procedure body can be tranformed
-    % to PUT them into the same conjunction, which can then be parallelised.
-    %
-    % Each PushGoal in PushGoals specifies a transformation that should bring
-    % two or more expensive goals into the same conjunction. This predicate
-    % attempts to perform each of those transformations. It returns
-    % push_succeeded if they all worked, and push_failed if at least one
-    % failed. This can happen because the program has changed since PushGoals
-    % was computed and put into the feedback file, or because PushGoals is
-    % inconsistent (regardless of the date of the file). One example of an
-    % inconsistency would be asking to push a goal into the condition of an
-    % if-then-else.
-    %
-:- pred push_goals_in_proc(list(push_goal)::in, push_result::out,
-    proc_info::in, proc_info::out, module_info::in, module_info::out) is det.
-
-push_goals_in_proc(PushGoals, OverallResult, !ProcInfo, !ModuleInfo) :-
-    proc_info_get_goal(!.ProcInfo, Goal0),
-    proc_info_get_varset(!.ProcInfo, VarSet0),
-    proc_info_get_vartypes(!.ProcInfo, VarTypes0),
-    proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
-    PushInfo = push_info(RttiVarMaps0),
-    do_push_list(PushGoals, PushInfo, OverallResult, Goal0, Goal1),
-    (
-        OverallResult = push_failed
-    ;
-        OverallResult = push_succeeded,
-        % We need to fix up the goal_infos by recalculating the nonlocal sets
-        % and the instmap deltas of the compound goals.
-        proc_info_get_headvars(!.ProcInfo, HeadVars),
-        implicitly_quantify_clause_body_general(ordinary_nonlocals_no_lambda,
-            HeadVars, _Warnings, Goal1, Goal2,
-            VarSet0, VarSet, VarTypes0, VarTypes,
-            RttiVarMaps0, RttiVarMaps),
-        proc_info_get_initial_instmap(!.ProcInfo, !.ModuleInfo, InstMap0),
-        proc_info_get_inst_varset(!.ProcInfo, InstVarSet),
-        recompute_instmap_delta(do_not_recompute_atomic_instmap_deltas,
-            Goal2, Goal, VarTypes, InstVarSet, InstMap0, !ModuleInfo),
-        proc_info_set_goal(Goal, !ProcInfo),
-        proc_info_set_varset(VarSet, !ProcInfo),
-        proc_info_set_vartypes(VarTypes, !ProcInfo),
-        proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo)
-    ).
-
-:- pred do_push_list(list(push_goal)::in, push_info::in,
-    push_result::out, hlds_goal::in, hlds_goal::out) is det.
-
-do_push_list([], _, push_succeeded, !Goal).
-do_push_list([PushGoal | PushGoals], PushInfo, OverallResult, !Goal) :-
-    do_one_push(PushGoal, PushInfo, Result, !Goal),
-    (
-        Result = push_succeeded,
-        do_push_list(PushGoals, PushInfo, OverallResult, !Goal)
-    ;
-        Result = push_failed,
-        OverallResult = push_failed
-    ).
-
-:- pred do_one_push(push_goal::in, push_info::in,
-    push_result::out, hlds_goal::in, hlds_goal::out) is det.
-
-do_one_push(PushGoal, PushInfo, Result, !Goal) :-
-    PushGoal = push_goal(GoalPathStr, _Lo, _Hi, _PushedInto),
-    ( goal_path_from_string(GoalPathStr, GoalPath) ->
-        GoalPath = fgp(GoalPathSteps),
-        do_push_in_goal(GoalPathSteps, PushGoal, PushInfo, Result, !Goal)
-    ;
-        Result = push_failed
-    ).
-
-:- pred do_push_in_goal(list(goal_path_step)::in, push_goal::in, push_info::in,
-    push_result::out, hlds_goal::in, hlds_goal::out) is det.
-
-do_push_in_goal([], PushGoal, PushInfo, Result, !Goal) :-
-    % We have arrives at the goal in which the push should take place.
-    perform_push_transform(PushGoal, PushInfo, Result, !Goal).
-do_push_in_goal([Step | Steps], PushGoal, PushInfo, Result, !Goal) :-
-    !.Goal = hlds_goal(GoalExpr0, GoalInfo0),
-    (
-        Step = step_conj(N),
-        ( GoalExpr0 = conj(ConjType, Goals0) ->
-            do_push_in_goals(N, Steps, PushGoal, PushInfo, Result,
-                Goals0, Goals),
-            GoalExpr = conj(ConjType, Goals),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        Step = step_disj(N),
-        ( GoalExpr0 = disj(Goals0) ->
-            do_push_in_goals(N, Steps, PushGoal, PushInfo, Result,
-                Goals0, Goals),
-            GoalExpr = disj(Goals),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        Step = step_switch(N, _),
-        ( GoalExpr0 = switch(Var, CanFail, Cases0) ->
-            do_push_in_cases(N, Steps, PushGoal, PushInfo, Result,
-                Cases0, Cases),
-            GoalExpr = switch(Var, CanFail, Cases),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        Step = step_ite_cond,
-        ( GoalExpr0 = if_then_else(Vars0, Cond0, Then0, Else0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result, Cond0, Cond),
-            GoalExpr = if_then_else(Vars0, Cond, Then0, Else0),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        Step = step_ite_then,
-        ( GoalExpr0 = if_then_else(Vars0, Cond0, Then0, Else0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result, Then0, Then),
-            GoalExpr = if_then_else(Vars0, Cond0, Then, Else0),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        Step = step_ite_else,
-        ( GoalExpr0 = if_then_else(Vars0, Cond0, Then0, Else0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result, Else0, Else),
-            GoalExpr = if_then_else(Vars0, Cond0, Then0, Else),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        Step = step_neg,
-        ( GoalExpr0 = negation(SubGoal0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result,
-                SubGoal0, SubGoal),
-            GoalExpr = negation(SubGoal),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        Step = step_scope(_),
-        ( GoalExpr0 = scope(Reason, SubGoal0) ->
-            do_push_in_goal(Steps, PushGoal, PushInfo, Result,
-                SubGoal0, SubGoal),
-            GoalExpr = scope(Reason, SubGoal),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo0)
-        ;
-            Result = push_failed
-        )
-    ;
-        ( Step = step_lambda
-        ; Step = step_try
-        ; Step = step_atomic_main
-        ; Step = step_atomic_orelse(_)
-        ),
-        % The constructs represented by these steps should have been
-        % expanded out by now.
-        Result = push_failed
-    ).
-
-:- pred do_push_in_goals(int::in, list(goal_path_step)::in, push_goal::in,
-    push_info::in, push_result::out,
-    list(hlds_goal)::in, list(hlds_goal)::out) is det.
-
-do_push_in_goals(_N, _Steps, _PushGoal, _PushInfo, push_failed, [], []).
-do_push_in_goals(N, Steps, PushGoal, PushInfo, Result,
-        [Goal0 | Goals0], [Goal | Goals]) :-
-    ( N = 1 ->
-        do_push_in_goal(Steps, PushGoal, PushInfo, Result, Goal0, Goal),
-        Goals = Goals0
-    ;
-        Goal = Goal0,
-        do_push_in_goals(N - 1, Steps, PushGoal, PushInfo, Result,
-            Goals0, Goals)
-    ).
-
-:- pred do_push_in_cases(int::in, list(goal_path_step)::in, push_goal::in,
-    push_info::in, push_result::out, list(case)::in, list(case)::out) is det.
-
-do_push_in_cases(_N, _Steps, _PushGoal, _PushInfo, push_failed, [], []).
-do_push_in_cases(N, Steps, PushGoal, PushInfo, Result,
-        [Case0 | Cases0], [Case | Cases]) :-
-    ( N = 1 ->
-        Case0 = case(MainConsId, OtherConsIds, Goal0),
-        do_push_in_goal(Steps, PushGoal, PushInfo, Result, Goal0, Goal),
-        Case = case(MainConsId, OtherConsIds, Goal),
-        Cases = Cases0
-    ;
-        Case = Case0,
-        do_push_in_cases(N - 1, Steps, PushGoal, PushInfo, Result,
-            Cases0, Cases)
-    ).
-
-:- pred perform_push_transform(push_goal::in, push_info::in,
-    push_result::out, hlds_goal::in, hlds_goal::out) is det.
-
-perform_push_transform(PushGoal, PushInfo, Result, !Goal) :-
-    PushGoal = push_goal(GoalPathStr, Lo, Hi, PushedInto),
-    goal_path_from_string_det(GoalPathStr, GoalPath),
-    !.Goal = hlds_goal(GoalExpr0, GoalInfo0),
-    (
-        GoalExpr0 = conj(plain_conj, Conjuncts),
-        find_lo_hi_goals(PushInfo, Conjuncts, Lo, Hi, 1, Before0, LoHi, After,
-            pushable),
-        find_relative_paths(GoalPath, PushedInto, RelGoalSteps),
-        RelGoalSteps = [HeadRelGoalSteps | TailRelGoalSteps],
-        HeadRelGoalSteps = [step_conj(PushConjNum) | HeadRestRelSteps],
-        list.map(maybe_steps_after(step_conj(PushConjNum)),
-            TailRelGoalSteps, TailRestRelSteps),
-        list.index1(Before0, PushConjNum, PushIntoGoal0),
-        push_into_goal(LoHi, HeadRestRelSteps, TailRestRelSteps,
-            PushIntoGoal0, PushIntoGoal, pushable),
-        % If PushConjNum specifies a conjunct that is NOT the last conjunct
-        % before Lo, then this transformation reorders the code.
-        % For now, we don't allow that.
-        PushConjNum + 1 = Lo
-    ->
-        list.replace_nth_det(Before0, PushConjNum, PushIntoGoal, Before),
-        GoalExpr = conj(plain_conj, Before ++ After),
-        !:Goal = hlds_goal(GoalExpr, GoalInfo0),
-        Result = push_succeeded
-    ;
-        Result = push_failed
-    ).
-
-:- pred maybe_steps_after(goal_path_step::in,
-    list(goal_path_step)::in, list(goal_path_step)::out) is semidet.
-
-maybe_steps_after(Step, [Step | Tail], Tail).
-
-    % find_lo_hi_goals(PushInfo, Conjuncts, Lo, Hi, Cur, Before, LoHi, After,
-    %   Pushable):
-    %
-    % Given a list of conjuncts in which the head conjunct (if it exists)
-    % has index Cur, and a range of integers Lo..Hi, where Cur =< Lo,
-    % return the list of conjuncts with indexes Lo..Hi in LoHi,
-    % the conjuncts before them in Before, and the conjuncts after them
-    % in After, PROVIDED that
-    %   - conjuncts with indexes Lo..Hi actually exist, and
-    %   - all those conjuncts are pushable.
-    % If either of these conditions isn't met, return Pushable = not_pushable,
-    % and garbage in Before, LoHi and After.
-    %
-:- pred find_lo_hi_goals(push_info::in, list(hlds_goal)::in, int::in, int::in,
-    int::in, list(hlds_goal)::out, list(hlds_goal)::out, list(hlds_goal)::out,
-    maybe_pushable::out) is det.
-
-find_lo_hi_goals(PushInfo, Conjuncts, Lo, Hi, Cur, Before, LoHi, After,
-        Pushable) :-
-    ( Cur = Lo ->
-        find_hi_goals(PushInfo, Conjuncts, Hi, Cur, LoHi, After, Pushable),
-        Before = []
-    ;
-        (
-            Conjuncts = [],
-            Before = [],
-            LoHi = [],
-            After = [],
-            Pushable = not_pushable
-        ;
-            Conjuncts = [Head | Tail],
-            find_lo_hi_goals(PushInfo, Tail, Lo, Hi, Cur + 1,
-                BeforeTail, LoHi, After, Pushable),
-            Before = [Head | BeforeTail]
-        )
-    ).
-
-    % find_hi_goals(PushInfo, Conjuncts, Hi, Cur, LoHi, After, Pushable):
-    %
-    % Given a list of conjuncts in which the head conjunct (if it exists)
-    % has index Cur, and an integer Hi, where Cur =< Hi,
-    % return the list of conjuncts with indexes up to Hi in LoHi,
-    % and the conjuncts after them in After, PROVIDED that
-    %   - conjuncts with indexes up to Hi actually exist, and
-    %   - all those conjuncts are pushable.
-    % If either of these conditions isn't met, return Pushable = not_pushable,
-    % and garbage in LoHi and After.
-    %
-:- pred find_hi_goals(push_info::in, list(hlds_goal)::in, int::in, int::in,
-    list(hlds_goal)::out, list(hlds_goal)::out, maybe_pushable::out) is det.
-
-find_hi_goals(_PushInfo, [], _Hi, _Cur, [], [], not_pushable).
-find_hi_goals(PushInfo, [Head | Tail], Hi, Cur, LoHi, After, Pushable) :-
-    is_pushable_goal(PushInfo, Head, HeadPushable),
-    (
-        HeadPushable = pushable,
-        ( Cur = Hi ->
-            LoHi = [Head],
-            After = Tail,
-            Pushable = pushable
-        ;
-            find_hi_goals(PushInfo, Tail, Hi, Cur + 1, LoHiTail, After,
-                Pushable),
-            LoHi = [Head | LoHiTail]
-        )
-    ;
-        HeadPushable = not_pushable,
-        LoHi = [],
-        After = [],
-        Pushable = not_pushable
-    ).
-
-:- type maybe_pushable
-    --->    not_pushable
-    ;       pushable.
-
-    % Check whether pushing the given goal, which will require duplicating it,
-    % would be ok, or whether it would cause problems by altering the
-    % pushed-into goal's purity, by altering its determinism, or
-    % by screwing up the compiler's record of existentially typed variables.
-    %
-:- pred is_pushable_goal(push_info::in, hlds_goal::in,
-    maybe_pushable::out) is det.
-
-is_pushable_goal(PushInfo, Goal, Pushable) :-
-    Goal = hlds_goal(GoalExpr, GoalInfo),
-    Purity = goal_info_get_purity(GoalInfo),
-    Detism = goal_info_get_determinism(GoalInfo),
-    (
-        Purity = purity_pure,
-        Detism = detism_det
-    ->
-        (
-            GoalExpr = unify(_, _, _, Unification, _),
-            (
-                ( Unification = assign(_, _)
-                ; Unification = simple_test(_, _)
-                ; Unification = construct(_, _, _, _, _, _, _)
-                ),
-                Pushable = pushable
-            ;
-                Unification = deconstruct(_, _, Args, _, _, _),
-                RttiVarMaps = PushInfo ^ pi_rtti_varmaps,
-                ( list.all_true(is_non_rtti_var(RttiVarMaps), Args) ->
-                    Pushable = pushable
-                ;
-                    Pushable = not_pushable
-                )
-            ;
-                Unification = complicated_unify(_, _, _),
-                unexpected($module, $pred, "complicated_unify")
-            )
-        ;
-            ( GoalExpr = plain_call(_, _, _, _, _, _)
-            ; GoalExpr = generic_call(_, _, _, _)
-            ; GoalExpr = call_foreign_proc(_, _, _, _, _, _, _)
-            ),
-            Pushable = pushable
-        ;
-            ( GoalExpr = conj(_, Goals)
-            ; GoalExpr = disj(Goals)
-            ),
-            is_pushable_goal_list(PushInfo, Goals, Pushable)
-        ;
-            GoalExpr = switch(_, _, Cases),
-            is_pushable_case_list(PushInfo, Cases, Pushable)
-        ;
-            GoalExpr = if_then_else(_, Cond, Then, Else),
-            is_pushable_goal_list(PushInfo, [Cond, Then, Else], Pushable)
-        ;
-            ( GoalExpr = negation(SubGoal)
-            ; GoalExpr = scope(_, SubGoal)
-            ),
-            is_pushable_goal(PushInfo, SubGoal, Pushable)
-        ;
-            GoalExpr = shorthand(Shorthand),
-            (
-                ( Shorthand = atomic_goal(_, _, _, _, _, _, _)
-                ; Shorthand = try_goal(_, _, _)
-                ),
-                % May be too conservative, but better safe than sorry.
-                Pushable = not_pushable
-            ;
-                Shorthand = bi_implication(_, _),
-                unexpected($module, $pred, "bi_implication")
-            )
-        )
-    ;
-        Pushable = not_pushable
-    ).
-
-:- pred is_non_rtti_var(rtti_varmaps::in, prog_var::in) is semidet.
-
-is_non_rtti_var(RttiVarMaps, Arg) :-
-    rtti_varmaps_var_info(RttiVarMaps, Arg, RttiVarInfo),
-    RttiVarInfo = non_rtti_var.
-
-:- pred is_pushable_goal_list(push_info::in, list(hlds_goal)::in,
-    maybe_pushable::out) is det.
-
-is_pushable_goal_list(_PushInfo, [], pushable).
-is_pushable_goal_list(PushInfo, [Goal | Goals], Pushable) :-
-    is_pushable_goal(PushInfo, Goal, GoalPushable),
-    (
-        GoalPushable = not_pushable,
-        Pushable = not_pushable
-    ;
-        GoalPushable = pushable,
-        is_pushable_goal_list(PushInfo, Goals, Pushable)
-    ).
-
-:- pred is_pushable_case_list(push_info::in, list(case)::in,
-    maybe_pushable::out) is det.
-
-is_pushable_case_list(_PushInfo, [], pushable).
-is_pushable_case_list(PushInfo, [Case | Cases], Pushable) :-
-    Case = case(_MainConsId, _OtherConsIds, Goal),
-    is_pushable_goal(PushInfo, Goal, GoalPushable),
-    (
-        GoalPushable = not_pushable,
-        Pushable = not_pushable
-    ;
-        GoalPushable = pushable,
-        is_pushable_case_list(PushInfo, Cases, Pushable)
-    ).
-
-:- pred find_relative_paths(forward_goal_path::in, list(goal_path_string)::in,
-    list(list(goal_path_step))::out) is semidet.
-
-find_relative_paths(_GoalPath, [], []).
-find_relative_paths(GoalPath, [HeadStr | TailStrs],
-        [HeadRelSteps | TailRelSteps]) :-
-    goal_path_from_string(HeadStr, HeadGoalPath),
-    GoalPath = fgp(GoalPathSteps),
-    HeadGoalPath = fgp(HeadGoalPathSteps),
-    list.append(GoalPathSteps, HeadRelSteps, HeadGoalPathSteps),
-    find_relative_paths(GoalPath, TailStrs, TailRelSteps).
-
-    % push_into_goal(LoHi, HeadSteps, TailSteps, Goal0, Goal, Pushable):
-    %
-    % Push the goals LoHi into Goal0, putting them at the ends of the
-    % (possibly implicit) conjunctions holding the expensive goals indicated
-    % by the goal paths [HeadSteps | TailSteps], which are all relative to
-    % Goal0, and at the ends of the branches that are alternatives to these.
-    %
-    % Return Pushable = pushable if the transformation was successful.
-    % Return Pushable = not_pushable and a garbage Goal if it wasn't.
-    %
-    % The returned goal will need to have its nonlocal sets and instmap deltas
-    % recomputed.
-    %
-    % For example, if HeadSteps and TailSteps together specified the two
-    % expensive goals in the original goal below,
-    %
-    %   ( Cond ->
-    %       (
-    %           X = f,
-    %           EXPENSIVE GOAL 1,
-    %           cheap goal 2
-    %       ;
-    %           X = g,
-    %           cheap goal 3
-    %       )
-    %   ;
-    %       EXPENSIVE GOAL 4
-    %   )
-    %
-    % this predicate should return this transformed goal:
-    %
-    %   ( Cond ->
-    %       (
-    %           X = f,
-    %           EXPENSIVE GOAL 1,
-    %           cheap goal 2,
-    %           LoHi
-    %       ;
-    %           X = g,
-    %           cheap goal 3,
-    %           LoHi
-    %       )
-    %   ;
-    %       EXPENSIVE GOAL 4,
-    %       LoHi
-    %   )
-    %
-:- pred push_into_goal(list(hlds_goal)::in,
-    list(goal_path_step)::in, list(list(goal_path_step))::in,
-    hlds_goal::in, hlds_goal::out, maybe_pushable::out) is det.
-
-push_into_goal(LoHi, HeadSteps, TailSteps, Goal0, Goal, Pushable) :-
-    Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
-    (
-        HeadSteps = [],
-        expect(unify(TailSteps, []), $module, "TailSteps != []"),
-        add_goals_at_end(LoHi, Goal0, Goal),
-        Pushable = pushable
-    ;
-        HeadSteps = [FirstHeadStep | LaterHeadSteps],
-        (
-            ( GoalExpr0 = unify(_, _, _, _, _)
-            ; GoalExpr0 = plain_call(_, _, _, _, _, _)
-            ; GoalExpr0 = generic_call(_, _, _, _)
-            ; GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
-            ),
-            Goal = Goal0,
-            Pushable = not_pushable
-        ;
-            GoalExpr0 = conj(ConjType, Conjuncts0),
-            (
-                % If the expensive goal is a conjunct in this conjunction,
-                % then put LoHi at the end of this conjunction.
-                FirstHeadStep = step_conj(_),
-                LaterHeadSteps = []
-            ->
-                expect(unify(TailSteps, []), $module, "TailSteps != []"),
-                add_goals_at_end(LoHi, Goal0, Goal),
-                Pushable = pushable
-            ;
-                % If the expensive goal or goals are INSIDE a conjunct
-                % in this conjunction, push LoHi into the selected conjunct.
-                % We insist on all expensive goals being inside the SAME
-                % conjunct, because  pushing LoHi into more than one conjunct
-                % would be a mode error.
-                %
-                FirstHeadStep = step_conj(ConjNum),
-                list.map(maybe_steps_after(step_conj(ConjNum)), TailSteps,
-                    LaterTailSteps),
-                list.index1(Conjuncts0, ConjNum, SelectedConjunct0),
-
-                % If ConjNum specifies a conjunct that is NOT the last
-                % conjunct, then this transformation reorders the code.
-                % For now, we don't allow that.
-                list.length(Conjuncts0, Length),
-                ConjNum = Length
-            ->
-                push_into_goal(LoHi, LaterHeadSteps, LaterTailSteps,
-                    SelectedConjunct0, SelectedConjunct, Pushable),
-                list.replace_nth_det(Conjuncts0, ConjNum, SelectedConjunct,
-                    Conjuncts),
-                GoalExpr = conj(ConjType, Conjuncts),
-                Goal = hlds_goal(GoalExpr, GoalInfo0)
-            ;
-                Goal = Goal0,
-                Pushable = not_pushable
-            )
-        ;
-            GoalExpr0 = disj(Disjuncts0),
-            (
-                build_disj_steps_map([HeadSteps | TailSteps], map.init,
-                    StepMap)
-            ->
-                map.to_assoc_list(StepMap, StepList),
-                push_into_disjuncts(LoHi, StepList, 1, Disjuncts0, Disjuncts,
-                    Pushable),
-                GoalExpr = disj(Disjuncts),
-                Goal = hlds_goal(GoalExpr, GoalInfo0)
-            ;
-                Goal = Goal0,
-                Pushable = not_pushable
-            )
-        ;
-            GoalExpr0 = switch(Var, CanFail, Cases0),
-            (
-                build_switch_steps_map([HeadSteps | TailSteps], map.init,
-                    StepMap)
-            ->
-                map.to_assoc_list(StepMap, StepList),
-                push_into_cases(LoHi, StepList, 1, Cases0, Cases, Pushable),
-                GoalExpr = switch(Var, CanFail, Cases),
-                Goal = hlds_goal(GoalExpr, GoalInfo0)
-            ;
-                Goal = Goal0,
-                Pushable = not_pushable
-            )
-        ;
-            GoalExpr0 = if_then_else(Vars, Cond, Then0, Else0),
-            (
-                build_ite_steps_map([HeadSteps | TailSteps],
-                    ThenSteps, ElseSteps)
-            ->
-                (
-                    ThenSteps = [],
-                    add_goals_at_end(LoHi, Then0, Then),
-                    ThenPushable = pushable
-                ;
-                    ThenSteps = [ThenStepsHead | ThenStepsTail],
-                    push_into_goal(LoHi, ThenStepsHead, ThenStepsTail,
-                        Then0, Then, ThenPushable)
-                ),
-                (
-                    ElseSteps = [],
-                    add_goals_at_end(LoHi, Else0, Else),
-                    ElsePushable = pushable
-                ;
-                    ElseSteps = [ElseStepsHead | ElseStepsTail],
-                    push_into_goal(LoHi, ElseStepsHead, ElseStepsTail,
-                        Else0, Else, ElsePushable)
-                ),
-                (
-                    ThenPushable = pushable,
-                    ElsePushable = pushable
-                ->
-                    GoalExpr = if_then_else(Vars, Cond, Then, Else),
-                    Goal = hlds_goal(GoalExpr, GoalInfo0),
-                    Pushable = pushable
-                ;
-                    Goal = Goal0,
-                    Pushable = not_pushable
-                )
-            ;
-                Goal = Goal0,
-                Pushable = not_pushable
-            )
-        ;
-            GoalExpr0 = negation(_SubGoal0),
-            % Pushing goals into a negation changes the meaning of the program.
-            Goal = Goal0,
-            Pushable = not_pushable
-        ;
-            GoalExpr0 = scope(Reason, SubGoal0),
-            SubGoal0 = hlds_goal(_SubGoalExpr0, SubGoalInfo0),
-            Detism = goal_info_get_determinism(GoalInfo0),
-            SubDetism = goal_info_get_determinism(SubGoalInfo0),
-            (
-                Detism = SubDetism,
-                maybe_steps_after(step_neg, HeadSteps, HeadStepsAfter),
-                list.map(maybe_steps_after(step_neg), TailSteps,
-                    TailStepsAfter)
-            ->
-                push_into_goal(LoHi, HeadStepsAfter, TailStepsAfter,
-                    SubGoal0, SubGoal, Pushable),
-                GoalExpr = scope(Reason, SubGoal),
-                Goal = hlds_goal(GoalExpr, GoalInfo0)
-            ;
-                Goal = Goal0,
-                Pushable = not_pushable
-            )
-        ;
-            GoalExpr0 = shorthand(Shorthand),
-            (
-                ( Shorthand = atomic_goal(_, _, _, _, _, _, _)
-                ; Shorthand = try_goal(_, _, _)
-                ),
-                Goal = Goal0,
-                Pushable = not_pushable
-            ;
-                Shorthand = bi_implication(_, _),
-                unexpected($module, $pred, "bi_implication")
-            )
-        )
-    ).
-
-:- pred push_into_case(list(hlds_goal)::in,
-    list(goal_path_step)::in, list(list(goal_path_step))::in,
-    case::in, case::out, maybe_pushable::out) is det.
-
-push_into_case(LoHi, HeadSteps, TailSteps, Case0, Case, Pushable) :-
-    Case0 = case(MainConsId, OtherConsIds, Goal0),
-    push_into_goal(LoHi, HeadSteps, TailSteps, Goal0, Goal, Pushable),
-    Case = case(MainConsId, OtherConsIds, Goal).
-
-:- pred push_into_disjuncts(list(hlds_goal)::in,
-    assoc_list(int, one_or_more(list(goal_path_step)))::in,
-    int::in, list(hlds_goal)::in, list(hlds_goal)::out, maybe_pushable::out)
-    is det.
-
-push_into_disjuncts(_LoHi, DisjStepList, _Cur, [], [], Pushable) :-
-    (
-        DisjStepList = [],
-        Pushable = pushable
-    ;
-        DisjStepList = [_ | _],
-        Pushable = not_pushable
-    ).
-push_into_disjuncts(LoHi, StepList, Cur, [HeadDisjunct0 | TailDisjuncts0],
-        [HeadDisjunct | TailDisjuncts], Pushable) :-
-    (
-        StepList = [],
-        add_goals_at_end(LoHi, HeadDisjunct0, HeadDisjunct),
-        list.map(add_goals_at_end(LoHi), TailDisjuncts0, TailDisjuncts),
-        Pushable = pushable
-    ;
-        StepList = [StepListHead | StepListTail],
-        (
-            StepListHead = StepListHeadNum - one_or_more(One, More),
-            ( StepListHeadNum = Cur ->
-                push_into_goal(LoHi, One, More, HeadDisjunct0, HeadDisjunct,
-                    GoalPushable),
-                (
-                    GoalPushable = pushable,
-                    push_into_disjuncts(LoHi, StepListTail, Cur + 1,
-                        TailDisjuncts0, TailDisjuncts, Pushable)
-                ;
-                    GoalPushable = not_pushable,
-                    TailDisjuncts = TailDisjuncts0,
-                    Pushable = not_pushable
-                )
-            ;
-                add_goals_at_end(LoHi, HeadDisjunct0, HeadDisjunct),
-                push_into_disjuncts(LoHi, StepList, Cur + 1,
-                    TailDisjuncts0, TailDisjuncts, Pushable)
-            )
-        )
-    ).
-
-:- pred push_into_cases(list(hlds_goal)::in,
-    assoc_list(int, one_or_more(list(goal_path_step)))::in,
-    int::in, list(case)::in, list(case)::out, maybe_pushable::out) is det.
-
-push_into_cases(_LoHi, StepList, _Cur, [], [], Pushable) :-
-    (
-        StepList = [],
-        Pushable = pushable
-    ;
-        StepList = [_ | _],
-        Pushable = not_pushable
-    ).
-push_into_cases(LoHi, StepList, Cur, [HeadCase0 | TailCases0],
-        [HeadCase | TailCases], Pushable) :-
-    (
-        StepList = [],
-        add_goals_at_end_of_case(LoHi, HeadCase0, HeadCase),
-        list.map(add_goals_at_end_of_case(LoHi), TailCases0, TailCases),
-        Pushable = pushable
-    ;
-        StepList = [StepListHead | StepListTail],
-        (
-            StepListHead = StepListHeadNum - one_or_more(One, More),
-            ( StepListHeadNum = Cur ->
-                push_into_case(LoHi, One, More, HeadCase0, HeadCase,
-                    GoalPushable),
-                (
-                    GoalPushable = pushable,
-                    push_into_cases(LoHi, StepListTail, Cur + 1,
-                        TailCases0, TailCases, Pushable)
-                ;
-                    GoalPushable = not_pushable,
-                    TailCases = TailCases0,
-                    Pushable = not_pushable
-                )
-            ;
-                add_goals_at_end_of_case(LoHi, HeadCase0, HeadCase),
-                push_into_cases(LoHi, StepList, Cur + 1,
-                    TailCases0, TailCases, Pushable)
-            )
-        )
-    ).
-
-:- pred build_disj_steps_map(list(list(goal_path_step))::in,
-    map(int, one_or_more(list(goal_path_step)))::in,
-    map(int, one_or_more(list(goal_path_step)))::out) is semidet.
-
-build_disj_steps_map([], !DisjStepMap).
-build_disj_steps_map([Head | Tail], !DisjStepMap) :-
-    Head = [step_disj(N) | HeadSteps],
-    ( map.search(!.DisjStepMap, N, one_or_more(One, More)) ->
-        svmap.det_update(N, one_or_more(HeadSteps, [One | More]), !DisjStepMap)
-    ;
-        svmap.det_insert(N, one_or_more(HeadSteps, []), !DisjStepMap)
-    ),
-    build_disj_steps_map(Tail, !DisjStepMap).
-
-:- pred build_switch_steps_map(list(list(goal_path_step))::in,
-    map(int, one_or_more(list(goal_path_step)))::in,
-    map(int, one_or_more(list(goal_path_step)))::out) is semidet.
-
-build_switch_steps_map([], !DisjStepMap).
-build_switch_steps_map([Head | Tail], !DisjStepMap) :-
-    Head = [step_switch(N, _) | HeadSteps],
-    ( map.search(!.DisjStepMap, N, one_or_more(One, More)) ->
-        svmap.det_update(N, one_or_more(HeadSteps, [One | More]), !DisjStepMap)
-    ;
-        svmap.det_insert(N, one_or_more(HeadSteps, []), !DisjStepMap)
-    ),
-    build_switch_steps_map(Tail, !DisjStepMap).
-
-:- pred build_ite_steps_map(list(list(goal_path_step))::in,
-    list(list(goal_path_step))::out, list(list(goal_path_step))::out)
-    is semidet.
-
-build_ite_steps_map([], [], []).
-build_ite_steps_map([Head | Tail], ThenSteps, ElseSteps) :-
-    build_ite_steps_map(Tail, ThenStepsTail, ElseStepsTail),
-    Head = [HeadFirstStep | HeadSteps],
-    ( HeadFirstStep = step_ite_then ->
-        ThenSteps = [HeadSteps | ThenStepsTail],
-        ElseSteps = ElseStepsTail
-    ; HeadFirstStep = step_ite_then ->
-        ThenSteps = ThenStepsTail,
-        ElseSteps = [HeadSteps | ElseStepsTail]
-    ;
-        fail
-    ).
-
-:- pred add_goals_at_end(list(hlds_goal)::in, hlds_goal::in, hlds_goal::out)
-    is det.
-
-add_goals_at_end(AddedGoals, Goal0, Goal) :-
-    Goal0 = hlds_goal(GoalExpr0, _GoalInfo0),
-    ( GoalExpr0 = conj(plain_conj, Conjuncts0) ->
-        create_conj_from_list(Conjuncts0 ++ AddedGoals, plain_conj, Goal)
-    ;
-        create_conj_from_list([Goal0 | AddedGoals], plain_conj, Goal)
-    ).
-
-:- pred add_goals_at_end_of_case(list(hlds_goal)::in, case::in, case::out)
-    is det.
-
-add_goals_at_end_of_case(AddedGoals, Case0, Case) :-
-    Case0 = case(MainConsId, OtherConsIds, Goal0),
-    add_goals_at_end(AddedGoals, Goal0, Goal),
-    Case = case(MainConsId, OtherConsIds, Goal).
-
-:- type one_or_more(T)
-    --->    one_or_more(T, list(T)).
-
-%-----------------------------------------------------------------------------%
-
-    % maybe_parallelise_goal(ProgRepInfo, VarTable, CPC, !Goal,
-    %   !IntroducedParallelism).
-    %
-    % Attempt to parallelise some part of !.Goal returning !:Goal.
-    % If !.IntroducedParallelism = have_not_introduced_parallelism then !Goal
-    % will be unmodified.
-    %
-:- pred maybe_parallelise_goal(pred_info::in, prog_rep_info::in,
-    var_table::in, instmap::in, candidate_par_conjunction::in,
-    hlds_goal::in, hlds_goal::out,
-    introduced_parallelism::in, introduced_parallelism::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
+:- include_module introduce_parallelism.
+:- include_module push_goals_together.
 
-maybe_parallelise_goal(PredInfo, ProgRepInfo, VarTable, Instmap0, CPC, Goal0,
-        Goal, !IntroducedParallelism, !Specs) :-
-    TargetGoalPathString = CPC ^ cpc_goal_path,
-    ( goal_path_from_string(TargetGoalPathString, TargetGoalPathPrime) ->
-        TargetGoalPath = TargetGoalPathPrime
-    ;
-        unexpected($module, $pred,
-            "Invalid goal path in CPC Feedback Information")
-    ),
-    maybe_transform_goal_at_goal_path_with_instmap(
-        maybe_parallelise_conj(ProgRepInfo, VarTable, CPC),
-        TargetGoalPath, Instmap0, Goal0, MaybeGoal),
-    (
-        MaybeGoal = ok(Goal),
-        !:IntroducedParallelism = introduced_parallelism
-    ;
-        (
-            MaybeGoal = error(Error)
-        ;
-            MaybeGoal = goal_not_found,
-            Error = "Could not find goal in procedure; "
-                ++ "perhaps the program has changed"
-        ),
-        Goal = Goal0,
-        Spec = report_failed_parallelisation(PredInfo, TargetGoalPathString,
-            Error),
-        !:Specs = [Spec | !.Specs]
-    ).
-
-:- func report_failed_parallelisation(pred_info, string, string) =
-    error_spec.
-
-report_failed_parallelisation(PredInfo, GoalPath, Error) = Spec :-
-    % Should the severity be informational?
-    PredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    ModuleName = pred_info_module(PredInfo),
-    PredName = pred_info_name(PredInfo),
-    Arity = pred_info_orig_arity(PredInfo),
-    Pieces = [words("In"), p_or_f(PredOrFunc),
-        sym_name_and_arity(qualified(ModuleName, PredName) / Arity),
-        suffix(":"), nl,
-        words("Warning: could not auto-parallelise"), quote(GoalPath),
-        suffix(":"), words(Error)],
-    pred_info_get_context(PredInfo, Context),
-    % XXX Make this a warning or error if the user wants compilation to
-    % abort.
-    Spec = error_spec(severity_informational, phase_auto_parallelism,
-        [simple_msg(Context, [always(Pieces)])]).
-
-:- func report_already_parallelised(pred_info) = error_spec.
-
-report_already_parallelised(PredInfo) = Spec :-
-    % Should the severity be informational?
-    PredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    ModuleName = pred_info_module(PredInfo),
-    PredName = pred_info_name(PredInfo),
-    Arity = pred_info_orig_arity(PredInfo),
-    Pieces = [words("In"), p_or_f(PredOrFunc),
-        sym_name_and_arity(qualified(ModuleName, PredName) / Arity),
-        suffix(":"), nl,
-        words("Warning: this procedure contains explicit parallel"),
-        words("conjunctions, it will not be automatically parallelised.")],
-    pred_info_get_context(PredInfo, Context),
-    Spec = error_spec(severity_warning, phase_auto_parallelism,
-        [simple_msg(Context, [always(Pieces)])]).
-
-:- pred maybe_parallelise_conj(prog_rep_info::in, var_table::in,
-    candidate_par_conjunction::in, instmap::in, hlds_goal::in,
-    maybe_error(hlds_goal)::out) is det.
-
-maybe_parallelise_conj(ProgRepInfo, VarTable, CPC, Instmap0,
-        Goal0, MaybeGoal) :-
-    Goal0 = hlds_goal(GoalExpr0, _GoalInfo0),
-    % We've reached the point indicated by the goal path, Find the
-    % conjuncts that we wish to parallelise.
-    cpc_get_first_goal(CPC, FirstGoalRep),
-    (
-        GoalExpr0 = conj(plain_conj, Conjs0),
-        flatten_conj(Conjs0, Conjs1),
-        find_first_goal(FirstGoalRep, Conjs1, ProgRepInfo, VarTable, Instmap0,
-            found_first_goal(GoalsBefore, FirstGoal, OtherGoals))
-    ->
-        GoalsBeforeInstDeltas = list.map(
-            (func(G) = goal_info_get_instmap_delta(G ^ hlds_goal_info)),
-            GoalsBefore),
-        list.foldl(apply_instmap_delta_sv, GoalsBeforeInstDeltas,
-            Instmap0, Instmap),
-        build_par_conjunction(ProgRepInfo, VarTable, Instmap,
-            [FirstGoal | OtherGoals], CPC, MaybeParConjunction),
-        (
-            MaybeParConjunction = ok(
-                par_conjunction_and_remaining_goals(ParConjunction,
-                RemainingGoals)),
-            Conjs = GoalsBefore ++ ParConjunction ++ RemainingGoals,
-            GoalExpr = conj(plain_conj, Conjs),
-            MaybeGoal = ok(hlds_goal(GoalExpr, Goal0 ^ hlds_goal_info))
-        ;
-            MaybeParConjunction = error(Error),
-            MaybeGoal = error(Error)
-        )
-    ;
-        MaybeGoal = error("Could not find partition within conjunction: "
-            ++ "perhaps the program has changed")
-    ).
-
-:- pred cpc_get_first_goal(candidate_par_conjunction::in, pard_goal::out)
-    is det.
-
-cpc_get_first_goal(CPC, FirstGoal) :-
-    GoalsBefore = CPC ^ cpc_goals_before,
-    (
-        GoalsBefore = [FirstGoal | _]
-    ;
-        GoalsBefore = [],
-        ParConj = CPC ^ cpc_conjs,
-        (
-            ParConj = [FirstParConj | _],
-            FirstParConj = seq_conj([FirstGoalPrime | _])
-        ->
-            FirstGoal = FirstGoalPrime
-        ;
-            unexpected($module, $pred,
-                "candidate parallel conjunction is empty")
-        )
-    ).
-
-:- type find_first_goal_result
-    --->    did_not_find_first_goal
-    ;       found_first_goal(
-                ffg_goals_before        :: hlds_goals,
-                ffg_goal                :: hlds_goal,
-                ffg_goals_after         :: hlds_goals
-            ).
-
-:- pred find_first_goal(pard_goal::in, list(hlds_goal)::in,
-    prog_rep_info::in, var_table::in, instmap::in,
-    find_first_goal_result::out) is det.
-
-find_first_goal(_, [], _, _, _, did_not_find_first_goal).
-find_first_goal(GoalRep, [Goal | Goals], ProcRepInfo, VarTable, !.Instmap,
-        Result) :-
-    (
-        pard_goal_match_hlds_goal(ProcRepInfo, VarTable, !.Instmap, GoalRep,
-            Goal)
-    ->
-        Result = found_first_goal([], Goal, Goals)
-    ;
-        InstmapDelta = goal_info_get_instmap_delta(Goal ^ hlds_goal_info),
-        apply_instmap_delta_sv(InstmapDelta, !Instmap),
-        find_first_goal(GoalRep, Goals, ProcRepInfo, VarTable, !.Instmap,
-            Result0),
-        (
-            Result0 = did_not_find_first_goal,
-            Result = did_not_find_first_goal
-        ;
-            Result0 = found_first_goal(GoalsBefore0, _, _),
-            Result = Result0 ^ ffg_goals_before := [Goal | GoalsBefore0]
-        )
-    ).
-
-:- type par_conjunction_and_remaining_goals
-    --->    par_conjunction_and_remaining_goals(
-                pcrg_par_conjunction            :: hlds_goals,
-                pcrg_remaining_goals            :: hlds_goals
-            ).
-
-:- pred build_par_conjunction(prog_rep_info::in, var_table::in, instmap::in,
-    hlds_goals::in, candidate_par_conjunction::in,
-    maybe_error(par_conjunction_and_remaining_goals)::out) is det.
-
-build_par_conjunction(ProcRepInfo, VarTable, Instmap0, !.Goals, CPC,
-        MaybeParConjunction) :-
-    GoalRepsBefore = CPC ^ cpc_goals_before,
-    GoalRepsAfter = CPC ^ cpc_goals_after,
-    ParConjReps = CPC ^ cpc_conjs,
-    some [!Instmap] (
-        !:Instmap = Instmap0,
-        build_seq_conjuncts(ProcRepInfo, VarTable, GoalRepsBefore,
-            MaybeGoalsBefore, !Goals, !Instmap),
-        build_par_conjuncts(ProcRepInfo, VarTable, ParConjReps,
-            MaybeParConjuncts, !Goals, !Instmap),
-        build_seq_conjuncts(ProcRepInfo, VarTable, GoalRepsAfter,
-            MaybeGoalsAfter, !Goals, !Instmap),
-        _ = !.Instmap
-    ),
-    (
-        MaybeGoalsBefore = yes(GoalsBefore),
-        (
-            MaybeParConjuncts = yes(ParConjuncts),
-            (
-                MaybeGoalsAfter = yes(GoalsAfter),
-                create_conj_from_list(ParConjuncts, parallel_conj,
-                    ParConjunction0),
-                ParConjunction = GoalsBefore ++ [ParConjunction0 | GoalsAfter],
-                MaybeParConjunction = ok(
-                    par_conjunction_and_remaining_goals(ParConjunction,
-                    !.Goals))
-            ;
-                MaybeGoalsAfter = no,
-                MaybeParConjunction = error("The goals after the parallel "
-                    ++ "conjunction do not match those in the feedback file")
-            )
-        ;
-            MaybeParConjuncts = no,
-            MaybeParConjunction = error("The goals within the parallel "
-                ++ "conjunction do not match those in the feedback file")
-        )
-    ;
-        MaybeGoalsBefore = no,
-        MaybeParConjunction = error("The goals before the parallel "
-            ++ "conjunction do not match those in the feedback file")
-    ).
-
-:- pred build_par_conjuncts(prog_rep_info::in, var_table::in,
-    list(seq_conj)::in, maybe(hlds_goals)::out,
-    hlds_goals::in, hlds_goals::out, instmap::in, instmap::out) is det.
-
-build_par_conjuncts(_, _, [], yes([]), !Goals, !Instmap).
-build_par_conjuncts(ProcRepInfo, VarTable, [GoalRep | GoalReps], MaybeConjs,
-        !Goals, !Instmap) :-
-    GoalRep = seq_conj(SeqConjs),
-    build_seq_conjuncts(ProcRepInfo, VarTable, SeqConjs, MaybeConj, !Goals,
-        !Instmap),
-    (
-        MaybeConj = yes(Conj0),
-        create_conj_from_list(Conj0, plain_conj, Conj),
-        build_par_conjuncts(ProcRepInfo, VarTable, GoalReps, MaybeConjs0,
-            !Goals, !Instmap),
-        (
-            MaybeConjs0 = yes(Conjs0),
-            MaybeConjs = yes([Conj | Conjs0])
-        ;
-            MaybeConjs0 = no,
-            MaybeConjs = no
-        )
-    ;
-        MaybeConj = no,
-        MaybeConjs = no
-    ).
-
-:- pred build_seq_conjuncts(prog_rep_info::in, var_table::in,
-    list(pard_goal)::in, maybe(hlds_goals)::out,
-    hlds_goals::in, hlds_goals::out, instmap::in, instmap::out) is det.
-
-build_seq_conjuncts(_, _, [], yes([]), !Goals, !Instmap).
-build_seq_conjuncts(ProcRepInfo, VarTable, [GoalRep | GoalReps], MaybeConjs,
-        !Goals, !Instmap) :-
-    (
-        !.Goals = [Goal | !:Goals],
-        ( pard_goal_match_hlds_goal(ProcRepInfo, VarTable, !.Instmap, GoalRep,
-                Goal) ->
-            InstmapDelta = goal_info_get_instmap_delta(Goal ^ hlds_goal_info),
-            apply_instmap_delta_sv(InstmapDelta, !Instmap),
-            build_seq_conjuncts(ProcRepInfo, VarTable, GoalReps, MaybeConjs0,
-                !Goals, !Instmap),
-            (
-                MaybeConjs0 = yes(Conjs0),
-                MaybeConjs = yes([Goal | Conjs0])
-            ;
-                MaybeConjs0 = no,
-                MaybeConjs = no
-            )
-        ;
-            MaybeConjs = no
-        )
-    ;
-        !.Goals = [],
-        MaybeConjs = no
-    ).
-
-:- pred pard_goal_match_hlds_goal(prog_rep_info::in, var_table::in,
-    instmap::in, pard_goal::in, hlds_goal::in) is semidet.
-
-pard_goal_match_hlds_goal(ProgRepInfo, VarTable, Instmap, GoalRepA, GoalB) :-
-    goal_to_goal_rep(ProgRepInfo, Instmap, GoalB, GoalRepB),
-    goal_reps_match(VarTable, GoalRepA, GoalRepB).
-
-:- pred goal_reps_match(var_table::in, goal_rep(A)::in, goal_rep(B)::in)
-    is semidet.
-
-goal_reps_match(VarTable, GoalA, GoalB) :-
-    GoalA = goal_rep(GoalRepA, Detism, _),
-    GoalB = goal_rep(GoalRepB, Detism, _),
-    (
-        GoalRepA = conj_rep(ConjsA),
-        GoalRepB = conj_rep(ConjsB),
-        zip_all_true(goal_reps_match(VarTable), ConjsA, ConjsB)
-    ;
-        GoalRepA = disj_rep(DisjsA),
-        GoalRepB = disj_rep(DisjsB),
-        zip_all_true(goal_reps_match(VarTable), DisjsA, DisjsB)
-    ;
-        GoalRepA = switch_rep(VarRepA, CanFail, CasesA),
-        GoalRepB = switch_rep(VarRepB, CanFail, CasesB),
-        var_reps_match(VarTable, VarRepA, VarRepB),
-        % Note that GoalRepA and GoalRepB could be equivalent
-        % even they contained the same cases but a different order.
-        list.sort(CasesA, SortedCasesA),
-        list.sort(CasesB, SortedCasesB),
-        zip_all_true(case_reps_match(VarTable), SortedCasesA, SortedCasesB)
-    ;
-        GoalRepA = ite_rep(CondA, ThenA, ElseA),
-        GoalRepB = ite_rep(CondB, ThenB, ElseB),
-        goal_reps_match(VarTable, CondA, CondB),
-        goal_reps_match(VarTable, ThenA, ThenB),
-        goal_reps_match(VarTable, ElseA, ElseB)
-    ;
-        GoalRepA = negation_rep(SubGoalA),
-        GoalRepB = negation_rep(SubGoalB),
-        goal_reps_match(VarTable, SubGoalA, SubGoalB)
-    ;
-        GoalRepA = scope_rep(SubGoalA, MaybeCut),
-        GoalRepB = scope_rep(SubGoalB, MaybeCut),
-        goal_reps_match(VarTable, SubGoalA, SubGoalB)
-    ;
-        GoalRepA = atomic_goal_rep(_, _, _, AtomicGoalA),
-        GoalRepB = atomic_goal_rep(_, _, _, AtomicGoalB),
-        % We don't compare names and file numbers, since trivial changes
-        % to e.g. comments could change line numbers dramatically without
-        % changing how the program should be parallelised.
-        %
-        % Vars are not matched here either, we only consider the vars
-        % within the atomic_goal_rep structures.
-        atomic_goal_reps_match(VarTable, AtomicGoalA, AtomicGoalB)
-    ).
-
-:- pred atomic_goal_reps_match(var_table::in,
-    atomic_goal_rep::in, atomic_goal_rep::in) is semidet.
-
-atomic_goal_reps_match(VarTable, AtomicRepA, AtomicRepB) :-
-    (
-        (
-            AtomicRepA = unify_construct_rep(VarA, ConsId, ArgsA),
-            AtomicRepB = unify_construct_rep(VarB, ConsId, ArgsB)
-        ;
-            AtomicRepA = unify_deconstruct_rep(VarA, ConsId, ArgsA),
-            AtomicRepB = unify_deconstruct_rep(VarB, ConsId, ArgsB)
-        ;
-            AtomicRepA = higher_order_call_rep(VarA, ArgsA),
-            AtomicRepB = higher_order_call_rep(VarB, ArgsB)
-        ;
-            AtomicRepA = method_call_rep(VarA, MethodNum, ArgsA),
-            AtomicRepB = method_call_rep(VarB, MethodNum, ArgsB)
-        ),
-        var_reps_match(VarTable, VarA, VarB),
-        zip_all_true(var_reps_match(VarTable), ArgsA, ArgsB)
-    ;
-        (
-            AtomicRepA = partial_deconstruct_rep(VarA, ConsId, MaybeArgsA),
-            AtomicRepB = partial_deconstruct_rep(VarB, ConsId, MaybeArgsB)
-        ;
-            AtomicRepA = partial_construct_rep(VarA, ConsId, MaybeArgsA),
-            AtomicRepB = partial_construct_rep(VarB, ConsId, MaybeArgsB)
-        ),
-        var_reps_match(VarTable, VarA, VarB),
-        zip_all_true(maybe_var_reps_match(VarTable), MaybeArgsA, MaybeArgsB)
-    ;
-        (
-            AtomicRepA = unify_assign_rep(VarA1, VarA2),
-            AtomicRepB = unify_assign_rep(VarB1, VarB2)
-        ;
-            AtomicRepA = cast_rep(VarA1, VarA2),
-            AtomicRepB = cast_rep(VarB1, VarB2)
-        ;
-            AtomicRepA = unify_simple_test_rep(VarA1, VarA2),
-            AtomicRepB = unify_simple_test_rep(VarB1, VarB2)
-        ),
-        var_reps_match(VarTable, VarA1, VarB1),
-        var_reps_match(VarTable, VarA2, VarB2)
-    ;
-        (
-            AtomicRepA = pragma_foreign_code_rep(ArgsA),
-            AtomicRepB = pragma_foreign_code_rep(ArgsB)
-        ;
-            AtomicRepA = plain_call_rep(ModuleName, PredName, ArgsA),
-            AtomicRepB = plain_call_rep(ModuleName, PredName, ArgsB)
-        ;
-            AtomicRepA = builtin_call_rep(ModuleName, PredName, ArgsA),
-            AtomicRepB = builtin_call_rep(ModuleName, PredName, ArgsB)
-        ;
-            AtomicRepA = event_call_rep(EventName, ArgsA),
-            AtomicRepB = event_call_rep(EventName, ArgsB)
-        ),
-        zip_all_true(var_reps_match(VarTable), ArgsA, ArgsB)
-    ).
-
-:- pred case_reps_match(var_table::in, case_rep(A)::in, case_rep(B)::in)
-    is semidet.
-
-case_reps_match(VarTable, CaseRepA, CaseRepB) :-
-    CaseRepA = case_rep(ConsId, OtherConsIds, GoalRepA),
-    CaseRepB = case_rep(ConsId, OtherConsIds, GoalRepB),
-    goal_reps_match(VarTable, GoalRepA, GoalRepB).
-
-:- pred var_reps_match(var_table::in, var_rep::in, var_rep::in) is semidet.
-
-var_reps_match(VarTable, VarA, VarB) :-
-    ( search_var_name(VarTable, VarA, _) ->
-        % Variables named by the programmer _must_ match, we expect to find
-        % them in the var table, and that they would be identical.  (Since one
-        % of the variables will be built using its name and the var table
-        % constructed when converting the original code to byte code).
-        VarA = VarB
-    ;
-        % Unnamed variables match implicitly. They will usually be identical,
-        % but we do not REQUIRE them to be identical, to allow the program
-        % to change a little after being profiled but before being parallelised.
-        true
-    ).
-
-:- pred maybe_var_reps_match(var_table::in,
-    maybe(var_rep)::in, maybe(var_rep)::in) is semidet.
-
-maybe_var_reps_match(_, no, no).
-maybe_var_reps_match(VarTable, yes(VarA), yes(VarB)) :-
-    var_reps_match(VarTable, VarA, VarB).
-
-    % zip_all_true(Pred, ListA, ListB)
-    %
-    % True when lists have equal length and every corresponding pair of values
-    % from the lists satisifies Pred.
-    %
-:- pred zip_all_true(pred(A, B), list(A), list(B)).
-:- mode zip_all_true(pred(in, in) is semidet, in, in) is semidet.
-
-zip_all_true(_, [], []).
-zip_all_true(Pred, [A | As], [B | Bs]) :-
-    Pred(A, B),
-    zip_all_true(Pred, As, Bs).
-
-:- pred match_sym_name(sym_name::in, string::in, string::in) is semidet.
-
-match_sym_name(unqualified(ProcName), _, ProcName).
-match_sym_name(qualified(SymModuleName, ProcName), ModuleName, ProcName) :-
-    ModuleNameParts = reverse(split_at_separator(unify('.'), ModuleName)),
-    match_sym_module_name(SymModuleName, ModuleNameParts).
-
-:- pred match_sym_module_name(sym_name::in, list(string)::in) is semidet.
-
-match_sym_module_name(unqualified(Name), [Name]).
-match_sym_module_name(qualified(SymName, Name), [Name | Names]) :-
-    match_sym_module_name(SymName, Names).
-
-:- pred args_match(prog_varset::in, prog_var::in, maybe(string)::in)
-    is semidet.
-
-args_match(_, _, no).
-args_match(VarSet, Var, yes(Name)) :-
-    varset.search_name(VarSet, Var, Name).
-
-:- pred model_det_and_at_least_semipure(hlds_goal::in) is semidet.
-
-model_det_and_at_least_semipure(Goal) :-
-    GoalInfo = Goal ^ hlds_goal_info,
-    Determinism = goal_info_get_determinism(GoalInfo),
-    ( Determinism = detism_det
-    ; Determinism = detism_cc_multi
-    ),
-    Purity = goal_info_get_purity(GoalInfo),
-    ( Purity = purity_pure
-    ; Purity = purity_semipure
-    ).
-
-%-----------------------------------------------------------------------------%
-%
-% The following code is deprecated, it is the older implicit parallelisation
-% transformation developed by Jerömé.
-%
-% TODO
-%   -   Once a call which is a candidate for implicit parallelism is found,
-%       search forward AND backward for the closest goal which is also a
-%       candidate for implicit parallelism/parallel conjunction and determine
-%       which side is the best (on the basis of the number of shared variables).
-%
-% XXX Several predicates in this module repeatedly add goals to the ends of
-% lists of goals, yielding quadratic behavior. This should be fixed.
-%
-%-----------------------------------------------------------------------------%
-
-    % Represent a call site static which is a candidate for introducing
-    % implicit parallelism.
-    %
-:- type candidate_call_site
-    --->    candidate_call_site(
-                caller      :: string,          % The caller of the call.
-                slot_number :: int,             % The slot number of the call.
-                kind        :: call_site_kind,  % The kind of the call.
-                callee      :: string           % The callee of the call.
-            ).
-
-    % Represent the kind of a call site.
-    %
-:- type call_site_kind
-        --->    csk_normal
-        ;       csk_special
-        ;       csk_higher_order
-        ;       csk_method
-        ;       csk_callback.
-
-    % Construct a call_site_kind from its string representation.
-    %
-:- pred construct_call_site_kind(string::in, call_site_kind::out) is semidet.
-
-construct_call_site_kind("normal_call",         csk_normal).
-construct_call_site_kind("special_call",        csk_special).
-construct_call_site_kind("higher_order_call",   csk_higher_order).
-construct_call_site_kind("method_call",         csk_method).
-construct_call_site_kind("callback",            csk_callback).
-
-%-----------------------------------------------------------------------------%
-
-:- pred apply_old_implicit_parallelism_transformation(
-    module_info::in, maybe_error(module_info)::out) is det.
-
-apply_old_implicit_parallelism_transformation(ModuleInfo0, MaybeModuleInfo) :-
-    module_info_get_globals(ModuleInfo0, Globals),
-    (
-        globals.get_maybe_feedback_info(Globals, yes(FeedbackInfo)),
-        FeedbackData = feedback_data_calls_above_threshold_sorted(_, _, _),
-        get_feedback_data(FeedbackInfo, FeedbackData)
-    ->
-        some [!ModuleInfo]
-        (
-            !:ModuleInfo = ModuleInfo0,
-            module_info_get_valid_predids(PredIds, !ModuleInfo),
-            FeedbackData =
-                feedback_data_calls_above_threshold_sorted(_, _, Calls),
-            list.map(call_site_convert, Calls, CandidateCallSites),
-            process_preds_for_implicit_parallelism(PredIds, CandidateCallSites,
-                !ModuleInfo),
-            MaybeModuleInfo = ok(!.ModuleInfo)
-        )
-    ;
-        MaybeModuleInfo =
-            error("Insufficient feedback information for implicit parallelism")
-    ).
-
-    % This predicate isn't really necessary as this entire module should use
-    % the call_site structure defined in mdbcomp.program_representation.
-    % However it's expected that the rest of this module will be replaced in
-    % the near future.
-    %
-:- pred call_site_convert(call_site::in, candidate_call_site::out) is det.
-
-call_site_convert(Call, CallSite) :-
-    Call = call_site(Caller0, Slot, CallTypeAndCallee),
-    string_proc_label_to_string(Caller0, Caller),
-    (
-        CallTypeAndCallee = plain_call(Callee0),
-        string_proc_label_to_string(Callee0, Callee),
-        CallSiteKind = csk_normal
-    ;
-        (
-            CallTypeAndCallee = callback_call,
-            CallSiteKind = csk_callback
-        ;
-            CallTypeAndCallee = higher_order_call,
-            CallSiteKind = csk_higher_order
-        ;
-            CallTypeAndCallee = method_call,
-            CallSiteKind = csk_method
-        ;
-            CallTypeAndCallee = special_call,
-            CallSiteKind = csk_special
-        ),
-        Callee = ""
-    ),
-    CallSite = candidate_call_site(Caller, Slot, CallSiteKind, Callee).
-
-:- pred string_proc_label_to_string(string_proc_label::in, string::out) is det.
-
-string_proc_label_to_string(ProcLabel, String) :-
-    (
-        ProcLabel = str_ordinary_proc_label(_, Module, _, Name, Arity, Mode)
-    ;
-        ProcLabel = str_special_proc_label(_, _, Module, Name, Arity, Mode)
-    ),
-    string.format("%s.%s/%d-%d", [s(Module), s(Name), i(Arity), i(Mode)],
-        String).
-
-    % Process predicates for implicit parallelism.
-    %
-:- pred process_preds_for_implicit_parallelism(list(pred_id)::in,
-    list(candidate_call_site)::in, module_info::in, module_info::out) is det.
-
-process_preds_for_implicit_parallelism([],
-        _CandidateCallSites, !ModuleInfo).
-process_preds_for_implicit_parallelism([PredId | PredIds],
-        CandidateCallSites, !ModuleInfo) :-
-    module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
-    ProcIds = pred_info_non_imported_procids(PredInfo),
-    process_procs_for_implicit_parallelism(PredId, ProcIds,
-        CandidateCallSites, !ModuleInfo),
-    process_preds_for_implicit_parallelism(PredIds,
-        CandidateCallSites, !ModuleInfo).
-
-    % Process procedures for implicit parallelism.
-    %
-:- pred process_procs_for_implicit_parallelism(pred_id::in,
-    list(proc_id)::in, list(candidate_call_site)::in,
-    module_info::in, module_info::out) is det.
-
-process_procs_for_implicit_parallelism(_PredId, [],
-        _CandidateCallSites, !ModuleInfo).
-process_procs_for_implicit_parallelism(PredId, [ProcId | ProcIds],
-        CandidateCallSites, !ModuleInfo) :-
-    module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
-        PredInfo0, ProcInfo0),
-    % Initialize the counter for the slot number.
-    SiteNumCounter = counter.init(0),
-    pred_proc_id_to_raw_id(PredInfo0, ProcId, CallerRawId),
-    get_callees_feedback(CallerRawId, CandidateCallSites, [], CallSites),
-    list.length(CallSites, NumCallSites),
-    ( NumCallSites = 0 ->
-        % No candidate calls for implicit parallelism in this procedure.
-        process_procs_for_implicit_parallelism(PredId, ProcIds,
-            CandidateCallSites, !ModuleInfo)
-    ;
-        proc_info_get_goal(ProcInfo0, Body0),
-        process_goal_for_implicit_parallelism(Body0, Body, ProcInfo0,
-            !ModuleInfo, no, _, 0, _, CallSites, _, SiteNumCounter, _),
-        proc_info_set_goal(Body, ProcInfo0, ProcInfo1),
-        proc_info_set_has_parallel_conj(yes, ProcInfo1, ProcInfo2),
-        requantify_proc_general(ordinary_nonlocals_no_lambda,
-            ProcInfo2, ProcInfo3),
-        recompute_instmap_delta_proc(do_not_recompute_atomic_instmap_deltas,
-            ProcInfo3, ProcInfo, !ModuleInfo),
-        pred_info_set_proc_info(ProcId, ProcInfo, PredInfo0, PredInfo),
-        module_info_set_pred_info(PredId, PredInfo, !ModuleInfo),
-        process_procs_for_implicit_parallelism(PredId, ProcIds,
-            CandidateCallSites, !ModuleInfo)
-    ).
-
-    % Filter the list of call site information from the feedback file so that
-    % the resulting list only contains those call sites that belong to the first
-    % argument, e.g. the caller.
-    %
-:- pred get_callees_feedback(string::in, list(candidate_call_site)::in,
-    list(candidate_call_site)::in, list(candidate_call_site)::out) is det.
-
-get_callees_feedback(_Caller, [], !ResultAcc).
-get_callees_feedback(Caller, [CandidateCallSite | CandidateCallSites],
-        !ResultAcc) :-
-    CandidateCallSite = candidate_call_site(CSSCaller, _, _, _),
-    ( Caller = CSSCaller ->
-        !:ResultAcc = [CandidateCallSite | !.ResultAcc]
-    ;
-        true
-    ),
-    get_callees_feedback(Caller, CandidateCallSites, !ResultAcc).
-
-    % Process a goal for implicit parallelism.
-    % MaybeConj is the conjunction which contains Goal.
-    %
-:- pred process_goal_for_implicit_parallelism(hlds_goal::in, hlds_goal::out,
-    proc_info::in, module_info::in, module_info::out,
-    maybe(hlds_goal_expr)::in, maybe(hlds_goal_expr)::out, int ::in, int::out,
-    list(candidate_call_site)::in, list(candidate_call_site)::out,
-    counter::in, counter::out) is det.
-
-process_goal_for_implicit_parallelism(!Goal, ProcInfo, !ModuleInfo,
-        !MaybeConj, !IndexInConj, !CalleesToBeParallelized, !SiteNumCounter) :-
-    !.Goal = hlds_goal(GoalExpr0, GoalInfo),
-    (
-        GoalExpr0 = unify(_, _, _, _, _),
-        increment_index_if_in_conj(!.MaybeConj, !IndexInConj)
-    ;
-        GoalExpr0 = plain_call(_, _, _, _, _, _),
-        process_call_for_implicit_parallelism(!.Goal, ProcInfo, !ModuleInfo,
-            !IndexInConj, !MaybeConj, !CalleesToBeParallelized,
-            !SiteNumCounter)
-        % We deal with the index in the conjunction in
-        % process_call_for_implicit_parallelism.
-    ;
-        GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _),
-        process_call_for_implicit_parallelism(!.Goal, ProcInfo, !ModuleInfo,
-            !IndexInConj, !MaybeConj, !CalleesToBeParallelized,
-            !SiteNumCounter)
-    ;
-        GoalExpr0 = generic_call(Details, _, _, _),
-        (
-            Details = higher_order(_, _, _, _),
-            process_call_for_implicit_parallelism(!.Goal, ProcInfo,
-                !ModuleInfo, !IndexInConj, !MaybeConj,
-                !CalleesToBeParallelized, !SiteNumCounter)
-        ;
-            Details = class_method(_, _, _, _),
-            process_call_for_implicit_parallelism(!.Goal, ProcInfo,
-                !ModuleInfo, !IndexInConj, !MaybeConj,
-                !CalleesToBeParallelized, !SiteNumCounter)
-        ;
-            Details = event_call(_),
-            increment_index_if_in_conj(!.MaybeConj, !IndexInConj)
-        ;
-            Details = cast(_),
-            increment_index_if_in_conj(!.MaybeConj, !IndexInConj)
-        )
-    ;
-        % No distinction is made between plain conjunctions and parallel
-        % conjunctions. We have to process the parallel conjunction for the
-        % slot number.
-        GoalExpr0 = conj(_, _),
-        process_conj_for_implicit_parallelism(GoalExpr0, GoalExpr, 1,
-            ProcInfo, !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter),
-        % A plain conjunction will never be contained in an other plain
-        % conjunction. As for parallel conjunctions, they will not be modified.
-        % Therefore, incrementing the index suffices (no need to call
-        % update_conj_and_index).
-        !:Goal = hlds_goal(GoalExpr, GoalInfo),
-        increment_index_if_in_conj(!.MaybeConj, !IndexInConj)
-    ;
-        GoalExpr0 = disj(Goals0),
-        process_disj_for_implicit_parallelism(Goals0, [], Goals,
-            ProcInfo, !ModuleInfo, !CalleesToBeParallelized,
-            !SiteNumCounter),
-        GoalExpr = disj(Goals),
-        % If we are not in a conjunction, then we need to return the modified
-        % value of Goal. If we are in a conjunction, that information is not
-        % read (see process_conj_for_implicit_parallelism).
-        !:Goal = hlds_goal(GoalExpr, GoalInfo),
-        update_conj_and_index(!MaybeConj, !.Goal, !IndexInConj)
-    ;
-        GoalExpr0 = switch(Var, CanFail, Cases0),
-        process_switch_cases_for_implicit_parallelism(Cases0, [], Cases,
-            ProcInfo, !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter),
-        GoalExpr = switch(Var, CanFail, Cases),
-        !:Goal = hlds_goal(GoalExpr, GoalInfo),
-        update_conj_and_index(!MaybeConj, !.Goal, !IndexInConj)
-    ;
-        GoalExpr0 = negation(SubGoal0),
-        process_goal_for_implicit_parallelism(SubGoal0, SubGoal, ProcInfo,
-            !ModuleInfo, !MaybeConj, !IndexInConj, !CalleesToBeParallelized,
-            !SiteNumCounter),
-        GoalExpr = negation(SubGoal),
-        !:Goal = hlds_goal(GoalExpr, GoalInfo),
-        update_conj_and_index(!MaybeConj, !.Goal, !IndexInConj)
-    ;
-        GoalExpr0 = scope(Reason, Goal0),
-        ( Reason = from_ground_term(_, from_ground_term_construct) ->
-            % Treat the scope as if it were a single unification, since
-            % that is effectively what happens at runtime.
-            increment_index_if_in_conj(!.MaybeConj, !IndexInConj)
-        ;
-            % 0 is the default value when we are not in a conjunction
-            % (in this case a scope).
-            process_goal_for_implicit_parallelism(Goal0, Goal, ProcInfo,
-                !ModuleInfo, no, _, 0, _, !CalleesToBeParallelized,
-                !SiteNumCounter),
-            GoalExpr = scope(Reason, Goal),
-            !:Goal = hlds_goal(GoalExpr, GoalInfo),
-            update_conj_and_index(!MaybeConj, !.Goal, !IndexInConj)
-        )
-    ;
-        GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
-        process_goal_for_implicit_parallelism(Cond0, Cond, ProcInfo,
-            !ModuleInfo, no, _, 0, _, !CalleesToBeParallelized,
-            !SiteNumCounter),
-        process_goal_for_implicit_parallelism(Then0, Then, ProcInfo,
-            !ModuleInfo, no, _, 0, _, !CalleesToBeParallelized,
-            !SiteNumCounter),
-        process_goal_for_implicit_parallelism(Else0, Else, ProcInfo,
-            !ModuleInfo, no, _, 0, _, !CalleesToBeParallelized,
-            !SiteNumCounter),
-        GoalExpr = if_then_else(Vars, Cond, Then, Else),
-        !:Goal = hlds_goal(GoalExpr, GoalInfo),
-        update_conj_and_index(!MaybeConj, !.Goal, !IndexInConj)
-    ;
-        GoalExpr0 = shorthand(_),
-        % These should have been expanded out by now.
-        unexpected($module, $pred, "shorthand")
-    ).
-
-    % Increment the index if we are in a conjunction.
-    %
-:- pred increment_index_if_in_conj(maybe(hlds_goal_expr)::in,
-    int::in, int::out) is det.
-
-increment_index_if_in_conj(MaybeConj, !IndexInConj) :-
-    (
-        MaybeConj = yes(_),
-        !:IndexInConj = !.IndexInConj + 1
-    ;
-        MaybeConj = no
-    ).
-
-    % Process a call for implicit parallelism.
-    %
-:- pred process_call_for_implicit_parallelism(hlds_goal::in, proc_info::in,
-    module_info::in, module_info::out, int::in, int::out,
-    maybe(hlds_goal_expr)::in, maybe(hlds_goal_expr)::out,
-    list(candidate_call_site)::in, list(candidate_call_site)::out,
-    counter::in, counter::out) is det.
-
-process_call_for_implicit_parallelism(Call, ProcInfo, !ModuleInfo,
-        !IndexInConj, !MaybeConj, !CalleesToBeParallelized, !SiteNumCounter) :-
-    counter.allocate(SlotNumber, !SiteNumCounter),
-    get_call_kind_and_callee(!.ModuleInfo, Call, Kind, CalleeRawId),
-    (
-        !.MaybeConj = yes(Conj0),
-        Conj0 = conj(plain_conj, ConjGoals0)
-    ->
-        (
-            is_in_css_list_to_be_parallelized(Kind, SlotNumber, CalleeRawId,
-                !.CalleesToBeParallelized, [], !:CalleesToBeParallelized)
-        ->
-            (
-                build_goals_surrounded_by_calls_to_be_parallelized(ConjGoals0,
-                    !.ModuleInfo, [Call], Goals, !.IndexInConj + 1, End,
-                    !SiteNumCounter, !CalleesToBeParallelized)
-            ->
-                parallelize_calls(Goals, !.IndexInConj, End, Conj0, Conj,
-                    ProcInfo, !ModuleInfo),
-                !:IndexInConj = End,
-                !:MaybeConj = yes(Conj)
-            ;
-                % The next call is not in the feedback file or we've hit a
-                % plain conjunction/disjunction/switch/if_then_else.
-                !:IndexInConj = !.IndexInConj + 1
-            )
-        ;
-            % Not to be parallelized.
-            !:IndexInConj = !.IndexInConj + 1
-        )
-    ;
-        % Call is not in a conjunction or the call is already in a parallel
-        % conjunction.
-        true
-    ).
-
-    % Give the raw id (the same as in the deep profiler) of a callee contained
-    % in a call.
-    %
-:- pred get_call_kind_and_callee(module_info::in, hlds_goal::in,
-    call_site_kind::out, string::out) is det.
-
-get_call_kind_and_callee(ModuleInfo, Call, Kind, CalleeRawId) :-
-    GoalExpr = Call ^ hlds_goal_expr,
-    (
-        GoalExpr = plain_call(PredId, ProcId, _, _, _, _),
-        module_info_pred_proc_info(ModuleInfo, PredId, ProcId, PredInfo, _),
-        pred_proc_id_to_raw_id(PredInfo, ProcId, CalleeRawId),
-        Kind = csk_normal
-    ;
-        GoalExpr = call_foreign_proc(_, PredId, ProcId, _, _, _, _),
-        module_info_pred_proc_info(ModuleInfo, PredId, ProcId, PredInfo, _),
-        pred_proc_id_to_raw_id(PredInfo, ProcId, CalleeRawId),
-        Kind = csk_special
-    ;
-        GoalExpr = generic_call(Details, _, _, _),
-        (
-            Details = higher_order(_, _, _, _),
-            CalleeRawId = "",
-            Kind = csk_higher_order
-        ;
-            Details = class_method(_, _, _, _),
-            CalleeRawId = "",
-            Kind = csk_method
-        ;
-            Details = event_call(_),
-            unexpected($module, $pred, "event_call")
-        ;
-            Details = cast(_),
-            unexpected($module, $pred, "cast")
-        )
-    ;
-        % XXX Some of our callers can call us with these kinds of goals.
-        ( GoalExpr = unify(_, _, _, _, _)
-        ; GoalExpr = conj(_, _)
-        ; GoalExpr = disj(_)
-        ; GoalExpr = switch(_, _, _)
-        ; GoalExpr = if_then_else(_, _, _, _)
-        ; GoalExpr = negation(_)
-        ; GoalExpr = scope(_, _)
-        ; GoalExpr = shorthand(_)
-        ),
-        unexpected($module, $pred, "unexpected kind of goal")
-    ).
-
-    % Convert a pred_info and a proc_id to the raw procedure id (the same used
-    % in the deep profiler).
-    %
-:- pred pred_proc_id_to_raw_id(pred_info::in, proc_id::in, string::out) is det.
-
-pred_proc_id_to_raw_id(PredInfo, ProcId, RawId) :-
-    ModuleName = pred_info_module(PredInfo),
-    Name = pred_info_name(PredInfo),
-    OrigArity = pred_info_orig_arity(PredInfo),
-    IsPredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    ModuleString = sym_name_to_string(ModuleName),
-    ProcIdInt = proc_id_to_int(ProcId),
-    RawId = string.append_list([ModuleString, ".", Name, "/",
-        string.int_to_string(OrigArity),
-        ( IsPredOrFunc = pf_function -> "+1" ; ""), "-",
-        string.from_int(ProcIdInt)]).
-
-    % Succeeds if the caller, slot number and callee correspond to a
-    % candidate_call_site in the list given as a parameter.
-    % Fail otherwise.
-    %
-:- pred is_in_css_list_to_be_parallelized(call_site_kind::in, int::in,
-    string::in, list(candidate_call_site)::in,
-    list(candidate_call_site)::in, list(candidate_call_site)::out) is semidet.
-
-is_in_css_list_to_be_parallelized(Kind, SlotNumber, CalleeRawId,
-        CandidateCallSites, !ResultAcc) :-
-    (
-        CandidateCallSites = [],
-        fail
-    ;
-        CandidateCallSites = [HeadCandidateCallSite | TailCandidateCallSites],
-        HeadCandidateCallSite = candidate_call_site(_, CSSSlotNumber, CSSKind,
-            CSSCallee),
-        % =< because there is not a one to one correspondance with the source
-        % code. New calls might have been added by the previous passes of the
-        % compiler.
-        (
-            CSSSlotNumber =< SlotNumber,
-            CSSKind = Kind,
-            CSSCallee = CalleeRawId
-        ->
-            !:ResultAcc = !.ResultAcc ++ TailCandidateCallSites
-        ;
-            !:ResultAcc = !.ResultAcc ++ [HeadCandidateCallSite],
-            is_in_css_list_to_be_parallelized(Kind, SlotNumber, CalleeRawId,
-                TailCandidateCallSites, !ResultAcc)
-        )
-    ).
-
-    % Build a list of goals surrounded by two calls which are in the feedback
-    % file or by a call which is in the feedback file and a parallel
-    % conjunction.
-    %
-    % Succeed if we can build that list of goals.
-    % Fail otherwise.
-    %
-:- pred build_goals_surrounded_by_calls_to_be_parallelized(list(hlds_goal)::in,
-    module_info::in, list(hlds_goal)::in, list(hlds_goal)::out,
-    int::in, int::out, counter::in, counter::out,
-    list(candidate_call_site)::in, list(candidate_call_site)::out)
-    is semidet.
-
-build_goals_surrounded_by_calls_to_be_parallelized(ConjGoals, ModuleInfo,
-        !ResultAcc, !Index, !SiteNumCounter, !CalleesToBeParallelized) :-
-    list.length(ConjGoals, Length),
-    ( !.Index > Length ->
-        fail
-    ;
-        list.index1_det(ConjGoals, !.Index, Goal),
-        GoalExpr = Goal ^ hlds_goal_expr,
-        (
-            ( GoalExpr = disj(_)
-            ; GoalExpr = switch(_, _, _)
-            ; GoalExpr = if_then_else(_, _, _, _)
-            ; GoalExpr = conj(plain_conj, _)
-            )
-        ->
-            fail
-        ;
-            !:ResultAcc = !.ResultAcc ++ [Goal],
-            ( goal_is_conjunction(Goal, parallel_conj) ->
-                true
-            ;
-                ( goal_is_call_or_negated_call(Goal) ->
-                    counter.allocate(SlotNumber, !SiteNumCounter),
-                    get_call_kind_and_callee(ModuleInfo, Goal, Kind,
-                        CalleeRawId),
-                    (
-                        is_in_css_list_to_be_parallelized(Kind, SlotNumber,
-                            CalleeRawId, !.CalleesToBeParallelized,
-                            [], !:CalleesToBeParallelized)
-                    ->
-                        true
-                    ;
-                        !:Index = !.Index + 1,
-                        build_goals_surrounded_by_calls_to_be_parallelized(
-                            ConjGoals, ModuleInfo, !ResultAcc, !Index,
-                            !SiteNumCounter, !CalleesToBeParallelized)
-                    )
-                ;
-                    !:Index = !.Index + 1,
-                    build_goals_surrounded_by_calls_to_be_parallelized(
-                        ConjGoals, ModuleInfo, !ResultAcc, !Index,
-                        !SiteNumCounter, !CalleesToBeParallelized)
-                )
-            )
-        )
-    ).
-
-    % Succeeds if Goal is a conjunction and return the type of the
-    % conjunction.  Fail otherwise.
-    %
-:- pred goal_is_conjunction(hlds_goal::in, conj_type::out) is semidet.
-
-goal_is_conjunction(Goal, Type) :-
-    Goal = hlds_goal(GoalExpr, _),
-    GoalExpr = conj(Type, _).
-
-    % Succeed if Goal is a call or a negated call.
-    % Call here includes higher-order and class method calls.
-    % Fail otherwise.
-    %
-    % XXX Should be a function returning a bool or something similar.
-    %
-:- pred goal_is_call_or_negated_call(hlds_goal::in) is semidet.
-
-goal_is_call_or_negated_call(Goal) :-
-    GoalExpr = Goal ^ hlds_goal_expr,
-    (
-        GoalExpr = plain_call(_, _, _, _, _, _)
-    ;
-        GoalExpr = call_foreign_proc(_, _, _, _, _, _, _)
-    ;
-        GoalExpr = generic_call(Details, _, _, _),
-        (
-            Details = class_method(_, _, _, _)
-        ;
-            Details = higher_order(_, _, _, _)
-        )
-    ;
-        GoalExpr = negation(GoalNeg),
-        GoalNegExpr = GoalNeg ^ hlds_goal_expr,
-        (
-            GoalNegExpr = plain_call(_, _, _, _, _, _)
-        ;
-            GoalNegExpr = call_foreign_proc(_, _, _, _, _, _, _)
-        ;
-            GoalNegExpr = generic_call(Details, _, _, _),
-            (
-                Details = class_method(_, _, _, _)
-            ;
-                Details = higher_order(_, _, _, _)
-            )
-        )
-    ).
-
-    % Parallelize two calls/a call and a parallel conjunction which might have
-    % goals between them. If these have no dependencies with the first call
-    % then we move them before the first call and parallelize the two
-    % calls/call and parallel conjunction.
-    %
-    % Goals is contained in Conj.
-    %
-:- pred parallelize_calls(list(hlds_goal)::in, int::in, int::in,
-    hlds_goal_expr::in, hlds_goal_expr::out, proc_info::in,
-    module_info::in, module_info::out) is det.
-
-parallelize_calls(Goals, Start, End, !Conj, ProcInfo, !ModuleInfo) :-
-    ( !.Conj = conj(plain_conj, ConjGoals0) ->
-        ( ConjGoals0 = [FirstGoal, LastGoal] ->
-            (
-                is_worth_parallelizing(FirstGoal, LastGoal, ProcInfo,
-                    !.ModuleInfo)
-            ->
-                ( goal_is_conjunction(LastGoal, parallel_conj) ->
-                    % The parallel conjunction has to remain flatened.
-                    add_call_to_parallel_conjunction(FirstGoal, LastGoal,
-                        ParallelGoal),
-                    !:Conj = ParallelGoal ^ hlds_goal_expr
-                ;
-                    !:Conj = conj(parallel_conj, ConjGoals0)
-                )
-            ;
-                % Not worth parallelizing.
-                true
-            )
-        ;
-            % There are more than two goals in the conjunction.
-            list.length(Goals, Length),
-            list.index1_det(Goals, 1, FirstGoal),
-            list.index1_det(Goals, Length, LastGoal),
-            (
-                is_worth_parallelizing(FirstGoal, LastGoal, ProcInfo,
-                    !.ModuleInfo)
-            ->
-                GoalsInBetweenAndLast = list.det_tail(Goals),
-                list.delete_all(GoalsInBetweenAndLast, LastGoal,
-                    GoalsInBetween),
-                % Check the dependencies of GoalsInBetween with FirstGoal.
-                list.filter(goal_depends_on_goal(FirstGoal),
-                    GoalsInBetween, GoalsFiltered),
-                ( list.is_empty(GoalsFiltered) ->
-                    ( goal_is_conjunction(LastGoal, parallel_conj) ->
-                        add_call_to_parallel_conjunction(FirstGoal, LastGoal,
-                            ParallelGoal)
-                    ;
-                        create_conj(FirstGoal, LastGoal, parallel_conj,
-                            ParallelGoal)
-                    ),
-                    ( Start = 1 ->
-                        GoalsFront = []
-                    ;
-                        list.det_split_list(Start - 1, ConjGoals0,
-                            GoalsFront, _)
-                    ),
-                    list.length(ConjGoals0, ConjLength),
-                    ( End = ConjLength ->
-                        GoalsBack = []
-                    ;
-                        list.det_split_list(End, ConjGoals0, _, GoalsBack)
-                    ),
-                    ConjGoals = GoalsFront ++ GoalsInBetween ++
-                        [ParallelGoal] ++ GoalsBack,
-                    !:Conj = conj(plain_conj, ConjGoals)
-                ;
-                    % The goals between the two calls/call and parallel
-                    % conjunction can't be moved before the first call.
-                    true
-                )
-            ;
-                % Not worth parallelizing.
-                true
-            )
-        )
-    ;
-        unexpected($module, $pred, "not a conjunction")
-    ).
-
-    % Two calls are worth parallelizing if the number of shared variables is
-    % smaller than the number of argument variables of at least one of the two
-    % calls.
-    %
-    % A call and a parallel conjunction are worth parallelizing if the number of
-    % shared variables is smaller than the number of argument variables of the
-    % call.
-    %
-    % Succeed if it is worth parallelizing the two goals.
-    % Fail otherwise.
-    %
-:- pred is_worth_parallelizing(hlds_goal::in, hlds_goal::in, proc_info::in,
-    module_info::in) is semidet.
-
-is_worth_parallelizing(GoalA, GoalB, ProcInfo, ModuleInfo) :-
-    proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap),
-    SharedVars = find_shared_variables(ModuleInfo, InstMap, [GoalA, GoalB]),
-    set.to_sorted_list(SharedVars, SharedVarsList),
-    list.length(SharedVarsList, NbSharedVars),
-    ( NbSharedVars = 0 ->
-        % No shared vars between the goals.
-        true
-    ;
-        ( goal_is_conjunction(GoalB, parallel_conj) ->
-            get_number_of_args(GoalA, NbArgsA),
-            NbSharedVars < NbArgsA
-        ;
-            (
-                get_number_of_args(GoalA, NbArgsA),
-                get_number_of_args(GoalB, NbArgsB)
-            ->
-                ( NbSharedVars < NbArgsA, NbSharedVars < NbArgsB
-                ; NbSharedVars = NbArgsA, NbSharedVars < NbArgsB
-                ; NbSharedVars < NbArgsA, NbSharedVars = NbArgsB
-                )
-            ;
-                unexpected($module, $pred, "could not get arg numbers")
-            )
-        )
-    ).
-
-    % Give the number of argument variables of a call.
-    %
-:- pred get_number_of_args(hlds_goal::in, int::out) is semidet.
-
-get_number_of_args(Call, NbArgs) :-
-    CallExpr = Call ^ hlds_goal_expr,
-    (
-        CallExpr = plain_call(_, _, Args, _, _, _),
-        list.length(Args, NbArgs)
-    ;
-        CallExpr = generic_call(Details, Args, _, _),
-        (
-            Details = higher_order(_, _, _, _),
-            list.length(Args, NbArgs)
-        ;
-            Details = class_method(_, _, _, _),
-            list.length(Args, NbArgs)
-        )
-    ;
-        CallExpr = call_foreign_proc(_, _, _, Args, _, _, _),
-        list.length(Args, NbArgs)
-    ).
-
-    % Add a call to an existing parallel conjunction.
-    %
-:- pred add_call_to_parallel_conjunction(hlds_goal::in, hlds_goal::in,
-    hlds_goal::out) is det.
-
-add_call_to_parallel_conjunction(Call, ParallelGoal0, ParallelGoal) :-
-    ParallelGoal0 = hlds_goal(ParallelGoalExpr0, ParallelGoalInfo0),
-    ( ParallelGoalExpr0 = conj(parallel_conj, GoalList0) ->
-        GoalList = [Call | GoalList0],
-        goal_list_nonlocals(GoalList, NonLocals),
-        goal_list_instmap_delta(GoalList, InstMapDelta),
-        goal_list_determinism(GoalList, Detism),
-        goal_list_purity(GoalList, Purity),
-        goal_info_set_nonlocals(NonLocals, ParallelGoalInfo0,
-            ParallelGoalInfo1),
-        goal_info_set_instmap_delta(InstMapDelta, ParallelGoalInfo1,
-            ParallelGoalInfo2),
-        goal_info_set_determinism(Detism,
-            ParallelGoalInfo2, ParallelGoalInfo3),
-        goal_info_set_purity(Purity, ParallelGoalInfo3, ParallelGoalInfo),
-        ParallelGoalExpr = conj(parallel_conj, GoalList),
-        ParallelGoal = hlds_goal(ParallelGoalExpr, ParallelGoalInfo)
-    ;
-        unexpected($module, $pred, "not conjunction")
-    ).
-
-    % Succeed if the first goal depends on the second one.
-    % Fail otherwise.
-    %
-:- pred goal_depends_on_goal(hlds_goal::in, hlds_goal::in) is semidet.
-
-goal_depends_on_goal(Goal1, Goal2) :-
-    Goal1 = hlds_goal(_, GoalInfo1),
-    Goal2 = hlds_goal(_, GoalInfo2),
-    InstmapDelta1 = goal_info_get_instmap_delta(GoalInfo1),
-    instmap_delta_changed_vars(InstmapDelta1, ChangedVars1),
-    NonLocals2 = goal_info_get_nonlocals(GoalInfo2),
-    set.intersect(ChangedVars1, NonLocals2, Intersection),
-    \+ set.empty(Intersection).
-
-    % Process a conjunction for implicit parallelism.
-    %
-:- pred process_conj_for_implicit_parallelism(
-    hlds_goal_expr::in, hlds_goal_expr::out, int::in,
-    proc_info::in, module_info::in, module_info::out,
-    list(candidate_call_site)::in, list(candidate_call_site)::out,
-    counter::in, counter::out) is det.
-
-process_conj_for_implicit_parallelism(!GoalExpr, IndexInConj, ProcInfo,
-    !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter) :-
-    ( !.GoalExpr = conj(_, GoalsConj) ->
-        list.length(GoalsConj, Length),
-        ( IndexInConj > Length ->
-            true
-        ;
-            MaybeConj0 = yes(!.GoalExpr),
-            list.index1_det(GoalsConj, IndexInConj, GoalInConj),
-            % We are not interested in the return value of GoalInConj, only
-            % MaybeConj matters.
-            process_goal_for_implicit_parallelism(GoalInConj, _, ProcInfo,
-                !ModuleInfo, MaybeConj0, MaybeConj, IndexInConj, IndexInConj0,
-                !CalleesToBeParallelized, !SiteNumCounter),
-            ( MaybeConj = yes(GoalExprProcessed) ->
-                !:GoalExpr = GoalExprProcessed
-            ;
-                unexpected($module, $pred, "failed")
-            ),
-            process_conj_for_implicit_parallelism(!GoalExpr, IndexInConj0,
-                ProcInfo, !ModuleInfo, !CalleesToBeParallelized,
-                !SiteNumCounter)
-        )
-    ;
-        unexpected($module, $pred, "not conjunction")
-    ).
-
-    % Process a disjunction for implicit parallelism.
-    %
-:- pred process_disj_for_implicit_parallelism(
-    list(hlds_goal)::in, list(hlds_goal)::in, list(hlds_goal)::out,
-    proc_info::in, module_info::in, module_info::out,
-    list(candidate_call_site)::in, list(candidate_call_site)::out,
-    counter::in, counter::out) is det.
-
-process_disj_for_implicit_parallelism([], !GoalsAcc, _ProcInfo,
-        !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter).
-process_disj_for_implicit_parallelism([Goal0 | Goals], !GoalsAcc,
-        ProcInfo, !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter) :-
-    process_goal_for_implicit_parallelism(Goal0, Goal, ProcInfo,
-        !ModuleInfo, no, _, 0, _, !CalleesToBeParallelized, !SiteNumCounter),
-    !:GoalsAcc = !.GoalsAcc ++ [Goal],
-    process_disj_for_implicit_parallelism(Goals, !GoalsAcc, ProcInfo,
-        !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter).
-
-    % If we are in a conjunction, update it by replacing the goal at index by
-    % Goal and increment the index.
-    %
-:- pred update_conj_and_index(
-    maybe(hlds_goal_expr)::in, maybe(hlds_goal_expr)::out,
-    hlds_goal::in, int::in, int::out) is det.
-
-update_conj_and_index(!MaybeConj, Goal, !IndexInConj) :-
-    ( !.MaybeConj = yes(conj(Type, Goals0)) ->
-        list.replace_nth_det(Goals0, !.IndexInConj, Goal, Goals),
-        !:IndexInConj = !.IndexInConj + 1,
-        !:MaybeConj = yes(conj(Type, Goals))
-    ;
-        true
-    ).
-
-    % Process a switch for implicit parallelism.
-    %
-:- pred process_switch_cases_for_implicit_parallelism(
-    list(case)::in, list(case)::in, list(case)::out, proc_info::in,
-    module_info::in, module_info::out,
-    list(candidate_call_site)::in, list(candidate_call_site)::out,
-    counter::in, counter::out) is det.
-
-process_switch_cases_for_implicit_parallelism([], !CasesAcc, _ProcInfo,
-        !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter).
-process_switch_cases_for_implicit_parallelism([Case0 | Cases], !CasesAcc,
-        ProcInfo, !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter) :-
-    Case0 = case(MainConsId, OtherConsIds, Goal0),
-    process_goal_for_implicit_parallelism(Goal0, Goal, ProcInfo,
-        !ModuleInfo, no, _, 0, _, !CalleesToBeParallelized, !SiteNumCounter),
-    Case = case(MainConsId, OtherConsIds, Goal),
-    !:CasesAcc = !.CasesAcc ++ [Case],
-    process_switch_cases_for_implicit_parallelism(Cases, !CasesAcc,
-        ProcInfo, !ModuleInfo, !CalleesToBeParallelized, !SiteNumCounter).
-
-%-----------------------------------------------------------------------------%
 :- end_module transform_hlds.implicit_parallelism.
-%-----------------------------------------------------------------------------%
Index: compiler/mercury_compile_middle_passes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile_middle_passes.m,v
retrieving revision 1.12
diff -u -b -r1.12 mercury_compile_middle_passes.m
--- compiler/mercury_compile_middle_passes.m	4 Jan 2011 03:51:09 -0000	1.12
+++ compiler/mercury_compile_middle_passes.m	4 Jan 2011 04:43:16 -0000
@@ -73,6 +73,7 @@
 :- import_module transform_hlds.granularity.
 :- import_module transform_hlds.higher_order.
 :- import_module transform_hlds.implicit_parallelism.
+:- import_module transform_hlds.implicit_parallelism.introduce_parallelism.
 :- import_module transform_hlds.inlining.
 :- import_module transform_hlds.lambda.
 :- import_module transform_hlds.lco.
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.684
diff -u -b -r1.684 options.m
--- compiler/options.m	30 Dec 2010 11:17:56 -0000	1.684
+++ compiler/options.m	4 Jan 2011 03:52:13 -0000
@@ -679,9 +679,6 @@
     ;       control_granularity
     ;       distance_granularity
     ;       implicit_parallelism
-    ;       old_implicit_parallelism
-            % implicit_parallelism_old enables Jerome's implementation,
-            % which has been kept for comparison and use in bench marks.
     ;       region_analysis
 
     % Stuff for the CTGC system (structure sharing / structure reuse).
@@ -1553,7 +1550,6 @@
     control_granularity                 -   bool(no),
     distance_granularity                -   int(0),
     implicit_parallelism                -   bool(no),
-    old_implicit_parallelism            -   bool(no),
     region_analysis                     -   bool(no),
 
     % HLDS -> LLDS
@@ -2447,7 +2443,6 @@
 long_option("control-granularity",  control_granularity).
 long_option("distance-granularity", distance_granularity).
 long_option("implicit-parallelism", implicit_parallelism).
-long_option("old-implicit-parallelism", old_implicit_parallelism).
 
 % CTGC related options.
 long_option("structure-sharing",    structure_sharing_analysis).
@@ -5021,8 +5016,6 @@
         "\tmdprof_feedback.",
         "\tThe profiling feedback file can be specified using the",
         "\t--feedback file option."
-%        "--old-implicit-parallelism",
-%        "\tUse the old implicit parallelism implementation",
 % '--region-analysis' is not documented because it is still experimental.
 %        "--region-analysis",
 %        "\tEnable the analysis for region-based memory management."
cvs diff: Diffing compiler/notes
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.149
diff -u -b -r1.149 compiler_design.html
--- compiler/notes/compiler_design.html	14 Oct 2009 05:28:53 -0000	1.149
+++ compiler/notes/compiler_design.html	4 Jan 2011 04:51:12 -0000
@@ -1190,6 +1190,14 @@
   parallelism. Its goal is to minimize parallelism's overhead while still
   gaining all the parallelism the machine can actually exploit.
 
+<li> implicit_parallelism.m is a package whose task is to introduce parallelism
+  into sequential code automatically. Its submodules are
+	<ul>
+	<li> introduce_parallelism.m does the main task of the package.
+	<li> push_goals_together.m performs a transformation that allows
+	     introduce_parallelism.m to do a better job.
+	</ul>
+
 </ul>
 
 <p>
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/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
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