[m-rev.] for post-commit review: another step for own stack tabling

Zoltan Somogyi zs at csse.unimelb.edu.au
Wed Jan 3 16:15:44 AEDT 2007


For review by anyone.

Simon, do you remember why the default value of the cflags_for_debug option
does not include -O0?

Zoltan.

Implement a large chunk of the code that was previously missing for .mmos
grades. The system now correctly computes several answers for the tc_minimal
test case, before going into an infinite loop (since the code for recognizing
the absence of further solutions is not yet there).

Significantly improve the infrastructure for debugging such changes.

compiler/table_gen.m:
	Complete the mmos transformation.

compiler/proc_gen.m:
	Handle the special return requirements of mmos generators, which must
	return not to a caller (since each generator is the root of its own
	SLD tree), but to a consumer in another SLD tree that is waiting for an
	answer.

compiler/hlds_pred.m:
	Provide a mechanism whereby table_gen.m can communicate to proc_gen.m
	the requirement for this special return.

compiler/trace_gen.m:
	When generating events, include the port and the goal path in a
	comment. This makes the generated C code significantly easier to
	understand.

compiler/layout_out.m:
	Export a function for trace_gen.m to use.

compiler/hlds_goal.m:
	Change goal_path_to_string to a function to make it easier to use.

compiler/*.m:
	Conform to the change to goal_path_to_string.

runtime/mercury_context.[ch]:
	In .mmos grades, include the current debugger call sequence number,
	depth, and event number in contexts, to be saved and loaded with
	the contexts. This allows each context to have its own separate
	sequence of events.

	This capability depends not directly on the grade, but on the macro
	MR_EXEC_TRACE_INFO_IN_CONTEXT. For now, this is defined only in .mmos
	grades, but in future, it may be useful in other grades as well.

runtime/mercury_conf_param.h:
	Define and document MR_EXEC_TRACE_INFO_IN_CONTEXT.

runtime/mercury_mm_own_stacks.[ch]:
runtime/mercury_tabling_preds.h:
	Implement some predicates needed by the own stack transformation.
	Implement the code for generators returning answers to consumers,
	and the code for consumers scheduling generators when they need
	more answers. At the moment, the code for detecting when generators
	depend on each other is not yet written.

	Provide better facilities for debugging own stack minimal model grades.

	Fix a cut-and-paste bug (wrong macro name guarding the handwritten
	C module).

runtime/Mmakefile:
	Rebuild only what needs to be rebuilt when mercury_tabling_preds.h
	changes.

runtime/mercury_label.[ch]:
	Add a utility function for returning the name of an arbitrary label
	(internal or entry).

	Rename some fields to give them MR_ prefixes.

	Always define the functions for recording both entry and internal
	labels, even if they are not called from most modules, since they
	may be called from a few handwritten modules in the runtime.

	Rename a function to avoid a clash with the name of a macro,
	and thus allow the change to mercury_goto.h.

runtime/mercury_goto.h:
	Fix a bug with MR_init_entry_an. This macro was supposed to always
	insert the entry label that is its argument into the entry table,
	but instead of calling the function it was meant to call, it called
	a macro that could be (and usually way) defined to expand to nothing.

	The fix is to call the function a different name than the macro,
	and to call the function, not the macro.

runtime/mercury_wrapper.c:
	In own stack minimal model grades, create a main context separate
	from the current context, since the current context may be needed
	to hold a generator's state. Make MR_eng_this_context point to
	this context.

	Register all labels in the debugging variants of minimal model grades.

runtime/mercury_accurate_gc.c:
runtime/mercury_agc_debug.c:
runtime/mercury_debug.c:
library/exception.m:
	Conform to the change to runtime/mercury_label.h.

runtime/mercury_stack_trace.c:
	Conform to the change to runtime/mercury_label.h.

	Document the link to trace/mercury_trace_internal.c.

trace/mercury_trace.[ch]:
trace/mercury_trace_cmd_forward.c:
	Split the GOTO command into two: STEP and GOTO. STEP always stops
	at the next event (without any test), even if it is in a different
	context (and possibly with a lower event number than the immediately
	previous event, since the event numbers in different contexts are
	not related). As before, GOTO always goes to the specified event
	number, but in .dmmos grades it can now be told that this event number
	should be matched only in a specified context. The specification is
	done by an extra argument specifying the short name of the context's
	generator; the ansence of such an argument means the main context.

trace/mercury_trace_cmd_internal.c:
	In own stack grades, when the current context is that of a generator,
	print the subgoal the generator is working on before the event number,
	call depth, call sequence number and the rest of the event report.

	Document the link to runtime/mercury_stack_trace.c, which has similar
	code.

trace/mercury_trace_cmd_external.c:
trace/mercury_trace_cmd_declararive.c:
	Use the STEP command where GOTO was used for this simpler job,
	since this is (very slightly) faster.

trace/mercury_trace_cmd_developer.c:
	Fix some bugs with handling own stack tables.

doc/user_guide.texi:
	Document the new functionality of the goto mdb command. The
	documentation is commented out, since .mmos grades are for developers
	only at the moment.

tools/lmc.in:
	Turn off C optimizations when C debugging is enabled. For some reason,
	the default value of --cflags-for-debug does not include -O0.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/build_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/build_mode_constraints.m,v
retrieving revision 1.22
diff -u -b -r1.22 build_mode_constraints.m
--- compiler/build_mode_constraints.m	21 Dec 2006 06:33:56 -0000	1.22
+++ compiler/build_mode_constraints.m	1 Jan 2007 11:14:35 -0000
@@ -1083,7 +1083,7 @@
 var_info_init = mc_var_info(varset.init, bimap.init).
 
 rep_var_to_string(ProgVarset, (ProgVar `in` _) `at` GoalPath) = RepString :-
-    goal_path_to_string(GoalPath, GoalPathString),
+    GoalPathString = goal_path_to_string(GoalPath),
     varset.lookup_name(ProgVarset, ProgVar, ProgVarString),
     ( GoalPathString = "" ->
         RepString = ProgVarString
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.172
diff -u -b -r1.172 hlds_goal.m
--- compiler/hlds_goal.m	27 Dec 2006 03:17:52 -0000	1.172
+++ compiler/hlds_goal.m	1 Jan 2007 10:54:03 -0000
@@ -1103,7 +1103,7 @@
     % Convert a goal path to a string, using the format documented
     % in the Mercury user's guide.
     %
-:- pred goal_path_to_string(goal_path::in, string::out) is det.
+:- func goal_path_to_string(goal_path) = string.
 
 %-----------------------------------------------------------------------------%
 %
@@ -1861,7 +1861,7 @@
 
 %-----------------------------------------------------------------------------%
 
-goal_path_to_string(Path, PathStr) :-
+goal_path_to_string(Path) = PathStr :-
     goal_path_steps_to_strings(Path, StepStrs),
     list.reverse(StepStrs, RevStepStrs),
     string.append_list(RevStepStrs, PathStr).
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.418
diff -u -b -r1.418 hlds_out.m
--- compiler/hlds_out.m	27 Dec 2006 04:16:26 -0000	1.418
+++ compiler/hlds_out.m	1 Jan 2007 11:14:51 -0000
@@ -1238,7 +1238,7 @@
         goal_info_get_goal_path(GoalInfo, Path),
         (
             Path = [_ | _],
-            goal_path_to_string(Path, PathStr),
+            PathStr = goal_path_to_string(Path),
             write_indent(Indent, !IO),
             io.write_string("% goal path: ", !IO),
             io.write_string(PathStr, !IO),
@@ -4040,7 +4040,7 @@
         ConstraintType = unproven,
         io.write_string("(A, ", !IO)
     ),
-    goal_path_to_string(GoalPath, GoalPathStr),
+    GoalPathStr = goal_path_to_string(GoalPath),
     io.write_strings(["""", GoalPathStr, """, "], !IO),
     io.write_int(N, !IO),
     io.write_char(')', !IO).
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.217
diff -u -b -r1.217 hlds_pred.m
--- compiler/hlds_pred.m	27 Dec 2006 04:16:27 -0000	1.217
+++ compiler/hlds_pred.m	1 Jan 2007 12:55:12 -0000
@@ -1675,6 +1675,18 @@
                 gen_arg_infos       :: table_arg_infos
             ).
 
+:- type special_proc_return
+    --->    generator_return(
+                % The generator is stored in this location. We can't use an
+                % rval to represent the location, since we don't want this
+                % module to depend on the ll_backend package.
+                generator_rval          :: string,
+
+                % What should we pass as the value of the debug paramater
+                % in the call to MR_tbl_mmos_return_answer?
+                return_debug            :: string
+            ).
+
 :- type untuple_proc_info
     --->    untuple_proc_info(
                 map(prog_var, prog_vars)
@@ -1737,6 +1749,8 @@
     maybe(proc_table_info)::out) is det.
 :- pred proc_info_get_table_attributes(proc_info::in,
     maybe(table_attributes)::out) is det.
+:- pred proc_info_get_maybe_special_return(proc_info::in,
+    maybe(special_proc_return)::out) is det.
 :- pred proc_info_get_maybe_deep_profile_info(proc_info::in,
     maybe(deep_profile_proc_info)::out) is det.
 :- pred proc_info_get_maybe_untuple_info(proc_info::in,
@@ -1792,6 +1806,8 @@
     proc_info::in, proc_info::out) is det.
 :- pred proc_info_set_table_attributes(maybe(table_attributes)::in,
     proc_info::in, proc_info::out) is det.
+:- pred proc_info_set_maybe_special_return(maybe(special_proc_return)::in,
+    proc_info::in, proc_info::out) is det.
 :- pred proc_info_set_maybe_deep_profile_info(
     maybe(deep_profile_proc_info)::in,
     proc_info::in, proc_info::out) is det.
@@ -2102,6 +2118,8 @@
 
                 table_attributes            :: maybe(table_attributes),
 
+                maybe_special_return        :: maybe(special_proc_return),
+
                 maybe_deep_profile_proc_info :: maybe(deep_profile_proc_info),
 
                 % If set, it means this procedure was created from another
@@ -2126,8 +2144,8 @@
             maybe_imported_sharing  :: maybe(imported_sharing)
                 % Records the sharing information from any `.opt' or
                 % `.trans_opt' file. This information needs to be processed
-                % at the beginning of structure sharing analysis. After that
-                % this field is of no use.
+                    % at the beginning of structure sharing analysis. After
+                    % that, this field is of no use.
         ).
 
     % Sharing information is expressed in terms of headvariables and the
@@ -2209,7 +2227,7 @@
     SharingInfo = structure_sharing_info_init,
     ReuseInfo = structure_reuse_info_init,
     ProcSubInfo = proc_sub_info(no, no, Term2Info, IsAddressTaken, StackSlots,
-        ArgInfo, InitialLiveness, no, no, no, no, no, no, no, no,
+        ArgInfo, InitialLiveness, no, no, no, no, no, no, no, no, no,
         SharingInfo, ReuseInfo),
     ProcInfo = proc_info(MContext, BodyVarSet, BodyTypes, HeadVars, InstVarSet,
         DeclaredModes, Modes, no, MaybeArgLives, MaybeDet, InferredDet,
@@ -2233,7 +2251,7 @@
     SharingInfo = structure_sharing_info_init,
     ReuseInfo = structure_reuse_info_init,
     ProcSubInfo = proc_sub_info(no, no, Term2Info, IsAddressTaken,
-        StackSlots, no, Liveness, no, no, no, no, no, no, no, no,
+        StackSlots, no, Liveness, no, no, no, no, no, no, no, no, no,
         SharingInfo, ReuseInfo),
     ProcInfo = proc_info(Context, VarSet, VarTypes, HeadVars,
         InstVarSet, no, HeadModes, no, MaybeHeadLives,
@@ -2276,6 +2294,8 @@
 proc_info_get_call_table_tip(PI, PI ^ proc_sub_info ^ call_table_tip).
 proc_info_get_maybe_proc_table_info(PI, PI ^ proc_sub_info ^ maybe_table_info).
 proc_info_get_table_attributes(PI, PI ^ proc_sub_info ^ table_attributes).
+proc_info_get_maybe_special_return(PI,
+    PI ^ proc_sub_info ^ maybe_special_return).
 proc_info_get_maybe_deep_profile_info(PI,
     PI ^ proc_sub_info ^ maybe_deep_profile_proc_info).
 proc_info_get_maybe_untuple_info(PI,
@@ -2316,6 +2336,8 @@
     PI ^ proc_sub_info ^ maybe_table_info := MTI).
 proc_info_set_table_attributes(TA, PI,
     PI ^ proc_sub_info ^ table_attributes := TA).
+proc_info_set_maybe_special_return(MSR, PI,
+    PI ^ proc_sub_info ^ maybe_special_return := MSR).
 proc_info_set_maybe_deep_profile_info(DPI, PI,
     PI ^ proc_sub_info ^ maybe_deep_profile_proc_info := DPI).
 proc_info_set_maybe_untuple_info(MUI, PI,
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.83
diff -u -b -r1.83 layout_out.m
--- compiler/layout_out.m	27 Dec 2006 04:16:27 -0000	1.83
+++ compiler/layout_out.m	1 Jan 2007 11:19:13 -0000
@@ -91,6 +91,11 @@
     %
 :- pred output_pred_or_func(pred_or_func::in, io::di, io::uo) is det.
 
+    % Return the name of the given port, as in the enum MR_Trace_Port
+    % in runtime/mercury_stack_layout.h.
+    %
+:- func trace_port_to_string(trace_port) = string.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -812,11 +817,6 @@
         output_rval(Rval, !IO)
     ).
 
-    % Return the name of the given port, as in the enum MR_Trace_Port
-    % in runtime/mercury_stack_layout.h.
-    %
-:- func trace_port_to_string(trace_port) = string.
-
 trace_port_to_string(port_call) =                "CALL".
 trace_port_to_string(port_exit) =                "EXIT".
 trace_port_to_string(port_redo) =                "REDO".
@@ -2102,7 +2102,7 @@
     io.write_string(""", ", !IO),
     io.write_int(LineNumber, !IO),
     io.write_string(", """, !IO),
-    goal_path_to_string(GoalPath, GoalPathStr),
+    GoalPathStr = goal_path_to_string(GoalPath),
     io.write_string(GoalPathStr, !IO),
     io.write_string(""" },\n", !IO).
 
Index: compiler/ordering_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ordering_mode_constraints.m,v
retrieving revision 1.11
diff -u -b -r1.11 ordering_mode_constraints.m
--- compiler/ordering_mode_constraints.m	27 Sep 2006 06:16:59 -0000	1.11
+++ compiler/ordering_mode_constraints.m	1 Jan 2007 11:15:02 -0000
@@ -756,7 +756,7 @@
 
 dump_goal_goal_paths(Indent, GoalExpr - GoalInfo, !IO) :-
     goal_info_get_goal_path(GoalInfo, GoalPath),
-    goal_path_to_string(GoalPath, GoalPathString),
+    GoalPathString = goal_path_to_string(GoalPath),
     GoalPathFormat = [words(GoalPathString), nl],
     write_error_pieces_maybe_with_context(no, Indent, GoalPathFormat, !IO),
     dump_goal_expr_goal_paths(Indent+1, GoalExpr, !IO).
Index: compiler/proc_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_gen.m,v
retrieving revision 1.12
diff -u -b -r1.12 proc_gen.m
--- compiler/proc_gen.m	5 Dec 2006 03:50:57 -0000	1.12
+++ compiler/proc_gen.m	1 Jan 2007 13:11:09 -0000
@@ -1000,7 +1000,8 @@
         comment("End of procedure epilogue") - ""
     ]),
     FrameInfo = frame(TotalSlots, MaybeSuccipSlot, NondetPragma),
-    ( NondetPragma = yes ->
+    (
+        NondetPragma = yes,
         UndefStr = "#undef\tMR_ORDINARY_SLOTS\n",
         UndefComponents = [pragma_c_raw_code(UndefStr, cannot_branch_away,
             live_lvals_info(set.init))],
@@ -1011,6 +1012,7 @@
         RestoreDeallocCode = empty, % always empty for nondet code
         ExitCode = tree_list([StartComment, UndefCode, EndComment])
     ;
+        NondetPragma = no,
         code_info.get_instmap(!.CI, InstMap),
         ArgModes = code_info.get_arginfo(!.CI),
         HeadVars = code_info.get_headvars(!.CI),
@@ -1124,8 +1126,12 @@
             LiveLvals = OutLvals
         ),
 
+        code_info.get_proc_info(!.CI, ProcInfo),
+        proc_info_get_maybe_special_return(ProcInfo, MaybeSpecialReturn),
         (
             CodeModel = model_det,
+            expect(unify(MaybeSpecialReturn, no), this_file,
+                "generate_exit: det special_return"),
             SuccessCode = node([
                 livevals(LiveLvals) - "",
                 goto(code_succip) - "Return from procedure call"
@@ -1134,6 +1140,8 @@
                 SuccessCode])
         ;
             CodeModel = model_semi,
+            expect(unify(MaybeSpecialReturn, no), this_file,
+                "generate_exit: semi special_return"),
             set.insert(LiveLvals, reg(reg_r, 1), SuccessLiveRegs),
             SuccessCode = node([
                 assign(reg(reg_r, 1), const(llconst_true)) - "Succeed",
@@ -1151,12 +1159,27 @@
                 MaybeTraceInfo = no,
                 SetupRedoCode = empty
             ),
+            (
+                MaybeSpecialReturn = yes(SpecialReturn),
+                SpecialReturn = generator_return(GeneratorLocnStr, DebugStr),
+                ReturnMacroName = "MR_tbl_mmos_return_answer",
+                ReturnCodeStr = "\t" ++ ReturnMacroName ++ "(" ++
+                    DebugStr ++ ", " ++ GeneratorLocnStr ++ ");\n",
+                Component = pragma_c_user_code(no, ReturnCodeStr),
+                SuccessCode = node([
+                    livevals(LiveLvals) - "",
+                    pragma_c([], [Component], proc_may_call_mercury,
+                        no, no, no, no, no, no) - ""
+                ])
+            ;
+                MaybeSpecialReturn = no,
             SuccessCode = node([
                 livevals(LiveLvals) - "",
                 goto(do_succeed(no)) - "Return from procedure call"
-            ]),
-            AllSuccessCode = tree_list([SetupRedoCode,
-                TraceExitCode, SuccessCode])
+                ])
+            ),
+            AllSuccessCode = tree_list([SetupRedoCode, TraceExitCode,
+                SuccessCode])
         ),
         ExitCode = tree_list([StartComment, FlushCode, AllSuccessCode,
             EndComment])
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.129
diff -u -b -r1.129 stack_layout.m
--- compiler/stack_layout.m	14 Dec 2006 04:35:48 -0000	1.129
+++ compiler/stack_layout.m	1 Jan 2007 11:19:24 -0000
@@ -887,7 +887,7 @@
         Return = no,
         MaybePort = yes(Port),
         MaybeIsHidden = yes(IsHidden),
-        goal_path_to_string(GoalPath, GoalPathStr),
+        GoalPathStr = goal_path_to_string(GoalPath),
         lookup_string_in_table(GoalPathStr, GoalPathNum, !Info),
         MaybeGoalPath = yes(GoalPathNum)
     ;
@@ -902,7 +902,7 @@
         % when we process "fail" commands in the debugger.
         ReturnInfo = return_layout_info(TargetsContexts, _),
         ( find_valid_return_context(TargetsContexts, _, _, GoalPath) ->
-            goal_path_to_string(GoalPath, GoalPathStr),
+            GoalPathStr = goal_path_to_string(GoalPath),
             lookup_string_in_table(GoalPathStr, GoalPathNum, !Info),
             MaybeGoalPath = yes(GoalPathNum)
         ;
Index: compiler/table_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/table_gen.m,v
retrieving revision 1.128
diff -u -b -r1.128 table_gen.m
--- compiler/table_gen.m	27 Dec 2006 04:16:30 -0000	1.128
+++ compiler/table_gen.m	1 Jan 2007 15:21:56 -0000
@@ -1510,6 +1510,7 @@
 %           % Check for duplicate answers.
 %       semipure table_mmos_get_answer_table(Generator, AT0),
 %       impure table_lookup_insert_int(AT0, B, AT1),
+%
 %           % Fail if the answer is already in the table;
 %           % otherwise, put it into the table.
 %       impure table_mmos_answer_is_not_duplicate(AT1),
@@ -1517,16 +1518,21 @@
 %           % Save the new answer in the table.
 %       impure table_mmos_create_answer_block(Generator, 1, AnswerBlock),
 %       impure table_save_int_ans(AnswerBlock, 0, B),
-%       impure table_mmos_return_answer(Generator, AnswerBlock)
 %   ;
 %       impure table_mmos_completion(Generator)
 %   ).
+%   MR_succeed is replaced by table_mmos_return_answer(Generator).
 %
 % p(A, B) :-
-%   table_mmos_save_inputs(1, A),       % into global variable
 %   CT0 = <table pointer for p/2>,
 %   impure table_lookup_insert_int(CT0, A, CT1),
-%   impure table_mmos_setup_consumer(CT1, 1, p2_gen, "p/2", Consumer),
+%   ( CT1 = NULL ->
+%       table_mmos_save_inputs(0, A),   % into global var MR_mmos_input_arg
+%       Generator = table_mmos_setup_generator(CT1, 1, p2_gen, "p"),
+%   ;
+%       Generator = trie_node_to_generator(CT1)
+%   ),
+%   impure table_mmos_setup_consumer(Generator, Consumer),
 %   impure table_mmos_consume_next_answer_nondet(Consumer, AnswerBlock),
 %   impure table_restore_int_ans(AnswerBlock, 0, B).
 
@@ -1671,7 +1677,7 @@
     table_info_init(ModuleInfo, GeneratorPredInfo, ProcInfo0,
         GeneratorTableInfo0),
     do_own_stack_create_generator(GeneratorPredId, ProcId, GeneratorPredInfo,
-        ProcInfo0, Statistics, Context, GeneratorPredVar,
+        ProcInfo0, Statistics, Context, GeneratorPredVar, DebugArgStr,
         PickupInputVarCode, PickupForeignArgs,
         NumberedInputVars, NumberedOutputVars,
         OrigNonLocals, OrigInstMapDelta, !.VarTypes, !.VarSet,
@@ -1708,14 +1714,14 @@
 :- pred do_own_stack_create_generator(pred_id::in, proc_id::in,
     pred_info::in, proc_info::in,
     table_attr_statistics::in, term.context::in,
-    prog_var::in, string::in, list(foreign_arg)::in,
+    prog_var::in, string::in, string::in, list(foreign_arg)::in,
     list(var_mode_pos_method)::in, list(var_mode_pos_method)::in,
     set(prog_var)::in, instmap_delta::in,
     vartypes::in, prog_varset::in, table_info::in, table_info::out,
     list(table_trie_step)::in, list(table_trie_step)::out) is det.
 
 do_own_stack_create_generator(PredId, ProcId, !.PredInfo, !.ProcInfo,
-        Statistics, Context, GeneratorVar, PickupVarCode,
+        Statistics, Context, GeneratorVar, DebugArgStr, PickupVarCode,
         PickupForeignArgs, NumberedInputVars, NumberedOutputVars,
         OrigNonLocals, OrigInstMapDelta, !.VarTypes, !.VarSet, !TableInfo,
         InputSteps, OutputSteps) :-
@@ -1739,19 +1745,36 @@
         PickupInstMapDeltaSrc, ModuleInfo0, Context, PickupGoal),
 
     list.length(NumberedOutputVars, BlockSize),
-    generate_own_stack_save_goal(NumberedOutputVars, GeneratorVar,
+    generate_own_stack_save_return_goal(NumberedOutputVars, GeneratorVar,
         PredId, ProcId, BlockSize, Statistics, Context, !VarSet, !VarTypes,
-        !TableInfo, OutputSteps, SaveAnswerGoals),
+        !TableInfo, OutputSteps, SaveReturnAnswerGoals),
 
     proc_info_get_goal(!.ProcInfo, OrigGoal),
-    GoalExpr = conj(plain_conj, [PickupGoal, OrigGoal | SaveAnswerGoals]),
     OrigGoal = _ - OrigGoalInfo,
+
+    MainGoalExpr = conj(plain_conj, [OrigGoal | SaveReturnAnswerGoals]),
     goal_info_get_determinism(OrigGoalInfo, Detism),
     set.insert(OrigNonLocals, GeneratorVar, NonLocals),
     goal_info_init(NonLocals, OrigInstMapDelta, Detism, purity_impure, Context,
-        GoalInfo0),
-    goal_info_add_feature(feature_hide_debug_event, GoalInfo0, GoalInfo),
-    Goal = GoalExpr - GoalInfo,
+        MainGoalInfo0),
+    goal_info_add_feature(feature_hide_debug_event,
+        MainGoalInfo0, MainGoalInfo),
+    MainGoal = MainGoalExpr - MainGoalInfo,
+
+    CompletionCode = "\t\t" ++ "MR_tbl_mmos_completion(" ++
+        DebugArgStr ++ ", " ++ generator_name ++ ");\n",
+    CompletionArg = foreign_arg(GeneratorVar,
+        yes(generator_name - in_mode), generator_type, native_if_possible),
+    table_generate_foreign_proc("table_mmos_completion", detism_failure,
+        tabling_c_attributes, [CompletionArg], [],
+        CompletionCode, purity_impure,
+        [], ModuleInfo0, Context, CompletionGoal),
+
+    DisjGoalExpr = disj([MainGoal, CompletionGoal]),
+    DisjGoal = DisjGoalExpr - MainGoalInfo,
+
+    GoalExpr = conj(plain_conj, [PickupGoal, DisjGoal]),
+    Goal = GoalExpr - OrigGoalInfo,
     proc_info_set_goal(Goal, !ProcInfo),
 
     proc_info_set_vartypes(!.VarTypes, !ProcInfo),
@@ -1763,6 +1786,8 @@
         InputVarModeMethods, OutputVarModeMethods, ProcTableInfo),
     proc_info_set_maybe_proc_table_info(yes(ProcTableInfo), !ProcInfo),
 
+    SpecialReturn = generator_return(returning_generator_locn, DebugArgStr),
+    proc_info_set_maybe_special_return(yes(SpecialReturn), !ProcInfo),
     proc_info_set_eval_method(eval_minimal(own_stacks_generator), !ProcInfo),
 
     pred_info_get_procedures(!.PredInfo, ProcTable0),
@@ -2547,16 +2572,16 @@
 
     % Generate a sequence of save goals for the given variables.
     %
-:- pred generate_own_stack_save_goal(list(var_mode_pos_method)::in,
+:- pred generate_own_stack_save_return_goal(list(var_mode_pos_method)::in,
     prog_var::in, pred_id::in, proc_id::in, int::in,
     table_attr_statistics::in, term.context::in,
     prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
     table_info::in, table_info::out, list(table_trie_step)::out,
     list(hlds_goal)::out) is det.
 
-generate_own_stack_save_goal(NumberedOutputVars, GeneratorVar, PredId, ProcId,
-        BlockSize, Statistics, Context, !VarSet, !VarTypes, !TableInfo,
-        OutputSteps, Goals) :-
+generate_own_stack_save_return_goal(NumberedOutputVars, GeneratorVar,
+        PredId, ProcId, BlockSize, Statistics, Context, !VarSet, !VarTypes,
+        !TableInfo, OutputSteps, Goals) :-
     GeneratorName = generator_name,
     GeneratorArg = foreign_arg(GeneratorVar, yes(GeneratorName - in_mode),
         generator_type, native_if_possible),
@@ -2592,9 +2617,12 @@
     CreateCodeStr = "\t" ++ CreateMacroName ++ "(" ++ DebugArgStr ++ ", " ++
         GeneratorName ++ ", " ++ int_to_string(BlockSize) ++ ", " ++
         answer_block_name ++ ");\n",
-    CreateSaveCodeStr = CreateCodeStr ++ SaveCodeStr,
+    SetupReturnCodeStr = "\t" ++ returning_generator_locn ++ " = " ++
+        GeneratorName ++ ";\n",
+    CreateSaveSetupReturnCodeStr = CreateCodeStr ++ SaveCodeStr ++
+        SetupReturnCodeStr,
     CondSaveCodeStr = "\tif (" ++ SuccName ++ ") {\n" ++
-        CreateSaveCodeStr ++ "\t}\n",
+        CreateSaveSetupReturnCodeStr ++ "\t}\n",
     CodeStr = LookupSaveDeclCodeStr ++ GetCodeStr ++ LookupCodeStr ++
         DuplCheckCodeStr ++ CondSaveCodeStr ++ AssignSuccessCodeStr,
     ModuleInfo = !.TableInfo ^ table_module_info,
@@ -2602,7 +2630,8 @@
         tabling_c_attributes, Args, LookupForeignArgs,
         CodeStr, purity_impure, [],
         ModuleInfo, Context, DuplicateCheckSaveGoal),
-    Goals = LookupPrefixGoals ++ SavePrefixGoals ++ [DuplicateCheckSaveGoal].
+    Goals = LookupPrefixGoals ++ SavePrefixGoals ++
+        [DuplicateCheckSaveGoal].
 
 :- pred generate_save_goals(list(var_mode_pos_method(T))::in, string::in,
     term.context::in, prog_varset::in, prog_varset::out,
@@ -3529,6 +3558,7 @@
 :- func consumer_name = string.
 :- func generator_name = string.
 :- func generator_pred_name = string.
+:- func returning_generator_locn = string.
 
 proc_table_info_name = "proc_table_info".
 cur_table_node_name = "cur_node".
@@ -3547,6 +3577,7 @@
 consumer_name = "consumer".
 generator_name = "generator".
 generator_pred_name = "generator_pred".
+returning_generator_locn = "MR_mmos_returning_generator".
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/trace_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trace_gen.m,v
retrieving revision 1.10
diff -u -b -r1.10 trace_gen.m
--- compiler/trace_gen.m	5 Dec 2006 03:51:00 -0000	1.10
+++ compiler/trace_gen.m	1 Jan 2007 11:30:35 -0000
@@ -799,18 +799,18 @@
 generate_external_event_code(ExternalPort, TraceInfo, Context,
         MaybeExternalInfo, !CI) :-
     Port = convert_external_port_type(ExternalPort),
-    (
         code_info.get_module_info(!.CI, ModuleInfo),
         code_info.get_pred_info(!.CI, PredInfo),
         code_info.get_proc_info(!.CI, ProcInfo),
-        eff_trace_needs_port(ModuleInfo, PredInfo, ProcInfo,
-            TraceInfo ^ trace_level,
-            TraceInfo ^ trace_suppress_items, Port) = yes
-    ->
+    NeedPort = eff_trace_needs_port(ModuleInfo, PredInfo, ProcInfo,
+        TraceInfo ^ trace_level, TraceInfo ^ trace_suppress_items, Port),
+    (
+        NeedPort = yes,
         generate_event_code(Port, port_info_external, yes(TraceInfo), Context,
             no, no, Label, TvarDataMap, Code, !CI),
         MaybeExternalInfo = yes(external_event_info(Label, TvarDataMap, Code))
     ;
+        NeedPort = no,
         MaybeExternalInfo = no
     ).
 
@@ -867,10 +867,10 @@
     code_info.variable_locations(!.CI, VarLocs),
     code_info.get_proc_info(!.CI, ProcInfo),
     set.to_sorted_list(TvarSet, TvarList),
-    continuation_info.find_typeinfos_for_tvars(TvarList,
-        VarLocs, ProcInfo, TvarDataMap),
+    continuation_info.find_typeinfos_for_tvars(TvarList, VarLocs, ProcInfo,
+        TvarDataMap),
 
-    % compute the set of live lvals at the event
+    % Compute the set of live lvals at the event.
     VarLvals = list.map(find_lval_in_var_info, VarInfoList),
     map.values(TvarDataMap, TvarLocnSets),
     TvarLocnSet = set.union_list(TvarLocnSets),
@@ -884,11 +884,15 @@
     LabelStr = llds_out.label_to_c_string(Label, no),
     (
         MaybeUserInfo = no,
-        TraceStmt = "\t\tMR_EVENT(" ++ LabelStr ++ ")\n"
+        TraceStmt0 = "\t\tMR_EVENT(" ++ LabelStr ++ ")\n"
     ;
         MaybeUserInfo = yes(_),
-        TraceStmt = "\t\tMR_USER_EVENT(" ++ LabelStr ++ ")\n"
+        TraceStmt0 = "\t\tMR_USER_EVENT(" ++ LabelStr ++ ")\n"
     ),
+    TraceStmt = "\t\t/* port " ++ trace_port_to_string(Port) ++ ", " ++
+        "path <" ++ goal_path_to_string(Path) ++ "> */\n" ++
+        TraceStmt0,
+
     code_info.add_trace_layout_for_label(Label, Context, Port, HideEvent,
         Path, MaybeUserInfo, LayoutLabelInfo, !CI),
     code_info.set_proc_trace_events(yes, !CI),
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.174
diff -u -b -r1.174 unify_gen.m
--- compiler/unify_gen.m	1 Dec 2006 15:04:27 -0000	1.174
+++ compiler/unify_gen.m	1 Jan 2007 11:19:30 -0000
@@ -662,7 +662,7 @@
         term.context_file(Context, FileName),
         term.context_line(Context, LineNumber),
         goal_info_get_goal_path(GoalInfo, GoalPath),
