[m-dev.] diff: more existential types changes

Fergus Henderson fjh at cs.mu.OZ.AU
Sun Jun 13 18:56:01 AEST 1999


Estimated hours taken: 6

Some more changes to fix test case failures in the existential_types_2
branch.

compiler/simplify.m:
	Be a bit more careful about when to issue warnings about 
	det goals that have no outputs or about goals that always fail.
	It was getting a few too many spurious warnings.

compiler/polymorphism.m:
	Add `private_builtin__table_restore_any_ans' and
	`private_builtin__table_lookup_insert_enum' to the list of
	no_type_info_builtins, i.e. polymorphic procedures for which we
	do not pass a type_info since they do not need it.
	This helps because it means that table_gen.m doesn't need
	to set up a type_info when calling them.

compiler/table_gen.m:
	Insert code to generate appropriate type_infos when calling
	polymorphic predicates (i.e. table_lookup_insert_user,
	table_lookup_insert_poly, and table_save_any_ans --
	but not table_lookup_insert_enum or table_restore_any_ans).

compiler/modecheck_call.m:
compiler/unique_modes.m:
compiler/modes.m:
compiler/mode_info.m:
compiler/mode_errors.m:
	Fix up the argument numbers in error messages so that they
	take the extra type_info arguments into account.

tests/term/arit_exp.trans_opt_exp:
tests/term/associative.trans_opt_exp:
tests/term/pl5_2_2.trans_opt_exp:
tests/term/vangelder.trans_opt_exp:
	Update the expected output for these tests.
	My changes to when polymorphism.m is invoked seem to have affected
	the intermodule inlining heuristics a bit, and this results in
	some additional information in a few of the `.trans_opt' files here.

Workspace: /home/mercury0/fjh/mercury-other
Index: compiler/mode_errors.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_errors.m,v
retrieving revision 1.62
diff -u -r1.62 mode_errors.m
--- mode_errors.m	1999/03/12 06:14:15	1.62
+++ mode_errors.m	1999/06/12 03:07:18
@@ -888,7 +888,7 @@
 write_mode_context(call(PredId, ArgNum), Context, ModuleInfo) -->
 	prog_out__write_context(Context),
 	io__write_string("  in "),
-	( { ArgNum = 0 } ->
+	( { ArgNum =< 0 } ->
 		[]
 	;
 		io__write_string("argument "),
Index: compiler/mode_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_info.m,v
retrieving revision 1.49.2.1
diff -u -r1.49.2.1 mode_info.m
--- mode_info.m	1999/06/10 16:26:02	1.49.2.1
+++ mode_info.m	1999/06/12 03:05:32
@@ -28,7 +28,10 @@
 :- type mode_context
 	--->	call(	
 			pred_id,	% pred name / arity
-			int		% argument number
+			int		% argument number (offset so that
+					% the real arguments start at number 1
+					% whereas the type_info arguments
+					% have numbers <= 0).
 		)
 	;	higher_order_call(
 			pred_or_func,	% is it call/N (higher-order pred call)
Index: compiler/modecheck_call.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modecheck_call.m,v
retrieving revision 1.29.2.1
diff -u -r1.29.2.1 modecheck_call.m
--- modecheck_call.m	1999/06/12 00:50:34	1.29.2.1
+++ modecheck_call.m	1999/06/12 03:39:49
@@ -139,12 +139,14 @@
 		Det = Det0,
 		Modes = Modes0,
 
+		ArgOffset = 1,
+
 		%
 		% Check that `Args0' have livenesses which match the
 		% expected livenesses.
 		%
 		get_arg_lives(Modes, ModuleInfo0, ExpectedArgLives),
-		modecheck_var_list_is_live(Args0, ExpectedArgLives, 1,
+		modecheck_var_list_is_live(Args0, ExpectedArgLives, ArgOffset,
 			ModeInfo0, ModeInfo1),
 
 		%
@@ -153,11 +155,11 @@
 		% extra unifications for implied modes, if necessary).
 		%
 		mode_list_get_initial_insts(Modes, ModuleInfo0, InitialInsts),
-		modecheck_var_has_inst_list(Args0, InitialInsts, 0,
+		modecheck_var_has_inst_list(Args0, InitialInsts, ArgOffset,
 					ModeInfo1, ModeInfo2),
 		mode_list_get_final_insts(Modes, ModuleInfo0, FinalInsts),
 		modecheck_set_var_inst_list(Args0, InitialInsts, FinalInsts,
-			Args, ExtraGoals, ModeInfo2, ModeInfo3),
+			ArgOffset, Args, ExtraGoals, ModeInfo2, ModeInfo3),
 		( determinism_components(Det, _, at_most_zero) ->
 			instmap__init_unreachable(Instmap),
 			mode_info_set_instmap(Instmap, ModeInfo3, ModeInfo)
@@ -200,6 +202,7 @@
 		map__keys(Procs, ProcIds)
 	),
 
+	compute_arg_offset(PredInfo, ArgOffset),
 	pred_info_get_markers(PredInfo, Markers),
 
 		% In order to give better diagnostics, we handle the
@@ -223,12 +226,13 @@
 	->
 		TheProcId = ProcId,
 		map__lookup(Procs, ProcId, ProcInfo),
