Revised diff for parallel conjunction
Thomas Charles CONWAY
conway at cs.mu.oz.au
Mon Oct 27 12:03:03 AEDT 1997
Hi
Here is a revised diff that addresses the concerns that fjh mentioned
in response to the earlier diff.
Note that the op declarations are ones that *should* have been part
of the diff that added '&' as an operator (comitted about 1000 years
ago).
Thomas
--
ZZ:wq!
^X^C
Thomas Conway conway at cs.mu.oz.au
AD DEUM ET VINUM Every sword has two edges.
Add parallel conjunction to the compiler.
New syntax: "Goal1 & Goal2".
Status: experemental, very alpha. (Currently there is no runtime
support.)
compiler/prog_data.m:
Add `&' as a constructor for a goal.
compiler/prog_*.m:
Parse parallel conjunction.
compiler/hlds_goal.m:
Add par_conj as a constructor for goal_exprn.
compiler/llds.m:
Add "fork", "join_and_terminate", and "join_and_continue"
as llds instructions.
compiler/instmap.m:
add a couple of new predicates:
instmap__unify which unifies the bindings of a set
of variables from a list of instmaps
merge_instmap_deltas which merges a list of instmap
deltas.
compiler/modes_info.m, mode_errors.m:
add a 'lock_context' to locked variables that specifies
whether they were locked in a negation, if-then-else or
parallel conjunction. Use this information for reporting
mode errors.
add a 'parallel vars' field to the mode_info to track which
variables that are nonlocal to the current parallel conjunct
have been bound (even if the conjunct as a whole is
erroneous or failure).
compiler/modes.m:
modecheck parallel conjunctions.
compiler/*.m:
Bits and pieces to handle parallel conjunction and
the fork/join llds instructions.
cvs diff: Diffing .
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/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing bytecode
cvs diff: Diffing bytecode/test
cvs diff: Diffing compiler
Index: compiler/bytecode_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.30
diff -u -r1.30 bytecode_gen.m
--- bytecode_gen.m 1997/09/01 14:00:22 1.30
+++ bytecode_gen.m 1997/09/08 22:43:24
@@ -193,6 +193,9 @@
GoalExpr = conj(GoalList),
bytecode_gen__conj(GoalList, ByteInfo0, ByteInfo, Code)
;
+ GoalExpr = par_conj(_GoalList, _SM),
+ error("sorry, bytecode_gen of parallel conj not implemented")
+ ;
GoalExpr = disj(GoalList, _),
( GoalList = [] ->
Code = node([fail]),
Index: compiler/code_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/code_gen.m,v
retrieving revision 1.38
diff -u -r1.38 code_gen.m
--- code_gen.m 1997/10/11 15:42:40 1.38
+++ code_gen.m 1997/10/17 04:20:09
@@ -58,7 +58,7 @@
:- implementation.
:- import_module call_gen, unify_gen, ite_gen, switch_gen, disj_gen.
-:- import_module pragma_c_gen, trace, globals, options, hlds_out.
+:- import_module par_conj_gen, pragma_c_gen, trace, globals, options, hlds_out.
:- import_module code_aux, middle_rec, passes_aux, llds_out.
:- import_module code_util, type_util, mode_util.
:- import_module prog_data, instmap.
@@ -672,6 +672,8 @@
code_gen__generate_det_goal_2(conj(Goals), _GoalInfo, Instr) -->
code_gen__generate_goals(Goals, model_det, Instr).
+code_gen__generate_det_goal_2(par_conj(Goals, _StoreMap), GoalInfo, Instr) -->
+ par_conj_gen__generate_det_par_conj(Goals, GoalInfo, Instr).
code_gen__generate_det_goal_2(some(_Vars, Goal), _GoalInfo, Instr) -->
{ Goal = _ - InnerGoalInfo },
{ goal_info_get_code_model(InnerGoalInfo, CodeModel) },
@@ -760,6 +762,10 @@
code_gen__generate_semi_goal_2(conj(Goals), _GoalInfo, Code) -->
code_gen__generate_goals(Goals, model_semi, Code).
+code_gen__generate_semi_goal_2(par_conj(_Goals, _SM), _GoalInfo, _Code) -->
+ % Determinism analysis will report a determinism error if the
+ % parallel conj is not det.
+ { error("sorry, semidet parallel conjunction not implemented") }.
code_gen__generate_semi_goal_2(some(_Vars, Goal), _GoalInfo, Code) -->
{ Goal = _ - InnerGoalInfo },
{ goal_info_get_code_model(InnerGoalInfo, CodeModel) },
@@ -972,6 +978,10 @@
code_gen__generate_non_goal_2(conj(Goals), _GoalInfo, Code) -->
code_gen__generate_goals(Goals, model_non, Code).
+code_gen__generate_non_goal_2(par_conj(_Goals, _SM), _GoalInfo, _Code) -->
+ % Determinism analysis will report a determinism error if the
+ % parallel conj is not det.
+ { error("sorry, nondet parallel conjunction not implemented") }.
code_gen__generate_non_goal_2(some(_Vars, Goal), _GoalInfo, Code) -->
{ Goal = _ - InnerGoalInfo },
{ goal_info_get_code_model(InnerGoalInfo, CodeModel) },
Index: compiler/code_info.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/code_info.m,v
retrieving revision 1.213
diff -u -r1.213 code_info.m
--- code_info.m 1997/10/03 04:55:31 1.213
+++ code_info.m 1997/10/20 22:44:01
@@ -275,12 +275,6 @@
% switched on.
).
-:- type slot_contents
- ---> ticket % a ticket (trail pointer)
- ; ticket_counter % a copy of the ticket counter
- ; trace_data
- ; lval(lval).
-
%---------------------------------------------------------------------------%
code_info__init(Varset, Liveness, StackSlots, SaveSuccip, Globals,
@@ -2969,6 +2963,7 @@
% modify this, if the GC is going
% to garbage-collect the trail.
code_info__get_live_value_type(ticket_counter, unwanted).
+code_info__get_live_value_type(sync_term, unwanted).
code_info__get_live_value_type(trace_data, unwanted).
%---------------------------------------------------------------------------%
@@ -3006,6 +3001,15 @@
:- interface.
+:- type slot_contents
+ ---> ticket % a ticket (trail pointer)
+ ; ticket_counter % a copy of the ticket counter
+ ; trace_data
+ ; sync_term % a syncronization term used
+ % at the end of par_conjs.
+ % see par_conj_gen.m for details.
+ ; lval(lval).
+
% Returns the total stackslot count, but not including space for
% succip.
:- pred code_info__get_total_stackslot_count(int, code_info, code_info).
@@ -3014,11 +3018,6 @@
:- pred code_info__get_trace_slot(lval, code_info, code_info).
:- mode code_info__get_trace_slot(out, in, out) is det.
-%---------------------------------------------------------------------------%
-%---------------------------------------------------------------------------%
-
-:- implementation.
-
:- pred code_info__acquire_temp_slot(slot_contents, lval,
code_info, code_info).
:- mode code_info__acquire_temp_slot(in, out, in, out) is det.
@@ -3029,12 +3028,20 @@
:- pred code_info__get_variable_slot(var, lval, code_info, code_info).
:- mode code_info__get_variable_slot(in, out, in, out) is det.
-:- pred code_info__max_var_slot(stack_slots, int).
-:- mode code_info__max_var_slot(in, out) is det.
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
:- pred code_info__stack_variable(int, lval, code_info, code_info).
:- mode code_info__stack_variable(in, out, in, out) is det.
+:- pred code_info__stack_variable_reference(int, rval, code_info, code_info).
+:- mode code_info__stack_variable_reference(in, out, in, out) is det.
+
+:- pred code_info__max_var_slot(stack_slots, int).
+:- mode code_info__max_var_slot(in, out) is det.
+
code_info__get_trace_slot(StackVar) -->
code_info__acquire_temp_slot(trace_data, StackVar).
@@ -3109,6 +3116,15 @@
{ Lval = framevar(Num1) }
;
{ Lval = stackvar(Num) } % stackvars start at one
+ ).
+
+code_info__stack_variable_reference(Num, mem_addr(Ref)) -->
+ code_info__get_proc_model(CodeModel),
+ ( { CodeModel = model_non } ->
+ { Num1 is Num - 1 }, % framevars start at zero
+ { Ref = framevar_ref(Num1) }
+ ;
+ { Ref = stackvar_ref(Num) } % stackvars start at one
).
%---------------------------------------------------------------------------%
Index: compiler/code_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/code_util.m,v
retrieving revision 1.89
diff -u -r1.89 code_util.m
--- code_util.m 1997/09/01 14:00:37 1.89
+++ code_util.m 1997/09/08 22:43:24
@@ -786,6 +786,8 @@
code_util__count_recursive_calls_2(conj(Goals), PredId, ProcId, Min, Max) :-
code_util__count_recursive_calls_conj(Goals, PredId, ProcId, 0, 0,
Min, Max).
+code_util__count_recursive_calls_2(par_conj(Goals, _), PredId, ProcId, Min, Max) :-
+ code_util__count_recursive_calls_conj(Goals, PredId, ProcId, 0, 0, Min, Max).
code_util__count_recursive_calls_2(disj(Goals, _), PredId, ProcId, Min, Max) :-
code_util__count_recursive_calls_disj(Goals, PredId, ProcId, Min, Max).
code_util__count_recursive_calls_2(switch(_, _, Cases, _), PredId, ProcId,
Index: compiler/constraint.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/constraint.m,v
retrieving revision 1.35
diff -u -r1.35 constraint.m
--- constraint.m 1997/09/01 14:00:47 1.35
+++ constraint.m 1997/09/08 22:43:24
@@ -140,6 +140,9 @@
constraint__propagate_conj(Goals0, Goals),
mode_checkpoint(exit, "conj").
+constraint__propagate_goal_2(par_conj(_, _), par_conj(_, _)) -->
+ { error("constraint__propagate_goal_2: par_conj not supported") }.
+
constraint__propagate_goal_2(disj(Goals0, SM), disj(Goals, SM)) -->
mode_checkpoint(enter, "disj"),
constraint__propagate_disj(Goals0, Goals),
Index: compiler/cse_detection.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/cse_detection.m,v
retrieving revision 1.48
diff -u -r1.48 cse_detection.m
--- cse_detection.m 1997/09/01 14:00:51 1.48
+++ cse_detection.m 1997/09/08 22:43:24
@@ -236,6 +236,10 @@
Redo, conj(Goals)) :-
detect_cse_in_conj(Goals0, InstMap, CseInfo0, CseInfo, Redo, Goals).
+detect_cse_in_goal_2(par_conj(Goals0, SM), _, InstMap, CseInfo0, CseInfo, Redo,
+ par_conj(Goals, SM)) :-
+ detect_cse_in_par_conj(Goals0, InstMap, CseInfo0, CseInfo, Redo, Goals).
+
detect_cse_in_goal_2(disj(Goals0, SM), GoalInfo, InstMap, CseInfo0, CseInfo,
Redo, Goal) :-
( Goals0 = [] ->
@@ -280,6 +284,20 @@
;
Goals = [Goal1 | Goals1]
),
+ bool__or(Redo1, Redo2, Redo).
+
+%-----------------------------------------------------------------------------%
+
+:- pred detect_cse_in_par_conj(list(hlds_goal), instmap, cse_info, cse_info,
+ bool, list(hlds_goal)).
+:- mode detect_cse_in_par_conj(in, in, in, out, out, out) is det.
+
+detect_cse_in_par_conj([], _InstMap, CseInfo, CseInfo, no, []).
+detect_cse_in_par_conj([Goal0 | Goals0], InstMap0, CseInfo0, CseInfo,
+ Redo, [Goal | Goals]) :-
+ detect_cse_in_goal(Goal0, InstMap0, CseInfo0, CseInfo1, Redo1, Goal),
+ detect_cse_in_par_conj(Goals0, InstMap0, CseInfo1, CseInfo,
+ Redo2, Goals),
bool__or(Redo1, Redo2, Redo).
%-----------------------------------------------------------------------------%
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.32
diff -u -r1.32 dead_proc_elim.m
--- dead_proc_elim.m 1997/09/01 14:00:56 1.32
+++ dead_proc_elim.m 1997/09/09 02:13:39
@@ -350,6 +350,10 @@
Needed0, Needed) :-
dead_proc_elim__examine_goals(Goals, CurrProc, Queue0, Queue,
Needed0, Needed).
+dead_proc_elim__examine_expr(par_conj(Goals, _SM), CurrProc, Queue0, Queue,
+ Needed0, Needed) :-
+ dead_proc_elim__examine_goals(Goals, CurrProc, Queue0, Queue,
+ Needed0, Needed).
dead_proc_elim__examine_expr(not(Goal), CurrProc, Queue0, Queue,
Needed0, Needed) :-
dead_proc_elim__examine_goal(Goal, CurrProc, Queue0, Queue,
@@ -681,6 +685,8 @@
dead_pred_info::in, dead_pred_info::out) is det.
pre_modecheck_examine_goal(conj(Goals) - _) -->
+ list__foldl(pre_modecheck_examine_goal, Goals).
+pre_modecheck_examine_goal(par_conj(Goals, _) - _) -->
list__foldl(pre_modecheck_examine_goal, Goals).
pre_modecheck_examine_goal(disj(Goals, _) - _) -->
list__foldl(pre_modecheck_examine_goal, Goals).
Index: compiler/dependency_graph.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dependency_graph.m,v
retrieving revision 1.30
diff -u -r1.30 dependency_graph.m
--- dependency_graph.m 1997/09/01 14:00:59 1.30
+++ dependency_graph.m 1997/09/08 22:43:25
@@ -195,6 +195,10 @@
DepGraph0, DepGraph) :-
dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph).
+dependency_graph__add_arcs_in_goal_2(par_conj(Goals, _SM), Caller,
+ DepGraph0, DepGraph) :-
+ dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph).
+
dependency_graph__add_arcs_in_goal_2(disj(Goals, _), Caller,
DepGraph0, DepGraph) :-
dependency_graph__add_arcs_in_list(Goals, Caller, DepGraph0, DepGraph).
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/det_analysis.m,v
retrieving revision 1.122
diff -u -r1.122 det_analysis.m
--- det_analysis.m 1997/09/01 14:01:06 1.122
+++ det_analysis.m 1997/10/21 02:15:48
@@ -378,6 +378,23 @@
det_infer_conj(Goals0, InstMap0, SolnContext, DetInfo,
Goals, Detism, Msgs).
+det_infer_goal_2(par_conj(Goals0, SM), GoalInfo, InstMap0, SolnContext,
+ DetInfo, _, _, par_conj(Goals, SM), Detism, Msgs) :-
+ det_infer_par_conj(Goals0, InstMap0, SolnContext, DetInfo,
+ Goals, Detism, Msgs0),
+ (
+ determinism_components(Detism, CanFail, Solns),
+ CanFail = cannot_fail,
+ Solns \= at_most_many
+ ->
+ Msgs = Msgs0
+ ;
+ det_info_get_pred_id(DetInfo, PredId),
+ det_info_get_proc_id(DetInfo, ProcId),
+ Msg = par_conj_not_det(Detism, PredId, ProcId, GoalInfo, Goals),
+ Msgs = [Msg|Msgs0]
+ ).
+
det_infer_goal_2(disj(Goals0, SM), _, InstMap0, SolnContext, DetInfo, _, _,
disj(Goals, SM), Detism, Msgs) :-
det_infer_disj(Goals0, InstMap0, SolnContext, DetInfo,
@@ -659,6 +676,27 @@
% Finally combine the results computed above.
%
det_conjunction_detism(DetismA, DetismB, Detism),
+ list__append(MsgsA, MsgsB, Msgs).
+
+:- pred det_infer_par_conj(list(hlds_goal), instmap, soln_context, det_info,
+ list(hlds_goal), determinism, list(det_msg)).
+:- mode det_infer_par_conj(in, in, in, in, out, out, out) is det.
+
+det_infer_par_conj([], _InstMap0, _SolnContext, _DetInfo, [], det, []).
+det_infer_par_conj([Goal0 | Goals0], InstMap0, SolnContext, DetInfo,
+ [Goal | Goals], Detism, Msgs) :-
+
+ det_infer_goal(Goal0, InstMap0, SolnContext, DetInfo,
+ Goal, DetismA, MsgsA),
+ determinism_components(DetismA, CanFailA, MaxSolnsA),
+
+ det_infer_par_conj(Goals0, InstMap0, SolnContext, DetInfo,
+ Goals, DetismB, MsgsB),
+ determinism_components(DetismB, CanFailB, MaxSolnsB),
+
+ det_conjunction_maxsoln(MaxSolnsA, MaxSolnsB, MaxSolns),
+ det_conjunction_canfail(CanFailA, CanFailB, CanFail),
+ determinism_components(Detism, CanFail, MaxSolns),
list__append(MsgsA, MsgsB, Msgs).
:- pred det_infer_disj(list(hlds_goal), instmap, soln_context, det_info,
Index: compiler/det_report.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/det_report.m,v
retrieving revision 1.42
diff -u -r1.42 det_report.m
--- det_report.m 1997/10/15 07:39:42 1.42
+++ det_report.m 1997/10/21 02:10:18
@@ -49,7 +49,10 @@
determinism)
; error_in_lambda(
determinism, determinism, % declared, inferred
- hlds_goal, hlds_goal_info, pred_id, proc_id).
+ hlds_goal, hlds_goal_info, pred_id, proc_id)
+ ; par_conj_not_det(determinism, pred_id, proc_id,
+ hlds_goal_info, list(hlds_goal))
+ .
:- type seen_call_id
---> seen_call(pred_id, proc_id)
@@ -383,6 +386,10 @@
Diagnosed) -->
det_diagnose_conj(Goals, Desired, Context, DetInfo, Diagnosed).
+det_diagnose_goal_2(par_conj(Goals, _SM), _GoalInfo, Desired, _Actual,
+ Context, DetInfo, Diagnosed) -->
+ det_diagnose_conj(Goals, Desired, Context, DetInfo, Diagnosed).
+
det_diagnose_goal_2(disj(Goals, _), GoalInfo, Desired, Actual, SwitchContext,
DetInfo, Diagnosed) -->
det_diagnose_disj(Goals, Desired, Actual, SwitchContext, DetInfo, 0,
@@ -598,6 +605,9 @@
io__write_string(".\n")
).
+ % det_diagnose_conj is used for both normal [sequential]
+ % conjunction and parallel conjunction.
+
:- pred det_diagnose_conj(list(hlds_goal), determinism,
list(switch_context), det_info, bool, io__state, io__state).
:- mode det_diagnose_conj(in, in, in, in, out, di, uo) is det.
@@ -891,6 +901,7 @@
det_msg_get_type(cc_pred_in_wrong_context(_, _, _, _), error).
det_msg_get_type(higher_order_cc_pred_in_wrong_context(_, _), error).
det_msg_get_type(error_in_lambda(_, _, _, _, _, _), error).
+det_msg_get_type(par_conj_not_det(_, _, _, _, _), error).
:- pred det_report_msg(det_msg, module_info, io__state, io__state).
:- mode det_report_msg(in, in, di, uo) is det.
@@ -1104,6 +1115,33 @@
globals__io_get_globals(Globals),
{ det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) },
det_diagnose_goal(Goal, DeclaredDetism, [], DetInfo, _),
+ io__set_exit_status(1).
+det_report_msg(par_conj_not_det(InferredDetism, PredId,
+ ProcId, GoalInfo, Goals), ModuleInfo) -->
+ { goal_info_get_context(GoalInfo, Context) },
+ prog_out__write_context(Context),
+ { determinism_components(InferredDetism, CanFail, MaxSoln) },
+ (
+ { CanFail \= cannot_fail }
+ ->
+ io__write_string("Error: parallel conjunct may fail.\n")
+ ;
+ { MaxSoln = at_most_many }
+ ->
+ prog_out__write_context(Context),
+ io__write_string("Error: parallel conjunct may have multiple solutions.\n")
+ ;
+ { error("strange determinism error for parallel conjunction") }
+ ),
+ prog_out__write_context(Context),
+ io__write_string(
+ " The current implementation supports only single-solution\n"
+ ),
+ prog_out__write_context(Context),
+ io__write_string(" non-failing parallel conjunctions.\n"),
+ globals__io_get_globals(Globals),
+ { det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) },
+ det_diagnose_conj(Goals, det, [], DetInfo, _),
io__set_exit_status(1).
%-----------------------------------------------------------------------------%
Index: compiler/dnf.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dnf.m,v
retrieving revision 1.22
diff -u -r1.22 dnf.m
--- dnf.m 1997/09/01 14:01:21 1.22
+++ dnf.m 1997/09/08 23:03:03
@@ -184,6 +184,9 @@
Goals, NewPredIds0, NewPredIds),
Goal = conj(Goals) - GoalInfo
;
+ GoalExpr0 = par_conj(_Goals0, _SM),
+ error("sorry, dnf of parallel conjunction not implemented")
+ ;
GoalExpr0 = some(_, _),
dnf__transform_conj([Goal0], InstMap0, MaybeNonAtomic,
ModuleInfo0, ModuleInfo, Base, 0, _, DnfInfo,
@@ -441,6 +444,7 @@
:- pred dnf__is_atomic_expr(hlds_goal_expr::in, bool::out) is det.
dnf__is_atomic_expr(conj(_), no).
+dnf__is_atomic_expr(par_conj(_, _), no).
dnf__is_atomic_expr(higher_order_call(_, _, _, _, _, _), yes).
dnf__is_atomic_expr(call(_, _, _, _, _, _), yes).
dnf__is_atomic_expr(switch(_, _, _, _), no).
Index: compiler/dupelim.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dupelim.m,v
retrieving revision 1.22
diff -u -r1.22 dupelim.m
--- dupelim.m 1997/08/25 17:48:09 1.22
+++ dupelim.m 1997/09/08 22:43:25
@@ -190,6 +190,16 @@
dupelim__replace_labels_instr(incr_sp(Size, Msg), _, incr_sp(Size, Msg)).
dupelim__replace_labels_instr(decr_sp(Size), _, decr_sp(Size)).
dupelim__replace_labels_instr(pragma_c(A,B,C,D,E), _, pragma_c(A,B,C,D,E)).
+dupelim__replace_labels_instr(fork(Child0, Parent0, SlotCount), Replmap,
+ fork(Child, Parent, SlotCount)) :-
+ dupelim__replace_labels_label(Child0, Replmap, Child),
+ dupelim__replace_labels_label(Parent0, Replmap, Parent).
+dupelim__replace_labels_instr(join_and_terminate(Lval0), Replmap, join_and_terminate(Lval)) :-
+ dupelim__replace_labels_lval(Lval0, Replmap, Lval).
+dupelim__replace_labels_instr(join_and_continue(Lval0, Label0),
+ Replmap, join_and_continue(Lval, Label)) :-
+ dupelim__replace_labels_label(Label0, Replmap, Label),
+ dupelim__replace_labels_lval(Lval0, Replmap, Lval).
:- pred dupelim__replace_labels_lval(lval, map(label, label), lval).
% :- mode dupelim__replace_labels_lval(di, in, uo) is det.
Index: compiler/excess.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/excess.m,v
retrieving revision 1.24
diff -u -r1.24 excess.m
--- excess.m 1997/09/01 14:01:24 1.24
+++ excess.m 1997/09/08 23:03:11
@@ -91,6 +91,12 @@
Goals, ElimVars),
conj_list_to_goal(Goals, GoalInfo0, Goal)
;
+ GoalExpr0 = par_conj(Goals0, _SM),
+ goal_info_get_nonlocals(GoalInfo0, NonLocals),
+ excess_assignments_in_conj(Goals0, [], ElimVars0, NonLocals,
+ Goals, ElimVars),
+ par_conj_list_to_goal(Goals, GoalInfo0, Goal)
+ ;
GoalExpr0 = disj(Goals0, SM),
excess_assignments_in_disj(Goals0, ElimVars0, Goals, ElimVars),
Goal = disj(Goals, SM) - GoalInfo0
@@ -142,6 +148,9 @@
% If (say) V_4 and V_6 are nonlocal, then after the V_5 => V_4
% substitution has been made, the second assignment V_4 = V_6
% is left alone.
+ %
+ % This code is used for both sequential conjunction (conj/1) and
+ % parallel conjunction (par_conj/2).
:- pred excess_assignments_in_conj(list(hlds_goal), list(hlds_goal),
list(var), set(var), list(hlds_goal), list(var)).
Index: compiler/follow_code.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/follow_code.m,v
retrieving revision 1.43
diff -u -r1.43 follow_code.m
--- follow_code.m 1997/09/01 14:01:28 1.43
+++ follow_code.m 1997/09/08 22:43:25
@@ -88,6 +88,13 @@
move_follow_code_in_goal_2(conj(Goals0), conj(Goals), Flags, R0, R) :-
move_follow_code_in_conj(Goals0, Goals, Flags, R0, R).
+move_follow_code_in_goal_2(par_conj(Goals0, SM), par_conj(Goals, SM),
+ Flags, R0, R) :-
+ % move_follow_code_in_disj treats its list of goals as
+ % independent goals, so we can use it to process the
+ % independent parallel conjuncts.
+ move_follow_code_in_disj(Goals0, Goals, Flags, R0, R).
+
move_follow_code_in_goal_2(disj(Goals0, SM), disj(Goals, SM), Flags, R0, R) :-
move_follow_code_in_disj(Goals0, Goals, Flags, R0, R).
@@ -118,6 +125,9 @@
pragma_c_code(A,B,C,D,E,F,G,H), _, R, R).
%-----------------------------------------------------------------------------%
+
+ % move_follow_code_in_disj is used both for disjunction and
+ % parallel conjunction.
:- pred move_follow_code_in_disj(list(hlds_goal), list(hlds_goal),
pair(bool), bool, bool).
Index: compiler/follow_vars.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/follow_vars.m,v
retrieving revision 1.43
diff -u -r1.43 follow_vars.m
--- follow_vars.m 1997/09/01 14:01:32 1.43
+++ follow_vars.m 1997/09/08 22:43:25
@@ -95,6 +95,14 @@
find_follow_vars_in_conj(Goals0, ArgsMethod, ModuleInfo, FollowVars0,
no, Goals, FollowVars).
+find_follow_vars_in_goal_2(par_conj(Goals0, SM), ArgsMethod, ModuleInfo,
+ FollowVars0, par_conj(Goals, SM), FollowVars) :-
+ % find_follow_vars_in_disj treats its list of goals as a
+ % series of independent goals, so we can use it to process
+ % independent parallel conjunction.
+ find_follow_vars_in_disj(Goals0, ArgsMethod, ModuleInfo, FollowVars0,
+ Goals, FollowVars).
+
% We record that at the end of each disjunct, live variables should
% be in the locations given by the initial follow_vars, which reflects
% the requirements of the code following the disjunction.
@@ -263,6 +271,8 @@
% they can only be entered with everything in stack slots; for
% model_det and model_semi disjunctions, they will never be
% entered at all.)
+ %
+ % This code is used both for disjunction and parallel conjunction.
:- pred find_follow_vars_in_disj(list(hlds_goal), args_method, module_info,
follow_vars, list(hlds_goal), follow_vars).
Index: compiler/frameopt.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/frameopt.m,v
retrieving revision 1.63
diff -u -r1.63 frameopt.m
--- frameopt.m 1997/08/25 17:48:12 1.63
+++ frameopt.m 1997/09/08 22:43:25
@@ -688,6 +688,9 @@
possible_targets(incr_sp(_, _), []).
possible_targets(decr_sp(_), []).
possible_targets(pragma_c(_, _, _, _, _), []).
+possible_targets(fork(Child, Parent, _), [Child, Parent]).
+possible_targets(join_and_terminate(_), []).
+possible_targets(join_and_continue(_, Label), [Label]).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -1301,18 +1304,33 @@
substitute_labels_instr(decr_sp(Size), _, decr_sp(Size)).
substitute_labels_instr(pragma_c(Decl, In, Code, Out, Context), _,
pragma_c(Decl, In, Code, Out, Context)).
+substitute_labels_instr(fork(Child0, Parent0, Lval), LabelMap,
+ fork(Child, Parent, Lval)) :-
+ substitute_label(LabelMap, Child0, Child),
+ substitute_label(LabelMap, Parent0, Parent).
+substitute_labels_instr(join_and_terminate(Lval), _LabelMap, join_and_terminate(Lval)).
+substitute_labels_instr(join_and_continue(Lval, Label0), LabelMap,
+ join_and_continue(Lval, Label)) :-
+ substitute_label(LabelMap, Label0, Label).
:- pred substitute_labels_list(list(label)::in, assoc_list(label)::in,
list(label)::out) is det.
substitute_labels_list([], _, []).
substitute_labels_list([Label0 | Labels0], LabelMap, [Label | Labels]) :-
- ( assoc_list__search(LabelMap, Label0, Label1) ->
+ substitute_label(LabelMap, Label0, Label),
+ substitute_labels_list(Labels0, LabelMap, Labels).
+
+:- pred substitute_label(assoc_list(label)::in, label::in, label::out) is det.
+
+substitute_label(LabelMap, Label0, Label) :-
+ (
+ assoc_list__search(LabelMap, Label0, Label1)
+ ->
Label = Label1
;
Label = Label0
- ),
- substitute_labels_list(Labels0, LabelMap, Labels).
+ ).
%-----------------------------------------------------------------------------%
Index: compiler/goal_path.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/goal_path.m,v
retrieving revision 1.1
diff -u -r1.1 goal_path.m
--- goal_path.m 1997/10/13 08:09:39 1.1
+++ goal_path.m 1997/10/20 02:24:17
@@ -40,6 +40,8 @@
fill_expr_slots(conj(Goals0), Path0, conj(Goals)) :-
fill_conj_slots(Goals0, Path0, 0, Goals).
+fill_expr_slots(par_conj(Goals0, SM), Path0, par_conj(Goals, SM)) :-
+ fill_conj_slots(Goals0, Path0, 0, Goals).
fill_expr_slots(disj(Goals0, B), Path0, disj(Goals, B)) :-
fill_disj_slots(Goals0, Path0, 0, Goals).
fill_expr_slots(switch(A, B, Cases0, D), Path0, switch(A, B, Cases, D)) :-
Index: compiler/goal_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/goal_util.m,v
retrieving revision 1.38
diff -u -r1.38 goal_util.m
--- goal_util.m 1997/09/01 14:01:36 1.38
+++ goal_util.m 1997/09/08 22:43:25
@@ -191,6 +191,11 @@
goal_util__name_apart_2(conj(Goals0), Must, Subn, conj(Goals)) :-
goal_util__name_apart_list(Goals0, Must, Subn, Goals).
+goal_util__name_apart_2(par_conj(Goals0, SM0), Must, Subn,
+ par_conj(Goals, SM)) :-
+ goal_util__name_apart_list(Goals0, Must, Subn, Goals),
+ goal_util__rename_var_maps(SM0, Must, Subn, SM).
+
goal_util__name_apart_2(disj(Goals0, SM0), Must, Subn, disj(Goals, SM)) :-
goal_util__name_apart_list(Goals0, Must, Subn, Goals),
goal_util__rename_var_maps(SM0, Must, Subn, SM).
@@ -424,6 +429,9 @@
goal_util__goal_vars_2(conj(Goals), Set0, Set) :-
goal_util__goals_goal_vars(Goals, Set0, Set).
+goal_util__goal_vars_2(par_conj(Goals, _SM), Set0, Set) :-
+ goal_util__goals_goal_vars(Goals, Set0, Set).
+
goal_util__goal_vars_2(disj(Goals, _), Set0, Set) :-
goal_util__goals_goal_vars(Goals, Set0, Set).
@@ -518,6 +526,9 @@
goal_expr_size(conj(Goals), Size) :-
goals_size(Goals, Size).
+goal_expr_size(par_conj(Goals, _SM), Size) :-
+ goals_size(Goals, Size1),
+ Size is Size1 + 1.
goal_expr_size(disj(Goals, _), Size) :-
goals_size(Goals, Size1),
Size is Size1 + 1.
Index: compiler/higher_order.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/higher_order.m,v
retrieving revision 1.33
diff -u -r1.33 higher_order.m
--- higher_order.m 1997/09/01 14:01:46 1.33
+++ higher_order.m 1997/09/08 22:43:25
@@ -280,6 +280,13 @@
traverse_conj(Goals0, Goals, PredProcId, unchanged, Changed,
0, GoalSize).
+traverse_goal(par_conj(Goals0, SM) - Info, par_conj(Goals, SM) - Info,
+ PredProcId, Changed, GoalSize) -->
+ % traverse_disj treats its list of goals as independent
+ % rather than specifically disjoint, so we can use it
+ % to process a list of independent parallel conjuncts.
+ traverse_disj(Goals0, Goals, PredProcId, Changed, GoalSize).
+
traverse_goal(disj(Goals0, SM) - Info, disj(Goals, SM) - Info,
PredProcId, Changed, GoalSize) -->
traverse_disj(Goals0, Goals, PredProcId, Changed, GoalSize).
@@ -348,6 +355,10 @@
% specialization information before the goal, then merge the
% results to give the specialization information after the
% disjunction.
+ %
+ % This code is used both for disjunction and parallel
+ % conjunction.
+
:- pred traverse_disj(hlds_goals::in, hlds_goals::out, pred_proc_id::in,
changed::out, int::out, higher_order_info::in,
higher_order_info::out) is det.
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_goal.m,v
retrieving revision 1.42
diff -u -r1.42 hlds_goal.m
--- hlds_goal.m 1997/10/13 08:09:41 1.42
+++ hlds_goal.m 1997/10/17 04:20:17
@@ -166,7 +166,15 @@
extra_pragma_info
% Extra information for model_non
% pragma_c_codes; none for others.
- ).
+ )
+
+ ; par_conj(hlds_goals, store_map)
+ % parallel conjunction
+ % The store_map specifies the locations
+ % in which live variables should be
+ % stored at the start of the parallel
+ % conjunction.
+ .
:- type extra_pragma_info
---> none
@@ -622,6 +630,13 @@
:- pred goal_to_conj_list(hlds_goal, list(hlds_goal)).
:- mode goal_to_conj_list(in, out) is det.
+ % Convert a goal to a list of parallel conjuncts.
+ % If the goal is a parallel conjunction, then return its conjuncts,
+ % otherwise return the goal as a singleton list.
+
+:- pred goal_to_par_conj_list(hlds_goal, list(hlds_goal)).
+:- mode goal_to_par_conj_list(in, out) is det.
+
% Convert a goal to a list of disjuncts.
% If the goal is a disjunction, then return its disjuncts,
% otherwise return the goal as a singleton list.
@@ -637,6 +652,14 @@
:- pred conj_list_to_goal(list(hlds_goal), hlds_goal_info, hlds_goal).
:- mode conj_list_to_goal(in, in, out) is det.
+ % Convert a list of parallel conjuncts to a goal.
+ % If the list contains only one goal, then return that goal,
+ % otherwise return the parallel conjunction of the conjuncts,
+ % with the specified goal_info.
+
+:- pred par_conj_list_to_goal(list(hlds_goal), hlds_goal_info, hlds_goal).
+:- mode par_conj_list_to_goal(in, in, out) is det.
+
% Convert a list of disjuncts to a goal.
% If the list contains only one goal, then return that goal,
% otherwise return the disjunction of the disjuncts,
@@ -846,6 +869,17 @@
ConjList = [Goal]
).
+ % Convert a goal to a list of parallel conjuncts.
+ % If the goal is a conjunction, then return its conjuncts,
+ % otherwise return the goal as a singleton list.
+
+goal_to_par_conj_list(Goal, ConjList) :-
+ ( Goal = (par_conj(List, _) - _) ->
+ ConjList = List
+ ;
+ ConjList = [Goal]
+ ).
+
% Convert a goal to a list of disjuncts.
% If the goal is a disjunction, then return its disjuncts
% otherwise return the goal as a singleton list.
@@ -867,6 +901,19 @@
Goal = Goal0
;
Goal = conj(ConjList) - GoalInfo
+ ).
+
+ % Convert a list of parallel conjuncts to a goal.
+ % If the list contains only one goal, then return that goal,
+ % otherwise return the parallel conjunction of the conjuncts,
+ % with the specified goal_info.
+
+par_conj_list_to_goal(ConjList, GoalInfo, Goal) :-
+ ( ConjList = [Goal0] ->
+ Goal = Goal0
+ ;
+ map__init(StoreMap),
+ Goal = par_conj(ConjList, StoreMap) - GoalInfo
).
% Convert a list of disjuncts to a goal.
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_out.m,v
retrieving revision 1.174
diff -u -r1.174 hlds_out.m
--- hlds_out.m 1997/10/13 08:09:43 1.174
+++ hlds_out.m 1997/10/21 02:28:30
@@ -919,14 +919,15 @@
hlds_out__write_indent(Indent),
io__write_string("( % conjunction\n"),
hlds_out__write_conj(Goal, Goals, ModuleInfo, VarSet,
- AppendVarnums, Indent1, "", Verbose, TypeQual),
+ AppendVarnums, Indent1, "", Verbose, ",\n",
+ TypeQual),
hlds_out__write_indent(Indent),
io__write_string(")"),
io__write_string(Follow),
io__write_string("\n")
;
hlds_out__write_conj(Goal, Goals, ModuleInfo, VarSet,
- AppendVarnums, Indent, Follow, Verbose,
+ AppendVarnums, Indent, Follow, Verbose, ",\n",
TypeQual)
)
;
@@ -936,6 +937,27 @@
io__write_string("\n")
).
+hlds_out__write_goal_2(par_conj(List, _), ModuleInfo, VarSet, AppendVarnums,
+ Indent, Follow, TypeQual) -->
+ hlds_out__write_indent(Indent),
+ ( { List = [Goal | Goals] } ->
+ io__write_string("( % parallel conjunction\n"),
+ { Indent1 is Indent + 1 },
+ hlds_out__write_goal_a(Goal, ModuleInfo, VarSet, AppendVarnums,
+ Indent1, "", TypeQual),
+ % See comments at hlds_out__write_goal_list.
+ hlds_out__write_goal_list(Goals, ModuleInfo, VarSet,
+ AppendVarnums, Indent, "&", TypeQual),
+ hlds_out__write_indent(Indent),
+ io__write_string(")"),
+ io__write_string(Follow),
+ io__write_string("\n")
+ ;
+ io__write_string("fail"),
+ io__write_string(Follow),
+ io__write_string("\n")
+ ).
+
hlds_out__write_goal_2(disj(List, _), ModuleInfo, VarSet, AppendVarnums,
Indent, Follow, TypeQual) -->
hlds_out__write_indent(Indent),
@@ -944,8 +966,8 @@
{ Indent1 is Indent + 1 },
hlds_out__write_goal_a(Goal, ModuleInfo, VarSet, AppendVarnums,
Indent1, "", TypeQual),
- hlds_out__write_disj(Goals, ModuleInfo, VarSet, AppendVarnums,
- Indent, TypeQual),
+ hlds_out__write_goal_list(Goals, ModuleInfo, VarSet,
+ AppendVarnums, Indent, ";", TypeQual),
hlds_out__write_indent(Indent),
io__write_string(")"),
io__write_string(Follow),
@@ -1383,11 +1405,12 @@
mercury_output_mode(Mode, VarSet).
:- pred hlds_out__write_conj(hlds_goal, list(hlds_goal), module_info, varset,
- bool, int, string, string, vartypes, io__state, io__state).
-:- mode hlds_out__write_conj(in, in, in, in, in, in, in, in, in, di, uo) is det.
+ bool, int, string, string, string, vartypes, io__state, io__state).
+:- mode hlds_out__write_conj(in, in, in, in, in, in, in, in, in, in,
+ di, uo) is det.
hlds_out__write_conj(Goal1, Goals1, ModuleInfo, VarSet, AppendVarnums,
- Indent, Follow, Verbose, TypeQual) -->
+ Indent, Follow, Verbose, Separator, TypeQual) -->
(
{ Goals1 = [Goal2 | Goals2] }
->
@@ -1400,34 +1423,39 @@
hlds_out__write_goal_a(Goal1, ModuleInfo, VarSet,
AppendVarnums, Indent, "", TypeQual),
hlds_out__write_indent(Indent),
- io__write_string(",\n")
+ io__write_string(Separator)
;
hlds_out__write_goal_a(Goal1, ModuleInfo, VarSet,
- AppendVarnums, Indent, ",", TypeQual)
+ AppendVarnums, Indent, Separator, TypeQual)
),
hlds_out__write_conj(Goal2, Goals2, ModuleInfo, VarSet,
- AppendVarnums, Indent, Follow, Verbose, TypeQual)
+ AppendVarnums, Indent, Follow, Verbose, Separator,
+ TypeQual)
;
hlds_out__write_goal_a(Goal1, ModuleInfo, VarSet,
AppendVarnums, Indent, Follow, TypeQual)
).
-:- pred hlds_out__write_disj(list(hlds_goal), module_info, varset, bool, int,
- vartypes, io__state, io__state).
-:- mode hlds_out__write_disj(in, in, in, in, in, in, di, uo) is det.
+ % hlds_out__write_goal_list is used to write both disjunctions and
+ % parallel conjunctions.
+
+:- pred hlds_out__write_goal_list(list(hlds_goal), module_info, varset, bool,
+ int, string, vartypes, io__state, io__state).
+:- mode hlds_out__write_goal_list(in, in, in, in, in, in, in, di, uo) is det.
-hlds_out__write_disj(GoalList, ModuleInfo, VarSet, AppendVarnums, Indent,
- TypeQual) -->
+hlds_out__write_goal_list(GoalList, ModuleInfo, VarSet, AppendVarnums, Indent,
+ Separator, TypeQual) -->
(
{ GoalList = [Goal | Goals] }
->
hlds_out__write_indent(Indent),
- io__write_string(";\n"),
+ io__write_string(Separator),
+ io__write_string("\n"),
{ Indent1 is Indent + 1 },
hlds_out__write_goal_a(Goal, ModuleInfo, VarSet,
AppendVarnums, Indent1, "", TypeQual),
- hlds_out__write_disj(Goals, ModuleInfo, VarSet,
- AppendVarnums, Indent, TypeQual)
+ hlds_out__write_goal_list(Goals, ModuleInfo, VarSet,
+ AppendVarnums, Indent, Separator, TypeQual)
;
[]
).
Index: compiler/inlining.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/inlining.m,v
retrieving revision 1.69
diff -u -r1.69 inlining.m
--- inlining.m 1997/09/01 14:02:31 1.69
+++ inlining.m 1997/09/09 02:19:04
@@ -386,6 +386,10 @@
inlining__inlining_in_goal(conj(Goals0) - GoalInfo, conj(Goals) - GoalInfo) -->
inlining__inlining_in_conj(Goals0, Goals).
+inlining__inlining_in_goal(par_conj(Goals0, SM) - GoalInfo,
+ par_conj(Goals, SM) - GoalInfo) -->
+ inlining__inlining_in_disj(Goals0, Goals).
+
inlining__inlining_in_goal(disj(Goals0, SM) - GoalInfo,
disj(Goals, SM) - GoalInfo) -->
inlining__inlining_in_disj(Goals0, Goals).
@@ -528,6 +532,9 @@
pragma_c_code(A, B, C, D, E, F, G, H) - GoalInfo) --> [].
%-----------------------------------------------------------------------------%
+
+ % inlining__inlining_in_disj is used for both disjunctions and
+ % parallel conjunctions.
:- pred inlining__inlining_in_disj(list(hlds_goal), list(hlds_goal),
inline_info, inline_info).
Index: compiler/instmap.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/instmap.m,v
retrieving revision 1.16
diff -u -r1.16 instmap.m
--- instmap.m 1997/09/30 14:53:49 1.16
+++ instmap.m 1997/10/21 05:18:35
@@ -185,6 +185,18 @@
mode_info, mode_info).
:- mode instmap__merge(in, in, in, mode_info_di, mode_info_uo) is det.
+ % instmap__unify(NonLocalVars, InstMapNonlocalvarPairss):
+ % Unify the `InstMaps' in the list of pairs resulting
+ % from different branches of a parallel conjunction and
+ % update the instantiatedness of all the nonlocal variables.
+ % The variable locking that is done when modechecking
+ % the individual conjuncts ensures that variables have
+ % at most one producer.
+ %
+:- pred instmap__unify(set(var), list(pair(instmap, set(var))),
+ mode_info, mode_info).
+:- mode instmap__unify(in, in, mode_info_di, mode_info_uo) is det.
+
% instmap__restrict takes an instmap and a set of vars and
% returns an instmap with its domain restricted to those
% vars.
@@ -214,8 +226,8 @@
% merge_instmap_delta(InitialInstMap, NonLocals,
% InstMapDeltaA, InstMapDeltaB, ModuleInfo0, ModuleInfo)
- % Merge the instmap_deltas of different branches of an ite, disj
- % or switch.
+ % Merge the instmap_deltas of different branches of an if-then-else,
+ % disj or switch.
:- pred merge_instmap_delta(instmap, set(var), instmap_delta, instmap_delta,
instmap_delta, module_info, module_info).
:- mode merge_instmap_delta(in, in, in, in, out, in, out) is det.
@@ -229,6 +241,14 @@
instmap_delta, module_info, module_info).
:- mode merge_instmap_deltas(in, in, in, out, in, out) is det.
+ % unify_instmap_delta(InitialInstMap, NonLocals,
+ % InstMapDeltaA, InstMapDeltaB, ModuleInfo0, ModuleInfo)
+ % Unify the instmap_deltas of different branches of a parallel
+ % conjunction.
+:- pred unify_instmap_delta(instmap, set(var), instmap_delta, instmap_delta,
+ instmap_delta, module_info, module_info).
+:- mode unify_instmap_delta(in, in, in, in, out, in, out) is det.
+
%-----------------------------------------------------------------------------%
% `instmap_delta_apply_sub(InstmapDelta0, Must, Sub, InstmapDelta)'
@@ -635,6 +655,127 @@
MergedDelta, ModuleInfo1, ModuleInfo).
%-----------------------------------------------------------------------------%
+
+instmap__unify(NonLocals, InstMapList, ModeInfo0, ModeInfo) :-
+ (
+ % If any of the instmaps is unreachable, then
+ % the final instmap is unreachable.
+ list__member(unreachable - _, InstMapList)
+ ->
+ mode_info_set_instmap(unreachable, ModeInfo0, ModeInfo)
+ ;
+ % If there is only one instmap, then we just
+ % stick it in the mode_info.
+ InstMapList = [InstMap - _]
+ ->
+ mode_info_set_instmap(InstMap, ModeInfo0, ModeInfo)
+ ;
+ InstMapList = [InstMap0 - _|InstMapList1],
+ InstMap0 = reachable(InstMapping0)
+ ->
+ % having got the first instmapping, to use as
+ % an accumulator, all instmap__unify_2 which
+ % unifies each of the nonlocals from each instmap
+ % with the corresponding inst in the accumulator.
+ mode_info_get_module_info(ModeInfo0, ModuleInfo0),
+ set__to_sorted_list(NonLocals, NonLocalsList),
+ instmap__unify_2(NonLocalsList, InstMap0, InstMapList1,
+ ModuleInfo0, InstMapping0, ModuleInfo,
+ InstMapping, ErrorList),
+ mode_info_set_module_info(ModeInfo0, ModuleInfo, ModeInfo1),
+
+ % If there were any errors, then add the error
+ % to the list of possible errors in the mode_info.
+ ( ErrorList = [FirstError | _] ->
+ FirstError = Var - _,
+ set__singleton_set(WaitingVars, Var),
+ mode_info_error(WaitingVars,
+ mode_error_par_conj(ErrorList),
+ ModeInfo1, ModeInfo2)
+ ;
+ ModeInfo2 = ModeInfo1
+ ),
+ mode_info_set_instmap(reachable(InstMapping),
+ ModeInfo2, ModeInfo)
+ ;
+ ModeInfo = ModeInfo0
+ ).
+
+%-----------------------------------------------------------------------------%
+
+ % instmap__unify_2(Vars, InitialInstMap, InstMaps, ModuleInfo,
+ % ErrorList):
+ % Let `ErrorList' be the list of variables in `Vars' for
+ % which there are two instmaps in `InstMaps' for which the insts
+ % of the variable is incompatible.
+:- pred instmap__unify_2(list(var), instmap, list(pair(instmap, set(var))),
+ module_info, map(var, inst), module_info,
+ map(var, inst), merge_errors).
+:- mode instmap__unify_2(in, in, in, in, in, out, out, out) is det.
+
+instmap__unify_2([], _, _, ModuleInfo, InstMap, ModuleInfo, InstMap, []).
+instmap__unify_2([Var|Vars], InitialInstMap, InstMapList, ModuleInfo0, InstMap0,
+ ModuleInfo, InstMap, ErrorList) :-
+ instmap__unify_2(Vars, InitialInstMap, InstMapList, ModuleInfo0,
+ InstMap0, ModuleInfo1, InstMap1, ErrorList1),
+ instmap__lookup_var(InitialInstMap, Var, InitialVarInst),
+ instmap__unify_var(InstMapList, Var, [], Insts, InitialVarInst, Inst,
+ ModuleInfo1, ModuleInfo, no, Error),
+ ( Error = yes ->
+ ErrorList = [Var - Insts | ErrorList1]
+ ;
+ ErrorList = ErrorList1
+ ),
+ map__set(InstMap1, Var, Inst, InstMap).
+
+ % instmap__unify_var(InstMaps, Var, InitialInstMap, ModuleInfo,
+ % Insts, Error):
+ % Let `Insts' be the list of the inst of `Var' in
+ % each of the corresponding `InstMaps'. Let `Error' be yes
+ % iff there are two instmaps for which the inst of `Var'
+ % is incompatible.
+
+:- pred instmap__unify_var(list(pair(instmap, set(var))), var,
+ list(inst), list(inst), inst, inst, module_info, module_info,
+ bool, bool).
+:- mode instmap__unify_var(in, in, in, out, in, out, in, out, in, out) is det.
+
+instmap__unify_var([], _, Insts, Insts, Inst, Inst, ModuleInfo, ModuleInfo,
+ Error, Error).
+instmap__unify_var([InstMap - Nonlocals| Rest], Var, InstList0, InstList,
+ Inst0, Inst, ModuleInfo0, ModuleInfo, Error0, Error) :-
+ (
+ set__member(Var, Nonlocals)
+ ->
+ instmap__lookup_var(InstMap, Var, VarInst),
+ (
+ % We unify the accumulated inst and the inst from the
+ % given instmap - we don't care about the determinism.
+ % Variable locking during mode analysis ensures that
+ % there is a unique producer for each variable - whether
+ % or not the unification may fail is up to determinism
+ % analysis.
+
+ abstractly_unify_inst(live, Inst0, VarInst, fake_unify,
+ ModuleInfo0, Inst1, _Det, ModuleInfo1)
+ ->
+ Inst2 = Inst1,
+ ModuleInfo2 = ModuleInfo1,
+ Error1 = Error0
+ ;
+ Error1 = yes,
+ ModuleInfo2 = ModuleInfo0,
+ Inst2 = not_reached
+ )
+ ;
+ VarInst = free,
+ Inst2 = Inst0,
+ Error1 = Error0,
+ ModuleInfo2 = ModuleInfo0
+ ),
+ instmap__unify_var(Rest, Var, [VarInst | InstList0], InstList,
+ Inst2, Inst, ModuleInfo2, ModuleInfo, Error1, Error).
+
%-----------------------------------------------------------------------------%
% Given two instmaps and a set of variables, compute an instmap delta
@@ -751,6 +892,75 @@
error("merge_instmapping_delta_2: unexpected mode error")
),
merge_instmapping_delta_2(Vars, InstMap, InstMappingA, InstMappingB,
+ InstMapping1, InstMapping, ModuleInfo1, ModuleInfo).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+ % Given two instmap deltas, unify them to produce a new instmap_delta.
+
+unify_instmap_delta(_, _, unreachable, InstMapDelta, InstMapDelta) --> [].
+unify_instmap_delta(_, _, reachable(InstMapping), unreachable,
+ reachable(InstMapping)) --> [].
+unify_instmap_delta(InstMap, NonLocals, reachable(InstMappingA),
+ reachable(InstMappingB), reachable(InstMapping)) -->
+ unify_instmapping_delta(InstMap, NonLocals, InstMappingA,
+ InstMappingB, InstMapping).
+
+:- pred unify_instmapping_delta(instmap, set(var), instmapping, instmapping,
+ instmapping, module_info, module_info).
+:- mode unify_instmapping_delta(in, in, in, in, out, in, out) is det.
+
+unify_instmapping_delta(InstMap, NonLocals, InstMappingA,
+ InstMappingB, InstMapping) -->
+ { map__keys(InstMappingA, VarsInA) },
+ { map__keys(InstMappingB, VarsInB) },
+ { set__sorted_list_to_set(VarsInA, SetofVarsInA) },
+ { set__insert_list(SetofVarsInA, VarsInB, SetofVars0) },
+ { set__intersect(SetofVars0, NonLocals, SetofVars) },
+ { map__init(InstMapping0) },
+ { set__to_sorted_list(SetofVars, ListofVars) },
+ unify_instmapping_delta_2(ListofVars, InstMap, InstMappingA,
+ InstMappingB, InstMapping0, InstMapping).
+
+:- pred unify_instmapping_delta_2(list(var), instmap, instmapping, instmapping,
+ instmapping, instmapping, module_info, module_info).
+:- mode unify_instmapping_delta_2(in, in, in, in, in, out, in, out) is det.
+
+unify_instmapping_delta_2([], _, _, _, InstMapping, InstMapping,
+ ModInfo, ModInfo).
+unify_instmapping_delta_2([Var | Vars], InstMap, InstMappingA, InstMappingB,
+ InstMapping0, InstMapping, ModuleInfo0, ModuleInfo) :-
+ ( map__search(InstMappingA, Var, InstA) ->
+ ( map__search(InstMappingB, Var, InstB) ->
+ (
+ % We unify the accumulated inst and the inst from the
+ % given instmap - we don't care about the determinism.
+ % Variable locking during mode analysis ensures that
+ % there is a unique producer for each variable - whether
+ % or not the unification may fail is up to determinism
+ % analysis.
+
+ abstractly_unify_inst(live, InstA, InstB,
+ fake_unify, ModuleInfo0, Inst, _Det,
+ ModuleInfoPrime)
+ ->
+ ModuleInfo1 = ModuleInfoPrime,
+ map__det_insert(InstMapping0, Var, Inst,
+ InstMapping1)
+ ;
+ error(
+ "unify_instmapping_delta_2: unexpected error")
+ )
+ ;
+ ModuleInfo1 = ModuleInfo0,
+ map__det_insert(InstMapping0, Var, InstA, InstMapping1)
+ )
+ ;
+ ModuleInfo1 = ModuleInfo0,
+ InstMapping1 = InstMapping0
+ ),
+ unify_instmapping_delta_2(Vars, InstMap, InstMappingA, InstMappingB,
InstMapping1, InstMapping, ModuleInfo1, ModuleInfo).
%-----------------------------------------------------------------------------%
Index: compiler/intermod.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/intermod.m,v
retrieving revision 1.34
diff -u -r1.34 intermod.m
--- intermod.m 1997/10/26 23:05:36 1.34
+++ intermod.m 1997/10/26 23:31:56
@@ -346,6 +346,10 @@
intermod__traverse_goal(conj(Goals0) - Info, conj(Goals) - Info, DoWrite) -->
intermod__traverse_list_of_goals(Goals0, Goals, DoWrite).
+intermod__traverse_goal(par_conj(Goals0, SM) - Info, par_conj(Goals, SM) - Info,
+ DoWrite) -->
+ intermod__traverse_list_of_goals(Goals0, Goals, DoWrite).
+
intermod__traverse_goal(disj(Goals0, SM) - Info, disj(Goals, SM) - Info,
DoWrite) -->
intermod__traverse_list_of_goals(Goals0, Goals, DoWrite).
Index: compiler/lambda.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/lambda.m,v
retrieving revision 1.32
diff -u -r1.32 lambda.m
--- lambda.m 1997/09/01 14:02:47 1.32
+++ lambda.m 1997/09/08 22:43:25
@@ -171,6 +171,9 @@
lambda__process_goal_2(conj(Goals0), GoalInfo, conj(Goals) - GoalInfo) -->
lambda__process_goal_list(Goals0, Goals).
+lambda__process_goal_2(par_conj(Goals0, SM), GoalInfo,
+ par_conj(Goals, SM) - GoalInfo) -->
+ lambda__process_goal_list(Goals0, Goals).
lambda__process_goal_2(disj(Goals0, SM), GoalInfo, disj(Goals, SM) - GoalInfo)
-->
lambda__process_goal_list(Goals0, Goals).
Index: compiler/lco.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/lco.m,v
retrieving revision 1.7
diff -u -r1.7 lco.m
--- lco.m 1997/09/01 14:02:49 1.7
+++ lco.m 1997/09/08 22:43:25
@@ -28,7 +28,7 @@
:- implementation.
:- import_module hlds_goal, passes_aux, hlds_out.
-:- import_module list, std_util.
+:- import_module list, require, std_util.
%-----------------------------------------------------------------------------%
@@ -62,6 +62,10 @@
lco_in_goal_2(conj(Goals0), ModuleInfo, conj(Goals)) :-
list__reverse(Goals0, RevGoals0),
lco_in_conj(RevGoals0, [], ModuleInfo, Goals).
+
+ % XXX Some execution algorithm issues here.
+lco_in_goal_2(par_conj(_Goals0, SM), _ModuleInfo, par_conj(_Goals, SM)) :-
+ error("sorry: lco of parallel conjunction not implemented").
lco_in_goal_2(disj(Goals0, SM), ModuleInfo, disj(Goals, SM)) :-
lco_in_disj(Goals0, ModuleInfo, Goals).
Index: compiler/live_vars.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/live_vars.m,v
retrieving revision 1.67
diff -u -r1.67 live_vars.m
--- live_vars.m 1997/09/01 14:02:55 1.67
+++ live_vars.m 1997/10/21 04:56:24
@@ -135,7 +135,7 @@
(
/*******
% goal_is_atomic(Goal0)
- fail
+ semidet_fail
% NB: `fail' is a conservative approximation
% We could do better, but `goal_is_atomic' is not
% quite right
@@ -170,6 +170,25 @@
build_live_sets_in_conj(Goals0, Liveness0, ResumeVars0, LiveSets0,
ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets).
+build_live_sets_in_goal_2(par_conj(Goals0, _SM), Liveness0, ResumeVars0,
+ LiveSets0, GoalInfo, ModuleInfo, ProcInfo, Liveness,
+ ResumeVars, LiveSets) :-
+ goal_info_get_nonlocals(GoalInfo, NonLocals),
+ set__union(NonLocals, Liveness0, LiveSet),
+ % We insert all the union of the live vars and the nonlocals.
+ % Since each parallel conjunct may be run on a different
+ % Mercury engine to the current engine, we must save all
+ % the variables that are live or nonlocal to the parallel
+ % conjunction. Nonlocal variables that are currently free, but
+ % are bound inside one of the conjuncts need a stackslot
+ % because they are passed out by reference to that stackslot.
+ set__insert(LiveSets0, LiveSet, LiveSets1),
+ % build_live_sets_in_disj treats its list of goals as a list
+ % of independent goals, so we can use it for parallel conj's
+ % too.
+ build_live_sets_in_disj(Goals0, Liveness0, ResumeVars0, LiveSets1,
+ GoalInfo, ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets).
+
build_live_sets_in_goal_2(disj(Goals0, _), Liveness0, ResumeVars0, LiveSets0,
GoalInfo, ModuleInfo, ProcInfo, Liveness, ResumeVars, LiveSets)
:-
@@ -386,6 +405,9 @@
).
%-----------------------------------------------------------------------------%
+
+ % build_live_sets_in_disj is used for both disjunctions and
+ % parallel conjunctions.
:- pred build_live_sets_in_disj(list(hlds_goal), set(var), set(var),
set(set(var)), hlds_goal_info, module_info, proc_info,
Index: compiler/livemap.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/livemap.m,v
retrieving revision 1.27
diff -u -r1.27 livemap.m
--- livemap.m 1997/08/25 17:48:18 1.27
+++ livemap.m 1997/09/09 02:19:23
@@ -60,9 +60,9 @@
livemap__build_2(Backinstrs, Livemap0, MaybeLivemap) :-
set__init(Livevals0),
- livemap__build_livemap(Backinstrs, Livevals0, no, Ccode1,
+ livemap__build_livemap(Backinstrs, Livevals0, no, DontValueNumber1,
Livemap0, Livemap1),
- ( Ccode1 = yes ->
+ ( DontValueNumber1 = yes ->
MaybeLivemap = no
; livemap__equal_livemaps(Livemap0, Livemap1) ->
MaybeLivemap = yes(Livemap1)
@@ -105,13 +105,15 @@
livemap, livemap).
:- mode livemap__build_livemap(in, in, in, out, in, out) is det.
-livemap__build_livemap([], _, Ccode, Ccode, Livemap, Livemap).
-livemap__build_livemap([Instr0 | Instrs0], Livevals0, Ccode0, Ccode,
- Livemap0, Livemap) :-
+livemap__build_livemap([], _, DontValueNumber, DontValueNumber,
+ Livemap, Livemap).
+livemap__build_livemap([Instr0 | Instrs0], Livevals0,
+ DontValueNumber0, DontValueNumber, Livemap0, Livemap) :-
livemap__build_livemap_instr(Instr0, Instrs0, Instrs1,
- Livevals0, Livevals1, Ccode0, Ccode1, Livemap0, Livemap1),
+ Livevals0, Livevals1, DontValueNumber0, DontValueNumber1,
+ Livemap0, Livemap1),
livemap__build_livemap(Instrs1, Livevals1,
- Ccode1, Ccode, Livemap1, Livemap).
+ DontValueNumber1, DontValueNumber, Livemap1, Livemap).
:- pred livemap__build_livemap_instr(instruction, list(instruction),
list(instruction), lvalset, lvalset, bool, bool, livemap, livemap).
@@ -119,14 +121,15 @@
is det.
livemap__build_livemap_instr(Instr0, Instrs0, Instrs,
- Livevals0, Livevals, Ccode0, Ccode, Livemap0, Livemap) :-
+ Livevals0, Livevals, DontValueNumber0, DontValueNumber,
+ Livemap0, Livemap) :-
Instr0 = Uinstr0 - _,
(
Uinstr0 = comment(_),
Livemap = Livemap0,
Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = livevals(_),
error("livevals found in backward scan in build_livemap")
@@ -148,31 +151,31 @@
livemap__make_live_in_rvals([Rval | Rvals], Livevals1, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = call(_, _, _, _),
livemap__look_for_livevals(Instrs0, Instrs,
Livevals0, Livevals, "call", yes, _),
Livemap = Livemap0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = mkframe(_, _, _),
Livemap = Livemap0,
Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = modframe(_),
Livemap = Livemap0,
Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = label(Label),
map__set(Livemap0, Label, Livevals0, Livemap),
Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = goto(CodeAddr),
opt_util__livevals_addr(CodeAddr, LivevalsNeeded),
@@ -201,7 +204,7 @@
Livevals = Livevals3
),
Livemap = Livemap0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = computed_goto(Rval, Labels),
set__init(Livevals1),
@@ -210,13 +213,13 @@
Livevals2, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = c_code(_),
Livemap = Livemap0,
Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = yes
+ DontValueNumber = yes
;
Uinstr0 = if_val(Rval, CodeAddr),
livemap__look_for_livevals(Instrs0, Instrs,
@@ -242,7 +245,7 @@
Livevals = Livevals3
),
Livemap = Livemap0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = incr_hp(Lval, _Tag, Rval),
@@ -258,7 +261,7 @@
livemap__make_live_in_rvals([Rval | Rvals], Livevals1, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = mark_hp(Lval),
set__delete(Livevals0, Lval, Livevals1),
@@ -266,13 +269,13 @@
livemap__make_live_in_rvals(Rvals, Livevals1, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = restore_hp(Rval),
livemap__make_live_in_rvals([Rval], Livevals0, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = store_ticket(Lval),
set__delete(Livevals0, Lval, Livevals1),
@@ -280,19 +283,19 @@
livemap__make_live_in_rvals(Rvals, Livevals1, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = reset_ticket(Rval, _Reason),
livemap__make_live_in_rval(Rval, Livevals0, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = discard_ticket,
Livevals = Livevals0,
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = mark_ticket_stack(Lval),
set__delete(Livevals0, Lval, Livevals1),
@@ -300,32 +303,56 @@
livemap__make_live_in_rvals(Rvals, Livevals1, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = discard_tickets_to(Rval),
livemap__make_live_in_rval(Rval, Livevals0, Livevals),
Livemap = Livemap0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = incr_sp(_, _),
- Livevals = Livevals0,
Livemap = Livemap0,
+ Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = DontValueNumber0
;
Uinstr0 = decr_sp(_),
+ Livemap = Livemap0,
Livevals = Livevals0,
+ Instrs = Instrs0,
+ DontValueNumber = DontValueNumber0
+ ;
+ % XXX Value numbering doesn't handle fork [yet] so
+ % set DontValueNumber to yes.
+ Uinstr0 = fork(_, _, _),
Livemap = Livemap0,
+ Livevals = Livevals0,
+ Instrs = Instrs0,
+ DontValueNumber = yes
+ ;
+ % XXX Value numbering doesn't handle join_and_terminate [yet] so
+ % set DontValueNumber to yes.
+ Uinstr0 = join_and_terminate(_),
+ Livemap = Livemap0,
+ Livevals = Livevals0,
+ Instrs = Instrs0,
+ DontValueNumber = yes
+ ;
+ % XXX Value numbering doesn't handle join_and_continue [yet] so
+ % set DontValueNumber to yes.
+ Uinstr0 = join_and_continue(_, _),
+ Livemap = Livemap0,
+ Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = Ccode0
+ DontValueNumber = yes
;
% XXX we shouldn't just give up here
Uinstr0 = pragma_c(_, _, _, _, _),
Livemap = Livemap0,
Livevals = Livevals0,
Instrs = Instrs0,
- Ccode = yes
+ DontValueNumber = yes
).
:- pred livemap__look_for_livevals(list(instruction), list(instruction),
Index: compiler/liveness.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/liveness.m,v
retrieving revision 1.84
diff -u -r1.84 liveness.m
--- liveness.m 1997/10/20 07:35:22 1.84
+++ liveness.m 1997/10/20 22:35:23
@@ -233,6 +233,13 @@
Liveness, conj(Goals)) :-
detect_liveness_in_conj(Goals0, Liveness0, LiveInfo, Liveness, Goals).
+detect_liveness_in_goal_2(par_conj(Goals0, SM), Liveness0, NonLocals, LiveInfo,
+ Liveness, par_conj(Goals, SM)) :-
+ set__init(Union0),
+ detect_liveness_in_par_conj(Goals0, Liveness0, NonLocals, LiveInfo,
+ Union0, Union, Goals),
+ set__union(Liveness0, Union, Liveness).
+
detect_liveness_in_goal_2(disj(Goals0, SM), Liveness0, NonLocals, LiveInfo,
Liveness, disj(Goals, SM)) :-
set__init(Union0),
@@ -357,6 +364,21 @@
add_liveness_after_goal(Goal1, Residue, Goal).
%-----------------------------------------------------------------------------%
+
+:- pred detect_liveness_in_par_conj(list(hlds_goal), set(var), set(var),
+ live_info, set(var), set(var), list(hlds_goal)).
+:- mode detect_liveness_in_par_conj(in, in, in, in, in, out, out) is det.
+
+detect_liveness_in_par_conj([], _Liveness, _NonLocals, _LiveInfo,
+ Union, Union, []).
+detect_liveness_in_par_conj([Goal0 | Goals0], Liveness, NonLocals, LiveInfo,
+ Union0, Union, [Goal | Goals]) :-
+ detect_liveness_in_goal(Goal0, Liveness, LiveInfo, Liveness1, Goal),
+ set__union(Union0, Liveness1, Union1),
+ detect_liveness_in_par_conj(Goals0, Liveness, NonLocals, LiveInfo,
+ Union1, Union, Goals).
+
+%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- pred detect_deadness_in_goal(hlds_goal, set(var), live_info,
@@ -420,6 +442,14 @@
detect_deadness_in_conj(Goals0, Deadness0, LiveInfo,
Goals, Deadness).
+detect_deadness_in_goal_2(par_conj(Goals0, SM), GoalInfo, Deadness0, LiveInfo,
+ Deadness, par_conj(Goals, SM)) :-
+ set__init(Union0),
+ goal_info_get_nonlocals(GoalInfo, NonLocals),
+ detect_deadness_in_par_conj(Goals0, Deadness0, NonLocals,
+ LiveInfo, Union0, Union, Goals),
+ set__union(Union, Deadness0, Deadness).
+
detect_deadness_in_goal_2(disj(Goals0, SM), GoalInfo, Deadness0,
LiveInfo, Deadness, disj(Goals, SM)) :-
set__init(Union0),
@@ -539,6 +569,24 @@
add_deadness_before_goal(Goal1, Residue, Goal).
%-----------------------------------------------------------------------------%
+
+:- pred detect_deadness_in_par_conj(list(hlds_goal), set(var), set(var),
+ live_info, set(var), set(var), list(hlds_goal)).
+:- mode detect_deadness_in_par_conj(in, in, in, in, in, out, out) is det.
+
+detect_deadness_in_par_conj([], _Deadness, _NonLocals, _LiveInfo,
+ Union, Union, []).
+detect_deadness_in_par_conj([Goal0 | Goals0], Deadness, NonLocals, LiveInfo,
+ Union0, Union, [Goal | Goals]) :-
+ detect_deadness_in_goal(Goal0, Deadness, LiveInfo, Deadness1, Goal1),
+ set__union(Union0, Deadness1, Union1),
+ detect_deadness_in_par_conj(Goals0, Deadness, NonLocals, LiveInfo,
+ Union1, Union, Goals),
+ set__intersect(Union, NonLocals, NonLocalUnion),
+ set__difference(NonLocalUnion, Deadness1, Residue),
+ add_deadness_before_goal(Goal1, Residue, Goal).
+
+%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- pred detect_resume_points_in_goal(hlds_goal, set(var), live_info, set(var),
@@ -570,6 +618,11 @@
detect_resume_points_in_conj(Goals0, Liveness0, LiveInfo, ResumeVars0,
Goals, Liveness).
+detect_resume_points_in_goal_2(par_conj(Goals0, SM), _, Liveness0, LiveInfo,
+ ResumeVars0, par_conj(Goals, SM), Liveness) :-
+ detect_resume_points_in_par_conj(Goals0, Liveness0, LiveInfo,
+ ResumeVars0, Goals, Liveness).
+
detect_resume_points_in_goal_2(disj(Goals0, SM), GoalInfo, Liveness0, LiveInfo,
ResumeVars0, disj(Goals, SM), Liveness) :-
goal_info_get_code_model(GoalInfo, CodeModel),
@@ -820,6 +873,18 @@
;
Cases = Cases0
).
+
+:- pred detect_resume_points_in_par_conj(list(hlds_goal), set(var), live_info,
+ set(var), list(hlds_goal), set(var)).
+:- mode detect_resume_points_in_par_conj(in, in, in, in, out, out) is det.
+
+detect_resume_points_in_par_conj([], Liveness, _, _, [], Liveness).
+detect_resume_points_in_par_conj([Goal0 | Goals0], Liveness0, LiveInfo,
+ ResumeVars0, [Goal | Goals], LivenessFirst) :-
+ detect_resume_points_in_goal(Goal0, Liveness0, LiveInfo, ResumeVars0,
+ Goal, LivenessFirst),
+ detect_resume_points_in_par_conj(Goals0, Liveness0, LiveInfo,
+ ResumeVars0, Goals, _LivenessRest).
:- pred require_equal(set(var), set(var), string, live_info).
:- mode require_equal(in, in, in, in) is det.
Index: compiler/llds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds.m,v
retrieving revision 1.211
diff -u -r1.211 llds.m
--- llds.m 1997/10/12 13:32:31 1.211
+++ llds.m 1997/10/21 04:57:34
@@ -221,7 +221,7 @@
% Decrement the det stack pointer.
; pragma_c(list(pragma_c_decl), list(pragma_c_input),
- string, list(pragma_c_output), term__context).
+ string, list(pragma_c_output), term__context)
% The local variable declarations, the info required
% for placing the inputs in the variables, the c code,
% the info required for picking up the outputs, and
@@ -234,6 +234,30 @@
% % in LABEL_1 and DEFINE_LABEL_1 style macros.
% % For use in model_non pragma_c_codes, where it
% % should be preceded by a mkframe.
+
+ ; fork(label, label, int)
+ % Create a new context.
+ % fork(Child, Parent, NumSlots) creates a new thread
+ % which will start executing at Child, then execution
+ % in the current context branches to Parent.
+ % NumSlots is the number of stack slots that need to
+ % be copied to the child's stack (see comments in
+ % runtime/context.{h,mod}).
+
+ ; join_and_terminate(lval)
+ % Signal that this thread of execution has finished in
+ % the current parallel conjunction, then terminate it.
+ % The synchronisation term specified by the
+ % given lval. (See the documentation in par_conj_gen.m
+ % and runtime/context.mod for further information about
+ % synchronisation terms.)
+
+ ; join_and_continue(lval, label)
+ % Signal that this thread of execution has finished
+ % in the current parallel conjunction, then branch to
+ % the given label. The synchronisation
+ % term specified by the given lval.
+ .
% pragma_c_decl holds the information needed for a variable
% declaration for a pragma_c instruction.
Index: compiler/llds_common.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds_common.m,v
retrieving revision 1.10
diff -u -r1.10 llds_common.m
--- llds_common.m 1997/08/25 17:48:23 1.10
+++ llds_common.m 1997/09/08 23:17:54
@@ -253,6 +253,18 @@
Instr0 = pragma_c(_, _, _, _, _),
Instr = Instr0,
Info = Info0
+ ;
+ Instr0 = fork(_, _, _),
+ Instr = Instr0,
+ Info = Info0
+ ;
+ Instr0 = join_and_terminate(_),
+ Instr = Instr0,
+ Info = Info0
+ ;
+ Instr0 = join_and_continue(_, _),
+ Instr = Instr0,
+ Info = Info0
).
:- pred llds_common__process_rval(rval, common_info, common_info, rval).
Index: compiler/llds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds_out.m,v
retrieving revision 1.59
diff -u -r1.59 llds_out.m
--- llds_out.m 1997/10/12 13:32:34 1.59
+++ llds_out.m 1997/10/21 04:59:00
@@ -650,8 +650,8 @@
llds_out__find_caller_label(Instrs, CallerLabel)
).
- % Locate all the labels which are the continutation labels for calls
- % or nondet disjunctions, and store them in ContLabelSet.
+ % Locate all the labels which are the continuation labels for calls,
+ % nondet disjunctions, forks or joins, and store them in ContLabelSet.
:- pred llds_out__find_cont_labels(list(instruction), set(label), set(label)).
:- mode llds_out__find_cont_labels(in, in, out) is det.
@@ -667,12 +667,18 @@
;
Instr = modframe(label(ContLabel))
;
+ Instr = join_and_continue(_, ContLabel)
+ ;
Instr = assign(redoip(lval(maxfr)),
const(code_addr_const(label(ContLabel))))
)
->
set__insert(ContLabelSet0, ContLabel, ContLabelSet1)
;
+ Instr = fork(Label1, Label2, _)
+ ->
+ set__insert_list(ContLabelSet0, [Label1, Label2], ContLabelSet1)
+ ;
Instr = block(_, _, Block)
->
llds_out__find_cont_labels(Block, ContLabelSet0, ContLabelSet1)
@@ -800,6 +806,14 @@
DeclSet0, DeclSet) -->
output_pragma_input_rval_decls(Inputs, DeclSet0, DeclSet1),
output_pragma_output_lval_decls(Outputs, DeclSet1, DeclSet).
+output_instruction_decls(fork(Child, Parent, _), DeclSet0, DeclSet) -->
+ output_code_addr_decls(label(Child), "", "", 0, _, DeclSet0, DeclSet2),
+ output_code_addr_decls(label(Parent), "", "", 0, _, DeclSet2, DeclSet).
+output_instruction_decls(join_and_terminate(Lval), DeclSet0, DeclSet) -->
+ output_lval_decls(Lval, "", "", 0, _, DeclSet0, DeclSet).
+output_instruction_decls(join_and_continue(Lval, Label), DeclSet0, DeclSet) -->
+ output_lval_decls(Lval, "", "", 0, _, DeclSet0, DeclSet1),
+ output_code_addr_decls(label(Label), "", "", 0, _, DeclSet1, DeclSet).
%-----------------------------------------------------------------------------%
@@ -1063,6 +1077,27 @@
output_reset_line_num,
output_pragma_outputs(Outputs),
io__write_string("\n\t}\n").
+
+output_instruction(fork(Child, Parent, Lval), _) -->
+ io__write_string("\tfork_new_context("),
+ output_label_as_code_addr(Child),
+ io__write_string(", "),
+ output_label_as_code_addr(Parent),
+ io__write_string(", "),
+ io__write_int(Lval),
+ io__write_string(");\n").
+
+output_instruction(join_and_terminate(Lval), _) -->
+ io__write_string("\tjoin_and_terminate("),
+ output_lval(Lval),
+ io__write_string(");\n").
+
+output_instruction(join_and_continue(Lval, Label), _) -->
+ io__write_string("\tjoin_and_continue("),
+ output_lval(Lval),
+ io__write_string(", "),
+ output_label_as_code_addr(Label),
+ io__write_string(");\n").
:- pred output_set_line_num(term__context, io__state, io__state).
:- mode output_set_line_num(in, di, uo) is det.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.242
diff -u -r1.242 make_hlds.m
--- make_hlds.m 1997/10/09 09:38:48 1.242
+++ make_hlds.m 1997/10/17 04:20:26
@@ -2035,6 +2035,10 @@
PredCallId) -->
warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId).
+warn_singletons_in_goal_2(par_conj(Goals, _SM), _GoalInfo, QuantVars, VarSet,
+ PredCallId) -->
+ warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId).
+
warn_singletons_in_goal_2(disj(Goals, _), _GoalInfo, QuantVars, VarSet,
PredCallId) -->
warn_singletons_in_goal_list(Goals, QuantVars, VarSet, PredCallId).
@@ -2580,6 +2584,12 @@
{ goal_info_init(GoalInfo) },
{ conj_list_to_goal(L, GoalInfo, Goal) }.
+transform_goal_2((A0 & B0), _, VarSet0, Subst, Goal, VarSet, Info0, Info) -->
+ get_par_conj(B0, Subst, [], VarSet0, L0, VarSet1, Info0, Info1),
+ get_par_conj(A0, Subst, L0, VarSet1, L, VarSet, Info1, Info),
+ { goal_info_init(GoalInfo) },
+ { par_conj_list_to_goal(L, GoalInfo, Goal) }.
+
transform_goal_2((A0;B0), _, VarSet0, Subst, Goal, VarSet, Info0, Info) -->
get_disj(B0, Subst, [], VarSet0, L0, VarSet1, Info0, Info1),
get_disj(A0, Subst, L0, VarSet1, L, VarSet, Info1, Info),
@@ -3200,6 +3210,29 @@
Info0, Info),
{ goal_to_conj_list(Goal1, ConjList) },
{ list__append(ConjList, Conj0, Conj) }
+ ).
+
+% get_par_conj(Goal, ParConj0, Subst, ParConj) :
+% Goal is a tree of conjuncts. Flatten it into a list (applying Subst),
+% append ParConj0, and return the result in ParConj.
+
+:- pred get_par_conj(goal, substitution, list(hlds_goal), varset,
+ list(hlds_goal), varset, qual_info, qual_info, io__state, io__state).
+:- mode get_par_conj(in, in, in, in, out, out, in, out, di, uo) is det.
+
+get_par_conj(Goal, Subst, ParConj0, VarSet0, ParConj, VarSet, Info0, Info) -->
+ (
+ { Goal = (A & B) - _Context }
+ ->
+ get_par_conj(B, Subst, ParConj0, VarSet0, ParConj1, VarSet1,
+ Info0, Info1),
+ get_par_conj(A, Subst, ParConj1, VarSet1, ParConj, VarSet,
+ Info1, Info)
+ ;
+ transform_goal(Goal, VarSet0, Subst, Goal1, VarSet,
+ Info0, Info),
+ { goal_to_par_conj_list(Goal1, ParConjList) },
+ { list__append(ParConjList, ParConj0, ParConj) }
).
% get_disj(Goal, Subst, Disj0, Disj) :
Index: compiler/mercury_to_c.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_to_c.m,v
retrieving revision 1.27
diff -u -r1.27 mercury_to_c.m
--- mercury_to_c.m 1997/09/01 14:03:37 1.27
+++ mercury_to_c.m 1997/09/08 22:43:25
@@ -603,6 +603,9 @@
c_gen_goal_2(conj(Goals), Indent, CGenInfo0, CGenInfo) -->
c_gen_conj(Goals, Indent, CGenInfo0, CGenInfo).
+c_gen_goal_2(par_conj(_Goals, _SM), _Indent, _CGenInfo0, _CGenInfo) -->
+ { error("sorry, c_gen of parallel conjunction not implemented") }.
+
c_gen_goal_2(disj(List, _), Indent, CGenInfo0, CGenInfo) -->
{ c_gen_info_get_code_model(CGenInfo0, CodeModel) },
( { CodeModel = model_non } ->
Index: compiler/mercury_to_goedel.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_to_goedel.m,v
retrieving revision 1.60
diff -u -r1.60 mercury_to_goedel.m
--- mercury_to_goedel.m 1997/08/22 13:55:25 1.60
+++ mercury_to_goedel.m 1997/09/08 22:43:25
@@ -596,6 +596,14 @@
goedel_output_newline(Indent),
goedel_output_goal(B, VarSet, Indent).
+ % Goedel doesn't have parallel conjunction,
+ % but we can use sequential conjunction instead.
+goedel_output_goal_2((A & B), VarSet, Indent) -->
+ goedel_output_goal(A, VarSet, Indent),
+ io__write_string(" &"),
+ goedel_output_newline(Indent),
+ goedel_output_goal(B, VarSet, Indent).
+
goedel_output_goal_2((A;B), VarSet, Indent) -->
io__write_string("("),
{ Indent1 is Indent + 1 },
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.119
diff -u -r1.119 mercury_to_mercury.m
--- mercury_to_mercury.m 1997/10/09 09:38:54 1.119
+++ mercury_to_mercury.m 1997/10/17 04:20:28
@@ -1434,6 +1434,16 @@
mercury_output_newline(Indent),
mercury_output_goal(B, VarSet, Indent).
+mercury_output_goal_2((A & B), VarSet, Indent) -->
+ io__write_string("("),
+ { Indent1 is Indent + 1 },
+ mercury_output_newline(Indent1),
+ mercury_output_goal(A, VarSet, Indent1),
+ mercury_output_par_conj(B, VarSet, Indent),
+ mercury_output_newline(Indent),
+ io__write_string(")").
+
+
mercury_output_goal_2((A;B), VarSet, Indent) -->
io__write_string("("),
{ Indent1 is Indent + 1 },
@@ -1480,6 +1490,23 @@
->
mercury_output_goal(A, VarSet, Indent1),
mercury_output_disj(B, VarSet, Indent)
+ ;
+ mercury_output_goal(Goal, VarSet, Indent1)
+ ).
+
+:- pred mercury_output_par_conj(goal, varset, int, io__state, io__state).
+:- mode mercury_output_par_conj(in, in, in, di, uo) is det.
+
+mercury_output_par_conj(Goal, VarSet, Indent) -->
+ mercury_output_newline(Indent),
+ io__write_string("&"),
+ { Indent1 is Indent + 1 },
+ mercury_output_newline(Indent1),
+ (
+ { Goal = (A & B) - _Context }
+ ->
+ mercury_output_goal(A, VarSet, Indent1),
+ mercury_output_par_conj(B, VarSet, Indent)
;
mercury_output_goal(Goal, VarSet, Indent1)
).
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/middle_rec.m,v
retrieving revision 1.66
diff -u -r1.66 middle_rec.m
--- middle_rec.m 1997/08/25 17:48:28 1.66
+++ middle_rec.m 1997/09/08 22:43:25
@@ -418,6 +418,11 @@
Used0, Used) :-
insert_pragma_c_input_registers(Ins, Used0, Used1),
insert_pragma_c_output_registers(Outs, Used1, Used).
+middle_rec__find_used_registers_instr(fork(_, _, _), Used, Used).
+middle_rec__find_used_registers_instr(join_and_terminate(Lval), Used0, Used) :-
+ middle_rec__find_used_registers_lval(Lval, Used0, Used).
+middle_rec__find_used_registers_instr(join_and_continue(Lval,_), Used0, Used) :-
+ middle_rec__find_used_registers_lval(Lval, Used0, Used).
:- pred middle_rec__find_used_registers_lvals(list(lval), set(int), set(int)).
:- mode middle_rec__find_used_registers_lvals(in, di, uo) is det.
Index: compiler/mode_errors.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mode_errors.m,v
retrieving revision 1.47
diff -u -r1.47 mode_errors.m
--- mode_errors.m 1997/07/27 15:01:04 1.47
+++ mode_errors.m 1997/10/23 00:59:55
@@ -39,6 +39,9 @@
---> mode_error_disj(merge_context, merge_errors)
% different arms of a disjunction result in
% different insts for some non-local variables
+ ; mode_error_par_conj(merge_errors)
+ % different arms of a parallel conj result in
+ % mutually exclusive bindings
; mode_error_higher_order_pred_var(pred_or_func, var, inst, arity)
% the predicate variable in a higher-order predicate
% or function call didn't have a higher-order
@@ -65,9 +68,10 @@
; mode_error_no_matching_mode(list(var), list(inst))
% call to a predicate with an insufficiently
% instantiated variable (for preds with >1 mode)
- ; mode_error_bind_var(var, inst, inst)
+ ; mode_error_bind_var(var, inst, inst, lock_context)
% attempt to bind a non-local variable inside
- % a negated context
+ % a negated context, or attempt to re-bind a variable
+ % in a parallel conjunct
; mode_error_unify_var_var(var, var, inst, inst)
% attempt to unify two free variables
; mode_error_unify_var_functor(var, cons_id, list(var),
@@ -83,9 +87,13 @@
; mode_error_final_inst(int, var, inst, inst, final_inst_error)
% one of the head variables did not have the
% expected final inst on exit from the proc
- ; mode_error_undefined_mode_in_lambda.
+ ; mode_error_undefined_mode_in_lambda
% This is a dummy error - the actual message
% is output by module_qual.m.
+ ; mode_error_parallel_var(var, inst, inst)
+ % attempt to bind a non-local variable that has already
+ % been bound in another parallel conjunct.
+ .
:- type final_inst_error
---> too_instantiated
@@ -156,6 +164,8 @@
report_mode_error(mode_error_disj(MergeContext, ErrorList), ModeInfo) -->
report_mode_error_disj(ModeInfo, MergeContext, ErrorList).
+report_mode_error(mode_error_par_conj(ErrorList), ModeInfo) -->
+ report_mode_error_par_conj(ModeInfo, ErrorList).
report_mode_error(mode_error_higher_order_pred_var(PredOrFunc, Var, Inst,
Arity), ModeInfo) -->
report_mode_error_higher_order_pred_var(ModeInfo, PredOrFunc, Var,
@@ -171,8 +181,8 @@
report_mode_error_implied_mode(ModeInfo, Var, InstA, InstB).
report_mode_error(mode_error_no_mode_decl, ModeInfo) -->
report_mode_error_no_mode_decl(ModeInfo).
-report_mode_error(mode_error_bind_var(Var, InstA, InstB), ModeInfo) -->
- report_mode_error_bind_var(ModeInfo, Var, InstA, InstB).
+report_mode_error(mode_error_bind_var(Var, InstA, InstB, Ctxt), ModeInfo) -->
+ report_mode_error_bind_var(ModeInfo, Var, InstA, InstB, Ctxt).
report_mode_error(mode_error_unify_var_var(VarA, VarB, InstA, InstB),
ModeInfo) -->
report_mode_error_unify_var_var(ModeInfo, VarA, VarB, InstA, InstB).
@@ -192,6 +202,8 @@
report_mode_error_final_inst(ModeInfo, ArgNum, Var, VarInst, Inst,
Reason).
report_mode_error(mode_error_undefined_mode_in_lambda, _ModeInfo) --> [].
+report_mode_error(mode_error_parallel_var(Var, InstA, InstB), ModeInfo) -->
+ report_mode_error_parallel_var(ModeInfo, Var, InstA, InstB).
%-----------------------------------------------------------------------------%
@@ -299,6 +311,17 @@
io__write_string(".\n"),
write_merge_error_list(ErrorList, ModeInfo).
+:- pred report_mode_error_par_conj(mode_info, merge_errors,
+ io__state, io__state).
+:- mode report_mode_error_par_conj(mode_info_no_io, in, di, uo) is det.
+
+report_mode_error_par_conj(ModeInfo, ErrorList) -->
+ { mode_info_get_context(ModeInfo, Context) },
+ mode_info_write_context(ModeInfo),
+ prog_out__write_context(Context),
+ io__write_string(" mode error: mutually exclusive bindings in parallel conjunction.\n"),
+ write_merge_error_list(ErrorList, ModeInfo).
+
:- pred write_merge_error_list(merge_errors, mode_info, io__state, io__state).
:- mode write_merge_error_list(in, mode_info_no_io, di, uo) is det.
@@ -326,17 +349,42 @@
%-----------------------------------------------------------------------------%
:- pred report_mode_error_bind_var(mode_info, var, inst, inst,
- io__state, io__state).
-:- mode report_mode_error_bind_var(mode_info_ui, in, in, in, di, uo) is det.
+ lock_context, io__state, io__state).
+:- mode report_mode_error_bind_var(mode_info_ui, in, in, in, in, di, uo) is det.
-report_mode_error_bind_var(ModeInfo, Var, VarInst, Inst) -->
+report_mode_error_bind_var(ModeInfo, Var, VarInst, Inst, LockContext) -->
{ mode_info_get_context(ModeInfo, Context) },
{ mode_info_get_varset(ModeInfo, VarSet) },
{ mode_info_get_instvarset(ModeInfo, InstVarSet) },
mode_info_write_context(ModeInfo),
- prog_out__write_context(Context),
- io__write_string(
- " scope error: attempt to bind variable inside a negation.\n"),
+ (
+ { LockContext = negation },
+ prog_out__write_context(Context),
+ io__write_string(
+ " scope error: attempt to bind variable inside a negation.\n")
+ ;
+ { LockContext = if_then_else },
+ prog_out__write_context(Context),
+ io__write_string(
+ " scope error: attempt to bind nonlocal variable inside \n"),
+ prog_out__write_context(Context),
+ io__write_string(
+ " the condition of an if-then-else.\n")
+ ;
+ { LockContext = par_conj },
+ prog_out__write_context(Context),
+ io__write_string(
+ " mode error: attempt to bind variable inside more than one\n"),
+ prog_out__write_context(Context),
+ io__write_string(" parallel conjunct.\n")
+ ;
+ { LockContext = lambda_goal },
+ prog_out__write_context(Context),
+ io__write_string(
+ " scope error: attempt to bind a nonlocal variable inside\n"),
+ prog_out__write_context(Context),
+ io__write_string(" a pred/lambda goal.\n")
+ ),
prog_out__write_context(Context),
io__write_string(" Variable `"),
mercury_output_var(Var, VarSet, no),
@@ -348,7 +396,9 @@
output_inst(Inst, InstVarSet),
io__write_string("'.\n"),
globals__io_lookup_bool_option(verbose_errors, VerboseErrors),
- ( { VerboseErrors = yes } ->
+ (
+ { VerboseErrors = yes }
+ ->
io__write_string("\tA negation is only allowed to bind variables which are local to the\n"),
io__write_string("\tnegation, i.e. those which are implicitly existentially quantified\n"),
io__write_string("\tinside the scope of the negation.\n"),
@@ -718,6 +768,24 @@
%-----------------------------------------------------------------------------%
+
+:- pred report_mode_error_parallel_var(mode_info, var, inst, inst,
+ io__state, io__state).
+:- mode report_mode_error_parallel_var(mode_info_ui, in, in, in, di, uo) is det.
+
+report_mode_error_parallel_var(ModeInfo, Var, _VarInst, _Inst) -->
+ { mode_info_get_context(ModeInfo, Context) },
+ { mode_info_get_varset(ModeInfo, VarSet) },
+ mode_info_write_context(ModeInfo),
+ prog_out__write_context(Context),
+ io__write_string(" mode error: attempt to bind a variable already bound\n"),
+ prog_out__write_context(Context),
+ io__write_string(" in anonther parallel conjunct.\n"),
+ prog_out__write_context(Context),
+ io__write_string(" The variable concerned was `"),
+ mercury_output_var(Var, VarSet, no),
+ io__write_string("'.\n").
+
%-----------------------------------------------------------------------------%
mode_context_init(uninitialized).
Index: compiler/mode_info.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mode_info.m,v
retrieving revision 1.40
diff -u -r1.40 mode_info.m
--- mode_info.m 1997/10/14 09:18:44 1.40
+++ mode_info.m 1997/10/23 00:13:00
@@ -119,10 +119,12 @@
:- pred mode_info_set_instmap(instmap, mode_info, mode_info).
:- mode mode_info_set_instmap(in, mode_info_di, mode_info_uo) is det.
-:- pred mode_info_get_locked_vars(mode_info, list(set(var))).
+:- type locked_vars == pair(set(var), lock_context).
+
+:- pred mode_info_get_locked_vars(mode_info, list(locked_vars)).
:- mode mode_info_get_locked_vars(mode_info_ui, out) is det.
-:- pred mode_info_set_locked_vars(mode_info, list(set(var)), mode_info).
+:- pred mode_info_set_locked_vars(mode_info, list(locked_vars), mode_info).
:- mode mode_info_set_locked_vars(mode_info_di, in, mode_info_uo) is det.
:- pred mode_info_get_errors(mode_info, list(mode_error_info)).
@@ -173,17 +175,24 @@
:- pred mode_info_get_types_of_vars(mode_info, list(var), list(type)).
:- mode mode_info_get_types_of_vars(mode_info_ui, in, out) is det.
-:- pred mode_info_lock_vars(set(var), mode_info, mode_info).
-:- mode mode_info_lock_vars(in, mode_info_di, mode_info_uo) is det.
+:- type lock_context
+ ---> negation
+ ; if_then_else
+ ; par_conj
+ ; lambda_goal
+ .
+
+:- pred mode_info_lock_vars(set(var), lock_context, mode_info, mode_info).
+:- mode mode_info_lock_vars(in, in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_unlock_vars(set(var), mode_info, mode_info).
:- mode mode_info_unlock_vars(in, mode_info_di, mode_info_uo) is det.
-:- pred mode_info_var_is_locked(mode_info, var).
-:- mode mode_info_var_is_locked(mode_info_ui, in) is semidet.
+:- pred mode_info_var_is_locked(mode_info, var, lock_context).
+:- mode mode_info_var_is_locked(mode_info_ui, in, out) is semidet.
-:- pred mode_info_var_is_locked_2(list(set(var)), var).
-:- mode mode_info_var_is_locked_2(in, in) is semidet.
+:- pred mode_info_var_is_locked_2(list(locked_vars), var, lock_context).
+:- mode mode_info_var_is_locked_2(in, in, out) is semidet.
:- pred mode_info_get_delay_info(mode_info, delay_info).
:- mode mode_info_get_delay_info(mode_info_no_io, out) is det.
@@ -205,6 +214,14 @@
:- mode mode_info_set_last_checkpoint_insts(in, mode_info_di, mode_info_uo)
is det.
+:- pred mode_info_get_parallel_vars(list(pair(set(var))), mode_info,
+ mode_info).
+:- mode mode_info_get_parallel_vars(out, mode_info_di, mode_info_uo) is det.
+
+:- pred mode_info_set_parallel_vars(list(pair(set(var))), mode_info,
+ mode_info).
+:- mode mode_info_set_parallel_vars(in, mode_info_di, mode_info_uo) is det.
+
:- pred mode_info_get_changed_flag(mode_info, bool).
:- mode mode_info_get_changed_flag(mode_info_no_io, out) is det.
@@ -218,7 +235,7 @@
ground, ground, ground,
ground, ground, ground, ground,
ground, ground, ground, ground,
- ground, ground, ground
+ ground, ground, ground, ground
)
).
*/
@@ -237,7 +254,7 @@
dead, ground, ground, ground,
ground, ground, ground, ground,
ground, ground, ground, ground,
- ground, ground, ground
+ ground, ground, ground, ground
)
).
*/
@@ -279,7 +296,7 @@
% goal the error occurred
instmap, % The current instantiatedness
% of the variables
- list(set(var)), % The "locked" variables,
+ list(locked_vars), % The "locked" variables,
% i.e. variables which cannot be
% further instantiated inside a
% negated context
@@ -312,6 +329,14 @@
% This field will always contain an empty list if debug_modes is off,
% since its information is not needed then.
+ list(pair(set(var), set(var))),
+ % A stack of pairs of sets of variables used to mode-check
+ % parallel conjunctions. The first set is the nonlocals of
+ % the parallel conjunction. The second set is a subset of the
+ % first, and is the set of variables that have been [further]
+ % bound inside the current parallel conjunct - the stack is for
+ % the correct handling of nested parallel conjunctions.
+
bool % Changed flag
% If `yes', then we may need
% to repeat mode inference.
@@ -347,7 +372,7 @@
ModeInfo = mode_info(
IOState, ModuleInfo, PredId, ProcId, VarSet, VarTypes,
Context, ModeContext, InstMapping0, LockedVars, DelayInfo,
- ErrorList, LiveVarsList, NondetLiveVarsList, [],
+ ErrorList, LiveVarsList, NondetLiveVarsList, [], [],
Changed
).
@@ -355,89 +380,95 @@
% Lots of very boring access predicates.
-mode_info_get_io_state(mode_info(IOState0,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
+mode_info_get_io_state(mode_info(IOState0,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
IOState) :-
% XXX
unsafe_promise_unique(IOState0, IOState).
%-----------------------------------------------------------------------------%
-mode_info_set_io_state( mode_info(_,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), IOState0,
- mode_info(IOState,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P)) :-
+mode_info_set_io_state( mode_info(_,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q), IOState0,
+ mode_info(IOState,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q)) :-
% XXX
unsafe_promise_unique(IOState0, IOState).
%-----------------------------------------------------------------------------%
-mode_info_get_module_info(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
+mode_info_get_module_info(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
ModuleInfo).
%-----------------------------------------------------------------------------%
-mode_info_set_module_info(mode_info(A,_,C,D,E,F,G,H,I,J,K,L,M,N,O,P), ModuleInfo,
- mode_info(A,ModuleInfo,C,D,E,F,G,H,I,J,K,L,M,N,O,P)).
+mode_info_set_module_info(mode_info(A,_,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q),
+ ModuleInfo,
+ mode_info(A,ModuleInfo,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q)).
%-----------------------------------------------------------------------------%
-mode_info_get_preds(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_), Preds) :-
+mode_info_get_preds(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
+ Preds) :-
module_info_preds(ModuleInfo, Preds).
%-----------------------------------------------------------------------------%
-mode_info_get_modes(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_), Modes) :-
+mode_info_get_modes(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
+ Modes) :-
module_info_modes(ModuleInfo, Modes).
%-----------------------------------------------------------------------------%
-mode_info_get_insts(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_), Insts) :-
+mode_info_get_insts(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
+ Insts) :-
module_info_insts(ModuleInfo, Insts).
%-----------------------------------------------------------------------------%
-mode_info_get_predid(mode_info(_,_,PredId,_,_,_,_,_,_,_,_,_,_,_,_,_), PredId).
+mode_info_get_predid(mode_info(_,_,PredId,_,_,_,_,_,_,_,_,_,_,_,_,_,_), PredId).
%-----------------------------------------------------------------------------%
-mode_info_get_procid(mode_info(_,_,_,ProcId,_,_,_,_,_,_,_,_,_,_,_,_), ProcId).
+mode_info_get_procid(mode_info(_,_,_,ProcId,_,_,_,_,_,_,_,_,_,_,_,_,_), ProcId).
%-----------------------------------------------------------------------------%
-mode_info_get_varset(mode_info(_,_,_,_,VarSet,_,_,_,_,_,_,_,_,_,_,_), VarSet).
+mode_info_get_varset(mode_info(_,_,_,_,VarSet,_,_,_,_,_,_,_,_,_,_,_,_), VarSet).
%-----------------------------------------------------------------------------%
-mode_info_set_varset(VarSet, mode_info(A,B,C,D,_,F,G,H,I,J,K,L,M,N,O,P),
- mode_info(A,B,C,D,VarSet,F,G,H,I,J,K,L,M,N,O,P)).
+mode_info_set_varset(VarSet, mode_info(A,B,C,D,_,F,G,H,I,J,K,L,M,N,O,P,Q),
+ mode_info(A,B,C,D,VarSet,F,G,H,I,J,K,L,M,N,O,P,Q)).
%-----------------------------------------------------------------------------%
-mode_info_get_var_types(mode_info(_,_,_,_,_,VarTypes,_,_,_,_,_,_,_,_,_,_),
+mode_info_get_var_types(mode_info(_,_,_,_,_,VarTypes,_,_,_,_,_,_,_,_,_,_,_),
VarTypes).
%-----------------------------------------------------------------------------%
-mode_info_set_var_types(VarTypes, mode_info(A,B,C,D,E,_,G,H,I,J,K,L,M,N,O,P),
- mode_info(A,B,C,D,E,VarTypes,G,H,I,J,K,L,M,N,O,P)).
+mode_info_set_var_types(VarTypes, mode_info(A,B,C,D,E,_,G,H,I,J,K,L,M,N,O,P,Q),
+ mode_info(A,B,C,D,E,VarTypes,G,H,I,J,K,L,M,N,O,P,Q)).
%-----------------------------------------------------------------------------%
-mode_info_get_context(mode_info(_,_,_,_,_,_,Context,_,_,_,_,_,_,_,_,_), Context).
+mode_info_get_context(mode_info(_,_,_,_,_,_,Context,_,_,_,_,_,_,_,_,_,_),
+ Context).
%-----------------------------------------------------------------------------%
-mode_info_set_context(Context, mode_info(A,B,C,D,E,F,_,H,I,J,K,L,M,N,O,P),
- mode_info(A,B,C,D,E,F,Context,H,I,J,K,L,M,N,O,P)).
+mode_info_set_context(Context, mode_info(A,B,C,D,E,F,_,H,I,J,K,L,M,N,O,P,Q),
+ mode_info(A,B,C,D,E,F,Context,H,I,J,K,L,M,N,O,P,Q)).
%-----------------------------------------------------------------------------%
-mode_info_get_mode_context(mode_info(_,_,_,_,_,_,_,ModeContext,_,_,_,_,_,_,_,_),
- ModeContext).
+mode_info_get_mode_context(
+ mode_info(_,_,_,_,_,_,_,ModeContext,_,_,_,_,_,_,_,_,_),
+ ModeContext).
%-----------------------------------------------------------------------------%
mode_info_set_mode_context(ModeContext,
- mode_info(A,B,C,D,E,F,G,_,I,J,K,L,M,N,O,P),
- mode_info(A,B,C,D,E,F,G,ModeContext,I,J,K,L,M,N,O,P)).
+ mode_info(A,B,C,D,E,F,G,_,I,J,K,L,M,N,O,P,Q),
+ mode_info(A,B,C,D,E,F,G,ModeContext,I,J,K,L,M,N,O,P,Q)).
%-----------------------------------------------------------------------------%
@@ -466,7 +497,8 @@
%-----------------------------------------------------------------------------%
-mode_info_get_instmap(mode_info(_,_,_,_,_,_,_,_,InstMap,_,_,_,_,_,_,_), InstMap).
+mode_info_get_instmap(mode_info(_,_,_,_,_,_,_,_,InstMap,_,_,_,_,_,_,_,_),
+ InstMap).
% mode_info_dcg_get_instmap/3 is the same as mode_info_get_instmap/2
% except that it's easier to use inside a DCG.
@@ -477,8 +509,8 @@
%-----------------------------------------------------------------------------%
mode_info_set_instmap( InstMap,
- mode_info(A,B,C,D,E,F,G,H,InstMap0,J,DelayInfo0,L,M,N,O,P),
- mode_info(A,B,C,D,E,F,G,H,InstMap,J,DelayInfo,L,M,N,O,P)) :-
+ mode_info(A,B,C,D,E,F,G,H,InstMap0,J,DelayInfo0,L,M,N,O,P,Q),
+ mode_info(A,B,C,D,E,F,G,H,InstMap,J,DelayInfo,L,M,N,O,P,Q)) :-
( instmap__is_unreachable(InstMap), instmap__is_reachable(InstMap0) ->
delay_info__bind_all_vars(DelayInfo0, DelayInfo)
;
@@ -487,28 +519,29 @@
%-----------------------------------------------------------------------------%
-mode_info_get_locked_vars(mode_info(_,_,_,_,_,_,_,_,_,LockedVars,_,_,_,_,_,_),
+mode_info_get_locked_vars(mode_info(_,_,_,_,_,_,_,_,_,LockedVars,_,_,_,_,_,_,_),
LockedVars).
%-----------------------------------------------------------------------------%
-mode_info_set_locked_vars( mode_info(A,B,C,D,E,F,G,H,I,_,K,L,M,N,O,P), LockedVars,
- mode_info(A,B,C,D,E,F,G,H,I,LockedVars,K,L,M,N,O,P)).
+mode_info_set_locked_vars( mode_info(A,B,C,D,E,F,G,H,I,_,K,L,M,N,O,P,Q),
+ LockedVars,
+ mode_info(A,B,C,D,E,F,G,H,I,LockedVars,K,L,M,N,O,P,Q)).
%-----------------------------------------------------------------------------%
-mode_info_get_errors(mode_info(_,_,_,_,_,_,_,_,_,_,_,Errors,_,_,_,_), Errors).
+mode_info_get_errors(mode_info(_,_,_,_,_,_,_,_,_,_,_,Errors,_,_,_,_,_), Errors).
%-----------------------------------------------------------------------------%
-mode_info_get_num_errors(mode_info(_,_,_,_,_,_,_,_,_,_,_,Errors,_,_,_,_),
+mode_info_get_num_errors(mode_info(_,_,_,_,_,_,_,_,_,_,_,Errors,_,_,_,_,_),
NumErrors) :-
list__length(Errors, NumErrors).
%-----------------------------------------------------------------------------%
-mode_info_set_errors( Errors, mode_info(A,B,C,D,E,F,G,H,I,J,K,_,M,N,O,P),
- mode_info(A,B,C,D,E,F,G,H,I,J,K,Errors,M,N,O,P)).
+mode_info_set_errors( Errors, mode_info(A,B,C,D,E,F,G,H,I,J,K,_,M,N,O,P,Q),
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,Errors,M,N,O,P,Q)).
%-----------------------------------------------------------------------------%
@@ -522,9 +555,9 @@
mode_info_add_live_vars(NewLiveVars,
mode_info(A,B,C,D,E,F,G,H,I,J,K,L,
- LiveVars0,NondetLiveVars0,O,P),
+ LiveVars0,NondetLiveVars0,O,P,Q),
mode_info(A,B,C,D,E,F,G,H,I,J,K,L,
- LiveVars,NondetLiveVars,O,P)) :-
+ LiveVars,NondetLiveVars,O,P,Q)) :-
LiveVars = [NewLiveVars | LiveVars0],
NondetLiveVars = [NewLiveVars | NondetLiveVars0].
@@ -534,9 +567,9 @@
mode_info_remove_live_vars(OldLiveVars, ModeInfo0, ModeInfo) :-
ModeInfo0 = mode_info(A,B,C,D,E,F,G,H,I,J,K,L,
- LiveVars0, NondetLiveVars0,O,P),
+ LiveVars0, NondetLiveVars0,O,P,Q),
ModeInfo1 = mode_info(A,B,C,D,E,F,G,H,I,J,K,L,
- LiveVars, NondetLiveVars,O,P),
+ LiveVars, NondetLiveVars,O,P,Q),
(
list__delete_first(LiveVars0, OldLiveVars, LiveVars1),
list__delete_first(NondetLiveVars0, OldLiveVars,
@@ -563,8 +596,8 @@
% Check whether a variable is live or not
-mode_info_var_is_live(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,LiveVarsList,_,_,_), Var,
- Result) :-
+mode_info_var_is_live(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,LiveVarsList,_,_,_,_),
+ Var, Result) :-
(
% some [LiveVars]
list__member(LiveVars, LiveVarsList),
@@ -578,7 +611,7 @@
% Check whether a variable is nondet_live or not.
mode_info_var_is_nondet_live(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,
- NondetLiveVarsList,_,_), Var, Result) :-
+ NondetLiveVarsList,_,_,_), Var, Result) :-
(
% some [LiveVars]
list__member(LiveVars, NondetLiveVarsList),
@@ -589,7 +622,7 @@
Result = dead
).
-mode_info_get_liveness(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,LiveVarsList,_,_,_),
+mode_info_get_liveness(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,LiveVarsList,_,_,_,_),
LiveVars) :-
set__init(LiveVars0),
mode_info_get_liveness_2(LiveVarsList, LiveVars0, LiveVars).
@@ -620,9 +653,9 @@
% push them on the stack, and to unlock a set of vars, we just
% pop them off the stack. The stack is implemented as a list.
-mode_info_lock_vars(Vars, ModeInfo0, ModeInfo) :-
+mode_info_lock_vars(Vars, Context, ModeInfo0, ModeInfo) :-
mode_info_get_locked_vars(ModeInfo0, LockedVars),
- mode_info_set_locked_vars(ModeInfo0, [Vars | LockedVars], ModeInfo).
+ mode_info_set_locked_vars(ModeInfo0, [Vars - Context | LockedVars], ModeInfo).
mode_info_unlock_vars(_, ModeInfo0, ModeInfo) :-
mode_info_get_locked_vars(ModeInfo0, LockedVars0),
@@ -633,46 +666,54 @@
),
mode_info_set_locked_vars(ModeInfo0, LockedVars, ModeInfo).
-mode_info_var_is_locked(ModeInfo, Var) :-
+mode_info_var_is_locked(ModeInfo, Var, Context) :-
mode_info_get_locked_vars(ModeInfo, LockedVarsList),
- mode_info_var_is_locked_2(LockedVarsList, Var).
+ mode_info_var_is_locked_2(LockedVarsList, Var, Context).
-mode_info_var_is_locked_2([Set | Sets], Var) :-
+mode_info_var_is_locked_2([Set - Context0| Sets], Var, Context) :-
(
set__member(Var, Set)
->
- true
+ Context = Context0
;
- mode_info_var_is_locked_2(Sets, Var)
+ mode_info_var_is_locked_2(Sets, Var, Context)
).
-mode_info_get_delay_info(mode_info(_,_,_,_,_,_,_,_,_,_,DelayInfo,_,_,_,_,_),
+mode_info_get_delay_info(mode_info(_,_,_,_,_,_,_,_,_,_,DelayInfo,_,_,_,_,_,_),
DelayInfo).
-mode_info_set_delay_info(DelayInfo, mode_info(A,B,C,D,E,F,G,H,I,J,_,L,M,N,O,P),
- mode_info(A,B,C,D,E,F,G,H,I,J,DelayInfo,L,M,N,O,P)).
+mode_info_set_delay_info(DelayInfo,
+ mode_info(A,B,C,D,E,F,G,H,I,J,_,L,M,N,O,P,Q),
+ mode_info(A,B,C,D,E,F,G,H,I,J,DelayInfo,L,M,N,O,P,Q)).
mode_info_get_nondet_live_vars(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,
- NondetLiveVars,_,_), NondetLiveVars).
+ NondetLiveVars,_,_,_), NondetLiveVars).
mode_info_set_nondet_live_vars(NondetLiveVars,
- mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,_,O,P),
- mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,NondetLiveVars,O,P)).
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,_,O,P,Q),
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,NondetLiveVars,O,P,Q)).
mode_info_get_last_checkpoint_insts(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,_,
- LastCheckpointInsts,_), LastCheckpointInsts).
+ LastCheckpointInsts,_,_), LastCheckpointInsts).
mode_info_set_last_checkpoint_insts(LastCheckpointInsts,
- mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,_,P),
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,_,P,Q),
mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,
- LastCheckpointInsts,P)).
+ LastCheckpointInsts,P,Q)).
+
+mode_info_get_parallel_vars(PVars, ModeInfo, ModeInfo) :-
+ ModeInfo = mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,PVars,_).
+
+mode_info_set_parallel_vars(PVars,
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,_,Q),
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,PVars,Q)).
-mode_info_get_changed_flag(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,Changed),
+mode_info_get_changed_flag(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,Changed),
Changed).
mode_info_set_changed_flag(Changed,
- mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,_),
- mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,Changed)).
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,_),
+ mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Changed)).
%-----------------------------------------------------------------------------%
Index: compiler/mode_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mode_util.m,v
retrieving revision 1.101
diff -u -r1.101 mode_util.m
--- mode_util.m 1997/09/29 06:45:48 1.101
+++ mode_util.m 1997/10/02 00:26:20
@@ -1092,6 +1092,12 @@
recompute_instmap_delta_conj(Atomic, Goals0, Goals,
InstMap, InstMapDelta).
+recompute_instmap_delta_2(Atomic, par_conj(Goals0, SM), GoalInfo,
+ par_conj(Goals, SM), InstMap, InstMapDelta) -->
+ { goal_info_get_nonlocals(GoalInfo, NonLocals) },
+ recompute_instmap_delta_par_conj(Atomic, Goals0, Goals,
+ InstMap, NonLocals, InstMapDelta).
+
recompute_instmap_delta_2(Atomic, disj(Goals0, SM), GoalInfo, disj(Goals, SM),
InstMap, InstMapDelta) -->
{ goal_info_get_nonlocals(GoalInfo, NonLocals) },
@@ -1179,6 +1185,27 @@
recompute_instmap_delta_disj(Atomic, Goals0, Goals,
InstMap, NonLocals, InstMapDelta1),
merge_instmap_delta(InstMap, NonLocals, InstMapDelta0,
+ InstMapDelta1, InstMapDelta).
+
+:- pred recompute_instmap_delta_par_conj(bool, list(hlds_goal),
+ list(hlds_goal), instmap, set(var), instmap_delta,
+ module_info, module_info).
+:- mode recompute_instmap_delta_par_conj(in, in, out, in, in, out,
+ in, out) is det.
+
+recompute_instmap_delta_par_conj(_, [], [], _, _, InstMapDelta) -->
+ { instmap_delta_init_unreachable(InstMapDelta) }.
+recompute_instmap_delta_par_conj(Atomic, [Goal0], [Goal],
+ InstMap, _, InstMapDelta) -->
+ recompute_instmap_delta(Atomic, Goal0, Goal, InstMap, InstMapDelta).
+recompute_instmap_delta_par_conj(Atomic, [Goal0 | Goals0], [Goal | Goals],
+ InstMap, NonLocals, InstMapDelta) -->
+ { Goals0 = [_|_] },
+ recompute_instmap_delta(Atomic, Goal0, Goal,
+ InstMap, InstMapDelta0),
+ recompute_instmap_delta_par_conj(Atomic, Goals0, Goals,
+ InstMap, NonLocals, InstMapDelta1),
+ unify_instmap_delta(InstMap, NonLocals, InstMapDelta0,
InstMapDelta1, InstMapDelta).
%-----------------------------------------------------------------------------%
Index: compiler/modecheck_unify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.24
diff -u -r1.24 modecheck_unify.m
--- modecheck_unify.m 1997/10/13 10:24:18 1.24
+++ modecheck_unify.m 1997/10/21 05:28:13
@@ -381,10 +381,11 @@
% lock the non-locals
% (a lambda goal is not allowed to bind any of the non-local
% variables, since it could get called more than once)
+ % `negation' as the locked_var_context is a place holder.
Goal0 = _ - GoalInfo0,
goal_info_get_nonlocals(GoalInfo0, NonLocals0),
set__delete_list(NonLocals0, Vars, NonLocals),
- mode_info_lock_vars(NonLocals, ModeInfo2, ModeInfo3),
+ mode_info_lock_vars(NonLocals, lambda_goal, ModeInfo2, ModeInfo3),
mode_checkpoint(enter, "lambda goal", ModeInfo3, ModeInfo4),
% if we're being called from unique_modes.m, then we need to
Index: compiler/modes.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modes.m,v
retrieving revision 1.205
diff -u -r1.205 modes.m
--- modes.m 1997/09/15 21:12:24 1.205
+++ modes.m 1997/10/23 00:52:28
@@ -711,6 +711,33 @@
),
mode_checkpoint(exit, "conj").
+ % To modecheck a parallel conjunction, we modecheck each
+ % conjunct independently (just like for disjunctions).
+ % To make sure that we don't try to bind a variable more than
+ % once (by binding it in more than one conjunct), we maintain a
+ % datastructure that keeps track of three things:
+ % the set of variables that are nonlocal to the conjuncts
+ % (which may be a superset of the nonlocals of the par_conj
+ % as a whole);
+ % the set of nonlocal variables that have been bound in the
+ % current conjunct; and
+ % the set of variables that were bound in previous conjuncts.
+ % When binding a variable, we check that it wasn't in the set of
+ % variables bound in other conjuncts, and we add it to the set of
+ % variables bound in this conjunct.
+ % At the end of the conjunct, we add the set of variables bound in
+ % this conjunct to the set of variables bound in previous conjuncts
+ % and set the set of variables bound in the current conjunct to
+ % empty.
+ % A stack of these structures is maintained to handle nested parallel
+ % conjunctions properly.
+modecheck_goal_expr(par_conj(List0, SM), GoalInfo0, par_conj(List, SM)) -->
+ mode_checkpoint(enter, "par_conj"),
+ { goal_info_get_nonlocals(GoalInfo0, NonLocals) },
+ modecheck_par_conj_list(List0, List, NonLocals, InstMapNonlocalList),
+ instmap__unify(NonLocals, InstMapNonlocalList),
+ mode_checkpoint(exit, "par_conj").
+
modecheck_goal_expr(disj(List0, SM), GoalInfo0, disj(List, SM)) -->
mode_checkpoint(enter, "disj"),
( { List0 = [] } -> % for efficiency, optimize common case
@@ -729,7 +756,7 @@
{ goal_info_get_nonlocals(GoalInfo0, NonLocals) },
{ goal_get_nonlocals(B0, B_Vars) },
mode_info_dcg_get_instmap(InstMap0),
- mode_info_lock_vars(NonLocals),
+ mode_info_lock_vars(NonLocals, if_then_else),
mode_info_add_live_vars(B_Vars),
modecheck_goal(A0, A),
mode_info_remove_live_vars(B_Vars),
@@ -748,7 +775,7 @@
mode_checkpoint(enter, "not"),
{ goal_info_get_nonlocals(GoalInfo0, NonLocals) },
mode_info_dcg_get_instmap(InstMap0),
- mode_info_lock_vars(NonLocals),
+ mode_info_lock_vars(NonLocals, negation),
modecheck_goal(A0, A),
mode_info_unlock_vars(NonLocals),
mode_info_set_instmap(InstMap0),
@@ -985,8 +1012,8 @@
% Now see whether the goal was successfully scheduled.
% If we didn't manage to schedule the goal, then we
- % restore the original instmap, delay_info & livevars here,
- % and delay the goal.
+ % restore the original instmap, delay_info and livevars
+ % here, and delay the goal.
=(ModeInfo1),
{ mode_info_get_errors(ModeInfo1, Errors) },
( { Errors = [ FirstError | _] } ->
@@ -1089,6 +1116,58 @@
%-----------------------------------------------------------------------------%
+:- pred modecheck_par_conj_list(list(hlds_goal), list(hlds_goal),
+ set(var), list(pair(instmap, set(var))), mode_info, mode_info).
+:- mode modecheck_par_conj_list(in, out, in, out,
+ mode_info_di, mode_info_uo) is det.
+
+modecheck_par_conj_list([], [], _NonLocals, []) --> [].
+modecheck_par_conj_list([Goal0|Goals0], [Goal|Goals], NonLocals,
+ [InstMap - GoalNonLocals|InstMaps]) -->
+ mode_info_dcg_get_instmap(InstMap0),
+ { Goal0 = _ - GoalInfo },
+ { goal_info_get_nonlocals(GoalInfo, GoalNonLocals) },
+ mode_info_get_parallel_vars(PVars0),
+ { set__init(Bound0) },
+ mode_info_set_parallel_vars([NonLocals - Bound0|PVars0]),
+
+ modecheck_goal(Goal0, Goal),
+ mode_info_get_parallel_vars(PVars1),
+ (
+ { PVars1 = [_ - Bound1|PVars2] },
+ (
+ { PVars2 = [OuterNonLocals - OuterBound0|PVars3] },
+ { set__intersect(OuterNonLocals, Bound1, Bound) },
+ { set__union(OuterBound0, Bound, OuterBound) },
+ { PVars = [OuterNonLocals - OuterBound|PVars3] },
+ mode_info_set_parallel_vars(PVars)
+ ;
+ { PVars2 = [] },
+ mode_info_set_parallel_vars(PVars2)
+ )
+ ;
+ { PVars1 = [] },
+ { error("lost parallel vars") }
+ ),
+ mode_info_dcg_get_instmap(InstMap),
+ mode_info_set_instmap(InstMap0),
+ mode_info_lock_vars(Bound1, par_conj),
+ modecheck_par_conj_list(Goals0, Goals, NonLocals, InstMaps),
+ mode_info_unlock_vars(Bound1).
+
+:- pred get_all_conjunct_nonlocals(list(hlds_goal), set(var), set(var)).
+:- mode get_all_conjunct_nonlocals(in, in, out) is det.
+
+get_all_conjunct_nonlocals([], NonLocals, NonLocals).
+get_all_conjunct_nonlocals([G|Gs], NonLocals0, NonLocals) :-
+ G = _ - GoalInfo,
+ goal_info_get_nonlocals(GoalInfo, GoalNonLocals),
+ set__union(GoalNonLocals, NonLocals0, NonLocals1),
+ get_all_conjunct_nonlocals(Gs, NonLocals1, NonLocals).
+
+
+%-----------------------------------------------------------------------------%
+
% Given a list of variables and a list of expected livenesses,
% ensure the liveness of each variable satisfies the corresponding
% expected liveness.
@@ -1227,8 +1306,9 @@
% The former is used for predicate calls, where we may need
% to introduce unifications to handle calls to implied modes.
-modecheck_set_var_inst(Var0, FinalInst, ModeInfo0, ModeInfo) :-
+modecheck_set_var_inst(Var0, FinalInst, ModeInfo00, ModeInfo) :-
mode_info_get_instmap(ModeInfo0, InstMap0),
+ mode_info_get_parallel_vars(PVars0, ModeInfo00, ModeInfo0),
( instmap__is_reachable(InstMap0) ->
% The new inst must be computed by unifying the
% old inst and the proc's final inst
@@ -1251,7 +1331,7 @@
inst_expand(ModuleInfo, Inst, not_reached)
->
instmap__init_unreachable(InstMap),
- mode_info_set_instmap(InstMap, ModeInfo1, ModeInfo)
+ mode_info_set_instmap(InstMap, ModeInfo1, ModeInfo3)
;
% If we haven't added any information and
% we haven't bound any part of the var, then
@@ -1259,7 +1339,7 @@
inst_matches_initial(Inst0, Inst, ModuleInfo)
->
instmap__set(InstMap0, Var0, Inst, InstMap),
- mode_info_set_instmap(InstMap, ModeInfo1, ModeInfo)
+ mode_info_set_instmap(InstMap, ModeInfo1, ModeInfo3)
;
% We must have either added some information,
% lost some uniqueness, or bound part of the var.
@@ -1273,26 +1353,40 @@
mode_info_set_instmap(InstMap, ModeInfo1, ModeInfo2),
mode_info_get_delay_info(ModeInfo2, DelayInfo0),
delay_info__bind_var(DelayInfo0, Var0, DelayInfo),
- mode_info_set_delay_info(DelayInfo, ModeInfo2, ModeInfo)
+ mode_info_set_delay_info(DelayInfo,
+ ModeInfo2, ModeInfo3)
;
% We've bound part of the var. If the var was locked,
% then we need to report an error.
- mode_info_var_is_locked(ModeInfo1, Var0)
+ mode_info_var_is_locked(ModeInfo1, Var0, LockContext)
->
set__singleton_set(WaitingVars, Var0),
mode_info_error(WaitingVars,
- mode_error_bind_var(Var0, Inst0, Inst),
- ModeInfo1, ModeInfo
- )
+ mode_error_bind_var(Var0, Inst0, Inst,
+ LockContext), ModeInfo1, ModeInfo3)
;
instmap__set(InstMap0, Var0, Inst, InstMap),
mode_info_set_instmap(InstMap, ModeInfo1, ModeInfo2),
mode_info_get_delay_info(ModeInfo2, DelayInfo0),
delay_info__bind_var(DelayInfo0, Var0, DelayInfo),
- mode_info_set_delay_info(DelayInfo, ModeInfo2, ModeInfo)
+ mode_info_set_delay_info(DelayInfo,
+ ModeInfo2, ModeInfo3)
)
;
- ModeInfo = ModeInfo0
+ ModeInfo3 = ModeInfo0
+ ),
+ (
+ PVars0 = [],
+ ModeInfo = ModeInfo3
+ ;
+ PVars0 = [NonLocals - Bound0|PVars1],
+ ( set__member(Var0, NonLocals) ->
+ set__insert(Bound0, Var0, Bound),
+ PVars = [NonLocals - Bound|PVars1]
+ ;
+ PVars = PVars0
+ ),
+ mode_info_set_parallel_vars(PVars, ModeInfo3, ModeInfo)
).
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/opt_debug.m,v
retrieving revision 1.72
diff -u -r1.72 opt_debug.m
--- opt_debug.m 1997/08/25 17:48:31 1.72
+++ opt_debug.m 1997/09/08 22:43:25
@@ -873,6 +873,19 @@
% XXX should probably give more info than this
opt_debug__dump_instr(pragma_c(_, _, Code, _, _), Str) :-
string__append_list(["pragma_c(", Code, ")"], Str).
+opt_debug__dump_instr(fork(Child, Parent, Lval), Str) :-
+ opt_debug__dump_label(Child, ChildStr),
+ opt_debug__dump_label(Parent, ParentStr),
+ string__int_to_string(Lval, LvalStr),
+ string__append_list(["fork(", ChildStr, ", ", ParentStr, ", ",
+ LvalStr, ")"], Str).
+opt_debug__dump_instr(join_and_terminate(Lval), Str) :-
+ opt_debug__dump_lval(Lval, LvalStr),
+ string__append_list(["join_and_terminate(", LvalStr, ")"], Str).
+opt_debug__dump_instr(join_and_continue(Lval, Label), Str) :-
+ opt_debug__dump_lval(Lval, LvalStr),
+ opt_debug__dump_label(Label, LabelStr),
+ string__append_list(["join(", LvalStr, ", ", LabelStr, ")"], Str).
opt_debug__dump_fullinstr(Uinstr - Comment, Str) :-
opt_debug__dump_instr(Uinstr, U_str),
Index: compiler/opt_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/opt_util.m,v
retrieving revision 1.84
diff -u -r1.84 opt_util.m
--- opt_util.m 1997/08/25 17:48:34 1.84
+++ opt_util.m 1997/09/08 23:18:30
@@ -891,6 +891,25 @@
;
Uinstr0 = pragma_c(_, _, _, _, _),
Need = no
+ ;
+ Uinstr0 = fork(_, _, _),
+ Need = no
+ ;
+ Uinstr0 = join_and_terminate(Lval),
+ opt_util__lval_refers_stackvars(Lval, Use),
+ ( Use = yes ->
+ Need = yes
+ ;
+ opt_util__block_refers_stackvars(Instrs0, Need)
+ )
+ ;
+ Uinstr0 = join_and_continue(Lval, _),
+ opt_util__lval_refers_stackvars(Lval, Use),
+ ( Use = yes ->
+ Need = yes
+ ;
+ opt_util__block_refers_stackvars(Instrs0, Need)
+ )
).
opt_util__filter_out_labels([], []).
@@ -990,6 +1009,9 @@
opt_util__can_instr_branch_away(incr_sp(_, _), no).
opt_util__can_instr_branch_away(decr_sp(_), no).
opt_util__can_instr_branch_away(pragma_c(_, _, _, _, _), no).
+opt_util__can_instr_branch_away(fork(_, _, _), yes).
+opt_util__can_instr_branch_away(join_and_terminate(_), no).
+opt_util__can_instr_branch_away(join_and_continue(_, _), yes).
opt_util__can_instr_fall_through(comment(_), yes).
opt_util__can_instr_fall_through(livevals(_), yes).
@@ -1015,6 +1037,9 @@
opt_util__can_instr_fall_through(incr_sp(_, _), yes).
opt_util__can_instr_fall_through(decr_sp(_), yes).
opt_util__can_instr_fall_through(pragma_c(_, _, _, _, _), yes).
+opt_util__can_instr_fall_through(fork(_, _, _), no).
+opt_util__can_instr_fall_through(join_and_terminate(_), no).
+opt_util__can_instr_fall_through(join_and_continue(_, _), no).
% Check whether an instruction sequence can possibly fall through
% to the next instruction without using its label.
@@ -1056,6 +1081,9 @@
opt_util__can_use_livevals(incr_sp(_, _), no).
opt_util__can_use_livevals(decr_sp(_), no).
opt_util__can_use_livevals(pragma_c(_, _, _, _, _), no).
+opt_util__can_use_livevals(fork(_, _, _), no).
+opt_util__can_use_livevals(join_and_terminate(_), no).
+opt_util__can_use_livevals(join_and_continue(_, _), no).
% determine all the labels and code_addresses that are referenced by Instr
@@ -1114,6 +1142,9 @@
opt_util__instr_labels_2(incr_sp(_, _), [], []).
opt_util__instr_labels_2(decr_sp(_), [], []).
opt_util__instr_labels_2(pragma_c(_, _, _, _, _), [], []).
+opt_util__instr_labels_2(fork(Child, Parent, _), [Child, Parent], []).
+opt_util__instr_labels_2(join_and_terminate(_), [], []).
+opt_util__instr_labels_2(join_and_continue(_, Label), [Label], []).
:- pred opt_util__instr_rvals_and_lvals(instr, list(rval), list(lval)).
:- mode opt_util__instr_rvals_and_lvals(in, out, out) is det.
@@ -1146,6 +1177,9 @@
opt_util__instr_rvals_and_lvals(pragma_c(_, In, _, Out, _), Rvals, Lvals) :-
pragma_c_inputs_get_rvals(In, Rvals),
pragma_c_outputs_get_lvals(Out, Lvals).
+opt_util__instr_rvals_and_lvals(fork(_, _, _), [], []).
+opt_util__instr_rvals_and_lvals(join_and_terminate(Lval), [], [Lval]).
+opt_util__instr_rvals_and_lvals(join_and_continue(Lval, _), [], [Lval]).
% extract the rvals from the pragma_c_input
:- pred pragma_c_inputs_get_rvals(list(pragma_c_input), list(rval)).
@@ -1241,6 +1275,11 @@
opt_util__count_temps_instr(incr_sp(_, _), R, R, F, F).
opt_util__count_temps_instr(decr_sp(_), R, R, F, F).
opt_util__count_temps_instr(pragma_c(_, _, _, _, _), R, R, F, F).
+opt_util__count_temps_instr(fork(_, _, _), R, R, F, F).
+opt_util__count_temps_instr(join_and_terminate(Lval), R0, R, F0, F) :-
+ opt_util__count_temps_lval(Lval, R0, R, F0, F).
+opt_util__count_temps_instr(join_and_continue(Lval, _), R0, R, F0, F) :-
+ opt_util__count_temps_lval(Lval, R0, R, F0, F).
:- pred opt_util__count_temps_lval(lval, int, int, int, int).
:- mode opt_util__count_temps_lval(in, in, out, in, out) is det.
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/polymorphism.m,v
retrieving revision 1.118
diff -u -r1.118 polymorphism.m
--- polymorphism.m 1997/10/14 09:27:53 1.118
+++ polymorphism.m 1997/10/17 04:20:34
@@ -503,6 +503,9 @@
polymorphism__process_goal_expr(conj(Goals0), GoalInfo,
conj(Goals) - GoalInfo) -->
polymorphism__process_goal_list(Goals0, Goals).
+polymorphism__process_goal_expr(par_conj(Goals0, SM), GoalInfo,
+ par_conj(Goals, SM) - GoalInfo) -->
+ polymorphism__process_goal_list(Goals0, Goals).
polymorphism__process_goal_expr(disj(Goals0, SM), GoalInfo,
disj(Goals, SM) - GoalInfo) -->
polymorphism__process_goal_list(Goals0, Goals).
Index: compiler/prog_data.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_data.m,v
retrieving revision 1.26
diff -u -r1.26 prog_data.m
--- prog_data.m 1997/10/09 09:39:05 1.26
+++ prog_data.m 1997/10/20 01:21:52
@@ -176,10 +176,12 @@
% clause/4 defined above
:- type goal == pair(goal_expr, term__context).
+
:- type goal_expr
---> (goal,goal)
; true
% could use conj(goals) instead
+ ; (goal & goal) % &/2 ie parallel-conj
; {goal;goal} % {...} quotes ';'/2.
; fail
% could use disj(goals) instead
Index: compiler/prog_io_dcg.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_dcg.m,v
retrieving revision 1.6
diff -u -r1.6 prog_io_dcg.m
--- prog_io_dcg.m 1997/10/06 22:18:13 1.6
+++ prog_io_dcg.m 1997/10/07 22:35:02
@@ -199,6 +199,11 @@
parse_dcg_goal(A0, VarSet0, N0, Var0, A, VarSet1, N1, Var1),
parse_dcg_goal(B0, VarSet1, N1, Var1, B, VarSet, N, Var).
+parse_dcg_goal_2("&", [A0, B0], Context, VarSet0, N0, Var0,
+ (A & B) - Context, VarSet, N, Var) :-
+ parse_dcg_goal(A0, VarSet0, N0, Var0, A, VarSet1, N1, Var1),
+ parse_dcg_goal(B0, VarSet1, N1, Var1, B, VarSet, N, Var).
+
% Disjunction or if-then-else (Prolog syntax).
parse_dcg_goal_2(";", [A0, B0], Context, VarSet0, N0, Var0,
Goal, VarSet, N, Var) :-
Index: compiler/prog_io_goal.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_goal.m,v
retrieving revision 1.6
diff -u -r1.6 prog_io_goal.m
--- prog_io_goal.m 1997/10/06 22:18:16 1.6
+++ prog_io_goal.m 1997/10/07 22:35:02
@@ -168,6 +168,9 @@
parse_goal_2(",", [A0, B0], V0, (A, B), V) :-
parse_goal(A0, V0, A, V1),
parse_goal(B0, V1, B, V).
+parse_goal_2("&", [A0, B0], V0, (A & B), V) :-
+ parse_goal(A0, V0, A, V1),
+ parse_goal(B0, V1, B, V).
parse_goal_2(";", [A0, B0], V0, R, V) :-
(
A0 = term__functor(term__atom("->"), [X0, Y0], _Context)
Index: compiler/prog_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_util.m,v
retrieving revision 1.35
diff -u -r1.35 prog_util.m
--- prog_util.m 1997/07/27 15:01:32 1.35
+++ prog_util.m 1997/09/08 22:43:25
@@ -140,6 +140,10 @@
(GoalA, GoalB)) :-
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
+prog_util__rename_in_goal_expr((GoalA0 & GoalB0), OldVar, NewVar,
+ (GoalA & GoalB)) :-
+ prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
+ prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
prog_util__rename_in_goal_expr(true, _Var, _NewVar, true).
prog_util__rename_in_goal_expr((GoalA0; GoalB0), OldVar, NewVar,
(GoalA; GoalB)) :-
Index: compiler/quantification.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/quantification.m,v
retrieving revision 1.53
diff -u -r1.53 quantification.m
--- quantification.m 1997/09/01 14:04:33 1.53
+++ quantification.m 1997/09/08 22:43:25
@@ -209,6 +209,9 @@
implicitly_quantify_goal_2(conj(List0), _, conj(List)) -->
implicitly_quantify_conj(List0, List).
+implicitly_quantify_goal_2(par_conj(List0, SM), _, par_conj(List, SM)) -->
+ implicitly_quantify_conj(List0, List).
+
implicitly_quantify_goal_2(disj(Goals0, SM), _, disj(Goals, SM)) -->
implicitly_quantify_disj(Goals0, Goals).
@@ -595,6 +598,9 @@
set__insert_list(Set0, ArgVars, Set).
quantification__goal_vars_2(conj(Goals), Set0, LambdaSet0, Set, LambdaSet) :-
+ goal_list_vars_2(Goals, Set0, LambdaSet0, Set, LambdaSet).
+
+quantification__goal_vars_2(par_conj(Goals, _SM), Set0, LambdaSet0, Set, LambdaSet) :-
goal_list_vars_2(Goals, Set0, LambdaSet0, Set, LambdaSet).
quantification__goal_vars_2(disj(Goals, _), Set0, LambdaSet0, Set, LambdaSet) :-
Index: compiler/saved_vars.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/saved_vars.m,v
retrieving revision 1.11
diff -u -r1.11 saved_vars.m
--- saved_vars.m 1997/09/01 14:04:35 1.11
+++ saved_vars.m 1997/09/08 23:18:36
@@ -84,6 +84,13 @@
Goals, SlotInfo),
conj_list_to_goal(Goals, GoalInfo0, Goal)
;
+ GoalExpr0 = par_conj(Goals0, SM),
+ % saved_vars_in_disj treats its goal list as
+ % an independent list of goals, so we can use
+ % it to process the list of parallel conjuncts too.
+ saved_vars_in_disj(Goals0, SlotInfo0, Goals, SlotInfo),
+ Goal = par_conj(Goals, SM) - GoalInfo0
+ ;
GoalExpr0 = disj(Goals0, SM),
saved_vars_in_disj(Goals0, SlotInfo0, Goals, SlotInfo),
Goal = disj(Goals, SM) - GoalInfo0
@@ -288,6 +295,11 @@
saved_vars_delay_goal(Goals1, Construct, Var,
IsNonLocal, SlotInfo0, Goals, SlotInfo)
;
+ Goal0Expr = par_conj(_ParConj, _SM),
+ saved_vars_delay_goal(Goals0, Construct, Var,
+ IsNonLocal, SlotInfo0, Goals1, SlotInfo),
+ Goals = [Goal0|Goals1]
+ ;
Goal0Expr = some(SomeVars, SomeGoal0),
rename_var(SlotInfo0, Var, NewVar, Subst, SlotInfo1),
goal_util__rename_vars_in_goal(Construct, Subst,
@@ -424,6 +436,9 @@
Cases, SlotInfo).
%-----------------------------------------------------------------------------%
+
+ % saved_vars_in_disj does a saved_vars_in_goal on an list of independent
+ % goals, and is used to process disjunctions and parallel conjunctions.
:- pred saved_vars_in_disj(list(hlds_goal), slot_info,
list(hlds_goal), slot_info).
Index: compiler/simplify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/simplify.m,v
retrieving revision 1.46
diff -u -r1.46 simplify.m
--- simplify.m 1997/09/01 14:04:39 1.46
+++ simplify.m 1997/09/08 22:43:25
@@ -275,6 +275,21 @@
)
).
+simplify__goal_2(par_conj(Goals0, SM), GoalInfo, Goal, GoalInfo, Info0, Info) :-
+ (
+ Goals0 = []
+ ->
+ Goal = conj([]),
+ Info = Info0
+ ;
+ Goals0 = [Goal0]
+ ->
+ simplify__goal(Goal0, Goal - _, Info0, Info)
+ ;
+ simplify__par_conj(Goals0, Goals, Info0, Info0, Info),
+ Goal = par_conj(Goals, SM)
+ ).
+
simplify__goal_2(disj(Disjuncts0, SM), GoalInfo0,
Goal, GoalInfo, Info0, Info) :-
( Disjuncts0 = [] ->
@@ -905,6 +920,18 @@
;
RevGoals = [Goal | RevGoals0]
).
+
+%-----------------------------------------------------------------------------%
+
+:- pred simplify__par_conj(list(hlds_goal), list(hlds_goal),
+ simplify_info, simplify_info, simplify_info).
+:- mode simplify__par_conj(in, out, in, in, out) is det.
+
+simplify__par_conj([], [], _, Info, Info).
+simplify__par_conj([Goal0 |Goals0], [Goal | Goals], Info0, Info1, Info) :-
+ simplify__goal(Goal0, Goal, Info1, Info2),
+ simplify_info_post_branch_update(Info0, Info2, Info3),
+ simplify__par_conj(Goals0, Goals, Info0, Info3, Info).
%-----------------------------------------------------------------------------%
Index: compiler/store_alloc.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/store_alloc.m,v
retrieving revision 1.55
diff -u -r1.55 store_alloc.m
--- store_alloc.m 1997/09/01 14:04:44 1.55
+++ store_alloc.m 1997/09/08 22:43:25
@@ -129,6 +129,11 @@
store_alloc_in_conj(Goals0, Liveness0, ResumeVars0, ModuleInfo,
Goals, Liveness).
+store_alloc_in_goal_2(par_conj(Goals0, SM), Liveness0, ResumeVars0, ModuleInfo,
+ par_conj(Goals, SM), Liveness) :-
+ store_alloc_in_par_conj(Goals0, Liveness0, ResumeVars0, ModuleInfo,
+ Goals, Liveness).
+
store_alloc_in_goal_2(disj(Goals0, FV), Liveness0, ResumeVars0, ModuleInfo,
disj(Goals, FV), Liveness) :-
store_alloc_in_disj(Goals0, Liveness0, ResumeVars0, ModuleInfo,
@@ -201,6 +206,20 @@
store_alloc_in_conj(Goals0, Liveness1, ResumeVars0, ModuleInfo,
Goals, Liveness)
).
+
+%-----------------------------------------------------------------------------%
+
+:- pred store_alloc_in_par_conj(list(hlds_goal), liveness_info, set(var),
+ module_info, list(hlds_goal), liveness_info).
+:- mode store_alloc_in_par_conj(in, in, in, in, out, out) is det.
+
+store_alloc_in_par_conj([], Liveness, _ResumeVars0, _ModuleInfo, [], Liveness).
+store_alloc_in_par_conj([Goal0 | Goals0], Liveness0, ResumeVars0, ModuleInfo,
+ [Goal | Goals], Liveness) :-
+ store_alloc_in_goal(Goal0, Liveness0, ResumeVars0, ModuleInfo,
+ Goal, Liveness),
+ store_alloc_in_par_conj(Goals0, Liveness0, ResumeVars0, ModuleInfo,
+ Goals, _Liveness1).
%-----------------------------------------------------------------------------%
Index: compiler/stratify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/stratify.m,v
retrieving revision 1.10
diff -u -r1.10 stratify.m
--- stratify.m 1997/09/01 14:04:49 1.10
+++ stratify.m 1997/09/08 22:43:25
@@ -161,6 +161,10 @@
ThisPredProcId, Error, Module0, Module) -->
first_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
Error, Module0, Module).
+first_order_check_goal(par_conj(Goals, _SM), _GoalInfo, Negated, WholeScc,
+ ThisPredProcId, Error, Module0, Module) -->
+ first_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
+ Error, Module0, Module).
first_order_check_goal(disj(Goals, _Follow), _GoalInfo, Negated,
WholeScc, ThisPredProcId, Error, Module0, Module) -->
first_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
@@ -337,6 +341,10 @@
ThisPredProcId, HighOrderLoops, Error, Module0, Module) -->
higher_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
HighOrderLoops, Error, Module0, Module).
+higher_order_check_goal(par_conj(Goals, _), _GoalInfo, Negated, WholeScc,
+ ThisPredProcId, HighOrderLoops, Error, Module0, Module) -->
+ higher_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
+ HighOrderLoops, Error, Module0, Module).
higher_order_check_goal(disj(Goals, _Follow), _GoalInfo, Negated, WholeScc,
ThisPredProcId, HighOrderLoops, Error, Module0, Module) -->
higher_order_check_goal_list(Goals, Negated, WholeScc, ThisPredProcId,
@@ -830,6 +838,9 @@
check_goal1(conj(Goals), Calls0, Calls, HasAT0, HasAT, CallsHO0, CallsHO) :-
check_goal_list(Goals, Calls0, Calls, HasAT0, HasAT, CallsHO0, CallsHO).
+check_goal1(par_conj(Goals, _), Calls0, Calls, HasAT0, HasAT,
+ CallsHO0, CallsHO) :-
+ check_goal_list(Goals, Calls0, Calls, HasAT0, HasAT, CallsHO0, CallsHO).
check_goal1(disj(Goals, _Follow), Calls0, Calls, HasAT0, HasAT, CallsHO0,
CallsHO) :-
check_goal_list(Goals, Calls0, Calls, HasAT0, HasAT, CallsHO0, CallsHO).
@@ -926,6 +937,8 @@
get_called_procs(conj(Goals), Calls0, Calls) :-
+ check_goal_list(Goals, Calls0, Calls).
+get_called_procs(par_conj(Goals, _), Calls0, Calls) :-
check_goal_list(Goals, Calls0, Calls).
get_called_procs(disj(Goals, _Follow), Calls0, Calls) :-
check_goal_list(Goals, Calls0, Calls).
Index: compiler/switch_detection.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/switch_detection.m,v
retrieving revision 1.76
diff -u -r1.76 switch_detection.m
--- switch_detection.m 1997/09/01 14:04:54 1.76
+++ switch_detection.m 1997/09/08 22:43:25
@@ -147,6 +147,11 @@
VarTypes, ModuleInfo, conj(Goals)) :-
detect_switches_in_conj(Goals0, InstMap0, VarTypes, ModuleInfo, Goals).
+detect_switches_in_goal_2(par_conj(Goals0, SM), _GoalInfo, InstMap0,
+ VarTypes, ModuleInfo, par_conj(Goals, SM)) :-
+ detect_switches_in_par_conj(Goals0, InstMap0, VarTypes,
+ ModuleInfo, Goals).
+
detect_switches_in_goal_2(not(Goal0), _GoalInfo, InstMap0,
VarTypes, ModuleInfo, not(Goal)) :-
detect_switches_in_goal(Goal0, InstMap0, VarTypes, ModuleInfo, Goal).
@@ -321,6 +326,17 @@
detect_switches_in_goal(Goal0, InstMap, VarTypes, ModuleInfo, Goal),
Case = case(Functor, Goal),
detect_switches_in_cases(Cases0, InstMap, VarTypes, ModuleInfo, Cases).
+
+:- pred detect_switches_in_par_conj(list(hlds_goal), instmap, map(var, type),
+ module_info, list(hlds_goal)).
+:- mode detect_switches_in_par_conj(in, in, in, in, out) is det.
+
+detect_switches_in_par_conj([], _InstMap, _VarTypes, _ModuleInfo, []).
+detect_switches_in_par_conj([Goal0 | Goals0], InstMap, VarTypes, ModuleInfo,
+ [Goal | Goals]) :-
+ detect_switches_in_goal(Goal0, InstMap, VarTypes, ModuleInfo, Goal),
+ detect_switches_in_par_conj(Goals0, InstMap, VarTypes,
+ ModuleInfo, Goals).
:- pred detect_switches_in_conj(list(hlds_goal), instmap, map(var, type),
module_info, list(hlds_goal)).
Index: compiler/term_pass1.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/term_pass1.m,v
retrieving revision 1.3
diff -u -r1.3 term_pass1.m
--- term_pass1.m 1997/10/20 04:12:41 1.3
+++ term_pass1.m 1997/10/20 04:49:20
@@ -402,6 +402,17 @@
Res, Offs0, Offs)
).
+proc_inequalities_goal(par_conj([], _), _, _Module, _, _PPId, ok, Offs, Offs).
+proc_inequalities_goal(par_conj([ Goal | Goals ], _), GoalInfo, Module, Info,
+ PPId, Res, Offs0, Offs) :-
+ ( goal_will_fail(GoalInfo) ->
+ Res = ok,
+ Offs = []
+ ;
+ proc_inequalities_conj(Goal, Goals, Module, Info, PPId,
+ Res, Offs0, Offs)
+ ).
+
% This clause fails (returns Res=error()) if:
% The called predicate contains higher order arguments
% The terminates value of the called predicate is 'dont_know'
Index: compiler/term_pass2.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/term_pass2.m,v
retrieving revision 1.2
diff -u -r1.2 term_pass2.m
--- term_pass2.m 1997/10/09 09:39:18 1.2
+++ term_pass2.m 1997/10/20 02:08:42
@@ -474,6 +474,11 @@
termination_conj(Goals, Module, UnifyInfo, CallInfo, Res,
Out0, Out).
+termination_goal(par_conj(Goals, _),
+ _GoalInfo, Module, UnifyInfo, CallInfo, Res, Out0, Out) :-
+ termination_conj(Goals, Module, UnifyInfo, CallInfo, Res,
+ Out0, Out).
+
% This processes calls when doing normal termination analysis (as opposed
% to single argument analysis).
termination_goal(call(CallPredId, CallProcId, Args, _IsBuiltin, _, _),
Index: compiler/typecheck.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/typecheck.m,v
retrieving revision 1.217
diff -u -r1.217 typecheck.m
--- typecheck.m 1997/10/14 09:18:50 1.217
+++ typecheck.m 1997/10/17 04:20:42
@@ -807,6 +807,9 @@
typecheck_goal_2(conj(List0), conj(List)) -->
checkpoint("conj"),
typecheck_goal_list(List0, List).
+typecheck_goal_2(par_conj(List0, SM), par_conj(List, SM)) -->
+ checkpoint("par_conj"),
+ typecheck_goal_list(List0, List).
typecheck_goal_2(disj(List0, SM), disj(List, SM)) -->
checkpoint("disj"),
typecheck_goal_list(List0, List).
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/unique_modes.m,v
retrieving revision 1.40
diff -u -r1.40 unique_modes.m
--- unique_modes.m 1997/09/15 21:12:50 1.40
+++ unique_modes.m 1997/09/16 00:14:39
@@ -382,6 +382,16 @@
),
mode_checkpoint(exit, "conj").
+unique_modes__check_goal_2(par_conj(List0, SM), GoalInfo0,
+ par_conj(List, SM)) -->
+ mode_checkpoint(enter, "par_conj"),
+ { goal_info_get_nonlocals(GoalInfo0, NonLocals) },
+ mode_info_add_live_vars(NonLocals),
+ unique_modes__check_par_conj(List0, List, InstMapList),
+ instmap__unify(NonLocals, InstMapList),
+ mode_info_remove_live_vars(NonLocals),
+ mode_checkpoint(exit, "par_conj").
+
unique_modes__check_goal_2(disj(List0, SM), GoalInfo0, disj(List, SM)) -->
mode_checkpoint(enter, "disj"),
( { List0 = [] } ->
@@ -422,7 +432,7 @@
{ unique_modes__goal_get_nonlocals(B0, B_Vars) },
{ unique_modes__goal_get_nonlocals(C0, C_Vars) },
mode_info_dcg_get_instmap(InstMap0),
- mode_info_lock_vars(NonLocals),
+ mode_info_lock_vars(NonLocals, if_then_else),
%
% At this point, we should set the inst of any `unique'
@@ -468,7 +478,7 @@
=(ModeInfo),
{ select_live_vars(NonLocalsList, ModeInfo, LiveNonLocals) },
make_var_list_mostly_uniq(LiveNonLocals),
- mode_info_lock_vars(NonLocals),
+ mode_info_lock_vars(NonLocals, negation),
unique_modes__check_goal(A0, A),
mode_info_unlock_vars(NonLocals),
mode_info_set_instmap(InstMap0),
@@ -615,6 +625,28 @@
mode_info_remove_live_vars(NonLocals),
unique_modes__check_goal(Goal0, Goal),
unique_modes__check_conj(Goals0, Goals).
+
+%-----------------------------------------------------------------------------%
+
+:- pred unique_modes__check_par_conj(list(hlds_goal), list(hlds_goal),
+ list(pair(instmap, set(var))), mode_info, mode_info).
+:- mode unique_modes__check_par_conj(in, out, out,
+ mode_info_di, mode_info_uo) is det.
+
+ % Just process each conjunct in turn.
+ % Because we have already done modechecking, we know that
+ % there are no attempts to bind a variable in multiple
+ % parallel conjuncts, so we don't need to lock/unlock variables.
+
+unique_modes__check_par_conj([], [], []) --> [].
+unique_modes__check_par_conj([Goal0 | Goals0], [Goal | Goals],
+ [InstMap - NonLocals|InstMaps]) -->
+ { unique_modes__goal_get_nonlocals(Goal0, NonLocals) },
+ mode_info_dcg_get_instmap(InstMap0),
+ unique_modes__check_goal(Goal0, Goal),
+ mode_info_dcg_get_instmap(InstMap),
+ mode_info_set_instmap(InstMap0),
+ unique_modes__check_par_conj(Goals0, Goals, InstMaps).
%-----------------------------------------------------------------------------%
Index: compiler/unused_args.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/unused_args.m,v
retrieving revision 1.35
diff -u -r1.35 unused_args.m
--- unused_args.m 1997/09/01 14:05:44 1.35
+++ unused_args.m 1997/09/08 22:43:25
@@ -356,6 +356,10 @@
traverse_goal(ModuleInfo, conj(Goals), UseInf0, UseInf) :-
traverse_list_of_goals(ModuleInfo, Goals, UseInf0, UseInf).
+% handle parallel conjunction
+traverse_goal(ModuleInfo, par_conj(Goals, _SM), UseInf0, UseInf) :-
+ traverse_list_of_goals(ModuleInfo, Goals, UseInf0, UseInf).
+
% handle disjunction
traverse_goal(ModuleInfo, disj(Goals, _), UseInf0, UseInf) :-
traverse_list_of_goals(ModuleInfo, Goals, UseInf0, UseInf).
@@ -1119,6 +1123,12 @@
fixup_goal_expr(ModuleInfo, UnusedVars, ProcCallInfo, Changed,
conj(Goals0) - GoalInfo, conj(Goals) - GoalInfo) :-
+ fixup_conjuncts(ModuleInfo, UnusedVars, ProcCallInfo, no,
+ Changed, Goals0, Goals).
+
+fixup_goal_expr(ModuleInfo, UnusedVars, ProcCallInfo, Changed,
+ par_conj(Goals0, SM) - GoalInfo,
+ par_conj(Goals, SM) - GoalInfo) :-
fixup_conjuncts(ModuleInfo, UnusedVars, ProcCallInfo, no,
Changed, Goals0, Goals).
Index: compiler/value_number.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/value_number.m,v
retrieving revision 1.86
diff -u -r1.86 value_number.m
--- value_number.m 1997/08/27 07:35:15 1.86
+++ value_number.m 1997/09/08 22:43:25
@@ -1093,6 +1093,9 @@
value_number__boundary_instr(incr_sp(_, _), yes).
value_number__boundary_instr(decr_sp(_), yes).
value_number__boundary_instr(pragma_c(_, _, _, _, _), yes).
+value_number__boundary_instr(fork(_, _, _), yes).
+value_number__boundary_instr(join_and_terminate(_), yes).
+value_number__boundary_instr(join_and_continue(_, _), yes).
%-----------------------------------------------------------------------------%
Index: compiler/vn_block.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_block.m,v
retrieving revision 1.49
diff -u -r1.49 vn_block.m
--- vn_block.m 1997/08/27 07:35:20 1.49
+++ vn_block.m 1997/09/08 22:43:25
@@ -357,6 +357,18 @@
_Livemap, _Params, VnTables, VnTables, Liveset, Liveset,
SeenIncr, SeenIncr, Tuple, Tuple) :-
error("value numbering not supported for pragma_c").
+vn_block__handle_instr(fork(_, _, _),
+ _Livemap, _Params, VnTables, VnTables, Liveset, Liveset,
+ SeenIncr, SeenIncr, Tuple, Tuple) :-
+ error("value numbering not supported for fork").
+vn_block__handle_instr(join_and_terminate(_),
+ _Livemap, _Params, VnTables, VnTables, Liveset, Liveset,
+ SeenIncr, SeenIncr, Tuple, Tuple) :-
+ error("value numbering not supported for join_and_terminate").
+vn_block__handle_instr(join_and_continue(_, _),
+ _Livemap, _Params, VnTables, VnTables, Liveset, Liveset,
+ SeenIncr, SeenIncr, Tuple, Tuple) :-
+ error("value numbering not supported for join_and_continue").
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -892,6 +904,9 @@
vn_block__is_ctrl_instr(incr_sp(_, _), yes).
vn_block__is_ctrl_instr(decr_sp(_), yes).
vn_block__is_ctrl_instr(pragma_c(_, _, _, _, _), no).
+vn_block__is_ctrl_instr(fork(_, _, _), yes).
+vn_block__is_ctrl_instr(join_and_terminate(_), yes).
+vn_block__is_ctrl_instr(join_and_continue(_, _), yes).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
Index: compiler/vn_cost.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_cost.m,v
retrieving revision 1.28
diff -u -r1.28 vn_cost.m
--- vn_cost.m 1997/08/25 17:48:42 1.28
+++ vn_cost.m 1997/09/08 22:43:25
@@ -183,6 +183,15 @@
;
Uinstr = pragma_c(_, _, _, _, _),
error("pragma_c found in vn_block_cost")
+ ;
+ Uinstr = fork(_, _, _),
+ error("fork found in vn_block_cost")
+ ;
+ Uinstr = join_and_terminate(_),
+ error("join_and_terminate found in vn_block_cost")
+ ;
+ Uinstr = join_and_continue(_, _),
+ error("join_and_continue found in vn_block_cost")
).
vn_cost__lval_cost(Lval, Params, Cost) :-
Index: compiler/vn_filter.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/vn_filter.m,v
retrieving revision 1.12
diff -u -r1.12 vn_filter.m
--- vn_filter.m 1997/08/27 07:35:21 1.12
+++ vn_filter.m 1997/09/09 00:46:27
@@ -156,6 +156,12 @@
vn_filter__user_instr(decr_sp(_), no).
vn_filter__user_instr(pragma_c(_, _, _, _, _), _):-
error("inappropriate instruction in vn__filter").
+vn_filter__user_instr(fork(_, _, _), _):-
+ error("fork instruction in vn__filter").
+vn_filter__user_instr(join_and_terminate(_), _):-
+ error("join_and_terminate instruction in vn__filter").
+vn_filter__user_instr(join_and_continue(_, _), _):-
+ error("join_and_continue instruction in vn__filter").
% vn_filter__replace_in_user_instr(Instr0, Old, New, Instr):
% Given that Instr0 refers to the values of some locations,
@@ -218,6 +224,12 @@
error("non-user instruction in vn_filter__replace_in_user_instr").
vn_filter__replace_in_user_instr(pragma_c(_, _, _, _, _), _, _, _):-
error("inappropriate instruction in vn__filter").
+vn_filter__replace_in_user_instr(fork(_, _, _), _, _, _):-
+ error("fork instruction in vn__filter").
+vn_filter__replace_in_user_instr(join_and_terminate(_), _, _, _):-
+ error("join_and_terminate instruction in vn__filter").
+vn_filter__replace_in_user_instr(join_and_continue(_, _), _, _, _):-
+ error("join_and_continue instruction in vn__filter").
% Check whether this instruction defines the value of any lval.
@@ -250,6 +262,12 @@
vn_filter__defining_instr(decr_sp(_), no).
vn_filter__defining_instr(pragma_c(_, _, _, _, _), _):-
error("inappropriate instruction in vn__filter").
+vn_filter__defining_instr(fork(_, _, _), _):-
+ error("fork instruction in vn__filter").
+vn_filter__defining_instr(join_and_terminate(_), _):-
+ error("join_and_terminate instruction in vn__filter").
+vn_filter__defining_instr(join_and_continue(_, _), _):-
+ error("join_and_continue instruction in vn__filter").
% vn_filter__replace_in_defining_instr(Instr0, Old, New, Instr):
% Given that Instr0 defines the value of a location,
@@ -309,7 +327,13 @@
vn_filter__replace_in_defining_instr(decr_sp(_), _, _, _) :-
error("non-def instruction in vn_filter__replace_in_defining_instr").
vn_filter__replace_in_defining_instr(pragma_c(_, _, _, _, _), _, _, _):-
- error("inappropriate instruction in vn__filter").
+ error("inappropriate instruction in vn_filter__replace_in_defining_instr").
+vn_filter__replace_in_defining_instr(fork(_, _, _), _, _, _):-
+ error("fork instruction in vn_filter__replace_in_defining_instr").
+vn_filter__replace_in_defining_instr(join_and_terminate(_), _, _, _):-
+ error("join_and_terminate instruction in vn_filter__replace_in_defining_instr").
+vn_filter__replace_in_defining_instr(join_and_continue(_, _), _, _, _):-
+ error("join_and_continue instruction in vn_filter__replace_in_defining_instr").
% vn_filter__replace_in_lval(Lval0, Old, New, Lval):
% Replace all occurrences of Old with New in Lval0,
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
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/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing library
Index: library/nc_builtin.nl
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/nc_builtin.nl,v
retrieving revision 1.15
diff -u -r1.15 nc_builtin.nl
--- nc_builtin.nl 1997/07/27 15:06:59 1.15
+++ nc_builtin.nl 1997/09/08 22:54:57
@@ -50,6 +50,8 @@
:- op(1179, xfy, (--->)).
:- op(1175, xfx, (::)).
+:- op(1025, xfy, (&)).
+
:- op(950, fxy, (lambda)).
:- op(400, yfx, (rem)).
Index: library/sp_builtin.nl
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/sp_builtin.nl,v
retrieving revision 1.13
diff -u -r1.13 sp_builtin.nl
--- sp_builtin.nl 1997/07/27 15:07:13 1.13
+++ sp_builtin.nl 1997/09/08 22:54:57
@@ -53,6 +53,7 @@
:- op(1199, fx, (mode)).
:- op(1199, fx, (inst)).
:- op(1179, xfy, (--->)).
+:- op(1025, xfy, (&)).
:- op(975, xfx, ('::')).
:- op(700, xfx, ( \= ) ).
:- op(500, fx, ( \ ) ).
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
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/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing scripts
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util
More information about the developers
mailing list