-        goal_path_to_string(GoalPath, GoalPathStr),
+        GoalPathStr = goal_path_to_string(GoalPath),
         code_info.get_cur_proc_label(!.CI, CallerProcLabel),
         code_info.get_next_closure_seq_no(SeqNo, !CI),
         code_info.get_static_cell_info(!.CI, StaticCellInfo0),
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.504
diff -u -b -r1.504 user_guide.texi
--- doc/user_guide.texi	3 Jan 2007 02:37:29 -0000	1.504
+++ doc/user_guide.texi	3 Jan 2007 05:02:53 -0000
@@ -2453,6 +2453,9 @@
 An empty command line is interpreted as `step 1'.
 @sp 1
 @item goto [-NSans] @var{num}
+ at c The @var{generatorname} option is enabled
+ at c only in own stack minimal model grades.
+ at c @item goto [-NSans] @var{num} [@var{generatorname}]
 @kindex goto (mdb command)
 Continues execution until the program reaches event number @var{num}.
 If the current event number is larger than @var{num}, it reports an error.
@@ -2463,6 +2466,11 @@
 while the options @samp{-S} or @samp{--strict}
 and @samp{-N} or @samp{--nostrict} specify
 the strictness of the command.
+ at c @sp 1
+ at c If given, @var{generatorname} specifies
+ at c the generator in which to reach the given event number.
+ at c In this case, the command does not check
+ at c whether the event has already passed.
 @sp 1
 By default, this command is strict, and it uses the default print level.
 @sp 1
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/stream/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/exception.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/exception.m,v
retrieving revision 1.120
diff -u -b -r1.120 exception.m
--- library/exception.m	26 Dec 2006 06:41:36 -0000	1.120
+++ library/exception.m	1 Jan 2007 16:25:38 -0000
@@ -1566,7 +1566,7 @@
         WARNING(""internal label not found\\n"");
         return NULL;
     }
-    return_label_layout = label->i_layout;
+    return_label_layout = label->MR_internal_layout;
 
     while (return_label_layout != NULL) {
         const MR_ProcLayout         *entry_layout;
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/Mmakefile,v
retrieving revision 1.136
diff -u -b -r1.136 Mmakefile
--- runtime/Mmakefile	4 Dec 2006 01:33:29 -0000	1.136
+++ runtime/Mmakefile	1 Jan 2007 14:43:26 -0000
@@ -83,7 +83,6 @@
 			mercury_string.h	\
 			mercury_tabling.h	\
 			mercury_tabling_macros.h	\
-			mercury_tabling_preds.h	\
 			mercury_tags.h		\
 			mercury_term_size.h	\
 			mercury_thread.h	\
@@ -123,6 +122,7 @@
 			mercury_table_int_start_index_body.h \
 			mercury_table_typeinfo_body.h \
 			mercury_table_type_body.h 	\
+			mercury_tabling_preds.h		\
 			mercury_tabling_stats_defs.h 	\
 			mercury_tabling_stats_nodefs.h 	\
 			mercury_tabling_stats_undefs.h 	\
@@ -286,7 +286,7 @@
 
 # These files depend on several of the files in $(BODY_HDRS), and it is
 # easier to depend on them all than to specifically list only the ones
-# we mercury_tabling.c actually includes.
+# that mercury_tabling.c actually includes.
 mercury_tabling.$(O):				$(BODY_HDRS)
 mercury_tabling.$(EXT_FOR_PIC_OBJECTS):		$(BODY_HDRS)
 
Index: runtime/mercury_accurate_gc.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_accurate_gc.c,v
retrieving revision 1.46
diff -u -b -r1.46 mercury_accurate_gc.c
--- runtime/mercury_accurate_gc.c	21 Dec 2006 09:47:11 -0000	1.46
+++ runtime/mercury_accurate_gc.c	1 Jan 2007 16:21:53 -0000
@@ -306,7 +306,7 @@
     /* Search for the entry label */
 
     entry_label = MR_prev_entry_by_addr(pc_at_signal);
-    proc_layout = (entry_label != NULL ? entry_label->e_layout : NULL);
+    proc_layout = (entry_label != NULL ? entry_label->MR_entry_layout : NULL);
 
     determinism = (proc_layout != NULL ? proc_layout->MR_sle_detism : -1);
 
@@ -319,16 +319,17 @@
             "attempt to schedule garbage collection failed\n");
         if (entry_label != NULL) {
             fprintf(stderr, "Mercury runtime: the label ");
-            if (entry_label->e_name != NULL) {
+            if (entry_label->MR_entry_name != NULL) {
                 fprintf(stderr, "%s has no stack layout info\n",
-                        entry_label->e_name);
+                        entry_label->MR_entry_name);
             } else {
                 fprintf(stderr, "at address %p "
-                    "has no stack layout info\n", entry_label->e_addr);
+                    "has no stack layout info\n", entry_label->MR_entry_addr);
             }
             fprintf(stderr, "Mercury runtime: PC address = %p\n", pc_at_signal);
             fprintf(stderr, "Mercury runtime: PC = label + 0x%lx\n",
-                (long) ((char *)pc_at_signal - (char *)entry_label->e_addr));
+                (long) ((char *) pc_at_signal -
+                    (char *)entry_label->MR_entry_addr));
         } else {
             fprintf(stderr, "Mercury runtime: no entry label ");
             fprintf(stderr, "for PC address %p\n", pc_at_signal);
@@ -338,13 +339,15 @@
         return;
     }
 #ifdef MR_DEBUG_AGC_SCHEDULING
-    if (entry_label->e_name != NULL) {
+    if (entry_label->MR_entry_name != NULL) {
         fprintf(stderr, "scheduling called at: %s (%ld %lx)\n",
-            entry_label->e_name, (long) entry_label->e_addr,
-            (long) entry_label->e_addr);
+            entry_label->MR_entry_name,
+            (long) entry_label->MR_entry_addr,
+            (long) entry_label->MR_entry_addr);
     } else {
         fprintf(stderr, "scheduling called at: (%ld %lx)\n",
-            (long) entry_label->e_addr, (long) entry_label->e_addr);
+            (long) entry_label->MR_entry_addr,
+            (long) entry_label->MR_entry_addr);
     }
     fflush(NULL);
 #endif
@@ -490,7 +493,7 @@
     MR_virtual_hp_word = (MR_Word) new_heap->MR_zone_min;
 
     label = MR_lookup_internal_by_addr(success_ip);
-    label_layout = label->i_layout;
+    label_layout = label->MR_internal_layout;
 
     if (MR_agc_debug) {
         fprintf(stderr, "BEFORE:\n");
Index: runtime/mercury_agc_debug.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_agc_debug.c,v
retrieving revision 1.28
diff -u -b -r1.28 mercury_agc_debug.c
--- runtime/mercury_agc_debug.c	29 Nov 2006 05:18:19 -0000	1.28
+++ runtime/mercury_agc_debug.c	1 Jan 2007 16:15:16 -0000
@@ -107,8 +107,8 @@
 
             label = MR_lookup_internal_by_addr(MR_redoip_slot(max_frame));
 
-            if (label && label->i_layout) {
-                MR_dump_live_variables(label->i_layout, heap_zone,
+            if (label && label->MR_internal_layout) {
+                MR_dump_live_variables(label->MR_internal_layout, heap_zone,
                     registers_valid, stack_pointer, MR_redofr_slot(max_frame));
             }
 
@@ -123,8 +123,8 @@
 
             label = MR_lookup_internal_by_addr(MR_redoip_slot(max_frame));
 
-            if (label && label->i_layout) {
-                MR_dump_live_variables(label->i_layout, heap_zone,
+            if (label && label->MR_internal_layout) {
+                MR_dump_live_variables(label->MR_internal_layout, heap_zone,
                     registers_valid, MR_tmp_detfr_slot(max_frame), max_frame);
                 /*
                 ** XXX should max_frame above be
@@ -148,10 +148,10 @@
             /* XXX ??? */
             label = MR_lookup_internal_by_addr(MR_redoip_slot(max_frame));
 
-            if (label && label->i_layout) {
-                MR_dump_live_variables(label->i_layout, heap_zone,
+            if (label != NULL && label->MR_internal_layout) {
+                MR_dump_live_variables(label->MR_internal_layout, heap_zone,
                     registers_valid, stack_pointer, MR_redofr_slot(max_frame));
-                fprintf(stderr, " this label: %s\n", label->i_name);
+                fprintf(stderr, " this label: %s\n", label->MR_internal_name);
             }
         }
 
@@ -179,8 +179,8 @@
     const MR_Code           *success_ip;
     MR_bool                 top_frame;
 
-    layout = label->i_layout;
-    success_ip = label->i_addr;
+    layout = label->MR_internal_layout;
+    success_ip = label->MR_internal_addr;
     entry_layout = layout->MR_sll_entry;
 
     /*
@@ -189,10 +189,10 @@
 
     top_frame = MR_TRUE;
     while (MR_DETISM_DET_STACK(entry_layout->MR_sle_detism)) {
-        if (label->i_name != NULL) {
-            fprintf(stderr, "    label: %s\n", label->i_name);
+        if (label->MR_internal_name != NULL) {
+            fprintf(stderr, "    label: %s\n", label->MR_internal_name);
         } else {
-            fprintf(stderr, "    label: %p\n", label->i_addr);
+            fprintf(stderr, "    label: %p\n", label->MR_internal_addr);
         }
 
         if (success_ip == MR_stack_trace_bottom) {
@@ -222,7 +222,7 @@
         }
 
         top_frame = MR_FALSE;
-        layout = label->i_layout;
+        layout = label->MR_internal_layout;
 
         if (layout != NULL) {
             entry_layout = layout->MR_sll_entry;
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.92
diff -u -b -r1.92 mercury_conf_param.h
--- runtime/mercury_conf_param.h	7 Dec 2006 00:57:43 -0000	1.92
+++ runtime/mercury_conf_param.h	1 Jan 2007 11:02:38 -0000
@@ -180,6 +180,11 @@
 ** 	Enables runtime checking of the invariants involving the implementation
 ** 	of the --trace-count runtime option.
 **
+** MR_EXEC_TRACE_INFO_IN_CONTEXT
+**	(Implied by MR_USE_MINIMAL_MODEL_OWN_STACKS.)
+** 	Allows the debugger to distinguish between different contexts.
+** 	Currently used only by own stack minimal model tabling.
+**
 ** MR_LOWLEVEL_DEBUG
 **	Enables various low-level debugging stuff,
 **	that was in the distant past used to debug
@@ -492,6 +497,17 @@
   #error "MR_USE_MINIMAL_MODEL_OWN_STACKS requires MR_CONSERVATIVE_GC"
 #endif
 
+/*
+** If the execution engine uses multiple contexts, we want separate event
+** counters, call counters and depth counters in each context. Currently,
+** we use multiple contexts only in parallel grades, for which the debugger
+** doesn't (yet) work, and in own stack minimal model grades.
+*/
+
+#ifdef	MR_USE_MINIMAL_MODEL_OWN_STACKS
+  #define MR_EXEC_TRACE_INFO_IN_CONTEXT
+#endif
+
 #ifdef MR_MINIMAL_MODEL_DEBUG
   #define MR_TABLE_STATISTICS
 #endif
Index: runtime/mercury_context.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.c,v
retrieving revision 1.52
diff -u -b -r1.52 mercury_context.c
--- runtime/mercury_context.c	27 Dec 2006 04:16:36 -0000	1.52
+++ runtime/mercury_context.c	1 Jan 2007 10:07:57 -0000
@@ -33,7 +33,7 @@
 #include "mercury_reg_workarounds.h"    /* for `MR_fd*' stuff */
 
 static  void            MR_init_context_maybe_generator(MR_Context *c,
-                            const char *id, MR_Generator *gen);
+                            const char *id, MR_GeneratorPtr gen);
 
 /*---------------------------------------------------------------------------*/
 
