[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