+
 		%
 		% Check that `ArgsVars0' have livenesses which match the
 		% expected livenesses.
 		%
 		proc_info_arglives(ProcInfo, ModuleInfo, ProcArgLives0),
-		modecheck_var_list_is_live(ArgVars0, ProcArgLives0, 0,
+		modecheck_var_list_is_live(ArgVars0, ProcArgLives0, ArgOffset,
 					ModeInfo0, ModeInfo1),
 
 		%
@@ -239,10 +243,10 @@
 		proc_info_argmodes(ProcInfo, ProcArgModes),
 		mode_list_get_initial_insts(ProcArgModes, ModuleInfo,
 					InitialInsts),
-		modecheck_var_has_inst_list(ArgVars0, InitialInsts, 0,
+		modecheck_var_has_inst_list(ArgVars0, InitialInsts, ArgOffset,
 					ModeInfo1, ModeInfo2),
 
-		modecheck_end_of_call(ProcInfo, ArgVars0, ArgVars,
+		modecheck_end_of_call(ProcInfo, ArgVars0, ArgOffset, ArgVars,
 					ExtraGoals, ModeInfo2, ModeInfo)
 	;
 			% set the current error list to empty (and
@@ -269,8 +273,8 @@
 			choose_best_match(MatchingProcIds, PredId, Procs,
 				ArgVars0, TheProcId, ModeInfo2),
 			map__lookup(Procs, TheProcId, ProcInfo),
-			modecheck_end_of_call(ProcInfo, ArgVars0, ArgVars,
-				ExtraGoals, ModeInfo2, ModeInfo3)
+			modecheck_end_of_call(ProcInfo, ArgVars0, ArgOffset,
+				ArgVars, ExtraGoals, ModeInfo2, ModeInfo3)
 		),
 
 			% restore the error list, appending any new error(s)
@@ -370,19 +374,19 @@
 			MatchingProcIds1, MatchingProcIds,
 			WaitingVars1, WaitingVars, ModeInfo3, ModeInfo).
 
-:- pred modecheck_end_of_call(proc_info, list(prog_var), list(prog_var),
-		extra_goals, mode_info, mode_info).
-:- mode modecheck_end_of_call(in, in, out, out,
+:- pred modecheck_end_of_call(proc_info, list(prog_var), int,
+		list(prog_var), extra_goals, mode_info, mode_info).
+:- mode modecheck_end_of_call(in, in, in, out, out,
 				mode_info_di, mode_info_uo) is det.
 
-modecheck_end_of_call(ProcInfo, ArgVars0, ArgVars, ExtraGoals,
-			ModeInfo0, ModeInfo) :-
+modecheck_end_of_call(ProcInfo, ArgVars0, ArgOffset,
+			ArgVars, ExtraGoals, ModeInfo0, ModeInfo) :-
 	proc_info_argmodes(ProcInfo, ProcArgModes),
 	mode_info_get_module_info(ModeInfo0, ModuleInfo),
 	mode_list_get_initial_insts(ProcArgModes, ModuleInfo, InitialInsts),
 	mode_list_get_final_insts(ProcArgModes, ModuleInfo, FinalInsts),
 	modecheck_set_var_inst_list(ArgVars0, InitialInsts, FinalInsts,
-			ArgVars, ExtraGoals, ModeInfo0, ModeInfo1),
+			ArgOffset, ArgVars, ExtraGoals, ModeInfo0, ModeInfo1),
 	proc_info_never_succeeds(ProcInfo, NeverSucceeds),
 	( NeverSucceeds = yes ->
 		instmap__init_unreachable(Instmap),
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.230.2.2
diff -u -r1.230.2.2 modes.m
--- modes.m	1999/06/12 00:50:36	1.230.2.2
+++ modes.m	1999/06/12 03:33:33
@@ -202,6 +202,16 @@
 :- pred get_live_vars(list(prog_var), list(is_live), list(prog_var)).
 :- mode get_live_vars(in, in, out) is det.
 
+	%
+	% calculate the argument number offset that needs to be passed to
+	% modecheck_var_list_is_live, modecheck_var_has_inst_list, and
+	% modecheck_set_var_inst_list.  This offset number is calculated
+	% so that real arguments get positive argument numbers and
+	% type_info arguments get argument numbers less than or equal to 0.
+	%
+:- pred compute_arg_offset(pred_info, int).
+:- mode compute_arg_offset(in, out) is det.
+
 	% Given a list of variables and a list of expected liveness, ensure
 	% that the inst of each variable satisfies the corresponding expected
 	% liveness.
@@ -224,8 +234,8 @@
 :- mode modecheck_set_var_inst(in, in, mode_info_di, mode_info_uo) is det.
 
 :- pred modecheck_set_var_inst_list(list(prog_var), list(inst), list(inst),
-		list(prog_var), extra_goals, mode_info, mode_info).
-:- mode modecheck_set_var_inst_list(in, in, in, out, out,
+		int, list(prog_var), extra_goals, mode_info, mode_info).
+:- mode modecheck_set_var_inst_list(in, in, in, in, out, out,
 					mode_info_di, mode_info_uo) is det.
 
 	% check that the final insts of the head vars of a lambda
@@ -1639,6 +1649,21 @@
 
 %-----------------------------------------------------------------------------%
 
+	%
+	% calculate the argument number offset that needs to be passed to
+	% modecheck_var_list_is_live, modecheck_var_has_inst_list, and
+	% modecheck_set_var_inst_list.  This offset number is calculated
+	% so that real arguments get positive argument numbers and
+	% type_info arguments get argument numbers less than or equal to 0.
+	%
+compute_arg_offset(PredInfo, ArgOffset) :-
+	pred_info_arity(PredInfo, OrigArity),
+	pred_info_arg_types(PredInfo, ArgTypes),
+	list__length(ArgTypes, CurrentArity),
+	ArgOffset = OrigArity - CurrentArity.
+
+%-----------------------------------------------------------------------------%
+
 	% Given a list of variables and a list of expected livenesses,
 	% ensure the liveness of each variable satisfies the corresponding
 	% expected liveness.
@@ -1710,10 +1735,11 @@
 
 %-----------------------------------------------------------------------------%
 
-modecheck_set_var_inst_list(Vars0, InitialInsts, FinalInsts, Vars, Goals) -->
+modecheck_set_var_inst_list(Vars0, InitialInsts, FinalInsts, ArgOffset,
+		Vars, Goals) -->
 	(
 		modecheck_set_var_inst_list_2(Vars0, InitialInsts, FinalInsts,
-			no_extra_goals, 0, Vars1, Goals1)
+			no_extra_goals, ArgOffset, Vars1, Goals1)
 	->
 		{ Vars = Vars1, Goals = Goals1 }
 	;
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.163.2.2
diff -u -r1.163.2.2 polymorphism.m
--- polymorphism.m	1999/06/12 00:50:38	1.163.2.2
+++ polymorphism.m	1999/06/13 08:22:14
@@ -493,20 +493,31 @@
 
 %---------------------------------------------------------------------------%
 
-polymorphism__no_type_info_builtin(MercuryBuiltin, "unsafe_type_cast", 2) :-
-	mercury_private_builtin_module(MercuryBuiltin).
-polymorphism__no_type_info_builtin(MercuryBuiltin,
-		"unsafe_promise_unique", 2) :-
-	mercury_public_builtin_module(MercuryBuiltin).
-polymorphism__no_type_info_builtin(MercuryBuiltin,
-		"superclass_from_typeclass_info", 3) :-
-	mercury_private_builtin_module(MercuryBuiltin).
-polymorphism__no_type_info_builtin(MercuryBuiltin,
-		"instance_constraint_from_typeclass_info", 3) :-
-	mercury_private_builtin_module(MercuryBuiltin).
-polymorphism__no_type_info_builtin(MercuryBuiltin,
-		"type_info_from_typeclass_info", 3) :-
-	mercury_private_builtin_module(MercuryBuiltin).
+polymorphism__no_type_info_builtin(ModuleName, PredName, Arity) :-
+	no_type_info_builtin_2(ModuleNameType, PredName, Arity),
+	check_module_name(ModuleNameType, ModuleName).
+
+:- type builtin_mod ---> builtin ; private_builtin.
+
+:- pred check_module_name(builtin_mod, module_name).
+:- mode check_module_name(in, in) is semidet.
+
+check_module_name(builtin, Module) :-
+	mercury_public_builtin_module(Module).
+check_module_name(private_builtin, Module) :-
+	mercury_private_builtin_module(Module).
+
+:- pred no_type_info_builtin_2(builtin_mod, string, int).
+:- mode no_type_info_builtin_2(out, in, out) is semidet.
+
+no_type_info_builtin_2(private_builtin, "unsafe_type_cast", 2).
+no_type_info_builtin_2(builtin, "unsafe_promise_unique", 2).
+no_type_info_builtin_2(private_builtin, "superclass_from_typeclass_info", 3).
+no_type_info_builtin_2(private_builtin,
+				"instance_constraint_from_typeclass_info", 3).
+no_type_info_builtin_2(private_builtin, "type_info_from_typeclass_info", 3).
+no_type_info_builtin_2(private_builtin, "table_restore_any_ans", 3).
+no_type_info_builtin_2(private_builtin, "table_lookup_insert_enum", 4).
 
 %---------------------------------------------------------------------------%
 
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.66.2.2
diff -u -r1.66.2.2 simplify.m
--- simplify.m	1999/06/12 00:50:41	1.66.2.2
+++ simplify.m	1999/06/12 08:08:27
@@ -318,11 +318,14 @@
 		; code_aux__goal_cannot_loop(ModuleInfo, Goal0)
 		)
 	->
-		% warn about this (if the goal wasn't `fail')
+		% warn about this, unless the goal was an explicit
+		% `fail', or some goal containing `fail'.
+
 		goal_info_get_context(GoalInfo0, Context),
 		(
 			simplify_do_warn(Info0),
-			Goal0 \= disj([], _) - _
+			\+ (goal_contains_goal(Goal0, SubGoal),
+			    SubGoal = disj([], _) - _)
 		->
 			simplify_info_add_msg(Info0,
 				goal_cannot_succeed(Context), Info1)
@@ -365,16 +368,22 @@
 	->
 		% warn about this, if the goal wasn't `true'
 		% and wasn't a deconstruction unification.
-		% (We don't warn about deconstruction unifications
+		% We don't warn about deconstruction unifications
 		% with no outputs that always succeed, because that
 		% would result in bogus warnings, since switch detection
 		% converts deconstruction unifications that can fail
 		% into ones that always succeed by moving the test into
-		% the switch.)
+		% the switch.
+		% We also don't warn about conjunctions or existential
+		% quantifications, because it seems that warnings in those
+		% cases are usually spurious.
+		% XXX perhaps it would be best to just disable this entirely.
 		goal_info_get_context(GoalInfo0, Context),
 		(
 			simplify_do_warn(Info0),
-			Goal0 \= conj([]) - _,
+			% Goal0 \= conj([]) - _,
+			Goal0 \= conj(_) - _,
+			Goal0 \= some(_, _) - _,
 			\+ (Goal0 = unify(_, _, _, Unification, _) - _,
 			    Unification = deconstruct(_, _, _, _, _))
 		->
@@ -2064,3 +2073,35 @@
 	simplify_info_set_common_info(Info2, CommonInfo0, Info3),
 	simplify_info_get_instmap(Info1, InstMap),
 	simplify_info_set_instmap(Info3, InstMap, Info).
+
+%-----------------------------------------------------------------------------%
+
+:- pred goal_contains_goal(hlds_goal, hlds_goal).
+:- mode goal_contains_goal(in, out) is multi.
+
+goal_contains_goal(Goal, Goal).
+goal_contains_goal(Goal - _, SubGoal) :-
+	direct_subgoal(Goal, DirectSubGoal),
+	goal_contains_goal(DirectSubGoal, SubGoal).
+
+:- pred direct_subgoal(hlds_goal_expr, hlds_goal).
+:- mode direct_subgoal(in, out) is nondet.
+
+direct_subgoal(some(_, Goal), Goal).
+direct_subgoal(not(Goal), Goal).
+direct_subgoal(if_then_else(_, If, Then, Else, _), Goal) :-
+	( Goal = If
+	; Goal = Then
+	; Goal = Else
+	).
+direct_subgoal(conj(ConjList), Goal) :-
+	list__member(Goal, ConjList).
+direct_subgoal(par_conj(ConjList, _), Goal) :-
+	list__member(Goal, ConjList).
+direct_subgoal(disj(DisjList, _), Goal) :-
+	list__member(Goal, DisjList).
+direct_subgoal(switch(_, _, CaseList, _), Goal) :-
+	list__member(Case, CaseList),
+	Case = case(_, Goal).
+
+%-----------------------------------------------------------------------------%
Index: compiler/table_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/table_gen.m,v
retrieving revision 1.7
diff -u -r1.7 table_gen.m
--- table_gen.m	1999/04/20 11:47:50	1.7
+++ table_gen.m	1999/06/13 08:36:39
@@ -170,11 +170,12 @@
 :- implementation.
 
 :- import_module hlds_out, prog_out.
-:- import_module hlds_pred, instmap.
+:- import_module hlds_pred, instmap, polymorphism.
 :- import_module code_aux, det_analysis, follow_code, goal_util, const_prop.
 :- import_module hlds_module, hlds_goal, hlds_data, (inst), inst_match.
 :- import_module globals, options, passes_aux, prog_data, mode_util, type_util.
 :- import_module code_util, quantification, modes, purity, prog_util.
+
 :- import_module term, varset.
 :- import_module bool, list, set, map, require, std_util, int.
 :- import_module assoc_list, string, llds.
@@ -237,7 +238,7 @@
 
 	table_gen__process_procs(PredId, ProcIds, Module2, Module).
 
-%---------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred table_gen__process_proc(eval_method, pred_id, proc_id, proc_info,
 		pred_info, module_info, module_info).
@@ -245,6 +246,8 @@
 
 table_gen__process_proc(EvalMethod, PredId, ProcId, ProcInfo0, PredInfo0,
 		Module0, Module) :-
+	table_info_init(Module0, PredInfo0, ProcInfo0, TableInfo0),
+	
 	% grab the appropriate fields from the pred_info and proc_info
 	proc_info_interface_code_model(ProcInfo0, CodeModel),
 	proc_info_headvars(ProcInfo0, HeadVars),
@@ -256,65 +259,71 @@
 	(
 		CodeModel = model_det,
 		table_gen__create_new_det_goal(EvalMethod, OrigGoal,
-			PredId, ProcId, PredInfo0, Module0,
-			HeadVars, ArgModes, VarTypes0,
-			VarTypes, VarSet0, VarSet, Goal)
+			PredId, ProcId, HeadVars, ArgModes,
+			VarTypes0, VarTypes, VarSet0, VarSet,
+			TableInfo0, TableInfo, Goal)
 	;
 		CodeModel = model_semi,
 		table_gen__create_new_semi_goal(EvalMethod, OrigGoal,
-			PredId, ProcId, PredInfo0, Module0,
-			HeadVars, ArgModes, VarTypes0,
-			VarTypes, VarSet0, VarSet, Goal)
+			PredId, ProcId, HeadVars, ArgModes,
+			VarTypes0, VarTypes, VarSet0, VarSet,
+			TableInfo0, TableInfo, Goal)
 	;
 		CodeModel = model_non,
 		table_gen__create_new_non_goal(EvalMethod, OrigGoal,
-			PredId, ProcId, PredInfo0, Module0,
-			HeadVars, ArgModes, VarTypes0,
-			VarTypes, VarSet0, VarSet, Goal)
+			PredId, ProcId, HeadVars, ArgModes,
+			VarTypes0, VarTypes, VarSet0, VarSet,
+			TableInfo0, TableInfo, Goal)
 	),
 