@@ -104,7 +104,7 @@
 
 static void 
 MR_init_context_maybe_generator(MR_Context *c, const char *id,
-    MR_Generator *gen)
+    MR_GeneratorPtr gen)
 {
     const char  *detstack_name;
     const char  *nondetstack_name;
@@ -257,6 +257,12 @@
     c->MR_ctxt_hp = NULL;
     c->MR_ctxt_min_hp_rec = NULL;
 #endif
+
+#ifdef  MR_EXEC_TRACE_INFO_IN_CONTEXT
+    c->MR_ctxt_call_seqno = 0;
+    c->MR_ctxt_call_depth = 0;
+    c->MR_ctxt_event_number = 0;
+#endif
 }
 
 MR_Context *
Index: runtime/mercury_context.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.h,v
retrieving revision 1.37
diff -u -b -r1.37 mercury_context.h
--- runtime/mercury_context.h	3 Nov 2006 08:31:20 -0000	1.37
+++ runtime/mercury_context.h	1 Jan 2007 11:00:15 -0000
@@ -17,8 +17,10 @@
 ** pointers that refer to them, a succip, and a thread-resumption continuation.
 ** Contexts are initally stored in a free-list.
 ** When one is running, the POSIX thread that is executing it has a pointer
-** to its context structure `this_context'. When a context suspends, it
-** calls `MR_save_context(context_ptr)' which copies the context from the
+** to its context structure `this_context'. (WARNING: code that manipulates
+** contexts must set this_context itself; it cannot rely on the generic
+** mechanisms below to set it.) When a context suspends, it calls
+** `MR_save_context(context_ptr)' which copies the context from the
 ** various registers and global variables into the structure referred to
 ** by `context_ptr'. The context contains no rN or fN registers - all
 ** registers are "context save" (by analogy to caller-save).
@@ -193,6 +195,12 @@
     MR_Word             *MR_ctxt_hp;
     MR_Word             *MR_ctxt_min_hp_rec;
 #endif
+
+#ifdef  MR_EXEC_TRACE_INFO_IN_CONTEXT
+    MR_Unsigned         MR_ctxt_call_seqno;
+    MR_Unsigned         MR_ctxt_call_depth;
+    MR_Unsigned         MR_ctxt_event_number;
+#endif
 };
 
 /*
@@ -475,6 +483,12 @@
   #define MR_IF_USE_MINIMAL_MODEL_STACK_COPY(x)
 #endif
 
+#ifdef MR_EXEC_TRACE_INFO_IN_CONTEXT
+  #define MR_IF_EXEC_TRACE_INFO_IN_CONTEXT(x) x
+#else
+  #define MR_IF_EXEC_TRACE_INFO_IN_CONTEXT(x)
+#endif
+
 #ifndef MR_HIGHLEVEL_CODE
   #define MR_IF_NOT_HIGHLEVEL_CODE(x) x
 #else
@@ -532,6 +546,11 @@
                     MR_ENGINE(MR_eng_context).MR_ctxt_pnegstack_zone->        \
                         MR_zone_min;                                          \
              )                                                                \
+            MR_IF_EXEC_TRACE_INFO_IN_CONTEXT(                                 \
+                MR_trace_call_seqno = load_context_c->MR_ctxt_call_seqno;     \
+                MR_trace_call_depth = load_context_c->MR_ctxt_call_depth;     \
+                MR_trace_event_number = load_context_c->MR_ctxt_event_number; \
+            )                                                                 \
         )                                                                     \
         MR_set_min_heap_reclamation_point(load_context_c);                    \
     } while (0)
@@ -558,10 +577,8 @@
         MR_IF_USE_TRAIL(                                                      \
             save_context_c->MR_ctxt_trail_zone = MR_trail_zone;               \
             save_context_c->MR_ctxt_trail_ptr = MR_trail_ptr;                 \
-            save_context_c->MR_ctxt_ticket_counter =                          \
-                MR_ticket_counter;                                            \
-            save_context_c->MR_ctxt_ticket_high_water =                       \
-                MR_ticket_high_water;                                         \
+            save_context_c->MR_ctxt_ticket_counter = MR_ticket_counter;       \
+            save_context_c->MR_ctxt_ticket_high_water = MR_ticket_high_water; \
         )                                                                     \
         MR_IF_NOT_HIGHLEVEL_CODE(                                             \
             save_context_c->MR_ctxt_detstack_zone =                           \
@@ -589,6 +606,11 @@
                     MR_ENGINE(MR_eng_context).MR_ctxt_pnegstack_zone->        \
                         MR_zone_min);                                         \
           )                                                                   \
+            MR_IF_EXEC_TRACE_INFO_IN_CONTEXT(                                 \
+                save_context_c->MR_ctxt_call_seqno = MR_trace_call_seqno;     \
+                save_context_c->MR_ctxt_call_depth = MR_trace_call_depth;     \
+                save_context_c->MR_ctxt_event_number = MR_trace_event_number; \
+            )                                                                 \
         )                                                                     \
         MR_save_hp_in_context(save_context_c);                                \
     } while (0)
Index: runtime/mercury_debug.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_debug.c,v
retrieving revision 1.29
diff -u -b -r1.29 mercury_debug.c
--- runtime/mercury_debug.c	27 Dec 2006 04:16:36 -0000	1.29
+++ runtime/mercury_debug.c	2 Jan 2007 05:32:21 -0000
@@ -835,8 +835,10 @@
     MR_Entry    *entry;
 
     entry = MR_prev_entry_by_addr(proc);
-    if (entry != NULL && entry->e_addr == proc && entry->e_name != NULL) {
-        if (MR_streq(entry->e_name, name)) {
+    if (entry != NULL && entry->MR_entry_addr == proc
+            && entry->MR_entry_name != NULL)
+    {
+        if (MR_streq(entry->MR_entry_name, name)) {
             return MR_TRUE;
         }
     }
@@ -958,6 +960,12 @@
     }
 }
 
+/*
+** The code of MR_print_label is similar to, but significantly more powerful
+** than, MR_lookup_entry_or_internal in mercury_label.c, since it does not
+** have to return a single short constant string.
+*/
+
 void
 MR_print_label(FILE *fp, const MR_Code *w)
 {
@@ -965,33 +973,30 @@
 
     internal = MR_lookup_internal_by_addr(w);
     if (internal != NULL) {
-        if (internal->i_name != NULL) {
-            fprintf(fp, "label %s", internal->i_name);
+        if (internal->MR_internal_name != NULL) {
+            fprintf(fp, "label %s", internal->MR_internal_name);
         } else {
-            fprintf(fp, "unnamed label %p", internal->i_addr);
+            fprintf(fp, "unnamed label %p", internal->MR_internal_addr);
         }
 #ifdef  MR_DEBUG_LABEL_GOAL_PATHS
-        if (internal->i_layout != NULL) {
-            fprintf(fp, " <%s>", MR_label_goal_path(internal->i_layout));
+        if (internal->MR_internal_layout != NULL) {
+            fprintf(fp, " <%s>",
+                MR_label_goal_path(internal->MR_internal_layout));
         }
 #endif
     } else {
-#ifdef  MR_NEED_ENTRY_LABEL_ARRAY
         MR_Entry    *entry;
 
         entry = MR_prev_entry_by_addr(w);
-        if (entry != NULL && entry->e_addr == w) {
-            if (entry->e_name != NULL) {
-                fprintf(fp, "entry label %s", entry->e_name);
+        if (entry != NULL && entry->MR_entry_addr == w) {
+            if (entry->MR_entry_name != NULL) {
+                fprintf(fp, "entry label %s", entry->MR_entry_name);
             } else {
-                fprintf(fp, "unnamed entry label %p", entry->e_addr);
+                fprintf(fp, "unnamed entry label %p", entry->MR_entry_addr);
             }
         } else {
             fprintf(fp, "label UNKNOWN %p", w);
         }
-#else
-        fprintf(fp, "label UNKNOWN %p", w);
-#endif  /* not MR_NEED_ENTRY_LABEL_ARRAY */
     }
 
     if (MR_print_raw_addrs) {
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.48
diff -u -b -r1.48 mercury_goto.h
--- runtime/mercury_goto.h	29 Nov 2006 05:18:22 -0000	1.48
+++ runtime/mercury_goto.h	1 Jan 2007 15:59:05 -0000
@@ -188,7 +188,7 @@
 ** label *has* a layout structure, use the _sl variant. The difference between
 ** the _ai and the _an variants is that the latter always inserts the name
 ** of the label as well. This is intended for a small number of labels that
-** are frequently needed in debugging, e.g. do_fail.
+** are frequently needed in debugging, e.g. MR_do_fail.
 */
 
 #define MR_make_label_ai(n, a, l)		MR_insert_internal(n, a, NULL)
@@ -198,13 +198,13 @@
 							MR_LABEL_LAYOUT(l))
 
 #define MR_make_local_ai(n, a, l)		MR_insert_entry(n, a, NULL)
-#define MR_make_local_an(n, a, l)		MR_insert_entry_label(n, \
+#define MR_make_local_an(n, a, l)		MR_do_insert_entry_label(n, \
 							a, NULL)
 #define MR_make_local_sl(n, a, l)		MR_insert_entry(n, a, \
 							MR_PROC_LAYOUT(l))
 
 #define MR_make_entry_ai(n, a, l)		MR_insert_entry(n, a, NULL)
-#define MR_make_entry_an(n, a, l)		MR_insert_entry_label(n, \
+#define MR_make_entry_an(n, a, l)		MR_do_insert_entry_label(n, \
 							a, NULL)
 #define MR_make_entry_sl(n, a, l)		MR_insert_entry(n, a, \
 							MR_PROC_LAYOUT(l))
Index: runtime/mercury_label.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_label.c,v
retrieving revision 1.26
diff -u -b -r1.26 mercury_label.c
--- runtime/mercury_label.c	29 Nov 2006 05:18:23 -0000	1.26
+++ runtime/mercury_label.c	2 Jan 2007 05:32:19 -0000
@@ -21,11 +21,28 @@
 
 #include    "mercury_label.h"
 
+#include    "mercury_stack_layout.h"    /* for MR_ProcLayout */
 #include    "mercury_hash_table.h"  /* for MR_Hash_Table and its ops */
 #include    "mercury_prof.h"        /* for prof_output_addr_decl() */
 #include    "mercury_engine.h"      /* for MR_progdebug */
 #include    "mercury_wrapper.h"     /* for MR_do_init_modules() */
 
+#if defined(MR_MINIMAL_MODEL_DEBUG) && !defined(MR_TABLE_DEBUG)
+  /*
+  ** MR_MINIMAL_MODEL_DEBUG implies MR_TABLE_DEBUG in some other files, since
+  ** if we want to debug minimal model tabling we need to enable all the
+  ** debugging facilities of those files. However, since MR_TABLE_DEBUG
+  ** increases object file sizes and link times significantly (by implying
+  ** MR_DEBUG_LABEL_NAMES), we don't necessarily want this implication
+  ** to hold globally. MR_TABLE_DEBUG therefore may not be defined globally.
+  ** If it isn't defined for this file, MR_NEED_ENTRY_LABEL_INFO and
+  ** MR_NEED_ENTRY_LABEL_ARRAY probably won't be defined either.
+  */
+
+  #define   MR_NEED_ENTRY_LABEL_INFO
+  #define   MR_NEED_ENTRY_LABEL_ARRAY
+#endif
+
 /*
 ** We record information about entry labels in an array that we sort
 ** by code address once all the entry labels have been inserted.
@@ -89,7 +106,7 @@
 #ifdef  MR_NEED_ENTRY_LABEL_INFO
 
 void
-MR_insert_entry_label(const char *name, MR_Code *addr,
+MR_do_insert_entry_label(const char *name, MR_Code *addr,
     const MR_ProcLayout *entry_layout)
 {
     MR_do_init_label_tables();
@@ -98,7 +115,7 @@
     if (MR_profiling) {
         MR_prof_output_addr_decl(name, addr);
     }
-#endif
+#endif  /* MR_MPROF_PROFILE_CALLS */
 
 #ifdef  MR_LOWLEVEL_DEBUG
     if (MR_progdebug) {
@@ -113,7 +130,7 @@
             printf("recording entry label at %p\n", addr);
         }
     }
-#endif
+#endif  /* MR_LOWLEVEL_DEBUG */
 
 #ifdef  MR_NEED_ENTRY_LABEL_ARRAY
     if (entry_array_next >= entry_array_size) {
@@ -125,15 +142,27 @@
         }
     }
 
-    entry_array[entry_array_next].e_addr = addr;
-    entry_array[entry_array_next].e_name = name;
-    entry_array[entry_array_next].e_layout = entry_layout;
+    entry_array[entry_array_next].MR_entry_addr = addr;
+    entry_array[entry_array_next].MR_entry_name = name;
+    entry_array[entry_array_next].MR_entry_layout = entry_layout;
     entry_array_next++;
     entry_array_sorted = MR_FALSE;
-#endif
+#endif  /* MR_NEED_ENTRY_LABEL_ARRAY */
 }
 
-#endif
+#else   /* MR_NEED_ENTRY_LABEL_INFO */
+
+void
+MR_do_insert_entry_label(const char *name, MR_Code *addr,
+    const MR_ProcLayout *entry_layout)
+{
+    /*
+    ** Do nothing, but the function must still exist, since entry labels
+    ** defined with MR_init_entry_an will generate calls to it.
+    */
+}
+
+#endif  /* MR_NEED_ENTRY_LABEL_INFO */
 
 #ifdef  MR_NEED_ENTRY_LABEL_ARRAY
 
@@ -148,9 +177,9 @@
     entry1 = (const MR_Entry *) e1;
     entry2 = (const MR_Entry *) e2;
 
-    if (entry1->e_addr > entry2->e_addr) {
+    if (entry1->MR_entry_addr > entry2->MR_entry_addr) {
         return 1;
-    } else if (entry1->e_addr < entry2->e_addr) {
+    } else if (entry1->MR_entry_addr < entry2->MR_entry_addr) {
         return -1;
     } else {
         return 0;
@@ -178,29 +207,37 @@
     lo = 0;
     hi = entry_array_next-1;
 
-    if (lo > hi || addr < entry_array[lo].e_addr) {
+    if (lo > hi || addr < entry_array[lo].MR_entry_addr) {
         return NULL;
     }
 
     while (lo <= hi) {
         mid = (lo + hi) / 2;
-        if (entry_array[mid].e_addr == addr) {
+        if (entry_array[mid].MR_entry_addr == addr) {
             return &entry_array[mid];
-        } else if (entry_array[mid].e_addr < addr) {
+        } else if (entry_array[mid].MR_entry_addr < addr) {
             lo = mid + 1;
         } else {
             hi = mid - 1;
         }
     }
 
-    if (lo < entry_array_next && entry_array[lo].e_addr < addr) {
+    if (lo < entry_array_next && entry_array[lo].MR_entry_addr < addr) {
         return &entry_array[lo];
     } else {
         return &entry_array[lo - 1];
     }
 }
 
-#endif
+#else   /* MR_NEED_ENTRY_LABEL_ARRAY */
+
+MR_Entry *
+MR_prev_entry_by_addr(const MR_Code *addr)
+{
+    return NULL;
+}
+
+#endif  /* MR_NEED_ENTRY_LABEL_ARRAY */
 
 void
 MR_insert_internal_label(const char *name, MR_Code *addr,
@@ -212,9 +249,9 @@
     MR_do_init_label_tables();
 
     internal = MR_GC_NEW(MR_Internal);
-    internal->i_addr = addr;
-    internal->i_layout = label_layout;
-    internal->i_name = name;
+    internal->MR_internal_addr = addr;
+    internal->MR_internal_layout = label_layout;
+    internal->MR_internal_name = name;
 
 #ifdef  MR_LOWLEVEL_DEBUG
     if (MR_progdebug) {
@@ -249,8 +286,8 @@
         ** either of their layout structures.
         */
 
-        if (prev_internal->i_layout == NULL) {
-            prev_internal->i_layout = label_layout;
+        if (prev_internal->MR_internal_layout == NULL) {
+            prev_internal->MR_internal_layout = label_layout;
         }
     }
 }
@@ -276,7 +313,8 @@
     if (internal == NULL) {
         return NULL;
     } else {
-        return (const void *) (((const MR_Internal *) internal)->i_addr);
+        return (const void *)
+            (((const MR_Internal *) internal)->MR_internal_addr);
     }
 }
 
@@ -298,3 +336,35 @@
     MR_do_init_label_tables();
     MR_process_all_entries(internal_addr_table, f);
 }
+
+/*
+** The code of MR_lookup_entry_or_internal is similar to, but significantly
+** simpler than, MR_print_label in mercury_debug.c
+*/
+
+const char *
+MR_lookup_entry_or_internal(const MR_Code *addr)
+{
+    MR_Internal *internal;
+    MR_Entry    *entry;
+
+    internal = MR_lookup_internal_by_addr(addr);
+    if (internal != NULL) {
+        if (internal->MR_internal_name != NULL) {
+            return internal->MR_internal_name;
+        } else {
+            return "unnamed internal label";
+        }
+    }
+
+    entry = MR_prev_entry_by_addr(addr);
+    if (entry != NULL && entry->MR_entry_addr == addr) {
+        if (entry->MR_entry_name != NULL) {
+            return entry->MR_entry_name;
+        } else {
+            return "unnamed entry label";
+        }
+    }
+
+    return "unknown";
+}
Index: runtime/mercury_label.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_label.h,v
retrieving revision 1.12
diff -u -b -r1.12 mercury_label.h
--- runtime/mercury_label.h	29 Nov 2006 05:18:23 -0000	1.12
+++ runtime/mercury_label.h	1 Jan 2007 16:07:02 -0000
@@ -23,15 +23,15 @@
 ** This struct records information about entry labels. Elements in the
 ** entry label array are of this type. The table is sorted on address,
 ** to allow the garbage collector to locate the entry label of the procedure 
-** to which an internal label belongs by a variant of binary search.
+** to which a entry label belongs by a variant of binary search.
 **
 ** The name field is needed only for low-level debugging.
 */
 
 typedef struct s_entry {
-	const MR_Code		*e_addr;
-	const MR_ProcLayout	*e_layout;
-	const char		*e_name;
+	const MR_Code		*MR_entry_addr;
+	const MR_ProcLayout	*MR_entry_layout;
+	const char		*MR_entry_name;
 } MR_Entry;
 
 /*
@@ -43,23 +43,25 @@
 */
 
 typedef struct s_internal {
-	const MR_Code		*i_addr;
-	const MR_LabelLayout	*i_layout;
-	const char		*i_name;
+	const MR_Code		*MR_internal_addr;
+	const MR_LabelLayout	*MR_internal_layout;
+	const char		*MR_internal_name;
 } MR_Internal;
 
 extern	void		MR_do_init_label_tables(void);
 
-#ifdef	MR_NEED_ENTRY_LABEL_INFO
-  extern void		MR_insert_entry_label(const char *name, MR_Code *addr,
+extern void		MR_do_insert_entry_label(const char *name,
+		  		MR_Code *addr,
 				const MR_ProcLayout *entry_layout);
+
+#ifdef	MR_NEED_ENTRY_LABEL_INFO
+  #define MR_insert_entry_label(n, a, l)		\
+	  MR_do_insert_entry_label((n), (a), (l))
 #else
   #define MR_insert_entry_label(n, a, l)	/* nothing */
 #endif	/* not MR_NEED_ENTRY_LABEL_INFO */
 
-#ifdef	MR_NEED_ENTRY_LABEL_ARRAY
-  extern MR_Entry	*MR_prev_entry_by_addr(const MR_Code *addr);
-#endif	/* MR_NEED_ENTRY_LABEL_ARRAY */
+extern MR_Entry		*MR_prev_entry_by_addr(const MR_Code *addr);
 
 extern	void		MR_insert_internal_label(const char *name,
 				MR_Code *addr,
@@ -67,4 +69,6 @@
 extern	MR_Internal	*MR_lookup_internal_by_addr(const MR_Code *addr);
 extern	void		MR_process_all_internal_labels(void f(const void *));
 
+extern	const char	*MR_lookup_entry_or_internal(const MR_Code *addr);
+
 #endif /* not MERCURY_LABEL_H */
Index: runtime/mercury_mm_own_stacks.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_mm_own_stacks.c,v
retrieving revision 1.8
diff -u -b -r1.8 mercury_mm_own_stacks.c
--- runtime/mercury_mm_own_stacks.c	27 Dec 2006 04:16:37 -0000	1.8
+++ runtime/mercury_mm_own_stacks.c	2 Jan 2007 05:33:04 -0000
@@ -16,13 +16,33 @@
 #include "mercury_array_macros.h"
 #include "mercury_tabling.h"
 #include "mercury_mm_own_stacks.h"
+#include "mercury_dlist.h"
 
 #include <stdio.h>
+#include <unistd.h>                         /* for sleep() */
+
+#ifdef  MR_MINIMAL_MODEL_DEBUG
+  /*
+  ** MR_MINIMAL_MODEL_DEBUG implies MR_TABLE_DEBUG in this file, since
+  ** if we want to debug minimal model tabling we need to enable all the
+  ** debugging facilities of this file. However, since MR_TABLE_DEBUG
+  ** increases object file sizes and link times significantly (by implying
+  ** MR_DEBUG_LABEL_NAMES), we don't necessarily want this implication
+  ** to hold globally.
+  */
+
+  #define   MR_TABLE_DEBUG
+#endif
 
 #ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
 
+MR_declare_entry(MR_mmos_initialize_generator);
+
 MR_Word                 MR_mmos_arg_regs[MR_MAX_FAKE_REG];
 MR_GeneratorPtr         MR_mmos_new_generator;
+MR_GeneratorPtr         MR_mmos_returning_generator;
+
+static MR_Context *     MR_get_context_for_gen(MR_GeneratorPtr generator);
 
 #if 0
 static  void            MR_table_mmos_make_gen_follow_leader(
@@ -138,16 +158,18 @@
     }
 
     if (cons_debug->MR_cod_version_num > 0) {
-        sprintf(buf, "con %d/%d (%p)%s for %s",
+        sprintf(buf, "con%d/%d (%p)%s of %s",
             cons_debug->MR_cod_sequence_num,
             cons_debug->MR_cod_version_num,
             cons_debug->MR_cod_consumer, warning,
-            cons_debug->MR_cod_consumer->MR_cons_pred_id);
+            MR_gen_subgoal(cons_debug->MR_cod_consumer->
+                MR_cons_answer_generator));
     } else {
-        sprintf(buf, "con %d (%p)%s for %s",
+        sprintf(buf, "con%d (%p)%s of %s",
             cons_debug->MR_cod_sequence_num,
             cons_debug->MR_cod_consumer, warning,
-            cons_debug->MR_cod_consumer->MR_cons_pred_id);
+            MR_gen_subgoal(cons_debug->MR_cod_consumer->
+                MR_cons_answer_generator));
     }
 
     return strdup(buf);
@@ -167,6 +189,20 @@
 }
 
 const char *
+MR_cons_addr_short_name(MR_Consumer *consumer)
+{
+    MR_ConsDebug *cons_debug;
+    char        buf[MR_NAME_BUF];
+
+    if (consumer == NULL) {
+        return "NULL";
+    }
+
+    sprintf(buf, "con%d", cons_debug->MR_cod_sequence_num);
+    return strdup(buf);
+}
+
+const char *
 MR_cons_num_name(int cons_index)
 {
     MR_ConsDebug *cons_debug;
@@ -243,16 +279,16 @@
     }
 
     if (gen_debug->MR_gd_version_num > 0) {
-        sprintf(buf, "gen %d/%d (%p)%s for %s",
+        sprintf(buf, "gen%d/%d (%p)%s for %s",
             gen_debug->MR_gd_sequence_num,
             gen_debug->MR_gd_version_num,
             gen_debug->MR_gd_generator, warning,
-            gen_debug->MR_gd_generator->MR_gen_pred_id);
+            MR_gen_subgoal(gen_debug->MR_gd_generator));
     } else {
-        sprintf(buf, "gen %d (%p)%s for %s",
+        sprintf(buf, "gen%d (%p)%s for %s",
             gen_debug->MR_gd_sequence_num,
             gen_debug->MR_gd_generator, warning,
-            gen_debug->MR_gd_generator->MR_gen_pred_id);
+            MR_gen_subgoal(gen_debug->MR_gd_generator));
     }
 
     return strdup(buf);
@@ -272,6 +308,76 @@
 }
 
 const char *
+MR_gen_addr_short_name(MR_Generator *generator)
+{
+    MR_GenDebug *gen_debug;
+    char        buf[MR_NAME_BUF];
+
+    if (generator == NULL) {
+        return "NULL";
+    }
+
+    gen_debug = MR_lookup_gen_debug_addr(generator);
+    sprintf(buf, "gen%d", gen_debug->MR_gd_sequence_num);
+    return strdup(buf);
+}
+
+const char *
+MR_gen_subgoal(MR_Generator *generator)
+{
+    char        buf[MR_NAME_BUF];
+
+    if (generator == NULL) {
+        return "NULL";
+    }
+
+     /*
+    ** The argument registers will be meaningful only if they contain integers,
+    ** but that is sufficient for debugging. Likewise, debugging can be done
+    ** with predicates of no more than three input arguments; printing more
+    ** arguments would lead to excessively long event report lines in mdb.
+    */
+
+    switch (generator->MR_gen_num_input_args) {
+        case 0:
+                sprintf(buf, "%s",
+                    generator->MR_gen_pred_id);
+                break;
+
+        case 1:
+                sprintf(buf, "%s(%d)",
+                    generator->MR_gen_pred_id,
+                    generator->MR_gen_input_args[0]);
+                break;
+
+        case 2:
+                sprintf(buf, "%s(%d,%d)",
+                    generator->MR_gen_pred_id,
+                    generator->MR_gen_input_args[0],
+                    generator->MR_gen_input_args[1]);
+                break;
+
+        case 3:
+                sprintf(buf, "%s(%d,%d,%d)",
+                    generator->MR_gen_pred_id,
+                    generator->MR_gen_input_args[0],
+                    generator->MR_gen_input_args[1],
+                    generator->MR_gen_input_args[2]);
+                break;
+
+        default:
+                sprintf(buf, "%s(%d,%d,%d,...)",
+                    generator->MR_gen_pred_id,
+                    generator->MR_gen_input_args[0],
+                    generator->MR_gen_input_args[1],
+                    generator->MR_gen_input_args[2]);
+                break;
+    }
+
+    return strdup(buf);
+}
+
+const char *
 MR_gen_num_name(int gen_index)
 {
     MR_GenDebug *gen_debug;
@@ -295,10 +401,11 @@
 MR_print_generator(FILE *fp, const MR_ProcLayout *proc,
     MR_Generator *generator)
 {
-    MR_SubgoalList  follower;
-    MR_ConsumerList consumer;
     MR_AnswerList   answer_list;
     MR_Word         *answer;
+    MR_Dlist        *list;
+    MR_ConsumerPtr  consumer;
+    MR_GeneratorPtr follower;
     int             answer_num;
 
     if (generator == NULL) {
@@ -307,8 +414,8 @@
     }
 
 #ifdef  MR_TABLE_DEBUG
-    if (proc == NULL && generator->MR_sg_proc_layout != NULL) {
-        proc = generator->MR_sg_proc_layout;
+    if (proc == NULL && generator->MR_gen_proc_layout != NULL) {
+        proc = generator->MR_gen_proc_layout;
     }
 #endif
 
@@ -324,29 +431,51 @@
         fprintf(fp, "\n");
     }
 
-#if 0
-    fprintf(fp, "leader: %s, ",
-        MR_gen_addr_name(generator->MR_sg_leader));
-    fprintf(fp, "followers:");
-    for (follower = generator->MR_sg_followers;
-        follower != NULL; follower = follower->MR_sl_next)
-    {
-        fprintf(fp, " %s", MR_gen_addr_name(follower->MR_sl_item));
+    if (generator->MR_gen_is_complete) {
+        fprintf(fp, "complete\n");
+    } else {
+        fprintf(fp, "not complete\n");
     }
 
-    fprintf(fp, "\nconsumers:");
-    for (consumer = generator->MR_sg_cons_list;
-        consumer != NULL; consumer = consumer->MR_cl_next)
-    {
-        fprintf(fp, " %s", MR_cons_addr_name(consumer->MR_cl_item));
+    if (generator->MR_gen_leader == generator) {
+        fprintf(fp, "own leader\n");
+    } else {
+        fprintf(fp, "leader: %s\n",
+            MR_gen_addr_name(generator->MR_gen_leader));
+    }
+
+    if (MR_dlist_maybe_null_length(generator->MR_gen_led_generators) > 0) {
+        fprintf(fp, "followers:\n");
+        MR_for_dlist (list, generator->MR_gen_led_generators) {
+            follower = (MR_GeneratorPtr) MR_dlist_data(list);
+            fprintf(fp, "\t%s\n", MR_gen_addr_name(follower));
+        }
+    }
+
+    fprintf(fp, "\n");
+    fprintf(fp, "consumers:\n");
+    MR_for_dlist (list, generator->MR_gen_consumers) {
+        consumer = (MR_ConsumerPtr) MR_dlist_data(list);
+
+        fprintf(fp, "\t%s", MR_cons_addr_name(consumer));
+
+        if (consumer->MR_cons_containing_generator != NULL) {
+            fprintf(fp, " in %s",
+                MR_gen_addr_name(consumer->MR_cons_containing_generator));
+        } else {
+            fprintf(fp, " in main context");
+        }
+
+        fprintf(fp, " (returned %d)\n",
+            consumer->MR_cons_num_returned_answers);
     }
 
     fprintf(fp, "\n");
-    fprintf(fp, "answers: %d\n", generator->MR_sg_num_ans);
+    fprintf(fp, "answers: %d\n", generator->MR_gen_num_answers);
 
     if (proc != NULL) {
-        answer_list = generator->MR_sg_answer_list;
-        answer_num = 1;
+        answer_list = generator->MR_gen_answer_list;
+        answer_num = 0;
         while (answer_list != NULL) {
             fprintf(fp, "answer #%d: <", answer_num);
             MR_print_answerblock(fp, proc, answer_list->MR_aln_answer_block);
@@ -355,7 +484,6 @@
             answer_num++;
         }
     }
-#endif
 }
 
 void
@@ -408,7 +536,7 @@
 static  int MR_next_gen_context = 1;
 
 static MR_Context *
-MR_get_context_for_gen(MR_Generator *gen)
+MR_get_context_for_gen(MR_GeneratorPtr generator)
 {
     MR_Dlist        *list;
     MR_Dlist        *item;
@@ -424,10 +552,11 @@
 
         sprintf(buf, "gen%d", MR_next_gen_context);
         MR_next_gen_context++;
-        ctxt = MR_create_context(strdup(buf), MR_CONTEXT_SIZE_SMALL, gen);
+        ctxt = MR_create_context(strdup(buf), MR_CONTEXT_SIZE_SMALL,
+            generator);
     }
 
-    ctxt->MR_ctxt_owner_generator = gen;
+    ctxt->MR_ctxt_owner_generator = generator;
     return ctxt;
 }
 
@@ -435,21 +564,45 @@
 MR_table_mmos_setup_consumer(MR_GeneratorPtr generator, MR_ConstString pred_id)
 {
     MR_ConsumerPtr  consumer;
+    MR_GeneratorPtr containing_generator;
 
     consumer = MR_TABLE_NEW(MR_Consumer);
     consumer->MR_cons_pred_id = pred_id;
     consumer->MR_cons_answer_generator = generator;
-    consumer->MR_cons_containing_generator =
+    containing_generator =
         MR_ENGINE(MR_eng_this_context)->MR_ctxt_owner_generator;
-    if (consumer->MR_cons_containing_generator != NULL) {
-        consumer->MR_cons_context = 
-            consumer->MR_cons_containing_generator->MR_gen_context;
+    consumer->MR_cons_containing_generator = containing_generator;
+    if (containing_generator != NULL) {
+        consumer->MR_cons_context = containing_generator->MR_gen_context;
+
+        /*
+        ** XXX We need to do something here to make `containing_generator'
+        ** depend on `generator'.
+        **
+        ** If the dependency is mutual, we need to make them part of the
+        ** same clique. We may delay this latter action until there is a
+        ** solution to return (since by then there may be more dependencies),
+        ** but doing it here may be better, since there may be many solutions.
+        */
     } else {
         consumer->MR_cons_context = MR_ENGINE(MR_eng_main_context);
     }
+    consumer->MR_cons_registered = MR_FALSE;
     consumer->MR_cons_num_returned_answers = 0;
     consumer->MR_cons_remaining_answer_list_ptr =
-        generator->MR_gen_answer_list_tail;
+        &generator->MR_gen_answer_list;
+
+#ifdef  MR_TABLE_DEBUG
+    MR_enter_cons_debug(consumer);
+
+    if (MR_tabledebug) {
+        /* The pred_id and address are printed as part of the consumer name. */
+        printf("setting up consumer %s\n",
+            MR_cons_addr_name(consumer));
+        printf("the relevant generator is %s\n", MR_gen_addr_name(generator));
+    }
+#endif
+
     return consumer;
 }
 
@@ -457,21 +610,34 @@
 MR_table_mmos_setup_generator(MR_TrieNode trie_node, MR_Integer num_input_args,
     MR_Word generator_pred, MR_ConstString pred_id)
 {
-    MR_GeneratorPtr gen;
+    MR_GeneratorPtr generator;
     MR_Context      *context;
+    int             i;
 
-    gen = MR_TABLE_NEW(MR_Generator);
-    context = MR_get_context_for_gen(gen);
+    generator = MR_TABLE_NEW(MR_Generator);
+    context = MR_get_context_for_gen(generator);
+    context->MR_ctxt_resume = MR_ENTRY(MR_mmos_initialize_generator);
+    generator->MR_gen_closure = generator_pred;
+
+    generator->MR_gen_back_ptr = trie_node;
+    generator->MR_gen_context = context;
+
+    generator->MR_gen_leader = generator;
+    generator->MR_gen_led_generators = MR_dlist_makelist(generator);
+    generator->MR_gen_consumers = MR_dlist_makelist0();
+    generator->MR_gen_num_answers = 0;
+    generator->MR_gen_answer_table.MR_integer = 0;
+    generator->MR_gen_answer_list = NULL;
+    generator->MR_gen_answer_list_tail = &generator->MR_gen_answer_list;
+
+    /* The following fields are for debugging */
+    generator->MR_gen_pred_id = pred_id;
+    generator->MR_gen_num_input_args = num_input_args;
+    generator->MR_gen_input_args = MR_TABLE_NEW_ARRAY(MR_Word, num_input_args);
 
-    gen->MR_gen_back_ptr = trie_node;
-    gen->MR_gen_context = context;
-    gen->MR_gen_leader = gen;
-    gen->MR_gen_led_generators = MR_dlist_makelist(gen);
-    gen->MR_gen_consumers = MR_dlist_makelist0();
-    gen->MR_gen_num_answers = 0;
-    gen->MR_gen_answer_table.MR_integer = 0;
-    gen->MR_gen_answer_list = NULL;
-    gen->MR_gen_answer_list_tail = &gen->MR_gen_answer_list;
+    for (i = 0; i < num_input_args; i++) {
+        generator->MR_gen_input_args[i] = MR_mmos_arg_regs[i];
+    }
 
     /*
     ** MR_subgoal_debug_cur_proc refers to the last procedure
@@ -486,20 +652,16 @@
     ** For implementors debugging minimal model tabling, this is
     ** the right tradeoff.
     */
-    gen->MR_gen_proc_layout = MR_subgoal_debug_cur_proc;
+    generator->MR_gen_proc_layout = MR_subgoal_debug_cur_proc;
 
 #ifdef  MR_TABLE_DEBUG
-    MR_enter_gen_debug(gen);
+    MR_enter_gen_debug(generator);
 
     if (MR_tabledebug) {
-        printf("setting up generator %p -> %s, ",
-            trie_node, MR_gen_addr_name(gen));
-        printf("answer slot %p\n", subgoal->MR_sg_answer_list_tail);
-        if (subgoal->MR_gen_proc_layout != NULL) {
-            printf("proc: ");
-            MR_print_proc_id(stdout, gen->MR_gen_proc_layout);
-            printf("\n");
-        }
+        /* The pred_id is printed as part of the generator name. */
+        printf("setting up generator %p -> %s\n",
+            trie_node, MR_gen_addr_name(generator));
+        printf("answer slot %p\n", generator->MR_gen_answer_list_tail);
     }
 
     if (MR_maxfr != MR_curfr) {
@@ -507,32 +669,11 @@
     }
 #endif
 
+    trie_node->MR_generator = generator;
     /* MR_save_transient_registers(); */
-    return gen;
+    return generator;
 }
 
-#if 0
-
-MR_AnswerBlock
-MR_table_consumer_get_next_answer(MR_ConsumerPtr consumer)
-{
-    /* not yet implemented */
-}
-
-MR_TrieNode
-MR_table_generator_get_answer_table(MR_GeneratorPtr generator)
-{
-    /* not yet implemented */
-}
-
-MR_TrieNode
-MR_table_generator_new_answer_slot(MR_GeneratorPtr generator)
-{
-    /* not yet implemented */
-}
-
-#endif /* if 0 */
-
 #endif  /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
 
 #ifdef MR_HIGHLEVEL_CODE
@@ -586,30 +727,138 @@
 
 #else   /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
 
+MR_declare_entry(mercury__do_call_closure_0);
+
+#define MR_RETURN_ALL_LABEL(name) \
+    MR_label_name(MR_MMOS_RET_ALL_NONDET_ENTRY, name)
+
+MR_declare_label(MR_RETURN_ALL_LABEL(FromTable));
+
 MR_BEGIN_MODULE(mmos_module)
     MR_init_entry_sl(MR_MMOS_RET_ALL_NONDET_ENTRY);
     MR_init_entry_sl(MR_MMOS_RET_ALL_MULTI_ENTRY);
     MR_INIT_PROC_LAYOUT_ADDR(MR_MMOS_RET_ALL_NONDET_ENTRY);
     MR_INIT_PROC_LAYOUT_ADDR(MR_MMOS_RET_ALL_MULTI_ENTRY);
+
+    MR_init_entry(MR_mmos_initialize_generator);
+
+    MR_init_label_an(MR_RETURN_ALL_LABEL(FromTable));
 MR_BEGIN_CODE
 
 MR_define_entry(MR_MMOS_RET_ALL_NONDET_ENTRY);
 {
-/*
     MR_GeneratorPtr     generator;
+    MR_ConsumerPtr  consumer;
 
-    generator = MR_r1;
+    consumer = (MR_ConsumerPtr) MR_r1;
+    generator = consumer->MR_cons_answer_generator;
 
-    XXX NumSlots 42
-    MR_mkframe("pred table_mmos_consume_next_answer_nondet/2-0", 42,
-        MR_ENTRY(MR_do_fail));
-    MR_fv(1) = MR_r1;
-*/
-    MR_fatal_error("table_mmos_consume_next_answer_nondet/2 NYI");
+    MR_mkframe("pred table_mmos_consume_next_answer_nondet/2-0", 2,
+        MR_LABEL(MR_RETURN_ALL_LABEL(FromTable)));
+    MR_fv(1) = (MR_Word) consumer;
+    MR_fv(2) = (MR_Word) generator;
+
+    /* fall through */
+}
+
+MR_define_label(MR_RETURN_ALL_LABEL(FromTable));
+{
+    MR_ConsumerPtr  consumer;
+    MR_GeneratorPtr generator;
+    MR_AnswerList   answer_list;
+
+    /*
+    ** We could and should delay the assignment to generator until we know
+    ** whether answer_list == NULL, but we need the value of generator
+    ** for the debugging code below.
+    */
+    consumer = (MR_ConsumerPtr) MR_fv(1);
+    generator = (MR_GeneratorPtr) MR_fv(2);
+
+    answer_list = *(consumer->MR_cons_remaining_answer_list_ptr);
+    if (answer_list != NULL) {
+        if (consumer->MR_cons_num_returned_answers
+            >= generator->MR_gen_num_answers)
+        {
+            MR_fatal_error("table_mmos_consume_next_answer_nondet: "
+                "answer list says solution, numbers say no solution");
+        }
+
+        if (MR_tabledebug) {
+            printf("consumer %s returning answer #%d from table\n",
+                MR_cons_addr_name(consumer),
+                consumer->MR_cons_num_returned_answers);
+        }
+
+        consumer->MR_cons_num_returned_answers++;
+
+        MR_r1 = (MR_Word) answer_list->MR_aln_answer_block;
+        consumer->MR_cons_remaining_answer_list_ptr =
+            &answer_list->MR_aln_next_answer;
+        MR_succeed();
+    } else {
+        if (generator->MR_gen_is_complete) {
+            if (MR_tabledebug) {
+                printf("consumer %s failing; generator %s complete\n",
+                    MR_cons_addr_name(consumer),
+                    MR_gen_addr_name(generator));
+            }
+
+            MR_fail();
+        } else {
+            /* XXX Investigate the performance effects of adding at tail. */
+            if (!consumer->MR_cons_registered) {
+                if (MR_tabledebug) {
+                    printf("registering %s with %s\n",
+                        MR_cons_addr_name(consumer),
+                        MR_gen_addr_name(generator));
+                }
+
+                generator->MR_gen_consumers =
+                    MR_dlist_addhead(generator->MR_gen_consumers, consumer);
+                consumer->MR_cons_registered = MR_TRUE;
+            }
+
+            if (MR_tabledebug) {
+                printf("consumer %s needs #%d from %s\n",
+                    MR_cons_addr_name(consumer),
+                    consumer->MR_cons_num_returned_answers,
+                    MR_gen_addr_name(generator));
+                /*
+                ** The sleep is to allow the infinite loop that happens here
+                ** to be interrupted from the keyboard.
+                */
+                sleep(1);
+            }
+
+            MR_save_context(consumer->MR_cons_context);
+            consumer->MR_cons_context->MR_ctxt_resume =
+                MR_LABEL(MR_RETURN_ALL_LABEL(FromTable));
+            MR_load_context(generator->MR_gen_context);
+            MR_ENGINE(MR_eng_this_context) = generator->MR_gen_context;
+            MR_GOTO(generator->MR_gen_context->MR_ctxt_resume);
+        }
+    }
 }
 
 MR_define_entry(MR_MMOS_RET_ALL_MULTI_ENTRY);
-    MR_fatal_error("table_mmos_consume_next_answer_multi/2 NYI");
+    /*
+    ** Although the two predicates differ in their determinism,
+    ** their implementation is the same.
+    */
+    MR_GOTO_ENTRY(MR_MMOS_RET_ALL_NONDET_ENTRY);
+
+MR_define_entry(MR_mmos_initialize_generator);
+{
+    MR_Context      *context;
+    MR_GeneratorPtr generator;
+
+    context = MR_ENGINE(MR_eng_this_context);
+    generator = context->MR_ctxt_owner_generator;
+    assert(generator != NULL);
+    MR_r1 = generator->MR_gen_closure;
+    MR_GOTO_ENTRY(mercury__do_call_closure_0);
+}
 
 MR_END_MODULE
 
Index: runtime/mercury_mm_own_stacks.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_mm_own_stacks.h,v
retrieving revision 1.6
diff -u -b -r1.6 mercury_mm_own_stacks.h
--- runtime/mercury_mm_own_stacks.h	27 Dec 2006 04:16:37 -0000	1.6
+++ runtime/mercury_mm_own_stacks.h	2 Jan 2007 04:54:41 -0000
@@ -49,14 +49,19 @@
 ** list. Not yet functional.
 **
 ** XXX more fields
+**
+** XXX Try encoding the value of MR_cons_registered in the redoip.
 */
 
 struct MR_Generator_Struct {
     MR_TrieNode             MR_gen_back_ptr;
     MR_Context              *MR_gen_context;
     const MR_ProcLayout     *MR_gen_proc_layout;
-    MR_String               *MR_gen_pred_id;
-    MR_Generator            *MR_gen_leader;
+    MR_ConstString          MR_gen_pred_id;
+    MR_Integer              MR_gen_num_input_args;
+    MR_Word                 *MR_gen_input_args;
+    MR_Word                 MR_gen_closure;
+    MR_GeneratorPtr         MR_gen_leader;
     MR_Dlist                *MR_gen_led_generators;
     MR_Dlist                *MR_gen_consumers;
     MR_Integer              MR_gen_num_answers;
@@ -68,9 +73,10 @@
 
 struct MR_Consumer_Struct {
     MR_ConstString          MR_cons_pred_id;
-    MR_Generator            *MR_cons_answer_generator;
-    MR_Generator            *MR_cons_containing_generator;
+    MR_GeneratorPtr         MR_cons_answer_generator;
+    MR_GeneratorPtr         MR_cons_containing_generator;
     MR_Context              *MR_cons_context;
+    MR_bool                 MR_cons_registered;
     MR_Integer              MR_cons_num_returned_answers;
     MR_AnswerList           *MR_cons_remaining_answer_list_ptr;
 };
@@ -80,6 +86,8 @@
 extern  MR_Word         MR_mmos_arg_regs[MR_MAX_FAKE_REG];
 extern  MR_GeneratorPtr MR_mmos_new_generator;
 
+extern  MR_GeneratorPtr MR_mmos_returning_generator;
+
 #define MR_table_mmos_save_input_arg(pos, arg)                          \
                         do {                                            \
                             MR_mmos_arg_regs[(pos)] = (arg);            \
@@ -100,6 +108,7 @@
 extern  MR_ConsDebug    *MR_lookup_cons_debug_num(int consumer_index);
 extern  const char      *MR_cons_debug_name(MR_ConsDebug *consumer_dbg);
 extern  const char      *MR_cons_addr_name(MR_Consumer *consumer);
+extern  const char      *MR_cons_addr_short_name(MR_Consumer *consumer);
 extern  const char      *MR_cons_num_name(int consumer_index);
 
 extern  void            MR_enter_gen_debug(MR_Generator *gen);
@@ -107,6 +116,8 @@
 extern  MR_GenDebug     *MR_lookup_gen_debug_num(int gen_index);
 extern  const char      *MR_gen_debug_name(MR_GenDebug *gen_debug);
 extern  const char      *MR_gen_addr_name(MR_Generator *gen);
+extern  const char      *MR_gen_addr_short_name(MR_Generator *gen);
+extern  const char      *MR_gen_subgoal(MR_Generator *gen);
 extern  const char      *MR_gen_num_name(int gen_index);
 
 extern  void            MR_print_gen_debug(FILE *fp,
@@ -128,8 +139,6 @@
                             MR_Integer num_input_args,
                             MR_Word genererator_pred,
                             MR_ConstString pred_id);
-extern  MR_AnswerBlock  MR_table_mmos_consumer_get_next_answer(
-                            MR_ConsumerPtr consumer);
 
 #endif  /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
 
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.77
diff -u -b -r1.77 mercury_stack_trace.c
--- runtime/mercury_stack_trace.c	5 Dec 2006 03:51:13 -0000	1.77
+++ runtime/mercury_stack_trace.c	2 Jan 2007 04:47:44 -0000
@@ -131,7 +131,7 @@
         if (label == NULL) {
             fprintf(stderr, "internal label not found\n");
         } else {
-            label_layout = label->i_layout;
+            label_layout = label->MR_internal_layout;
             result = MR_dump_stack_from_layout(stderr, label_layout,
                 det_stack_pointer, current_frame, include_trace_data,
                 MR_TRUE, 0, 0, &MR_dump_stack_record_print);
@@ -338,12 +338,12 @@
         return MR_STEP_ERROR_AFTER;
     }
 
-    if (label->i_layout == NULL) {
+    if (label->MR_internal_layout == NULL) {
         *problem_ptr = "reached label with no stack layout info";
         return MR_STEP_ERROR_AFTER;
     }
 
-    *return_label_layout = label->i_layout;
+    *return_label_layout = label->MR_internal_layout;
     return MR_STEP_OK;
 }
 
@@ -845,11 +845,11 @@
                 &base_sp, &base_curfr, &problem);
         } else {
             internal = MR_lookup_internal_by_addr(redoip);
-            if (internal == NULL || internal->i_layout == NULL) {
+            if (internal == NULL || internal->MR_internal_layout == NULL) {
                 return "cannot find redoip label's layout structure";
             }
 
-            label_layout = internal->i_layout;
+            label_layout = internal->MR_internal_layout;
             (*func)(func_data, MR_TOP_FRAME_ON_SIDE_BRANCH, NULL, label_layout,
                 NULL, fr, level_number);
             MR_erase_temp_redoip(fr);
@@ -1251,9 +1251,17 @@
             depth = MR_call_depth_framevar(base_curfr);
         }
 
+        /*
+        ** The code below does has a job that is very similar to the job
+        ** of the function MR_trace_event_print_internal_report in
+        ** trace/mercury_trace_internal.c. Any changes here will probably
+        ** require similar changes there.
+        */
+
         if (MR_standardize_event_details) {
             char    buf[64];    /* plenty big enough */
 
+            /* Do not print the context id, since it is not standardized. */
             event_num = MR_standardize_event_num(event_num);
             call_num = MR_standardize_call_num(call_num);
             snprintf(buf, 64, "E%lu", event_num);
@@ -1262,6 +1270,10 @@
             fprintf(fp, "%7s ", buf);
             fprintf(fp, "%4lu ", depth);
         } else {
+            /*
+            ** Do not print the context id, since it is the same for
+            ** all the calls in the stack.
+            */
             fprintf(fp, "%7lu %7lu %4lu ", event_num, call_num, depth);
         }
     } else {
Index: runtime/mercury_tabling_preds.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling_preds.h,v
retrieving revision 1.10
diff -u -b -r1.10 mercury_tabling_preds.h
--- runtime/mercury_tabling_preds.h	27 Dec 2006 04:16:37 -0000	1.10
+++ runtime/mercury_tabling_preds.h	2 Jan 2007 05:29:59 -0000
@@ -778,8 +778,6 @@
         MR_AnswerListNode   *answer_node;                                   \
         MR_Word             **Slot;                                         \
                                                                             \
-        Generator->MR_gen_num_answers++;                                    \
-                                                                            \
         /*                                                                  \
         ** We fill in the answer_data slot with a dummy value.              \
         ** This slot will be filled in by the next piece of code            \
@@ -800,6 +798,8 @@
                 Generator->MR_gen_answer_list_tail);                        \
         }                                                                   \
                                                                             \
+        Generator->MR_gen_num_answers++;                                    \
+                                                                            \
         *(Generator->MR_gen_answer_list_tail) = answer_node;                \
         Generator->MR_gen_answer_list_tail =                                \
             &(answer_node->MR_aln_next_answer);                             \
@@ -808,34 +808,75 @@
         AnswerBlock = *Slot;                                                \
     } while(0)
 
-#else   /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
-
-#define MR_MMOS_ERROR  \
-        "own stack minimal model code entered when not enabled"
-
-#define MR_tbl_mmos_save_inputs_shortcut(num_inputs)                        \
+#define MR_tbl_mmos_return_answer(debug, generator)                         \
     do {                                                                    \
-        MR_fatal_error(MR_MMOS_ERROR);                                      \
-    } while(0)
-#define MR_tbl_mmos_consume_next_answer_nondet(consumer, answerblock, succ) \
-    do {                                                                    \
-        MR_fatal_error(MR_MMOS_ERROR);                                      \
+        MR_Dlist        *list;                                              \
+        MR_ConsumerPtr  consumer;                                           \
+        MR_Code         *target;                                            \
+                                                                            \
+        if (debug && MR_tabledebug) {                                       \
+            printf("generator %s returning answer #%d\n",                   \
+                MR_gen_addr_name(generator),                                \
+                generator->MR_gen_num_answers);                             \
+        }                                                                   \
+                                                                            \
+        /*                                                                  \
+        ** The choice of the consumer to return an answer to, made here,    \
+        ** implements the scheduling strategy. There is a wide range of     \
+        ** possible strategies, and we should investigate several.          \
+        ** For now, we use the simplest possible strategy.                  \
+        */                                                                  \
+                                                                            \
+        MR_for_dlist (list, generator->MR_gen_consumers) {                  \
+            consumer = (MR_ConsumerPtr) MR_dlist_data(list);                \
+            if (*(consumer->MR_cons_remaining_answer_list_ptr) != NULL) {   \
+                target = consumer->MR_cons_context->MR_ctxt_resume;         \
+                if (debug && MR_tabledebug) {                               \
+                    printf("scheduling consumer %s\n",                      \
+                        MR_cons_addr_name(consumer));                       \
+                    printf("resume target %p (%s)\n",                       \
+                        target, MR_lookup_entry_or_internal(target));       \
+                }                                                           \
+                                                                            \
+                MR_save_context(generator->MR_gen_context);                 \
+                generator->MR_gen_context->MR_ctxt_resume =                 \
+                    MR_ENTRY(MR_do_redo);                                   \
+                MR_load_context(consumer->MR_cons_context);                 \
+                MR_ENGINE(MR_eng_this_context) = consumer->MR_cons_context; \
+                MR_GOTO(consumer->MR_cons_context->MR_ctxt_resume);         \
+            }                                                               \
+        }                                                                   \
+                                                                            \
+        MR_fatal_error("MR_tbl_mmos_return_answer: no waiting consumers");  \
     } while(0)
-#define MR_tbl_mmos_get_answer_table(generator, trienode)                   \
+
+#define MR_tbl_mmos_completion(debug, generator)                            \
     do {                                                                    \
-        MR_fatal_error(MR_MMOS_ERROR);                                      \
+        /* This code is a placeholder, since it doesn't work with coups. */ \
+        generator->MR_gen_is_complete = MR_TRUE;                            \
+                                                                            \
+        if (debug && MR_tabledebug) {                                       \
+            printf("completing generator %s\n",                             \
+                MR_gen_addr_name(generator));                               \
+        }                                                                   \
+                                                                            \
+        MR_fail();                                                          \
     } while(0)
 
+#else   /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
+#define MR_MMOS_ERROR  \
+        "own stack minimal model code entered when not enabled"
+
 #define MR_tbl_mmos_create_answer_block(debug, Generator, Size, AnswerBlock)\
     do {                                                                    \
         MR_fatal_error(MR_MMOS_ERROR);                                      \
     } while(0)
-
-#define MR_tbl_mmos_return_answer(generator, answerblock)                   \
+#define MR_tbl_mmos_return_answer(debug, generator)                         \
     do {                                                                    \
         MR_fatal_error(MR_MMOS_ERROR);                                      \
     } while(0)
-#define MR_tbl_mmos_completion(generator)                                   \
+#define MR_tbl_mmos_completion(debug, generator)                            \
     do {                                                                    \
         MR_fatal_error(MR_MMOS_ERROR);                                      \
     } while(0)
Index: runtime/mercury_trace_base.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_trace_base.c,v
retrieving revision 1.79
diff -u -b -r1.79 mercury_trace_base.c
--- runtime/mercury_trace_base.c	29 Nov 2006 05:18:27 -0000	1.79
+++ runtime/mercury_trace_base.c	1 Jan 2007 15:59:13 -0000
@@ -1436,8 +1436,7 @@
     ** If this code ever needs changing, you may also need to change
     ** the code in extras/exceptions/exception.m similarly.
     */
-    if (MR_redo_fromfull_framevar(MR_redofr_slot(MR_curfr)))
-    {
+    if (MR_redo_fromfull_framevar(MR_redofr_slot(MR_curfr))) {
         MR_Code *MR_jumpaddr;
         MR_save_transient_registers();
         MR_jumpaddr = MR_trace((const MR_LabelLayout *)
Index: runtime/mercury_type_tables.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_type_tables.c,v
retrieving revision 1.11
diff -u -b -r1.11 mercury_type_tables.c
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.176
diff -u -b -r1.176 mercury_wrapper.c
--- runtime/mercury_wrapper.c	27 Dec 2006 04:16:37 -0000	1.176
+++ runtime/mercury_wrapper.c	1 Jan 2007 14:52:05 -0000
@@ -550,7 +550,7 @@
     MR_trace_count_enabled = MR_FALSE;
     MR_update_trace_func_enabled();
 
-#ifdef MR_NEED_INITIALIZATION_AT_START
+#if defined(MR_NEED_INITIALIZATION_AT_START) || defined(MR_MINIMAL_MODEL_DEBUG)
     MR_do_init_modules();
 #endif
 
@@ -671,6 +671,12 @@
   #endif
 #endif
 
+#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
+    MR_ENGINE(MR_eng_main_context) = MR_NEW(MR_Context);
+    MR_save_context(MR_ENGINE(MR_eng_main_context));
+    MR_ENGINE(MR_eng_this_context) = MR_ENGINE(MR_eng_main_context);
+#endif
+
     /*
     ** Now the real tracing starts; undo any updates to the trace state
     ** made by the trace code in the library initializer.
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
Index: tools/lmc.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/tools/lmc.in,v
retrieving revision 1.9
diff -u -b -r1.9 lmc.in
--- tools/lmc.in	24 Nov 2006 03:48:25 -0000	1.9
+++ tools/lmc.in	3 Jan 2007 05:10:50 -0000
@@ -102,7 +102,7 @@
 
 if test "$MMC_CDEBUG" != ""
 then
-	CDEBUG_FLAGS="--target-debug"
+	CDEBUG_FLAGS="--target-debug --cflags -O0"
 else
 	CDEBUG_FLAGS=""
 fi
cvs diff: Diffing trace
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.102
diff -u -b -r1.102 mercury_trace.c
--- trace/mercury_trace.c	27 Dec 2006 04:16:38 -0000	1.102
+++ trace/mercury_trace.c	1 Jan 2007 17:41:08 -0000
@@ -57,9 +57,10 @@
 #include <stdio.h>
 
 MR_TraceCmdInfo MR_trace_ctrl = {
-    MR_CMD_GOTO,
+    MR_CMD_STEP,
     0,                      /* stop depth */
     0,                      /* stop event */
+    NULL,                   /* stop generator */
     MR_PRINT_LEVEL_SOME,
     MR_FALSE,               /* not strict */
 #ifdef  MR_TRACE_CHECK_INTEGRITY
@@ -218,7 +219,7 @@
                 layout, path, lineno, &stop_collecting);
             MR_copy_saved_regs_to_regs(event_info.MR_max_mr_num, saved_regs);
             if (stop_collecting) {
-                MR_trace_ctrl.MR_trace_cmd = MR_CMD_GOTO;
+                MR_trace_ctrl.MR_trace_cmd = MR_CMD_STEP;
                 return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
                     seqno, depth);
             }
@@ -229,8 +230,25 @@
             goto check_stop_print;
           }
 
+        case MR_CMD_STEP:
+            port = (MR_TracePort) layout->MR_sll_port;
+            return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
+                seqno, depth);
+
         case MR_CMD_GOTO:
-            if (MR_trace_event_number >= MR_trace_ctrl.MR_trace_stop_event) {
+#if 0
+            /* This code is here in case this needs to be debugged again. */
+            printf("owner generator %p\n",
+                MR_ENGINE(MR_eng_this_context)->MR_ctxt_owner_generator);
+            printf("owner generator name %s\n",
+                MR_gen_addr_name(
+                    MR_ENGINE(MR_eng_this_context)->MR_ctxt_owner_generator));
+#endif
+
+            if (MR_trace_event_number >= MR_trace_ctrl.MR_trace_stop_event
+                && MR_cur_generator_is_named(
+                    MR_trace_ctrl.MR_trace_stop_generator))
+            {
                 port = (MR_TracePort) layout->MR_sll_port;
                 return MR_trace_event(&MR_trace_ctrl, MR_TRUE, layout, port,
                     seqno, depth);
@@ -1371,7 +1389,7 @@
     int                     record_ptr_next;
     int                     frame_size;
     int                     cur_gen;
-    MR_Internal             *label;
+    MR_Internal             *internal;
     int                     i;
     MR_bool                 any_missing_generators;
 
@@ -1415,19 +1433,19 @@
         */
 
         redoip = MR_redoip_slot(cur_maxfr);
-        label = MR_lookup_internal_by_addr(redoip);
-        if (label == NULL) {
+        internal = MR_lookup_internal_by_addr(redoip);
+        if (internal == NULL) {
             /* code in this file depends on the exact string we return here */
             *problem = "reached unknown label";
             return MR_RETRY_ERROR;
         }
 
-        if (label->i_layout == NULL) {
+        if (internal->MR_internal_layout == NULL) {
             *problem = "reached label without debugging info";
             return MR_RETRY_ERROR;
         }
 
-        label_layout = label->i_layout;
+        label_layout = internal->MR_internal_layout;
         proc_layout = label_layout->MR_sll_entry;
 
         if (! MR_PROC_LAYOUT_HAS_EXEC_TRACE(proc_layout)) {
Index: trace/mercury_trace.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.h,v
retrieving revision 1.35
diff -u -b -r1.35 mercury_trace.h
--- trace/mercury_trace.h	29 Nov 2006 05:18:33 -0000	1.35
+++ trace/mercury_trace.h	2 Jan 2007 04:54:40 -0000
@@ -156,8 +156,14 @@
 ** the `stop_collecting' variable is set to MR_TRUE. It is the tracer mode
 ** after a `collect' request.
 **
+** If MR_trace_cmd == MR_CMD_STEP, the event handler will stop at the next
+** event.
+**
 ** If MR_trace_cmd == MR_CMD_GOTO, the event handler will stop at the next
 ** event whose event number is equal to or greater than MR_trace_stop_event.
+** In own stack minimal model grades, the MR_trace_stop_generator has to match
+** the current context as well, the matching being defined by the
+** MR_cur_generator_is_named() macro
 **
 ** If MR_trace_cmd == MR_CMD_NEXT, the event handler will stop at the next
 ** event at depth MR_trace_stop_depth.
@@ -193,6 +199,7 @@
 
 typedef enum {
     MR_CMD_COLLECT,
+    MR_CMD_STEP,
     MR_CMD_GOTO,
     MR_CMD_NEXT,
     MR_CMD_FINISH,
@@ -230,9 +237,14 @@
     MR_Unsigned             MR_trace_stop_depth;
                             /*
                             ** The MR_trace_stop_event field is meaningful
-                            ** if MR_trace_cmd is MR_CMD_GOTO  .
+                            ** if MR_trace_cmd is MR_CMD_GOTO.
+                            **
+                            ** The MR_trace_stop_generator field is meaningful
+                            ** if MR_trace_cmd is MR_CMD_GOTO and the grade
+                            ** is own stack minimal model.
                             */
     MR_Unsigned             MR_trace_stop_event;
+    const char              *MR_trace_stop_generator;
     MR_TracePrintLevel      MR_trace_print_level;
     MR_bool                 MR_trace_strict;
 #ifdef  MR_TRACE_CHECK_INTEGRITY
@@ -262,6 +274,50 @@
 
 extern  MR_TraceCmdInfo     MR_trace_ctrl;
 
+/*
+** MR_cur_generator_is_named(genname) succeeds if the current context
+** belongs to a generator named `genname' (using either MR_gen_addr_short_name
+** or MR_gen_subgoal), or genname is NULL or the empty string and the current
+** context does not belong to a generator.
+*/
+
+#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
+  #define   MR_cur_generator_is_named(genname)                              \
+    (                                                                       \
+        (MR_ENGINE(MR_eng_this_context) != NULL)                            \
+    &&                                                                      \
+        (                                                                   \
+            (                                                               \
+                (MR_ENGINE(MR_eng_this_context)->MR_ctxt_owner_generator    \
+                    == NULL)                                                \
+            &&                                                              \
+                ((genname) == NULL || MR_streq((genname), ""))              \
+            )                                                               \
+        ||                                                                  \
+            (                                                               \
+                (MR_ENGINE(MR_eng_this_context)->MR_ctxt_owner_generator    \
+                    != NULL)                                                \
+            &&                                                              \
+                ((genname) != NULL)                                         \
+            &&                                                              \
+                (                                                           \
+                    MR_streq((genname),                                     \
+                        MR_gen_addr_short_name(                             \
+                            MR_ENGINE(MR_eng_this_context)->                \
+                            MR_ctxt_owner_generator))                       \
+                ||                                                          \
+                    MR_streq((genname),                                     \
+                        MR_gen_subgoal(                                     \
+                            MR_ENGINE(MR_eng_this_context)->                \
+                            MR_ctxt_owner_generator))                       \
+                )                                                           \
+            )                                                               \
+        )                                                                   \
+    )
+#else   /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+  #define   MR_cur_generator_is_named(genname)      MR_TRUE
+#endif   /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
 #ifdef  MR_TRACE_CHECK_INTEGRITY
   #define MR_init_trace_check_integrity(cmd)                            \
     do { (cmd)->MR_trace_check_integrity = MR_FALSE; } while (0)
