[m-dev.] Re: pragma fact_table
David Matthew OVERTON
dmo at students.cs.mu.oz.au
Thu Feb 27 13:54:29 AEDT 1997
Fergus Henderson wrote:
>
> Can I please see another diff for fact_table.m relative to the version
> as at this diff, and another diff for modules.m?
>
Hi again Fergus,
Here's the latest diff for fact_table.m and modules.m. As well as the
changes you suggested, I fixed a couple of bugs that I noticed in
fact_tables.m.
David
--- ../bak/fact_table.m Wed Feb 26 18:24:32 1997
+++ compiler/fact_table.m Thu Feb 27 13:21:40 1997
@@ -2128,7 +2128,8 @@
;
Key = term__integer(Int)
->
- Ns = [Int]
+ int__abs(Int, N),
+ Ns = [N]
;
Key = term__float(Float)
->
@@ -2135,7 +2136,8 @@
% XXX This method of hashing floats may not work cross-compiling
% between architectures that have different floating-point
% representations.
- float__hash(Float, N),
+ float__hash(Float, N0),
+ int__abs(N0, N),
Ns = [N]
;
error("fact_table_hash: unsupported type in key")
@@ -2450,7 +2452,7 @@
Determinism = semidet
->
generate_all_in_code(Identifier, PragmaVars, ProcID,
- ArgTypes, ModuleInfo, ProcCode),
+ ArgTypes, ModuleInfo, FactTableSize, ProcCode),
ExtraCode = ""
;
ModeType = in_out,
@@ -2511,7 +2513,7 @@
{
/* declare argument vars */
%s
- Word ind = framevar(0);
+ Word ind = framevar(0), tmp;
/* lookup fact table */
%s
/* save output args to registers */
@@ -2623,7 +2625,7 @@
generate_cc_multi_code_2([], _, _, ProcCode, ProcCode).
generate_cc_multi_code_2([pragma_var(_, VarName, _)|PragmaVars], StructName,
ArgNum, ProcCode0, ProcCode) :-
- string__format("%s = %s[0][0].V_%d\n", [s(VarName), s(StructName),
+ string__format("\t\t%s = %s[0][0].V_%d;\n", [s(VarName), s(StructName),
i(ArgNum)], ProcCode1),
string__append(ProcCode1, ProcCode0, ProcCode2),
NextArgNum is ArgNum + 1,
@@ -2634,16 +2636,16 @@
% generate semidet code for all_in mode
:- pred generate_all_in_code(string, list(pragma_var), proc_id, list(type),
- module_info, string).
-:- mode generate_all_in_code(in, in, in, in, in, out) is det.
+ module_info, int, string).
+:- mode generate_all_in_code(in, in, in, in, in, in, out) is det.
generate_all_in_code(PredName, PragmaVars, ProcID, ArgTypes, ModuleInfo,
- ProcCode) :-
+ FactTableSize, ProcCode) :-
generate_decl_code(PredName, ProcID, DeclCode),
string__format("%s_%d", [s(PredName), i(ProcID)], LabelName),
generate_hash_code(PragmaVars, ArgTypes, ModuleInfo, LabelName, 0,
- HashCode),
+ PredName, 1, FactTableSize, HashCode),
SuccessCodeTemplate = "
success_code_%s:
@@ -2674,12 +2676,11 @@
string__format("%s_%d", [s(PredName), i(ProcID)], LabelName),
generate_hash_code(PragmaVars, ArgTypes, ModuleInfo, LabelName, 0,
- HashCode),
+ PredName, 1, FactTableSize, HashCode),
SuccessCodeTemplate = "
success_code_%s:
SUCCESS_INDICATOR = TRUE;
- ind = FACT_TABLE_HASH_INDEX(ind);
",
string__format(SuccessCodeTemplate, [s(LabelName)], SuccessCode),
@@ -2709,7 +2710,7 @@
Word ind;
void *current_table;
char keytype;
- Word current_key;
+ Word current_key, tmp;
/*
** Initialise current_table to the top level hash table
@@ -2723,49 +2724,62 @@
% generate code to calculate hash values and lookup the hash tables
:- pred generate_hash_code(list(pragma_var), list(type), module_info, string,
- int, string).
-:- mode generate_hash_code(in, in, in, in, in, out) is det.
+ int, string, int, int, string).
+:- mode generate_hash_code(in, in, in, in, in, in, in, in, out) is det.
-generate_hash_code([], [], _, _, _, "").
-generate_hash_code([], [_|_], _, _, _, _) :- error("generate_hash_code").
-generate_hash_code([_|_], [], _, _, _, _) :- error("generate_hash_code").
+generate_hash_code([], [], _, _, _, _, _, _, "").
+generate_hash_code([], [_|_], _, _, _, _, _, _, _) :-
+ error("generate_hash_code").
+generate_hash_code([_|_], [], _, _, _, _, _, _, _) :-
+ error("generate_hash_code").
generate_hash_code([pragma_var(_, Name, Mode)|PragmaVars], [Type | Types],
- ModuleInfo, LabelName, LabelNum, C_Code) :-
+ ModuleInfo, LabelName, LabelNum, PredName, ArgNum,
+ FactTableSize, C_Code) :-
+ NextArgNum is ArgNum + 1,
( mode_is_fully_input(ModuleInfo, Mode) ->
(
Type = term__functor(term__atom("int"), [], _)
->
generate_hash_int_code(Name, LabelName, LabelNum,
- C_Code0)
+ PredName, PragmaVars, Types, ModuleInfo,
+ NextArgNum, FactTableSize, C_Code0)
;
Type = term__functor(term__atom("float"), [], _)
->
generate_hash_float_code(Name, LabelName, LabelNum,
- C_Code0)
+ PredName, PragmaVars, Types, ModuleInfo,
+ NextArgNum, FactTableSize, C_Code0)
;
Type = term__functor(term__atom("string"), [], _)
->
generate_hash_string_code(Name, LabelName, LabelNum,
- C_Code0)
+ PredName, PragmaVars, Types, ModuleInfo,
+ NextArgNum, FactTableSize, C_Code0)
;
error("generate_hash_code: unsupported type")
),
NextLabelNum is LabelNum + 1,
generate_hash_code(PragmaVars, Types, ModuleInfo, LabelName,
- NextLabelNum, C_Code1),
+ NextLabelNum, PredName, NextArgNum, FactTableSize,
+ C_Code1),
string__append(C_Code0, C_Code1, C_Code)
;
% skip non-input arguments
generate_hash_code(PragmaVars, Types, ModuleInfo, LabelName,
- LabelNum, C_Code)
+ LabelNum, PredName, NextArgNum, FactTableSize,
+ C_Code)
).
-:- pred generate_hash_int_code(string::in, string::in, int::in, string::out)
+:- pred generate_hash_int_code(string::in, string::in, int::in, string::in,
+ list(pragma_var)::in, list(type)::in, module_info::in,
+ int::in, int::in, string::out)
is det.
-generate_hash_int_code(Name, LabelName, LabelNum, C_Code) :-
+generate_hash_int_code(Name, LabelName, LabelNum, PredName, PragmaVars,
+ Types, ModuleInfo, ArgNum, FactTableSize, C_Code) :-
generate_hash_lookup_code(Name, LabelName, LabelNum, "%s == %s", 'i',
- HashLookupCode),
+ yes, PredName, PragmaVars, Types, ModuleInfo, ArgNum,
+ FactTableSize, HashLookupCode),
C_Code_Template = "
/* calculate hash value for an integer */
@@ -2773,7 +2787,7 @@
hashsize = ((struct fact_table_hash_table_i *)current_table)
->size;
- hashval = %s %% hashsize;
+ hashval = (%s >= 0 ? %s : -%s) %% hashsize;
current_key = %s;
@@ -2781,15 +2795,19 @@
%s
",
- string__format(C_Code_Template, [s(Name), s(Name), s(HashLookupCode)],
- C_Code).
+ string__format(C_Code_Template, [s(Name), s(Name), s(Name), s(Name),
+ s(HashLookupCode)], C_Code).
-:- pred generate_hash_float_code(string::in, string::in, int::in, string::out)
+:- pred generate_hash_float_code(string::in, string::in, int::in, string::in,
+ list(pragma_var)::in, list(type)::in, module_info::in,
+ int::in, int::in, string::out)
is det.
-generate_hash_float_code(Name, LabelName, LabelNum, C_Code) :-
+generate_hash_float_code(Name, LabelName, LabelNum, PredName, PragmaVars,
+ Types, ModuleInfo, ArgNum, FactTableSize, C_Code) :-
generate_hash_lookup_code(Name, LabelName, LabelNum, "%s == %s", 'f',
- HashLookupCode),
+ yes, PredName, PragmaVars, Types, ModuleInfo, ArgNum,
+ FactTableSize, HashLookupCode),
C_Code_Template = "
/* calculate hash value for a float */
@@ -2797,7 +2815,8 @@
hashsize = ((struct fact_table_hash_table_f *)current_table)
->size;
- hashval = hash_float(%s) %% hashsize;
+ hashval = hash_float(%s);
+ hashval = (hashval >= 0 ? hashval : -hashval) %% hashsize;
current_key = float_to_word(%s);
@@ -2808,12 +2827,16 @@
string__format(C_Code_Template, [s(Name), s(Name), s(HashLookupCode)],
C_Code).
-:- pred generate_hash_string_code(string::in, string::in, int::in, string::out)
+:- pred generate_hash_string_code(string::in, string::in, int::in, string::in,
+ list(pragma_var)::in, list(type)::in, module_info::in,
+ int::in, int::in, string::out)
is det.
-generate_hash_string_code(Name, LabelName, LabelNum, C_Code) :-
+generate_hash_string_code(Name, LabelName, LabelNum, PredName, PragmaVars,
+ Types, ModuleInfo, ArgNum, FactTableSize, C_Code) :-
generate_hash_lookup_code(Name, LabelName, LabelNum,
- "strcmp(%s, %s) == 0", 's', HashLookupCode),
+ "strcmp(%s, %s) == 0", 's', yes, PredName, PragmaVars,
+ Types, ModuleInfo, ArgNum, FactTableSize, HashLookupCode),
C_Code_Template = "
hashsize = ((struct fact_table_hash_table_s *)current_table)
@@ -2843,10 +2866,13 @@
% equality for the type given, e.g. "%s == %s" for ints,
% "strcmp(%s, %s) == 0" for strings.
:- pred generate_hash_lookup_code(string::in, string::in, int::in, string::in,
- char::in, string::out) is det.
+ char::in, bool::in, string::in, list(pragma_var)::in,
+ list(type)::in, module_info::in, int::in, int::in, string::out)
+ is det.
generate_hash_lookup_code(VarName, LabelName, LabelNum, CompareTemplate,
- KeyType, HashLookupCode) :-
+ KeyType, CheckKeys, PredName, PragmaVars, Types,
+ ModuleInfo, ArgNum, FactTableSize, HashLookupCode) :-
string__format(
"((struct fact_table_hash_table_%c *)current_table)->table[hashval]",
[c(KeyType)], HashTableEntry),
@@ -2859,7 +2885,7 @@
do {
if (FACT_TABLE_HASH_ENTRY_TYPE(%s) != 0 && %s)
{
- ind = (Word)%s.index;
+ ind = (Word) %s.index;
goto found_%s_%d;
}
} while ((hashval = %s.next) != -1);
@@ -2870,19 +2896,41 @@
found_%s_%d:
if (FACT_TABLE_HASH_ENTRY_TYPE(%s) == 1) {
+ ind = FACT_TABLE_HASH_INDEX(ind);
+
+ /* check that any remaining input arguments match */
+ %s
keytype = '%c';
hashval = %s.next;
goto success_code_%s;
}
- current_table = (void *)FACT_TABLE_HASH_POINTER(ind);
+ current_table = (void *) FACT_TABLE_HASH_POINTER(ind);
",
+ ( CheckKeys = yes ->
+ string__append_list(["mercury__", PredName, "_fact_table"],
+ FactTableName),
+ generate_test_condition_code(FactTableName, PragmaVars, Types,
+ ModuleInfo, ArgNum, yes, FactTableSize, CondCode),
+ ( CondCode \= "" ->
+ TestCodeTemplate =
+ "if (%s\t\t\t) goto failure_code_%s;\n",
+ string__format(TestCodeTemplate,
+ [s(CondCode), s(LabelName)], TestCode)
+ ;
+ TestCode = ""
+ )
+ ;
+ TestCode = ""
+ ),
+
string__format(HashLookupCodeTemplate, [s(HashTableEntry),
s(CompareString), s(HashTableEntry), s(LabelName), i(LabelNum),
s(HashTableEntry), s(LabelName), s(LabelName), i(LabelNum),
- s(HashTableEntry), c(KeyType), s(HashTableEntry),
- s(LabelName)], HashLookupCode).
+ s(HashTableEntry), s(TestCode), c(KeyType),
+ s(HashTableEntry), s(LabelName)],
+ HashLookupCode).
@@ -2900,27 +2948,43 @@
[Type | Types], ModuleInfo, ArgNum, FactTableSize, C_Code) :-
NextArgNum is ArgNum + 1,
( mode_is_fully_output(ModuleInfo, Mode) ->
- C_Code_Template =
- "\t\t%s = %smercury__%s_fact_table[ind/%d][ind%%%d].V_%d;\n",
- ( Type = term__functor(term__atom("string"), [], _) ->
- % Cast ConstString -> Word -> String to avoid
- % gcc warning "assignment discards `const'".
- % XXX Is this safe or should I be copying the string
- % onto the heap?
- Cast = "(String)(Word)"
+ TableEntryTemplate =
+ "mercury__%s_fact_table[ind/%d][ind%%%d].V_%d",
+ string__format(TableEntryTemplate, [s(PredName),
+ i(FactTableSize), i(FactTableSize), i(ArgNum)],
+ TableEntry),
+ ( Type = term__functor(term__atom("string"), [], _) ->
+ mode_get_insts(ModuleInfo, Mode, _, FinalInst),
+ ( inst_is_not_partly_unique(ModuleInfo, FinalInst) ->
+ % Cast ConstString -> Word -> String to avoid
+ % gcc warning "assignment discards `const'".
+ Template =
+ "\t\tmake_aligned_string(%s, (String) (Word) %s);\n",
+ string__format(Template, [s(VarName), s(TableEntry)],
+ C_Code0)
;
- Cast = ""
- ),
- string__format(C_Code_Template, [s(VarName), s(Cast),
- s(PredName), i(FactTableSize), i(FactTableSize),
- i(ArgNum)], C_Code0),
- generate_fact_lookup_code(PredName, PragmaVars, Types,
- ModuleInfo, NextArgNum, FactTableSize, C_Code1),
- string__append(C_Code0, C_Code1, C_Code)
+ % Unique modes need to allow destructive update so we
+ % need to make a copy of the string on the heap.
+ Template =
+" incr_hp_atomic(tmp, (strlen(%s) + sizeof(Word)) / sizeof(Word));
+ %s = (String) tmp;
+ strcpy(%s, %s);
+",
+ string__format(Template, [s(TableEntry), s(VarName),
+ s(VarName), s(TableEntry)], C_Code0)
+ )
+ ;
+ Template = "\t\t%s = %s;\n",
+ string__format(Template, [s(VarName), s(TableEntry)],
+ C_Code0)
+ ),
+ generate_fact_lookup_code(PredName, PragmaVars, Types,
+ ModuleInfo, NextArgNum, FactTableSize, C_Code1),
+ string__append(C_Code0, C_Code1, C_Code)
;
- % skip non-output arguments
- generate_fact_lookup_code(PredName, PragmaVars, Types,
- ModuleInfo, NextArgNum, FactTableSize, C_Code)
+ % skip non-output arguments
+ generate_fact_lookup_code(PredName, PragmaVars, Types,
+ ModuleInfo, NextArgNum, FactTableSize, C_Code)
).
%---------------------------------------------------------------------------%
@@ -2945,7 +3009,7 @@
Define_extern_entry(%s);
Declare_label(%s_i1);
-BEGIN_MODULE(%s_module)
+ BEGIN_MODULE(%s_module)
init_entry(%s);
init_label(%s_i);
BEGIN_CODE
@@ -2963,7 +3027,6 @@
/* lookup hash table */
%s
success_code_%s:
- ind = FACT_TABLE_HASH_INDEX(ind);
/* lookup fact table */
%s
/* save output args to registers */
@@ -3013,7 +3076,7 @@
generate_decl_code(PredName, ProcID, DeclCode),
string__format("%s_%d", [s(PredName), i(ProcID)], LabelName),
generate_hash_code(PragmaVars, ArgTypes, ModuleInfo, LabelName, 0,
- HashCode),
+ PredName, 1, FactTableSize, HashCode),
generate_fact_lookup_code(PredName, PragmaVars, ArgTypes, ModuleInfo, 1,
FactTableSize, FactLookupCode),
generate_fact_test_code(PredName, PragmaVars, ArgTypes, ModuleInfo,
@@ -3263,7 +3326,6 @@
/* lookup hash table */
%s
success_code_%s:
- ind = FACT_TABLE_HASH_INDEX(ind);
/* lookup fact table */
%s
/* save output args to registers */
@@ -3302,7 +3364,6 @@
fatal_error(""fact table hash lookup: nondet stack corrupted?"");
}
success_code_%s:
- ind = FACT_TABLE_HASH_INDEX(ind);
/* lookup fact table */
%s
/* save output args to registers */
@@ -3334,14 +3395,16 @@
string__format("%s_%d", [s(PredName), i(ProcID)], LabelName),
string__append(LabelName, "_2", LabelName2),
generate_hash_code(PragmaVars, ArgTypes, ModuleInfo, LabelName, 0,
- HashCode),
+ PredName, 1, FactTableSize, HashCode),
generate_hash_lookup_code("(char *)framevar(3)", LabelName2, 0,
- "strcmp(%s, %s) == 0", 's', StringHashLookupCode),
+ "strcmp(%s, %s) == 0", 's', no, "", [], [], ModuleInfo, 0, 0,
+ StringHashLookupCode),
generate_hash_lookup_code("framevar(3)", LabelName2, 1, "%s == %s",
- 'i', IntHashLookupCode),
+ 'i', no, "", [], [], ModuleInfo, 0, 0, IntHashLookupCode),
generate_hash_lookup_code("word_to_float(framevar(3))", LabelName2, 2,
- "%s == %s", 'f', FloatHashLookupCode),
+ "%s == %s", 'f', no, "", [], [], ModuleInfo, 0, 0,
+ FloatHashLookupCode),
generate_fact_lookup_code(PredName, PragmaVars, ArgTypes, ModuleInfo, 1,
FactTableSize, FactLookupCode),
list__length(PragmaVars, Arity),
Index: compiler/modules.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modules.m,v
retrieving revision 1.31
diff -u -r1.31 modules.m
--- 1.31 1997/02/23 06:07:32
+++ modules.m 1997/02/26 07:32:20
@@ -398,6 +398,39 @@
{ list__delete_all(ShortDeps2, ModuleName, ShortDeps) },
{ list__sort_and_remove_dups(FactDeps0, FactDeps) },
+ ( { FactDeps \= [] } ->
+ io__write_strings(DepStream,
+ [ModuleName, ".fact_tables = "]),
+ write_dependencies_list(FactDeps, "", DepStream),
+ io__nl(DepStream),
+ globals__io_lookup_bool_option(assume_gmake,
+ AssumeGmake),
+ ( { AssumeGmake = no} ->
+ io__write_strings(DepStream,
+ [ModuleName, ".fact_tables.os = "]),
+ write_dependencies_list(FactDeps, ".o",
+ DepStream),
+ io__write_strings(DepStream, [
+ "\n\n",
+ ModuleName, ".fact_tables.cs = "]),
+ write_dependencies_list(FactDeps, ".c",
+ DepStream),
+ io__nl(DepStream)
+ ;
+ io__write_strings(DepStream, [
+ "\n\n", ModuleName,
+ ".fact_tables.os = $(", ModuleName,
+ ".fact_tables:%=%.o)\n\n",
+ ModuleName,
+ ".fact_tables.cs = $(", ModuleName,
+ ".fact_tables:%=%.c)\n\n"
+ ])
+ )
+ ;
+ []
+ ),
+
+
io__write_strings(DepStream, [
ModuleName, ".optdate ",
ModuleName, ".c ",
@@ -407,7 +440,19 @@
] ),
write_dependencies_list(LongDeps, ".int", DepStream),
write_dependencies_list(ShortDeps, ".int2", DepStream),
- write_dependencies_list(FactDeps, "", DepStream),
+
+ ( { FactDeps \= [] } ->
+ io__write_strings(DepStream, [
+ " \\\n\t$(", ModuleName, ".fact_tables)\n\n",
+ "$(", ModuleName, ".fact_tables.os) : $(",
+ ModuleName, ".fact_tables) ",
+ ModuleName, ".m\n\n",
+ "$(", ModuleName, ".fact_tables.cs) : ",
+ ModuleName, ".o\n"
+ ] )
+ ;
+ []
+ ),
globals__io_lookup_bool_option(intermodule_optimization,
Intermod),
@@ -449,17 +494,6 @@
"\t$(MCS) -s$(GRADE) $(MCSFLAGS) ", ModuleName, ".m\n"
]),
- ( { FactDeps = [_|_] } ->
- { Lambda = lambda([S0::in, S::out] is det,
- string__append(S0, ".c ", S)) },
- { list__map(Lambda, FactDeps, Fact_C_Files) },
- io__nl,
- io__write_strings(DepStream, Fact_C_Files),
- io__write_strings(DepStream, [": ",ModuleName,".o\n"])
- ;
- []
- ),
-
io__close_output(DepStream),
maybe_write_string(Verbose, " done.\n")
;
More information about the developers
mailing list