+	table_info_extract(TableInfo, Module1, PredInfo1, ProcInfo1),
+
 	% set the new values of the fields in proc_info and pred_info
 	% and save in the module info
-	proc_info_set_goal(ProcInfo0, Goal, ProcInfo1),
-	proc_info_set_varset(ProcInfo1, VarSet, ProcInfo2),
-	proc_info_set_vartypes(ProcInfo2, VarTypes, ProcInfo),
+	proc_info_set_goal(ProcInfo1, Goal, ProcInfo2),
+	proc_info_set_varset(ProcInfo2, VarSet, ProcInfo3),
+	proc_info_set_vartypes(ProcInfo3, VarTypes, ProcInfo),
 
-	pred_info_procedures(PredInfo0, ProcTable1),
+	pred_info_procedures(PredInfo1, ProcTable1),
 	map__det_update(ProcTable1, ProcId, ProcInfo, ProcTable),
-	pred_info_set_procedures(PredInfo0, ProcTable, PredInfo),
-	module_info_preds(Module0, PredTable0),
-	map__det_update(PredTable0, PredId, PredInfo, PredTable),
-	module_info_set_preds(Module0, PredTable, Module).
+	pred_info_set_procedures(PredInfo1, ProcTable, PredInfo),
+	module_info_preds(Module1, PredTable1),
+	map__det_update(PredTable1, PredId, PredInfo, PredTable),
+	module_info_set_preds(Module1, PredTable, Module).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 		%
 		% Transform deterministic procedures.
 		%
 :- pred table_gen__create_new_det_goal(eval_method, hlds_goal,
-	pred_id, proc_id, pred_info, module_info, list(prog_var), list(mode),
+	pred_id, proc_id, list(prog_var), list(mode),
 	map(prog_var, type), map(prog_var, type), prog_varset, prog_varset,
-	hlds_goal).
-:- mode table_gen__create_new_det_goal(in, in, in, in, in, in, in, in,
-		in, out, in, out, out) is det.
+	table_info, table_info, hlds_goal).
+:- mode table_gen__create_new_det_goal(in, in, in, in, in, in,
+		in, out, in, out, in, out, out) is det.
 
 table_gen__create_new_det_goal(EvalMethod, OrigGoal, PredId, ProcId,
-		PredInfo, Module, HeadVars, HeadVarModes,
-		VarTypes0, VarTypes, VarSet0, VarSet, Goal) :-
+		HeadVars, HeadVarModes,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
+
 	get_input_output_vars(HeadVars, HeadVarModes, Module, InputVars,
 		OutputVars),
 