Index: trace/mercury_trace_cmd_developer.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_cmd_developer.c,v
retrieving revision 1.5
diff -u -b -r1.5 mercury_trace_cmd_developer.c
--- trace/mercury_trace_cmd_developer.c	27 Dec 2006 04:16:39 -0000	1.5
+++ trace/mercury_trace_cmd_developer.c	1 Jan 2007 16:42:37 -0000
@@ -924,7 +924,7 @@
             break;
 
         case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
-        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_CONSUMER:
+        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_GENERATOR:
             fprintf(MR_mdb_out, "minimal model table for ");
             MR_print_proc_id(MR_mdb_out, proc);
             fprintf(MR_mdb_out, ":\n");
@@ -935,7 +935,7 @@
         case MR_EVAL_METHOD_TABLE_IO_DECL:
         case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
         case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
-        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_GENERATOR:
+        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_CONSUMER:
             MR_fatal_error("MR_trace_cmd_table: bad eval method");
     }
 
@@ -1719,7 +1719,7 @@
             }
             break;
 
-        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_CONSUMER:
+        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_GENERATOR:
             {
                 MR_GeneratorPtr generator;
 
@@ -1758,7 +1758,7 @@
         case MR_EVAL_METHOD_TABLE_IO_DECL:
         case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
         case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
-        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_GENERATOR:
+        case MR_EVAL_METHOD_MINIMAL_OWN_STACKS_CONSUMER:
             MR_fatal_error("MR_trace_cmd_table_print_tip: bad eval method");
             break;
     }
