[m-rev.] diff: major improvements to tabling (part 2 of 2)
Zoltan Somogyi
zs at cs.mu.OZ.AU
Tue Jul 20 14:44:00 AEST 2004
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.112
diff -u -b -r1.112 Mmakefile
--- runtime/Mmakefile 7 Jul 2004 07:11:07 -0000 1.112
+++ runtime/Mmakefile 7 Jul 2004 07:57:28 -0000
@@ -29,8 +29,8 @@
mercury_builtin_types.h \
mercury_builtin_types_proc_layouts.h \
mercury_calls.h \
- mercury_conf.h \
mercury_conf_bootstrap.h \
+ mercury_conf.h \
mercury_conf_param.h \
mercury_construct.h \
mercury_context.h \
@@ -64,19 +64,22 @@
mercury_memory_zones.h \
mercury_minimal_model.h \
mercury_misc.h \
+ mercury_mm_own_stacks.h \
mercury_overflow.h \
mercury_proc_id.h \
mercury_prof.h \
+ mercury_profiling_builtin.h \
mercury_prof_mem.h \
mercury_prof_time.h \
mercury_profiling_builtin.h \
mercury_reg_workarounds.h \
mercury_regs.h \
+ mercury_reg_workarounds.h \
mercury_runtime_util.h \
mercury_signal.h \
mercury_stack_layout.h \
- mercury_stack_trace.h \
mercury_stacks.h \
+ mercury_stack_trace.h \
mercury_std.h \
mercury_string.h \
mercury_tabling.h \
@@ -88,11 +91,11 @@
mercury_timing.h \
mercury_trace_base.h \
mercury_trail.h \
+ mercury_typeclass_info.h \
mercury_type_desc.h \
mercury_type_info.h \
- mercury_type_tables.h \
- mercury_typeclass_info.h \
mercury_types.h \
+ mercury_type_tables.h \
mercury_univ.h \
mercury_wrapper.h
@@ -148,8 +151,8 @@
mercury_engine.c \
mercury_file.c \
mercury_float.c \
- mercury_getopt.c \
mercury_getopt1.c \
+ mercury_getopt.c \
mercury_grade.c \
mercury_hash_table.c \
mercury_heap_profile.c \
@@ -161,16 +164,17 @@
mercury_memory_zones.c \
mercury_minimal_model.c \
mercury_misc.c \
+ mercury_mm_own_stacks.c \
mercury_prof.c \
+ mercury_profiling_builtin.c \
mercury_prof_mem.c \
mercury_prof_time.c \
- mercury_profiling_builtin.c \
- mercury_reg_workarounds.c \
mercury_regs.c \
+ mercury_reg_workarounds.c \
mercury_runtime_util.c \
mercury_signal.c \
- mercury_stack_trace.c \
mercury_stacks.c \
+ mercury_stack_trace.c \
mercury_string.c \
mercury_tabling.c \
mercury_term_size.c \
Index: runtime/mercury_bootstrap.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_bootstrap.h,v
retrieving revision 1.36
diff -u -b -r1.36 mercury_bootstrap.h
--- runtime/mercury_bootstrap.h 7 Jul 2004 07:11:08 -0000 1.36
+++ runtime/mercury_bootstrap.h 18 Jul 2004 01:53:16 -0000
@@ -48,6 +48,11 @@
typedef MR_UnsignedChar UnsignedChar;
typedef MR_String String;
typedef MR_ConstString ConstString;
+
+#ifndef MR_HIGHLEVEL_CODE
+typedef MR_Context Context;
+#endif
+
/*
** MR_Bool is the C representation for the Mercury type bool__bool.
** For ordinary booleans, use MR_bool in mercury_std.h.
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.78
diff -u -b -r1.78 mercury_conf_param.h
--- runtime/mercury_conf_param.h 31 May 2004 04:13:04 -0000 1.78
+++ runtime/mercury_conf_param.h 2 Jul 2004 07:31:40 -0000
@@ -53,7 +53,8 @@
** MR_BOXED_FLOAT
** MR_USE_TRAIL
** MR_RESERVE_TAG
-** MR_USE_MINIMAL_MODEL
+** MR_USE_MINIMAL_MODEL_STACK_COPY
+** MR_USE_MINIMAL_MODEL_OWN_STACKS
** MR_MINIMAL_MODEL_DEBUG
** MR_SPLIT_C_FILES
** MR_INLINE_ALLOC
Index: runtime/mercury_context.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.c,v
retrieving revision 1.37
diff -u -b -r1.37 mercury_context.c
--- runtime/mercury_context.c 7 Jul 2004 07:11:09 -0000 1.37
+++ runtime/mercury_context.c 18 Jul 2004 11:42:54 -0000
@@ -26,6 +26,9 @@
#include "mercury_engine.h" /* for `MR_memdebug' */
#include "mercury_reg_workarounds.h" /* for `MR_fd*' stuff */
+static void MR_init_context_maybe_generator(MR_Context *c,
+ MR_Generator *gen);
+
MR_Context *MR_runqueue_head;
MR_Context *MR_runqueue_tail;
#ifdef MR_THREAD_SAFE
@@ -83,8 +86,9 @@
}
void
-MR_init_context(MR_Context *c)
+MR_init_context(MR_Context *c, const char *id, MR_Generator *gen)
{
+ c->MR_ctxt_id = id;
c->MR_ctxt_next = NULL;
c->MR_ctxt_resume = NULL;
#ifdef MR_THREAD_SAFE
@@ -96,18 +100,26 @@
if (c->MR_ctxt_detstack_zone != NULL) {
MR_reset_redzone(c->MR_ctxt_detstack_zone);
+ } else if (gen != NULL) {
+ c->MR_ctxt_detstack_zone = MR_create_zone("gen_detstack",
+ 0, MR_gen_detstack_size, MR_next_offset(),
+ MR_gen_detstack_zone_size, MR_default_handler);
} else {
- c->MR_ctxt_detstack_zone = MR_create_zone("detstack", 0,
- MR_detstack_size, MR_next_offset(),
+ c->MR_ctxt_detstack_zone = MR_create_zone("detstack",
+ 0, MR_detstack_size, MR_next_offset(),
MR_detstack_zone_size, MR_default_handler);
}
c->MR_ctxt_sp = c->MR_ctxt_detstack_zone->min;
if (c->MR_ctxt_nondetstack_zone != NULL) {
MR_reset_redzone(c->MR_ctxt_nondetstack_zone);
+ } else if (gen != NULL) {
+ c->MR_ctxt_nondetstack_zone = MR_create_zone("gen_nondetstack",
+ 0, MR_gen_nonstack_size, MR_next_offset(),
+ MR_gen_nonstack_zone_size, MR_default_handler);
} else {
- c->MR_ctxt_nondetstack_zone = MR_create_zone("nondetstack", 0,
- MR_nondstack_size, MR_next_offset(),
+ c->MR_ctxt_nondetstack_zone = MR_create_zone("nondetstack",
+ 0, MR_nondstack_size, MR_next_offset(),
MR_nondstack_zone_size, MR_default_handler);
}
/*
@@ -127,7 +139,12 @@
MR_ENTRY(MR_do_not_reached);
MR_succfr_slot_word(c->MR_ctxt_curfr) = (MR_Word) NULL;
- #ifdef MR_USE_MINIMAL_MODEL
+ #ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+ if (gen != NULL) {
+ MR_fatal_error("MR_init_context_maybe_generator: "
+ "generator and stack_copy");
+ }
+
if (c->MR_ctxt_genstack_zone != NULL) {
MR_reset_redzone(c->MR_ctxt_genstack_zone);
} else {
@@ -154,10 +171,19 @@
MR_pnegstack_zone_size, MR_default_handler);
}
c->MR_ctxt_pneg_next = 0;
- #endif /* MR_USE_MINIMAL_MODEL */
+ #endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ #ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ c->MR_ctxt_owner_generator = gen;
+ #endif /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
#endif /* !MR_HIGHLEVEL_CODE */
#ifdef MR_USE_TRAIL
+ if (gen != NULL) {
+ MR_fatal_error("MR_init_context_maybe_generator: "
+ "generator and trail");
+ }
+
if (c->MR_ctxt_trail_zone != NULL) {
MR_reset_redzone(c->MR_ctxt_trail_zone);
} else {
@@ -170,11 +196,19 @@
c->MR_ctxt_ticket_high_water = 1;
#endif
+#ifndef MR_CONSERVATIVE_GC
+ if (is_generator) {
+ MR_fatal_error("MR_init_context_maybe_generator: "
+ "generator and no conservative gc");
+ }
+
c->MR_ctxt_hp = NULL;
+ c->MR_ctxt_min_hp_rec = NULL;
+#endif
}
MR_Context *
-MR_create_context(void)
+MR_create_context(const char *id, MR_Generator *gen)
{
MR_Context *c;
@@ -195,7 +229,7 @@
MR_UNLOCK(&free_context_list_lock, "create_context ii");
}
- MR_init_context(c);
+ MR_init_context(c, id, gen);
return c;
}
Index: runtime/mercury_context.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.h,v
retrieving revision 1.25
diff -u -b -r1.25 mercury_context.h
--- runtime/mercury_context.h 7 Jul 2004 07:11:09 -0000 1.25
+++ runtime/mercury_context.h 7 Jul 2004 08:02:15 -0000
@@ -47,7 +47,7 @@
#include <stdio.h>
-#include "mercury_types.h" /* for MR_Word */
+#include "mercury_types.h" /* for MR_Word, MR_Code, etc */
#include "mercury_trail.h" /* for MR_TrailEntry */
#include "mercury_memory.h" /* for MR_MemoryZone */
#include "mercury_thread.h" /* for MercuryLock */
@@ -62,28 +62,31 @@
typedef struct MR_Context_Struct MR_Context;
struct MR_Context_Struct {
+ const char *MR_ctxt_id;
+
MR_Context *MR_ctxt_next;
/*
- ** if this context is in the free-list `next' will point
- ** to the next free context. If this context is suspended
- ** waiting for a variable to become bound, `next' will point to
- ** the next waiting context. If this context is runnable but not
- ** currently running then `next' points to the next runnable
+ ** If this context is in the free-list `next' will
+ ** point to the next free context. If this context
+ ** is suspended waiting for a variable to become bound,
+ ** `next' will point to the next waiting context.
+ ** If this context is runnable but not currently
+ ** running then `next' points to the next runnable
** context in the runqueue.
*/
MR_Code *MR_ctxt_resume;
/*
- ** a pointer to the code at which execution should resume when
- ** this context is next scheduled.
+ ** A pointer to the code at which execution should
+ ** resume when this context is next scheduled.
*/
#ifdef MR_THREAD_SAFE
MercuryThread MR_ctxt_owner_thread;
/*
- ** The owner_thread field is used to ensure that when we
- ** enter a mercury engine from C, we return to the same
- ** engine. See the coments in mercury_engine.h
+ ** The owner_thread field is used to ensure that when
+ ** we enter a mercury engine from C, we return to the
+ ** same engine. See the coments in mercury_engine.h
*/
#endif
@@ -102,7 +105,7 @@
/* saved maxfr pointer for this context */
MR_Word *MR_ctxt_curfr;
/* saved curfr pointer for this context */
- #ifdef MR_USE_MINIMAL_MODEL
+ #ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_MemoryZone *MR_ctxt_genstack_zone;
/* pointer to the genstack_zone for this context */
MR_Integer MR_ctxt_gen_next;
@@ -115,7 +118,10 @@
/* pointer to the pnegstack_zone for this context */
MR_Integer MR_ctxt_pneg_next;
/* saved pneg stack index for this context */
- #endif /* MR_USE_MINIMAL_MODEL */
+ #endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+ #ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ MR_Generator *MR_ctxt_owner_generator;
+ #endif /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
#endif /* !MR_HIGHLEVEL_CODE */
#ifdef MR_USE_TRAIL
@@ -129,18 +135,19 @@
/* saved MR_ticket_high_water for this context */
#endif
+#ifndef MR_CONSERVATIVE_GC
MR_Word *MR_ctxt_hp;
/* saved hp for this context */
MR_Word *MR_ctxt_min_hp_rec;
/*
- ** this pointer marks the minimum value of MR_hp to which we can
- ** truncate the heap on backtracking. See comments before the
- ** set_min_heap_reclamation_point macro (below).
+ ** This pointer marks the minimum value of MR_hp to
+ ** which we can truncate the heap on backtracking.
+ ** See comments before the macro
+ ** set_min_heap_reclamation_point (below).
*/
+#endif
};
-typedef MR_Context Context; /* for backwards compatibility */
-
/*
** The runqueue is a linked list of contexts that are runnable.
*/
@@ -187,42 +194,44 @@
#endif
/*
-** Initializes a context structure.
+** Initializes a context structure, and gives it the given id. If gen is
+** non-NULL, the context is for the given generator.
*/
-extern void MR_init_context(MR_Context *context);
+extern void MR_init_context(MR_Context *context, const char *id,
+ MR_Generator *gen);
/*
-** create_context() allocates and initializes a new context
-** structure.
+** Allocates and initializes a new context structure, and gives it the given
+** id. If gen is non-NULL, the context is for the given generator.
*/
-extern MR_Context *MR_create_context(void);
+extern MR_Context *MR_create_context(const char *id, MR_Generator *gen);
/*
-** destroy_context(ptr) returns the context structure pointed
+** MR_destroy_context(ptr) returns the context structure pointed
** to by ptr to the free list, and releases resources as
** necessary.
*/
extern void MR_destroy_context(MR_Context *context);
/*
-** init_thread_stuff() initializes the lock structures for the runqueue.
+** MR_init_thread_stuff() initializes the lock structures for the runqueue.
*/
extern void MR_init_thread_stuff(void);
/*
-** finialize_runqueue() finalizes the lock structures for the runqueue.
+** MR_finialize_runqueue() finalizes the lock structures for the runqueue.
*/
extern void MR_finalize_runqueue(void);
/*
-** flounder() aborts with a runtime error message. It is called if
+** MR_flounder() aborts with a runtime error message. It is called if
** the runqueue becomes empty and none of the running processes are
** working - ie the computation has floundered.
*/
extern void MR_flounder(void);
/*
-** schedule(MR_Context *cptr):
+** MR_schedule(MR_Context *cptr):
** Append a context onto the end of the run queue.
*/
@@ -250,16 +259,19 @@
** The new context gets put on the runqueue, and the current
** context resumes at `parent'.
*/
- #define MR_fork_new_context(child, parent, numslots) do { \
+ #define MR_fork_new_context(child, parent, numslots) \
+ do { \
MR_Context *f_n_c_context; \
int fork_new_context_i; \
+ \
f_n_c_context = MR_create_context(); \
MR_IF_MR_THREAD_SAFE( \
f_n_c_context->owner_thread = NULL; \
) \
- for (fork_new_context_i = (numslots) ; \
- fork_new_context_i > 0 ; \
- fork_new_context_i--) { \
+ for (fork_new_context_i = (numslots); \
+ fork_new_context_i > 0; \
+ fork_new_context_i--) \
+ { \
*(f_n_c_context->context_sp) = \
MR_stackvar(fork_new_context_i); \
f_n_c_context->MR_ctxt_sp++; \
@@ -303,7 +315,8 @@
#define MR_set_min_heap_reclamation_point(ctxt) \
do { \
if (MR_hp != (ctxt)->MR_ctxt_hp \
- || (ctxt)->MR_ctxt_hp == NULL) { \
+ || (ctxt)->MR_ctxt_hp == NULL) \
+ { \
MR_min_hp_rec = MR_hp; \
(ctxt)->MR_ctxt_min_hp_rec = MR_hp; \
} else { \
@@ -331,10 +344,10 @@
#define MR_IF_USE_TRAIL(x)
#endif
-#ifdef MR_USE_MINIMAL_MODEL
- #define MR_IF_USE_MINIMAL_MODEL(x) x
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+ #define MR_IF_USE_MINIMAL_MODEL_STACK_COPY(x) x
#else
- #define MR_IF_USE_MINIMAL_MODEL(x)
+ #define MR_IF_USE_MINIMAL_MODEL_STACK_COPY(x)
#endif
#ifndef MR_HIGHLEVEL_CODE
@@ -357,26 +370,26 @@
load_context_c->MR_ctxt_maxfr; \
MR_curfr_word = (MR_Word) \
load_context_c->MR_ctxt_curfr; \
- MR_IF_USE_MINIMAL_MODEL( \
+ MR_IF_USE_MINIMAL_MODEL_STACK_COPY( \
MR_gen_next = load_context_c->MR_ctxt_gen_next; \
MR_cut_next = load_context_c->MR_ctxt_cut_next; \
- MR_pneg_next = load_context_c->MR_ctxt_pneg_next;\
+ MR_pneg_next = load_context_c->MR_ctxt_pneg_next; \
) \
) \
MR_IF_USE_TRAIL( \
- MR_trail_zone = load_context_c->MR_ctxt_trail_zone;\
- MR_trail_ptr = load_context_c->MR_ctxt_trail_ptr;\
+ MR_trail_zone = load_context_c->MR_ctxt_trail_zone; \
+ MR_trail_ptr = load_context_c->MR_ctxt_trail_ptr; \
MR_ticket_counter = \
load_context_c->MR_ctxt_ticket_counter; \
MR_ticket_high_water = \
- load_context_c->MR_ctxt_ticket_high_water;\
+ load_context_c->MR_ctxt_ticket_high_water; \
) \
MR_IF_NOT_HIGHLEVEL_CODE( \
MR_ENGINE(MR_eng_context).MR_ctxt_detstack_zone = \
load_context_c->MR_ctxt_detstack_zone; \
MR_ENGINE(MR_eng_context).MR_ctxt_nondetstack_zone = \
- load_context_c->MR_ctxt_nondetstack_zone;\
- MR_IF_USE_MINIMAL_MODEL( \
+ load_context_c->MR_ctxt_nondetstack_zone; \
+ MR_IF_USE_MINIMAL_MODEL_STACK_COPY( \
MR_ENGINE(MR_eng_context).MR_ctxt_genstack_zone = \
load_context_c->MR_ctxt_genstack_zone; \
MR_ENGINE(MR_eng_context).MR_ctxt_cutstack_zone = \
@@ -407,15 +420,15 @@
save_context_c->MR_ctxt_sp = MR_sp; \
save_context_c->MR_ctxt_maxfr = MR_maxfr; \
save_context_c->MR_ctxt_curfr = MR_curfr; \
- MR_IF_USE_MINIMAL_MODEL( \
+ MR_IF_USE_MINIMAL_MODEL_STACK_COPY( \
save_context_c->MR_ctxt_gen_next = MR_gen_next; \
save_context_c->MR_ctxt_cut_next = MR_cut_next; \
save_context_c->MR_ctxt_pneg_next = MR_pneg_next;\
) \
) \
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_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 = \
@@ -423,30 +436,22 @@
) \
MR_IF_NOT_HIGHLEVEL_CODE( \
save_context_c->MR_ctxt_detstack_zone = \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_detstack_zone; \
+ MR_ENGINE(MR_eng_context).MR_ctxt_detstack_zone; \
save_context_c->MR_ctxt_nondetstack_zone = \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_nondetstack_zone; \
- MR_IF_USE_MINIMAL_MODEL( \
+ MR_ENGINE(MR_eng_context).MR_ctxt_nondetstack_zone; \
+ MR_IF_USE_MINIMAL_MODEL_STACK_COPY( \
save_context_c->MR_ctxt_genstack_zone = \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_genstack_zone; \
+ MR_ENGINE(MR_eng_context).MR_ctxt_genstack_zone; \
save_context_c->MR_ctxt_cutstack_zone = \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_cutstack_zone; \
+ MR_ENGINE(MR_eng_context).MR_ctxt_cutstack_zone; \
save_context_c->MR_ctxt_pnegstack_zone = \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_pnegstack_zone; \
+ MR_ENGINE(MR_eng_context).MR_ctxt_pnegstack_zone; \
assert(MR_gen_stack == (MR_GenStackFrame *) \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_genstack_zone->min); \
+ MR_ENGINE(MR_eng_context).MR_ctxt_genstack_zone->min); \
assert(MR_cut_stack == (MR_CutStackFrame *) \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_cutstack_zone->min); \
+ MR_ENGINE(MR_eng_context).MR_ctxt_cutstack_zone->min); \
assert(MR_pneg_stack == (MR_PNegStackFrame *) \
- MR_ENGINE(MR_eng_context). \
- MR_ctxt_pnegstack_zone->min); \
+ MR_ENGINE(MR_eng_context).MR_ctxt_pnegstack_zone->min);\
) \
) \
MR_save_hp_in_context(save_context_c); \
Index: runtime/mercury_debug.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_debug.c,v
retrieving revision 1.22
diff -u -b -r1.22 mercury_debug.c
--- runtime/mercury_debug.c 23 May 2004 22:16:50 -0000 1.22
+++ runtime/mercury_debug.c 24 Jun 2004 08:20:37 -0000
@@ -14,6 +14,33 @@
#include <stdio.h>
#include <stdarg.h>
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ #define MR_in_ctxt_det_zone(ptr, ctxt) \
+ MR_in_zone(ptr, ctxt->MR_ctxt_detstack_zone)
+ #define MR_in_ctxt_non_zone(ptr, ctxt) \
+ MR_in_zone(ptr, ctxt->MR_ctxt_nondetstack_zone)
+
+ extern const MR_Context *MR_find_ctxt_for_det_ptr(const MR_Word *ptr);
+ extern const MR_Context *MR_find_ctxt_for_non_ptr(const MR_Word *ptr);
+
+ extern MR_MemoryZone *MR_find_zone_for_det_ptr(const MR_Word *ptr);
+ extern MR_MemoryZone *MR_find_zone_for_non_ptr(const MR_Word *ptr);
+
+ extern MR_Generator *MR_find_gen_for_det_ptr(const MR_Word *ptr);
+ extern MR_Generator *MR_find_gen_for_non_ptr(const MR_Word *ptr);
+
+ #define MR_det_zone(fr) (MR_find_zone_for_det_ptr(fr))
+ #define MR_non_zone(fr) (MR_find_zone_for_non_ptr(fr))
+#else
+ #define MR_det_zone(fr) (MR_CONTEXT(MR_ctxt_detstack_zone))
+ #define MR_non_zone(fr) (MR_CONTEXT(MR_ctxt_nondetstack_zone))
+#endif
+
+#define MR_det_stack_min(fr) (MR_det_zone(fr)->min)
+#define MR_det_stack_offset(fr) (fr - MR_det_stack_min(fr))
+#define MR_non_stack_min(fr) (MR_non_zone(fr)->min)
+#define MR_non_stack_offset(fr) (fr - MR_non_stack_min(fr))
+
/*--------------------------------------------------------------------*/
#ifdef MR_DEEP_PROFILING
@@ -28,7 +55,6 @@
static void MR_print_ordinary_regs(void);
static void MR_do_watches(void);
static MR_bool MR_proc_matches_name(MR_Code *proc, const char *name);
-static void MR_printdetslot_as_label(const MR_Integer offset);
#ifdef MR_LOWLEVEL_ADDR_DEBUG
#define MR_PRINT_RAW_ADDRS MR_TRUE
@@ -38,6 +64,104 @@
static MR_bool MR_print_raw_addrs = MR_PRINT_RAW_ADDRS;
+/* auxiliary routines for the code that prints debugging messages */
+
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+
+const MR_Context *
+MR_find_ctxt_for_det_ptr(const MR_Word *ptr)
+{
+ const MR_Dlist *item;
+ const MR_Context *ctxt;
+
+ if (MR_in_ctxt_det_zone(ptr, MR_ENGINE(MR_eng_main_context))) {
+ return MR_ENGINE(MR_eng_main_context);
+ }
+
+ MR_for_dlist(item, MR_ENGINE(MR_eng_gen_contexts)) {
+ ctxt = (MR_Context *) MR_dlist_data(item);
+ if (MR_in_ctxt_det_zone(ptr, ctxt)) {
+ return ctxt;
+ }
+ }
+
+ return NULL;
+}
+
+const MR_Context *
+MR_find_ctxt_for_non_ptr(const MR_Word *ptr)
+{
+ const MR_Dlist *item;
+ const MR_Context *ctxt;
+
+ if (MR_in_ctxt_non_zone(ptr, MR_ENGINE(MR_eng_main_context))) {
+ return MR_ENGINE(MR_eng_main_context);
+ }
+
+ MR_for_dlist(item, MR_ENGINE(MR_eng_gen_contexts)) {
+ ctxt = (MR_Context *) MR_dlist_data(item);
+ if (MR_in_ctxt_non_zone(ptr, ctxt)) {
+ return ctxt;
+ }
+ }
+
+ return NULL;
+}
+
+MR_MemoryZone *
+MR_find_zone_for_det_ptr(const MR_Word *ptr)
+{
+ const MR_Context *ctxt;
+
+ ctxt = MR_find_ctxt_for_det_ptr(ptr);
+ if (ctxt != NULL) {
+ return ctxt->MR_ctxt_detstack_zone;
+ }
+
+ MR_fatal_error("MR_find_zone_for_det_ptr: not in any context");
+}
+
+MR_MemoryZone *
+MR_find_zone_for_non_ptr(const MR_Word *ptr)
+{
+ const MR_Context *ctxt;
+
+ ctxt = MR_find_ctxt_for_non_ptr(ptr);
+ if (ctxt != NULL) {
+ return ctxt->MR_ctxt_nondetstack_zone;
+ }
+
+ MR_fatal_error("MR_find_zone_for_non_ptr: not in any context");
+}
+
+MR_Generator *
+MR_find_gen_for_det_ptr(const MR_Word *ptr)
+{
+ const MR_Context *ctxt;
+
+ ctxt = MR_find_ctxt_for_det_ptr(ptr);
+ if (ctxt != NULL) {
+ return ctxt->MR_ctxt_owner_generator;
+ }
+
+ MR_fatal_error("MR_find_gen_for_det_ptr: not in any context");
+}
+
+MR_Generator *
+MR_find_gen_for_non_ptr(const MR_Word *ptr)
+{
+ const MR_Context *ctxt;
+
+ ctxt = MR_find_ctxt_for_non_ptr(ptr);
+ if (ctxt != NULL) {
+ return ctxt->MR_ctxt_owner_generator;
+ }
+
+ MR_fatal_error("MR_find_gen_for_non_ptr: not in any context");
+}
+
+#endif /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
/* debugging messages */
#ifdef MR_DEBUG_HEAP_ALLOC
@@ -95,7 +219,7 @@
printf("succ ip: "); MR_printlabel(stdout, MR_succip_slot(MR_curfr));
printf("redo fr: "); MR_printnondstack(MR_redofr_slot(MR_curfr));
printf("redo ip: "); MR_printlabel(stdout, MR_redoip_slot(MR_curfr));
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
printf("det fr: "); MR_printdetstack(MR_table_detfr_slot(MR_curfr));
#endif
@@ -543,8 +667,7 @@
}
printf("offset %3ld words\n",
- (long) (MR_Integer)
- (fr - MR_CONTEXT(MR_ctxt_nondetstack_zone)->min));
+ (long) (MR_Integer) MR_non_stack_offset(fr));
printf("\t succip "); MR_printlabel(stdout, MR_succip_slot(fr));
printf("\t redoip "); MR_printlabel(stdout, MR_redoip_slot(fr));
printf("\t succfr "); MR_printnondstack(MR_succfr_slot(fr));
@@ -784,15 +907,6 @@
#ifndef MR_HIGHLEVEL_CODE
-static void
-MR_printdetslot_as_label(const MR_Integer offset)
-{
- MR_printdetstackptr(&MR_CONTEXT(MR_ctxt_detstack_zone)->min[offset]);
- printf(" ");
- MR_printlabel(stdout,
- (MR_Code *) (MR_CONTEXT(MR_ctxt_detstack_zone)->min[offset]));
-}
-
void
MR_printdetstackptr(const MR_Word *s)
{
@@ -803,8 +917,7 @@
MR_print_detstackptr(FILE *fp, const MR_Word *s)
{
fprintf(fp, "det %3ld",
- (long) (MR_Integer)
- (s - MR_CONTEXT(MR_ctxt_detstack_zone)->min));
+ (long) (MR_Integer) MR_det_stack_offset(s));
if (MR_print_raw_addrs) {
fprintf(fp, " (%p)", (const void *) s);
@@ -819,8 +932,7 @@
}
printf("offset %3ld words\n",
- (long) (MR_Integer)
- (s - MR_CONTEXT(MR_ctxt_detstack_zone)->min));
+ (long) (MR_Integer) MR_det_stack_offset(s));
}
void
@@ -833,8 +945,7 @@
MR_print_nondstackptr(FILE *fp, const MR_Word *s)
{
fprintf(fp, "non %3ld",
- (long) (MR_Integer)
- (s - MR_CONTEXT(MR_ctxt_nondetstack_zone)->min));
+ (long) (MR_Integer) MR_non_stack_offset(s));
if (MR_print_raw_addrs) {
fprintf(fp, " (%p)",
@@ -850,8 +961,7 @@
}
printf("offset %3ld words\n",
- (long) (MR_Integer)
- (s - MR_CONTEXT(MR_ctxt_nondetstack_zone)->min));
+ (long) (MR_Integer) MR_non_stack_offset(s));
}
#endif /* !MR_HIGHLEVEL_CODE */
Index: runtime/mercury_dlist.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_dlist.c,v
retrieving revision 1.6
diff -u -b -r1.6 mercury_dlist.c
--- runtime/mercury_dlist.c 10 Jan 2001 10:57:25 -0000 1.6
+++ runtime/mercury_dlist.c 15 Apr 2004 16:46:05 -0000
@@ -60,7 +60,7 @@
item = MR_GC_NEW(MR_Dlist);
MR_dlist_data(item) = data;
- MR_dlist_length(list)++;
+ MR_dlist_length_field(list)++;
/* item's pointers */
MR_dlist_next(item) = MR_dlist_next(list);
@@ -87,7 +87,7 @@
item = MR_GC_NEW(MR_Dlist);
MR_dlist_data(item) = data;
- MR_dlist_length(list)++;
+ MR_dlist_length_field(list)++;
/* item's pointers */
MR_dlist_next(item) = list;
@@ -125,7 +125,7 @@
MR_dlist_prev(MR_dlist_next(list1)) = list1;
MR_dlist_next(MR_dlist_prev(list1)) = list1;
} else {
- MR_dlist_length(list1) = MR_dlist_length(list1)
+ MR_dlist_length_field(list1) = MR_dlist_length(list1)
+ MR_dlist_length(list2);
/* end of list 1 to start of list 2 */
MR_dlist_next(MR_dlist_prev(list1)) =
@@ -179,7 +179,7 @@
item = MR_GC_NEW(MR_Dlist);
MR_dlist_data(item) = data;
- MR_dlist_length(list)++;
+ MR_dlist_length_field(list)++;
/* item's pointers */
MR_dlist_next(item) = where;
@@ -200,7 +200,7 @@
item = MR_GC_NEW(MR_Dlist);
MR_dlist_data(item) = data;
- MR_dlist_length(list)++;
+ MR_dlist_length_field(list)++;
/* item's pointers */
MR_dlist_next(item) = MR_dlist_next(where);
@@ -246,7 +246,7 @@
func(MR_dlist_data(item));
}
- MR_dlist_length(list)--;
+ MR_dlist_length_field(list)--;
MR_dlist_next(MR_dlist_prev(item)) = MR_dlist_next(item);
MR_dlist_prev(MR_dlist_next(item)) = MR_dlist_prev(item);
Index: runtime/mercury_dlist.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_dlist.h,v
retrieving revision 1.4
diff -u -b -r1.4 mercury_dlist.h
--- runtime/mercury_dlist.h 20 Jan 2004 02:51:17 -0000 1.4
+++ runtime/mercury_dlist.h 15 Apr 2004 16:45:44 -0000
@@ -31,7 +31,11 @@
#define MR_dlist_next(ptr) (ptr)->MR_dlist_next
#define MR_dlist_prev(ptr) (ptr)->MR_dlist_prev
#define MR_dlist_data(ptr) (ptr)->MR_dlist_union.MR_dlist_data
-#define MR_dlist_length(list) ((list)->MR_dlist_union.MR_dlist_length)
+#define MR_dlist_length_field(list) ((list)->MR_dlist_union.\
+ MR_dlist_length)
+#define MR_dlist_length(list) ((list) != NULL ? \
+ MR_dlist_length_field(list) \
+ : 0)
#define MR_dlist_first_ptr(list) ((list)->MR_dlist_next)
#define MR_dlist_last_ptr(list) ((list)->MR_dlist_prev)
#define MR_dlist_first(list) ((list)->MR_dlist_next-> \
Index: runtime/mercury_engine.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_engine.c,v
retrieving revision 1.48
diff -u -b -r1.48 mercury_engine.c
--- runtime/mercury_engine.c 7 Jul 2004 07:11:10 -0000 1.48
+++ runtime/mercury_engine.c 7 Jul 2004 07:17:04 -0000
@@ -74,7 +74,7 @@
/*---------------------------------------------------------------------------*/
/*
-** init_engine() calls init_memory() which sets up all the necessary
+** MR_init_engine() calls MR_init_memory() which sets up all the necessary
** stuff for allocating memory-zones and other runtime areas (such as
** the zone structures and context structures).
*/
@@ -105,15 +105,15 @@
*/
#ifndef MR_CONSERVATIVE_GC
- eng->MR_eng_heap_zone = MR_create_zone("heap", 1, MR_heap_size,
- MR_next_offset(), MR_heap_zone_size,
- MR_default_handler);
+ eng->MR_eng_heap_zone = MR_create_zone("heap", 1,
+ MR_heap_size, MR_next_offset(),
+ MR_heap_zone_size, MR_default_handler);
eng->MR_eng_hp = eng->MR_eng_heap_zone->min;
#ifdef MR_NATIVE_GC
- eng->MR_eng_heap_zone2 = MR_create_zone("heap2", 1, MR_heap_size,
- MR_next_offset(), MR_heap_zone_size,
- MR_default_handler);
+ eng->MR_eng_heap_zone2 = MR_create_zone("heap2", 1,
+ MR_heap_size, MR_next_offset(),
+ MR_heap_zone_size, MR_default_handler);
#ifdef MR_DEBUG_AGC_PRINT_VARS
eng->MR_eng_debug_heap_zone = MR_create_zone("debug_heap", 1,
@@ -145,7 +145,7 @@
** Finally, allocate an initial context (Mercury thread)
** in the engine and initialize the per-context stuff.
*/
- eng->MR_eng_this_context = MR_create_context();
+ eng->MR_eng_this_context = MR_create_context("main", NULL);
}
/*---------------------------------------------------------------------------*/
Index: runtime/mercury_engine.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_engine.h,v
retrieving revision 1.35
diff -u -b -r1.35 mercury_engine.h
--- runtime/mercury_engine.h 7 Jul 2004 07:11:10 -0000 1.35
+++ runtime/mercury_engine.h 7 Jul 2004 07:17:04 -0000
@@ -297,6 +297,26 @@
** MR_eng_context stores all the context information
** for the context executing in this engine.
*/
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ MR_Context *MR_eng_main_context;
+ /*
+ ** The context of the main computation. The
+ ** owner_generator field of this context must be NULL.
+ */
+ MR_Dlist *MR_eng_gen_contexts; /* elements are MR_Context */
+ /*
+ ** The contexts of the active generators. The
+ ** owner_generator fields of these contexts will point
+ ** to their generators.
+ */
+ MR_Dlist *MR_eng_free_contexts; /* elements are MR_Context */
+ /*
+ ** Contexts that used to belong to active generators,
+ ** but which are no longer needed. They are cached here
+ ** to allow new generators to be created without
+ ** redoing the work required to allocate a new context.
+ */
+#endif
#ifdef MR_THREAD_SAFE
MercuryThread MR_eng_owner_thread;
unsigned MR_eng_c_depth;
@@ -305,19 +325,21 @@
** These three fields are used to ensure that when a
** thread executing C code calls the Mercury engine
** associated with that thread, the Mercury code
- ** will finish in the same engine and return appropriately.
- ** Each time C calls Mercury in a thread, the c_depth
- ** is incremented, and the owner_thread field of the current
- ** context is set to the id of the thread. While the
- ** owner_thread is set, the context will not be scheduled
- ** for execution by any other thread. When the call to
- ** the Mercury engine finishes, c_depth is decremented and
- ** the owner_thread field of the current context is restored
- ** to its previous value.
- ** The list `saved_owners' is used in call_engine_inner
- ** to store the owner of a context across calls into Mercury.
- ** At the moment this is only used for sanity checking - that
- ** execution never returns into C in the wrong thread.
+ ** will finish in the same engine and return
+ ** appropriately. Each time C calls Mercury in a
+ ** thread, the c_depth is incremented, and the
+ ** owner_thread field of the current context is set
+ ** to the id of the thread. While the owner_thread
+ ** is set, the context will not be scheduled for
+ ** execution by any other thread. When the call to
+ ** the Mercury engine finishes, c_depth is decremented
+ ** and the owner_thread field of the current context
+ ** is restored to its previous value. The list
+ ** `saved_owners' is used in call_engine_inner to store
+ ** the owner of a context across calls into Mercury.
+ ** At the moment this is only used for sanity checking
+ ** - that execution never returns into C in the
+ ** wrong thread.
*/
#endif
jmp_buf *MR_eng_jmp_buf;
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.54
diff -u -b -r1.54 mercury_grade.h
--- runtime/mercury_grade.h 7 Jul 2004 07:11:11 -0000 1.54
+++ runtime/mercury_grade.h 7 Jul 2004 07:17:04 -0000
@@ -23,6 +23,7 @@
** scripts/ml.in
** compiler/handle_options.m
** compiler/compile_target_code.m
+** configure.in
*/
#ifndef MERCURY_GRADES_H
@@ -207,13 +208,27 @@
#define MR_GRADE_OPT_PART_7 MR_GRADE_OPT_PART_6
#endif
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+ #ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ #error "Invalid combination of minimal model tabling options"
+ #endif
+#endif
+
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+ #ifdef MR_MINIMAL_MODEL_DEBUG
+ #define MR_GRADE_PART_8 MR_PASTE2(MR_GRADE_PART_7, _dmmsc)
+ #define MR_GRADE_OPT_PART_8 MR_GRADE_OPT_PART_7 ".dmmsc"
+ #else
+ #define MR_GRADE_PART_8 MR_PASTE2(MR_GRADE_PART_7, _mmsc)
+ #define MR_GRADE_OPT_PART_8 MR_GRADE_OPT_PART_7 ".mmsc"
+ #endif
+#elif MR_USE_MINIMAL_MODEL_OWN_STACKS
#ifdef MR_MINIMAL_MODEL_DEBUG
- #define MR_GRADE_PART_8 MR_PASTE2(MR_GRADE_PART_7, _dmm)
- #define MR_GRADE_OPT_PART_8 MR_GRADE_OPT_PART_7 ".dmm"
+ #define MR_GRADE_PART_8 MR_PASTE2(MR_GRADE_PART_7, _dmmos)
+ #define MR_GRADE_OPT_PART_8 MR_GRADE_OPT_PART_7 ".dmmos"
#else
- #define MR_GRADE_PART_8 MR_PASTE2(MR_GRADE_PART_7, _mm)
- #define MR_GRADE_OPT_PART_8 MR_GRADE_OPT_PART_7 ".mm"
+ #define MR_GRADE_PART_8 MR_PASTE2(MR_GRADE_PART_7, _mmos)
+ #define MR_GRADE_OPT_PART_8 MR_GRADE_OPT_PART_7 ".mmos"
#endif
#else
#define MR_GRADE_PART_8 MR_GRADE_PART_7
@@ -221,13 +236,17 @@
#endif
/*
-** Minimal model tabling works by saving and restoring segments of the nondet
-** stack. Since in high level code grades we don't have a nondet stack that
-** we can save and restore, minimal model tabling is fundamentally incompatible
+** One implementation of minimal model tabling works by saving and restoring
+** segments of the nondet stack, the other by creating a separate stack for
+** each generator. Since in high level code grades we don't have a nondet
+** stack that we can save and restore and we can't establish extra stacks,
+** both forms of minimal model tabling are fundamentally incompatible
** with high level code.
*/
-#if defined(MR_USE_MINIMAL_MODEL) && defined(MR_HIGHLEVEL_CODE)
+#if defined(MR_HIGHLEVEL_CODE) && \
+ (defined(MR_USE_MINIMAL_MODEL_STACK_COPY) || \
+ defined(MR_USE_MINIMAL_MODEL_OWN_STACKS))
#error "high level code and minimal model tabling are not compatible"
#endif
@@ -253,17 +272,20 @@
** The trail handler will be thoroughly confused by such a sequence.
**
** Until we can figure out (and implement) a fix for this problem,
-** minimal model tabling and trailing cannot be used together.
+** minimal model tabling (either form) and trailing cannot be used together.
*/
-#if defined(MR_USE_TRAIL) && defined(MR_USE_MINIMAL_MODEL)
+#if defined(MR_USE_TRAIL) && \
+ (defined(MR_USE_MINIMAL_MODEL_STACK_COPY) || \
+ defined(MR_USE_MINIMAL_MODEL_OWN_STACKS))
#error "trailing and minimal model tabling are not compatible"
#endif
/*
** Native gc needs to be able to redirect pointers to the heap. Minimal model
** tabling takes snapshots of stack segments that may contain pointers to the
-** heap, but there is currently no mechanism implemented to trace and redirect
+** heap, or creates extra stacks that may contain pointers to the heap,
+** but there is currently no mechanism implemented to trace and redirect
** such pointers.
**
** Minimal model tabling has no problems with conservative gc or with no gc,
@@ -272,7 +294,9 @@
** space.
*/
-#if defined(MR_USE_MINIMAL_MODEL) && defined(MR_NATIVE_GC)
+#if defined(MR_NATIVE_GC) && \
+ (defined(MR_USE_MINIMAL_MODEL_STACK_COPY) || \
+ defined(MR_USE_MINIMAL_MODEL_OWN_STACKS))
#error "minimal model tabling and native gc are not compatible"
#endif
Index: runtime/mercury_imp.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_imp.h,v
retrieving revision 1.22
diff -u -b -r1.22 mercury_imp.h
--- runtime/mercury_imp.h 23 Oct 2003 02:02:31 -0000 1.22
+++ runtime/mercury_imp.h 21 Mar 2004 08:25:11 -0000
@@ -81,8 +81,11 @@
#include "mercury_misc.h"
#include "mercury_tabling.h"
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
#include "mercury_minimal_model.h"
+#endif
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+#include "mercury_mm_own_stacks.h"
#endif
#include "mercury_univ.h"
Index: runtime/mercury_memory.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory.c,v
retrieving revision 1.34
diff -u -b -r1.34 mercury_memory.c
--- runtime/mercury_memory.c 30 Dec 2003 13:17:13 -0000 1.34
+++ runtime/mercury_memory.c 15 Apr 2004 16:55:00 -0000
@@ -102,7 +102,7 @@
** XXX All the zones should be in mercury_engine.h
*/
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_MemoryZone *MR_genstack_zone;
MR_MemoryZone *MR_cutstack_zone;
MR_MemoryZone *MR_pnegstack_zone;
@@ -168,7 +168,7 @@
MR_unit);
MR_nondstack_zone_size = MR_round_up(MR_nondstack_zone_size * 1024,
MR_unit);
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_genstack_size = MR_round_up(MR_genstack_size * 1024,
MR_unit);
MR_genstack_zone_size = MR_round_up(
@@ -182,6 +182,31 @@
MR_unit);
MR_pnegstack_zone_size = MR_round_up(MR_pnegstack_zone_size * 1024,
MR_unit);
+#else
+ MR_genstack_size = 0;
+ MR_genstack_zone_size = 0;
+ MR_cutstack_size = 0;
+ MR_cutstack_zone_size = 0;
+ MR_pnegstack_size = 0;
+ MR_pnegstack_zone_size = 0;
+#endif
+
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ MR_gen_detstack_size = MR_round_up(MR_gen_detstack_size * 1024,
+ MR_unit);
+ MR_gen_nonstack_size = MR_round_up(MR_gen_nonstack_size * 1024,
+ MR_unit);
+ MR_gen_detstack_zone_size = MR_round_up(
+ MR_gen_detstack_zone_size * 1024,
+ MR_unit);
+ MR_gen_nonstack_zone_size = MR_round_up(
+ MR_gen_nonstack_zone_size * 1024,
+ MR_unit);
+#else
+ MR_gen_detstack_size = 0;
+ MR_gen_nonstack_size = 0;
+ MR_gen_detstack_zone_size = 0;
+ MR_gen_nonstack_zone_size = 0;
#endif
#ifdef MR_USE_TRAIL
Index: runtime/mercury_memory_zones.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory_zones.c,v
retrieving revision 1.24
diff -u -b -r1.24 mercury_memory_zones.c
--- runtime/mercury_memory_zones.c 7 Jul 2004 07:11:13 -0000 1.24
+++ runtime/mercury_memory_zones.c 7 Jul 2004 07:17:05 -0000
@@ -466,6 +466,12 @@
return used_memory_zones;
}
+MR_bool
+MR_in_zone(const MR_Word *ptr, const MR_MemoryZone *zone)
+{
+ return (zone->bottom <= ptr && ptr < zone->top);
+}
+
void
MR_debug_memory(void)
{
Index: runtime/mercury_memory_zones.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory_zones.h,v
retrieving revision 1.15
diff -u -b -r1.15 mercury_memory_zones.h
--- runtime/mercury_memory_zones.h 7 Jul 2004 07:11:13 -0000 1.15
+++ runtime/mercury_memory_zones.h 7 Jul 2004 07:17:05 -0000
@@ -176,7 +176,7 @@
/*
** MR_construct_zone(Name, Id, Base, Size, Offset, RedZoneSize, FaultHandler)
-** has the same behaviour as MR_create_zone, except instread of allocating
+** has the same behaviour as MR_create_zone, except instead of allocating
** the memory, it takes a pointer to a region of memory that must be at
** least Size + unit[*] bytes, or if MR_PROTECTPAGE is defined, then it
** must be at least Size + 2 * unit[*] bytes.
@@ -206,6 +206,13 @@
*/
extern MR_MemoryZone *MR_get_used_memory_zones(void);
+
+/*
+** Returns true iff ptr is the given zone.
+*/
+
+extern MR_bool MR_in_zone(const MR_Word *ptr,
+ const MR_MemoryZone *zone);
/*
** MR_debug_memory() prints out debugging information about the current
Index: runtime/mercury_minimal_model.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_minimal_model.c,v
retrieving revision 1.15
diff -u -b -r1.15 mercury_minimal_model.c
--- runtime/mercury_minimal_model.c 7 Jul 2004 07:11:13 -0000 1.15
+++ runtime/mercury_minimal_model.c 19 Jul 2004 02:10:09 -0000
@@ -8,8 +8,8 @@
*/
/*
-** This module contains the functions related specifically to minimal model
-** tabling.
+** This module contains the functions related specifically to the stack copy
+** style of minimal model tabling.
*/
#include "mercury_imp.h"
@@ -32,7 +32,7 @@
#define MR_TABLE_DEBUG
#endif
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
#ifdef MR_TABLE_DEBUG
static MR_Word *saved_to_real_nondet_stack(MR_SavedState *saved_state,
@@ -396,6 +396,7 @@
MR_ConsumerList consumer;
MR_AnswerList answer_list;
MR_Word *answer;
+ int answer_num;
if (subgoal == NULL) {
fprintf(fp, "NULL subgoal\n");
@@ -444,16 +445,13 @@
if (proc != NULL) {
answer_list = subgoal->MR_sg_answer_list;
+ answer_num = 1;
while (answer_list != NULL) {
-#ifdef MR_MINIMAL_MODEL_DEBUG
- fprintf(fp, "answer #%d: <", answer_list->MR_aln_answer_num);
-#else
- fprintf(fp, "answer: <");
-#endif
- MR_print_answerblock(fp, proc,
- answer_list->MR_aln_answer_data.MR_answerblock);
+ fprintf(fp, "answer #%d: <", answer_num);
+ MR_print_answerblock(fp, proc, answer_list->MR_aln_answer_block);
fprintf(fp, ">\n");
answer_list = answer_list->MR_aln_next_answer;
+ answer_num++;
}
}
}
@@ -504,11 +502,12 @@
** In that case, we want to forget all about the old generator.
*/
+ MR_restore_transient_registers();
+
#ifdef MR_TABLE_STATISTICS
MR_minmodel_stats_cnt_setup++;
#endif
- MR_restore_transient_registers();
if (trie_node->MR_subgoal == NULL) {
MR_Subgoal *subgoal;
@@ -576,8 +575,8 @@
trie_node->MR_subgoal = subgoal;
}
- return trie_node->MR_subgoal;
MR_save_transient_registers();
+ return trie_node->MR_subgoal;
}
/*---------------------------------------------------------------------------*/
@@ -747,13 +746,13 @@
*/
#define SUSPEND_LABEL(name) \
- MR_label_name(MR_SUSPEND_ENTRY, name)
+ MR_label_name(MR_MMSC_SUSPEND_ENTRY, name)
#define COMPLETION_LABEL(name) \
- MR_label_name(MR_COMPLETION_ENTRY, name)
+ MR_label_name(MR_MMSC_COMPLETION_ENTRY, name)
#define RET_ALL_MULTI_LABEL(name) \
- MR_label_name(MR_RET_ALL_MULTI_ENTRY, name)
+ MR_label_name(MR_MMSC_RET_ALL_MULTI_ENTRY, name)
#define RET_ALL_NONDET_LABEL(name) \
- MR_label_name(MR_RET_ALL_NONDET_ENTRY, name)
+ MR_label_name(MR_MMSC_RET_ALL_NONDET_ENTRY, name)
/*
** With debugging of tabling code enabled, define function versions
@@ -1407,7 +1406,7 @@
#endif /* MR_TABLE_DEBUG */
*MR_redoip_addr(saved_fr) =
- (MR_Word) MR_ENTRY(MR_COMPLETION_ENTRY);
+ (MR_Word) MR_ENTRY(MR_MMSC_COMPLETION_ENTRY);
} else if (!generator_is_at_bottom &&
real_fr == MR_gen_stack[cur_gen].MR_gen_frame)
{
@@ -1431,7 +1430,7 @@
#endif /* MR_TABLE_DEBUG */
*MR_redoip_addr(saved_fr) =
- (MR_Word) MR_ENTRY(MR_COMPLETION_ENTRY);
+ (MR_Word) MR_ENTRY(MR_MMSC_COMPLETION_ENTRY);
} else {
/*
** This is the nondet stack frame of some other generator.
@@ -1650,7 +1649,7 @@
}
}
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
/*---------------------------------------------------------------------------*/
@@ -1659,9 +1658,9 @@
** of derivations.
**
** We need to define stubs for the predicates which are marked as `:- external'
-** in table_builtin.m, even if MR_USE_MINIMAL_MODEL is not enabled, because
-** in profiling grades the code generated for table_builtin.m will take their
-** address to store in the label table.
+** in table_builtin.m, even if MR_USE_MINIMAL_MODEL_STACK_COPY is not enabled,
+** because in profiling grades the code generated for table_builtin.m will
+** take their address to store in the label table.
**
** We provide three definitions for these procedures: one for high level
** code (which is incompatible with minimal model tabling), and two for low
@@ -1671,19 +1670,6 @@
#ifdef MR_HIGHLEVEL_CODE
-/* Declare them first, to avoid warnings from gcc -Wmissing-decls */
-void MR_CALL mercury__table_builtin__table_mm_completion_1_p_0(
- MR_C_Pointer subgoal_table_node, MR_C_Pointer *answer_block,
- MR_Cont cont, void *cont_env_ptr);
-void MR_CALL mercury__table_builtin__table_mm_suspend_consumer_2_p_0(
- MR_C_Pointer subgoal_table_node);
-void MR_CALL mercury__table_builtin__table_mm_return_all_nondet_2_2_p_0(
- MR_C_Pointer answer_list, MR_C_Pointer answer_block);
-void MR_CALL mercury__table_builtin__table_mm_return_all_multi_2_2_p_0(
- MR_C_Pointer answer_list, MR_C_Pointer answer_block);
-void MR_CALL mercury__table_builtin__table_mm_answer_is_not_duplicate_1_p_0(
- MR_C_Pointer subgoal_table_node);
-
void MR_CALL
mercury__table_builtin__table_mm_completion_1_p_0(
MR_C_Pointer subgoal_table_node, MR_C_Pointer *answer_block,
@@ -1727,11 +1713,11 @@
#else /* ! MR_HIGHLEVEL_CODE */
-MR_define_extern_entry(MR_SUSPEND_ENTRY);
-MR_define_extern_entry(MR_COMPLETION_ENTRY);
-MR_define_extern_entry(MR_RET_ALL_NONDET_ENTRY);
-MR_define_extern_entry(MR_RET_ALL_MULTI_ENTRY);
-MR_define_extern_entry(MR_IS_NOT_DUPL_ENTRY);
+MR_define_extern_entry(MR_MMSC_SUSPEND_ENTRY);
+MR_define_extern_entry(MR_MMSC_COMPLETION_ENTRY);
+MR_define_extern_entry(MR_MMSC_RET_ALL_NONDET_ENTRY);
+MR_define_extern_entry(MR_MMSC_RET_ALL_MULTI_ENTRY);
+MR_define_extern_entry(MR_MMSC_IS_NOT_DUPL_ENTRY);
MR_EXTERN_USER_PROC_ID_PROC_LAYOUT(MR_DETISM_NON, 0, -1,
MR_PREDICATE, table_builtin, table_mm_suspend_consumer, 2, 0);
@@ -1744,39 +1730,39 @@
MR_EXTERN_USER_PROC_ID_PROC_LAYOUT(MR_DETISM_NON, 0, -1,
MR_PREDICATE, table_builtin, table_mm_answer_is_not_duplicate, 1, 0);
-#ifndef MR_USE_MINIMAL_MODEL
+#ifndef MR_USE_MINIMAL_MODEL_STACK_COPY
-MR_BEGIN_MODULE(table_mm_suspend_completion_module)
- MR_init_entry_sl(MR_SUSPEND_ENTRY);
- MR_init_entry_sl(MR_COMPLETION_ENTRY);
- MR_init_entry_sl(MR_RET_ALL_NONDET_ENTRY);
- MR_init_entry_sl(MR_RET_ALL_MULTI_ENTRY);
- MR_init_entry_sl(MR_IS_NOT_DUPL_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_SUSPEND_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_COMPLETION_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_RET_ALL_NONDET_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_RET_ALL_MULTI_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_IS_NOT_DUPL_ENTRY);
+MR_BEGIN_MODULE(mmsc_module)
+ MR_init_entry_sl(MR_MMSC_SUSPEND_ENTRY);
+ MR_init_entry_sl(MR_MMSC_COMPLETION_ENTRY);
+ MR_init_entry_sl(MR_MMSC_RET_ALL_NONDET_ENTRY);
+ MR_init_entry_sl(MR_MMSC_RET_ALL_MULTI_ENTRY);
+ MR_init_entry_sl(MR_MMSC_IS_NOT_DUPL_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_SUSPEND_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_COMPLETION_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_RET_ALL_NONDET_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_RET_ALL_MULTI_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_IS_NOT_DUPL_ENTRY);
MR_BEGIN_CODE
-MR_define_entry(MR_SUSPEND_ENTRY);
+MR_define_entry(MR_MMSC_SUSPEND_ENTRY);
MR_fatal_error("call to table_mm_suspend_consumer/2 in a grade "
- "without minimal model tabling");
-MR_define_entry(MR_COMPLETION_ENTRY);
+ "without stack copy minimal model tabling");
+MR_define_entry(MR_MMSC_COMPLETION_ENTRY);
MR_fatal_error("call to table_mm_completion/1 in a grade "
- "without minimal model tabling");
-MR_define_entry(MR_RET_ALL_NONDET_ENTRY);
+ "without stack copy minimal model tabling");
+MR_define_entry(MR_MMSC_RET_ALL_NONDET_ENTRY);
MR_fatal_error("call to table_mm_return_all_nondet/2 in a grade "
- "without minimal model tabling");
-MR_define_entry(MR_RET_ALL_MULTI_ENTRY);
+ "without stack copy minimal model tabling");
+MR_define_entry(MR_MMSC_RET_ALL_MULTI_ENTRY);
MR_fatal_error("call to table_mm_return_all_multi/2 in a grade "
- "without minimal model tabling");
-MR_define_entry(MR_IS_NOT_DUPL_ENTRY);
+ "without stack copy minimal model tabling");
+MR_define_entry(MR_MMSC_IS_NOT_DUPL_ENTRY);
MR_fatal_error("call to table_mm_answer_is_not_duplicate/1 in a grade "
- "without minimal model tabling");
+ "without stack copy minimal model tabling");
MR_END_MODULE
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
MR_Subgoal *MR_cur_leader;
@@ -1820,13 +1806,13 @@
MR_MAKE_USER_INTERNAL_LAYOUT(table_builtin, table_mm_return_all_multi, 2, 0,
Next);
-MR_BEGIN_MODULE(table_mm_suspend_completion_module)
- MR_init_entry_sl(MR_SUSPEND_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_SUSPEND_ENTRY);
+MR_BEGIN_MODULE(mmsc_module)
+ MR_init_entry_sl(MR_MMSC_SUSPEND_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_SUSPEND_ENTRY);
MR_init_label_sl(SUSPEND_LABEL(Call));
- MR_init_entry_sl(MR_COMPLETION_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_COMPLETION_ENTRY);
+ MR_init_entry_sl(MR_MMSC_COMPLETION_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_COMPLETION_ENTRY);
MR_init_label_sl(COMPLETION_LABEL(StartCompletionOp));
MR_init_label_sl(COMPLETION_LABEL(LoopOverSubgoals));
MR_init_label_sl(COMPLETION_LABEL(LoopOverSuspensions));
@@ -1838,18 +1824,18 @@
MR_init_entry_an(MR_table_mm_commit);
- MR_init_entry_sl(MR_RET_ALL_NONDET_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_RET_ALL_NONDET_ENTRY);
+ MR_init_entry_sl(MR_MMSC_RET_ALL_NONDET_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_RET_ALL_NONDET_ENTRY);
MR_init_label_sl(RET_ALL_NONDET_LABEL(Next));
- MR_init_entry_sl(MR_RET_ALL_MULTI_ENTRY);
- MR_INIT_PROC_LAYOUT_ADDR(MR_RET_ALL_MULTI_ENTRY);
+ MR_init_entry_sl(MR_MMSC_RET_ALL_MULTI_ENTRY);
+ MR_INIT_PROC_LAYOUT_ADDR(MR_MMSC_RET_ALL_MULTI_ENTRY);
MR_init_label_sl(RET_ALL_MULTI_LABEL(Next));
- MR_init_entry_sl(MR_IS_NOT_DUPL_ENTRY);
+ MR_init_entry_sl(MR_MMSC_IS_NOT_DUPL_ENTRY);
MR_BEGIN_CODE
-MR_define_entry(MR_SUSPEND_ENTRY);
+MR_define_entry(MR_MMSC_SUSPEND_ENTRY);
/*
** The suspend procedure saves the state of the Mercury runtime so that
** it may be used in the table_mm_completion procedure below to return
@@ -1873,7 +1859,7 @@
** nondet stack fragment. The framevar slot is for use by
** table_mm_completion.
*/
- MR_mkframe(MR_STRINGIFY(MR_SUSPEND_ENTRY), 1, MR_ENTRY(MR_do_fail));
+ MR_mkframe(MR_STRINGIFY(MR_MMSC_SUSPEND_ENTRY), 1, MR_ENTRY(MR_do_fail));
MR_define_label(SUSPEND_LABEL(Call));
{
@@ -1951,7 +1937,7 @@
}
MR_fail();
-MR_define_entry(MR_COMPLETION_ENTRY);
+MR_define_entry(MR_MMSC_COMPLETION_ENTRY);
/*
** The completion procedure restores answers to suspended consumers.
** It works by restoring the consumer state saved by the consumer's call
@@ -2194,16 +2180,20 @@
#ifdef MR_TABLE_DEBUG
if (MR_tabledebug) {
MR_AnswerList answer_list;
+ MR_Consumer *consumer;
+ consumer = completion_info->MR_ri_cur_consumer;
printf("returning answers to consumer %s\n",
- MR_consumer_addr_name(completion_info->MR_ri_cur_consumer));
+ MR_consumer_addr_name(consumer));
#ifdef MR_MINIMAL_MODEL_DEBUG
printf("the list of answers to return:");
for (answer_list = cur_consumer_answer_list;
answer_list != NULL;
answer_list = answer_list->MR_aln_next_answer)
{
- printf(" #%d", answer_list->MR_aln_answer_num);
+ MR_print_answerblock(stdout,
+ consumer->MR_cns_subgoal->MR_sg_proc_layout,
+ answer_list->MR_aln_answer_block);
}
#endif /* MR_MINIMAL_MODEL_DEBUG */
printf("\n");
@@ -2237,20 +2227,19 @@
** XXX we need to prove that assertion
*/
- MR_r1 = (MR_Word) answer_list->MR_aln_answer_data.MR_answerblock;
+ MR_r1 = (MR_Word) answer_list->MR_aln_answer_block;
consumer->MR_cns_remaining_answer_list_ptr =
&(answer_list->MR_aln_next_answer);
consumer->MR_cns_num_returned_answers++;
#ifdef MR_TABLE_DEBUG
if (MR_tabledebug) {
- #ifdef MR_MINIMAL_MODEL_DEBUG
- printf("returning answer %d to consumer %s\n",
- answer_list->MR_aln_answer_num,
- MR_consumer_addr_name(completion_info->MR_ri_cur_consumer));
- #else
printf("returning answer to consumer %s\n",
MR_consumer_addr_name(completion_info->MR_ri_cur_consumer));
+ #ifdef MR_MINIMAL_MODEL_DEBUG
+ MR_print_answerblock(stdout, completion_info->MR_ri_cur_consumer->
+ MR_cns_subgoal->MR_sg_proc_layout,
+ answer_list->MR_aln_answer_block);
#endif
}
#endif /* MR_TABLE_DEBUG */
@@ -2264,7 +2253,7 @@
}
MR_define_label(COMPLETION_LABEL(RedoPoint));
- MR_update_prof_current_proc(MR_LABEL(MR_COMPLETION_ENTRY));
+ MR_update_prof_current_proc(MR_LABEL(MR_MMSC_COMPLETION_ENTRY));
#ifdef MR_TABLE_STATISTICS
MR_minmodel_stats_cnt_completion_redo_point++;
@@ -2422,7 +2411,7 @@
MR_commit_cut();
MR_fail();
-MR_define_entry(MR_RET_ALL_NONDET_ENTRY);
+MR_define_entry(MR_MMSC_RET_ALL_NONDET_ENTRY);
{
MR_SubgoalPtr Subgoal;
MR_AnswerList CurNode0;
@@ -2443,7 +2432,7 @@
MR_redo();
}
- AnswerBlock = CurNode0->MR_aln_answer_data.MR_answerblock;
+ AnswerBlock = CurNode0->MR_aln_answer_block;
CurNode = CurNode0->MR_aln_next_answer;
/* Consider not creating the stack frame if CurNode is NULL. */
@@ -2466,14 +2455,14 @@
MR_fail();
}
- AnswerBlock = CurNode0->MR_aln_answer_data.MR_answerblock;
+ AnswerBlock = CurNode0->MR_aln_answer_block;
CurNode = CurNode0->MR_aln_next_answer;
MR_framevar(1) = (MR_Word) CurNode;
MR_r1 = (MR_Word) AnswerBlock;
}
MR_succeed();
-MR_define_entry(MR_RET_ALL_MULTI_ENTRY);
+MR_define_entry(MR_MMSC_RET_ALL_MULTI_ENTRY);
{
MR_SubgoalPtr Subgoal;
MR_AnswerList CurNode0;
@@ -2494,7 +2483,7 @@
MR_fatal_error("table_mm_return_all_multi: no answers");
}
- AnswerBlock = CurNode0->MR_aln_answer_data.MR_answerblock;
+ AnswerBlock = CurNode0->MR_aln_answer_block;
CurNode = CurNode0->MR_aln_next_answer;
/* Consider not creating the stack frame if CurNode is NULL. */
@@ -2517,14 +2506,14 @@
MR_fail();
}
- AnswerBlock = CurNode0->MR_aln_answer_data.MR_answerblock;
+ AnswerBlock = CurNode0->MR_aln_answer_block;
CurNode = CurNode0->MR_aln_next_answer;
MR_framevar(1) = (MR_Word) CurNode;
MR_r1 = (MR_Word) AnswerBlock;
}
MR_succeed();
-MR_define_entry(MR_IS_NOT_DUPL_ENTRY);
+MR_define_entry(MR_MMSC_IS_NOT_DUPL_ENTRY);
{
MR_TrieNode T;
@@ -2535,38 +2524,40 @@
MR_END_MODULE
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
#endif /* MR_HIGHLEVEL_CODE */
/* Ensure that the initialization code for the above modules gets to run. */
/*
-INIT mercury_sys_init_table_modules
+INIT mercury_sys_init_mmsc_modules
*/
-MR_MODULE_STATIC_OR_EXTERN MR_ModuleFunc table_mm_suspend_completion_module;
+MR_MODULE_STATIC_OR_EXTERN MR_ModuleFunc mmsc_module;
/* forward declarations to suppress gcc -Wmissing-decl warnings */
-void mercury_sys_init_table_modules_init(void);
-void mercury_sys_init_table_modules_init_type_tables(void);
+void mercury_sys_init_mmsc_modules_init(void);
+void mercury_sys_init_mmsc_modules_init_type_tables(void);
#ifdef MR_DEEP_PROFILING
-void mercury_sys_init_table_modules_write_out_proc_statics(FILE *fp);
+void mercury_sys_init_mmsc_modules_write_out_proc_statics(FILE *fp);
#endif
-void mercury_sys_init_table_modules_init(void)
+void mercury_sys_init_mmsc_modules_init(void)
{
#ifndef MR_HIGHLEVEL_CODE
- table_mm_suspend_completion_module();
+ mmsc_module();
#endif /* MR_HIGHLEVEL_CODE */
}
-void mercury_sys_init_table_modules_init_type_tables(void)
+void mercury_sys_init_mmsc_modules_init_type_tables(void)
{
/* no types to register */
}
#ifdef MR_DEEP_PROFILING
-void mercury_sys_init_table_modules_write_out_proc_statics(FILE *fp)
+void mercury_sys_init_mmsc_modules_write_out_proc_statics(FILE *fp)
{
/* no proc_statics to write out */
+ /* XXX we need to fix the deep profiling */
+ /* of minimal model tabled predicates */
}
#endif
Index: runtime/mercury_minimal_model.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_minimal_model.h,v
retrieving revision 1.10
diff -u -b -r1.10 mercury_minimal_model.h
--- runtime/mercury_minimal_model.h 31 May 2004 04:13:05 -0000 1.10
+++ runtime/mercury_minimal_model.h 17 Jul 2004 06:54:27 -0000
@@ -5,11 +5,11 @@
*/
/*
-** mercury_minimal_model.h - definitions of some basic stuff used for tabling.
-** For tabling code, the Mercury compiler (compiler/table_gen.m) generates
-** references to special procedures defined in library/table_builtin.m.
-** The types and macros defined here are used by the procedures defined in
-** library/table_builtin.m.
+** mercury_minimal_model.h - definitions of some basic stuff used for the stack
+** copy style of minimal model tabling. For tabling code, the Mercury compiler
+** (compiler/table_gen.m) generates references to special procedures defined
+** in library/table_builtin.m. The types and macros defined here are used
+** by the procedures defined in library/table_builtin.m.
*/
#ifndef MERCURY_MINIMAL_MODEL_H
@@ -21,14 +21,7 @@
#include "mercury_goto.h" /* for MR_declare_entry */
#include <stdio.h>
-struct MR_AnswerListNode_Struct {
- MR_TableNode MR_aln_answer_data;
- /* always uses the MR_answerblock member */
- MR_AnswerList MR_aln_next_answer;
-#ifdef MR_MINIMAL_MODEL_DEBUG
- MR_Integer MR_aln_answer_num;
-#endif
-};
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
/*
** The saved state of a generator or a consumer. While consumers get
@@ -104,6 +97,7 @@
** subgoal. The list of answers it points to expands transparently whenever
** the generator subgoal adds an answer to its answer list.
*/
+
struct MR_Consumer_Struct {
MR_SavedState MR_cns_saved_state;
MR_Subgoal *MR_cns_subgoal;
@@ -201,8 +195,6 @@
/*---------------------------------------------------------------------------*/
-#ifdef MR_USE_MINIMAL_MODEL
-
extern const MR_Proc_Layout *MR_subgoal_debug_cur_proc;
extern void MR_enter_consumer_debug(MR_Consumer *consumer);
@@ -240,31 +232,50 @@
/* XXX */
#endif
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+#ifdef MR_HIGHLEVEL_CODE
+
+ extern void MR_CALL
+ mercury__table_builtin__table_mm_completion_1_p_0(
+ MR_C_Pointer subgoal_table_node, MR_C_Pointer *answer_block,
+ MR_Cont cont, void *cont_env_ptr);
+ extern void MR_CALL
+ mercury__table_builtin__table_mm_suspend_consumer_2_p_0(
+ MR_C_Pointer subgoal_table_node);
+ extern void MR_CALL
+ mercury__table_builtin__table_mm_return_all_nondet_2_2_p_0(
+ MR_C_Pointer answer_list, MR_C_Pointer answer_block);
+ extern void MR_CALL
+ mercury__table_builtin__table_mm_return_all_multi_2_2_p_0(
+ MR_C_Pointer answer_list, MR_C_Pointer answer_block);
+ extern void MR_CALL
+ mercury__table_builtin__table_mm_answer_is_not_duplicate_1_p_0(
+ MR_C_Pointer subgoal_table_node);
-#ifndef MR_HIGHLEVEL_CODE
+#else /* ! MR_HIGHLEVEL_CODE */
- #define MR_SUSPEND_ENTRY \
+ #define MR_MMSC_SUSPEND_ENTRY \
MR_proc_entry_user_name(table_builtin, \
table_mm_suspend_consumer, 2, 0)
- #define MR_COMPLETION_ENTRY \
+ #define MR_MMSC_COMPLETION_ENTRY \
MR_proc_entry_user_name(table_builtin, \
table_mm_completion, 1, 0)
- #define MR_RET_ALL_NONDET_ENTRY \
+ #define MR_MMSC_RET_ALL_NONDET_ENTRY \
MR_proc_entry_user_name(table_builtin, \
table_mm_return_all_nondet, 2, 0)
- #define MR_RET_ALL_MULTI_ENTRY \
+ #define MR_MMSC_RET_ALL_MULTI_ENTRY \
MR_proc_entry_user_name(table_builtin, \
table_mm_return_all_multi, 2, 0)
- #define MR_IS_NOT_DUPL_ENTRY \
+ #define MR_MMSC_IS_NOT_DUPL_ENTRY \
MR_proc_entry_user_name(table_builtin, \
table_mm_answer_is_not_duplicate, 1, 0)
- MR_declare_entry(MR_SUSPEND_ENTRY);
- MR_declare_entry(MR_COMPLETION_ENTRY);
- MR_declare_entry(MR_RET_ALL_NONDET_ENTRY);
- MR_declare_entry(MR_RET_ALL_MULTI_ENTRY);
- MR_declare_entry(MR_IS_NOT_DUPL_ENTRY);
+ MR_declare_entry(MR_MMSC_SUSPEND_ENTRY);
+ MR_declare_entry(MR_MMSC_COMPLETION_ENTRY);
+ MR_declare_entry(MR_MMSC_RET_ALL_NONDET_ENTRY);
+ MR_declare_entry(MR_MMSC_RET_ALL_MULTI_ENTRY);
+ MR_declare_entry(MR_MMSC_IS_NOT_DUPL_ENTRY);
#endif /* !MR_HIGHLEVEL_CODE */
Index: runtime/mercury_ml_expand_body.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_ml_expand_body.h,v
retrieving revision 1.33
diff -u -b -r1.33 mercury_ml_expand_body.h
--- runtime/mercury_ml_expand_body.h 28 Jun 2004 04:50:05 -0000 1.33
+++ runtime/mercury_ml_expand_body.h 28 Jun 2004 05:06:10 -0000
@@ -868,7 +868,7 @@
return;
case MR_TYPECTOR_REP_SUBGOAL:
-#if MR_USE_MINIMAL_MODEL
+#if MR_USE_MINIMAL_MODEL_STACK_COPY
if (noncanon == MR_NONCANON_CC) {
handle_functor_name(MR_subgoal_addr_name(
(MR_SubgoalPtr) *data_word_ptr));
Index: runtime/mercury_mm_own_stacks.c
===================================================================
RCS file: runtime/mercury_mm_own_stacks.c
diff -N runtime/mercury_mm_own_stacks.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ runtime/mercury_mm_own_stacks.c 19 Jul 2004 04:10:14 -0000
@@ -0,0 +1,510 @@
+/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
+** Copyright (C) 2004 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** This module contains the functions related specifically to the own stack
+** style of minimal model tabling.
+*/
+
+#include "mercury_imp.h"
+#include "mercury_array_macros.h"
+#include "mercury_tabling.h"
+#include "mercury_mm_own_stacks.h"
+
+#include <stdio.h>
+
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+
+static void make_gen_follow_leader(MR_Generator *this_follower,
+ MR_Generator *leader);
+
+/*---------------------------------------------------------------------------*/
+
+/*
+** This part of the file maintains data structures that can be used
+** to debug minimal model tabling. It does so by allowing the debugger
+** to refer to tabling data structures such as subgoals and consumers
+** by small, easily remembered numbers, not memory addresses.
+*/
+
+/* set by MR_trace_event, used by table_nondet_setup */
+const MR_Proc_Layout *MR_subgoal_debug_cur_proc = NULL;
+
+struct MR_ConsDebug_Struct
+{
+ MR_Consumer *MR_cod_consumer;
+ int MR_cod_sequence_num;
+ int MR_cod_version_num;
+ int MR_cod_valid;
+};
+
+struct MR_GenDebug_Struct
+{
+ MR_Generator *MR_gd_generator;
+ int MR_gd_sequence_num;
+ int MR_gd_version_num;
+ int MR_gd_valid;
+};
+
+#define MR_CONS_DEBUG_INIT 10
+#define MR_GEN_DEBUG_INIT 10
+#define MR_NAME_BUF 1024
+
+static MR_ConsDebug *MR_cons_debug_infos = NULL;
+static int MR_cons_debug_info_next = 0;
+static int MR_cons_debug_info_max = 0;
+
+static MR_GenDebug *MR_gen_debug_infos = NULL;
+static int MR_gen_debug_info_next = 0;
+static int MR_gen_debug_info_max = 0;
+
+void
+MR_enter_cons_debug(MR_Consumer *consumer)
+{
+ int i;
+
+ for (i = 0; i < MR_cons_debug_info_next; i++) {
+ if (MR_cons_debug_infos[i].MR_cod_consumer == consumer) {
+ MR_cons_debug_infos[i].MR_cod_version_num++;
+ MR_cons_debug_infos[i].MR_cod_valid = MR_TRUE;
+ return;
+ }
+ }
+
+ MR_ensure_room_for_next(MR_cons_debug_info, MR_ConsDebug,
+ MR_CONS_DEBUG_INIT);
+ i = MR_cons_debug_info_next;
+ MR_cons_debug_infos[i].MR_cod_consumer = consumer;
+ MR_cons_debug_infos[i].MR_cod_sequence_num = i;
+ MR_cons_debug_infos[i].MR_cod_version_num = 0;
+ MR_cons_debug_infos[i].MR_cod_valid = MR_TRUE;
+ MR_cons_debug_info_next++;
+}
+
+MR_ConsDebug *
+MR_lookup_cons_debug_addr(MR_Consumer *consumer)
+{
+ int i;
+
+ for (i = 0; i < MR_cons_debug_info_next; i++) {
+ if (MR_cons_debug_infos[i].MR_cod_consumer == consumer) {
+ return &MR_cons_debug_infos[i];
+ }
+ }
+
+ return NULL;
+}
+
+MR_ConsDebug *
+MR_lookup_cons_debug_num(int cons_index)
+{
+ int i;
+
+ for (i = 0; i < MR_cons_debug_info_next; i++) {
+ if (MR_cons_debug_infos[i].MR_cod_sequence_num == cons_index) {
+ return &MR_cons_debug_infos[i];
+ }
+ }
+
+ return NULL;
+}
+
+const char *
+MR_cons_debug_name(MR_ConsDebug *cons_debug)
+{
+ const char *warning;
+ char buf[MR_NAME_BUF];
+
+ if (cons_debug == NULL) {
+ return "unknown";
+ }
+
+ if (cons_debug->MR_cod_valid) {
+ warning = "";
+ } else {
+ warning = " INVALID";
+ }
+
+ if (cons_debug->MR_cod_version_num > 0) {
+ sprintf(buf, "con %d/%d (%p)%s", cons_debug->MR_cod_sequence_num,
+ cons_debug->MR_cod_version_num,
+ cons_debug->MR_cod_consumer, warning);
+ } else {
+ sprintf(buf, "con %d (%p)%s", cons_debug->MR_cod_sequence_num,
+ cons_debug->MR_cod_consumer, warning);
+ }
+
+ return strdup(buf);
+}
+
+const char *
+MR_cons_addr_name(MR_Consumer *consumer)
+{
+ MR_ConsDebug *cons_debug;
+
+ if (consumer == NULL) {
+ return "NULL";
+ }
+
+ cons_debug = MR_lookup_cons_debug_addr(consumer);
+ return MR_cons_debug_name(cons_debug);
+}
+
+const char *
+MR_cons_num_name(int cons_index)
+{
+ MR_ConsDebug *cons_debug;
+
+ cons_debug = MR_lookup_cons_debug_num(cons_index);
+ return MR_cons_debug_name(cons_debug);
+}
+
+void
+MR_enter_gen_debug(MR_Generator *generator)
+{
+ int i;
+
+ for (i = 0; i < MR_gen_debug_info_next; i++) {
+ if (MR_gen_debug_infos[i].MR_gd_generator == generator) {
+ MR_gen_debug_infos[i].MR_gd_version_num++;
+ MR_gen_debug_infos[i].MR_gd_valid = MR_TRUE;
+ return;
+ }
+ }
+
+ MR_ensure_room_for_next(MR_gen_debug_info, MR_GenDebug,
+ MR_GEN_DEBUG_INIT);
+ i = MR_gen_debug_info_next;
+ MR_gen_debug_infos[i].MR_gd_generator = generator;
+ MR_gen_debug_infos[i].MR_gd_sequence_num = i;
+ MR_gen_debug_infos[i].MR_gd_version_num = 0;
+ MR_gen_debug_infos[i].MR_gd_valid = MR_TRUE;
+ MR_gen_debug_info_next++;
+}
+
+MR_GenDebug *
+MR_lookup_gen_debug_addr(MR_Generator *generator)
+{
+ int i;
+
+ for (i = 0; i < MR_gen_debug_info_next; i++) {
+ if (MR_gen_debug_infos[i].MR_gd_generator == generator) {
+ return &MR_gen_debug_infos[i];
+ }
+ }
+
+ return NULL;
+}
+
+MR_GenDebug *
+MR_lookup_gen_debug_num(int gen_index)
+{
+ int i;
+
+ for (i = 0; i < MR_gen_debug_info_next; i++) {
+ if (MR_gen_debug_infos[i].MR_gd_sequence_num == gen_index) {
+ return &MR_gen_debug_infos[i];
+ }
+ }
+
+ return NULL;
+}
+
+const char *
+MR_gen_debug_name(MR_GenDebug *gen_debug)
+{
+ const char *warning;
+ char buf[MR_NAME_BUF];
+
+ if (gen_debug == NULL) {
+ return "unknown";
+ }
+
+ if (gen_debug->MR_gd_valid) {
+ warning = "";
+ } else {
+ warning = " INVALID";
+ }
+
+ if (gen_debug->MR_gd_version_num > 0) {
+ sprintf(buf, "sub %d/%d (%p)%s", gen_debug->MR_gd_sequence_num,
+ gen_debug->MR_gd_version_num,
+ gen_debug->MR_gd_generator, warning);
+ } else {
+ sprintf(buf, "sub %d (%p)%s", gen_debug->MR_gd_sequence_num,
+ gen_debug->MR_gd_generator, warning);
+ }
+
+ return strdup(buf);
+}
+
+const char *
+MR_gen_addr_name(MR_Generator *generator)
+{
+ MR_GenDebug *gen_debug;
+
+ if (generator == NULL) {
+ return "NULL";
+ }
+
+ gen_debug = MR_lookup_gen_debug_addr(generator);
+ return MR_gen_debug_name(gen_debug);
+}
+
+const char *
+MR_gen_num_name(int gen_index)
+{
+ MR_GenDebug *gen_debug;
+
+ gen_debug = MR_lookup_gen_debug_num(gen_index);
+ return MR_gen_debug_name(gen_debug);
+}
+
+void
+MR_print_gen_debug(FILE *fp, const MR_Proc_Layout *proc,
+ MR_GenDebug *gen_debug)
+{
+ if (gen_debug == NULL) {
+ fprintf(fp, "NULL gen_debug\n");
+ } else {
+ MR_print_generator(fp, proc, gen_debug->MR_gd_generator);
+ }
+}
+
+void
+MR_print_generator(FILE *fp, const MR_Proc_Layout *proc,
+ MR_Generator *generator)
+{
+ MR_SubgoalList follower;
+ MR_ConsumerList consumer;
+ MR_AnswerList answer_list;
+ MR_Word *answer;
+ int answer_num;
+
+ if (generator == NULL) {
+ fprintf(fp, "NULL generator\n");
+ return;
+ }
+
+#ifdef MR_TABLE_DEBUG
+ if (proc == NULL && generator->MR_sg_proc_layout != NULL) {
+ proc = generator->MR_sg_proc_layout;
+ }
+#endif
+
+ fprintf(fp, "generator %s", MR_gen_addr_name(generator));
+ if (generator->MR_gen_back_ptr == NULL) {
+ fprintf(fp, ", DELETED");
+ }
+ fprintf(fp, "\n");
+
+ if (proc != NULL) {
+ fprintf(fp, "proc: ");
+ MR_print_proc_id(fp, proc);
+ 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));
+ }
+
+ 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));
+ }
+
+ fprintf(fp, "\n");
+ fprintf(fp, "answers: %d\n", generator->MR_sg_num_ans);
+
+ if (proc != NULL) {
+ answer_list = generator->MR_sg_answer_list;
+ answer_num = 1;
+ while (answer_list != NULL) {
+ fprintf(fp, "answer #%d: <", answer_num);
+ MR_print_answerblock(fp, proc, answer_list->MR_aln_answer_block);
+ fprintf(fp, ">\n");
+ answer_list = answer_list->MR_aln_next_answer;
+ answer_num++;
+ }
+ }
+#endif
+}
+
+void
+MR_print_cons_debug(FILE *fp, const MR_Proc_Layout *proc,
+ MR_ConsDebug *cons_debug)
+{
+ if (cons_debug == NULL) {
+ fprintf(fp, "NULL cons_debug\n");
+ } else {
+ MR_print_consumer(fp, proc, cons_debug->MR_cod_consumer);
+ }
+}
+
+void
+MR_print_consumer(FILE *fp, const MR_Proc_Layout *proc, MR_Consumer *consumer)
+{
+ if (consumer == NULL) {
+ fprintf(fp, "NULL consumer\n");
+ return;
+ }
+
+ fprintf(fp, "consumer %s", MR_cons_addr_name(consumer));
+
+ /* XXX check semantics of DELETED */
+ if (consumer->MR_cons_answer_generator == NULL) {
+ fprintf(fp, ", DELETED\n");
+ } else {
+ fprintf(fp, ", answer generator %s",
+ MR_gen_addr_name(consumer->MR_cons_answer_generator));
+ if (consumer->MR_cons_containing_generator != NULL) {
+ fprintf(fp, ", in generator %s\n",
+ MR_gen_addr_name(consumer->MR_cons_answer_generator));
+ } else {
+ fprintf(fp, ", in main context\n\n");
+ }
+ fprintf(fp, "returned answers %d, remaining answers ptr %p\n",
+ consumer->MR_cons_num_returned_answers,
+ consumer->MR_cons_remaining_answer_list_ptr);
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+
+static int MR_next_gen_context = 1;
+
+static MR_Context *
+MR_get_context_for_gen(MR_Generator *gen)
+{
+ MR_Dlist *list;
+ MR_Dlist *item;
+ MR_Context *ctxt;
+
+ list = MR_ENGINE(MR_eng_free_contexts);
+ if (MR_dlist_length(list) > 0) {
+ item = MR_dlist_first_ptr(list);
+ ctxt = (MR_Context *) MR_dlist_data(item);
+ MR_dlist_delete(list, item, NULL);
+ } else {
+ char buf[80]; /* ought to be plenty big enough */
+
+ sprintf(buf, "gen%d", MR_next_gen_context);
+ MR_next_gen_context++;
+ ctxt = MR_create_context(strdup(buf), gen);
+ }
+
+ ctxt->MR_ctxt_owner_generator = gen;
+ return ctxt;
+}
+
+MR_ConsumerPtr
+MR_table_setup_consumer(MR_TableNode trie_node, MR_Integer num_input_args,
+ MR_Word *generator_pred, MR_String pred_id)
+{
+ /* not yet implemented */
+}
+
+MR_Generator *
+MR_setup_generator(MR_String pred_id, MR_TrieNode trie_node)
+{
+ /*
+ ** Initialize the generator if this is the first time we see it.
+ ** If the subgoal structure already exists but is marked inactive,
+ ** then it was left by a previous generator that couldn't
+ ** complete the evaluation of the subgoal due to a commit.
+ ** In that case, we want to forget all about the old generator.
+ */
+
+ MR_restore_transient_registers();
+#if 0
+ if (trie_node->MR_generator == NULL) {
+ MR_Generator *gen;
+ MR_Context *context;
+
+ gen = MR_TABLE_NEW(MR_Generator);
+ context = MR_get_context_for_gen(gen);
+
+ 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;
+
+ /*
+ ** MR_subgoal_debug_cur_proc refers to the last procedure
+ ** that executed a call event, if any. If the procedure that is
+ ** executing table_nondet_setup is traced, this will be that
+ ** procedure, and recording the layout structure of the
+ ** processor in the generator allows us to interpret the contents
+ ** of the generator's answer tables. If the procedure executing
+ ** table_nondet_setup is not traced, then the layout structure
+ ** belongs to another procedure and the any use of the
+ ** MR_gen_proc_layout field will probably cause a core dump.
+ ** For implementors debugging minimal model tabling, this is
+ ** the right tradeoff.
+ */
+ gen->MR_gen_proc_layout = MR_subgoal_debug_cur_proc;
+
+#ifdef MR_TABLE_DEBUG
+ MR_enter_gen_debug(gen);
+
+ 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");
+ }
+ }
+
+ if (MR_maxfr != MR_curfr) {
+ MR_fatal_error("MR_maxfr != MR_curfr at table setup\n");
+ }
+#endif
+ trie_node->MR_generator = gen;
+ }
+
+#endif
+ return trie_node->MR_generator;
+ MR_save_transient_registers();
+}
+
+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 /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
Index: runtime/mercury_mm_own_stacks.h
===================================================================
RCS file: runtime/mercury_mm_own_stacks.h
diff -N runtime/mercury_mm_own_stacks.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ runtime/mercury_mm_own_stacks.h 24 Jun 2004 09:22:16 -0000
@@ -0,0 +1,115 @@
+/*
+** Copyright (C) 2004 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** mercury_mm_own_stacks.h:
+** definitions of some basic stuff used for the own stack style of
+** minimal model tabling.
+*/
+
+#ifndef MERCURY_MM_OWN_STACKS_H
+#define MERCURY_MM_OWN_STACKS_H
+
+#include "mercury_imp.h"
+#include "mercury_tabling.h"
+#include "mercury_stack_layout.h"
+
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+
+/*
+** There is one MR_Generator structure per active generator.
+**
+** The back_ptr field points back to the MR_TrieNode that points to this
+** generator.
+**
+** The stack_pair field points back to the MR_GenStackPair struct whose
+** MR_gen_pair_gen field points here; it is used to find the generator's
+** stacks.
+**
+** The proc_layout field is set only if debugging is enabled; it allows us
+** to find out what subgoal we are the generator for, and to interpret
+** the answer table.
+**
+** The pred_id field is currently always set to a string identifying the
+** main predicate of the subgoal we are the generator for. It is used for
+** debugging. Once this stuff is debugged, we can disable this field.
+**
+** The leader field points to the leader of the clique this generator belongs
+** to; if this generator is the leader, this field points to its own structure.
+**
+** If this generator is the leader of its clique, the led_generators field will
+** point to a list of all generators in the clique, including itself. If this
+** generator is not the leader of its clique, this field will contain an empty
+** list.
+*/
+
+struct MR_Generator_Struct {
+ MR_TrieNode MR_gen_back_ptr;
+ MR_Context *MR_gen_context;
+ const MR_Proc_Layout *MR_gen_proc_layout;
+ MR_String *MR_gen_pred_id;
+ MR_Generator *MR_gen_leader;
+ MR_Dlist *MR_gen_led_generators;
+ MR_Dlist *MR_gen_consumers;
+ MR_Integer MR_gen_num_answers;
+ MR_TableNode MR_gen_answer_table;
+ MR_AnswerList MR_gen_answer_list;
+ MR_AnswerList *MR_gen_answer_list_tail;
+};
+
+struct MR_Consumer_Struct {
+ MR_Generator *MR_cons_answer_generator;
+ MR_Generator *MR_cons_containing_generator;
+ MR_Integer MR_cons_num_returned_answers;
+ MR_AnswerList *MR_cons_remaining_answer_list_ptr;
+};
+
+/*---------------------------------------------------------------------------*/
+
+extern const MR_Proc_Layout *MR_subgoal_debug_cur_proc;
+
+extern void MR_enter_cons_debug(MR_Consumer *consumer);
+extern MR_ConsDebug *MR_lookup_cons_debug_addr(MR_Consumer *consumer);
+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_num_name(int consumer_index);
+
+extern void MR_enter_gen_debug(MR_Generator *gen);
+extern MR_GenDebug *MR_lookup_gen_debug_addr(MR_Generator *gen);
+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_num_name(int gen_index);
+
+extern void MR_print_gen_debug(FILE *fp,
+ const MR_Proc_Layout *proc,
+ MR_GenDebug *gen_debug);
+extern void MR_print_generator(FILE *fp,
+ const MR_Proc_Layout *proc,
+ MR_Generator *gen);
+extern void MR_print_cons_debug(FILE *fp,
+ const MR_Proc_Layout *proc,
+ MR_ConsDebug *consumer_debug);
+extern void MR_print_consumer(FILE *fp,
+ const MR_Proc_Layout *proc,
+ MR_Consumer *consumer);
+
+extern MR_ConsumerPtr MR_table_mmos_setup_consumer(MR_TableNode trie_node,
+ MR_Integer num_input_args,
+ MR_Word *generator_pred, MR_String pred_id);
+extern MR_GeneratorPtr MR_mmos_setup_generator(MR_String pred_id,
+ MR_TrieNode trie_node);
+extern MR_AnswerBlock MR_table_mmos_consumer_get_next_answer(
+ MR_ConsumerPtr consumer);
+extern MR_TrieNode MR_table_mmos_get_answer_table(MR_GeneratorPtr
+ generator);
+extern MR_AnswerBlock MR_table_mmos_create_answer_block(MR_GeneratorPtr
+ generator);
+
+#endif /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
+#endif /* MERCURY_MM_OWN_STACKS_H */
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.83
diff -u -b -r1.83 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h 7 Jul 2004 07:11:16 -0000 1.83
+++ runtime/mercury_stack_layout.h 7 Jul 2004 07:17:06 -0000
@@ -748,7 +748,8 @@
MR_EVAL_METHOD_NORMAL,
MR_EVAL_METHOD_LOOP_CHECK,
MR_EVAL_METHOD_MEMO,
- MR_EVAL_METHOD_MINIMAL,
+ MR_EVAL_METHOD_MINIMAL_STACK_COPY,
+ MR_EVAL_METHOD_MINIMAL_OWN_STACKS,
MR_EVAL_METHOD_TABLE_IO,
MR_EVAL_METHOD_TABLE_IO_DECL,
MR_EVAL_METHOD_TABLE_IO_UNITIZE,
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.66
diff -u -b -r1.66 mercury_stack_trace.c
--- runtime/mercury_stack_trace.c 7 Jul 2004 07:11:16 -0000 1.66
+++ runtime/mercury_stack_trace.c 19 Jul 2004 02:46:07 -0000
@@ -92,14 +92,24 @@
MR_dump_stack(MR_Code *success_pointer, MR_Word *det_stack_pointer,
MR_Word *current_frame, MR_bool include_trace_data)
{
-#ifndef MR_STACK_TRACE
- fprintf(stderr, "Stack dump not available in this grade.\n");
-#else
-
const MR_Internal *label;
const MR_Label_Layout *layout;
const char *result;
+ MR_bool stack_dump_available;
+ char *env_suppress;
+ env_suppress = getenv("MERCURY_SUPPRESS_STACK_TRACE");
+ if (env_suppress != NULL) {
+ return;
+ }
+
+#ifdef MR_STACK_TRACE
+ stack_dump_available = MR_TRUE;
+#else
+ stack_dump_available = MR_FALSE;
+#endif
+
+ if (stack_dump_available) {
fprintf(stderr, "Stack dump follows:\n");
MR_do_init_modules();
@@ -116,7 +126,9 @@
fprintf(stderr, "%s\n", result);
}
}
-#endif
+ } else {
+ fprintf(stderr, "Stack dump not available in this grade.\n");
+ }
}
const char *
@@ -487,7 +499,7 @@
fprintf(fp, " succfr: ");
MR_print_nondstackptr(fp, MR_succfr_slot(base_maxfr));
fprintf(fp, "\n");
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
fprintf(fp, " detfr: ");
MR_print_detstackptr(fp, MR_table_detfr_slot(base_maxfr));
fprintf(fp, "\n");
@@ -930,8 +942,8 @@
if (ip == MR_ENTRY(MR_do_trace_redo_fail_deep)) {
return MR_FALSE;
}
-#ifdef MR_USE_MINIMAL_MODEL
- if (ip == MR_ENTRY(MR_COMPLETION_ENTRY)) {
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+ if (ip == MR_ENTRY(MR_MMSC_COMPLETION_ENTRY)) {
return MR_FALSE;
}
#endif
@@ -1227,6 +1239,8 @@
}
#if !defined(MR_HIGHLEVEL_CODE) && defined(MR_TABLE_DEBUG)
+ #if 0
+ /* reenable this code if you need to */
if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
MR_print_detstackptr(fp, base_sp);
} else {
@@ -1234,6 +1248,7 @@
}
fprintf(fp, " ");
+ #endif
#endif
}
Index: runtime/mercury_stacks.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.c,v
retrieving revision 1.14
diff -u -b -r1.14 mercury_stacks.c
--- runtime/mercury_stacks.c 7 Jul 2004 07:11:17 -0000 1.14
+++ runtime/mercury_stacks.c 7 Jul 2004 07:17:06 -0000
@@ -116,7 +116,7 @@
#undef MR_TABLE_DEBUG
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_Integer MR_gen_next_var;
MR_GenStackFrame *MR_gen_stack_var;
@@ -609,4 +609,4 @@
/***************************************************************************/
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.48
diff -u -b -r1.48 mercury_stacks.h
--- runtime/mercury_stacks.h 7 Jul 2004 07:11:17 -0000 1.48
+++ runtime/mercury_stacks.h 7 Jul 2004 07:17:06 -0000
@@ -133,7 +133,7 @@
#define MR_NONDET_TEMP_SIZE 3 /* prevfr, redoip, redofr */
#define MR_DET_TEMP_SIZE 4 /* prevfr, redoip, redofr, detfr */
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
#define MR_NONDET_FIXED_SIZE 6 /* prevfr, redoip, redofr, succip, succfr,
sp */
#else
@@ -179,7 +179,7 @@
/* DEFINITIONS FOR MANIPULATING THE NONDET STACK */
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
#define MR_maybe_fill_table_detfr_slot() \
do { \
MR_table_detfr_slot_word(MR_curfr) = \
@@ -476,7 +476,7 @@
/*---------------------------------------------------------------------------*/
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
/* DEFINITIONS FOR GENERATOR STACK FRAMES */
@@ -623,6 +623,6 @@
MR_Integer pneg_next,
MR_PNegStackFrame *pneg_block);
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
#endif /* not MERCURY_STACKS_H */
Index: runtime/mercury_tabling.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling.c,v
retrieving revision 1.63
diff -u -b -r1.63 mercury_tabling.c
--- runtime/mercury_tabling.c 28 Jun 2004 04:50:05 -0000 1.63
+++ runtime/mercury_tabling.c 18 Jul 2004 05:24:20 -0000
@@ -1154,10 +1154,14 @@
MR_table_hash_resize_new_entries);
fprintf(fp, "chunk allocations: %d\n", MR_table_hash_allocs);
- #ifdef MR_USE_MINIMAL_MODEL
+ #ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
fprintf(fp, "\n");
MR_minimal_model_report_stats(fp);
#endif
+ #ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ fprintf(fp, "\n");
+ MR_mm_own_stacks_report_stats(fp);
+ #endif
#else
fprintf(fp, "not enabled\n");
#endif
@@ -1165,6 +1169,143 @@
/*---------------------------------------------------------------------------*/
+const char *
+MR_loopcheck_status(MR_Unsigned status)
+{
+ switch (status) {
+ case MR_LOOP_INACTIVE:
+ return "INACTIVE";
+
+ case MR_LOOP_ACTIVE:
+ return "ACTIVE";
+ }
+
+ return "INVALID";
+}
+
+const char *
+MR_memo_status(MR_Unsigned status)
+{
+ switch (status) {
+ case MR_MEMO_INACTIVE:
+ return "INACTIVE";
+
+ case MR_MEMO_ACTIVE:
+ return "ACTIVE";
+
+ case MR_MEMO_SUCCEEDED:
+ return "SUCCEEDED";
+
+ case MR_MEMO_FAILED:
+ return "FAILED";
+
+ default:
+ return "SUCCESS_BLOCK";
+ }
+
+ return "INVALID";
+}
+
+const char *
+MR_memo_non_status(MR_MemoNonStatus status)
+{
+ switch (status) {
+ case MR_MEMO_NON_INACTIVE:
+ return "INACTIVE";
+
+ case MR_MEMO_NON_ACTIVE:
+ return "ACTIVE";
+
+ case MR_MEMO_NON_INCOMPLETE:
+ return "INCOMPLETE";
+
+ case MR_MEMO_NON_COMPLETE:
+ return "COMPLETE";
+ }
+
+ return "INVALID";
+}
+
+void
+MR_print_loopcheck_tip(FILE *fp, const MR_Proc_Layout *proc, MR_TrieNode table)
+{
+ switch (table->MR_loop_status) {
+ case MR_LOOP_INACTIVE:
+ fprintf(fp, "uninitialized\n");
+ break;
+ case MR_LOOP_ACTIVE:
+ fprintf(fp, "working\n");
+ break;
+ default:
+ MR_fatal_error("MR_print_loopcheck: bad status");
+ }
+}
+
+void
+MR_print_memo_tip(FILE *fp, const MR_Proc_Layout *proc, MR_TrieNode table)
+{
+ switch (table->MR_memo_status) {
+ case MR_MEMO_INACTIVE:
+ fprintf(fp, "uninitialized\n");
+ break;
+ case MR_MEMO_ACTIVE:
+ fprintf(fp, "working\n");
+ break;
+ case MR_MEMO_FAILED:
+ fprintf(fp, "failed\n");
+ break;
+ case MR_MEMO_SUCCEEDED:
+ fprintf(fp, "succeeded (no outputs)\n");
+ break;
+ default:
+ fprintf(fp, "succeeded <");
+ MR_print_answerblock(fp, proc, table->MR_answerblock);
+ fprintf(fp, ">\n");
+ break;
+ }
+}
+
+void
+MR_print_memo_non_record(FILE *fp, const MR_Proc_Layout *proc,
+ MR_MemoNonRecordPtr record)
+{
+ MR_AnswerList answer_list;
+ int i;
+
+ if (record == NULL) {
+ fprintf(fp, "inactive\n");
+ return;
+ }
+
+ switch (record->MR_mn_status) {
+ case MR_MEMO_NON_INACTIVE:
+ fprintf(fp, "inactive\n");
+ return;
+ case MR_MEMO_NON_ACTIVE:
+ fprintf(fp, "active\n");
+ break;
+ case MR_MEMO_NON_INCOMPLETE:
+ fprintf(fp, "incomplete\n");
+ break;
+ case MR_MEMO_NON_COMPLETE:
+ fprintf(fp, "complete\n");
+ break;
+ default:
+ MR_fatal_error("MR_print_memo_non_record: bad status");
+ break;
+ }
+
+ answer_list = record->MR_mn_answer_list;
+ i = 1;
+ while (answer_list != NULL) {
+ fprintf(fp, "answer #%d: <", i);
+ MR_print_answerblock(fp, proc, answer_list->MR_aln_answer_block);
+ fprintf(fp, ">\n");
+ answer_list = answer_list->MR_aln_next_answer;
+ i++;
+ }
+}
+
void
MR_print_answerblock(FILE *fp, const MR_Proc_Layout *proc,
MR_Word *answer_block)
@@ -1213,5 +1354,229 @@
}
}
}
+
+#ifdef MR_HIGHLEVEL_CODE
+
+static void MR_CALL
+ mercury__table_builtin__table_memo_return_all_answers_2_p_0(
+ MR_AnswerList answer_list0, MR_Box *boxed_answer_block,
+ MR_Cont cont, void *cont_env_ptr);
+
+static void MR_CALL
+mercury__table_builtin__table_memo_return_all_answers_2_p_0(
+ MR_AnswerList answer_list0, MR_Box *boxed_answer_block_ptr,
+ MR_Cont cont, void *cont_env_ptr)
+{
+ MR_AnswerList answer_list;
+
+ while (answer_list0 != NULL) {
+ answer_list = answer_list0->MR_aln_next_answer;
+ *boxed_answer_block_ptr = (MR_Box) answer_list0->MR_aln_answer_block;
+ cont(cont_env_ptr);
+ answer_list0 = answer_list;
+ }
+}
+
+void MR_CALL
+mercury__table_builtin__table_memo_return_all_answers_multi_2_p_0(
+ MR_Box boxed_record, MR_Box *boxed_answer_block_ptr,
+ MR_Cont cont, void *cont_env_ptr)
+{
+ MR_MemoNonRecordPtr record;
+ MR_AnswerList list;
+
+ record = (MR_MemoNonRecordPtr) boxed_record;
+ list = record->MR_mn_answer_list;
+ if (list == NULL) {
+ MR_fatal_error("table_memo_return_all_answers_multi: no answers");
+ }
+ mercury__table_builtin__table_memo_return_all_answers_2_p_0(list,
+ boxed_answer_block_ptr, cont, cont_env_ptr);
+}
+
+void MR_CALL
+mercury__table_builtin__table_memo_return_all_answers_nondet_2_p_0(
+ MR_Box boxed_record, MR_Box *boxed_answer_block_ptr,
+ MR_Cont cont, void *cont_env_ptr)
+{
+ MR_MemoNonRecordPtr record;
+ MR_AnswerList list;
+
+ record = (MR_MemoNonRecordPtr) boxed_record;
+ list = record->MR_mn_answer_list;
+ mercury__table_builtin__table_memo_return_all_answers_2_p_0(list,
+ boxed_answer_block_ptr, cont, cont_env_ptr);
+}
+
+#else /* MR_HIGHLEVEL_CODE */
+
+MR_define_extern_entry(MR_MEMO_NON_RET_ALL_NONDET_ENTRY);
+MR_define_extern_entry(MR_MEMO_NON_RET_ALL_MULTI_ENTRY);
+
+MR_EXTERN_USER_PROC_ID_PROC_LAYOUT(MR_DETISM_NON, 0, -1,
+ MR_PREDICATE, table_builtin, table_memo_return_all_answers_nondet, 2, 0);
+MR_EXTERN_USER_PROC_ID_PROC_LAYOUT(MR_DETISM_NON, 0, -1,
+ MR_PREDICATE, table_builtin, table_memo_return_all_answers_multi, 2, 0);
+
+#define MEMO_NON_RET_ALL_NONDET_LABEL(name) \
+ MR_label_name(MR_MEMO_NON_RET_ALL_NONDET_ENTRY, name)
+#define MEMO_NON_RET_ALL_MULTI_LABEL(name) \
+ MR_label_name(MR_MEMO_NON_RET_ALL_MULTI_ENTRY, name)
+
+MR_declare_label(MEMO_NON_RET_ALL_NONDET_LABEL(Next));
+MR_declare_label(MEMO_NON_RET_ALL_MULTI_LABEL(Next));
+
+MR_MAKE_USER_INTERNAL_LAYOUT(table_builtin,
+ table_memo_return_all_answers_nondet, 2, 0, Next);
+MR_MAKE_USER_INTERNAL_LAYOUT(table_builtin,
+ table_memo_return_all_answers_multi, 2, 0, Next);
+
+MR_BEGIN_MODULE(table_memo_non_module)
+ MR_init_entry_sl(MR_MEMO_NON_RET_ALL_NONDET_ENTRY);
+ MR_init_label_sl(MEMO_NON_RET_ALL_NONDET_LABEL(Next));
+ MR_init_entry_sl(MR_MEMO_NON_RET_ALL_MULTI_ENTRY);
+ MR_init_label_sl(MEMO_NON_RET_ALL_MULTI_LABEL(Next));
+MR_BEGIN_CODE
+
+MR_define_entry(MR_MEMO_NON_RET_ALL_NONDET_ENTRY);
+{
+ MR_MemoNonRecordPtr record;
+ MR_AnswerList cur_node0;
+ MR_AnswerList cur_node;
+ MR_AnswerBlock answer_block;
+
+ record = (MR_MemoNonRecordPtr) MR_r1;
+ cur_node0 = record->MR_mn_answer_list;
+
+ #ifdef MR_TABLE_DEBUG
+ if (MR_tabledebug) {
+ printf("picking up all answers in %p -> %p\n",
+ record->MR_mn_back_ptr, record);
+ }
+ #endif
+
+ if (cur_node0 == NULL) {
+ MR_redo();
+ }
+
+ answer_block = cur_node0->MR_aln_answer_block;
+ cur_node = cur_node0->MR_aln_next_answer;
+
+ /* Consider not creating the stack frame if cur_node is NULL. */
+
+ MR_mkframe("pred table_builtin.table_memo_return_all_answers_nondet/2-0",
+ 1, MR_LABEL(MEMO_NON_RET_ALL_NONDET_LABEL(Next)));
+ MR_framevar(1) = (MR_Word) cur_node;
+ MR_r1 = (MR_Word) answer_block;
+}
+ MR_succeed();
+
+MR_define_label(MEMO_NON_RET_ALL_NONDET_LABEL(Next));
+{
+ MR_AnswerList cur_node0;
+ MR_AnswerList cur_node;
+ MR_AnswerBlock answer_block;
+
+ cur_node0 = (MR_AnswerList) MR_framevar(1);
+ if (cur_node0 == NULL) {
+ MR_fail();
+ }
+
+ answer_block = cur_node0->MR_aln_answer_block;
+ cur_node = cur_node0->MR_aln_next_answer;
+ MR_framevar(1) = (MR_Word) cur_node;
+ MR_r1 = (MR_Word) answer_block;
+}
+ MR_succeed();
+
+MR_define_entry(MR_MEMO_NON_RET_ALL_MULTI_ENTRY);
+{
+ MR_MemoNonRecordPtr record;
+ MR_AnswerList cur_node0;
+ MR_AnswerList cur_node;
+ MR_AnswerBlock answer_block;
+
+ record = (MR_MemoNonRecordPtr) MR_r1;
+ cur_node0 = record->MR_mn_answer_list;
+
+ #ifdef MR_TABLE_DEBUG
+ if (MR_tabledebug) {
+ printf("picking up all answers in %p -> %p\n",
+ record->MR_mn_back_ptr, record);
+ }
+ #endif
+
+ if (cur_node0 == NULL) {
+ MR_fatal_error("table_memo_return_all_answers_multi: no answers");
+ }
+
+ answer_block = cur_node0->MR_aln_answer_block;
+ cur_node = cur_node0->MR_aln_next_answer;
+
+ /* Consider not creating the stack frame if cur_node is NULL. */
+
+ MR_mkframe("pred table_builtin.table_memo_return_all_answers_multi/2-0",
+ 1, MR_LABEL(MEMO_NON_RET_ALL_MULTI_LABEL(Next)));
+ MR_framevar(1) = (MR_Word) cur_node;
+ MR_r1 = (MR_Word) answer_block;
+}
+ MR_succeed();
+
+MR_define_label(MEMO_NON_RET_ALL_MULTI_LABEL(Next));
+{
+ MR_AnswerList cur_node0;
+ MR_AnswerList cur_node;
+ MR_AnswerBlock answer_block;
+
+ cur_node0 = (MR_AnswerList) MR_framevar(1);
+ if (cur_node0 == NULL) {
+ MR_fail();
+ }
+
+ answer_block = cur_node0->MR_aln_answer_block;
+ cur_node = cur_node0->MR_aln_next_answer;
+ MR_framevar(1) = (MR_Word) cur_node;
+ MR_r1 = (MR_Word) answer_block;
+}
+ MR_succeed();
+
+MR_END_MODULE
+
+#endif /* MR_HIGHLEVEL_CODE */
+
+/* Ensure that the initialization code for the above modules gets to run. */
+/*
+INIT mercury_sys_init_table_modules
+*/
+
+MR_MODULE_STATIC_OR_EXTERN MR_ModuleFunc table_memo_non_module;
+
+/* forward declarations to suppress gcc -Wmissing-decl warnings */
+void mercury_sys_init_table_modules_init(void);
+void mercury_sys_init_table_modules_init_type_tables(void);
+#ifdef MR_DEEP_PROFILING
+void mercury_sys_init_table_modules_write_out_proc_statics(FILE *fp);
+#endif
+
+void mercury_sys_init_table_modules_init(void)
+{
+#ifndef MR_HIGHLEVEL_CODE
+ table_memo_non_module();
+#endif /* MR_HIGHLEVEL_CODE */
+}
+
+void mercury_sys_init_table_modules_init_type_tables(void)
+{
+ /* no types to register */
+}
+
+#ifdef MR_DEEP_PROFILING
+void mercury_sys_init_table_modules_write_out_proc_statics(FILE *fp)
+{
+ /* no proc_statics to write out */
+ /* XXX we need to fix the deep profiling */
+ /* of model_non memo tabled predicates */
+}
+#endif
/*---------------------------------------------------------------------------*/
Index: runtime/mercury_tabling.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling.h,v
retrieving revision 1.33
diff -u -b -r1.33 mercury_tabling.h
--- runtime/mercury_tabling.h 31 May 2004 04:13:06 -0000 1.33
+++ runtime/mercury_tabling.h 18 Jul 2004 05:24:36 -0000
@@ -117,9 +117,6 @@
** MR_type_table field.
*/
-typedef MR_Word *MR_AnswerBlock;
-typedef MR_Subgoal *MR_SubgoalPtr;
-
/* these macros are used to interpret the MR_loop_status field */
#define MR_LOOP_INACTIVE 0
#define MR_LOOP_ACTIVE 1
@@ -132,11 +129,23 @@
#define MR_MEMO_BLOCK 4
typedef enum {
+ MR_MEMO_NON_INACTIVE,
+ MR_MEMO_NON_ACTIVE,
+ MR_MEMO_NON_INCOMPLETE,
+ MR_MEMO_NON_COMPLETE
+} MR_MemoNonStatus;
+
+typedef enum {
MR_SUBGOAL_INACTIVE,
MR_SUBGOAL_ACTIVE,
MR_SUBGOAL_COMPLETE
} MR_SubgoalStatus;
+struct MR_AnswerListNode_Struct {
+ MR_Word *MR_aln_answer_block;
+ MR_AnswerList MR_aln_next_answer;
+};
+
union MR_TableNode_Union {
MR_Integer MR_integer;
MR_HashTable *MR_hash_table;
@@ -145,10 +154,21 @@
MR_Unsigned MR_loop_status;
MR_Unsigned MR_memo_status;
MR_Subgoal *MR_subgoal;
+ MR_MemoNonRecordPtr MR_memo_non_record;
+ MR_Consumer *MR_consumer;
MR_AnswerBlock MR_answerblock;
MR_Dlist *MR_type_table;
};
+struct MR_MemoNonRecord_Struct {
+ MR_TrieNode MR_mn_back_ptr;
+ MR_MemoNonStatus MR_mn_status;
+ int MR_mn_num_answers;
+ MR_TableNode MR_mn_answer_table;
+ MR_AnswerList MR_mn_answer_list;
+ MR_AnswerList *MR_mn_answer_list_tail;
+};
+
/*---------------------------------------------------------------------------*/
/*
@@ -247,8 +267,31 @@
extern void MR_table_report_statistics(FILE *fp);
/*
+** These functions return printable representations of the MR_loop_status
+** MR_memo_status and MR_mn_status fields.
+*/
+
+extern const char *MR_loopcheck_status(MR_Unsigned);
+extern const char *MR_memo_status(MR_Unsigned);
+extern const char *MR_memo_non_status(MR_MemoNonStatus);
+
+/*
+** These functions print the tips of the call tables for loopcheck and memo
+** tabled predicates to fp.
+*/
+
+extern void MR_print_loopcheck_tip(FILE *fp,
+ const MR_Proc_Layout *proc, MR_TrieNode table);
+extern void MR_print_memo_tip(FILE *fp,
+ const MR_Proc_Layout *proc, MR_TrieNode table);
+extern void MR_print_memo_non_record(FILE *fp,
+ const MR_Proc_Layout *proc,
+ MR_MemoNonRecordPtr record);
+
+/*
** Prints the given answer_block of the given procedure to fp.
*/
+
extern void MR_print_answerblock(FILE *fp,
const MR_Proc_Layout *proc,
MR_Word *answer_block);
@@ -350,6 +393,31 @@
(MR_CHECK_EXPR_TYPE((source), type *), \
MR_memcpy((char *) (dest), (char *) (source), \
sizeof(type) * (num))))
+
+/*---------------------------------------------------------------------------*/
+
+#ifdef MR_HIGHLEVEL_CODE
+
+ extern void MR_CALL
+ mercury__table_builtin__table_memo_return_all_answers_multi_2_p_0(
+ MR_Box record, MR_Box *answer_block_ptr,
+ MR_Cont cont, void *cont_env_ptr);
+ extern void MR_CALL
+ mercury__table_builtin__table_memo_return_all_answers_nondet_2_p_0(
+ MR_Box record, MR_Box *answer_block_ptr,
+ MR_Cont cont, void *cont_env_ptr);
+
+#else /* ! MR_HIGHLEVEL_CODE */
+ #define MR_MEMO_NON_RET_ALL_NONDET_ENTRY \
+ MR_proc_entry_user_name(table_builtin, \
+ table_memo_return_all_answers_nondet, 2, 0)
+ #define MR_MEMO_NON_RET_ALL_MULTI_ENTRY \
+ MR_proc_entry_user_name(table_builtin, \
+ table_memo_return_all_answers_multi, 2, 0)
+
+ MR_declare_entry(MR_MEMO_NON_RET_ALL_NONDET_ENTRY);
+ MR_declare_entry(MR_MEMO_NON_RET_ALL_MULTI_ENTRY);
+#endif /* MR_HIGHLEVEL_CODE */
/*---------------------------------------------------------------------------*/
Index: runtime/mercury_tabling_macros.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling_macros.h,v
retrieving revision 1.10
diff -u -b -r1.10 mercury_tabling_macros.h
--- runtime/mercury_tabling_macros.h 7 Jun 2004 09:07:21 -0000 1.10
+++ runtime/mercury_tabling_macros.h 17 Jul 2004 13:09:02 -0000
@@ -371,6 +371,15 @@
(int) (num_slots)); \
} while(0)
+#define MR_TABLE_CREATE_NODE_ANSWER_BLOCK(block_ptr, num_slots) \
+ do { \
+ *block_ptr = MR_TABLE_NEW_ARRAY(MR_Word, (num_slots)); \
+ if (MR_tabledebug) \
+ printf("allocated node block %p -> %p, %d words\n",\
+ block_ptr, *block_ptr, \
+ (int) (num_slots)); \
+ } while(0)
+
#define MR_TABLE_GET_ANSWER(ab, offset) \
(( MR_tabledebug ? \
printf("using answer block: %p, slot %d\n", \
@@ -396,6 +405,11 @@
do { \
(table)->MR_answerblock = MR_TABLE_NEW_ARRAY(MR_Word, \
(num_slots)); \
+ } while(0)
+
+#define MR_TABLE_CREATE_NODE_ANSWER_BLOCK(block_ptr, num_slots) \
+ do { \
+ *block_ptr = MR_TABLE_NEW_ARRAY(MR_Word, (num_slots)); \
} while(0)
#define MR_TABLE_GET_ANSWER(ab, offset) \
Index: runtime/mercury_tabling_preds.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling_preds.h,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_tabling_preds.h
--- runtime/mercury_tabling_preds.h 7 Jun 2004 09:07:21 -0000 1.2
+++ runtime/mercury_tabling_preds.h 19 Jul 2004 04:09:01 -0000
@@ -173,11 +173,18 @@
#define MR_table_loop_mark_as_inactive_msg(T) \
do { \
if (MR_tabledebug) { \
- printf("marking %p as uninitialized\n", T); \
+ printf("marking %p as inactive\n", T); \
+ } \
+ } while (0)
+ #define MR_table_loop_mark_as_active_msg(T) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("marking %p as active\n", T); \
} \
} while (0)
#else
#define MR_table_loop_mark_as_inactive_msg(T) ((void) 0)
+ #define MR_table_loop_mark_as_active_msg(T) ((void) 0)
#endif
#define MR_table_loop_mark_as_inactive(T) \
@@ -186,6 +193,18 @@
T->MR_loop_status = MR_LOOP_INACTIVE; \
} while (0)
+#define MR_table_loop_mark_as_inactive_and_fail(T) \
+ do { \
+ MR_table_loop_mark_as_inactive_msg(T); \
+ T->MR_loop_status = MR_LOOP_INACTIVE; \
+ } while (0)
+
+#define MR_table_loop_mark_as_active_and_fail(T) \
+ do { \
+ MR_table_loop_mark_as_active_msg(T); \
+ T->MR_loop_status = MR_LOOP_ACTIVE; \
+ } while (0)
+
/***********************************************************************/
#ifdef MR_TABLE_DEBUG
@@ -197,8 +216,24 @@
(long) T->MR_memo_status); \
} \
} while(0)
+ #define MR_table_memo_non_setup_msg(T) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("setting up of memo non table for %p\n", T); \
+ } \
+ } while(0)
+ #define MR_table_memo_non_status_msg(R) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("status of memo non table %p -> %p: %s\n", \
+ R->MR_mn_back_ptr, R, \
+ MR_memo_non_status(R->MR_mn_status)); \
+ } \
+ } while(0)
#else
#define MR_table_memo_setup_msg(T) ((void) 0)
+ #define MR_table_memo_non_setup_msg(T) ((void) 0)
+ #define MR_table_memo_non_status_msg(R) ((void) 0)
#endif
#define MR_table_memo_setup(T, Status) \
@@ -221,10 +256,35 @@
#define MR_table_memo_semi_setup(T, Status) \
MR_table_memo_setup(T, Status)
+#define MR_table_memo_non_setup(T, Record, Status) \
+ do { \
+ MR_save_transient_registers(); \
+ if (T->MR_memo_non_record == NULL) { \
+ MR_table_memo_non_setup_msg(T); \
+ Status = MR_MEMO_NON_INACTIVE; \
+ Record = MR_TABLE_NEW(MR_MemoNonRecord); \
+ Record->MR_mn_back_ptr = T; \
+ Record->MR_mn_status = MR_MEMO_NON_ACTIVE; \
+ Record->MR_mn_num_answers = 0; \
+ Record->MR_mn_answer_table.MR_integer = 0; \
+ Record->MR_mn_answer_list = NULL; \
+ Record->MR_mn_answer_list_tail = &Record->MR_mn_answer_list;\
+ T->MR_memo_non_record = Record; \
+ } else { \
+ Record = T->MR_memo_non_record; \
+ Status = Record->MR_mn_status; \
+ } \
+ MR_table_memo_non_status_msg(Record); \
+ MR_restore_transient_registers(); \
+ Status = MR_CONVERT_C_ENUM_CONSTANT(Status); \
+ } while(0)
+
#define MR_table_memo_det_setup_shortcut(T0, T, Status) ((void) 0)
#define MR_table_memo_semi_setup_shortcut(T0, T, Status) ((void) 0)
+#define MR_table_memo_non_setup_shortcut(T0, T, R, Status) ((void) 0)
+
/***********************************************************************/
#ifdef MR_TABLE_DEBUG
@@ -265,6 +325,51 @@
/***********************************************************************/
+#ifdef MR_TABLE_DEBUG
+ #define MR_table_memo_mark_as_complete_msg(R) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("marking %p as complete\n", R); \
+ } \
+ } while (0)
+ #define MR_table_memo_mark_as_incomplete_msg(R) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("marking %p as incomplete\n", R); \
+ } \
+ } while (0)
+ #define MR_table_memo_mark_as_active_msg(R) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("marking %p as active\n", R); \
+ } \
+ } while (0)
+#else
+ #define MR_table_memo_mark_as_complete_msg(R) ((void) 0)
+ #define MR_table_memo_mark_as_incomplete_msg(R) ((void) 0)
+ #define MR_table_memo_mark_as_active_msg(R) ((void) 0)
+#endif
+
+#define MR_table_memo_mark_as_incomplete(R) \
+ do { \
+ MR_table_memo_mark_as_incomplete_msg(R); \
+ R->MR_mn_status = MR_MEMO_NON_INCOMPLETE; \
+ } while (0)
+
+#define MR_table_memo_mark_as_active_and_fail(R) \
+ do { \
+ MR_table_memo_mark_as_active_msg(R); \
+ R->MR_mn_status = MR_MEMO_NON_ACTIVE; \
+ } while (0)
+
+#define MR_table_memo_mark_as_complete_and_fail(R) \
+ do { \
+ MR_table_memo_mark_as_complete_msg(R); \
+ R->MR_mn_status = MR_MEMO_NON_COMPLETE; \
+ } while (0)
+
+/***********************************************************************/
+
#define MR_table_memo_create_answer_block(T, Size, AnswerBlock) \
do { \
MR_TABLE_CREATE_ANSWER_BLOCK(T, Size); \
@@ -306,6 +411,106 @@
/***********************************************************************/
+#ifdef MR_TABLE_DEBUG
+ #define MR_table_memo_non_get_answer_table_msg(Record) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("getting answer table %p -> %p\n", \
+ Record, \
+ &(Record->MR_mn_answer_table)); \
+ } \
+ } while(0)
+#else
+ #define MR_table_memo_non_get_answer_table_msg(Record) ((void) 0)
+#endif
+
+#define MR_table_memo_non_get_answer_table(Record, AnswerTable) \
+ do { \
+ MR_table_memo_non_get_answer_table_msg(Record); \
+ AnswerTable = &(Record->MR_mn_answer_table); \
+ } while(0)
+
+/***********************************************************************/
+
+#ifdef MR_TABLE_DEBUG
+ #define MR_table_memo_non_create_answer_block_msg(Record, answer_node)\
+ do { \
+ if (MR_tabledebug) { \
+ printf("new answer slot %d at %p(%p)\n", \
+ Record->MR_mn_num_answers, answer_node, \
+ &answer_node->MR_aln_answer_block); \
+ printf("\tstoring into %p\n", \
+ Record->MR_mn_answer_list_tail); \
+ } \
+ } while(0)
+#else
+ #define MR_table_memo_non_create_answer_block_msg(Record, answer_node)\
+ ((void) 0)
+#endif
+
+#define MR_table_memo_non_create_answer_block(Record, Size, AnswerBlock)\
+ do { \
+ MR_AnswerListNode *answer_node; \
+ MR_Word **Slot; \
+ \
+ Record->MR_mn_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 \
+ ** to be executed after we return, which is why we return \
+ ** its address. \
+ */ \
+ \
+ answer_node = MR_TABLE_NEW(MR_AnswerListNode); \
+ answer_node->MR_aln_answer_block = NULL; \
+ answer_node->MR_aln_next_answer = NULL; \
+ \
+ MR_table_memo_non_create_answer_block_msg(Record, answer_node); \
+ *(Record->MR_mn_answer_list_tail) = answer_node; \
+ Record->MR_mn_answer_list_tail = \
+ &(answer_node->MR_aln_next_answer); \
+ Slot = &(answer_node->MR_aln_answer_block); \
+ MR_TABLE_CREATE_NODE_ANSWER_BLOCK(Slot, Size); \
+ AnswerBlock = *Slot; \
+ } while(0)
+
+#define MR_table_memo_non_create_answer_block_shortcut(Record) \
+ ((void) 0)
+
+/***********************************************************************/
+
+#define MR_table_memo_non_return_all_shortcut(Record) \
+ ((void) 0)
+
+/***********************************************************************/
+
+#ifdef MR_TABLE_DEBUG
+ #define MR_table_memo_non_answer_is_not_duplicate_msg(T) \
+ do { \
+ if (MR_tabledebug) { \
+ printf("checking if %p is a duplicate answer: %ld\n", \
+ T, (long) T->MR_integer); \
+ } \
+ } while(0)
+#else
+ #define MR_table_memo_non_answer_is_not_duplicate_msg(T) ((void) 0)
+#endif
+
+#define MR_table_memo_non_answer_is_not_duplicate(T, succ) \
+ do { \
+ MR_bool is_new_answer; \
+ MR_table_memo_non_answer_is_not_duplicate_msg(T); \
+ is_new_answer = (T->MR_integer == 0); \
+ T->MR_integer = 1; /* any nonzero value will do */ \
+ succ = is_new_answer; \
+ } while(0)
+
+#define MR_table_memo_non_answer_is_not_duplicate_shortcut(R, succ) \
+ ((void) 0)
+
+/***********************************************************************/
+
#ifdef MR_DEBUG_RETRY
#define MR_table_io_in_range_check_msg \
if (MR_io_tabling_debug) { \
@@ -397,7 +602,7 @@
/***********************************************************************/
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
/***********************************************************************/
@@ -484,16 +689,6 @@
/***********************************************************************/
-#ifdef MR_MINIMAL_MODEL_DEBUG
- #define MR_table_mm_create_answer_block_set(Subgoal, answer_node) \
- do { \
- answer_node->MR_aln_answer_num = Subgoal->MR_sg_num_ans; \
- } while(0)
-#else
- #define MR_table_mm_create_answer_block_set(Subgoal, answer_node) \
- ((void) 0)
-#endif
-
#ifdef MR_TABLE_DEBUG
#define MR_table_mm_create_answer_block_msg(Subgoal, answer_node) \
do { \
@@ -501,7 +696,7 @@
printf("%s: new answer slot %d at %p(%p)\n", \
MR_subgoal_addr_name(Subgoal), \
Subgoal->MR_sg_num_ans, answer_node, \
- &answer_node->MR_aln_answer_data); \
+ &answer_node->MR_aln_answer_block); \
printf("\tstoring into %p\n", \
Subgoal->MR_sg_answer_list_tail); \
} \
@@ -514,7 +709,7 @@
#define MR_table_mm_create_answer_block(Subgoal, Size, AnswerBlock) \
do { \
MR_AnswerListNode *answer_node; \
- MR_TrieNode Slot; \
+ MR_Word **Slot; \
\
Subgoal->MR_sg_num_ans++; \
\
@@ -526,17 +721,16 @@
*/ \
\
answer_node = MR_TABLE_NEW(MR_AnswerListNode); \
- answer_node->MR_aln_answer_data.MR_integer = 0; \
+ answer_node->MR_aln_answer_block = NULL; \
answer_node->MR_aln_next_answer = NULL; \
\
- MR_table_mm_create_answer_block_set(Subgoal, answer_node); \
MR_table_mm_create_answer_block_msg(Subgoal, answer_node); \
*(Subgoal->MR_sg_answer_list_tail) = answer_node; \
Subgoal->MR_sg_answer_list_tail = \
&(answer_node->MR_aln_next_answer); \
- Slot = &(answer_node->MR_aln_answer_data); \
- MR_TABLE_CREATE_ANSWER_BLOCK(Slot, Size); \
- AnswerBlock = Slot->MR_answerblock; \
+ Slot = &(answer_node->MR_aln_answer_block); \
+ MR_TABLE_CREATE_NODE_ANSWER_BLOCK(Slot, Size); \
+ AnswerBlock = *Slot; \
} while(0)
/***********************************************************************/
@@ -545,33 +739,108 @@
/***********************************************************************/
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+#define MR_MMSC_ERROR \
+ "stack copy minimal model code entered when not enabled"
#define MR_table_mm_setup(T, Subgoal, Status) \
do { \
- MR_fatal_error("minimal model code entered when not enabled"); \
+ MR_fatal_error(MR_MMSC_ERROR); \
} while(0)
#define MR_table_mm_setup_shortcut(Subgoal, Status) \
do { \
- MR_fatal_error("minimal model code entered when not enabled"); \
+ MR_fatal_error(MR_MMSC_ERROR); \
} while(0)
#define MR_table_mm_return_all_shortcut(AnswerBlock) \
do { \
- MR_fatal_error("minimal model code entered when not enabled"); \
+ MR_fatal_error(MR_MMSC_ERROR); \
} while(0)
#define MR_table_mm_get_answer_table(Subgoal, AnswerTable) \
do { \
- MR_fatal_error("minimal model code entered when not enabled"); \
+ MR_fatal_error(MR_MMSC_ERROR); \
} while(0)
#define MR_table_mm_create_answer_block(Subgoal, Size, AnswerBlock) \
do { \
- MR_fatal_error("minimal model code entered when not enabled"); \
+ MR_fatal_error(MR_MMSC_ERROR); \
} while(0)
#define MR_table_mm_fill_answer_block_shortcut(Subgoal) \
do { \
- MR_fatal_error("minimal model code entered when not enabled"); \
+ MR_fatal_error(MR_MMSC_ERROR); \
+ } while(0)
+
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+/***********************************************************************/
+
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+
+#define MR_MMOS_ERROR \
+ "own stack minimal model code entered when not enabled"
+
+#define MR_table_mmos_save_inputs_shortcut(num_inputs) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_setup_consumer(t, num_inputs, gen_pred, name, consumer) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_consume_next_answer_nondet(consumer, answerblock, succ) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_get_answer_table(generator, trienode) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_create_answer_block(generator, blocksize, answerblock) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_return_answer(generator, answerblock) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_completion(generator) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+
+#else /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
+#define MR_MMOS_ERROR \
+ "own stack minimal model code entered when not enabled"
+
+#define MR_table_mmos_save_inputs_shortcut(num_inputs) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_setup_consumer(t, num_inputs, gen_pred, name, consumer) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_consume_next_answer_nondet(consumer, answerblock, succ) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_get_answer_table(generator, trienode) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_create_answer_block(generator, blocksize, answerblock) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_return_answer(generator, answerblock) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
+ } while(0)
+#define MR_table_mmos_completion(generator) \
+ do { \
+ MR_fatal_error(MR_MMOS_ERROR); \
} while(0)
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
/***********************************************************************/
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_types.h,v
retrieving revision 1.38
diff -u -b -r1.38 mercury_types.h
--- runtime/mercury_types.h 7 Jul 2004 07:11:19 -0000 1.38
+++ runtime/mercury_types.h 15 Jul 2004 13:59:56 -0000
@@ -231,11 +231,14 @@
typedef MR_TrieNode *MR_TrieNodePtr;
typedef struct MR_HashTable_Struct MR_HashTable;
+typedef struct MR_MemoNonRecord_Struct MR_MemoNonRecord;
+typedef struct MR_MemoNonRecord_Struct *MR_MemoNonRecordPtr;
+typedef struct MR_AnswerListNode_Struct MR_AnswerListNode;
typedef struct MR_Subgoal_Struct MR_Subgoal;
typedef struct MR_SubgoalListNode_Struct MR_SubgoalListNode;
-typedef struct MR_AnswerListNode_Struct MR_AnswerListNode;
typedef struct MR_Consumer_Struct MR_Consumer;
typedef struct MR_ConsumerListNode_Struct MR_ConsumerListNode;
+typedef struct MR_Generator_Struct MR_Generator;
typedef MR_SubgoalListNode *MR_SubgoalList;
typedef MR_AnswerListNode *MR_AnswerList;
@@ -250,5 +253,12 @@
typedef struct MR_ConsumerDebug_Struct MR_ConsumerDebug;
typedef struct MR_SubgoalDebug_Struct MR_SubgoalDebug;
+typedef struct MR_ConsDebug_Struct MR_ConsDebug;
+typedef struct MR_GenDebug_Struct MR_GenDebug;
+
+typedef MR_Word *MR_AnswerBlock;
+typedef MR_Subgoal *MR_SubgoalPtr;
+typedef MR_Consumer *MR_ConsumerPtr;
+typedef MR_Generator *MR_GeneratorPtr;
#endif /* not MERCURY_TYPES_H */
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.134
diff -u -b -r1.134 mercury_wrapper.c
--- runtime/mercury_wrapper.c 7 Jul 2004 07:11:19 -0000 1.134
+++ runtime/mercury_wrapper.c 19 Jul 2004 02:43:58 -0000
@@ -88,6 +88,8 @@
size_t MR_genstack_size = 32;
size_t MR_cutstack_size = 32;
size_t MR_pnegstack_size = 32;
+size_t MR_gen_detstack_size = 64;
+size_t MR_gen_nonstack_size = 64;
/*
** size of the redzones at the end of data areas, in kilobytes
@@ -121,6 +123,8 @@
size_t MR_genstack_zone_size = 16;
size_t MR_cutstack_zone_size = 16;
size_t MR_pnegstack_zone_size = 16;
+size_t MR_gen_detstack_zone_size = 16;
+size_t MR_gen_nonstack_zone_size = 16;
/*
** MR_heap_margin_size is used for accurate GC with the MLDS->C back-end.
@@ -848,7 +852,7 @@
static void
process_environment_options(void)
{
- char* env_options;
+ char *env_options;
env_options = getenv("MERCURY_OPTIONS");
if (env_options == NULL) {
@@ -911,6 +915,10 @@
MR_TRAIL_REDZONE_SIZE,
MR_HEAP_MARGIN_SIZE,
MR_HEAP_EXPANSION_FACTOR,
+ MR_GEN_DETSTACK_SIZE,
+ MR_GEN_NONSTACK_SIZE,
+ MR_GEN_DETSTACK_REDZONE_SIZE,
+ MR_GEN_NONSTACK_REDZONE_SIZE,
MR_MDB_TTY,
MR_MDB_IN,
MR_MDB_OUT,
@@ -936,6 +944,10 @@
{ "trail-redzone-size", 1, 0, MR_TRAIL_REDZONE_SIZE },
{ "heap-margin-size", 1, 0, MR_HEAP_MARGIN_SIZE },
{ "heap-expansion-factor", 1, 0, MR_HEAP_EXPANSION_FACTOR },
+ { "gen-detstack-size", 1, 0, MR_GEN_DETSTACK_SIZE },
+ { "gen-nonstack-size", 1, 0, MR_GEN_NONSTACK_SIZE },
+ { "gen-detstack-zone-size", 1, 0, MR_GEN_DETSTACK_REDZONE_SIZE },
+ { "gen-nonstack-zone-size", 1, 0, MR_GEN_NONSTACK_REDZONE_SIZE },
{ "mdb-tty", 1, 0, MR_MDB_TTY },
{ "mdb-in", 1, 0, MR_MDB_IN },
{ "mdb-out", 1, 0, MR_MDB_OUT },
@@ -1044,6 +1056,34 @@
{
usage();
}
+ break;
+
+ case MR_GEN_DETSTACK_SIZE:
+ if (sscanf(MR_optarg, "%lu", &size) != 1)
+ usage();
+
+ MR_gen_detstack_size = size;
+ break;
+
+ case MR_GEN_NONSTACK_SIZE:
+ if (sscanf(MR_optarg, "%lu", &size) != 1)
+ usage();
+
+ MR_gen_nonstack_size = size;
+ break;
+
+ case MR_GEN_DETSTACK_REDZONE_SIZE:
+ if (sscanf(MR_optarg, "%lu", &size) != 1)
+ usage();
+
+ MR_gen_detstack_zone_size = size;
+ break;
+
+ case MR_GEN_NONSTACK_REDZONE_SIZE:
+ if (sscanf(MR_optarg, "%lu", &size) != 1)
+ usage();
+
+ MR_gen_nonstack_zone_size = size;
break;
case 'i':
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.62
diff -u -b -r1.62 mercury_wrapper.h
--- runtime/mercury_wrapper.h 22 Oct 2003 05:56:08 -0000 1.62
+++ runtime/mercury_wrapper.h 9 Apr 2004 18:37:09 -0000
@@ -197,6 +197,8 @@
extern size_t MR_genstack_size;
extern size_t MR_cutstack_size;
extern size_t MR_pnegstack_size;
+extern size_t MR_gen_detstack_size;
+extern size_t MR_gen_nonstack_size;
/* sizes of the red zones */
extern size_t MR_heap_zone_size;
@@ -209,6 +211,8 @@
extern size_t MR_genstack_zone_size;
extern size_t MR_cutstack_zone_size;
extern size_t MR_pnegstack_zone_size;
+extern size_t MR_gen_detstack_zone_size;
+extern size_t MR_gen_nonstack_zone_size;
/* heap margin for MLDS->C accurate GC (documented in mercury_wrapper.c) */
extern size_t MR_heap_margin_size;
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
Index: scripts/canonical_grade.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/canonical_grade.sh-subr,v
retrieving revision 1.10
diff -u -b -r1.10 canonical_grade.sh-subr
--- scripts/canonical_grade.sh-subr 31 May 2004 04:13:11 -0000 1.10
+++ scripts/canonical_grade.sh-subr 29 Jun 2004 14:00:10 -0000
@@ -115,9 +115,11 @@
false) ;;
esac
-case $use_minimal_model,$minimal_model_debug in
- true,false) GRADE="$GRADE.mm" ;;
- true,true) GRADE="$GRADE.dmm" ;;
+case $use_minimal_model_stack_copy,$use_minimal_model_own_stack,$minimal_model_debug in
+ true,false,false) GRADE="$GRADE.mmsc" ;;
+ true,false,true) GRADE="$GRADE.dmmsc" ;;
+ false,true,false) GRADE="$GRADE.mmos" ;;
+ false,true,true) GRADE="$GRADE.dmmos" ;;
*) ;;
esac
Index: scripts/final_grade_options.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/final_grade_options.sh-subr,v
retrieving revision 1.12
diff -u -b -r1.12 final_grade_options.sh-subr
--- scripts/final_grade_options.sh-subr 31 May 2004 04:13:11 -0000 1.12
+++ scripts/final_grade_options.sh-subr 24 Jun 2004 07:50:51 -0000
@@ -19,8 +19,20 @@
#
#---------------------------------------------------------------------------#
+use_minimal_model=false
+case $use_minimal_model_stack_copy in
+ true)
+ use_minimal_model=true
+ ;;
+esac
+case $use_minimal_model_own_stacks in
+ true)
+ use_minimal_model=true
+ ;;
+esac
+
#
-# .tr grade is not compatible with .mm
+# .tr grade is not compatible with .*mm*
# (see comment in runtime/mercury_tabling.c for rationale)
#
case $use_trail,$use_minimal_model in true,true)
@@ -29,7 +41,7 @@
esac
#
-# .debug grade implies --use-trail in the absence of .mm
+# .debug grade implies --use-trail in the absence of .*mm*
# (see comment in compiler/handle_options.m for rationale)
#
case $debug,$use_minimal_model in true,false)
Index: scripts/init_grade_options.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/init_grade_options.sh-subr,v
retrieving revision 1.23
diff -u -b -r1.23 init_grade_options.sh-subr
--- scripts/init_grade_options.sh-subr 31 May 2004 04:13:12 -0000 1.23
+++ scripts/init_grade_options.sh-subr 24 Jun 2004 07:51:09 -0000
@@ -40,7 +40,8 @@
--record-term-sizes-as-cells
--use-trail
--reserve-tag
- --use-minimal-model
+ --use-minimal-model-stack-copy
+ --use-minimal-model-own-stacks
--minimal-model-debug
--pic-reg
--no-stack-trace
@@ -71,7 +72,8 @@
record_term_sizes_as_cells=false
use_trail=false
reserve_tag=false
-use_minimal_model=false
+use_minimal_model_stack_copy=false
+use_minimal_model_own_stacks=false
minimal_model_debug=false
pic_reg=false
debug=false
Index: scripts/mgnuc.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/mgnuc.in,v
retrieving revision 1.104
diff -u -b -r1.104 mgnuc.in
--- scripts/mgnuc.in 7 Jul 2004 07:11:21 -0000 1.104
+++ scripts/mgnuc.in 7 Jul 2004 07:17:09 -0000
@@ -404,9 +404,20 @@
false) RESERVE_TAG_OPTS="" ;;
esac
+case $use_minimal_model_stack_copy,$use_minimal_model_own_stacks in
+ true,true) progname=`basename $0`
+ echo "$progname: can't enable both forms of minimal model tabling at once"
+ exit 1 ;;
+ true,false) MINIMAL_MODEL_OPTS="-DMR_USE_MINIMAL_MODEL_STACK_COPY"
+ ;;
+ false,true) MINIMAL_MODEL_OPTS="-DMR_USE_MINIMAL_MODEL_OWN_STACKS"
+ ;;
+ false,false) MINIMAL_MODEL_OPTS="" ;;
+esac
+
case $use_minimal_model,$minimal_model_debug in
- true,false) MINIMAL_MODEL_OPTS="-DMR_USE_MINIMAL_MODEL" ;;
- true,true) MINIMAL_MODEL_OPTS="-DMR_USE_MINIMAL_MODEL -DMR_MINIMAL_MODEL_DEBUG" ;;
+ true,false) ;; # MINIMAL_MODEL_OPTS is already set
+ true,true) MINIMAL_MODEL_OPTS="$MINIMAL_MODEL_OPTS -DMR_MINIMAL_MODEL_DEBUG" ;;
*) MINIMAL_MODEL_OPTS="" ;;
esac
Index: scripts/parse_grade_options.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/parse_grade_options.sh-subr,v
retrieving revision 1.29
diff -u -b -r1.29 parse_grade_options.sh-subr
--- scripts/parse_grade_options.sh-subr 31 May 2004 04:13:12 -0000 1.29
+++ scripts/parse_grade_options.sh-subr 29 Jun 2004 14:00:14 -0000
@@ -148,10 +148,15 @@
--no-reserve-tag)
reserve_tag=false ;;
- --use-minimal-model)
- use_minimal_model=true ;;
- --no-use-minimal-model)
- use_minimal_model=false ;;
+ --use-minimal-model-stack-copy)
+ use_minimal_model_stack_copy=true ;;
+ --no-use-minimal-model-stack-copy)
+ use_minimal_model_stack_copy=false ;;
+
+ --use-minimal-model-own-stacks)
+ use_minimal_model_own_stacks=true ;;
+ --no-use-minimal-model-own-stacks)
+ use_minimal_model_own_stacks=false ;;
--minimal-model-debug)
minimal_model_debug=true ;;
@@ -200,7 +205,8 @@
record_term_sizes_as_cells=false
use_trail=false
reserve_tag=false
- use_minimal_model=false
+ use_minimal_model_stack_copy=false
+ use_minimal_model_own_stacks=false
minimal_model_debug=false
pic_reg=false
debug=false
@@ -397,12 +403,32 @@
;;
mm)
- use_minimal_model=true
+ use_minimal_model_stack_copy=true
minimal_model_debug=false
;;
dmm)
- use_minimal_model=true
+ use_minimal_model_stack_copy=true
+ minimal_model_debug=true
+ ;;
+
+ mmsc)
+ use_minimal_model_stack_copy=true
+ minimal_model_debug=false
+ ;;
+
+ dmmsc)
+ use_minimal_model_stack_copy=true
+ minimal_model_debug=true
+ ;;
+
+ mmos)
+ use_minimal_model_own_stacks=true
+ minimal_model_debug=false
+ ;;
+
+ dmmos)
+ use_minimal_model_own_stacks=true
minimal_model_debug=true
;;
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/print_table.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/print_table.exp,v
retrieving revision 1.6
diff -u -b -r1.6 print_table.exp
--- tests/debugger/print_table.exp 7 Jun 2004 09:07:21 -0000 1.6
+++ tests/debugger/print_table.exp 18 Jul 2004 03:21:50 -0000
@@ -348,6 +348,39 @@
call table does not contain xyz in argument position 3.
mdb> delete 1
1: E stop interface pred print_table.s/6-0 (det)
+mdb> b t
+ 1: + stop interface pred print_table.t/3-0 (nondet)
+mdb> c
+ E29: C15 2 CALL pred print_table.t/3-0 (nondet)
+mdb> table t
+memo table for pred print_table.t/3-0 (nondet):
+end of table (0 entries)
+mdb> s
+ E30: C15 2 DISJ pred print_table.t/3-0 (nondet)
+mdb> table t
+memo table for pred print_table.t/3-0 (nondet):
+<1, 2>: active
+end of table (1 entry)
+mdb> finish
+ E31: C15 2 EXIT pred print_table.t/3-0 (nondet)
+mdb> table t
+memo table for pred print_table.t/3-0 (nondet):
+<1, 2>: incomplete
+answer #1: <120>
+end of table (1 entry)
+mdb> delete 1
+ 1: E stop interface pred print_table.t/3-0 (nondet)
+mdb> b tdone
+ 1: + stop interface pred print_table.tdone/0-0 (det)
+mdb> c
+ E32: C16 2 CALL pred print_table.tdone/0-0 (det)
+mdb> table t
+memo table for pred print_table.t/3-0 (nondet):
+<1, 2>: complete
+answer #1: <120>
+answer #2: <210>
+<2, 2>: complete
+end of table (2 entries)
mdb> c -S -n
75
24
@@ -361,3 +394,5 @@
[3.5xyz2][3.5xyz2][3.5xyz2] 6.50000000000000
[3.5xyz2][3.5xyz2][3.5xyz2][3.5xyz2] 7.50000000000000
[9.2def2][9.2def2][9.2def2][9.2def2][9.2def2] 14.2000000000000
+[120, 210]
+[]
Index: tests/debugger/print_table.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/print_table.inp,v
retrieving revision 1.2
diff -u -b -r1.2 print_table.inp
--- tests/debugger/print_table.inp 7 Jun 2004 09:07:21 -0000 1.2
+++ tests/debugger/print_table.inp 18 Jul 2004 03:20:09 -0000
@@ -92,4 +92,15 @@
table s 9.2 2 def
table s 9.2 2 xyz
delete 1
+b t
+c
+table t
+s
+table t
+finish
+table t
+delete 1
+b tdone
+c
+table t
c -S -n
Index: tests/debugger/print_table.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/print_table.m,v
retrieving revision 1.2
diff -u -b -r1.2 print_table.m
--- tests/debugger/print_table.m 4 May 2004 08:07:23 -0000 1.2
+++ tests/debugger/print_table.m 18 Jul 2004 03:20:51 -0000
@@ -31,6 +31,9 @@
{ s(3.5, 2, "xyz", 3, SC, TC) },
{ s(3.5, 2, "xyz", 4, SD, TD) },
{ s(9.2, 2, "def", 5, SE, TE) },
+ { solutions(t(1, 2), T12) },
+ { solutions(t(2, 2), T22) },
+ { tdone },
io__write_int(P55),
io__nl,
io__write_int(P43),
@@ -64,6 +67,10 @@
io__write_string(SE),
io__write_string(" "),
io__write_float(TE),
+ io__nl,
+ io__write(T12),
+ io__nl,
+ io__write(T22),
io__nl.
:- pred p(int::in, int::in, int::out) is det.
@@ -112,3 +119,21 @@
S = from_char_list(list__condense(
list__duplicate(D, to_char_list(S0)))),
T = A + float(D).
+
+:- pred t(int::in, int::in, int::out) is nondet.
+:- pragma memo(t/3).
+
+t(A, B, C) :-
+ ( A = 1 ->
+ (
+ C = (A * 100) + (B * 10)
+ ;
+ C = (B * 100) + (A * 10)
+ )
+ ;
+ fail
+ ).
+
+:- pred tdone is det.
+
+tdone.
Index: tests/debugger/retry.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/retry.exp,v
retrieving revision 1.8
diff -u -b -r1.8 retry.exp
--- tests/debugger/retry.exp 7 Jun 2004 09:07:22 -0000 1.8
+++ tests/debugger/retry.exp 18 Jul 2004 05:32:32 -0000
@@ -126,5 +126,32 @@
E17: C10 2 CALL pred retry.fib/2-0 (det)
mdb> finish -n
E23: C10 2 EXIT pred retry.fib/2-0 (det)
-mdb> continue -n -S
+mdb> delete *
+ 0: E stop interface pred retry.fib/2-0 (det)
+mdb> break t
+ 0: + stop interface pred retry.t/3-0 (nondet)
+mdb> continue
987
+ E24: C14 2 CALL pred retry.t/3-0 (nondet)
+mdb> table t 1 2
+call table does not contain 1 in argument position 1.
+mdb> finish
+marker executed: t 1 2
+ E25: C14 2 EXIT pred retry.t/3-0 (nondet)
+mdb> table t 1 2
+<1, 2>: incomplete
+answer #1: <120>
+mdb> retry
+ E24: C14 2 CALL pred retry.t/3-0 (nondet)
+mdb> table t 1 2
+<1, 2>: inactive
+mdb> finish
+marker executed: t 1 2
+ E25: C14 2 EXIT pred retry.t/3-0 (nondet)
+mdb> table t 1 2
+<1, 2>: incomplete
+answer #1: <120>
+mdb> delete *
+ 0: E stop interface pred retry.t/3-0 (nondet)
+mdb> continue -n -S
+120 210
Index: tests/debugger/retry.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/retry.inp,v
retrieving revision 1.3
diff -u -b -r1.3 retry.inp
--- tests/debugger/retry.inp 7 Jun 2004 09:07:22 -0000 1.3
+++ tests/debugger/retry.inp 18 Jul 2004 03:27:59 -0000
@@ -49,4 +49,15 @@
next
retry 1
finish -n
+delete *
+break t
+continue
+table t 1 2
+finish
+table t 1 2
+retry
+table t 1 2
+finish
+table t 1 2
+delete *
continue -n -S
Index: tests/debugger/retry.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/retry.m,v
retrieving revision 1.3
diff -u -b -r1.3 retry.m
--- tests/debugger/retry.m 26 May 2003 09:00:52 -0000 1.3
+++ tests/debugger/retry.m 18 Jul 2004 05:31:29 -0000
@@ -36,7 +36,9 @@
outputs(Ds),
outputs(Es),
{ fib(15, F) },
- output(F).
+ output(F),
+ { solutions(t(1, 2), T12) },
+ outputs(T12).
%---------------------------------------------------------------------------%
@@ -119,6 +121,31 @@
fib(N - 2, F2),
F = F1 + F2
).
+
+:- pred t(int::in, int::in, int::out) is nondet.
+:- pragma memo(t/3).
+
+t(A, B, C) :-
+ marker("t", A, B, Zero),
+ ( A = 1 ->
+ (
+ C = Zero + (A * 100) + (B * 10)
+ ;
+ C = Zero + (B * 100) + (A * 10)
+ )
+ ;
+ fail
+ ).
+
+:- pred marker(string::in, int::in, int::in, int::out) is det.
+
+:- pragma foreign_proc("C",
+ marker(S::in, A::in, B::in, X::out),
+ [will_not_call_mercury, promise_pure],
+"
+ printf(""marker executed: %s %d %d\\n"", S, A, B);
+ X = 0;
+").
%---------------------------------------------------------------------------%
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/recompilation
cvs diff: Diffing tests/tabling
Index: tests/tabling/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/Mmakefile,v
retrieving revision 1.33
diff -u -b -r1.33 Mmakefile
--- tests/tabling/Mmakefile 21 Jun 2004 03:45:52 -0000 1.33
+++ tests/tabling/Mmakefile 18 Jul 2004 11:30:56 -0000
@@ -15,14 +15,20 @@
fib_list \
fib_string \
loopcheck_no_loop \
+ loopcheck_nondet_no_loop \
+ memo_non \
oota \
table_foreign_output \
unused_args
SIMPLE_LOOP_PROGS = \
- loopcheck
+ loopcheck \
+ loopcheck_nondet \
+ tc_loop \
+ tc_memo \
+ tc_memo2
-NONDET_NONLOOP_PROGS = \
+MINIMAL_NONLOOP_PROGS = \
combine \
completed_consumer_in_solutions \
consumer_in_commit \
@@ -47,15 +53,14 @@
tc_minimal \
tc_minimal2
-NONDET_LOOP_PROGS =
+MINIMAL_LOOP_PROGS =
# The following programs do not work:
# semidet_minimal.m
# tc_minimal_semidet.m
-# tc_loop
ALL_SIMPLE_PROGS = $(SIMPLE_NONLOOP_PROGS) $(SIMPLE_LOOP_PROGS)
-ALL_NONDET_PROGS = $(NONDET_NONLOOP_PROGS) $(NONDET_LOOP_PROGS)
+ALL_MINIMAL_PROGS = $(MINIMAL_NONLOOP_PROGS)
# Tabling does not yet work in .rt grades
ifneq "$(findstring .gc,$(GRADE))" ""
@@ -64,9 +69,9 @@
NONLOOP_PROGS=
else
ifneq "$(findstring mm,$(GRADE))" ""
- PROGS=$(ALL_SIMPLE_PROGS) $(ALL_NONDET_PROGS)
+ PROGS=$(ALL_SIMPLE_PROGS) $(ALL_MINIMAL_PROGS)
NONLOOP_PROGS=$(SIMPLE_NONLOOP_PROGS) \
- $(NONDET_NONLOOP_PROGS)
+ $(MINIMAL_NONLOOP_PROGS)
else
PROGS=$(ALL_SIMPLE_PROGS)
NONLOOP_PROGS=$(SIMPLE_NONLOOP_PROGS)
@@ -106,6 +111,30 @@
rm -f $@.tmp; \
fi
+tc_memo.out: tc_memo
+ if ./$< > $@.tmp 2>&1; then \
+ grep . $@.tmp; \
+ exit 1; \
+ else \
+ sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
+ -e 's/require.m:[0-9]*/require.m:NNNN/g' \
+ -e 's/std_util.m:[0-9]*/std_util.m:NNNN/g' \
+ < $@.tmp > $@; \
+ rm -f $@.tmp; \
+ fi
+
+tc_memo2.out: tc_memo2
+ if ./$< > $@.tmp 2>&1; then \
+ grep . $@.tmp; \
+ exit 1; \
+ else \
+ sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
+ -e 's/require.m:[0-9]*/require.m:NNNN/g' \
+ -e 's/std_util.m:[0-9]*/std_util.m:NNNN/g' \
+ < $@.tmp > $@; \
+ rm -f $@.tmp; \
+ fi
+
loopcheck.out: loopcheck
if ./$< > $@.tmp 2>&1; then \
grep . $@.tmp; \
@@ -117,6 +146,17 @@
rm -f $@.tmp; \
fi
+loopcheck_nondet.out: loopcheck_nondet
+ if ./$< > $@.tmp 2>&1; then \
+ grep . $@.tmp; \
+ exit 1; \
+ else \
+ sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
+ -e 's/require.m:[0-9]*/require.m:NNNN/g' \
+ < $@.tmp > $@; \
+ rm -f $@.tmp; \
+ fi
+
consumer_in_solutions.out: consumer_in_solutions
if ./$< > $@.tmp 2>&1; then \
grep . $@.tmp; \
@@ -133,9 +173,9 @@
echo_nonloop_progs:
@echo $(NONLOOP_PROGS)
-.PHONY: echo_nondet_nonloop_progs
-echo_nondet_nonloop_progs:
- @echo $(NONDET_NONLOOP_PROGS)
+.PHONY: echo_minimal_nonloop_progs
+echo_minimal_nonloop_progs:
+ @echo $(MINIMAL_NONLOOP_PROGS)
.PHONY: echo_simple_nonloop_progs
echo_simple_nonloop_progs:
Index: tests/tabling/loopcheck.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/loopcheck.exp,v
retrieving revision 1.3
diff -u -b -r1.3 loopcheck.exp
--- tests/tabling/loopcheck.exp 17 Jan 2003 05:57:15 -0000 1.3
+++ tests/tabling/loopcheck.exp 19 Jul 2004 02:57:51 -0000
@@ -1,3 +1,2 @@
Uncaught Mercury exception:
Software Error: detected infinite recursion in pred loopcheck.loop/1
-Stack dump not available in this grade.
Index: tests/tabling/loopcheck_nondet.exp
===================================================================
RCS file: tests/tabling/loopcheck_nondet.exp
diff -N tests/tabling/loopcheck_nondet.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/loopcheck_nondet.exp 19 Jul 2004 02:57:31 -0000
@@ -0,0 +1,2 @@
+Uncaught Mercury exception:
+Software Error: detected infinite recursion in pred loopcheck_nondet.loop/2
Index: tests/tabling/loopcheck_nondet.m
===================================================================
RCS file: tests/tabling/loopcheck_nondet.m
diff -N tests/tabling/loopcheck_nondet.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/loopcheck_nondet.m 15 Jul 2004 12:47:20 -0000
@@ -0,0 +1,33 @@
+:- module loopcheck_nondet.
+
+:- interface.
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module int, std_util.
+
+main(!IO) :-
+ solutions(loop(2), Y),
+ io__write(Y, !IO),
+ io__write_string("\n", !IO).
+
+:- pragma loop_check(loop/2).
+:- pred loop(int::in, int::out) is nondet.
+
+loop(X, Y) :-
+ ( X < 0 ->
+ fail
+ ; X > 100 ->
+ fail
+ ;
+ (
+ Y = X
+ ;
+ loop(X - 2, Y)
+ ;
+ loop(X * 2, Y)
+ )
+ ).
Index: tests/tabling/loopcheck_nondet_no_loop.exp
===================================================================
RCS file: tests/tabling/loopcheck_nondet_no_loop.exp
diff -N tests/tabling/loopcheck_nondet_no_loop.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/loopcheck_nondet_no_loop.exp 18 Jul 2004 09:02:37 -0000
@@ -0,0 +1,2 @@
+[1, 2, 3, 5, 6, 10, 11]
+[1, 2, 3, 5, 6, 10, 11, 20, 21]
Index: tests/tabling/loopcheck_nondet_no_loop.m
===================================================================
RCS file: tests/tabling/loopcheck_nondet_no_loop.m
diff -N tests/tabling/loopcheck_nondet_no_loop.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/loopcheck_nondet_no_loop.m 15 Jul 2004 13:04:40 -0000
@@ -0,0 +1,54 @@
+% Check that loopcheck isn't overzealous.
+
+:- module loopcheck_nondet_no_loop.
+
+:- interface.
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module int, std_util.
+
+main(!IO) :-
+ solutions(non(10), N),
+ io__write(N, !IO),
+ io__write_string("\n", !IO),
+ solutions(mul(20), M),
+ io__write(M, !IO),
+ io__write_string("\n", !IO).
+
+:- pred non(int::in, int::out) is nondet.
+:- pragma loop_check(non/2).
+
+non(A, B) :-
+ ( A < 0 ->
+ fail
+ ;
+ (
+ B = A
+ ;
+ B = A + 1
+ ;
+ A > 1,
+ non(A / 2, B)
+ )
+ ).
+
+:- pred mul(int::in, int::out) is nondet.
+:- pragma loop_check(mul/2).
+
+mul(A, B) :-
+ ( A < 0 ->
+ B = -1
+ ;
+ (
+ B = A
+ ;
+ B = A + 1
+ ;
+ A > 1,
+ mul(A / 2, B)
+ )
+ ).
Index: tests/tabling/memo_non.exp
===================================================================
RCS file: tests/tabling/memo_non.exp
diff -N tests/tabling/memo_non.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/memo_non.exp 18 Jul 2004 11:06:01 -0000
@@ -0,0 +1,12 @@
+marker executed: non 1 2
+[120, 210]
+[120, 210]
+marker executed: non 2 2
+[]
+[]
+marker executed: multi 1 2
+[120, 210]
+[120, 210]
+marker executed: multi 2 2
+[220]
+[220]
Index: tests/tabling/memo_non.m
===================================================================
RCS file: tests/tabling/memo_non.m
diff -N tests/tabling/memo_non.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/memo_non.m 17 Jul 2004 06:21:28 -0000
@@ -0,0 +1,75 @@
+% Test the memoization of model_non predicates.
+
+:- module memo_non.
+
+:- interface.
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int, std_util.
+
+main(!IO) :-
+ solutions(test_non(1, 2), NonSoln1),
+ io__write(NonSoln1, !IO),
+ io__nl(!IO),
+ solutions(test_non(1, 2), NonSoln2),
+ io__write(NonSoln2, !IO),
+ io__nl(!IO),
+ solutions(test_non(2, 2), NonSoln3),
+ io__write(NonSoln3, !IO),
+ io__nl(!IO),
+ solutions(test_non(2, 2), NonSoln4),
+ io__write(NonSoln4, !IO),
+ io__nl(!IO),
+
+ solutions(test_multi(1, 2), MultiSoln1),
+ io__write(MultiSoln1, !IO),
+ io__nl(!IO),
+ solutions(test_multi(1, 2), MultiSoln2),
+ io__write(MultiSoln2, !IO),
+ io__nl(!IO),
+ % This tests the duplicate detection machinery.
+ solutions(test_multi(2, 2), MultiSoln3),
+ io__write(MultiSoln3, !IO),
+ io__nl(!IO),
+ solutions(test_multi(2, 2), MultiSoln4),
+ io__write(MultiSoln4, !IO),
+ io__nl(!IO).
+
+:- pred test_non(int::in, int::in, int::out) is nondet.
+:- pragma memo(test_non/3).
+
+test_non(A, B, C) :-
+ marker("non", A, B, Zero),
+ ( A = 1 ->
+ (
+ C = Zero + (A * 100) + (B * 10)
+ ;
+ C = Zero + (B * 100) + (A * 10)
+ )
+ ;
+ fail
+ ).
+
+:- pred test_multi(int::in, int::in, int::out) is multi.
+:- pragma memo(test_multi/3).
+
+test_multi(A, B, C) :-
+ marker("multi", A, B, Zero),
+ (
+ C = Zero + (A * 100) + (B * 10)
+ ;
+ C = Zero + (B * 100) + (A * 10)
+ ).
+
+:- pred marker(string::in, int::in, int::in, int::out) is det.
+
+:- pragma foreign_proc("C",
+ marker(S::in, A::in, B::in, X::out),
+ [will_not_call_mercury, promise_pure],
+"
+ printf(""marker executed: %s %d %d\\n"", S, A, B);
+ X = 0;
+").
Index: tests/tabling/tc_loop.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/tc_loop.exp,v
retrieving revision 1.4
diff -u -b -r1.4 tc_loop.exp
--- tests/tabling/tc_loop.exp 17 Jan 2003 05:57:15 -0000 1.4
+++ tests/tabling/tc_loop.exp 19 Jul 2004 02:57:29 -0000
@@ -1,3 +1,2 @@
Uncaught Mercury exception:
Software Error: detected infinite recursion in pred tc_loop.tc/2
-Stack dump not available in this grade.
Index: tests/tabling/tc_memo.exp
===================================================================
RCS file: tests/tabling/tc_memo.exp
diff -N tests/tabling/tc_memo.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/tc_memo.exp 19 Jul 2004 02:57:27 -0000
@@ -0,0 +1,2 @@
+Uncaught Mercury exception:
+Software Error: detected infinite recursion in pred tc_memo.tc/2
Index: tests/tabling/tc_memo.m
===================================================================
RCS file: tests/tabling/tc_memo.m
diff -N tests/tabling/tc_memo.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/tc_memo.m 17 Jul 2004 06:10:02 -0000
@@ -0,0 +1,34 @@
+:- module tc_memo.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module std_util, list.
+
+main(!IO) :-
+ solutions(tc(1), Solns),
+ io__write(Solns, !IO),
+ io__write_string("\n", !IO).
+
+:- pred tc(int::in, int::out) is nondet.
+:- pragma memo(tc/2).
+
+tc(A, B) :-
+ edge(A, C),
+ (
+ B = C
+ ;
+ tc(C, B)
+ ).
+
+:- pred edge(int::in, int::out) is nondet.
+
+edge(1, 2).
+edge(1, 3).
+edge(2, 1).
+edge(3, 4).
Index: tests/tabling/tc_memo2.exp
===================================================================
RCS file: tests/tabling/tc_memo2.exp
diff -N tests/tabling/tc_memo2.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/tc_memo2.exp 19 Jul 2004 02:57:22 -0000
@@ -0,0 +1,2 @@
+Uncaught Mercury exception:
+Software Error: detected need for minimal model in pred tc_memo2.tc/2
Index: tests/tabling/tc_memo2.m
===================================================================
RCS file: tests/tabling/tc_memo2.m
diff -N tests/tabling/tc_memo2.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/tc_memo2.m 18 Jul 2004 10:18:44 -0000
@@ -0,0 +1,38 @@
+:- module tc_memo2.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module std_util, list.
+
+main(!IO) :-
+ (
+ tc(1, 4),
+ tc(3, 4)
+ ->
+ io__write_string("yes\n", !IO)
+ ;
+ io__write_string("no\n", !IO)
+ ).
+
+:- pred tc(int::in, int::out) is nondet.
+:- pragma memo(tc/2).
+
+tc(A, B) :-
+ edge(A, C),
+ (
+ B = C
+ ;
+ tc(C, B)
+ ).
+
+:- pred edge(int::in, int::out) is nondet.
+
+edge(1, 2).
+edge(1, 3).
+edge(3, 4).
Index: tests/tabling/test_tabling
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/test_tabling,v
retrieving revision 1.4
diff -u -b -r1.4 test_tabling
--- tests/tabling/test_tabling 21 Jun 2004 03:15:04 -0000 1.4
+++ tests/tabling/test_tabling 15 Jul 2004 12:51:15 -0000
@@ -39,7 +39,7 @@
then
testcases=`mmake echo_simple_nonloop_progs`
else
- testcases=`mmake echo_nondet_nonloop_progs echo_simple_nonloop_progs`
+ testcases=`mmake echo_minimal_nonloop_progs echo_simple_nonloop_progs`
fi
status=0
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
Index: tools/bootcheck
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/tools/bootcheck,v
retrieving revision 1.160
diff -u -b -r1.160 bootcheck
--- tools/bootcheck 11 Jun 2004 09:09:18 -0000 1.160
+++ tools/bootcheck 19 Jul 2004 02:54:51 -0000
@@ -1201,6 +1201,9 @@
MERCURY_DEBUGGER_INIT=$root/scripts/test_mdbrc
export MERCURY_DEBUGGER_INIT
+ MERCURY_SUPPRESS_STACK_TRACE=yes
+ export MERCURY_SUPPRESS_STACK_TRACE
+
if test "$test_grade" != ""
then
test_grade_opt="GRADE=$test_grade"
Index: tools/test_mercury
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/tools/test_mercury,v
retrieving revision 1.246
diff -u -b -r1.246 test_mercury
--- tools/test_mercury 11 Jun 2004 09:09:18 -0000 1.246
+++ tools/test_mercury 19 Jul 2004 02:55:18 -0000
@@ -906,6 +906,8 @@
for grade in $GRADES
do
echo "test_mercury starting tests for grade $grade at `date`" 1>&2
+ MERCURY_SUPPRESS_STACK_TRACE=yes
+ export MERCURY_SUPPRESS_STACK_TRACE
case $BRANCH in
0.10)
./runtests -f "$TEST_MCFLAGS" -c "$TEST_CFLAGS" -g "$grade" \
cvs diff: Diffing trace
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.71
diff -u -b -r1.71 mercury_trace.c
--- trace/mercury_trace.c 7 Jul 2004 07:11:22 -0000 1.71
+++ trace/mercury_trace.c 18 Jul 2004 05:14:45 -0000
@@ -93,7 +93,7 @@
MR_Word *base_curfr, MR_uint_least16_t var_num,
MR_bool *succeeded);
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
static MR_Retry_Result
MR_check_minimal_model_calls(MR_Event_Info *event_info,
int ancestor_level, MR_Word *target_maxfr,
@@ -148,7 +148,7 @@
depth = (MR_Unsigned) MR_call_depth_framevar(MR_curfr);
}
-#if defined(MR_USE_MINIMAL_MODEL) && defined(MR_MINIMAL_MODEL_DEBUG)
+#if defined(MR_USE_MINIMAL_MODEL_STACK_COPY) && defined(MR_MINIMAL_MODEL_DEBUG)
if ((MR_Trace_Port) layout->MR_sll_port == MR_PORT_CALL) {
MR_subgoal_debug_cur_proc = layout->MR_sll_entry;
}
@@ -513,7 +513,7 @@
MR_bool has_io_state;
MR_bool found_io_action_counter;
MR_Unsigned saved_io_action_counter;
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_Retry_Result result;
#endif
@@ -692,7 +692,7 @@
}
}
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
result = MR_check_minimal_model_calls(event_info, ancestor_level,
base_maxfr, problem);
@@ -717,7 +717,7 @@
goto report_problem;
}
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
/*
** At this point, we are now sure that we can carry out the retry
@@ -1136,7 +1136,7 @@
/*****************************************************************************/
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
/*
** MR_check_minimal_model_calls scans the nondet stack region about to be
@@ -1244,7 +1244,9 @@
return MR_RETRY_ERROR;
}
- if (MR_sle_eval_method(proc_layout) != MR_EVAL_METHOD_MINIMAL) {
+ if (MR_sle_eval_method(proc_layout)
+ != MR_EVAL_METHOD_MINIMAL_STACK_COPY)
+ {
continue;
}
@@ -1303,7 +1305,9 @@
label_layout = event_info->MR_event_sll;
proc_layout = label_layout->MR_sll_entry;
- if (MR_sle_eval_method(proc_layout) == MR_EVAL_METHOD_MINIMAL) {
+ if (MR_sle_eval_method(proc_layout)
+ == MR_EVAL_METHOD_MINIMAL_STACK_COPY)
+ {
return MR_RETRY_OK_FAIL_FIRST;
} else {
return MR_RETRY_OK_FINISH_FIRST;
@@ -1313,7 +1317,7 @@
}
}
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
/*****************************************************************************/
@@ -1349,6 +1353,7 @@
MR_Word *base_sp, MR_Word *base_curfr)
{
MR_TrieNode call_table;
+ MR_EvalMethod eval_method;
if (! MR_PROC_LAYOUT_HAS_EXEC_TRACE(level_layout)) {
/*
@@ -1360,7 +1365,8 @@
"in MR_maybe_record_call_table");
}
- switch (MR_sle_eval_method(level_layout)) {
+ eval_method = MR_sle_eval_method(level_layout);
+ switch (eval_method) {
case MR_EVAL_METHOD_NORMAL:
/* nothing to do */
@@ -1372,9 +1378,22 @@
call_table = (MR_TrieNode) MR_based_stackvar(base_sp,
level_layout->MR_sle_maybe_call_table);
} else {
+ if (eval_method == MR_EVAL_METHOD_MEMO) {
+ MR_MemoNonRecordPtr record;
+
+ record = (MR_MemoNonRecordPtr) MR_based_framevar(base_curfr,
+ level_layout->MR_sle_maybe_call_table);
+ call_table = record->MR_mn_back_ptr;
+
+#ifdef MR_DEBUG_RETRY
+ printf("reset: memo non record %p, call_table %p\n",
+ record, call_table);
+#endif
+ } else {
call_table = (MR_TrieNode) MR_based_framevar(base_curfr,
level_layout->MR_sle_maybe_call_table);
}
+ }
if (call_table != NULL) {
MR_GC_ensure_room_for_next(MR_call_table_ptr, MR_TrieNode,
@@ -1386,7 +1405,11 @@
return;
- case MR_EVAL_METHOD_MINIMAL:
+ case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
+ MR_fatal_error("retry with MR_EVAL_METHOD_MINIMAL_OWN_STACKS: "
+ "not yet implemented");
+
+ case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
/*
** We want to process all the minimal model calls whose
** stack frames are in the part of the nondet stack to be
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.176
diff -u -b -r1.176 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 19 Jul 2004 03:37:55 -0000 1.176
+++ trace/mercury_trace_internal.c 19 Jul 2004 03:41:01 -0000
@@ -591,6 +591,12 @@
static void MR_trace_print_subgoal_debug(const MR_Proc_Layout *proc,
MR_SubgoalDebug *subgoal_debug);
+/* Prints the given generator of the given procedure to MR_mdb_out. */
+static void MR_trace_print_generator(const MR_Proc_Layout *proc,
+ MR_Generator *generator);
+static void MR_trace_print_generator_debug(const MR_Proc_Layout *proc,
+ MR_GenDebug *generator_debug);
+
/* Prints the given consumer of the given procedure to MR_mdb_out. */
static void MR_trace_print_consumer(const MR_Proc_Layout *proc,
MR_Consumer *consumer);
@@ -1519,12 +1525,14 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
- MR_Determinism detism = event_info->MR_event_sll->
- MR_sll_entry->MR_sle_detism;
- MR_Unsigned depth = event_info->MR_call_depth;
+ MR_Determinism detism;
+ MR_Unsigned depth;
int stop_depth;
int n;
+ detism = event_info->MR_event_sll->MR_sll_entry->MR_sle_detism;
+ depth = event_info->MR_call_depth;
+
cmd->MR_trace_strict = MR_TRUE;
cmd->MR_trace_print_level = MR_default_print_level;
MR_init_trace_check_integrity(cmd);
@@ -3475,7 +3483,7 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_SubgoalDebug *subgoal_debug;
MR_Subgoal *subgoal;
@@ -3494,12 +3502,12 @@
MR_trace_usage("developer", "subgoal");
}
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
fprintf(MR_mdb_out, "mdb: the `subgoal' command is available "
- "only in minimal model tabling grades.\n");
+ "only in stack copy minimal model tabling grades.\n");
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
return KEEP_INTERACTING;
}
@@ -3509,7 +3517,7 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_ConsumerDebug *consumer_debug;
MR_Consumer *consumer;
@@ -3528,12 +3536,12 @@
MR_trace_usage("developer", "consumer");
}
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
fprintf(MR_mdb_out, "mdb: the `consumer' command is available "
- "only in minimal model tabling grades.\n");
+ "only in stack copy minimal model tabling grades.\n");
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
return KEEP_INTERACTING;
}
@@ -3544,7 +3552,7 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
if (word_count == 1) {
MR_bool saved_tabledebug;
@@ -3558,12 +3566,12 @@
MR_trace_usage("developer", "gen_stack");
}
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
fprintf(MR_mdb_out, "mdb: the `gen_stack' command is available "
- "only in minimal model grades.\n");
+ "only in stack copy minimal model tabling grades.\n");
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
return KEEP_INTERACTING;
}
@@ -3573,7 +3581,7 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
if (word_count == 1) {
MR_bool saved_tabledebug;
@@ -3587,12 +3595,12 @@
MR_trace_usage("developer", "cut_stack");
}
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
fprintf(MR_mdb_out, "mdb: the `cut_stack' command is available "
- "only in minimal model grades.\n");
+ "only in stack copy minimal model tabling grades.\n");
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
return KEEP_INTERACTING;
}
@@ -3602,7 +3610,7 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
if (word_count == 1) {
MR_bool saved_tabledebug;
@@ -3616,12 +3624,12 @@
MR_trace_usage("developer", "pneg_stack");
}
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
fprintf(MR_mdb_out, "mdb: the `pneg_stack' command is available "
- "only in minimal model grades.\n");
+ "only in stack copy minimal model tabling grades.\n");
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
return KEEP_INTERACTING;
}
@@ -3631,7 +3639,7 @@
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
if (word_count == 1) {
MR_bool saved_tabledebug;
@@ -3649,12 +3657,12 @@
MR_trace_usage("developer", "pneg_stack");
}
-#else /* MR_USE_MINIMAL_MODEL */
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
fprintf(MR_mdb_out, "mdb: the `pneg_stack' command is available "
- "only in minimal model grades.\n");
+ "only in stack copy minimal model tabling grades.\n");
-#endif /* MR_USE_MINIMAL_MODEL */
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
return KEEP_INTERACTING;
}
@@ -4108,7 +4116,8 @@
case MR_EVAL_METHOD_LOOP_CHECK:
case MR_EVAL_METHOD_MEMO:
- case MR_EVAL_METHOD_MINIMAL:
+ case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
+ case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
break;
case MR_EVAL_METHOD_TABLE_IO:
@@ -4246,7 +4255,8 @@
fprintf(MR_mdb_out, ":\n");
break;
- case MR_EVAL_METHOD_MINIMAL:
+ case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
+ case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
fprintf(MR_mdb_out, "minimal model table for ");
MR_print_proc_id(MR_mdb_out, proc);
fprintf(MR_mdb_out, ":\n");
@@ -4289,7 +4299,7 @@
** value of the last argument. We also do this whenever we run out of
** values in any trie.
**
- ** We step when we are about to backtrack out of the outermost loop.
+ ** We stop when we are about to backtrack out of the outermost loop.
*/
cur_arg = word_count;
@@ -4620,6 +4630,7 @@
MR_Call_Table_Arg *call_table_args, MR_TrieNode table)
{
int i;
+ MR_EvalMethod eval_method;
fprintf(MR_mdb_out, "<");
for (i = 0; i < num_inputs; i++) {
@@ -4654,7 +4665,8 @@
fprintf(MR_mdb_out, ">: ");
- if (MR_sle_eval_method(proc) == MR_EVAL_METHOD_MINIMAL) {
+ eval_method = MR_sle_eval_method(proc);
+ if (eval_method == MR_EVAL_METHOD_MINIMAL_STACK_COPY) {
MR_Subgoal *subgoal;
int subgoal_num;
@@ -4665,39 +4677,30 @@
} else {
MR_trace_print_subgoal(proc, subgoal);
}
- } else if (MR_sle_eval_method(proc) == MR_EVAL_METHOD_MEMO) {
- switch (table->MR_memo_status) {
- case MR_MEMO_INACTIVE:
+ } else if (eval_method == MR_EVAL_METHOD_MINIMAL_OWN_STACKS) {
+ MR_Consumer *consumer;
+
+ fprintf(MR_mdb_out, "trie node %p\n", table);
+ consumer = table->MR_consumer;
+ if (consumer == NULL) {
fprintf(MR_mdb_out, "uninitialized\n");
- break;
- case MR_MEMO_ACTIVE:
- fprintf(MR_mdb_out, "working\n");
- break;
- case MR_MEMO_FAILED:
- fprintf(MR_mdb_out, "failed\n");
- break;
- case MR_MEMO_SUCCEEDED:
- fprintf(MR_mdb_out, "succeeded (no outputs)\n");
- break;
- default:
- fprintf(MR_mdb_out, "succeeded <");
- MR_print_answerblock(MR_mdb_out, proc,
- table->MR_answerblock);
- fprintf(MR_mdb_out, ">\n");
- break;
+ } else {
+ MR_trace_print_consumer(proc, consumer);
}
- } else if (MR_sle_eval_method(proc) == MR_EVAL_METHOD_LOOP_CHECK) {
- switch (table->MR_loop_status) {
- case MR_LOOP_INACTIVE:
- fprintf(MR_mdb_out, "uninitialized\n");
- break;
- case MR_LOOP_ACTIVE:
- fprintf(MR_mdb_out, "working\n");
- break;
- default:
- MR_fatal_error("MR_trace_cmd_table_print_tip: "
- "bad loopcheck status");
+ } else if (eval_method == MR_EVAL_METHOD_MEMO) {
+ MR_Determinism detism;
+
+ detism = proc->MR_sle_detism;
+ if (MR_DETISM_DET_STACK(detism)) {
+ MR_print_memo_tip(MR_mdb_out, proc, table);
+ } else {
+ MR_MemoNonRecordPtr record;
+
+ record = table->MR_memo_non_record;
+ MR_print_memo_non_record(MR_mdb_out, proc, record);
}
+ } else if (eval_method == MR_EVAL_METHOD_LOOP_CHECK) {
+ MR_print_loopcheck_tip(MR_mdb_out, proc, table);
} else {
MR_fatal_error("MR_trace_cmd_table_print_tip: bad eval method");
}
@@ -4706,7 +4709,7 @@
static void
MR_trace_print_subgoal(const MR_Proc_Layout *proc, MR_Subgoal *subgoal)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_print_subgoal(MR_mdb_out, proc, subgoal);
#else
fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
@@ -4717,7 +4720,7 @@
MR_trace_print_subgoal_debug(const MR_Proc_Layout *proc,
MR_SubgoalDebug *subgoal_debug)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
MR_print_subgoal_debug(MR_mdb_out, proc, subgoal_debug);
#else
fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
@@ -4725,9 +4728,31 @@
}
static void
+MR_trace_print_generator(const MR_Proc_Layout *proc, MR_Generator *generator)
+{
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ MR_print_generator(MR_mdb_out, proc, generator);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
+MR_trace_print_generator_debug(const MR_Proc_Layout *proc,
+ MR_GenDebug *generator_debug)
+{
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ MR_print_generator_debug(MR_mdb_out, proc, generator_debug);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
MR_trace_print_consumer(const MR_Proc_Layout *proc, MR_Consumer *consumer)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#if defined(MR_USE_MINIMAL_MODEL_STACK_COPY) \
+ || defined(MR_USE_MINIMAL_MODEL_OWN_STACKS)
MR_print_consumer(MR_mdb_out, proc, consumer);
#else
fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
@@ -4738,7 +4763,8 @@
MR_trace_print_consumer_debug(const MR_Proc_Layout *proc,
MR_ConsumerDebug *consumer_debug)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#if defined(MR_USE_MINIMAL_MODEL_STACK_COPY) \
+ || defined(MR_USE_MINIMAL_MODEL_OWN_STACKS)
MR_print_consumer_debug(MR_mdb_out, proc, consumer_debug);
#else
fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
Index: trace/mercury_trace_util.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_util.c,v
retrieving revision 1.12
diff -u -b -r1.12 mercury_trace_util.c
--- trace/mercury_trace_util.c 7 Jul 2004 07:11:22 -0000 1.12
+++ trace/mercury_trace_util.c 7 Jul 2004 07:17:14 -0000
@@ -112,7 +112,7 @@
void
MR_print_tabling_regs(FILE *fp, MR_Word *saved_regs)
{
-#ifdef MR_USE_MINIMAL_MODEL
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
fprintf(fp, "gen_next = %ld\n", (long) MR_saved_gen_next(saved_regs));
fprintf(fp, "cut_next = %ld\n", (long) MR_saved_cut_next(saved_regs));
#endif
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: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list