-	generate_det_lookup_goal(InputVars, Module, PredId, ProcId,
-		VarTypes0, VarTypes1, VarSet0, VarSet1, TableVar, LookUpGoal),
+	generate_det_lookup_goal(InputVars, PredId, ProcId,
+		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
+		TableVar, LookUpGoal),
 	generate_call("table_simple_is_complete", [TableVar], semidet, semipure,
 		[], Module, CompleteCheckGoal),
 	generate_save_goal(OutputVars, TableVar, VarTypes1, VarTypes2,
-		VarSet1, VarSet2, Module, SaveAnsGoal0),
+		VarSet1, VarSet2, TableInfo1, TableInfo, SaveAnsGoal0),
 	generate_restore_goal(OutputVars, TableVar,  Module, VarTypes2,
 		VarTypes3, VarSet2, VarSet3, RestoreAnsGoal),
 	generate_call("table_simple_mark_as_inactive", [TableVar], det, impure,
 		[], Module, MarkAsInactiveGoal),
-	generate_loop_error_goal(PredInfo, Module, VarTypes3, VarTypes,
+	generate_loop_error_goal(TableInfo, VarTypes3, VarTypes,
 		VarSet3, VarSet, LoopErrorGoal),
 
 	OrigGoal = _ - OrigGoalInfo,
@@ -373,33 +382,36 @@
 
 	Goal = GoalEx - GoalInfo.
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 		%
 		% Transform semi deterministic procedures
 		%
 :- pred table_gen__create_new_semi_goal(eval_method, hlds_goal,
-	pred_id, proc_id, pred_info, module_info, list(prog_var), list(mode),
+	pred_id, proc_id, list(prog_var), list(mode),
 	map(prog_var, type), map(prog_var, type), prog_varset, prog_varset,
-	hlds_goal).
-:- mode table_gen__create_new_semi_goal(in, in, in, in, in, in, in, in,
-	in, out, in, out, out) is det.
+	table_info, table_info, hlds_goal).
+:- mode table_gen__create_new_semi_goal(in, in, in, in, in, in,
+	in, out, in, out, in, out, out) is det.
 
 table_gen__create_new_semi_goal(EvalMethod, OrigGoal, PredId, ProcId,
-		PredInfo, Module, HeadVars, HeadVarModes,
-		VarTypes0, VarTypes, VarSet0, VarSet, Goal) :-
+		HeadVars, HeadVarModes,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
 	get_input_output_vars(HeadVars, HeadVarModes, Module, InputVars,
 		OutputVars),
 
-	generate_det_lookup_goal(InputVars, Module, PredId, ProcId,
-		VarTypes0, VarTypes1, VarSet0, VarSet1, TableVar, LookUpGoal),
+	generate_det_lookup_goal(InputVars, PredId, ProcId,
+		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
+		TableVar, LookUpGoal),
 	generate_call("table_simple_is_complete", [TableVar],
 		semidet, semipure, [], Module, CompleteCheckGoal),
 	generate_save_goal(OutputVars, TableVar, VarTypes1, VarTypes2,
-		VarSet1, VarSet2, Module, SaveAnsGoal0),
+		VarSet1, VarSet2, TableInfo1, TableInfo, SaveAnsGoal0),
 	generate_restore_goal(OutputVars, TableVar,  Module, VarTypes2,
 		VarTypes3, VarSet2, VarSet3, RestoreTrueAnsGoal),
-	generate_loop_error_goal(PredInfo, Module, VarTypes3, VarTypes,
+	generate_loop_error_goal(TableInfo, VarTypes3, VarTypes,
 		VarSet3, VarSet, LoopErrorGoal),
 	generate_call("table_simple_mark_as_failed", [TableVar],
 		failure, impure, [], Module, MarkAsFailedGoal),
@@ -516,37 +528,40 @@
 
 	Goal = GoalEx - GoalInfo.
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 		%
 		% Transform non deterministic procedures
 		%
 :- pred table_gen__create_new_non_goal(eval_method, hlds_goal,
-	pred_id, proc_id, pred_info, module_info, list(prog_var), list(mode),
+	pred_id, proc_id, list(prog_var), list(mode),
 	map(prog_var, type), map(prog_var, type), prog_varset, prog_varset,
-	hlds_goal).
-:- mode table_gen__create_new_non_goal(in, in, in, in, in, in, in, in,
-	in, out, in, out, out) is det.
+	table_info, table_info, hlds_goal).
+:- mode table_gen__create_new_non_goal(in, in, in, in, in, in,
+	in, out, in, out, in, out, out) is det.
 
 table_gen__create_new_non_goal(EvalMethod, OrigGoal, PredId, ProcId,
-		PredInfo, Module, HeadVars, HeadVarModes,
-		VarTypes0, VarTypes, VarSet0, VarSet, Goal) :-
+		HeadVars, HeadVarModes,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
 	get_input_output_vars(HeadVars, HeadVarModes, Module, InputVars,
 		OutputVars),
 
-	generate_non_lookup_goal(InputVars, Module, PredId, ProcId,
-		VarTypes0, VarTypes1, VarSet0, VarSet1, TableVar, LookUpGoal),
+	generate_non_lookup_goal(InputVars, PredId, ProcId,
+		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
+		TableVar, LookUpGoal),
 	generate_call("table_nondet_is_complete", [TableVar], semidet, semipure,
 		[], Module, CompleteCheckGoal),
 	generate_non_save_goal(OutputVars, TableVar, VarTypes1, VarTypes2,
-		VarSet1, VarSet2, Module, SaveAnsGoal0),
+		VarSet1, VarSet2, TableInfo1, TableInfo, SaveAnsGoal0),
 	generate_restore_all_goal(OutputVars, TableVar,  Module, VarTypes2,
 		VarTypes3, VarSet2, VarSet3, RestoreAllAnsGoal),
 	generate_call("table_nondet_is_active", [TableVar], semidet, semipure,
 		[], Module, IsActiveCheckGoal),
 	generate_suspend_goal(OutputVars, TableVar, Module, VarTypes3,
 		VarTypes4, VarSet3, VarSet4, SuspendGoal),
