[m-rev.] for review: Re-factor the MR_join_and_continue macro.
Paul Bone
pbone at csse.unimelb.edu.au
Mon Nov 23 14:09:01 AEDT 2009
For review by someone familiar with the low-level C backend, probably Zoltan.
- Thanks, Paul.
Re-factor the MR_join_and_continue macro.
This change replaces the MR_join_and_continue macro with a Mercury C procedure.
This macro is used in the implementation of parallel conjunctions in the low
level C grades. This means that this code will always be a procedure call
rather than always being in-lined.
This change also required changes to the compiler, namely in the hlds->llds
and llds->C transformations for parallel conjunctions.
runtime/mercury_context.h:
runtime/mercury_context.c:
Created MR_do_join_and_continue procedure from old MR_join_and_continue
macro.
Created a new macro MR_join_and_continue that wraps the new procedure.
Added additional comments to this procedure, describing how it works.
compiler/llds.m:
Modified the LLDS data structure:
Removed the synchronization term parameter from the join_and_continue
instruction.
Added a new memory reference, one can now address data on the parent
context's stack.
compiler/par_conj_gen.m:
Modified the generation of the join and continue code. This now includes
instructions for saving a pointer to the synchronization term into MR_r1,
before calling MR_join_and_continue.
Added an XXX: How to I tell the low-level backend that I will clobber MR_r1
and MR_succip? Could someone familiar with the low-level backend help me?
compiler/llds_out_data.m:
Generate code for taking the address of something on the parent context's
stack.
compiler/llds_out_instr.m:
Alter the code generation for the join_and_continue instruction.
compiler/opt_util.m:
Conform to changes in llds.m.
Introduced an XXX: I don't know if join_and_continue use livevals. Can
someone familiar with this part of the compiler advise me?
compiler/code_util.m:
compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out_file.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/use_local_vars.m:
compiler/var_locn.m:
Conform to changes in llds.m
In some cases code has been re-factored to factor out code common to a
number of switch arms.
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.186
diff -u -p -b -r1.186 code_util.m
--- compiler/code_util.m 30 Oct 2009 03:33:12 -0000 1.186
+++ compiler/code_util.m 20 Nov 2009 10:30:53 -0000
@@ -383,6 +383,7 @@ lvals_in_lval(global_var_ref(_)) = [].
:- func lvals_in_mem_ref(mem_ref) = list(lval).
lvals_in_mem_ref(stackvar_ref(Rval)) = lvals_in_rval(Rval).
+lvals_in_mem_ref(parent_stackvar_ref(Rval)) = lvals_in_rval(Rval).
lvals_in_mem_ref(framevar_ref(Rval)) = lvals_in_rval(Rval).
lvals_in_mem_ref(heap_ref(Rval1, _, Rval2)) =
lvals_in_rval(Rval1) ++ lvals_in_rval(Rval2).
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.94
diff -u -p -b -r1.94 dupelim.m
--- compiler/dupelim.m 21 Oct 2009 06:36:18 -0000 1.94
+++ compiler/dupelim.m 22 Nov 2009 00:19:54 -0000
@@ -425,10 +425,6 @@ standardize_instr(Instr0, Instr) :-
standardize_lval(Lval0, Lval),
Instr = init_sync_term(Lval, N)
;
- Instr0 = join_and_continue(Lval0, Label),
- standardize_lval(Lval0, Lval),
- Instr = join_and_continue(Lval, Label)
- ;
( Instr0 = comment(_)
; Instr0 = livevals(_)
; Instr0 = block(_, _, _)
@@ -447,6 +443,7 @@ standardize_instr(Instr0, Instr) :-
; Instr0 = decr_sp_and_return(_)
; Instr0 = fork_new_child(_, _)
; Instr0 = foreign_proc_code(_, _, _, _, _, _, _, _, _, _)
+ ; Instr0 = join_and_continue(_)
),
Instr = Instr0
).
@@ -836,7 +833,7 @@ most_specific_instr(InstrA, InstrB, Mayb
; InstrA = foreign_proc_code(_, _, _, _, _, _, _, _, _, _)
; InstrA = fork_new_child(_, _)
; InstrA = init_sync_term(_, _)
- ; InstrA = join_and_continue(_, _)
+ ; InstrA = join_and_continue(_)
),
( InstrA = InstrB ->
MaybeInstr = yes(InstrA)
Index: compiler/dupproc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dupproc.m,v
retrieving revision 1.25
diff -u -p -b -r1.25 dupproc.m
--- compiler/dupproc.m 21 Oct 2009 06:36:18 -0000 1.25
+++ compiler/dupproc.m 22 Nov 2009 00:20:38 -0000
@@ -226,9 +226,9 @@ standardize_instr(Instr, StdInstr, DupPr
standardize_label(Child, StdChild, DupProcMap),
StdInstr = fork_new_child(Lval, StdChild)
;
- Instr = join_and_continue(Lval, Label),
+ Instr = join_and_continue(Label),
standardize_label(Label, StdLabel, DupProcMap),
- StdInstr = join_and_continue(Lval, StdLabel)
+ StdInstr = join_and_continue(StdLabel)
;
% The labels occurring in foreign_proc_code instructions
% cannot be substituted.
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.90
diff -u -p -b -r1.90 exprn_aux.m
--- compiler/exprn_aux.m 30 Oct 2009 03:33:13 -0000 1.90
+++ compiler/exprn_aux.m 22 Nov 2009 00:21:31 -0000
@@ -234,6 +234,8 @@ vars_in_lval(lvar(Var), [Var]).
vars_in_mem_ref(stackvar_ref(Rval), Vars) :-
vars_in_rval(Rval, Vars).
+vars_in_mem_ref(parent_stackvar_ref(Rval), Vars) :-
+ vars_in_rval(Rval, Vars).
vars_in_mem_ref(framevar_ref(Rval), Vars) :-
vars_in_rval(Rval, Vars).
vars_in_mem_ref(heap_ref(BaseRval, _Tag, FieldRval), BaseVars ++ FieldVars) :-
@@ -263,6 +265,7 @@ transform_lval_in_uinstr(Transform, Uins
; Uinstr0 = decr_sp(_)
; Uinstr0 = decr_sp_and_return(_)
; Uinstr0 = fork_new_child(_, _)
+ ; Uinstr0 = join_and_continue(_)
),
Uinstr = Uinstr0
;
@@ -404,10 +407,6 @@ transform_lval_in_uinstr(Transform, Uins
Uinstr0 = init_sync_term(Lval0, BranchCount),
Transform(Lval0, Lval, !Acc),
Uinstr = init_sync_term(Lval, BranchCount)
- ;
- Uinstr0 = join_and_continue(Lval0, Label),
- Transform(Lval0, Lval, !Acc),
- Uinstr = join_and_continue(Lval, Label)
).
:- pred transform_lval_in_component(transform_lval(T)::in(transform_lval),
@@ -514,6 +513,10 @@ transform_lval_in_mem_ref(Transform, Mem
transform_lval_in_rval(Transform, Rval0, Rval, !Acc),
MemRef = stackvar_ref(Rval)
;
+ MemRef0 = parent_stackvar_ref(Rval0),
+ transform_lval_in_rval(Transform, Rval0, Rval, !Acc),
+ MemRef = parent_stackvar_ref(Rval)
+ ;
MemRef0 = framevar_ref(Rval0),
transform_lval_in_rval(Transform, Rval0, Rval, !Acc),
MemRef = framevar_ref(Rval)
@@ -643,6 +646,9 @@ substitute_rval_in_mem_ref(OldRval, NewR
MemRef0 = stackvar_ref(N),
MemRef = stackvar_ref(N)
;
+ MemRef0 = parent_stackvar_ref(N),
+ MemRef = parent_stackvar_ref(N)
+ ;
MemRef0 = framevar_ref(N),
MemRef = framevar_ref(N)
;
@@ -870,6 +876,7 @@ lval_list_addrs([Lval | Lvals], CodeAddr
list(code_addr)::out, list(data_id)::out) is det.
mem_ref_addrs(stackvar_ref(_SlotNum), [], []).
+mem_ref_addrs(parent_stackvar_ref(_SlotNum), [], []).
mem_ref_addrs(framevar_ref(_SlotNum), [], []).
mem_ref_addrs(heap_ref(Rval, _Tag, _FieldNum), CodeAddrs, DataIds) :-
rval_addrs(Rval, CodeAddrs, DataIds).
Index: compiler/global_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/global_data.m,v
retrieving revision 1.43
diff -u -p -b -r1.43 global_data.m
--- compiler/global_data.m 30 Oct 2009 03:33:13 -0000 1.43
+++ compiler/global_data.m 22 Nov 2009 00:22:11 -0000
@@ -1020,10 +1020,6 @@ remap_instr(Remap, Instr0, Instr) :-
remap_lval(Remap, Lval0, Lval),
Instr = init_sync_term(Lval, NumJoins)
;
- Instr0 = join_and_continue(Lval0, Label),
- remap_lval(Remap, Lval0, Lval),
- Instr = join_and_continue(Lval, Label)
- ;
( Instr0 = comment(_)
; Instr0 = livevals(_)
; Instr0 = llcall(_, _, _, _, _, _)
@@ -1037,6 +1033,7 @@ remap_instr(Remap, Instr0, Instr) :-
; Instr0 = decr_sp(_)
; Instr0 = decr_sp_and_return(_)
; Instr0 = fork_new_child(_, _)
+ ; Instr0 = join_and_continue(_)
),
Instr = Instr0
).
@@ -1196,6 +1193,7 @@ remap_rval_const(Remap, Const0, Const) :
remap_mem_ref(Remap, MemRef0, MemRef) :-
(
( MemRef0 = stackvar_ref(_)
+ ; MemRef0 = parent_stackvar_ref(_)
; MemRef0 = framevar_ref(_)
),
MemRef = MemRef0
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.112
diff -u -p -b -r1.112 jumpopt.m
--- compiler/jumpopt.m 21 Oct 2009 06:36:19 -0000 1.112
+++ compiler/jumpopt.m 22 Nov 2009 00:23:22 -0000
@@ -798,12 +798,12 @@ jump_opt_instr_list([Instr0 | Instrs0],
NewRemain = specified([Instr], Instrs0)
)
;
- Uinstr0 = join_and_continue(SyncTerm, Label0),
+ Uinstr0 = join_and_continue(Label0),
short_label(Instrmap, Label0, Label),
( Label = Label0 ->
NewRemain = usual_case
;
- Uinstr = join_and_continue(SyncTerm, Label),
+ Uinstr = join_and_continue(Label),
Comment = Comment0 ++ " (redirect)",
Instr = llds_instr(Uinstr, Comment),
NewRemain = specified([Instr], Instrs0)
Index: compiler/livemap.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/livemap.m,v
retrieving revision 1.93
diff -u -p -b -r1.93 livemap.m
--- compiler/livemap.m 21 Oct 2009 06:36:19 -0000 1.93
+++ compiler/livemap.m 22 Nov 2009 00:27:54 -0000
@@ -350,7 +350,7 @@ livemap_do_build_instr(Instr0, !Instrs,
;
Uinstr0 = fork_new_child(_, _)
;
- Uinstr0 = join_and_continue(_, _)
+ Uinstr0 = join_and_continue(_)
;
Uinstr0 = arbitrary_c_code(AffectsLiveness, LiveLvalInfo, Code),
build_live_lval_info(AffectsLiveness, LiveLvalInfo, Code,
@@ -523,6 +523,8 @@ make_live_in_rval(mem_addr(MemRef), !Liv
make_live_in_mem_ref(stackvar_ref(Rval), !Live) :-
make_live_in_rval(Rval, !Live).
+make_live_in_mem_ref(parent_stackvar_ref(Rval), !Live) :-
+ make_live_in_rval(Rval, !Live).
make_live_in_mem_ref(framevar_ref(Rval), !Live) :-
make_live_in_rval(Rval, !Live).
make_live_in_mem_ref(heap_ref(Rval1, _, Rval2), !Live) :-
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.365
diff -u -p -b -r1.365 llds.m
--- compiler/llds.m 30 Oct 2009 03:33:14 -0000 1.365
+++ compiler/llds.m 22 Nov 2009 10:33:18 -0000
@@ -621,13 +621,15 @@
% the synchronisation term. Control continues at the next
% instruction.
- ; join_and_continue(lval, label).
+ ; join_and_continue(label).
% Signal that this thread of execution has finished in the current
% parallel conjunct. For details of how we at the end of a parallel
- % conjunct see runtime/mercury_context.{c,h}.
- % The synchronisation term is specified by the given lval.
- % The label gives the address of the code following the parallel
- % conjunction.
+ % conjunct see runtime/mercury_context.{c,h}. The value in MR_r1
+ % points to The synchronisation term. The label gives the address
+ % of the code following the parallel conjunction. The
+ % MR_join_and_continue macro loads the address of the label into
+ % MR_succip before jumping to the implementation of
+ % MR_do_join_and_continue.
:- type stack_incr_kind
---> stack_incr_leaf % The incr_sp creates the stack frame
@@ -1129,8 +1131,9 @@
% stack.
:- type mem_ref
- ---> stackvar_ref(rval) % Stack slot number.
- ; framevar_ref(rval) % Stack slot number.
+ ---> stackvar_ref(rval) % Det stack slot number.
+ ; parent_stackvar_ref(rval) % Parent's det stack slot number.
+ ; framevar_ref(rval) % Nondet stack slot number.
; heap_ref(rval, int, rval). % The cell pointer, the tag to
% subtract, and the field number.
Index: compiler/llds_out_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out_data.m,v
retrieving revision 1.1
diff -u -p -b -r1.1 llds_out_data.m
--- compiler/llds_out_data.m 4 Nov 2009 03:44:48 -0000 1.1
+++ compiler/llds_out_data.m 20 Nov 2009 10:52:12 -0000
@@ -756,6 +756,7 @@ output_record_mem_ref_decls_format(Info,
!N, !DeclSet, !IO) :-
(
( MemRef = stackvar_ref(Rval)
+ ; MemRef = parent_stackvar_ref(Rval)
; MemRef = framevar_ref(Rval)
),
output_record_rval_decls_format(Info, Rval,
@@ -957,18 +958,16 @@ output_rval(Info, Rval, !IO) :-
;
Rval = mem_addr(MemRef),
(
+ (
MemRef = stackvar_ref(SubRval),
- io.write_string("&MR_sv(", !IO),
- % Don't clutter the output with unnecessary casts.
- ( SubRval = const(llconst_int(SlotNum)) ->
- io.write_int(SlotNum, !IO)
+ io.write_string("&MR_sv(", !IO)
;
- output_rval_as_type(Info, SubRval, lt_integer, !IO)
- ),
- io.write_string(")", !IO)
+ MemRef = parent_stackvar_ref(SubRval),
+ io.write_string("&MR_parent_sv(", !IO)
;
MemRef = framevar_ref(SubRval),
- io.write_string("&MR_fv(", !IO),
+ io.write_string("&MR_fv(", !IO)
+ ),
% Don't clutter the output with unnecessary casts.
( SubRval = const(llconst_int(SlotNum)) ->
io.write_int(SlotNum, !IO)
Index: compiler/llds_out_file.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out_file.m,v
retrieving revision 1.1
diff -u -p -b -r1.1 llds_out_file.m
--- compiler/llds_out_file.m 4 Nov 2009 03:44:48 -0000 1.1
+++ compiler/llds_out_file.m 22 Nov 2009 00:28:30 -0000
@@ -1134,7 +1134,7 @@ find_cont_labels([Instr | Instrs], !Cont
;
Uinstr = mkframe(_, yes(code_label(ContLabel)))
;
- Uinstr = join_and_continue(_, ContLabel)
+ Uinstr = join_and_continue(ContLabel)
;
Uinstr = assign(redoip_slot(_), const(Const)),
Const = llconst_code_addr(code_label(ContLabel))
Index: compiler/llds_out_instr.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out_instr.m,v
retrieving revision 1.1
diff -u -p -b -r1.1 llds_out_instr.m
--- compiler/llds_out_instr.m 4 Nov 2009 03:44:48 -0000 1.1
+++ compiler/llds_out_instr.m 22 Nov 2009 00:38:03 -0000
@@ -233,8 +233,7 @@ output_record_instr_decls(Info, Instr, !
output_record_lval_decls(Info, Lval, !DeclSet, !IO),
output_record_code_addr_decls(Info, code_label(Child), !DeclSet, !IO)
;
- Instr = join_and_continue(Lval, Label),
- output_record_lval_decls(Info, Lval, !DeclSet, !IO),
+ Instr = join_and_continue(Label),
output_record_code_addr_decls(Info, code_label(Label), !DeclSet, !IO)
).
@@ -905,10 +904,8 @@ output_instruction(Info, Instr, ProfInfo
output_label_as_code_addr(Child, !IO),
io.write_string(");\n", !IO)
;
- Instr = join_and_continue(Lval, Label),
+ Instr = join_and_continue(Label),
io.write_string("\tMR_join_and_continue(", !IO),
- output_lval(Info, Lval, !IO),
- io.write_string(", ", !IO),
output_label_as_code_addr(Label, !IO),
io.write_string(");\n", !IO)
).
Index: compiler/llds_to_x86_64.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_to_x86_64.m,v
retrieving revision 1.13
diff -u -p -b -r1.13 llds_to_x86_64.m
--- compiler/llds_to_x86_64.m 4 Nov 2009 03:44:48 -0000 1.13
+++ compiler/llds_to_x86_64.m 22 Nov 2009 00:29:49 -0000
@@ -438,7 +438,7 @@ instr_to_x86_64(!RegMap, init_sync_term(
Instr = [x86_64_comment("<<init_sync_term>>")].
instr_to_x86_64(!RegMap, fork_new_child(_, _), Instr) :-
Instr = [x86_64_comment("<<fork_new_child>>")].
-instr_to_x86_64(!RegMap, join_and_continue(_, _), Instr) :-
+instr_to_x86_64(!RegMap, join_and_continue(_), Instr) :-
Instr = [x86_64_comment("<<join_and_continue>>")].
% Transform lval into either an x86_64 operand or x86_64 instructions.
@@ -700,6 +700,8 @@ transform_rval(!RegMap, binop(Op, Rval1,
).
transform_rval(!RegMap, mem_addr(stackvar_ref(Rval)), Op, no) :-
transform_rval(!RegMap, Rval, Op, _).
+transform_rval(!RegMap, mem_addr(parent_stackvar_ref(Rval)), Op, no) :-
+ transform_rval(!RegMap, Rval, Op, _).
transform_rval(!RegMap, mem_addr(framevar_ref(Rval)), Op, no) :-
transform_rval(!RegMap, Rval, Op, _).
transform_rval(!RegMap, mem_addr(heap_ref(Rval1, Tag, Rval2)), no, Instrs) :-
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/middle_rec.m,v
retrieving revision 1.139
diff -u -p -b -r1.139 middle_rec.m
--- compiler/middle_rec.m 21 Oct 2009 06:36:20 -0000 1.139
+++ compiler/middle_rec.m 22 Nov 2009 00:33:02 -0000
@@ -529,6 +529,7 @@ find_used_registers_instr(Uinstr, !Used)
; Uinstr = incr_sp(_, _, _)
; Uinstr = decr_sp(_)
; Uinstr = decr_sp_and_return(_)
+ ; Uinstr = join_and_continue(_)
)
;
Uinstr = livevals(LvalSet),
@@ -595,7 +596,6 @@ find_used_registers_instr(Uinstr, !Used)
; Uinstr = mark_ticket_stack(Lval)
; Uinstr = init_sync_term(Lval, _)
; Uinstr = fork_new_child(Lval, _)
- ; Uinstr = join_and_continue(Lval, _)
),
find_used_registers_lval(Lval, !Used)
).
@@ -676,6 +676,8 @@ find_used_registers_rval(Rval, !Used) :-
find_used_registers_mem_ref(stackvar_ref(Rval), !Used) :-
find_used_registers_rval(Rval, !Used).
+find_used_registers_mem_ref(parent_stackvar_ref(Rval), !Used) :-
+ find_used_registers_rval(Rval, !Used).
find_used_registers_mem_ref(framevar_ref(Rval), !Used) :-
find_used_registers_rval(Rval, !Used).
find_used_registers_mem_ref(heap_ref(Rval1, _, Rval2), !Used) :-
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.214
diff -u -p -b -r1.214 opt_debug.m
--- compiler/opt_debug.m 4 Nov 2009 03:44:49 -0000 1.214
+++ compiler/opt_debug.m 22 Nov 2009 00:24:23 -0000
@@ -354,6 +354,8 @@ dump_rvals(MaybeProcLabel, [Rval | Rvals
dump_mem_ref(MaybeProcLabel, stackvar_ref(N)) =
"stackvar_ref(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_mem_ref(MaybeProcLabel, parent_stackvar_ref(N)) =
+ "parent_stackvar_ref(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
dump_mem_ref(MaybeProcLabel, framevar_ref(N)) =
"framevar_ref(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
dump_mem_ref(MaybeProcLabel, heap_ref(R, T, N)) =
@@ -1027,9 +1029,8 @@ dump_instr(MaybeProcLabel, AutoComments,
Str = "fork_new_child(" ++ dump_lval(MaybeProcLabel, Lval)
++ dump_label(MaybeProcLabel, Child) ++ ", " ++ ")"
;
- Instr = join_and_continue(Lval, Label),
- Str = "join_and_continue(" ++ dump_lval(MaybeProcLabel, Lval) ++ ", "
- ++ dump_label(MaybeProcLabel, Label) ++ ")"
+ Instr = join_and_continue(Label),
+ Str = "join_and_continue(" ++ dump_label(MaybeProcLabel, Label) ++ ")"
;
Instr = foreign_proc_code(Decls, Comps, MCM, MFNL, MFL, MFOL, MNF, MDL,
SSR, MD),
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.171
diff -u -p -b -r1.171 opt_util.m
--- compiler/opt_util.m 21 Oct 2009 06:36:21 -0000 1.171
+++ compiler/opt_util.m 22 Nov 2009 10:35:36 -0000
@@ -736,6 +736,7 @@ lval_refers_stackvars(global_var_ref(_))
:- func mem_ref_refers_stackvars(mem_ref) = bool.
mem_ref_refers_stackvars(stackvar_ref(_)) = yes.
+mem_ref_refers_stackvars(parent_stackvar_ref(_)) = yes.
mem_ref_refers_stackvars(framevar_ref(_)) = yes.
mem_ref_refers_stackvars(heap_ref(Rval1, _, Rval2)) =
bool.or(rval_refers_stackvars(Rval1), rval_refers_stackvars(Rval2)).
@@ -887,7 +888,7 @@ instr_refers_to_stack(llds_instr(Uinstr,
; Uinstr = decr_sp_and_return(_)
; Uinstr = init_sync_term(_, _)
; Uinstr = fork_new_child(_, _)
- ; Uinstr = join_and_continue(_, _)
+ ; Uinstr = join_and_continue(_)
),
Refers = yes
;
@@ -1111,7 +1112,7 @@ can_instr_branch_away(decr_sp(_)) = no.
can_instr_branch_away(decr_sp_and_return(_)) = yes.
can_instr_branch_away(init_sync_term(_, _)) = no.
can_instr_branch_away(fork_new_child(_, _)) = no.
-can_instr_branch_away(join_and_continue(_, _)) = yes.
+can_instr_branch_away(join_and_continue(_)) = yes.
can_instr_branch_away(foreign_proc_code(_, Comps, _, _, _, _, _, _, _, _)) =
can_components_branch_away(Comps).
@@ -1190,7 +1191,7 @@ can_instr_fall_through(decr_sp(_)) = yes
can_instr_fall_through(decr_sp_and_return(_)) = no.
can_instr_fall_through(init_sync_term(_, _)) = yes.
can_instr_fall_through(fork_new_child(_, _)) = yes.
-can_instr_fall_through(join_and_continue(_, _)) = no.
+can_instr_fall_through(join_and_continue(_)) = no.
can_instr_fall_through(foreign_proc_code(_, _, _, _, _, _, _, _, _, _)) = yes.
% Check whether an instruction sequence can possibly fall through
@@ -1241,7 +1242,9 @@ can_use_livevals(decr_sp(_), no).
can_use_livevals(decr_sp_and_return(_), yes).
can_use_livevals(init_sync_term(_, _), no).
can_use_livevals(fork_new_child(_, _), no).
-can_use_livevals(join_and_continue(_, _), no).
+% XXX: Is the synchronization term (now in R1) a liveval?, I don't want the
+% move to be optimized away. -pbone
+can_use_livevals(join_and_continue(_), no).
can_use_livevals(foreign_proc_code(_, _, _, _, _, _, _, _, _, _), no).
instr_labels(Instr, Labels, CodeAddrs) :-
@@ -1314,7 +1317,7 @@ instr_labels_2(Uinstr, Labels, CodeAddrs
Labels = [Child],
CodeAddrs = []
;
- Uinstr = join_and_continue(_, Label),
+ Uinstr = join_and_continue(Label),
Labels = [Label],
CodeAddrs = []
;
@@ -1404,7 +1407,7 @@ possible_targets(Uinstr, Labels, CodeAdd
% XXX see the comment in instr_labels_2.
unexpected(this_file, "possible_targets: decr_sp_and_return")
;
- Uinstr = join_and_continue(_, Label),
+ Uinstr = join_and_continue(Label),
Labels = [Label],
CodeAddrs = []
;
@@ -1544,7 +1547,7 @@ instr_rvals_and_lvals(decr_sp(_), [], []
instr_rvals_and_lvals(decr_sp_and_return(_), [], []).
instr_rvals_and_lvals(init_sync_term(Lval, _), [], [Lval]).
instr_rvals_and_lvals(fork_new_child(Lval, _), [], [Lval]).
-instr_rvals_and_lvals(join_and_continue(Lval, _), [], [Lval]).
+instr_rvals_and_lvals(join_and_continue(_), [], []).
instr_rvals_and_lvals(foreign_proc_code(_, Cs, _, _, _, _, _, _, _, _),
Rvals, Lvals) :-
foreign_proc_components_get_rvals_and_lvals(Cs, Rvals, Lvals).
@@ -1724,8 +1727,7 @@ count_temps_instr(init_sync_term(Lval, _
count_temps_lval(Lval, !R, !F).
count_temps_instr(fork_new_child(Lval, _), !R, !F) :-
count_temps_lval(Lval, !R, !F).
-count_temps_instr(join_and_continue(Lval, _), !R, !F) :-
- count_temps_lval(Lval, !R, !F).
+count_temps_instr(join_and_continue(_), !R, !F).
count_temps_instr(foreign_proc_code(_, Comps, _, _, _, _, _, _, _, _),
!R, !F) :-
count_temps_components(Comps, !R, !F).
@@ -1855,6 +1857,7 @@ count_temps_rval(Rval, !R, !F) :-
count_temps_mem_ref(MemRef, !R, !F) :-
(
( MemRef = stackvar_ref(Rval)
+ ; MemRef = parent_stackvar_ref(Rval)
; MemRef = framevar_ref(Rval)
),
count_temps_rval(Rval, !R, !F)
@@ -1933,7 +1936,7 @@ touches_nondet_ctrl_instr(Uinstr) = Touc
; Uinstr = restore_maxfr(_)
; Uinstr = init_sync_term(_, _) % This is a safe approximation.
; Uinstr = fork_new_child(_, _) % This is a safe approximation.
- ; Uinstr = join_and_continue(_, _) % This is a safe approximation.
+ ; Uinstr = join_and_continue(_) % This is a safe approximation.
),
Touch = yes
;
@@ -2064,6 +2067,7 @@ touches_nondet_ctrl_rval(mem_addr(MemRef
:- func touches_nondet_ctrl_mem_ref(mem_ref) = bool.
touches_nondet_ctrl_mem_ref(stackvar_ref(_)) = no.
+touches_nondet_ctrl_mem_ref(parent_stackvar_ref(_)) = no.
touches_nondet_ctrl_mem_ref(framevar_ref(_)) = no.
touches_nondet_ctrl_mem_ref(heap_ref(Rval, _, _)) =
touches_nondet_ctrl_rval(Rval).
@@ -2497,10 +2501,9 @@ replace_labels_instr(Uinstr0, Uinstr, Re
replace_labels_label(Child0, Child, ReplMap),
Uinstr = fork_new_child(Lval, Child)
;
- Uinstr0 = join_and_continue(Lval0, Label0),
+ Uinstr0 = join_and_continue(Label0),
replace_labels_label(Label0, Label, ReplMap),
- replace_labels_lval(Lval0, Lval, ReplMap),
- Uinstr = join_and_continue(Lval, Label)
+ Uinstr = join_and_continue(Label)
;
Uinstr0 = foreign_proc_code(Decls, Comps0, MayCallMercury,
MaybeFix, MaybeLayout, MaybeOnlyLayout, MaybeSub0, MaybeDef,
@@ -2693,6 +2696,7 @@ replace_labels_rval(Rval0, Rval, ReplMap
replace_labels_mem_ref(MemRef0, MemRef, ReplMap) :-
(
( MemRef0 = stackvar_ref(_)
+ ; MemRef0 = parent_stackvar_ref(_)
; MemRef0 = framevar_ref(_)
),
MemRef = MemRef0
Index: compiler/par_conj_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/par_conj_gen.m,v
retrieving revision 1.40
diff -u -p -b -r1.40 par_conj_gen.m
--- compiler/par_conj_gen.m 3 Sep 2009 23:07:28 -0000 1.40
+++ compiler/par_conj_gen.m 23 Nov 2009 03:05:41 -0000
@@ -186,11 +186,11 @@ generate_par_conj(Goals, GoalInfo, CodeM
(
% The highest numbered slot has the lowest address.
list.last(SyncTermSlots, SyncTermBaseSlotPrime),
- SyncTermBaseSlotPrime = stackvar(SlotNum),
+ SyncTermBaseSlotPrime = stackvar(SlotNumPrime),
StackId = det_stack
->
SyncTermBaseSlot = SyncTermBaseSlotPrime,
- ParentSyncTermBaseSlot = parent_stackvar(SlotNum)
+ SlotNum = SlotNumPrime
;
unexpected(this_file, "generate_par_conj")
),
@@ -204,8 +204,8 @@ generate_par_conj(Goals, GoalInfo, CodeM
set_par_conj_depth(Depth+1, !CI),
get_next_label(EndLabel, !CI),
clear_all_registers(no, !CI),
- generate_det_par_conj_2(Goals, ParentSyncTermBaseSlot, EndLabel, Initial,
- no, GoalCode, !CI),
+ generate_det_par_conj_2(Goals, SlotNum, EndLabel, Initial, no, GoalCode,
+ !CI),
set_par_conj_depth(Depth, !CI),
EndLabelCode = singleton(
@@ -252,12 +252,12 @@ generate_par_conj(Goals, GoalInfo, CodeM
place_all_outputs(Outputs, !CI).
:- pred generate_det_par_conj_2(list(hlds_goal)::in,
- lval::in, label::in, instmap::in, branch_end::in, llds_code::out,
+ int::in, label::in, instmap::in, branch_end::in, llds_code::out,
code_info::in, code_info::out) is det.
-generate_det_par_conj_2([], _ParentSyncTermBaseSlot, _EndLabel,
+generate_det_par_conj_2([], _ParentSyncTermBaseSlotNum, _EndLabel,
_Initial, _, empty, !CI).
-generate_det_par_conj_2([Goal | Goals], ParentSyncTermBaseSlot, EndLabel,
+generate_det_par_conj_2([Goal | Goals], ParentSyncTermBaseSlotNum, EndLabel,
Initial, MaybeEnd0, Code, !CI) :-
remember_position(!.CI, StartPos),
code_gen.generate_goal(model_det, Goal, ThisGoalCode0, !CI),
@@ -271,6 +271,18 @@ generate_det_par_conj_2([Goal | Goals],
generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd, SaveCode0, !CI),
replace_stack_vars_by_parent_sv(SaveCode0, SaveCode),
+ ParentSyncTermBaseSlot = parent_stackvar(ParentSyncTermBaseSlotNum),
+ SyncTermPointer = mem_addr(parent_stackvar_ref(
+ const(llconst_int(ParentSyncTermBaseSlotNum)))),
+ % The move instruction clobbers MR_r1,
+ % The join_and_continue instruction clobbers MR_succip.
+ % XXX: How do I tell the low-level backend that I want to use these
+ % registers and arrange for anything important to be saved? -pbone
+ JoinInstructions = [
+ llds_instr(assign(reg(reg_r, 1), SyncTermPointer),
+ "Put the address of the sync term in r1"),
+ llds_instr(join_and_continue(EndLabel),
+ "Join after parallel execution")],
(
Goals = [_ | _],
get_next_label(NextConjunct, !CI),
@@ -279,22 +291,17 @@ generate_det_par_conj_2([Goal | Goals],
llds_instr(fork_new_child(ParentSyncTermBaseSlot, NextConjunct),
"fork off a child")
),
- JoinCode = from_list([
- llds_instr(join_and_continue(ParentSyncTermBaseSlot, EndLabel),
- "finish"),
- llds_instr(label(NextConjunct),
- "start of the next conjunct")
- ])
+ JoinCode = from_list( JoinInstructions ++
+ [llds_instr(label(NextConjunct),
+ "start of the next conjunct")]
+ )
;
Goals = [],
ForkCode = empty,
- JoinCode = singleton(
- llds_instr(join_and_continue(ParentSyncTermBaseSlot, EndLabel),
- "finish")
- )
+ JoinCode = from_list(JoinInstructions)
),
ThisCode = ForkCode ++ ThisGoalCode ++ SaveCode ++ JoinCode,
- generate_det_par_conj_2(Goals, ParentSyncTermBaseSlot, EndLabel, Initial,
+ generate_det_par_conj_2(Goals, ParentSyncTermBaseSlotNum, EndLabel, Initial,
MaybeEnd, RestCode, !CI),
Code = ThisCode ++ RestCode.
Index: compiler/reassign.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/reassign.m,v
retrieving revision 1.30
diff -u -p -b -r1.30 reassign.m
--- compiler/reassign.m 21 Oct 2009 06:36:21 -0000 1.30
+++ compiler/reassign.m 22 Nov 2009 00:24:53 -0000
@@ -320,7 +320,7 @@ remove_reassign_loop([Instr0 | Instrs0],
!:KnownContentsMap = map.init,
!:DepLvalMap = map.init
;
- Uinstr0 = join_and_continue(_, _),
+ Uinstr0 = join_and_continue(_),
!:RevInstrs = [Instr0 | !.RevInstrs],
% Other threads may modify any lval.
!:KnownContentsMap = map.init,
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.40
diff -u -p -b -r1.40 use_local_vars.m
--- compiler/use_local_vars.m 21 Oct 2009 06:36:22 -0000 1.40
+++ compiler/use_local_vars.m 22 Nov 2009 00:25:11 -0000
@@ -690,7 +690,7 @@ substitute_lval_in_instr_until_defn_2(Ol
; Uinstr0 = decr_sp_and_return(_)
; Uinstr0 = init_sync_term(_, _)
; Uinstr0 = fork_new_child(_, _)
- ; Uinstr0 = join_and_continue(_, _)
+ ; Uinstr0 = join_and_continue(_)
; Uinstr0 = arbitrary_c_code(_, _, _)
)
).
Index: compiler/var_locn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/var_locn.m,v
retrieving revision 1.68
diff -u -p -b -r1.68 var_locn.m
--- compiler/var_locn.m 2 Sep 2009 00:30:24 -0000 1.68
+++ compiler/var_locn.m 20 Nov 2009 21:52:41 -0000
@@ -2270,11 +2270,9 @@ var_locn_materialize_vars_in_rval_avoid(
var_locn_materialize_vars_in_mem_ref_avoid(ModuleInfo, MemRef0, MemRef, Avoid,
Code, !VLI) :-
(
- MemRef0 = stackvar_ref(_),
- MemRef = MemRef0,
- Code = empty
- ;
- MemRef0 = framevar_ref(_),
+ ( MemRef0 = stackvar_ref(_)
+ ; MemRef0 = parent_stackvar_ref(_)
+ ; MemRef0 = framevar_ref(_) ),
MemRef = MemRef0,
Code = empty
;
Index: runtime/mercury_context.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_context.c,v
retrieving revision 1.70
diff -u -p -b -r1.70 mercury_context.c
--- runtime/mercury_context.c 6 Nov 2009 05:40:24 -0000 1.70
+++ runtime/mercury_context.c 23 Nov 2009 02:56:02 -0000
@@ -811,9 +811,10 @@ MR_schedule_spark_globally(const MR_Spar
#ifndef MR_HIGHLEVEL_CODE
+
MR_define_extern_entry(MR_do_runnext);
-MR_BEGIN_MODULE(scheduler_module)
+MR_BEGIN_MODULE(scheduler_module_do_runnext)
MR_init_entry_an(MR_do_runnext);
MR_BEGIN_CODE
@@ -983,6 +984,133 @@ MR_define_entry(MR_do_runnext);
MR_END_MODULE
+#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ)
+MR_define_extern_entry(MR_do_join_and_continue);
+
+MR_BEGIN_MODULE(scheduler_module_do_join_and_continue)
+ MR_init_entry_an(MR_do_join_and_continue);
+MR_BEGIN_CODE
+
+MR_define_entry(MR_do_join_and_continue);
+{
+ MR_SyncTerm *jnc_st = (MR_SyncTerm *) MR_r1;
+
+ if (!jnc_st->MR_st_is_shared) {
+ /* This parallel conjunction has only executed sequentially. */
+ if (--jnc_st->MR_st_count == 0) {
+ /*
+ ** It has finished executing, continue execution from the join
+ ** label.
+ */
+ MR_proceed();
+ } else {
+ /*
+ ** It has not finished executing. Try to finish it by executing
+ ** our sparks.
+ ** This code was formerly MR_join_and_continue_1()
+ */
+ MR_Context *jnc_ctxt;
+ MR_bool jnc_popped;
+ MR_Spark jnc_spark;
+
+ jnc_ctxt = MR_ENGINE(MR_eng_this_context);
+ jnc_popped = MR_wsdeque_pop_bottom(&jnc_ctxt->MR_ctxt_spark_deque,
+ &jnc_spark);
+ if (jnc_popped) {
+ MR_atomic_dec_int(&MR_num_outstanding_contexts_and_all_sparks);
+ MR_GOTO(jnc_spark.MR_spark_resume);
+ } else {
+ /*
+ ** Someone's stolen our sparks, we should try to execute
+ ** something that's been scheduled globally.
+ */
+ MR_runnext();
+ }
+ }
+ } else {
+ /* This parallel conjunction may be executing in parallel. */
+ MR_LOCK(&MR_sync_term_lock, "continue");
+ if (--jnc_st->MR_st_count == 0) {
+ /* This parallel conjunction has finished. */
+ if (MR_ENGINE(MR_eng_this_context) == jnc_st->MR_st_orig_context) {
+ /*
+ ** This context originated this parallel conjunction and all
+ ** the branches have finished so jump to the join label.
+ */
+ MR_UNLOCK(&MR_sync_term_lock, "continue i");
+ MR_proceed();
+ } else {
+ /*
+ ** This context didn't originate this parallel conjunction and
+ ** we're the last branch to finish. The originating context
+ ** should be suspended waiting for us to finish, so wake it up.
+ */
+ jnc_st->MR_st_orig_context->MR_ctxt_resume = (MR_Code*)MR_succip;
+ MR_schedule_context(jnc_st->MR_st_orig_context);
+ MR_UNLOCK(&MR_sync_term_lock, "continue ii");
+ MR_runnext();
+ }
+ } else {
+ /*
+ ** The parallel conjunction is being executed in parallel but it is
+ ** not yet finished. This code was Formerly
+ ** MR_join_and_continue_2()
+ */
+ MR_Context *jnc_ctxt;
+ MR_bool jnc_popped;
+ MR_Spark jnc_spark;
+
+ jnc_ctxt = MR_ENGINE(MR_eng_this_context);
+ jnc_popped = MR_wsdeque_pop_bottom(&jnc_ctxt->MR_ctxt_spark_deque,
+ &jnc_spark);
+ if (jnc_popped && (jnc_spark.MR_spark_parent_sp == MR_parent_sp)) {
+ /*
+ ** The spark at the top of the stack is from to the same parallel
+ ** conjunction that we've just been executing. We can immediately
+ ** execute the next branch of the same parallel conjunction in
+ ** the current context.
+ */
+ MR_UNLOCK(&MR_sync_term_lock, "continue_2 i");
+ MR_atomic_dec_int(&MR_num_outstanding_contexts_and_all_sparks);
+ MR_GOTO(jnc_spark.MR_spark_resume);
+ } else {
+ /*
+ ** The spark stack is empty or the next spark is from a different
+ ** parallel conjunction to the one we've been executing. Either
+ ** way, there's nothing more we can do with this context right
+ ** now. Put back the spark we won't be using.
+ */
+ if (jnc_popped) {
+ MR_wsdeque_putback_bottom(&jnc_ctxt->MR_ctxt_spark_deque,
+ &jnc_spark);
+ }
+ /*
+ ** If this context originated the parallel conjunction we've been
+ ** executing, the rest of the parallel conjunction must have been
+ ** put on the global spark queue to be executed in other
+ ** contexts. This context will need to be resumed once the
+ ** parallel conjunction is completed, so suspend the context.
+ **
+ ** What if the other conjuncts where put on the global queue
+ ** but haven't yet been taken by other threads? Then this step
+ ** is redundant. It's not worth fixing, this problem will go
+ ** away once we enable work-stealing. - pbone.
+ */
+ if (jnc_ctxt == jnc_st->MR_st_orig_context) {
+ MR_save_context(jnc_ctxt);
+ MR_ENGINE(MR_eng_this_context) = NULL;
+ }
+ /* Finally look for other work. */
+ MR_UNLOCK(&MR_sync_term_lock, "continue_2 ii");
+ MR_runnext();
+ }
+ }
+ }
+}
+MR_END_MODULE
+
+#endif /* defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) */
+
#endif /* !MR_HIGHLEVEL_CODE */
#ifdef MR_LL_PARALLEL_CONJ
@@ -1051,7 +1179,10 @@ void mercury_sys_init_scheduler_wrapper_
void mercury_sys_init_scheduler_wrapper_init(void)
{
#ifndef MR_HIGHLEVEL_CODE
- scheduler_module();
+ scheduler_module_do_runnext();
+#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ)
+ scheduler_module_do_join_and_continue();
+#endif
#endif
}
Index: runtime/mercury_context.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_context.h,v
retrieving revision 1.55
diff -u -p -b -r1.55 mercury_context.h
--- runtime/mercury_context.h 17 Nov 2009 06:30:26 -0000 1.55
+++ runtime/mercury_context.h 22 Nov 2009 06:33:40 -0000
@@ -811,111 +811,19 @@ extern void MR_schedule_context(
MR_atomic_inc_int(&MR_num_outstanding_contexts_and_all_sparks); \
} while (0)
- #define MR_join_and_continue(sync_term, join_label) \
- do { \
- MR_SyncTerm *jnc_st = (MR_SyncTerm *) &sync_term; \
- \
- if (!jnc_st->MR_st_is_shared) { \
- /* This parallel conjunction has only executed sequentially. */ \
- if (--jnc_st->MR_st_count == 0) { \
- MR_GOTO(join_label); \
- } else { \
- MR_join_and_continue_1(); \
- } \
- } else { \
- /* This parallel conjunction may be executing in parallel. */ \
- MR_LOCK(&MR_sync_term_lock, "continue"); \
- if (--jnc_st->MR_st_count == 0) { \
- if (MR_ENGINE(MR_eng_this_context) \
- == jnc_st->MR_st_orig_context) \
- { \
- /* \
- ** This context originated this parallel conjunction and \
- ** all the branches have finished so jump to the join \
- ** label. \
- */ \
- MR_UNLOCK(&MR_sync_term_lock, "continue i"); \
- MR_GOTO(join_label); \
- } else { \
- /* \
- ** This context didn't originate this parallel \
- ** conjunction and we're the last branch to finish. The \
- ** originating context should be suspended waiting for us \
- ** to finish, so wake it up. \
- */ \
- jnc_st->MR_st_orig_context->MR_ctxt_resume = join_label; \
- MR_schedule_context(jnc_st->MR_st_orig_context); \
- MR_UNLOCK(&MR_sync_term_lock, "continue ii"); \
- MR_runnext(); \
- } \
- } else { \
- MR_join_and_continue_2(); \
- } \
- } \
- } while (0)
-
- #define MR_join_and_continue_1() \
- do { \
- MR_Context *jnc_ctxt; \
- MR_bool jnc_popped; \
- MR_Spark jnc_spark; \
- \
- jnc_ctxt = MR_ENGINE(MR_eng_this_context); \
- jnc_popped = MR_wsdeque_pop_bottom(&jnc_ctxt->MR_ctxt_spark_deque, \
- &jnc_spark); \
- if (jnc_popped) { \
- MR_atomic_dec_int(&MR_num_outstanding_contexts_and_all_sparks); \
- MR_GOTO(jnc_spark.MR_spark_resume); \
- } else { \
- MR_runnext(); \
- } \
- } while (0)
-
- #define MR_join_and_continue_2() \
+ /*
+ ** At the end of a parallel conjunct this is called, depending on which
+ ** context calls this the context may block, jump to the join label or look
+ ** for other parallel work.
+ ** The arguments are:
+ ** MR_r1 - sync term pointer.
+ ** MR_succip - join label.
+ */
+ MR_declare_entry(MR_do_join_and_continue);
+ #define MR_join_and_continue(label) \
do { \
- MR_Context *jnc_ctxt; \
- MR_bool jnc_popped; \
- MR_Spark jnc_spark; \
- \
- jnc_ctxt = MR_ENGINE(MR_eng_this_context); \
- jnc_popped = MR_wsdeque_pop_bottom(&jnc_ctxt->MR_ctxt_spark_deque, \
- &jnc_spark); \
- if (jnc_popped && (jnc_spark.MR_spark_parent_sp == MR_parent_sp)) { \
- /* \
- ** The spark at the top of the stack is due to the same parallel \
- ** conjunction that we've just been executing. We can immediately \
- ** execute the next branch of the same parallel conjunction in \
- ** the current context. \
- */ \
- MR_UNLOCK(&MR_sync_term_lock, "continue_2 i"); \
- MR_atomic_dec_int(&MR_num_outstanding_contexts_and_all_sparks); \
- MR_GOTO(jnc_spark.MR_spark_resume); \
- } else { \
- /* \
- ** The spark stack is empty or the next spark is from a different \
- ** parallel conjunction to the one we've been executing. Either \
- ** way, there's nothing more we can do with this context right \
- ** now. Put back the spark we won't be using. \
- */ \
- if (jnc_popped) { \
- MR_wsdeque_putback_bottom(&jnc_ctxt->MR_ctxt_spark_deque, \
- &jnc_spark); \
- } \
- /* \
- ** If this context originated the parallel conjunction we've been \
- ** executing, the rest of the parallel conjunction must have been \
- ** put on the global spark queue to be executed in other \
- ** contexts. This context will need to be resumed once the \
- ** parallel conjunction is completed, so suspend the context. \
- */ \
- if (jnc_ctxt == jnc_st->MR_st_orig_context) { \
- MR_save_context(jnc_ctxt); \
- MR_ENGINE(MR_eng_this_context) = NULL; \
- } \
- /* Finally look for other work. */ \
- MR_UNLOCK(&MR_sync_term_lock, "continue_2 ii"); \
- MR_runnext(); \
- } \
+ MR_succip_word = label; \
+ MR_GOTO(MR_ENTRY(MR_do_join_and_continue)); \
} while (0)
/* This needs to come after the definition of MR_SparkDeque_Struct. */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20091123/7b49eb75/attachment.sig>
More information about the reviews
mailing list