Index: trace/mercury_trace_cmd_forward.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_cmd_forward.c,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_trace_cmd_forward.c
--- trace/mercury_trace_cmd_forward.c	29 Nov 2006 05:18:35 -0000	1.3
+++ trace/mercury_trace_cmd_forward.c	1 Jan 2007 17:46:59 -0000
@@ -48,8 +48,7 @@
     if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
         ; /* the usage message has already been printed */
     } else if (word_count == 1) {
-        cmd->MR_trace_cmd = MR_CMD_GOTO;
-        cmd->MR_trace_stop_event = MR_trace_event_number + 1;
+        cmd->MR_trace_cmd = MR_CMD_STEP;
         return STOP_INTERACTING;
     } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
         cmd->MR_trace_cmd = MR_CMD_GOTO;
@@ -67,6 +66,7 @@
     MR_EventInfo *event_info, MR_Code **jumpaddr)
 {
     MR_Unsigned n;
+    const char  *generator_name;
 
     cmd->MR_trace_strict = MR_TRUE;
     cmd->MR_trace_print_level = MR_default_print_level;
@@ -74,15 +74,39 @@
     if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
         ; /* the usage message has already been printed */
     } else if (word_count == 2 && MR_trace_is_unsigned(words[1], &n)) {
-        if (MR_trace_event_number < n) {
+        generator_name = NULL;
+        if (MR_trace_event_number < n
+            || !MR_cur_generator_is_named(generator_name))
+        {
+            cmd->MR_trace_cmd = MR_CMD_GOTO;
+            cmd->MR_trace_stop_event = n;
+            cmd->MR_trace_stop_generator = generator_name;
+            return STOP_INTERACTING;
+        } else {
+            /* XXX this message is misleading */
+            fflush(MR_mdb_out);
+            fprintf(MR_mdb_err, "The debugger cannot go to a past event.\n");
+        }
+#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
+    } else if (word_count == 3 && MR_trace_is_unsigned(words[1], &n)) {
+        generator_name = words[2];
+        if (MR_trace_event_number < n
+            || !MR_cur_generator_is_named(generator_name))
+        {
             cmd->MR_trace_cmd = MR_CMD_GOTO;
             cmd->MR_trace_stop_event = n;
+            /*
+            ** We don't ever deallocate the memory allocated here,
+            ** but this memory leak leaks only negligible amounts of memory.
+            */
+            cmd->MR_trace_stop_generator = strdup(generator_name);
             return STOP_INTERACTING;
         } else {
             /* XXX this message is misleading */
             fflush(MR_mdb_out);
             fprintf(MR_mdb_err, "The debugger cannot go to a past event.\n");
         }
+#endif
     } else {
         MR_trace_usage_cur_cmd();
     }
Index: trace/mercury_trace_declarative.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_declarative.c,v
retrieving revision 1.107
diff -u -b -r1.107 mercury_trace_declarative.c
--- trace/mercury_trace_declarative.c	11 Dec 2006 03:08:39 -0000	1.107
+++ trace/mercury_trace_declarative.c	1 Jan 2007 11:44:43 -0000
@@ -1781,8 +1781,7 @@
     /*
     ** Single step through every event.
     */
-    cmd->MR_trace_cmd = MR_CMD_GOTO;
-    cmd->MR_trace_stop_event = 0;
+    cmd->MR_trace_cmd = MR_CMD_STEP;
     cmd->MR_trace_strict = MR_TRUE;
     cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
     cmd->MR_trace_must_check = MR_FALSE;
Index: trace/mercury_trace_external.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_external.c,v
retrieving revision 1.83
diff -u -b -r1.83 mercury_trace_external.c
--- trace/mercury_trace_external.c	11 Dec 2006 03:08:38 -0000	1.83
+++ trace/mercury_trace_external.c	1 Jan 2007 11:44:10 -0000
@@ -633,8 +633,7 @@
                     &message, NULL, NULL, &jumpaddr);
                 if (retry_result == MR_RETRY_OK_DIRECT) {
                     MR_send_message_to_socket("ok");
-                    cmd->MR_trace_cmd = MR_CMD_GOTO;
-                    cmd->MR_trace_stop_event = MR_trace_event_number + 1;
+                    cmd->MR_trace_cmd = MR_CMD_STEP;
                     goto done;
                 } else {
                     MR_send_message_to_socket_format("error(\"%s\").\n",
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.231
diff -u -b -r1.231 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	3 Jan 2007 02:37:31 -0000	1.231
+++ trace/mercury_trace_internal.c	3 Jan 2007 05:03:07 -0000
@@ -1216,10 +1216,9 @@
         line = MR_trace_getline("> ", mdb_in, mdb_out);
         if (line == NULL) {
             /*
-            ** We got an EOF... we need to stop processing
-            ** the input, even though it is not syntactically
-            ** correct, otherwise we might get into an infinite
-            ** loop if we keep getting EOF.
+            ** We got an EOF... we need to stop processing the input,
+            ** even though it is not syntactically correct, otherwise we might
+            ** get into an infinite loop if we keep getting EOF.
             */
             break;
         }
@@ -1467,11 +1466,24 @@
     filename = "";
     parent_filename = "";
 
+    /*
+    ** The code below does has a job that is very similar to the job
+    ** of the function MR_print_call_trace_info in
+    ** runtime/mercury_stack_trace.c. Any changes here will probably
+    ** require similar changes there.
+    */
+
     if (MR_standardize_event_details) {
         char        buf[64];
         MR_Unsigned event_num;
         MR_Unsigned call_num;
 
+        /*
+        ** Do not print the context id. It contains the values of the arguments
+        ** cast to integers. Since those arguments may originally have been
+        ** addresses, their values may differ from run to run.
+        */
+
         event_num = MR_standardize_event_num(event_info->MR_event_number);
         call_num = MR_standardize_call_num(event_info->MR_call_seqno);
         snprintf(buf, 64, "E%ld", (long) event_num);
@@ -1480,6 +1492,16 @@
         fprintf(MR_mdb_out, "%6s ", buf);
         fprintf(MR_mdb_out, "%s", MR_port_names[event_info->MR_trace_port]);
     } else {
+#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
+        MR_Generator    *generator;
+        int             i;
+
+        generator = MR_ENGINE(MR_eng_this_context)->MR_ctxt_owner_generator;
+        if (generator != NULL) {
+            fprintf(MR_mdb_out, "%s ", MR_gen_subgoal(generator));
+        }
+#endif
+
         fprintf(MR_mdb_out, "%8ld: %6ld %2ld %s",
             (long) event_info->MR_event_number,
             (long) event_info->MR_call_seqno,
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list