-	generate_loop_error_goal(PredInfo, Module, VarTypes4, VarTypes,
+	generate_loop_error_goal(TableInfo, VarTypes4, VarTypes,
 		VarSet4, VarSet, LoopErrorGoal),
 	generate_call("table_nondet_mark_as_active", [TableVar], det, impure,
 		[], Module, MarkAsActiveGoal),
@@ -620,7 +635,7 @@
 
 	Goal = GoalEx - GoalInfo.
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred generate_get_table_goal(map(prog_var, type), map(prog_var, type),
 	prog_varset, prog_varset, pred_id, proc_id, prog_var, hlds_goal).
@@ -646,21 +661,23 @@
 	goal_info_add_feature(GoalInfo0, impure, GoalInfo),
 	Goal = GoalExpr - GoalInfo.
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
-:- pred generate_det_lookup_goal(list(prog_var), module_info, pred_id, proc_id,
-	map(prog_var, type), map(prog_var, type), prog_varset,
-	prog_varset, prog_var, hlds_goal).
-:- mode generate_det_lookup_goal(in, in, in, in, in, out, in, out, out, out)
-	is det.
+:- pred generate_det_lookup_goal(list(prog_var), pred_id, proc_id,
+		map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info,
+		prog_var, hlds_goal).
+:- mode generate_det_lookup_goal(in, in, in, in, out, in, out, in, out,
+		out, out) is det.
 
-generate_det_lookup_goal(Vars, Module, PredId, ProcId, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableVar, Goal) :-
+generate_det_lookup_goal(Vars, PredId, ProcId, VarTypes0, VarTypes,
+		VarSet0, VarSet, TableInfo0, TableInfo, TableVar, Goal) :-
 
 	generate_get_table_goal(VarTypes0, VarTypes1, VarSet0, VarSet1,
 		PredId, ProcId, PredTableVar, GetTableGoal),
-	generate_lookup_goals(Vars, PredTableVar, TableVar, Module,
-		VarTypes1, VarTypes, VarSet1, VarSet, LookupGoals),
+	generate_lookup_goals(Vars, PredTableVar, TableVar, 
+		VarTypes1, VarTypes, VarSet1, VarSet, TableInfo0, TableInfo,
+		LookupGoals),
 
 	GoalEx = conj([GetTableGoal | LookupGoals]),
 	set__singleton_set(NonLocals0, TableVar),
@@ -669,19 +686,22 @@
 	goal_info_init(NonLocals, InstMapDelta, det, GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-:- pred generate_non_lookup_goal(list(prog_var), module_info, pred_id, proc_id,
-	map(prog_var, type), map(prog_var, type), prog_varset,
-	prog_varset, prog_var, hlds_goal).
-:- mode generate_non_lookup_goal(in, in, in, in, in, out, in, out, out, out)
-	is det.
-
-generate_non_lookup_goal(Vars, Module, PredId, ProcId, VarTypes0, VarTypes,
-		VarSet0, VarSet, SubgoalVar, Goal) :-
+:- pred generate_non_lookup_goal(list(prog_var), pred_id, proc_id,
+		map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info,
+		prog_var, hlds_goal).
+:- mode generate_non_lookup_goal(in, in, in, in, out, in, out, in, out,
+		out, out) is det.
+
+generate_non_lookup_goal(Vars, PredId, ProcId, VarTypes0, VarTypes,
+		VarSet0, VarSet, TableInfo0, TableInfo, SubgoalVar, Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
 
 	generate_get_table_goal(VarTypes0, VarTypes1, VarSet0, VarSet1,
 		PredId, ProcId, PredTableVar, GetTableGoal),
-	generate_lookup_goals(Vars, PredTableVar, TableNodeVar, Module,
-		VarTypes1, VarTypes2, VarSet1, VarSet2, LookupGoals),
+	generate_lookup_goals(Vars, PredTableVar, TableNodeVar,
+		VarTypes1, VarTypes2, VarSet1, VarSet2, TableInfo0, TableInfo,
+		LookupGoals),
 	generate_new_table_var("SubgoalVar", VarTypes2, VarTypes,
 		VarSet2, VarSet, SubgoalVar),
 	generate_call("table_nondet_setup", [TableNodeVar, SubgoalVar],
@@ -697,35 +717,41 @@
 	goal_info_init(NonLocals, InstMapDelta, det, GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-:- pred generate_lookup_goals(list(prog_var), prog_var, prog_var, module_info,
-		map(prog_var, type), map(prog_var, type), prog_varset,
-		prog_varset, list(hlds_goal)).
-:- mode generate_lookup_goals(in, in, out, in, in, out, in, out, out) is det.
-
-generate_lookup_goals([], TableVar, TableVar, _, VarTypes, VarTypes, VarSet,
-		VarSet, []).
-generate_lookup_goals([Var|Rest], TableVar0, TableVar, Module, VarTypes0,
-		VarTypes, VarSet0, VarSet, [Goal|RestGoals]) :-
+:- pred generate_lookup_goals(list(prog_var), prog_var, prog_var,
+		map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info,
+		list(hlds_goal)).
+:- mode generate_lookup_goals(in, in, out, in, out, in, out, in, out, out)
+		is det.
+
+generate_lookup_goals([], TableVar, TableVar,
+		VarTypes, VarTypes, VarSet, VarSet, TableInfo, TableInfo, []).
+generate_lookup_goals([Var|Rest], TableVar0, TableVar,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		[Goal|RestGoals]) :-
+	table_info_get_module_info(TableInfo0, Module),
 	map__lookup(VarTypes0, Var, VarType),
-
 	classify_type(VarType, Module, TypeCat),
 	gen_lookup_call_for_type(TypeCat, VarType, TableVar0, Var,
-		Module, VarTypes0, VarTypes1, VarSet0, VarSet1, TableVar1,
-		Goal),
-	generate_lookup_goals(Rest, TableVar1, TableVar, Module,
-		VarTypes1, VarTypes, VarSet1, VarSet, RestGoals).
+		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
+		TableVar1, Goal),
+	generate_lookup_goals(Rest, TableVar1, TableVar, 
+		VarTypes1, VarTypes, VarSet1, VarSet, TableInfo1, TableInfo,
+		RestGoals).
 
 :- pred gen_lookup_call_for_type(builtin_type, type, prog_var, prog_var,
-		module_info, map(prog_var, type), map(prog_var, type),
-		prog_varset, prog_varset, prog_var, hlds_goal).
-:- mode gen_lookup_call_for_type(in, in, in, in, in, in, out, in,
-		out, out, out) is det.
+		map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info,
+		prog_var, hlds_goal).
+:- mode gen_lookup_call_for_type(in, in, in, in, in, out, in, out, in, out,
+		out, out) is det.
+
+gen_lookup_call_for_type(TypeCat, Type, TableVar, ArgVar,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		NextTableVar, Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
 
-gen_lookup_call_for_type(TypeCat, Type, TableVar, ArgVar, Module, VarTypes0,
-		VarTypes, VarSet0, VarSet, NextTableVar, Goal) :-
-	(
-		TypeCat = enum_type
-	->
+	( TypeCat = enum_type ->
 		(
 			type_to_type_id(Type, TypeId, _)
 		->
@@ -757,23 +783,19 @@
 				NonLocals),
 			instmap_delta_from_assoc_list([], InstMapDelta),
 			goal_info_init(NonLocals, InstMapDelta, det, GoalInfo),
-			Goal = conj([RangeUnifyGoal, LookupGoal]) - GoalInfo
+			Goal = conj([RangeUnifyGoal, LookupGoal]) - GoalInfo,
+			TableInfo = TableInfo0
 		;
 			error("gen_lookup: unexpected type")
 		)
 	;
 		(
-			(
-				TypeCat = pred_type
-			;
-				TypeCat = polymorphic_type
-			;
-				TypeCat = user_type
+			( TypeCat = pred_type
+			; TypeCat = polymorphic_type
+			; TypeCat = user_type
 			)
 		->
-			(
-				term__vars(Type, [])
-			->
+			( type_util__vars(Type, []) ->
 				LookupPredName = "table_lookup_insert_user"
 			;
 				LookupPredName = "table_lookup_insert_poly"
@@ -783,22 +805,33 @@
 			string__append("table_lookup_insert_", CatString,
 				LookupPredName)
 		),
-		generate_new_table_var("TableNodeVar", VarTypes0, VarTypes,
-			VarSet0, VarSet, NextTableVar),
-		generate_call(LookupPredName, [TableVar, ArgVar, NextTableVar],
-			det, impure, [NextTableVar - ground(unique, no)],
-			Module, Goal)
+		generate_new_table_var("TableNodeVar", VarTypes0, VarTypes1,
+			VarSet0, VarSet1, NextTableVar),
+
+		make_type_info_var(Type, TypeInfoVar, ExtraGoals,
+			VarTypes1, VarTypes, VarSet1, VarSet,
+			TableInfo0, TableInfo),
+
+		InstMapAL = [NextTableVar - ground(unique, no)],
+		generate_call(LookupPredName,
+			[TypeInfoVar, TableVar, ArgVar, NextTableVar],
+			det, impure, InstMapAL, Module, CallGoal),
+
+		list__append(ExtraGoals, [CallGoal], ConjList),
+		CallGoal = _ - GoalInfo,
+		conj_list_to_goal(ConjList, GoalInfo, Goal)
 	).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred generate_save_goal(list(prog_var), prog_var, map(prog_var, type),
 		map(prog_var, type), prog_varset, prog_varset,
-		module_info, hlds_goal).
-:- mode generate_save_goal(in, in, in, out, in, out, in, out) is det.
+		table_info, table_info, hlds_goal).
+:- mode generate_save_goal(in, in, in, out, in, out, in, out, out) is det.
 
-generate_save_goal(AnsList, TableVar, VarTypes0, VarTypes, VarSet0,
-		VarSet, Module, Goal) :-
+generate_save_goal(AnsList, TableVar, VarTypes0, VarTypes, VarSet0, VarSet,
+		TableInfo0, TableInfo, Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
 
 	list__length(AnsList, NumAnsVars),
 	(
@@ -816,8 +849,9 @@
 			[AnsTableVar - ground(unique, no)], Module,
 			CreateAnsBlockGoal),
 
-		generate_save_goals(AnsList, AnsTableVar, 0, Module,
-			VarTypes2, VarTypes, VarSet2, VarSet, SaveGoals),
+		generate_save_goals(AnsList, AnsTableVar, 0,
+			VarTypes2, VarTypes, VarSet2, VarSet,
+			TableInfo0, TableInfo, SaveGoals),
 
 		GoalEx = conj([NumAnsVarsUnifyGoal, CreateAnsBlockGoal |
 			SaveGoals]),
@@ -832,24 +866,27 @@
 		VarTypes = VarTypes0,
 		VarSet = VarSet0,
 		generate_call("table_mark_as_succeeded", [TableVar], det,
-			impure, [], Module, Goal)
+			impure, [], Module, Goal),
+		TableInfo = TableInfo0
 	).
 
 :- pred generate_non_save_goal(list(prog_var), prog_var, map(prog_var, type),
 		map(prog_var, type), prog_varset, prog_varset,
-		module_info, hlds_goal).
-:- mode generate_non_save_goal(in, in, in, out, in, out, in, out) is det.
+		table_info, table_info, hlds_goal).
+:- mode generate_non_save_goal(in, in, in, out, in, out, in, out, out) is det.
 
 generate_non_save_goal(AnsList, TableVar, VarTypes0, VarTypes,
-		VarSet0, VarSet, Module, Goal) :-
+		VarSet0, VarSet, TableInfo0, TableInfo, Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
 
 	generate_new_table_var("AnswerTableVar", VarTypes0, VarTypes1,
 		VarSet0, VarSet1, AnsTableVar0),
 	generate_call("table_nondet_get_ans_table", [TableVar, AnsTableVar0],
 		det, impure, [AnsTableVar0 - ground(unique, no)],
 		Module, GetAnsTableGoal),
-	generate_lookup_goals(AnsList, AnsTableVar0, AnsTableVar1, Module,
-		VarTypes1, VarTypes2, VarSet1, VarSet2, LookupAnsGoals),
+	generate_lookup_goals(AnsList, AnsTableVar0, AnsTableVar1,
+		VarTypes1, VarTypes2, VarSet1, VarSet2, TableInfo0, TableInfo1,
+		LookupAnsGoals),
 	generate_call("table_nondet_answer_is_not_duplicate", [AnsTableVar1],
 		semidet, impure, [], Module, DuplicateCheckGoal),
 
@@ -869,8 +906,8 @@
 		[AnsBlockVar - ground(unique, no)],
 		Module, CreateAnsBlockGoal),
 
-	generate_save_goals(AnsList, AnsBlockVar, 0, Module, VarTypes5,
-		VarTypes, VarSet5, VarSet, SaveGoals),
+	generate_save_goals(AnsList, AnsBlockVar, 0, VarTypes5,
+		VarTypes, VarSet5, VarSet, TableInfo1, TableInfo, SaveGoals),
 
 	list__append([GetAnsTableGoal | LookupAnsGoals],
 		[DuplicateCheckGoal, NewAnsSlotGoal, NumAnsVarsUnifyGoal,
@@ -884,49 +921,73 @@
 	goal_info_init(NonLocals, InstMapDelta, semidet,  GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-:- pred generate_save_goals(list(prog_var), prog_var, int, module_info,
-		map(prog_var, type), map(prog_var, type), prog_varset,
-		prog_varset, list(hlds_goal)).
-:- mode generate_save_goals(in, in, in, in, in, out, in, out, out) is det.
-
-generate_save_goals([], _TableVar, _Offset, _Module, VarTypes, VarTypes,
-		VarSet, VarSet, []).
-generate_save_goals([Var|Rest], TableVar, Offset0, Module, VarTypes0,
-		VarTypes, VarSet0, VarSet, [OffsetUnifyGoal,
-		CallGoal|RestGoals]) :-
+:- pred generate_save_goals(list(prog_var), prog_var, int,
+		map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info,
+		list(hlds_goal)).
+:- mode generate_save_goals(in, in, in, in, out, in, out, in, out, out) is det.
+
+generate_save_goals([], _TableVar, _Offset,
+		VarTypes, VarTypes, VarSet, VarSet, TableInfo, TableInfo, []).
+generate_save_goals([Var|Rest], TableVar, Offset0,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		Goals) :-
 
 	gen_int_construction("OffsetVar", Offset0, VarTypes0, VarTypes1,
 		VarSet0, VarSet1, OffsetVar, OffsetUnifyGoal),
 
+	table_info_get_module_info(TableInfo0, Module),
 	map__lookup(VarTypes1, Var, VarType),
 	classify_type(VarType, Module, TypeCat),
 
 	gen_save_call_for_type(TypeCat, VarType, TableVar, Var, OffsetVar,
-		Module, CallGoal),
+		VarTypes1, VarTypes2, VarSet1, VarSet2, TableInfo0, TableInfo1,
+		CallGoal),
 
 	Offset is Offset0 + 1,
-	generate_save_goals(Rest, TableVar, Offset, Module, VarTypes1,
-		VarTypes, VarSet1, VarSet, RestGoals).
+	generate_save_goals(Rest, TableVar, Offset,
+		VarTypes2, VarTypes, VarSet2, VarSet, TableInfo1, TableInfo,
+		RestGoals),
+	
+	Goals =	[OffsetUnifyGoal, CallGoal | RestGoals].
 
 :- pred gen_save_call_for_type(builtin_type, type, prog_var, prog_var,
-		prog_var, module_info, hlds_goal).
-:- mode gen_save_call_for_type(in, in, in, in, in, in, out) is det.
+		prog_var, map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info, hlds_goal).
+:- mode gen_save_call_for_type(in, in, in, in, in, in, out, in, out, in, out,
+		out) is det.
 
-gen_save_call_for_type(TypeCat, _Type, TableVar, Var, OffsetVar, Module,
+gen_save_call_for_type(TypeCat, Type, TableVar, Var, OffsetVar,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
 		Goal) :-
+	table_info_get_module_info(TableInfo0, Module),
 	(
 		not_builtin_type(TypeCat)
 	->
-		LookupPredName = "table_save_any_ans"
+		make_type_info_var(Type, TypeInfoVar, ExtraGoals,
+			VarTypes0, VarTypes, VarSet0, VarSet,
+			TableInfo0, TableInfo),
+
+		generate_call("table_save_any_ans",
+			[TypeInfoVar, TableVar, OffsetVar, Var],
+			det, impure, [], Module, CallGoal),
+
+		list__append(ExtraGoals, [CallGoal], ConjList),
+		CallGoal = _ - GoalInfo,
+		conj_list_to_goal(ConjList, GoalInfo, Goal)
 	;
 		builtin_type_to_string(TypeCat, CatString),
 		string__append_list(["table_save_", CatString, "_ans"],
-			LookupPredName)
-	),
-	generate_call(LookupPredName, [TableVar, OffsetVar, Var],
-		det, impure, [], Module, Goal).
+			LookupPredName),
+		generate_call(LookupPredName, [TableVar, OffsetVar, Var],
+			det, impure, [], Module, Goal),
+
+		VarTypes = VarTypes0,
+		VarSet = VarSet0,
+		TableInfo = TableInfo0
+	).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred generate_restore_goal(list(prog_var), prog_var, module_info,
 		map(prog_var, type), map(prog_var, type), prog_varset,
@@ -1017,7 +1078,7 @@
 	generate_call(LookupPredName, [TableVar, OffsetVar, Var],
 		det, impure, [Var - ground(shared, no)], Module, Goal).
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred generate_suspend_goal(list(prog_var), prog_var, module_info,
 		map(prog_var, type), map(prog_var, type), prog_varset,
@@ -1046,14 +1107,17 @@
 		GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
-:- pred generate_loop_error_goal(pred_info, module_info, map(prog_var, type),
+:- pred generate_loop_error_goal(table_info, map(prog_var, type),
 		map(prog_var, type), prog_varset, prog_varset, hlds_goal).
-:- mode generate_loop_error_goal(in, in, in, out, in, out, out) is det.
+:- mode generate_loop_error_goal(in, in, out, in, out, out) is det.
 
-generate_loop_error_goal(PredInfo, ModuleInfo, VarTypes0, VarTypes,
+generate_loop_error_goal(TableInfo, VarTypes0, VarTypes,
 		VarSet0, VarSet, Goal) :-
+	table_info_get_module_info(TableInfo, ModuleInfo),
+	table_info_get_pred_info(TableInfo, PredInfo),
+
 	pred_info_module(PredInfo, Module),
 	pred_info_name(PredInfo, Name),
 	pred_info_arity(PredInfo, Arity),
@@ -1078,7 +1142,7 @@
 		GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 :- pred generate_new_table_var(string,
 		map(prog_var, type), map(prog_var, type),
@@ -1114,6 +1178,15 @@
 	->
 		PredId = PredId0
 	;
+		% Some of the table builtins are polymorphic,
+		% and for them we need to subtract one from the arity
+		% to take into account the type_info argument.
+		predicate_table_search_pred_m_n_a(PredTable,
+			BuiltinModule, PredName, Arity - 1,
+			[PredId0])
+	->
+		PredId = PredId0
+	;
 		string__int_to_string(Arity, ArityS),
 		string__append_list(["can't locate ", PredName,
 			"/", ArityS], ErrorMessage),
@@ -1270,3 +1343,101 @@
 builtin_type_to_string(enum_type, 	"enum").
 builtin_type_to_string(polymorphic_type, "any").
 builtin_type_to_string(user_type, 	"any").
+
+%-----------------------------------------------------------------------------%
+
+:- pred table_gen__make_type_info_var(type, prog_var,
+		list(hlds_goal), map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info) is det.
+:- mode table_gen__make_type_info_var(in, out, out,
+		in, out, in, out, in, out) is det.
+
+table_gen__make_type_info_var(Type, TypeInfoVar, TypeInfoGoals,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo) :-
+	table_gen__make_type_info_vars([Type], TypeInfoVars, TypeInfoGoals,
+			VarTypes0, VarTypes, VarSet0, VarSet,
+			TableInfo0, TableInfo),
+	( TypeInfoVars = [TypeInfoVar0] ->
+		TypeInfoVar = TypeInfoVar0
+	;
+		error("table_gen__make_type_info_var: list length != 1")
+	).
+
+:- pred table_gen__make_type_info_vars(list(type), list(prog_var),
+		list(hlds_goal), map(prog_var, type), map(prog_var, type),
+		prog_varset, prog_varset, table_info, table_info) is det.
+:- mode table_gen__make_type_info_vars(in, out, out,
+		in, out, in, out, in, out) is det.
+
+table_gen__make_type_info_vars(Types, TypeInfoVars, TypeInfoGoals,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo) :-
+	%
+	% Extract the information from table_info
+	%
+	table_info_extract(TableInfo0, ModuleInfo0, PredInfo0, ProcInfo0),
+
+	%
+	% Put the varset and vartypes from the simplify_info
+	% back in the proc_info
+	%
+	proc_info_set_vartypes(ProcInfo0, VarTypes0, ProcInfo1),
+	proc_info_set_varset(ProcInfo1, VarSet0, ProcInfo2),
+
+	%
+	% Call polymorphism.m to create the type_infos
+	%
+	create_poly_info(ModuleInfo0, PredInfo0, ProcInfo2, PolyInfo0),
+	ExistQVars = [],
+	term__context_init(Context),
+	polymorphism__make_type_info_vars(Types, ExistQVars, Context,
+		TypeInfoVars, TypeInfoGoals, PolyInfo0, PolyInfo),
+	poly_info_extract(PolyInfo, PredInfo0, PredInfo,
+		ProcInfo0, ProcInfo, ModuleInfo),
+
+	%
+	% Get the new varset and vartypes from the proc_info
+	%
+	proc_info_vartypes(ProcInfo, VarTypes),
+	proc_info_varset(ProcInfo, VarSet),
+
+	%
+	% Put the new module_info, pred_info, and proc_info back in the
+	% table_info.
+	%
+	table_info_init(ModuleInfo, PredInfo, ProcInfo, TableInfo).
+
+%-----------------------------------------------------------------------------%
+
+:- type table_info ---> table_info(module_info, pred_info, proc_info).
+
+:- pred table_info_init(module_info, pred_info, proc_info, table_info).
+:- mode table_info_init(in, in, in, out) is det.
+
+:- pred table_info_extract(table_info, module_info, pred_info, proc_info).
+:- mode table_info_extract(in, out, out, out) is det.
+
+:- pred table_info_get_module_info(table_info, module_info).
+:- mode table_info_get_module_info(in, out) is det.
+
+:- pred table_info_get_pred_info(table_info, pred_info).
+:- mode table_info_get_pred_info(in, out) is det.
+
+:- pred table_info_get_proc_info(table_info, proc_info).
+:- mode table_info_get_proc_info(in, out) is det.
+
+table_info_init(ModuleInfo, PredInfo, ProcInfo, TableInfo) :-
+	TableInfo = table_info(ModuleInfo, PredInfo, ProcInfo).
+
+table_info_extract(TableInfo, ModuleInfo, PredInfo, ProcInfo) :-
+	TableInfo = table_info(ModuleInfo, PredInfo, ProcInfo).
+
+table_info_get_module_info(TableInfo, ModuleInfo) :-
+	TableInfo = table_info(ModuleInfo, _PredInfo, _ProcInfo).
+
+table_info_get_pred_info(TableInfo, PredInfo) :-
+	TableInfo = table_info(_ModuleInfo, PredInfo, _ProcInfo).
+
+table_info_get_proc_info(TableInfo, ProcInfo) :-
+	TableInfo = table_info(_ModuleInfo, _PredInfo, ProcInfo).
+
+%-----------------------------------------------------------------------------%
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.52.2.1
diff -u -r1.52.2.1 unique_modes.m
--- unique_modes.m	1999/06/12 00:50:41	1.52.2.1
+++ unique_modes.m	1999/06/12 03:27:09
@@ -395,7 +395,8 @@
 		NeverSucceeds = no
 	},
 	{ determinism_to_code_model(Det, CodeModel) },
-	unique_modes__check_call_modes(Args, Modes, CodeModel, NeverSucceeds),
+	unique_modes__check_call_modes(Args, Modes, 0,
+			CodeModel, NeverSucceeds),
 	{ Goal = higher_order_call(PredVar, Args, Types, Modes, Det,
 			PredOrFunc) },
 	mode_info_unset_call_context,
@@ -416,7 +417,8 @@
 		NeverSucceeds = no
 	},
 	{ determinism_to_code_model(Det, CodeModel) },
-	unique_modes__check_call_modes(Args, Modes, CodeModel, NeverSucceeds),
+	unique_modes__check_call_modes(Args, Modes, 0,
+			CodeModel, NeverSucceeds),
 	{ Goal = class_method_call(TCVar, Num, Args, Types, Modes, Det) },
 	mode_info_unset_call_context,
 	mode_checkpoint(exit, "class method call").
@@ -490,12 +492,14 @@
 	% first off, try using the existing mode
 	%
 	mode_info_get_module_info(ModeInfo0, ModuleInfo),
-	module_info_pred_proc_info(ModuleInfo, PredId, ProcId0, _, ProcInfo),
+	module_info_pred_proc_info(ModuleInfo, PredId, ProcId0,
+		PredInfo, ProcInfo),
+	compute_arg_offset(PredInfo, ArgOffset),
 	proc_info_argmodes(ProcInfo, ProcArgModes0),
 	proc_info_interface_code_model(ProcInfo, CodeModel),
 	proc_info_never_succeeds(ProcInfo, NeverSucceeds),
-	unique_modes__check_call_modes(ArgVars, ProcArgModes0, CodeModel,
-				NeverSucceeds, ModeInfo1, ModeInfo2),
+	unique_modes__check_call_modes(ArgVars, ProcArgModes0, ArgOffset,
+			CodeModel, NeverSucceeds, ModeInfo1, ModeInfo2),
 
 	%
 	% see whether or not that worked
@@ -550,21 +554,21 @@
 	% argument if the variable is nondet-live and the required initial
 	% inst was unique.
 
-:- pred unique_modes__check_call_modes(list(prog_var), list(mode), code_model,
-		bool, mode_info, mode_info).
-:- mode unique_modes__check_call_modes(in, in, in, in,
+:- pred unique_modes__check_call_modes(list(prog_var), list(mode), int,
+		code_model, bool, mode_info, mode_info).
+:- mode unique_modes__check_call_modes(in, in, in, in, in,
 			mode_info_di, mode_info_uo) is det.
 
-unique_modes__check_call_modes(ArgVars, ProcArgModes, CodeModel, NeverSucceeds,
-			ModeInfo0, ModeInfo) :-
+unique_modes__check_call_modes(ArgVars, ProcArgModes, ArgOffset,
+		CodeModel, NeverSucceeds, ModeInfo0, ModeInfo) :-
 	mode_info_get_module_info(ModeInfo0, ModuleInfo),
 	mode_list_get_initial_insts(ProcArgModes, ModuleInfo,
 				InitialInsts),
-	modecheck_var_has_inst_list(ArgVars, InitialInsts, 0,
+	modecheck_var_has_inst_list(ArgVars, InitialInsts, ArgOffset,
 				ModeInfo0, ModeInfo1),
 	mode_list_get_final_insts(ProcArgModes, ModuleInfo, FinalInsts),
 	modecheck_set_var_inst_list(ArgVars, InitialInsts, FinalInsts,
-		NewArgVars, ExtraGoals, ModeInfo1, ModeInfo2),
+		ArgOffset, NewArgVars, ExtraGoals, ModeInfo1, ModeInfo2),
 	( NewArgVars = ArgVars, ExtraGoals = no_extra_goals ->
 		true
 	;	
Index: tests/term/arit_exp.trans_opt_exp
===================================================================
RCS file: /home/mercury1/repository/tests/term/arit_exp.trans_opt_exp,v
retrieving revision 1.3
diff -u -r1.3 arit_exp.trans_opt_exp
--- arit_exp.trans_opt_exp	1998/05/25 21:54:59	1.3
+++ arit_exp.trans_opt_exp	1999/06/13 05:31:14
@@ -1,2 +1,3 @@
 :- module arit_exp.
 :- pragma termination_info(arit_exp:e((builtin:in)), finite(0, [no]), cannot_loop).
+:- pragma termination_info(arit_exp:f((builtin:in)), finite(0, [no]), cannot_loop).
Index: tests/term/associative.trans_opt_exp
===================================================================
RCS file: /home/mercury1/repository/tests/term/associative.trans_opt_exp,v
retrieving revision 1.5
diff -u -r1.5 associative.trans_opt_exp
--- associative.trans_opt_exp	1998/06/29 06:58:40	1.5
+++ associative.trans_opt_exp	1999/06/13 05:31:14
@@ -1,2 +1,3 @@
 :- module associative.
 :- pragma termination_info(associative:normal_form((builtin:in), (builtin:out)), finite(0, [yes, no]), can_loop).
+:- pragma termination_info(associative:rewrite((builtin:in), (builtin:out)), finite(0, [yes, no]), cannot_loop).
Index: tests/term/pl5_2_2.trans_opt_exp
===================================================================
RCS file: /home/mercury1/repository/tests/term/pl5_2_2.trans_opt_exp,v
retrieving revision 1.3
diff -u -r1.3 pl5_2_2.trans_opt_exp
--- pl5_2_2.trans_opt_exp	1998/05/25 21:55:19	1.3
+++ pl5_2_2.trans_opt_exp	1999/06/13 05:31:14
@@ -1,2 +1,3 @@
 :- module pl5_2_2.
 :- pragma termination_info(pl5_2_2:turing((builtin:in), (builtin:in), (builtin:in), (builtin:out)), infinite, can_loop).
+:- pragma termination_info(pl5_2_2:member((builtin:out), (builtin:in)), finite(-1, [no, no, yes]), cannot_loop).
Index: tests/term/vangelder.trans_opt_exp
===================================================================
RCS file: /home/mercury1/repository/tests/term/vangelder.trans_opt_exp,v
retrieving revision 1.3
diff -u -r1.3 vangelder.trans_opt_exp
--- vangelder.trans_opt_exp	1998/05/25 21:55:28	1.3
+++ vangelder.trans_opt_exp	1999/06/13 05:31:15
@@ -1,2 +1,4 @@
 :- module vangelder.
 :- pragma termination_info(vangelder:q((builtin:in), (builtin:in)), finite(0, [no, no]), can_loop).
+:- pragma termination_info(vangelder:p((builtin:in), (builtin:in)), finite(0, [no, no]), can_loop).
+:- pragma termination_info(vangelder:e((builtin:in), (builtin:in)), finite(0, [no, no]), cannot_loop).

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list