[m-rev.] for review: fast_loose_memo
Zoltan Somogyi
zs at cs.mu.OZ.AU
Fri May 20 16:50:50 AEST 2005
For review by anyone. I will add the new feature to the NEWS file only
after more testing.
Zoltan.
Add a new form of tabling pragma, fast_loose_memo. It differs from memo in
only one way: for arguments of user-defined types, instead of tabling every
single function symbol in the value, it tables a pointer to the term instead.
(Actually, it tables the contents of the selected argument register, so it
works even if the value is not a pointer.)
As the name implies, this form of tabling is faster than memo. The tradeoff
is that it is looser: if two invocations specify two terms that are at
different addresses but have the same value, this new form of tabling will
not recognize the commonality.
doc/reference_manual.texi:
Document the new pragma.
compiler/prog_data.m:
Generalize the type specifying eval methods to allow the expression
of the new form of tabling.
compiler/prog_io_pragma.m:
Parse the new form of tabling pragma.
compiler/hlds_pred.m:
Handle the new, more general form of memoing.
Add the required provisions for the representation of the new form
of trie step in tables.
compiler/table_gen.m:
Implement the new form of tabling as a minor variant of memo tabling.
Convert this module to four-space indentation to reduce the number
of bad line breaks.
compiler/layout_out.m:
compiler/prog_out.m:
Conform to the changes above.
library/table_builtins.m:
Add the primitives required to implement fast_loose_memo.
Fix an old bug: make table_lookup_insert_poly call the right macro.
runtime/mercury_tabling.h:
runtime/mercury_tabling_macros.h:
runtime/mercury_tabling_preds.h:
Provide the basic mechanism of fast_loose_memo tabling: a hash table
that works on MR_Words.
runtime/mercury_stack_layout.h:
Allow the representation of the new evaluation method and the new form
of trie step.
tests/tabling/fast_loose.{m,exp}:
Add this test case of the operation of fast_loose tabling. The test
case pronounces success only if fast_loose_memo is measured to be
significantly faster than plain memo.
tests/tabling/Mmakefile:
Enable the new test case.
cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.161
diff -u -b -r1.161 hlds_pred.m
--- compiler/hlds_pred.m 7 Apr 2005 06:32:08 -0000 1.161
+++ compiler/hlds_pred.m 20 May 2005 02:29:17 -0000
@@ -1828,7 +1828,9 @@
% type, and thus the size of
% the corresponding trie node.
; table_trie_step_user(type)
+ ; table_trie_step_user_fast_loose(type)
; table_trie_step_poly
+ ; table_trie_step_poly_fast_loose
; table_trie_step_typeinfo
; table_trie_step_typeclassinfo.
@@ -3138,7 +3140,7 @@
;
Valid = yes
).
-valid_determinism_for_eval_method(eval_memo, Detism) = Valid :-
+valid_determinism_for_eval_method(eval_memo(_), Detism) = Valid :-
determinism_components(Detism, _, MaxSoln),
( MaxSoln = at_most_zero ->
Valid = no
@@ -3165,37 +3167,37 @@
eval_method_needs_stratification(eval_normal) = no.
eval_method_needs_stratification(eval_loop_check) = no.
eval_method_needs_stratification(eval_table_io(_, _)) = no.
-eval_method_needs_stratification(eval_memo) = no.
+eval_method_needs_stratification(eval_memo(_)) = no.
eval_method_needs_stratification(eval_minimal(_)) = yes.
eval_method_has_per_proc_tabling_pointer(eval_normal) = no.
eval_method_has_per_proc_tabling_pointer(eval_loop_check) = yes.
eval_method_has_per_proc_tabling_pointer(eval_table_io(_, _)) = no.
-eval_method_has_per_proc_tabling_pointer(eval_memo) = yes.
+eval_method_has_per_proc_tabling_pointer(eval_memo(_)) = yes.
eval_method_has_per_proc_tabling_pointer(eval_minimal(_)) = yes.
eval_method_requires_tabling_transform(eval_normal) = no.
eval_method_requires_tabling_transform(eval_loop_check) = yes.
eval_method_requires_tabling_transform(eval_table_io(_, _)) = yes.
-eval_method_requires_tabling_transform(eval_memo) = yes.
+eval_method_requires_tabling_transform(eval_memo(_)) = yes.
eval_method_requires_tabling_transform(eval_minimal(_)) = yes.
eval_method_requires_ground_args(eval_normal) = no.
eval_method_requires_ground_args(eval_loop_check) = yes.
eval_method_requires_ground_args(eval_table_io(_, _)) = yes.
-eval_method_requires_ground_args(eval_memo) = yes.
+eval_method_requires_ground_args(eval_memo(_)) = yes.
eval_method_requires_ground_args(eval_minimal(_)) = yes.
eval_method_destroys_uniqueness(eval_normal) = no.
eval_method_destroys_uniqueness(eval_loop_check) = yes.
eval_method_destroys_uniqueness(eval_table_io(_, _)) = no.
-eval_method_destroys_uniqueness(eval_memo) = yes.
+eval_method_destroys_uniqueness(eval_memo(_)) = yes.
eval_method_destroys_uniqueness(eval_minimal(_)) = yes.
eval_method_change_determinism(eval_normal, Detism) = Detism.
eval_method_change_determinism(eval_loop_check, Detism) = Detism.
eval_method_change_determinism(eval_table_io(_, _), Detism) = Detism.
-eval_method_change_determinism(eval_memo, Detism) = Detism.
+eval_method_change_determinism(eval_memo(_), Detism) = Detism.
eval_method_change_determinism(eval_minimal(_), Detism0) = Detism :-
det_conjunction_detism(semidet, Detism0, Detism).
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.47
diff -u -b -r1.47 layout_out.m
--- compiler/layout_out.m 31 Mar 2005 04:44:21 -0000 1.47
+++ compiler/layout_out.m 20 May 2005 02:56:05 -0000
@@ -987,7 +987,14 @@
eval_method_to_c_string(eval_normal) = "MR_EVAL_METHOD_NORMAL".
eval_method_to_c_string(eval_loop_check) = "MR_EVAL_METHOD_LOOP_CHECK".
-eval_method_to_c_string(eval_memo) = "MR_EVAL_METHOD_MEMO".
+eval_method_to_c_string(eval_memo(CallStrictness)) = Str :-
+ (
+ CallStrictness = strict,
+ Str = "MR_EVAL_METHOD_MEMO_STRICT"
+ ;
+ CallStrictness = fast_loose,
+ Str = "MR_EVAL_METHOD_MEMO_FAST_LOOSE"
+ ).
eval_method_to_c_string(eval_minimal(MinimalMethod)) = Str :-
(
MinimalMethod = stack_copy,
@@ -1812,8 +1819,16 @@
StepType = "MR_TABLE_STEP_USER",
MaybeEnumParam = no
;
+ Step = table_trie_step_user_fast_loose(_),
+ StepType = "MR_TABLE_STEP_USER_FAST_LOOSE",
+ MaybeEnumParam = no
+ ;
Step = table_trie_step_poly,
StepType = "MR_TABLE_STEP_POLY",
+ MaybeEnumParam = no
+ ;
+ Step = table_trie_step_poly_fast_loose,
+ StepType = "MR_TABLE_STEP_POLY_FAST_LOOSE",
MaybeEnumParam = no
;
Step = table_trie_step_typeinfo,
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.126
diff -u -b -r1.126 prog_data.m
--- compiler/prog_data.m 20 Apr 2005 12:57:15 -0000 1.126
+++ compiler/prog_data.m 20 May 2005 01:27:24 -0000
@@ -586,13 +586,18 @@
---> eval_normal % normal mercury
% evaluation
; eval_loop_check % loop check only
- ; eval_memo % memoing + loop check
+ ; eval_memo(call_table_strictness)
+ % memoing + loop check
; eval_table_io( % memoing I/O actions for debugging
table_io_is_decl,
table_io_is_unitize
)
; eval_minimal(eval_minimal_method).
% minimal model evaluation
+
+:- type call_table_strictness
+ ---> strict
+ ; fast_loose.
:- type table_io_is_decl
---> table_io_decl % The procedure is tabled for
Index: compiler/prog_io_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.81
diff -u -b -r1.81 prog_io_pragma.m
--- compiler/prog_io_pragma.m 7 Apr 2005 06:32:14 -0000 1.81
+++ compiler/prog_io_pragma.m 20 May 2005 01:47:01 -0000
@@ -822,7 +822,11 @@
parse_pragma_type(ModuleName, "memo", PragmaTerms, ErrorTerm, _VarSet,
Result) :-
- parse_tabling_pragma(ModuleName, "memo", eval_memo,
+ parse_tabling_pragma(ModuleName, "memo", eval_memo(strict),
+ PragmaTerms, ErrorTerm, Result).
+parse_pragma_type(ModuleName, "fast_loose_memo", PragmaTerms, ErrorTerm,
+ _VarSet, Result) :-
+ parse_tabling_pragma(ModuleName, "fast_loose_memo", eval_memo(fast_loose),
PragmaTerms, ErrorTerm, Result).
parse_pragma_type(ModuleName, "loop_check", PragmaTerms, ErrorTerm, _VarSet,
Result) :-
Index: compiler/prog_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_out.m,v
retrieving revision 1.57
diff -u -b -r1.57 prog_out.m
--- compiler/prog_out.m 30 Mar 2005 00:50:21 -0000 1.57
+++ compiler/prog_out.m 20 May 2005 01:47:26 -0000
@@ -306,7 +306,8 @@
eval_method_to_string(eval_normal) = "normal".
eval_method_to_string(eval_loop_check) = "loop_check".
-eval_method_to_string(eval_memo) = "memo".
+eval_method_to_string(eval_memo(strict)) = "memo".
+eval_method_to_string(eval_memo(fast_loose)) = "fast_loose_memo".
eval_method_to_string(eval_minimal(MinimalMethod)) = Str :-
(
MinimalMethod = own_stacks,
Index: compiler/table_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/table_gen.m,v
retrieving revision 1.80
diff -u -b -r1.80 table_gen.m
--- compiler/table_gen.m 1 Apr 2005 14:29:02 -0000 1.80
+++ compiler/table_gen.m 20 May 2005 03:03:42 -0000
@@ -1,4 +1,6 @@
%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
% Copyright (C) 1997-2005 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
@@ -97,12 +99,14 @@
% Values of this type map the pred_id of a minimal_model tabled
% predicate to the pred_id of its generator variant.
+ %
:- type generator_map == map(pred_id, pred_id).
% NOTE: following preds seem to duplicate the code in passes_aux.m.
% The reason for this duplication is that this module needs a variant
% of this code that is able to handle passing a module_info to
% polymorphism and getting an updated module_info back.
+ %
table_gen__process_module(!ModuleInfo, !IO) :-
module_info_preds(!.ModuleInfo, Preds0),
map__keys(Preds0, PredIds),
@@ -150,8 +154,7 @@
proc_info_eval_method(ProcInfo0, EvalMethod),
( eval_method_requires_tabling_transform(EvalMethod) = yes ->
table_gen__transform_proc_if_possible(EvalMethod, PredId,
- ProcId, ProcInfo0, _, PredInfo0, _, !ModuleInfo,
- !GenMap, !IO)
+ ProcId, ProcInfo0, _, PredInfo0, _, !ModuleInfo, !GenMap, !IO)
;
module_info_globals(!.ModuleInfo, Globals),
globals__lookup_bool_option(Globals, trace_table_io, yes),
@@ -163,20 +166,16 @@
true
;
pred_id_to_int(PredId, PredIdInt),
- Msg = string__format(
- "I/O procedure pred id %d not model_det",
+ Msg = string__format("I/O procedure pred id %d not model_det",
[i(PredIdInt)]),
error(Msg)
),
- globals__lookup_bool_option(Globals, trace_table_io_all,
- TransformAll),
- globals__lookup_bool_option(Globals, trace_table_io_require,
- Require),
+ globals__lookup_bool_option(Globals, trace_table_io_all, TransformAll),
+ globals__lookup_bool_option(Globals, trace_table_io_require, Require),
proc_info_goal(ProcInfo0, BodyGoal),
predicate_module(!.ModuleInfo, PredId, PredModuleName),
- should_io_procedure_be_transformed(TransformAll, Require,
- BodyGoal, PredModuleName, AnnotationIsMissing,
- TransformPrimitive),
+ should_io_procedure_be_transformed(TransformAll, Require, BodyGoal,
+ PredModuleName, AnnotationIsMissing, TransformPrimitive),
(
AnnotationIsMissing = yes,
report_missing_tabled_for_io(!.ModuleInfo, PredInfo0,
@@ -189,8 +188,7 @@
TransformPrimitive = no
;
TransformPrimitive = yes(Unitize),
- globals__lookup_bool_option(Globals,
- trace_table_io_only_retry,
+ globals__lookup_bool_option(Globals, trace_table_io_only_retry,
TraceTableIoOnlyRetry),
(
TraceTableIoOnlyRetry = no,
@@ -200,11 +198,10 @@
Decl = table_io_proc
),
TableIoMethod = eval_table_io(Decl, Unitize),
- proc_info_set_eval_method(TableIoMethod,
- ProcInfo0, ProcInfo1),
+ proc_info_set_eval_method(TableIoMethod, ProcInfo0, ProcInfo1),
table_gen__transform_proc_if_possible(TableIoMethod,
- PredId, ProcId, ProcInfo1, _, PredInfo0, _,
- !ModuleInfo, !GenMap, !IO)
+ PredId, ProcId, ProcInfo1, _, PredInfo0, _, !ModuleInfo,
+ !GenMap, !IO)
)
;
true
@@ -240,13 +237,11 @@
may_call_mercury_attributes(BodyGoal,
MayCallMercuryAttrs),
(
- MayCallMercuryAttrs =
- [may_call_mercury]
+ MayCallMercuryAttrs = [may_call_mercury]
->
TransformInfo = no
;
- TransformInfo =
- yes(table_io_alone)
+ TransformInfo = yes(table_io_alone)
)
)
)
@@ -276,8 +271,7 @@
is det.
may_call_mercury_attributes(Goal, MayCallMercuryAttrs) :-
- solutions(subgoal_may_call_mercury_attribute(Goal),
- MayCallMercuryAttrs).
+ solutions(subgoal_may_call_mercury_attribute(Goal), MayCallMercuryAttrs).
:- pred subgoal_may_call_mercury_attribute(hlds_goal::in,
may_call_mercury::out) is nondet.
@@ -371,8 +365,7 @@
EvalMethodStr = eval_method_to_string(EvalMethod),
Msg = [words("Ignoring the pragma"), fixed(EvalMethodStr),
words("for")] ++ ProcPieces ++
- [words("due to lack of support"),
- words("on this back end."), nl],
+ [words("due to lack of support on this back end."), nl],
error_util__write_error_pieces(Context, 0, Msg, !IO),
%
% XXX We set the evaluation method to eval_normal here
@@ -414,8 +407,8 @@
BadVars = []
;
BadVars = [_ | _],
- report_bad_mode_for_tabling(!.ModuleInfo, !.PredInfo,
- PredId, ProcId, VarSet0, BadVars, !IO),
+ report_bad_mode_for_tabling(!.ModuleInfo, !.PredInfo, PredId, ProcId,
+ VarSet0, BadVars, !IO),
% We continue the transformation as best we can,
% but prevent the creation of an executable.
module_info_incr_errors(!ModuleInfo)
@@ -430,17 +423,15 @@
module_info_globals(!.ModuleInfo, Globals),
globals__lookup_bool_option(Globals, trace_table_io_states,
TableIoStates),
- table_gen__create_new_io_goal(OrigGoal, Decl, Unitize,
- TableIoStates, PredId, ProcId, TablingViaExtraArgs,
- HeadVars, InputVars, OutputVars,
- VarTypes0, VarTypes, VarSet0, VarSet,
+ table_gen__create_new_io_goal(OrigGoal, Decl, Unitize, TableIoStates,
+ PredId, ProcId, TablingViaExtraArgs, HeadVars,
+ InputVars, OutputVars, VarTypes0, VarTypes, VarSet0, VarSet,
TableInfo0, TableInfo, Goal, MaybeProcTableInfo),
MaybeCallTableTip = no
;
EvalMethod = eval_loop_check,
- table_gen__create_new_loop_goal(Detism, OrigGoal,
- PredId, ProcId, TablingViaExtraArgs,
- HeadVars, InputVars, OutputVars,
+ table_gen__create_new_loop_goal(Detism, OrigGoal, PredId, ProcId,
+ TablingViaExtraArgs, HeadVars, InputVars, OutputVars,
VarTypes0, VarTypes, VarSet0, VarSet,
TableInfo0, TableInfo, CallTableTip, Goal, Steps),
generate_gen_proc_table_info(TableInfo, Steps,
@@ -448,24 +439,21 @@
MaybeCallTableTip = yes(CallTableTip),
MaybeProcTableInfo = yes(ProcTableInfo)
;
- EvalMethod = eval_memo,
+ EvalMethod = eval_memo(CallStrictness),
( CodeModel = model_non ->
- table_gen__create_new_memo_non_goal(Detism, OrigGoal,
- PredId, ProcId,
- HeadVars, InputVars, OutputVars,
- VarTypes0, VarTypes, VarSet0, VarSet,
- TableInfo0, TableInfo, CallTableTip, Goal,
- Steps)
+ table_gen__create_new_memo_non_goal(CallStrictness, Detism,
+ OrigGoal, PredId, ProcId, HeadVars, InputVars, OutputVars,
+ VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+ CallTableTip, Goal, Steps)
;
- table_gen__create_new_memo_goal(Detism, OrigGoal,
- PredId, ProcId, TablingViaExtraArgs,
+ table_gen__create_new_memo_goal(CallStrictness, Detism,
+ OrigGoal, PredId, ProcId, TablingViaExtraArgs,
HeadVars, InputVars, OutputVars,
VarTypes0, VarTypes, VarSet0, VarSet,
- TableInfo0, TableInfo, CallTableTip, Goal,
- Steps)
+ TableInfo0, TableInfo, CallTableTip, Goal, Steps)
),
- generate_gen_proc_table_info(TableInfo, Steps,
- InputVars, OutputVars, ProcTableInfo),
+ generate_gen_proc_table_info(TableInfo, Steps, InputVars, OutputVars,
+ ProcTableInfo),
MaybeCallTableTip = yes(CallTableTip),
MaybeProcTableInfo = yes(ProcTableInfo)
;
@@ -479,24 +467,20 @@
;
CodeModel = model_non,
MinimalMethod = stack_copy,
- table_gen__create_new_mm_goal(Detism, OrigGoal,
- PredId, ProcId, TablingViaExtraArgs,
- HeadVars, InputVars, OutputVars,
- VarTypes0, VarTypes, VarSet0, VarSet,
- TableInfo0, TableInfo,
+ table_gen__create_new_mm_goal(Detism, OrigGoal, PredId, ProcId,
+ TablingViaExtraArgs, HeadVars, InputVars, OutputVars,
+ VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
CallTableTip, Goal, Steps)
;
CodeModel = model_non,
MinimalMethod = own_stacks,
- table_gen__do_own_stack_transform(Detism, OrigGoal,
- PredId, ProcId, !.PredInfo, !.ProcInfo,
- HeadVars, InputVars, OutputVars,
+ table_gen__do_own_stack_transform(Detism, OrigGoal, PredId, ProcId,
+ !.PredInfo, !.ProcInfo, HeadVars, InputVars, OutputVars,
VarTypes0, VarTypes, VarSet0, VarSet,
- TableInfo0, TableInfo, !GenMap,
- CallTableTip, Goal, Steps)
+ TableInfo0, TableInfo, !GenMap, CallTableTip, Goal, Steps)
),
- generate_gen_proc_table_info(TableInfo, Steps,
- InputVars, OutputVars, ProcTableInfo),
+ generate_gen_proc_table_info(TableInfo, Steps, InputVars, OutputVars,
+ ProcTableInfo),
MaybeCallTableTip = yes(CallTableTip),
MaybeProcTableInfo = yes(ProcTableInfo)
),
@@ -516,8 +500,7 @@
% recompute them here.
RecomputeAtomic = no,
- recompute_instmap_delta_proc(RecomputeAtomic, !ProcInfo,
- !ModuleInfo),
+ recompute_instmap_delta_proc(RecomputeAtomic, !ProcInfo, !ModuleInfo),
pred_info_procedures(!.PredInfo, ProcTable1),
map__det_update(ProcTable1, ProcId, !.ProcInfo, ProcTable),
@@ -639,7 +622,7 @@
ModuleInfo = !.TableInfo ^ table_module_info,
allocate_slot_numbers(InputVars, 0, NumberedInputVars),
- generate_simple_call_table_lookup_goal(loop_status_type,
+ generate_simple_call_table_lookup_goal(strict, loop_status_type,
"table_loop_setup", NumberedInputVars, PredId, ProcId,
TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo,
TableTipVar, StatusVar, LookUpGoal, Steps),
@@ -652,20 +635,16 @@
MarkActiveFailPred = "table_loop_mark_as_active_and_fail",
(
TablingViaExtraArgs = no,
- generate_call(MarkInactivePred, det,
- [TableTipVar], impure_code, [], ModuleInfo,
- Context, MarkInactiveGoal),
- generate_call(MarkInactiveFailPred, failure,
- [TableTipVar], impure_code, [], ModuleInfo,
- Context, MarkInactiveFailGoal),
- generate_call(MarkActiveFailPred, failure,
- [TableTipVar], impure_code, [], ModuleInfo,
- Context, MarkActiveFailGoal)
+ generate_call(MarkInactivePred, det, [TableTipVar],
+ impure_code, [], ModuleInfo, Context, MarkInactiveGoal),
+ generate_call(MarkInactiveFailPred, failure, [TableTipVar],
+ impure_code, [], ModuleInfo, Context, MarkInactiveFailGoal),
+ generate_call(MarkActiveFailPred, failure, [TableTipVar],
+ impure_code, [], ModuleInfo, Context, MarkActiveFailGoal)
;
TablingViaExtraArgs = yes,
TableTipArg = foreign_arg(TableTipVar,
- yes(cur_table_node_name - in_mode),
- trie_node_type),
+ yes(cur_table_node_name - in_mode), trie_node_type),
MarkInactiveCode = "\tMR_" ++ MarkInactivePred ++
"(" ++ cur_table_node_name ++ ");\n",
MarkInactiveFailCode = "\tMR_" ++ MarkInactiveFailPred ++
@@ -706,8 +685,8 @@
Detism, impure, Context, ThenGoalInfo),
ThenGoal = ThenGoalExpr - ThenGoalInfo,
- InactiveGoalExpr = if_then_else([], RenamedOrigGoal,
- ThenGoal, MarkInactiveFailGoal)
+ InactiveGoalExpr = if_then_else([], RenamedOrigGoal, ThenGoal,
+ MarkInactiveFailGoal)
;
CodeModel = model_non,
AfterGoalExpr = disj([MarkInactiveGoal, MarkActiveFailGoal]),
@@ -719,8 +698,7 @@
FirstGoalExpr = conj([OrigGoal, AfterGoal]),
goal_info_get_nonlocals(OrigGoalInfo, OrigGINonLocals),
set__insert(OrigGINonLocals, TableTipVar, FirstNonlocals),
- goal_info_set_nonlocals(OrigGoalInfo, FirstNonlocals,
- FirstGoalInfo),
+ goal_info_set_nonlocals(OrigGoalInfo, FirstNonlocals, FirstGoalInfo),
FirstGoal = FirstGoalExpr - FirstGoalInfo,
InactiveGoalExpr = disj([FirstGoal, MarkInactiveFailGoal])
),
@@ -730,21 +708,19 @@
mercury_table_builtin_module(TB),
SwitchArms = [
- case(cons(qualified(TB, "loop_active"), 0),
- ActiveGoal),
- case(cons(qualified(TB, "loop_inactive"), 0),
- InactiveGoal)
+ case(cons(qualified(TB, "loop_active"), 0), ActiveGoal),
+ case(cons(qualified(TB, "loop_inactive"), 0), InactiveGoal)
],
SwitchExpr = switch(StatusVar, cannot_fail, SwitchArms),
set__insert_list(InactiveNonLocals, [StatusVar, TableTipVar],
SwitchNonLocals),
- goal_info_init_hide(SwitchNonLocals, InactiveInstmapDelta,
- Detism, impure, Context, SwitchGoalInfo),
+ goal_info_init_hide(SwitchNonLocals, InactiveInstmapDelta, Detism, impure,
+ Context, SwitchGoalInfo),
SwitchGoal = SwitchExpr - SwitchGoalInfo,
GoalExpr = conj([LookUpGoal, SwitchGoal]),
- goal_info_init_hide(OrigNonLocals, OrigInstMapDelta, Detism,
- impure, Context, GoalInfo),
+ goal_info_init_hide(OrigNonLocals, OrigInstMapDelta, Detism, impure,
+ Context, GoalInfo),
Goal = GoalExpr - GoalInfo.
%-----------------------------------------------------------------------------%
@@ -867,16 +843,16 @@
% If there are no output variables, then instead of creating an answer block
% and filling it in, we call table_memo_mark_as_succeeded.
-:- pred create_new_memo_goal(determinism::in, hlds_goal::in,
- pred_id::in, proc_id::in, bool::in,
+:- pred create_new_memo_goal(call_table_strictness::in, determinism::in,
+ hlds_goal::in, pred_id::in, proc_id::in, bool::in,
list(prog_var)::in, list(prog_var)::in, list(prog_var)::in,
vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
table_info::in, table_info::out, prog_var::out, hlds_goal::out,
list(table_trie_step)::out) is det.
-create_new_memo_goal(Detism, OrigGoal, PredId, ProcId, TablingViaExtraArgs,
- HeadVars, InputVars, OutputVars, !VarTypes, !VarSet,
- !TableInfo, TableTipVar, Goal, Steps) :-
+create_new_memo_goal(CallStrictness, Detism, OrigGoal, PredId, ProcId,
+ TablingViaExtraArgs, HeadVars, InputVars, OutputVars,
+ !VarTypes, !VarSet, !TableInfo, TableTipVar, Goal, Steps) :-
% even if the original goal doesn't use all of the headvars,
% the code generated by the tabling transformation does,
% so we need to compute the nonlocals from the headvars rather
@@ -901,9 +877,9 @@
error("create_new_memo_goal: model_non")
),
allocate_slot_numbers(InputVars, 0, NumberedInputVars),
- generate_simple_call_table_lookup_goal(StatusType, SetupPred,
- NumberedInputVars, PredId, ProcId, TablingViaExtraArgs,
- Context, !VarTypes, !VarSet, !TableInfo,
+ generate_simple_call_table_lookup_goal(CallStrictness, StatusType,
+ SetupPred, NumberedInputVars, PredId, ProcId,
+ TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo,
TableTipVar, StatusVar, LookUpGoal, Steps),
generate_error_goal(!.TableInfo, Context, infinite_recursion_msg,
@@ -930,12 +906,9 @@
mercury_table_builtin_module(TB),
SwitchArms = [
- case(cons(qualified(TB, "memo_det_active"), 0),
- ActiveGoal),
- case(cons(qualified(TB, "memo_det_inactive"), 0),
- InactiveGoal),
- case(cons(qualified(TB, "memo_det_succeeded"), 0),
- SucceededGoal)
+ case(cons(qualified(TB, "memo_det_active"), 0), ActiveGoal),
+ case(cons(qualified(TB, "memo_det_inactive"), 0), InactiveGoal),
+ case(cons(qualified(TB, "memo_det_succeeded"), 0), SucceededGoal)
]
;
CodeModel = model_semi,
@@ -954,8 +927,7 @@
(
TablingViaExtraArgs = yes,
TableTipArg = foreign_arg(TableTipVar,
- yes(cur_table_node_name - in_mode),
- trie_node_type),
+ yes(cur_table_node_name - in_mode), trie_node_type),
MarkAsFailedCode = "MR_" ++ MarkAsFailedPred ++
"(" ++ cur_table_node_name ++ ");",
generate_foreign_proc(MarkAsFailedPred, failure,
@@ -964,9 +936,8 @@
ModuleInfo, Context, ElseGoal)
;
TablingViaExtraArgs = no,
- generate_call("table_memo_mark_as_failed", failure,
- [TableTipVar], impure_code, [], ModuleInfo,
- Context, ElseGoal)
+ generate_call("table_memo_mark_as_failed", failure, [TableTipVar],
+ impure_code, [], ModuleInfo, Context, ElseGoal)
),
InactiveGoalExpr = if_then_else([], RenamedOrigGoal,
ThenGoal, ElseGoal),
@@ -977,14 +948,10 @@
mercury_table_builtin_module(TB),
SwitchArms = [
- case(cons(qualified(TB, "memo_semi_active"), 0),
- ActiveGoal),
- case(cons(qualified(TB, "memo_semi_inactive"), 0),
- InactiveGoal),
- case(cons(qualified(TB, "memo_semi_succeeded"), 0),
- SucceededGoal),
- case(cons(qualified(TB, "memo_semi_failed"), 0),
- FailedGoal)
+ case(cons(qualified(TB, "memo_semi_active"), 0), ActiveGoal),
+ case(cons(qualified(TB, "memo_semi_inactive"), 0), InactiveGoal),
+ case(cons(qualified(TB, "memo_semi_succeeded"), 0), SucceededGoal),
+ case(cons(qualified(TB, "memo_semi_failed"), 0), FailedGoal)
]
;
CodeModel = model_non,
@@ -998,18 +965,18 @@
SwitchGoal = SwitchExpr - SwitchGoalInfo,
GoalExpr = conj([LookUpGoal, SwitchGoal]),
- goal_info_init_hide(OrigNonLocals, OrigInstMapDelta, Detism,
- impure, Context, GoalInfo),
+ goal_info_init_hide(OrigNonLocals, OrigInstMapDelta, Detism, impure,
+ Context, GoalInfo),
Goal = GoalExpr - GoalInfo.
-:- pred create_new_memo_non_goal(determinism::in, hlds_goal::in,
- pred_id::in, proc_id::in,
+:- pred create_new_memo_non_goal(call_table_strictness::in, determinism::in,
+ hlds_goal::in, pred_id::in, proc_id::in,
list(prog_var)::in, list(prog_var)::in, list(prog_var)::in,
vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
table_info::in, table_info::out, prog_var::out, hlds_goal::out,
list(table_trie_step)::out) is det.
-create_new_memo_non_goal(Detism, OrigGoal, PredId, ProcId,
+create_new_memo_non_goal(CallStrictness, Detism, OrigGoal, PredId, ProcId,
HeadVars, InputVars, OutputVars, !VarTypes, !VarSet,
!TableInfo, RecordVar, Goal, Steps) :-
% even if the original goal doesn't use all of the headvars,
@@ -1029,11 +996,11 @@
generate_error_goal(!.TableInfo, Context, infinite_recursion_msg,
!VarTypes, !VarSet, InfiniteRecursionGoal),
generate_error_goal(!.TableInfo, Context, need_minimal_model_msg,
- !VarTypes, !VarSet, NeedMinimalModelGoal),
+ !VarTypes, !VarSet, NeedMinModelGoal),
- generate_memo_non_call_table_lookup_goal(NumberedInputVars,
- PredId, ProcId, Context, !VarTypes, !VarSet, !TableInfo,
- RecordVar, StatusVar, LookUpGoal, Steps),
+ generate_memo_non_call_table_lookup_goal(CallStrictness,
+ NumberedInputVars, PredId, ProcId, Context, !VarTypes, !VarSet,
+ !TableInfo, RecordVar, StatusVar, LookUpGoal, Steps),
generate_memo_non_save_goals(NumberedOutputVars, RecordVar, BlockSize,
Context, !VarTypes, !VarSet, !TableInfo, SaveAnswerGoals),
@@ -1092,25 +1059,21 @@
mercury_table_builtin_module(TB),
SwitchArms = [
- case(cons(qualified(TB, "memo_non_active"), 0),
- InfiniteRecursionGoal),
- case(cons(qualified(TB, "memo_non_inactive"), 0),
- InactiveGoal),
- case(cons(qualified(TB, "memo_non_incomplete"), 0),
- NeedMinimalModelGoal),
- case(cons(qualified(TB, "memo_non_complete"), 0),
- RestoreAllAnswerGoal)
+ case(cons(qualified(TB, "memo_non_active"), 0), InfiniteRecursionGoal),
+ case(cons(qualified(TB, "memo_non_inactive"), 0), InactiveGoal),
+ case(cons(qualified(TB, "memo_non_incomplete"), 0), NeedMinModelGoal),
+ case(cons(qualified(TB, "memo_non_complete"), 0), RestoreAllAnswerGoal)
],
SwitchExpr = switch(StatusVar, cannot_fail, SwitchArms),
set__insert(InactiveNonLocals, StatusVar, SwitchNonLocals),
- goal_info_init_hide(SwitchNonLocals, InactiveInstmapDelta,
- Detism, impure, Context, SwitchGoalInfo),
+ goal_info_init_hide(SwitchNonLocals, InactiveInstmapDelta, Detism, impure,
+ Context, SwitchGoalInfo),
SwitchGoal = SwitchExpr - SwitchGoalInfo,
GoalExpr = conj([LookUpGoal, SwitchGoal]),
- goal_info_init_hide(OrigNonLocals, OrigInstMapDelta, Detism,
- impure, Context, GoalInfo),
+ goal_info_init_hide(OrigNonLocals, OrigInstMapDelta, Detism, impure,
+ Context, GoalInfo),
Goal = GoalExpr - GoalInfo.
%-----------------------------------------------------------------------------%
@@ -1190,9 +1153,8 @@
hlds_goal::out, maybe(proc_table_info)::out) is det.
table_gen__create_new_io_goal(OrigGoal, TableDecl, Unitize, TableIoStates,
- PredId, ProcId, TablingViaExtraArgs,
- HeadVars, InputVars, OutputVars, !VarTypes, !VarSet,
- !TableInfo, Goal, MaybeProcTableInfo) :-
+ PredId, ProcId, TablingViaExtraArgs, HeadVars, InputVars, OutputVars,
+ !VarTypes, !VarSet, !TableInfo, Goal, MaybeProcTableInfo) :-
OrigGoal = _ - OrigGoalInfo,
goal_info_get_nonlocals(OrigGoalInfo, OrigNonLocals),
goal_info_get_context(OrigGoalInfo, Context),
@@ -1216,8 +1178,7 @@
TableVar),
generate_new_table_var("CounterVar", int_type, !VarTypes, !VarSet,
CounterVar),
- generate_new_table_var("StartVar", int_type, !VarTypes, !VarSet,
- StartVar),
+ generate_new_table_var("StartVar", int_type, !VarTypes, !VarSet, StartVar),
generate_call("table_io_in_range", semidet,
[TableVar, CounterVar, StartVar], impure_code,
ground_vars([TableVar, CounterVar, StartVar]),
@@ -1251,8 +1212,7 @@
;
TableDecl = table_io_proc,
true_goal(TableIoDeclGoal),
- allocate_slot_numbers(SavedOutputVars, 0,
- NumberedSavedOutputVars),
+ allocate_slot_numbers(SavedOutputVars, 0, NumberedSavedOutputVars),
NumberedRestoreVars = NumberedSavedOutputVars,
NumberedSaveVars = NumberedSavedOutputVars,
MaybeProcTableInfo = no
@@ -1299,16 +1259,14 @@
goal_info_init_hide(RestoreAnswerNonLocals,
RestoreAnswerInstMapDelta, det, semipure, Context,
RestoreAnswerGoalInfo),
- RestoreAnswerGoal = RestoreAnswerGoalExpr
- - RestoreAnswerGoalInfo
+ RestoreAnswerGoal = RestoreAnswerGoalExpr - RestoreAnswerGoalInfo
),
generate_memo_save_goals(NumberedSaveVars, TipVar, BlockSize,
TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo,
SaveAnswerGoals),
(
Unitize = table_io_alone,
- CallSaveAnswerGoalList = [OrigGoal, TableIoDeclGoal
- | SaveAnswerGoals]
+ CallSaveAnswerGoalList = [OrigGoal, TableIoDeclGoal | SaveAnswerGoals]
;
Unitize = table_io_unitize,
generate_new_table_var("SavedTraceEnabled", int_type,
@@ -1459,8 +1417,7 @@
!VarTypes, !VarSet, SuspendGoal),
MainExpr = conj([OrigGoal | SaveAnswerGoals]),
- set__insert_list(OrigNonLocals, [SubgoalVar, StatusVar],
- MainNonLocals),
+ set__insert_list(OrigNonLocals, [SubgoalVar, StatusVar], MainNonLocals),
create_instmap_delta([OrigGoal | SaveAnswerGoals], MainIMD0),
instmap_delta_restrict(MainIMD0, MainNonLocals, MainIMD),
goal_info_init_hide(MainNonLocals, MainIMD, nondet, impure, Context,
@@ -1475,12 +1432,9 @@
mercury_table_builtin_module(TB),
SwitchArms = [
- case(cons(qualified(TB, "mm_inactive"), 0),
- InactiveGoal),
- case(cons(qualified(TB, "mm_complete"), 0),
- RestoreAllAnswerGoal),
- case(cons(qualified(TB, "mm_active"), 0),
- SuspendGoal)
+ case(cons(qualified(TB, "mm_inactive"), 0), InactiveGoal),
+ case(cons(qualified(TB, "mm_complete"), 0), RestoreAllAnswerGoal),
+ case(cons(qualified(TB, "mm_active"), 0), SuspendGoal)
],
SwitchExpr = switch(StatusVar, cannot_fail, SwitchArms),
goal_info_add_feature(MainGoalInfo, hide_debug_event, SwitchGoalInfo),
@@ -1545,14 +1499,12 @@
table_gen__do_own_stack_transform(Detism, OrigGoal, PredId, ProcId,
PredInfo0, ProcInfo0, HeadVars, InputVars, OutputVars,
- !VarTypes, !VarSet, !TableInfo, !GenMap, TableTipVar,
- Goal, Steps) :-
+ !VarTypes, !VarSet, !TableInfo, !GenMap, TableTipVar, Goal, Steps) :-
PredName = pred_info_name(PredInfo0),
( map__search(!.GenMap, PredId, GeneratorPredIdPrime) ->
GeneratorPredId = GeneratorPredIdPrime
;
- clone_pred_info(PredId, PredInfo0, GeneratorPredId,
- !TableInfo),
+ clone_pred_info(PredId, PredInfo0, GeneratorPredId, !TableInfo),
map__det_insert(!.GenMap, PredId, GeneratorPredId, !:GenMap)
),
@@ -1590,17 +1542,16 @@
generate_new_table_var("Consumer", consumer_type, !VarTypes, !VarSet,
ConsumerVar),
- ShroudedPredProcId =
- shroud_pred_proc_id(proc(GeneratorPredId, ProcId)),
+ ShroudedPredProcId = shroud_pred_proc_id(proc(GeneratorPredId, ProcId)),
GeneratorConsId = pred_const(ShroudedPredProcId, normal),
make_const_construction(GeneratorPredVar, GeneratorConsId,
MakeGeneratorVarGoal),
% XXX use tabling via foreign_proc
- generate_call_table_lookup_goals(NumberedInputVars, PredId, ProcId,
- Context, !VarTypes, !VarSet, !TableInfo, TableTipVar,
- LookupGoals, Steps, _PredTableVar, _LookupForeignArgs,
- _LookupPrefixGoals, _LookupCodeStr),
+ generate_call_table_lookup_goals(strict, NumberedInputVars,
+ PredId, ProcId, Context, !VarTypes, !VarSet, !TableInfo,
+ TableTipVar, LookupGoals, Steps, _PredTableVar,
+ _LookupForeignArgs, _LookupPrefixGoals, _LookupCodeStr),
TableTipVarName = table_tip_node_name,
GeneratorPredVarName = generator_pred_name,
@@ -1641,8 +1592,7 @@
_RestoreCodeStr),
GoalExpr = conj([SaveGoal | LookupGoals] ++
- [MakeGeneratorVarGoal, SetupGoal, GetNextAnswerGoal
- | RestoreGoals]),
+ [MakeGeneratorVarGoal, SetupGoal, GetNextAnswerGoal | RestoreGoals]),
goal_info_init(OrigNonLocals, OrigInstMapDelta, Detism, impure,
Context, GoalInfo),
Goal = GoalExpr - GoalInfo,
@@ -1663,14 +1613,12 @@
generate_save_input_vars_code([], _, [], "").
generate_save_input_vars_code([InputVar - Num | NumberedInputVars], VarTypes,
- [InputVarArg | InputVarArgs],
- SaveInputVarCode ++ SaveInputVarCodes) :-
+ [InputVarArg | InputVarArgs], SaveInputVarCode ++ SaveInputVarCodes) :-
map__lookup(VarTypes, InputVar, Type),
InputVarName = "save_input" ++ int_to_string(Num),
InputVarArg = foreign_arg(InputVar, yes(InputVarName - in_mode), Type),
SaveInputVarCode = "\tMR_mm_save_input_arg(" ++
- int_to_string(Num) ++ ", " ++
- InputVarName ++ ");\n",
+ int_to_string(Num) ++ ", " ++ InputVarName ++ ");\n",
generate_save_input_vars_code(NumberedInputVars, VarTypes,
InputVarArgs, SaveInputVarCodes).
@@ -1693,8 +1641,7 @@
list__length(NumberedOutputVars, BlockSize),
generate_own_stack_save_goal(NumberedOutputVars, GeneratorVar,
- BlockSize, Context, !VarTypes, !VarSet, !TableInfo,
- SaveAnswerGoals),
+ BlockSize, Context, !VarTypes, !VarSet, !TableInfo, SaveAnswerGoals),
proc_info_goal(!.ProcInfo, OrigGoal),
GoalExpr = conj([OrigGoal | SaveAnswerGoals]),
@@ -1824,21 +1771,20 @@
% Generate a goal for doing lookups in call tables for
% loopcheck and memo predicates.
-:- pred generate_simple_call_table_lookup_goal((type)::in, string::in,
- assoc_list(prog_var, int)::in, pred_id::in, proc_id::in, bool::in,
- term__context::in, vartypes::in, vartypes::out,
+:- pred generate_simple_call_table_lookup_goal(call_table_strictness::in,
+ (type)::in, string::in, assoc_list(prog_var, int)::in, pred_id::in,
+ proc_id::in, bool::in, term__context::in, vartypes::in, vartypes::out,
prog_varset::in, prog_varset::out, table_info::in, table_info::out,
prog_var::out, prog_var::out, hlds_goal::out,
list(table_trie_step)::out) is det.
-generate_simple_call_table_lookup_goal(StatusType, SetupPred, NumberedVars,
- PredId, ProcId, TablingViaExtraArgs, Context,
- !VarTypes, !VarSet, !TableInfo, TableTipVar, StatusVar,
- Goal, Steps) :-
- generate_call_table_lookup_goals(NumberedVars, PredId, ProcId, Context,
- !VarTypes, !VarSet, !TableInfo, TableTipVar, LookupGoals,
- Steps, PredTableVar, LookupForeignArgs, LookupPrefixGoals,
- LookupCodeStr),
+generate_simple_call_table_lookup_goal(CallStrictness, StatusType, SetupPred,
+ NumberedVars, PredId, ProcId, TablingViaExtraArgs, Context,
+ !VarTypes, !VarSet, !TableInfo, TableTipVar, StatusVar, Goal, Steps) :-
+ generate_call_table_lookup_goals(CallStrictness, NumberedVars, PredId,
+ ProcId, Context, !VarTypes, !VarSet, !TableInfo, TableTipVar,
+ LookupGoals, Steps, PredTableVar, LookupForeignArgs,
+ LookupPrefixGoals, LookupCodeStr),
generate_new_table_var("Status", StatusType, !VarTypes, !VarSet,
StatusVar),
ModuleInfo = !.TableInfo ^ table_module_info,
@@ -1907,24 +1853,25 @@
% Generate a goal for doing lookups in call tables for
% model_non memo predicates.
-:- pred generate_memo_non_call_table_lookup_goal(assoc_list(prog_var, int)::in,
- pred_id::in, proc_id::in, term__context::in,
- vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
- table_info::in, table_info::out, prog_var::out, prog_var::out,
- hlds_goal::out, list(table_trie_step)::out) is det.
+:- pred generate_memo_non_call_table_lookup_goal(call_table_strictness::in,
+ assoc_list(prog_var, int)::in, pred_id::in, proc_id::in,
+ term__context::in, vartypes::in, vartypes::out, prog_varset::in,
+ prog_varset::out, table_info::in, table_info::out,
+ prog_var::out, prog_var::out, hlds_goal::out,
+ list(table_trie_step)::out) is det.
-generate_memo_non_call_table_lookup_goal(NumberedVars, PredId, ProcId, Context,
- !VarTypes, !VarSet, !TableInfo, RecordVar, StatusVar,
- Goal, Steps) :-
- generate_call_table_lookup_goals(NumberedVars, PredId, ProcId, Context,
- !VarTypes, !VarSet, !TableInfo, _TableTipVar, _LookupGoals,
- Steps, PredTableVar, LookupForeignArgs, LookupPrefixGoals,
- LookupCodeStr),
+generate_memo_non_call_table_lookup_goal(CallStrictness, NumberedVars,
+ PredId, ProcId, Context, !VarTypes, !VarSet, !TableInfo,
+ RecordVar, StatusVar, Goal, Steps) :-
+ generate_call_table_lookup_goals(CallStrictness, NumberedVars,
+ PredId, ProcId, Context, !VarTypes, !VarSet, !TableInfo,
+ _TableTipVar, _LookupGoals, Steps, PredTableVar,
+ LookupForeignArgs, LookupPrefixGoals, LookupCodeStr),
ModuleInfo = !.TableInfo ^ table_module_info,
- generate_new_table_var("Record", memo_non_record_type,
- !VarTypes, !VarSet, RecordVar),
- generate_new_table_var("Status", memo_non_status_type,
- !VarTypes, !VarSet, StatusVar),
+ generate_new_table_var("Record", memo_non_record_type, !VarTypes, !VarSet,
+ RecordVar),
+ generate_new_table_var("Status", memo_non_status_type, !VarTypes, !VarSet,
+ StatusVar),
SetupPred = "table_memo_non_setup",
BoundVars = [RecordVar, StatusVar],
PredTableVarName = pred_table_name,
@@ -1973,10 +1920,10 @@
generate_mm_call_table_lookup_goal(NumberedVars, PredId, ProcId,
TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo,
SubgoalVar, StatusVar, Goal, Steps) :-
- generate_call_table_lookup_goals(NumberedVars, PredId, ProcId, Context,
- !VarTypes, !VarSet, !TableInfo, TableTipVar, LookupGoals,
- Steps, PredTableVar, LookupForeignArgs, LookupPrefixGoals,
- LookupCodeStr),
+ generate_call_table_lookup_goals(strict, NumberedVars, PredId, ProcId,
+ Context, !VarTypes, !VarSet, !TableInfo, TableTipVar,
+ LookupGoals, Steps, PredTableVar, LookupForeignArgs,
+ LookupPrefixGoals, LookupCodeStr),
ModuleInfo = !.TableInfo ^ table_module_info,
generate_new_table_var("Subgoal", subgoal_type, !VarTypes, !VarSet,
SubgoalVar),
@@ -2016,8 +1963,7 @@
TablingViaExtraArgs = no,
generate_call(SetupPred, det,
[TableTipVar, SubgoalVar, StatusVar], impure_code,
- ground_vars(BoundVars), ModuleInfo, Context,
- SetupGoal0),
+ ground_vars(BoundVars), ModuleInfo, Context, SetupGoal0),
attach_call_table_tip(SetupGoal0, SetupGoal),
list__append(LookupGoals, [SetupGoal], LookupSetupGoals)
),
@@ -2032,22 +1978,23 @@
% Utility predicates used when creating call table lookup goals.
-:- pred generate_call_table_lookup_goals(assoc_list(prog_var, int)::in,
- pred_id::in, proc_id::in, term__context::in,
- vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
+:- pred generate_call_table_lookup_goals(call_table_strictness::in,
+ assoc_list(prog_var, int)::in, pred_id::in, proc_id::in,
+ term__context::in, vartypes::in, vartypes::out,
+ prog_varset::in, prog_varset::out,
table_info::in, table_info::out, prog_var::out,
list(hlds_goal)::out, list(table_trie_step)::out, prog_var::out,
list(foreign_arg)::out, list(hlds_goal)::out, string::out) is det.
-generate_call_table_lookup_goals(NumberedVars, PredId, ProcId, Context,
- !VarTypes, !VarSet, !TableInfo, TableTipVar, Goals, Steps,
- PredTableVar, ForeignArgs, PrefixGoals, CodeStr) :-
+generate_call_table_lookup_goals(CallStrictness, NumberedVars, PredId, ProcId,
+ Context, !VarTypes, !VarSet, !TableInfo, TableTipVar, Goals,
+ Steps, PredTableVar, ForeignArgs, PrefixGoals, CodeStr) :-
generate_get_table_goal(PredId, ProcId, !VarTypes, !VarSet,
PredTableVar, GetTableGoal),
- generate_table_lookup_goals(NumberedVars, "CallTableNode", Context,
- PredTableVar, TableTipVar, !VarTypes, !VarSet,
- !TableInfo, LookupGoals, Steps, ForeignArgs,
- LookupPrefixGoals, CodeStr),
+ generate_table_lookup_goals(NumberedVars, CallStrictness,
+ "CallTableNode", Context, PredTableVar, TableTipVar,
+ !VarTypes, !VarSet, !TableInfo, LookupGoals, Steps,
+ ForeignArgs, LookupPrefixGoals, CodeStr),
Goals = [GetTableGoal | LookupGoals],
PrefixGoals = [GetTableGoal | LookupPrefixGoals].
@@ -2057,8 +2004,8 @@
generate_get_table_goal(PredId, ProcId, !VarTypes, !VarSet, PredTableVar,
Goal) :-
- generate_new_table_var("PredTable", trie_node_type,
- !VarTypes, !VarSet, PredTableVar),
+ generate_new_table_var("PredTable", trie_node_type, !VarTypes, !VarSet,
+ PredTableVar),
ShroudedPredProcId = shroud_pred_proc_id(proc(PredId, ProcId)),
ConsId = tabling_pointer_const(ShroudedPredProcId),
make_const_construction(PredTableVar, ConsId, GoalExpr - GoalInfo0),
@@ -2078,39 +2025,41 @@
% The generated code is used for lookups in both call tables
% and answer tables.
-:- pred generate_table_lookup_goals(assoc_list(prog_var, int)::in, string::in,
+:- pred generate_table_lookup_goals(assoc_list(prog_var, int)::in,
+ call_table_strictness::in, string::in,
term__context::in, prog_var::in, prog_var::out,
vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
table_info::in, table_info::out, list(hlds_goal)::out,
list(table_trie_step)::out, list(foreign_arg)::out,
list(hlds_goal)::out, string::out) is det.
-generate_table_lookup_goals([], _, _, !TableVar, !VarTypes, !VarSet,
+generate_table_lookup_goals([], _, _, _, !TableVar, !VarTypes, !VarSet,
!TableInfo, [], [], [], [], "").
-generate_table_lookup_goals([Var - VarSeqNum | NumberedVars], Prefix, Context,
- !TableVar, !VarTypes, !VarSet, !TableInfo, Goals ++ RestGoals,
- [Step | Steps], ForeignArgs ++ RestForeignArgs,
- PrefixGoals ++ RestPrefixGoals, CodeStr ++ RestCodeStr) :-
+generate_table_lookup_goals([Var - VarSeqNum | NumberedVars], CallStrictness,
+ Prefix, Context, !TableVar, !VarTypes, !VarSet, !TableInfo,
+ Goals ++ RestGoals, [Step | Steps],
+ ForeignArgs ++ RestForeignArgs, PrefixGoals ++ RestPrefixGoals,
+ CodeStr ++ RestCodeStr) :-
ModuleInfo = !.TableInfo ^ table_module_info,
map__lookup(!.VarTypes, Var, VarType),
classify_type(ModuleInfo, VarType) = TypeCat,
- gen_lookup_call_for_type(TypeCat, VarType, Var, Prefix, VarSeqNum,
- Context, !VarTypes, !VarSet, !TableInfo, !TableVar,
+ gen_lookup_call_for_type(CallStrictness, TypeCat, VarType, Var, Prefix,
+ VarSeqNum, Context, !VarTypes, !VarSet, !TableInfo, !TableVar,
Goals, Step, ForeignArgs, PrefixGoals, CodeStr),
- generate_table_lookup_goals(NumberedVars, Prefix, Context,
- !TableVar, !VarTypes, !VarSet, !TableInfo, RestGoals, Steps,
- RestForeignArgs, RestPrefixGoals, RestCodeStr).
+ generate_table_lookup_goals(NumberedVars, CallStrictness, Prefix,
+ Context, !TableVar, !VarTypes, !VarSet, !TableInfo, RestGoals,
+ Steps, RestForeignArgs, RestPrefixGoals, RestCodeStr).
-:- pred gen_lookup_call_for_type(type_category::in, (type)::in,
- prog_var::in, string::in, int::in, term__context::in,
+:- pred gen_lookup_call_for_type(call_table_strictness::in, type_category::in,
+ (type)::in, prog_var::in, string::in, int::in, term__context::in,
vartypes::in, vartypes::out, prog_varset::in, prog_varset::out,
table_info::in, table_info::out, prog_var::in, prog_var::out,
list(hlds_goal)::out, table_trie_step::out,
list(foreign_arg)::out, list(hlds_goal)::out, string::out) is det.
-gen_lookup_call_for_type(TypeCat, Type, ArgVar, Prefix, VarSeqNum, Context,
- !VarTypes, !VarSet, !TableInfo, TableVar, NextTableVar,
- Goals, Step, ExtraArgs, PrefixGoals, CodeStr) :-
+gen_lookup_call_for_type(CallStrictness, TypeCat, Type, ArgVar, Prefix,
+ VarSeqNum, Context, !VarTypes, !VarSet, !TableInfo, TableVar,
+ NextTableVar, Goals, Step, ExtraArgs, PrefixGoals, CodeStr) :-
ModuleInfo = !.TableInfo ^ table_module_info,
VarName = Prefix ++ int_to_string(VarSeqNum),
generate_new_table_var(VarName, trie_node_type, !VarTypes, !VarSet,
@@ -2130,8 +2079,7 @@
->
list__length(Ctors, EnumRange)
;
- error("gen_lookup_call_for_type: " ++
- "enum type is not du_type?")
+ error("gen_lookup_call_for_type: enum type is not du_type?")
),
gen_int_construction("RangeVar", EnumRange, !VarTypes,
!VarSet, RangeVar, RangeUnifyGoal),
@@ -2156,19 +2104,35 @@
lookup_tabling_category(TypeCat, MaybeCatStringStep),
(
MaybeCatStringStep = no,
- ( prog_type__vars(Type, []) ->
+ prog_type__vars(Type, TypeVars),
+ (
+ CallStrictness = strict,
+ (
+ TypeVars = [],
LookupPredName = "table_lookup_insert_user",
Step = table_trie_step_user(Type)
;
+ TypeVars = [_ | _],
LookupPredName = "table_lookup_insert_poly",
Step = table_trie_step_poly
+ )
+ ;
+ CallStrictness = fast_loose,
+ (
+ TypeVars = [],
+ LookupPredName = "table_lookup_insert_user_fast_loose",
+ Step = table_trie_step_user_fast_loose(Type)
+ ;
+ TypeVars = [_ | _],
+ LookupPredName = "table_lookup_insert_poly_fast_loose",
+ Step = table_trie_step_poly_fast_loose
+ )
),
make_type_info_var(Type, Context, !VarTypes, !VarSet,
!TableInfo, TypeInfoVar, ExtraGoals),
generate_call(LookupPredName, det,
[TypeInfoVar, TableVar, ArgVar, NextTableVar],
- impure_code, BindNextTableVar,
- ModuleInfo, Context, CallGoal),
+ impure_code, BindNextTableVar, ModuleInfo, Context, CallGoal),
Goals = ExtraGoals ++ [CallGoal],
PrefixGoals = ExtraGoals,
TypeInfoArgName = "input_typeinfo" ++
@@ -2178,24 +2142,20 @@
yes(TypeInfoArgName - in_mode), TypeInfoType),
ExtraArgs = [ForeignTypeInfoArg, ForeignArg],
CodeStr0 = "\tMR_" ++ LookupPredName ++ "(" ++
- cur_table_node_name ++ ", " ++
- TypeInfoArgName ++ ", " ++
- ArgName ++ ", " ++
- next_table_node_name ++ ");\n"
+ cur_table_node_name ++ ", " ++ TypeInfoArgName ++ ", " ++
+ ArgName ++ ", " ++ next_table_node_name ++ ");\n"
;
MaybeCatStringStep = yes(CatString - Step),
string__append("table_lookup_insert_", CatString,
LookupPredName),
generate_call(LookupPredName, det,
[TableVar, ArgVar, NextTableVar],
- impure_code, BindNextTableVar, ModuleInfo,
- Context, Goal),
+ impure_code, BindNextTableVar, ModuleInfo, Context, Goal),
Goals = [Goal],
PrefixGoals = [],
ExtraArgs = [ForeignArg],
CodeStr0 = "\tMR_" ++ LookupPredName ++ "(" ++
- cur_table_node_name ++ ", " ++
- ArgName ++ ", " ++
+ cur_table_node_name ++ ", " ++ ArgName ++ ", " ++
next_table_node_name ++ ");\n"
)
),
@@ -2213,8 +2173,7 @@
table_info::in, table_info::out, list(hlds_goal)::out) is det.
generate_memo_save_goals(NumberedSaveVars, TableTipVar, BlockSize,
- TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo,
- Goals) :-
+ TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo, Goals) :-
ModuleInfo = !.TableInfo ^ table_module_info,
( BlockSize > 0 ->
CreatePredName = "table_memo_create_answer_block",
@@ -2228,8 +2187,7 @@
(
TablingViaExtraArgs = yes,
TableArg = foreign_arg(TableTipVar,
- yes(cur_table_node_name - in_mode),
- trie_node_type),
+ yes(cur_table_node_name - in_mode), trie_node_type),
MarkAsSucceededCode = "MR_" ++ MarkAsSucceededPred ++
"(" ++ cur_table_node_name ++ ");",
generate_foreign_proc(MarkAsSucceededPred, det,
@@ -2270,8 +2228,8 @@
[RecordArg, AnswerTableArg], [], "", GetPredCode, "",
semipure_code, ground_vars([AnswerTableVar]),
ModuleInfo, Context, GetAnswerTableGoal),
- generate_table_lookup_goals(NumberedSaveVars, "AnswerTableNode",
- Context, AnswerTableVar, _AnswerTableTipVar,
+ generate_table_lookup_goals(NumberedSaveVars, strict,
+ "AnswerTableNode", Context, AnswerTableVar, _AnswerTableTipVar,
!VarTypes, !VarSet, !TableInfo, _LookupAnswerGoals, _,
LookupForeignArgs, LookupPrefixGoals, LookupCodeStr),
@@ -2323,8 +2281,7 @@
table_info::in, table_info::out, list(hlds_goal)::out) is det.
generate_mm_save_goals(NumberedSaveVars, SubgoalVar, BlockSize,
- TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo,
- Goals) :-
+ TablingViaExtraArgs, Context, !VarTypes, !VarSet, !TableInfo, Goals) :-
ModuleInfo = !.TableInfo ^ table_module_info,
generate_new_table_var("AnswerTableVar", trie_node_type,
!VarTypes, !VarSet, AnswerTableVar),
@@ -2332,10 +2289,10 @@
generate_call(GetPredName, det, [SubgoalVar, AnswerTableVar],
semipure_code, ground_vars([AnswerTableVar]),
ModuleInfo, Context, GetAnswerTableGoal),
- generate_table_lookup_goals(NumberedSaveVars, "AnswerTableNode",
- Context, AnswerTableVar, AnswerTableTipVar, !VarTypes, !VarSet,
- !TableInfo, LookupAnswerGoals, _, LookupForeignArgs,
- LookupPrefixGoals, LookupCodeStr),
+ generate_table_lookup_goals(NumberedSaveVars, strict,
+ "AnswerTableNode", Context, AnswerTableVar, AnswerTableTipVar,
+ !VarTypes, !VarSet, !TableInfo, LookupAnswerGoals, _,
+ LookupForeignArgs, LookupPrefixGoals, LookupCodeStr),
CreatePredName = "table_mm_create_answer_block",
ShortcutCreatePredName = "table_mm_fill_answer_block_shortcut",
@@ -2375,13 +2332,11 @@
tabling_c_attributes, Args, LookupForeignArgs,
PreStr, DuplCheckCodeStr, PostStr, impure_code, [],
ModuleInfo, Context, DuplicateCheckSaveGoal),
- list__append(LookupPrefixGoals, [DuplicateCheckSaveGoal],
- Goals)
+ list__append(LookupPrefixGoals, [DuplicateCheckSaveGoal], Goals)
;
TablingViaExtraArgs = no,
generate_call(DuplCheckPredName, semidet, [AnswerTableTipVar],
- impure_code, [], ModuleInfo, Context,
- DuplicateCheckGoal),
+ impure_code, [], ModuleInfo, Context, DuplicateCheckGoal),
list__append([GetAnswerTableGoal | LookupAnswerGoals],
[DuplicateCheckGoal], LookupCheckGoals),
list__append(LookupCheckGoals, SaveGoals, Goals)
@@ -2410,11 +2365,9 @@
TableArg = foreign_arg(BaseVar, yes(BaseVarName - in_mode),
BaseVarType),
Args = [TableArg],
- SaveDeclCodeStr = "\tMR_AnswerBlock " ++
- answer_block_name ++ ";\n",
+ SaveDeclCodeStr = "\tMR_AnswerBlock " ++ answer_block_name ++ ";\n",
CreateCodeStr = "\tMR_" ++ CreatePredName ++ "(" ++
- BaseVarName ++ ", " ++
- int_to_string(BlockSize) ++ ", " ++
+ BaseVarName ++ ", " ++ int_to_string(BlockSize) ++ ", " ++
answer_block_name ++ ");\n",
CreateSaveCodeStr = CreateCodeStr ++ SaveCodeStr,
ShortcutStr = "\tMR_" ++ ShortcutPredName ++ "(" ++
@@ -2432,8 +2385,7 @@
[BaseVar, BlockSizeVar, AnswerBlockVar],
impure_code, ground_vars([AnswerBlockVar]),
ModuleInfo, Context, CreateAnswerBlockGoal),
- Goals = [BlockSizeVarUnifyGoal, CreateAnswerBlockGoal |
- SaveGoals],
+ Goals = [BlockSizeVarUnifyGoal, CreateAnswerBlockGoal | SaveGoals],
SaveDeclCodeStr = "",
CreateSaveCodeStr = ""
).
@@ -2459,9 +2411,9 @@
GetAnswerTableGoal),
% assoc_list__keys(NumberedOutputVars, OutputVars),
% XXX use foreign_proc
- generate_table_lookup_goals(NumberedOutputVars, "AnswerTableNode",
- Context, AnswerTableVar, AnswerTableTipVar, !VarTypes, !VarSet,
- !TableInfo, LookupAnswerGoals, _, _, _, _),
+ generate_table_lookup_goals(NumberedOutputVars, strict,
+ "AnswerTableNode", Context, AnswerTableVar, AnswerTableTipVar,
+ !VarTypes, !VarSet, !TableInfo, LookupAnswerGoals, _, _, _, _),
generate_call("table_nondet_answer_is_not_duplicate", semidet,
[AnswerTableTipVar], impure_code,
[], ModuleInfo, Context, DuplicateCheckGoal),
@@ -2527,8 +2479,7 @@
PrefixGoals = [],
CodeStr = "\tMR_" ++ SavePredName ++ "(" ++
answer_block_name ++ ", " ++
- int_to_string(Offset) ++ ", " ++
- Name ++ ");\n"
+ int_to_string(Offset) ++ ", " ++ Name ++ ");\n"
; builtin_type(TypeCat) = no ->
% If used ForeignArg instead of GenericForeignArg, then
% Var would be unboxed when assigned to Name, which we
@@ -2549,10 +2500,8 @@
Args = [GenericForeignArg, TypeInfoForeignArg],
PrefixGoals = ExtraGoals,
CodeStr = "\tMR_" ++ SavePredName ++ "(" ++
- answer_block_name ++ ", " ++
- int_to_string(Offset) ++ ", " ++
- TypeInfoName ++ ", " ++
- Name ++ ");\n"
+ answer_block_name ++ ", " ++ int_to_string(Offset) ++ ", " ++
+ TypeInfoName ++ ", " ++ Name ++ ");\n"
;
type_save_category(TypeCat, CatString),
string__append_list(["table_save_", CatString, "_answer"],
@@ -2563,8 +2512,7 @@
Args = [ForeignArg],
PrefixGoals = [],
CodeStr = "\tMR_" ++ SavePredName ++ "(" ++
- answer_block_name ++ ", " ++
- int_to_string(Offset) ++ ", " ++
+ answer_block_name ++ ", " ++ int_to_string(Offset) ++ ", " ++
Name ++ ");\n"
).
@@ -2814,10 +2762,8 @@
error("gen_restore_call_for_type: no inst")
),
Arg = foreign_arg(Var, yes(Name - (free -> Inst)), ArgType),
- CodeStr = "\tMR_" ++ RestorePredName ++ "(" ++
- answer_block_name ++ ", " ++
- int_to_string(Offset) ++ ", " ++
- Name ++ ");\n",
+ CodeStr = "\tMR_" ++ RestorePredName ++ "(" ++ answer_block_name ++ ", " ++
+ int_to_string(Offset) ++ ", " ++ Name ++ ");\n",
generate_call(RestorePredName, det, [TableVar, OffsetVar, Var],
semipure_code, [Var - Inst], ModuleInfo, Context, Goal).
@@ -2844,8 +2790,7 @@
Arity = pred_info_orig_arity(PredInfo),
PredOrFunc = pred_info_is_pred_or_func(PredInfo),
PredOrFuncStr = pred_or_func_to_str(PredOrFunc),
- mdbcomp__prim_data__sym_name_to_string(qualified(Module, Name),
- NameStr),
+ sym_name_to_string(qualified(Module, Name), NameStr),
string__int_to_string(Arity, ArityStr),
string__append_list([Msg, " in ", PredOrFuncStr, " ", NameStr,
"/", ArityStr], Message),
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.316
diff -u -b -r1.316 reference_manual.texi
--- doc/reference_manual.texi 26 Apr 2005 07:38:01 -0000 1.316
+++ doc/reference_manual.texi 20 May 2005 06:33:43 -0000
@@ -8856,6 +8856,13 @@
does no loop checking, @samp{pragma loop_check} checks for loops
and throws an exception if a loop is detected, while
@samp{pragma minimal_model} computes the ``minimal model'' semantics.
+ at samp{pragma fast_loose_memo} is a variant of @samp{pragma memo}.
+While @samp{memo} tabling requires time proportional to the size of
+the input arguments to look up the current call in its table,
+ at samp{fast_loose_memo} requires constant time.
+The tradeoff is that @samp{fast_loose_memo} does not recognize
+calls as duplicates if they involve input argumens that are logically equal
+but are stored at different locations in memory.
@c XXX we should fix this bug...
@cartouche
@@ -8872,6 +8879,7 @@
@example
:- pragma memo(@var{Name}/@var{Arity}).
+:- pragma fast_loose_memo(@var{Name}/@var{Arity}).
:- pragma loop_check(@var{Name}/@var{Arity}).
:- pragma minimal_model(@var{Name}/@var{Arity}).
@end example
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/table_builtin.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/table_builtin.m,v
retrieving revision 1.42
diff -u -b -r1.42 table_builtin.m
--- library/table_builtin.m 16 Aug 2004 03:51:06 -0000 1.42
+++ library/table_builtin.m 8 Apr 2005 05:58:18 -0000
@@ -1110,10 +1110,24 @@
:- impure pred table_lookup_insert_user(ml_trie_node::in, T::in,
ml_trie_node::out) is det.
+ % Lookup or insert a monomorphic user defined type in the given trie,
+ % tabling terms without traversing them. This makes the operation fast,
+ % but if a term was inserted previously, we will catch it only if the
+ % insert was the exact same memory cells. (This is the "loose" part.)
+:- impure pred table_lookup_insert_user_fast_loose(ml_trie_node::in, T::in,
+ ml_trie_node::out) is det.
+
% Lookup or insert a polymorphic user defined type in the given trie.
:- impure pred table_lookup_insert_poly(ml_trie_node::in, T::in,
ml_trie_node::out) is det.
+ % Lookup or insert a polymorphic user defined type in the given trie,
+ % tabling terms without traversing them. This makes the operation fast,
+ % but if a term was inserted previously, we will catch it only if the
+ % insert was the exact same memory cells. (This is the "loose" part.)
+:- impure pred table_lookup_insert_poly_fast_loose(ml_trie_node::in, T::in,
+ ml_trie_node::out) is det.
+
% Lookup or insert a type_info in the given trie.
:- impure pred table_lookup_insert_typeinfo(ml_trie_node::in,
private_builtin.type_info(T)::in, ml_trie_node::out) is det.
@@ -1253,10 +1267,24 @@
").
:- pragma foreign_proc("C",
+ table_lookup_insert_user_fast_loose(T0::in, V::in, T::out),
+ [will_not_call_mercury],
+"
+ MR_table_lookup_insert_user_fast_loose(T0, TypeInfo_for_T, V, T);
+").
+
+:- pragma foreign_proc("C",
table_lookup_insert_poly(T0::in, V::in, T::out),
[will_not_call_mercury],
"
- MR_table_lookup_insert_user(T0, TypeInfo_for_T, V, T);
+ MR_table_lookup_insert_poly(T0, TypeInfo_for_T, V, T);
+").
+
+:- pragma foreign_proc("C",
+ table_lookup_insert_poly_fast_loose(T0::in, V::in, T::out),
+ [will_not_call_mercury],
+"
+ MR_table_lookup_insert_poly_fast_loose(T0, TypeInfo_for_T, V, T);
").
:- pragma foreign_proc("C",
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.89
diff -u -b -r1.89 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h 14 Apr 2005 02:35:01 -0000 1.89
+++ runtime/mercury_stack_layout.h 20 May 2005 02:32:44 -0000
@@ -627,7 +627,9 @@
MR_TABLE_STEP_FLOAT,
MR_TABLE_STEP_ENUM,
MR_TABLE_STEP_USER,
+ MR_TABLE_STEP_USER_FAST_LOOSE,
MR_TABLE_STEP_POLY,
+ MR_TABLE_STEP_POLY_FAST_LOOSE,
MR_TABLE_STEP_TYPEINFO,
MR_TABLE_STEP_TYPECLASSINFO
} MR_Table_Trie_Step;
@@ -771,7 +773,8 @@
typedef enum {
MR_EVAL_METHOD_NORMAL,
MR_EVAL_METHOD_LOOP_CHECK,
- MR_EVAL_METHOD_MEMO,
+ MR_EVAL_METHOD_MEMO_STRICT,
+ MR_EVAL_METHOD_MEMO_FAST_LOOSE,
MR_EVAL_METHOD_MINIMAL_STACK_COPY,
MR_EVAL_METHOD_MINIMAL_OWN_STACKS,
MR_EVAL_METHOD_TABLE_IO,
Index: runtime/mercury_tabling.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling.c,v
retrieving revision 1.66
diff -u -b -r1.66 mercury_tabling.c
--- runtime/mercury_tabling.c 14 Dec 2004 01:07:24 -0000 1.66
+++ runtime/mercury_tabling.c 20 May 2005 05:43:32 -0000
@@ -37,6 +37,7 @@
typedef struct MR_IntHashTableSlot_Struct MR_IntHashTableSlot;
typedef struct MR_FloatHashTableSlot_Struct MR_FloatHashTableSlot;
typedef struct MR_StringHashTableSlot_Struct MR_StringHashTableSlot;
+typedef struct MR_WordHashTableSlot_Struct MR_WordHashTableSlot;
typedef struct MR_AllocRecord_Struct MR_AllocRecord;
@@ -58,10 +59,17 @@
MR_ConstString key;
};
+struct MR_WordHashTableSlot_Struct {
+ MR_WordHashTableSlot *next;
+ MR_TableNode data;
+ MR_Word key;
+};
+
typedef union {
MR_IntHashTableSlot *int_slot_ptr;
MR_FloatHashTableSlot *float_slot_ptr;
MR_StringHashTableSlot *string_slot_ptr;
+ MR_WordHashTableSlot *word_slot_ptr;
} MR_HashTableSlotPtr;
struct MR_AllocRecord_Struct {
@@ -455,6 +463,46 @@
#undef lookup_only
}
+MR_TrieNode
+MR_word_hash_lookup_or_add(MR_TrieNode t, MR_Word key)
+{
+#define key_format "%p"
+#define key_cast (MR_Word)
+#define table_type MR_WordHashTableSlot
+#define table_field word_slot_ptr
+#define hash(key) ((long) (key))
+#define equal_keys(k1, k2) ((k1) == (k2))
+#define lookup_only MR_FALSE
+#include "mercury_hash_lookup_or_add_body.h"
+#undef key_format
+#undef key_cast
+#undef table_type
+#undef table_field
+#undef hash
+#undef equal_keys
+#undef lookup_only
+}
+
+MR_TrieNode
+MR_ptr_hash_lookup(MR_TrieNode t, MR_Word key)
+{
+#define key_format "%p"
+#define key_cast (MR_Word)
+#define table_type MR_WordHashTableSlot
+#define table_field word_slot_ptr
+#define hash(key) ((long) (key))
+#define equal_keys(k1, k2) ((k1) == (k2))
+#define lookup_only MR_TRUE
+#include "mercury_hash_lookup_or_add_body.h"
+#undef key_format
+#undef key_cast
+#undef table_type
+#undef table_field
+#undef hash
+#undef equal_keys
+#undef lookup_only
+}
+
static int
MR_cmp_ints(const void *p1, const void *p2)
{
@@ -717,8 +765,6 @@
/*
** This part defines the MR_table_type() function.
-**
-** Due to the depth of the control here, we'll use 4 space indentation.
**
** NOTE: changes to this function will probably also have to be reflected
** in the places listed in mercury_type_info.h.
Index: runtime/mercury_tabling.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling.h,v
retrieving revision 1.36
diff -u -b -r1.36 mercury_tabling.h
--- runtime/mercury_tabling.h 15 Feb 2005 05:22:32 -0000 1.36
+++ runtime/mercury_tabling.h 20 May 2005 05:41:03 -0000
@@ -191,6 +191,8 @@
MR_Float key);
extern MR_TrieNode MR_string_hash_lookup_or_add(MR_TrieNode table,
MR_ConstString key);
+extern MR_TrieNode MR_word_hash_lookup_or_add(MR_TrieNode table,
+ MR_Word key);
/*
** This function assumes that the table is a statically sized array,
@@ -224,7 +226,10 @@
/*
** This function tables values of arbitrary types; the form of the data
-** structure depends on the actual type of the value.
+** structure depends on the actual type of the value. The tabling is done
+** by tabling all the function symbols of the value; unlike
+** MR_word_hash_lookup, this function *does* guarantee that all duplicates
+** will be detected.
*/
extern MR_TrieNode MR_table_type(MR_TrieNode table,
@@ -244,6 +249,8 @@
MR_Float key);
extern MR_TrieNode MR_string_hash_lookup(MR_TrieNode table,
MR_ConstString key);
+extern MR_TrieNode MR_word_hash_lookup(MR_TrieNode table,
+ MR_Word data_value);
/*
** These functions return a dynamically resizable array (using the primitives
Index: runtime/mercury_tabling_macros.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling_macros.h,v
retrieving revision 1.11
diff -u -b -r1.11 mercury_tabling_macros.h
--- runtime/mercury_tabling_macros.h 20 Jul 2004 04:41:25 -0000 1.11
+++ runtime/mercury_tabling_macros.h 20 May 2005 05:44:36 -0000
@@ -19,6 +19,9 @@
#define MR_RAW_TABLE_ANY(table, type_info, value) \
MR_table_type((table), (type_info), (value))
+#define MR_RAW_TABLE_ANY_FAST_LOOSE(table, type_info, value) \
+ MR_word_hash_lookup_or_add((table), (value))
+
#define MR_RAW_TABLE_TAG(table, tag) \
MR_int_fix_index_lookup_or_add((table), 1 << MR_TAGBITS, (tag))
@@ -72,6 +75,27 @@
} \
} while (0)
+#define MR_DEBUG_NEW_TABLE_ANY_FAST_LOOSE(table, table0, type_info, value) \
+ do { \
+ (table) = MR_RAW_TABLE_ANY_FAST_LOOSE((table0), (type_info), \
+ (value)); \
+ if (MR_tabledebug) { \
+ printf("TABLE %p: any %x type %p => %p\n", \
+ (table0), (value), (type_info), (table));\
+ } \
+ } while (0)
+#define MR_DEBUG_TABLE_ANY_FAST_LOOSE(table, type_info, value) \
+ do { \
+ MR_TrieNode prev_table = (table); \
+ (table) = MR_RAW_TABLE_ANY_FAST_LOOSE((table), \
+ (type_info), (value)); \
+ if (MR_tabledebug) { \
+ printf("TABLE %p: any %x type %p => %p\n", \
+ prev_table, (value), (type_info), \
+ (table)); \
+ } \
+ } while (0)
+
#define MR_DEBUG_NEW_TABLE_TAG(table, table0, value) \
do { \
(table) = MR_RAW_TABLE_TAG((table0), (value)); \
@@ -263,6 +287,17 @@
#define MR_DEBUG_TABLE_ANY(table, type_info, value) \
do { \
(table) = MR_RAW_TABLE_ANY((table), (type_info), (value));\
+ } while (0)
+
+#define MR_DEBUG_NEW_TABLE_ANY_FAST_LOOSE(table, table0, type_info, value) \
+ do { \
+ (table) = MR_RAW_TABLE_ANY_FAST_LOOSE((table0), (type_info), \
+ (value)); \
+ } while (0)
+#define MR_DEBUG_TABLE_ANY_FAST_LOOSE(table, type_info, value) \
+ do { \
+ (table) = MR_RAW_TABLE_ANY_FAST_LOOSE((table), (type_info), \
+ (value)); \
} while (0)
#define MR_DEBUG_NEW_TABLE_TAG(table, table0, value) \
Index: runtime/mercury_tabling_preds.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_tabling_preds.h,v
retrieving revision 1.4
diff -u -b -r1.4 mercury_tabling_preds.h
--- runtime/mercury_tabling_preds.h 16 Aug 2004 03:51:09 -0000 1.4
+++ runtime/mercury_tabling_preds.h 8 Apr 2005 05:47:33 -0000
@@ -56,11 +56,21 @@
MR_DEBUG_NEW_TABLE_ANY(T, T0, (MR_TypeInfo) TI, V); \
} while(0)
+#define MR_table_lookup_insert_user_fast_loose(T0, TI, V, T) \
+ do { \
+ MR_DEBUG_NEW_TABLE_ANY_FAST_LOOSE(T, T0, (MR_TypeInfo) TI, V); \
+ } while(0)
+
#define MR_table_lookup_insert_poly(T0, TI, V, T) \
do { \
MR_DEBUG_NEW_TABLE_ANY(T, T0, (MR_TypeInfo) TI, V); \
} while(0)
+#define MR_table_lookup_insert_poly_fast_loose(T0, TI, V, T) \
+ do { \
+ MR_DEBUG_NEW_TABLE_ANY_FAST_LOOSE(T, T0, (MR_TypeInfo) TI, V); \
+ } while(0)
+
#define MR_table_lookup_insert_typeinfo(T0, TI, T) \
do { \
MR_DEBUG_NEW_TABLE_TYPEINFO(T, T0, (MR_TypeInfo) TI); \
@@ -549,8 +559,7 @@
Start = MR_io_tabling_start; \
if (MR_io_tabling_counter > MR_io_tabling_counter_hwm) \
{ \
- MR_io_tabling_counter_hwm = \
- MR_io_tabling_counter; \
+ MR_io_tabling_counter_hwm = MR_io_tabling_counter; \
} \
\
MR_table_io_in_range_in_range_msg; \
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
Index: tests/tabling/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/Mmakefile,v
retrieving revision 1.35
diff -u -b -r1.35 Mmakefile
--- tests/tabling/Mmakefile 10 Jan 2005 05:30:25 -0000 1.35
+++ tests/tabling/Mmakefile 20 May 2005 05:39:48 -0000
@@ -10,6 +10,7 @@
expand_float \
expand_poly \
expand_tuple \
+ fast_loose \
fib \
fib_float \
fib_list \
Index: tests/tabling/fast_loose.exp
===================================================================
RCS file: tests/tabling/fast_loose.exp
diff -N tests/tabling/fast_loose.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/fast_loose.exp 20 May 2005 05:25:48 -0000
@@ -0,0 +1 @@
+fast_loose works
Index: tests/tabling/fast_loose.m
===================================================================
RCS file: tests/tabling/fast_loose.m
diff -N tests/tabling/fast_loose.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/tabling/fast_loose.m 20 May 2005 05:26:04 -0000
@@ -0,0 +1,87 @@
+:- module fast_loose.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+
+:- import_module benchmarking.
+:- import_module int.
+:- import_module list.
+:- import_module require.
+
+main(!IO) :-
+ perform_trials(80, !IO).
+
+:- pred perform_trials(int::in, io::di, io::uo) is cc_multi.
+
+perform_trials(N, !IO) :-
+ trial(N, STime, FLTime),
+ % io__write_int(N, !IO),
+ % io__write_string(": ", !IO),
+ % io__write_int(STime, !IO),
+ % io__write_string("ms vs ", !IO),
+ % io__write_int(FLTime, !IO),
+ % io__write_string("ms\n", !IO),
+ (
+ (
+ STime > 10 * FLTime,
+ FLTime > 0 % strict takes ten times as long
+ ;
+ STime > 100, % strict takes at least 100 ms
+ FLTime < 1 % while fast_loose takes at most 1 ms
+ )
+ ->
+ io__write_string("fast_loose works\n", !IO)
+ ;
+ STime > 10000 % Strict takes at least 10 seconds
+ ->
+ io__write_string("fast_loose does not appear to work\n", !IO)
+ ;
+ % We couldn't get a measurable result with N,
+ % and it looks like we can afford a bigger trial.
+ perform_trials(N+5, !IO)
+ ).
+
+:- pred trial(int::in, int::out, int::out) is cc_multi.
+
+trial(N, STime, FLTime) :-
+ benchmark_det(strict, N, SRes, 1, STime),
+ benchmark_det(fast_loose, N, FLRes, 1, FLTime),
+ require(unify(SRes, FLRes), "tabling produces wrong answer").
+
+:- pred strict(int::in, int::out) is det.
+
+strict(N, R) :-
+ strict_sum(iota(N), R).
+
+:- pred strict_sum(list(int)::in, int::out) is det.
+:- pragma memo(strict_sum/2).
+
+strict_sum([], 0).
+strict_sum([H | T], H + TS) :-
+ strict_sum(T, TS).
+
+:- pred fast_loose(int::in, int::out) is det.
+
+fast_loose(N, R) :-
+ fast_loose_sum(iota(N), R).
+
+:- pred fast_loose_sum(list(int)::in, int::out) is det.
+:- pragma fast_loose_memo(fast_loose_sum/2).
+
+fast_loose_sum([], 0).
+fast_loose_sum([H | T], H + TS) :-
+ fast_loose_sum(T, TS).
+
+:- func iota(int) = list(int).
+
+iota(N) =
+ ( N =< 0 ->
+ []
+ ;
+ [N | iota(N - 1)]
+ ).
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.81
diff -u -b -r1.81 mercury_trace.c
--- trace/mercury_trace.c 13 May 2005 13:45:32 -0000 1.81
+++ trace/mercury_trace.c 20 May 2005 02:25:33 -0000
@@ -1451,13 +1451,17 @@
/* nothing to do */
return;
- case MR_EVAL_METHOD_MEMO:
+ case MR_EVAL_METHOD_MEMO_STRICT:
+ case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
case MR_EVAL_METHOD_LOOP_CHECK:
if (MR_DETISM_DET_STACK(level_layout->MR_sle_detism)) {
call_table = (MR_TrieNode) MR_based_stackvar(base_sp,
level_layout->MR_sle_maybe_call_table);
} else {
- if (eval_method == MR_EVAL_METHOD_MEMO) {
+ if (eval_method == MR_EVAL_METHOD_LOOP_CHECK) {
+ call_table = (MR_TrieNode) MR_based_framevar(base_curfr,
+ level_layout->MR_sle_maybe_call_table);
+ } else {
MR_MemoNonRecordPtr record;
record = (MR_MemoNonRecordPtr) MR_based_framevar(base_curfr,
@@ -1468,9 +1472,6 @@
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);
}
}
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.204
diff -u -b -r1.204 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 20 May 2005 05:40:37 -0000 1.204
+++ trace/mercury_trace_internal.c 20 May 2005 06:15:57 -0000
@@ -4451,7 +4451,8 @@
return KEEP_INTERACTING;
case MR_EVAL_METHOD_LOOP_CHECK:
- case MR_EVAL_METHOD_MEMO:
+ case MR_EVAL_METHOD_MEMO_STRICT:
+ case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
break;
@@ -4574,7 +4575,8 @@
fprintf(MR_mdb_out, ":\n");
break;
- case MR_EVAL_METHOD_MEMO:
+ case MR_EVAL_METHOD_MEMO_STRICT:
+ case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
fprintf(MR_mdb_out, "memo table for ");
MR_print_proc_id(MR_mdb_out, proc);
fprintf(MR_mdb_out, ":\n");
@@ -4980,7 +4982,9 @@
fprintf(MR_mdb_out, ">: ");
eval_method = MR_sle_eval_method(proc);
- if (eval_method == MR_EVAL_METHOD_MINIMAL_STACK_COPY) {
+ switch (eval_method) {
+ case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
+ {
MR_Subgoal *subgoal;
int subgoal_num;
@@ -4991,7 +4995,11 @@
} else {
MR_trace_print_subgoal(proc, subgoal);
}
- } else if (eval_method == MR_EVAL_METHOD_MINIMAL_OWN_STACKS) {
+ }
+ break;
+
+ case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
+ {
MR_Consumer *consumer;
fprintf(MR_mdb_out, "trie node %p\n", table);
@@ -5001,7 +5009,12 @@
} else {
MR_trace_print_consumer(proc, consumer);
}
- } else if (eval_method == MR_EVAL_METHOD_MEMO) {
+ }
+ break;
+
+ case MR_EVAL_METHOD_MEMO_STRICT:
+ case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
+ {
MR_Determinism detism;
detism = proc->MR_sle_detism;
@@ -5013,10 +5026,20 @@
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) {
+ }
+ break;
+
+ case MR_EVAL_METHOD_LOOP_CHECK:
MR_print_loopcheck_tip(MR_mdb_out, proc, table);
- } else {
+ break;
+
+ case MR_EVAL_METHOD_NORMAL:
+ case MR_EVAL_METHOD_TABLE_IO:
+ case MR_EVAL_METHOD_TABLE_IO_DECL:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
MR_fatal_error("MR_trace_cmd_table_print_tip: bad eval method");
+ break;
}
}
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