[m-dev.] for review: alias branch improvements [1/2]

David Overton dmo at cs.mu.OZ.AU
Fri Jul 23 18:23:21 AEST 1999


Hi,

This is for Fergus to review, please.


David

Estimated hours taken: 30

Improve handling of aliasing in the modes of procedure arguments, in
particular for unification procedures.
Re-organise the inst_table and place it in a new module together with
the predicates that operate on it.

compiler/inst_match.m:
	Fix inst_matches_initial and inst_matches_final so that they
	work properly in the presence of aliasing.  This requires a
	new pair of arguments, of type alias_map, which should
	be threaded through the calls to inst_matches_{initial,final}
	for each argument of the call being checked.

	Add new predicates inst_matches_initial_ignore_aliasing and
	inst_matches_final_ignore_aliasing which work the same as
	the old inst_matches_{initial,final}.  This is for cases where
	inst_matches_{initial,final} were just being used to compare
	the binding and uniqueness of two insts rather than actually
	checking whether a set of insts are compatible with the
	initial/final insts of a procedure's arguments.

compiler/unify_proc.m:
	Fix the code that deals with requests for unification
	procedures so that it works properly in the presence of
	aliasing.  Previously, it was just using structural
	equivalence of insts to check whether a requested unification
	procedure was already in the unify_req_map.
	This makes use of the modified inst_matches_final predicate.

compiler/instmap.m:
compiler/modecheck_call.m:
compiler/modes.m:
compiler/pd_info.m:
compiler/unique_modes.m:
	Change calls to inst_matches_{initial,final} to either pass
	a pair of alias_map arguments or use the `_ignore_aliasing'
	version instead.

compiler/modecheck_unify.m:
	Change the arguments passed to unify_proc__request_unify.
	Pass the instmap from _before_ the unification to
	modecheck_complicated_unify.

compiler/simplify.m:
	Change call to unify_proc__lookup_mode_num to pass the correct
	arguments.

compiler/hlds_data.m:
compiler/inst_util.m:
	Move inst_table related stuff to inst_table.m.

compiler/inst_table.m:
	New module for the inst_table and related stuff.  Changed the
	substitution_inst_table to a more generally useful
	other_inst_table which can be used by many transformations that
	turn one recursive inst into another.
	Having this new module allows parts of the inst_table to
	become more abstract by including all predicates that operate
	on the inst_table as a whole in the same module.
	It also means that prog_data no longer needs to import
	hlds_data just to get the definition of the inst_table type.

compiler/instmap.m:
	Use other_inst_table instead of substitution_inst_table when
	expanding alias substitutions.

compiler/prog_data.m:
	Add a new ADT other_inst_id for identifying entries in
	other_inst_table.  This is in prog_data.m because it is
	reffered to by the inst_name type which is defined here.
	Change the inst_name type to have a other_inst functor instead
	of the substitution_inst functor.

compiler/mode_util.m:
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
	Change predicates that use the inst_name type to handle the
	new other_inst functor instead of the substitution_inst functor.

compiler/mode_util.m:
	Rename apply_inst_key_sub_mode to apply_inst_table_sub_mode
	and change it to take an inst_table_sub instead of an
	inst_key_sub.

compiler/higher_order.m:
compiler/modecheck_call.m:
compiler/modecheck_unify.m:
	s/inst_apply_sub/inst_apply_inst_table_sub/g
	s/apply_inst_key_sub_mode/apply_inst_table_sub_mode/g

compiler/*.m:
	Import the new inst_table module where necessary.
	Remove imports of hlds_data where possible.

Index: accumulator.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/accumulator.m,v
retrieving revision 1.1.2.3
diff -u -u -r1.1.2.3 accumulator.m
--- accumulator.m	1999/07/19 01:44:10	1.1.2.3
+++ accumulator.m	1999/07/21 06:22:11
@@ -97,6 +97,7 @@
 
 :- import_module goal_util, globals, hlds_data, hlds_goal, hlds_out, (inst).
 :- import_module inst_match, instmap, mode_util, options, prog_data, prog_util.
+:- import_module inst_table.
 
 :- import_module assoc_list, bool, list, map, multi_map.
 :- import_module require, set, std_util, term, varset.
Index: arg_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/arg_info.m,v
retrieving revision 1.23.4.13
diff -u -u -r1.23.4.13 arg_info.m
--- arg_info.m	1999/06/03 01:38:20	1.23.4.13
+++ arg_info.m	1999/07/21 06:22:22
@@ -17,8 +17,8 @@
 
 :- module arg_info.
 :- interface. 
-:- import_module hlds_module, hlds_data, hlds_pred, llds, prog_data.
-:- import_module instmap.
+:- import_module hlds_module, hlds_pred, llds, prog_data.
+:- import_module instmap, inst_table.
 :- import_module list, assoc_list.
 
 :- pred generate_arg_info(module_info, module_info).
Index: bytecode_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.30.2.14
diff -u -u -r1.30.2.14 bytecode_gen.m
--- bytecode_gen.m	1999/07/19 01:44:11	1.30.2.14
+++ bytecode_gen.m	1999/07/21 06:22:49
@@ -26,7 +26,7 @@
 
 :- import_module hlds_pred, hlds_goal, hlds_data, prog_data, llds, arg_info.
 :- import_module passes_aux, call_gen, mode_util, code_util, goal_util.
-:- import_module globals, tree, (inst), instmap, varset, term.
+:- import_module globals, tree, (inst), instmap, inst_table.
 
 :- import_module bool, int, string, list, assoc_list, set, map, varset.
 :- import_module std_util, require, term.
Index: clause_to_proc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.16.4.9
diff -u -u -r1.16.4.9 clause_to_proc.m
--- clause_to_proc.m	1999/07/13 04:42:58	1.16.4.9
+++ clause_to_proc.m	1999/07/21 06:23:26
@@ -49,7 +49,7 @@
 :- implementation.
 
 :- import_module hlds_goal, hlds_data, prog_data, mode_util, make_hlds, purity.
-:- import_module globals.
+:- import_module globals, inst_table.
 :- import_module bool, int, set, map.
 
 maybe_add_default_modes([], Preds, Preds).
Index: code_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.211.2.22
diff -u -u -r1.211.2.22 code_info.m
--- code_info.m	1999/06/04 01:47:16	1.211.2.22
+++ code_info.m	1999/07/21 05:21:36
@@ -31,6 +31,7 @@
 
 :- import_module hlds_module, hlds_pred, hlds_goal, llds, instmap, trace.
 :- import_module continuation_info, prog_data, hlds_data, globals.
+:- import_module inst_table.
 
 :- import_module bool, set, list, map, std_util, assoc_list.
 
Index: common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/common.m,v
retrieving revision 1.44.4.13
diff -u -u -r1.44.4.13 common.m
--- common.m	1999/07/19 01:44:17	1.44.4.13
+++ common.m	1999/07/21 06:23:51
@@ -79,7 +79,7 @@
 
 :- implementation.
 
-:- import_module quantification, mode_util, type_util, prog_util.
+:- import_module quantification, mode_util, type_util, prog_util, inst_table.
 :- import_module det_util, det_report, globals, options, inst_match, instmap.
 :- import_module hlds_data, hlds_module, (inst), pd_cost, term.
 :- import_module bool, map, set, eqvclass, require, std_util, string.
Index: continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.3.4.13
diff -u -u -r1.3.4.13 continuation_info.m
--- continuation_info.m	1999/07/19 01:44:18	1.3.4.13
+++ continuation_info.m	1999/07/22 01:22:52
@@ -51,8 +51,8 @@
 
 :- interface.
 
-:- import_module llds, hlds_module, hlds_pred, hlds_data, prog_data.
-:- import_module (inst), instmap, trace, globals.
+:- import_module llds, hlds_module, hlds_pred, prog_data.
+:- import_module (inst), instmap, inst_table, trace, globals.
 :- import_module std_util, bool, list, assoc_list, set, map.
 
 	%
Index: cse_detection.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.48.2.10
diff -u -u -r1.48.2.10 cse_detection.m
--- cse_detection.m	1999/07/19 01:44:19	1.48.2.10
+++ cse_detection.m	1999/07/21 06:24:12
@@ -36,6 +36,7 @@
 :- import_module hlds_goal, hlds_data, options, globals, goal_util, hlds_out.
 :- import_module modes, mode_util, make_hlds, quantification, instmap.
 :- import_module prog_data, switch_detection, det_util, inst_match, (inst).
+:- import_module inst_table.
 :- import_module term, varset.
 
 :- import_module int, bool, list, map, set, std_util, require.
Index: deforest.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deforest.m,v
retrieving revision 1.3.2.9
diff -u -u -r1.3.2.9 deforest.m
--- deforest.m	1999/07/19 01:44:21	1.3.2.9
+++ deforest.m	1999/07/21 06:24:31
@@ -28,7 +28,7 @@
 
 :- import_module pd_cost, pd_debug, pd_info, pd_term, pd_util.
 :- import_module hlds_pred, hlds_goal, inlining, passes_aux.
-:- import_module (inst), instmap, inst_match, simplify.
+:- import_module (inst), instmap, inst_table, inst_match, simplify.
 :- import_module dependency_graph, hlds_data, det_analysis, globals.
 :- import_module mode_util, goal_util, prog_data, prog_util, purity.
 :- import_module modes, mode_info, unique_modes, options, hlds_out.
Index: det_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_util.m,v
retrieving revision 1.12.4.10
diff -u -u -r1.12.4.10 det_util.m
--- det_util.m	1999/07/19 01:44:24	1.12.4.10
+++ det_util.m	1999/07/21 05:40:12
@@ -17,7 +17,7 @@
 :- interface.
 
 :- import_module hlds_module, hlds_pred, hlds_goal, hlds_data, globals.
-:- import_module instmap, prog_data.
+:- import_module instmap, prog_data, inst_table.
 :- import_module bool, set, list.
 
 :- type maybe_changed	--->	changed ; unchanged.
Index: dnf.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dnf.m,v
retrieving revision 1.22.2.14
diff -u -u -r1.22.2.14 dnf.m
--- dnf.m	1999/07/19 01:44:24	1.22.2.14
+++ dnf.m	1999/07/21 06:24:49
@@ -60,7 +60,7 @@
 
 :- implementation.
 
-:- import_module hlds_goal, hlds_data, prog_data, instmap, (inst).
+:- import_module hlds_goal, hlds_data, prog_data, instmap, (inst), inst_table.
 :- import_module excess, make_hlds, mode_util.
 :- import_module require, map, string, int, term, varset.
 
Index: fact_table.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/fact_table.m,v
retrieving revision 1.11.4.14
diff -u -u -r1.11.4.14 fact_table.m
--- fact_table.m	1999/06/03 01:38:30	1.11.4.14
+++ fact_table.m	1999/07/21 06:25:40
@@ -93,6 +93,7 @@
 :- import_module prog_util, prog_out, llds_out, modules, hlds_out, hlds_data.
 :- import_module globals, options, passes_aux, arg_info, llds, mode_util.
 :- import_module prog_io, code_util, export, inst_match, (inst), instmap, term.
+:- import_module inst_table.
 
 :- type fact_result
 	--->	ok ; error.
Index: follow_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/follow_vars.m,v
retrieving revision 1.43.2.15
diff -u -u -r1.43.2.15 follow_vars.m
--- follow_vars.m	1999/07/19 01:44:29	1.43.2.15
+++ follow_vars.m	1999/07/21 06:25:54
@@ -29,7 +29,9 @@
 
 :- interface.
 
-:- import_module hlds_data, hlds_module, hlds_pred, hlds_goal, prog_data.
+:- import_module hlds_module, hlds_pred, hlds_goal, prog_data.
+:- import_module inst_table.
+
 :- import_module map.
 
 :- pred find_final_follow_vars(proc_info, follow_vars).
Index: goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.38.2.13
diff -u -u -r1.38.2.13 goal_util.m
--- goal_util.m	1999/07/19 01:44:30	1.38.2.13
+++ goal_util.m	1999/07/21 05:59:18
@@ -27,7 +27,7 @@
 :- interface.
 
 :- import_module hlds_data, hlds_goal, hlds_module, hlds_pred.
-:- import_module instmap, prog_data.
+:- import_module instmap, prog_data, inst_table.
 :- import_module bool, list, set, map, term.
 
 	% goal_util__rename_vars_in_goals(GoalList, MustRename, Substitution,
Index: higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.33.2.21
diff -u -u -r1.33.2.21 higher_order.m
--- higher_order.m	1999/07/19 01:44:31	1.33.2.21
+++ higher_order.m	1999/07/21 06:57:50
@@ -39,7 +39,7 @@
 :- import_module code_util, globals, make_hlds, mode_util, goal_util.
 :- import_module type_util, options, prog_data, prog_out, quantification.
 :- import_module mercury_to_mercury, inlining, polymorphism, prog_util.
-:- import_module special_pred, passes_aux, check_typeclass.
+:- import_module special_pred, passes_aux, check_typeclass, inst_table.
 :- import_module hlds_out. % YYY
 
 :- import_module assoc_list, bool, char, int, list, map, require, set.
@@ -2000,7 +2000,7 @@
 	proc_info_set_headvars(NewProcInfo4, HeadVars, NewProcInfo5),
 
 	inst_table_create_sub(InstTable0, ArgIT0, InstSub, ArgIT),
-	list__map(apply_inst_key_sub_mode(InstSub), ArgModes, NewArgModes),
+	list__map(apply_inst_table_sub_mode(InstSub), ArgModes, NewArgModes),
 	proc_info_set_argmodes(NewProcInfo5,
 		argument_modes(ArgIT, NewArgModes), NewProcInfo6),
 
Index: hlds_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_data.m,v
retrieving revision 1.17.2.16
diff -u -u -r1.17.2.16 hlds_data.m
--- hlds_data.m	1999/07/19 01:44:32	1.17.2.16
+++ hlds_data.m	1999/07/22 01:22:41
@@ -14,7 +14,7 @@
 :- interface.
 
 :- import_module hlds_pred, llds, prog_data, (inst), term.
-:- import_module bool, list, map, std_util, set_bbbtree.
+:- import_module bool, list, map, std_util.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -360,54 +360,12 @@
 
 :- interface.
 
-	% The symbol table for insts.
-
 :- type inst_id		==	pair(sym_name, arity).
 				% name, arity.
 
-:- type inst_table.
-
 :- type user_inst_table.
 :- type user_inst_defns ==	map(inst_id, hlds_inst_defn).
 
-:- type unify_inst_table ==	map(inst_name, maybe_inst_det).
-
-:- type unify_inst_pair	--->	unify_inst_pair(is_live, inst, inst,
-					unify_is_real).
-
-:- type merge_inst_table ==	map(merge_inst_pair, maybe_inst).
-
-:- type merge_inst_pair --->	merge_inst_pair(is_live, inst, inst).
-
-:- type ground_inst_table == 	map(inst_name, maybe_inst_det).
-
-:- type any_inst_table == 	map(inst_name, maybe_inst_det).
-
-:- type shared_inst_table == 	map(inst_name, maybe_inst).
-
-:- type mostly_uniq_inst_table == map(inst_name, maybe_inst).
-
-:- type substitution_inst_table == map(substitution_inst, maybe_inst).
-
-:- type clobbered_inst_table == map(inst_name, maybe_inst).
-
-:- type substitution_inst
-	--->	substitution_inst(
-			inst_name,
-			inst_key_set,	% The set of inst_keys that have
-					% had their substitutions expanded.
-			inst_key_sub	% The substitution map used to expand
-					% the substitutions.
-		).
-
-:- type inst_key_set == set_bbbtree(inst_key).
-
-:- type maybe_inst	--->	unknown
-			;	known(inst).
-
-:- type maybe_inst_det	--->	unknown
-			;	known(inst, determinism).
-
 	% An `hlds_inst_defn' holds the information we need to store
 	% about inst definitions such as
 	%	:- inst list_skel(I) = bound([] ; [I | list_skel(I)].
@@ -438,82 +396,6 @@
 						% later.  (XXX Abstract insts
 						% are not really supported.)
 
-%-----------------------------------------------------------------------------%
-
-:- pred inst_table_init(inst_table).
-:- mode inst_table_init(out) is det.
-
-:- pred inst_table_get_all_tables(inst_table, substitution_inst_table,
-	unify_inst_table, merge_inst_table, ground_inst_table, any_inst_table,
-	shared_inst_table, mostly_uniq_inst_table, clobbered_inst_table,
-	inst_key_table).
-:- mode inst_table_get_all_tables(in, out, out, out, out, out, out, out,
-	out, out) is det.
-
-:- pred inst_table_set_all_tables(inst_table, substitution_inst_table,
-	unify_inst_table, merge_inst_table, ground_inst_table, any_inst_table,
-	shared_inst_table, mostly_uniq_inst_table, clobbered_inst_table,
-	inst_key_table, inst_table).
-:- mode inst_table_set_all_tables(in, in, in, in, in, in, in, in, in, in, out)
-	is det.
-
-:- pred inst_table_get_substitution_insts(inst_table, substitution_inst_table).
-:- mode inst_table_get_substitution_insts(in, out) is det.
-
-:- pred inst_table_get_unify_insts(inst_table, unify_inst_table).
-:- mode inst_table_get_unify_insts(in, out) is det.
-
-:- pred inst_table_get_merge_insts(inst_table, merge_inst_table).
-:- mode inst_table_get_merge_insts(in, out) is det.
-
-:- pred inst_table_get_ground_insts(inst_table, ground_inst_table).
-:- mode inst_table_get_ground_insts(in, out) is det.
-
-:- pred inst_table_get_any_insts(inst_table, any_inst_table).
-:- mode inst_table_get_any_insts(in, out) is det.
-
-:- pred inst_table_get_shared_insts(inst_table, shared_inst_table).
-:- mode inst_table_get_shared_insts(in, out) is det.
-
-:- pred inst_table_get_mostly_uniq_insts(inst_table, mostly_uniq_inst_table).
-:- mode inst_table_get_mostly_uniq_insts(in, out) is det.
-
-:- pred inst_table_get_clobbered_insts(inst_table, clobbered_inst_table).
-:- mode inst_table_get_clobbered_insts(in, out) is det.
-
-:- pred inst_table_get_inst_key_table(inst_table, inst_key_table).
-:- mode inst_table_get_inst_key_table(in, out) is det.
-
-:- pred inst_table_set_substitution_insts(inst_table, substitution_inst_table,
-	inst_table).
-:- mode inst_table_set_substitution_insts(in, in, out) is det.
-
-:- pred inst_table_set_unify_insts(inst_table, unify_inst_table, inst_table).
-:- mode inst_table_set_unify_insts(in, in, out) is det.
-
-:- pred inst_table_set_merge_insts(inst_table, merge_inst_table, inst_table).
-:- mode inst_table_set_merge_insts(in, in, out) is det.
-
-:- pred inst_table_set_ground_insts(inst_table, ground_inst_table, inst_table).
-:- mode inst_table_set_ground_insts(in, in, out) is det.
-
-:- pred inst_table_set_any_insts(inst_table, any_inst_table, inst_table).
-:- mode inst_table_set_any_insts(in, in, out) is det.
-
-:- pred inst_table_set_shared_insts(inst_table, shared_inst_table, inst_table).
-:- mode inst_table_set_shared_insts(in, in, out) is det.
-
-:- pred inst_table_set_mostly_uniq_insts(inst_table, mostly_uniq_inst_table,
-					inst_table).
-:- mode inst_table_set_mostly_uniq_insts(in, in, out) is det.
-
-:- pred inst_table_set_clobbered_insts(inst_table, clobbered_inst_table,
-					inst_table).
-:- mode inst_table_set_clobbered_insts(in, in, out) is det.
-
-:- pred inst_table_set_inst_key_table(inst_table, inst_key_table, inst_table).
-:- mode inst_table_set_inst_key_table(in, in, out) is det.
-
 :- pred user_inst_table_init(user_inst_table).
 :- mode user_inst_table_init(out) is det.
 
@@ -534,19 +416,6 @@
 
 :- implementation.
 
-:- type inst_table
-	--->	inst_table(
-			substitution_inst_table,
-			unify_inst_table,
-			merge_inst_table,
-			ground_inst_table,
-			any_inst_table,
-			shared_inst_table,
-			mostly_uniq_inst_table,
-			clobbered_inst_table,
-			inst_key_table
-		).
-
 :- type user_inst_defns.
 
 :- type user_inst_table
@@ -556,92 +425,6 @@
 				% qualifying the modes of lambda expressions.
 		).
 
-inst_table_init(inst_table(SubInsts, UnifyInsts, MergeInsts, GroundInsts,
-			AnyInsts, SharedInsts, NondetLiveInsts, ClobberedInsts,
-			InstKeys)) :-
-	map__init(SubInsts),
-	map__init(UnifyInsts),
-	map__init(MergeInsts),
-	map__init(GroundInsts),
-	map__init(AnyInsts),
-	map__init(SharedInsts),
-	map__init(NondetLiveInsts),
-	map__init(ClobberedInsts),
-	inst_key_table_init(InstKeys).
-
-inst_table_get_all_tables(InstTable, SubInsts, UnifyInsts, MergeInsts,
-		GroundInsts, AnyInsts, SharedInsts, NondetLiveInsts,
-		ClobberedInsts, InstKeys) :-
-	InstTable = inst_table(SubInsts, UnifyInsts, MergeInsts, GroundInsts,
-		AnyInsts, SharedInsts, NondetLiveInsts, ClobberedInsts,
-		InstKeys).
-
-inst_table_set_all_tables(_InstTable0, SubInsts, UnifyInsts, MergeInsts,
-		GroundInsts, AnyInsts, SharedInsts, NondetLiveInsts,
-		ClobberedInsts, InstKeys, InstTable) :-
-	InstTable  = inst_table(SubInsts, UnifyInsts, MergeInsts, GroundInsts,
-		AnyInsts, SharedInsts, NondetLiveInsts, ClobberedInsts,
-		InstKeys).
-
-inst_table_get_substitution_insts(inst_table(SubInsts, _, _, _, _, _, _, _, _),
-			SubInsts).
-
-inst_table_get_unify_insts(inst_table(_, UnifyInsts, _, _, _, _, _, _, _),
-			UnifyInsts).
-
-inst_table_get_merge_insts(inst_table(_, _, MergeInsts, _, _, _, _, _, _),
-			MergeInsts).
-
-inst_table_get_ground_insts(inst_table(_, _, _, GroundInsts, _, _, _, _, _),
-			GroundInsts).
-
-inst_table_get_any_insts(inst_table(_, _, _, _, AnyInsts, _, _, _, _),
-			AnyInsts).
-
-inst_table_get_shared_insts(inst_table(_, _, _, _, _, SharedInsts, _, _, _),
-			SharedInsts).
-
-inst_table_get_mostly_uniq_insts(
-			inst_table(_, _, _, _, _, _, NondetLiveInsts, _, _),
-			NondetLiveInsts).
-
-inst_table_get_clobbered_insts(
-			inst_table(_, _, _, _, _, _, _, ClobberedInsts, _),
-			ClobberedInsts).
-
-inst_table_get_inst_key_table(inst_table(_, _, _, _, _, _, _, _, InstKeyTable),
-			InstKeyTable).
-
-inst_table_set_substitution_insts(inst_table(_, B, C, D, E, F, G, H, I),
-			SubInsts,
-			inst_table(SubInsts, B, C, D, E, F, G, H, I)).
-
-inst_table_set_unify_insts(inst_table(A, _, C, D, E, F, G, H, I), UnifyInsts,
-			inst_table(A, UnifyInsts, C, D, E, F, G, H, I)).
-
-inst_table_set_merge_insts(inst_table(A, B, _, D, E, F, G, H, I), MergeInsts,
-			inst_table(A, B, MergeInsts, D, E, F, G, H, I)).
-
-inst_table_set_ground_insts(inst_table(A, B, C, _, E, F, G, H, I), GroundInsts,
-			inst_table(A, B, C, GroundInsts, E, F, G, H, I)).
-
-inst_table_set_any_insts(inst_table(A, B, C, D, _, F, G, H, I), AnyInsts,
-			inst_table(A, B, C, D, AnyInsts, F, G, H, I)).
-
-inst_table_set_shared_insts(inst_table(A, B, C, D, E, _, G, H, I), SharedInsts,
-			inst_table(A, B, C, D, E, SharedInsts, G, H, I)).
-
-inst_table_set_mostly_uniq_insts(inst_table(A, B, C, D, E, F, _, H, I),
-			NondetLiveInsts,
-			inst_table(A, B, C, D, E, F, NondetLiveInsts, H, I)).
-
-inst_table_set_clobbered_insts(inst_table(A, B, C, D, E, F, G, _, I),
-			ClobberedInsts,
-			inst_table(A, B, C, D, E, F, G, ClobberedInsts, I)).
-
-inst_table_set_inst_key_table(inst_table(A, B, C, D, E, F, G, H, _), InstKeys,
-			inst_table(A, B, C, D, E, F, G, H, InstKeys)).
-
 user_inst_table_init(user_inst_table(InstDefns, InstIds)) :-
 	map__init(InstDefns),
 	InstIds = [].
@@ -659,8 +442,6 @@
 			user_inst_table(InstDefns, InstIds)) :-
 	map__optimize(InstDefns0, InstDefns),
 	list__sort(InstIds0, InstIds).
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
 
 :- interface.
 
Index: hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.40.2.16
diff -u -u -r1.40.2.16 hlds_goal.m
--- hlds_goal.m	1999/07/19 01:44:33	1.40.2.16
+++ hlds_goal.m	1999/07/21 05:21:04
@@ -13,6 +13,7 @@
 :- interface.
 
 :- import_module hlds_data, hlds_pred, llds, prog_data, (inst), instmap.
+:- import_module inst_table.
 :- import_module bool, char, list, set, map, std_util.
 
 	% Here is how goals are represented
Index: hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.172.2.27
diff -u -u -r1.172.2.27 hlds_out.m
--- hlds_out.m	1999/07/19 01:44:35	1.172.2.27
+++ hlds_out.m	1999/07/21 05:59:46
@@ -34,7 +34,7 @@
 :- interface.
 
 :- import_module hlds_module, hlds_pred, hlds_goal, hlds_data.
-:- import_module prog_data, llds, instmap, term.
+:- import_module prog_data, llds, instmap, inst_table.
 :- import_module io, bool, map, list, term.
 
 %-----------------------------------------------------------------------------%
Index: hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.35.4.23
diff -u -u -r1.35.4.23 hlds_pred.m
--- hlds_pred.m	1999/07/19 01:44:37	1.35.4.23
+++ hlds_pred.m	1999/07/21 05:22:43
@@ -14,7 +14,7 @@
 :- interface.
 
 :- import_module hlds_data, hlds_goal, hlds_module, llds, prog_data, instmap.
-:- import_module term_util.
+:- import_module term_util, inst_table.
 :- import_module bool, list, set, map, std_util, term, varset.
 
 :- implementation.
Index: inst_match.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/inst_match.m,v
retrieving revision 1.34.2.14
diff -u -u -r1.34.2.14 inst_match.m
--- inst_match.m	1999/02/21 23:53:10	1.34.2.14
+++ inst_match.m	1999/07/22 06:31:38
@@ -39,9 +39,11 @@
 
 :- interface.
 
-:- import_module hlds_module, hlds_data, prog_data, (inst), instmap.
-:- import_module list.
+:- import_module hlds_module, prog_data, (inst), instmap.
+:- import_module inst_table.
 
+:- import_module list, std_util, map.
+
 %-----------------------------------------------------------------------------%
 
 :- pred inst_expand(instmap, inst_table, module_info, inst, inst).
@@ -60,13 +62,15 @@
 
 %-----------------------------------------------------------------------------%
 
+:- type alias_map == map(inst_key, maybe(inst_key)).
+
 :- pred inst_matches_initial(inst, instmap, inst, instmap, inst_table,
-		module_info).
-:- mode inst_matches_initial(in, in, in, in, in, in) is semidet.
+		module_info, alias_map, alias_map).
+:- mode inst_matches_initial(in, in, in, in, in, in, in, out) is semidet.
 
 :- pred inst_matches_final(inst, instmap, inst, instmap, inst_table,
-		module_info).
-:- mode inst_matches_final(in, in, in, in, in, in) is semidet.
+		module_info, alias_map, alias_map).
+:- mode inst_matches_final(in, in, in, in, in, in, in, out) is semidet.
 
 	% inst_matches_initial(InstA, InstMapA, InstB, InstMapB, InstTable,
 	%		ModuleInfo):
@@ -107,6 +111,24 @@
 	% inst_matches_final into a single predicate inst_matches(When, ...)
 	% where When is either `initial' or `final'.
 
+:- pred inst_matches_initial_ignore_aliasing(inst, instmap, inst, instmap,
+		inst_table, module_info).
+:- mode inst_matches_initial_ignore_aliasing(in, in, in, in, in, in)
+		is semidet.
+
+:- pred inst_matches_final_ignore_aliasing(inst, instmap, inst, instmap,
+		inst_table, module_info).
+:- mode inst_matches_final_ignore_aliasing(in, in, in, in, in, in) is semidet.
+
+	% inst_matches_initial_ignore_aliasing and
+	% inst_matches_final_ignore_aliasing are the same as
+	% inst_matches_initial and inst_matches_final, respectively except that
+	% alias insts are expanded and ignored.
+	% These predicates can be used in situations where we are only
+	% interested in comparing bindings and uniqueness between insts rather
+	% than determining whether the insts of a set of variables match
+	% the required insts for a procedure's arguments.
+
 :- pred unique_matches_initial(uniqueness, uniqueness).
 :- mode unique_matches_initial(in, in) is semidet.
 
@@ -289,7 +311,7 @@
 
 	% Given a list of insts, and a corresponding list of livenesses,
 	% return true iff for every element in the list of insts, either
-	% the elemement is ground or any, or the corresponding element
+	% the element is ground or any, or the corresponding element
 	% in the liveness list is dead.
 
 :- pred inst_list_is_ground_or_any_or_dead(list(inst), list(is_live),
@@ -301,87 +323,106 @@
 
 :- implementation.
 :- import_module hlds_data, mode_util, prog_data, inst_util, type_util.
-:- import_module list, set, map, term, std_util, require.
+:- import_module list, set, term, require, bool.
 
 inst_matches_initial(InstA, InstMapA, InstB, InstMapB,
+			InstTable, ModuleInfo, AliasMap0, AliasMap) :-
+	set__init(Expansions),
+	IgnoreAliasing = no,
+	inst_matches_initial_2(InstA, InstMapA, InstB, InstMapB, InstTable,
+		ModuleInfo, Expansions, IgnoreAliasing, AliasMap0, AliasMap).
+
+inst_matches_initial_ignore_aliasing(InstA, InstMapA, InstB, InstMapB,
 			InstTable, ModuleInfo) :-
 	set__init(Expansions),
-	inst_matches_initial_2(InstA, InstMapA, InstB, InstMapB,
-		InstTable, ModuleInfo, Expansions).
+	map__init(AliasMap0),
+	IgnoreAliasing = yes,
+	inst_matches_initial_2(InstA, InstMapA, InstB, InstMapB, InstTable,
+		ModuleInfo, Expansions, IgnoreAliasing, AliasMap0, _AliasMap).
 
 :- type expansions == set(pair(inst)).
 
 :- pred inst_matches_initial_2(inst, instmap, inst, instmap, inst_table,
-		module_info, expansions).
-:- mode inst_matches_initial_2(in, in, in, in, in, in, in) is semidet.
+		module_info, expansions, bool, alias_map, alias_map).
+:- mode inst_matches_initial_2(in, in, in, in, in, in, in, in, in, out)
+		is semidet.
 
 inst_matches_initial_2(InstA, InstMapA, InstB, InstMapB, InstTable, ModuleInfo,
-		Expansions) :-
+		Expansions, IgnoreAliasing, AliasMap0, AliasMap) :-
 	ThisExpansion = InstA - InstB,
 	( set__member(ThisExpansion, Expansions) ->
-		true
+		AliasMap = AliasMap0
 /********* 
 		% does this test improve efficiency??
 	; InstA = InstB ->
 		true
 **********/
 	;
+		inst_matches_aliasing(IgnoreAliasing, InstA, InstB,
+			AliasMap0, AliasMap1),
+
 		inst_expand(InstMapA, InstTable, ModuleInfo, InstA, InstA2),
 		inst_expand(InstMapB, InstTable, ModuleInfo, InstB, InstB2),
 		set__insert(Expansions, ThisExpansion, Expansions2),
 		inst_matches_initial_3(InstA2, InstMapA, InstB2, InstMapB,
-			InstTable, ModuleInfo, Expansions2)
+			InstTable, ModuleInfo, Expansions2, IgnoreAliasing,
+			AliasMap1, AliasMap)
 	).
 
 :- pred inst_matches_initial_3(inst, instmap, inst, instmap, inst_table,
-		module_info, expansions).
-:- mode inst_matches_initial_3(in, in, in, in, in, in, in) is semidet.
+		module_info, expansions, bool, alias_map, alias_map).
+:- mode inst_matches_initial_3(in, in, in, in, in, in, in, in, in, out)
+		is semidet.
 
 	% To avoid infinite regress, we assume that
 	% inst_matches_initial is true for any pairs of insts which
 	% occur in `Expansions'.
 
-inst_matches_initial_3(any(UniqA), _, any(UniqB), _, _, _, _) :-
+inst_matches_initial_3(any(UniqA), _, any(UniqB), _, _, _, _, _, AM, AM) :-
 	unique_matches_initial(UniqA, UniqB).
-inst_matches_initial_3(any(_), _, free(unique), _, _, _, _).
-inst_matches_initial_3(free(unique), _, any(_), _, _, _, _).
-inst_matches_initial_3(free(alias), _, free(alias), _, _, _, _).
+inst_matches_initial_3(any(_), _, free(unique), _, _, _, _, _, AM, AM).
+inst_matches_initial_3(free(unique), _, any(_), _, _, _, _, _, AM, AM).
+inst_matches_initial_3(free(alias), _, free(alias), _, _, _, _, _, AM, AM).
 			% AAA free(alias) should match_initial free(unique)
 			% and vice-versa.  They will as soon as the mode
 			% checker supports the implied modes that would result.
-inst_matches_initial_3(free(unique), _, free(unique), _, _, _, _).
+inst_matches_initial_3(free(unique), _, free(unique), _, _, _, _, _, AM, AM).
 inst_matches_initial_3(bound(UniqA, ListA), InstMapA, any(UniqB), _InstMapB,
-		InstTable, ModuleInfo, _) :-
+		InstTable, ModuleInfo, _, _, AM, AM) :-
 	unique_matches_initial(UniqA, UniqB),
 	bound_inst_list_matches_uniq(ListA, UniqB, InstMapA, InstTable,
 		ModuleInfo).
-inst_matches_initial_3(bound(_Uniq, _List), _, free(_), _, _, _, _).
+inst_matches_initial_3(bound(_Uniq, _List), _, free(_), _, _, _, _, _, AM, AM).
 inst_matches_initial_3(bound(UniqA, ListA), InstMapA, bound(UniqB, ListB), 
-			InstMapB, InstTable, ModuleInfo, Expansions) :-
+		InstMapB, InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+		AliasMap0, AliasMap) :-
 	unique_matches_initial(UniqA, UniqB),
 	bound_inst_list_matches_initial(ListA, InstMapA, ListB, InstMapB,
-			InstTable, ModuleInfo, Expansions).
+		InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+		AliasMap0, AliasMap).
 inst_matches_initial_3(bound(UniqA, ListA), InstMapA, ground(UniqB, no),
-		_InstMapB, InstTable, ModuleInfo, _) :-
+		_InstMapB, InstTable, ModuleInfo, _, _, AM, AM) :-
 	unique_matches_initial(UniqA, UniqB),
 	bound_inst_list_is_ground(ListA, InstMapA, InstTable, ModuleInfo),
 	bound_inst_list_matches_uniq(ListA, UniqB, InstMapA, InstTable,
 			ModuleInfo).
 inst_matches_initial_3(bound(Uniq, List), InstMapA, abstract_inst(_,_),
-		_InstMapB, InstTable, ModuleInfo, _) :-
+		_InstMapB, InstTable, ModuleInfo, _, _, AM, AM) :-
 	Uniq = unique,
 	bound_inst_list_is_ground(List, InstMapA, InstTable, ModuleInfo),
 	bound_inst_list_is_unique(List, InstMapA, InstTable, ModuleInfo).
 inst_matches_initial_3(bound(Uniq, List), InstMapA, abstract_inst(_,_),
-		_InstMapB, InstTable, ModuleInfo, _) :-
+		_InstMapB, InstTable, ModuleInfo, _, _, AM, AM) :-
 	Uniq = mostly_unique,
 	bound_inst_list_is_ground(List, InstMapA, InstTable, ModuleInfo),
 	bound_inst_list_is_mostly_unique(List, InstMapA, InstTable, ModuleInfo).
-inst_matches_initial_3(ground(UniqA, _PredInst), _, any(UniqB), _, _, _, _) :-
+inst_matches_initial_3(ground(UniqA, _PredInst), _, any(UniqB), _, _, _, _,
+		_, AM, AM) :-
 	unique_matches_initial(UniqA, UniqB).
-inst_matches_initial_3(ground(_Uniq, _PredInst), _, free(_), _, _, _, _).
+inst_matches_initial_3(ground(_Uniq, _PredInst), _, free(_), _, _, _, _, _,
+		AM, AM).
 inst_matches_initial_3(ground(UniqA, _), _, bound(UniqB, List), InstMapB,
-		InstTable, ModuleInfo, _) :-
+		InstTable, ModuleInfo, _, _, _, _) :-
 	unique_matches_initial(UniqA, UniqB),
 	uniq_matches_bound_inst_list(UniqA, List, InstMapB, InstTable,
 			ModuleInfo),
@@ -392,22 +433,25 @@
 		% for the type.  Problem is we don't know what the type was :-(
 inst_matches_initial_3(ground(UniqA, PredInstA), InstMapA,
 		ground(UniqB, PredInstB), InstMapB,
-		InstTable, ModuleInfo, _) :-
+		InstTable, ModuleInfo, _, _, AM, AM) :-
 	maybe_pred_inst_matches_initial(PredInstA, InstMapA, PredInstB,
 		InstMapB, InstTable, ModuleInfo),
 	unique_matches_initial(UniqA, UniqB).
-inst_matches_initial_3(ground(_UniqA, no), _, abstract_inst(_,_), _, _, _, _) :-
+inst_matches_initial_3(ground(_UniqA, no), _, abstract_inst(_,_), _, _, _, _,
+		_, AM, AM) :-
 		% I don't know what this should do.
 		% Abstract insts aren't really supported.
 	error("inst_matches_initial(ground, abstract_inst) == ??").
-inst_matches_initial_3(abstract_inst(_,_), _, any(shared), _, _, _, _).
-inst_matches_initial_3(abstract_inst(_,_), _, free(_), _, _, _, _).
+inst_matches_initial_3(abstract_inst(_,_), _, any(shared), _, _, _, _, _,
+		AM, AM).
+inst_matches_initial_3(abstract_inst(_,_), _, free(_), _, _, _, _, _, AM, AM).
 inst_matches_initial_3(abstract_inst(Name, ArgsA), InstMapA,
-		abstract_inst(Name, ArgsB), InstMapB,
-		InstTable, ModuleInfo, Expansions) :-
+		abstract_inst(Name, ArgsB), InstMapB, InstTable, ModuleInfo,
+		Expansions, IgnoreAliasing, AliasMap0, AliasMap) :-
 	inst_list_matches_initial(ArgsA, InstMapA, ArgsB, InstMapB,
-		InstTable, ModuleInfo, Expansions).
-inst_matches_initial_3(not_reached, _, _, _, _, _, _).
+		InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+		AliasMap0, AliasMap).
+inst_matches_initial_3(not_reached, _, _, _, _, _, _, _, AM, AM).
 
 %-----------------------------------------------------------------------------%
 
@@ -440,16 +484,17 @@
 :- mode pred_inst_matches_2(in, in, in, in, in, in, in) is semidet.
 
 pred_inst_matches_2(
-		pred_inst_info(PredOrFunc, argument_modes(_InstTableA, ModesA),
+		pred_inst_info(PredOrFunc, argument_modes(InstTableA, ModesA),
 				Det),
 		InstMapA,
-		pred_inst_info(PredOrFunc, argument_modes(_InstTableB, ModesB),
+		pred_inst_info(PredOrFunc, argument_modes(InstTableB, ModesB0),
 				Det),
-		InstMapB, InstTable, ModuleInfo, Expansions) :-
-	% XXX This is incorrect in the case where the pred insts have
-	%     aliasing in their argument_modes.
+		InstMapB, _InstTable, ModuleInfo, Expansions) :-
+	inst_table_create_sub(InstTableA, InstTableB, Sub, InstTable),
+	list__map(apply_inst_table_sub_mode(Sub), ModesB0, ModesB),
+	map__init(AliasMap0),
 	pred_inst_argmodes_matches(ModesA, InstMapA, ModesB, InstMapB,
-			InstTable, ModuleInfo, Expansions).
+		InstTable, ModuleInfo, Expansions, AliasMap0, AliasMap0).
 
 	% pred_inst_matches_argmodes(ModesA, ModesB, ModuleInfo, Expansions):
 	% succeeds if the initial insts of ModesB specify at least as
@@ -460,20 +505,22 @@
 	% to match_final each other.
 	%
 :- pred pred_inst_argmodes_matches(list(mode), instmap, list(mode), instmap,
-				inst_table, module_info, expansions).
-:- mode pred_inst_argmodes_matches(in, in, in, in, in, in, in) is semidet.
+		inst_table, module_info, expansions, alias_map, alias_map).
+:- mode pred_inst_argmodes_matches(in, in, in, in, in, in, in, in, in)
+		is semidet.
 
-pred_inst_argmodes_matches([], _, [], _, _, _, _).
+pred_inst_argmodes_matches([], _, [], _, _, _, _, _, _).
 pred_inst_argmodes_matches([ModeA|ModeAs], InstMapA, [ModeB|ModeBs],
-		InstMapB, InstTable, ModuleInfo, Expansions) :-
+		InstMapB, InstTable, ModuleInfo, Expansions, AliasMapA0,
+		AliasMapB0) :-
 	mode_get_insts(ModuleInfo, ModeA, InitialA, FinalA),
 	mode_get_insts(ModuleInfo, ModeB, InitialB, FinalB),
 	inst_matches_final_2(InitialB, InstMapB, InitialA, InstMapA,
-			InstTable, ModuleInfo, Expansions),
+		InstTable, ModuleInfo, Expansions, no, AliasMapA0, AliasMapA1),
 	inst_matches_final_2(FinalA, InstMapA, FinalB, InstMapB,
-			InstTable, ModuleInfo, Expansions),
+		InstTable, ModuleInfo, Expansions, no, AliasMapB0, AliasMapB1),
 	pred_inst_argmodes_matches(ModeAs, InstMapA, ModeBs, InstMapB,
-			InstTable, ModuleInfo, Expansions).
+		InstTable, ModuleInfo, Expansions, AliasMapA1, AliasMapB1).
 
 %-----------------------------------------------------------------------------%
 
@@ -536,20 +583,24 @@
 	% are sorted.
 
 :- pred bound_inst_list_matches_initial(list(bound_inst), instmap,
-			list(bound_inst), instmap, inst_table,
-			module_info, expansions).
-:- mode bound_inst_list_matches_initial(in, in, in, in, in, in, in) is semidet.
+		list(bound_inst), instmap, inst_table, module_info, expansions,
+		bool, alias_map, alias_map).
+:- mode bound_inst_list_matches_initial(in, in, in, in, in, in, in, in,
+		in, out) is semidet.
 
-bound_inst_list_matches_initial([], _, _, _, _, _, _).
+bound_inst_list_matches_initial([], _, _, _, _, _, _, _, AM, AM).
 bound_inst_list_matches_initial([X|Xs], InstMapA, [Y|Ys], InstMapB,
-			InstTable, ModuleInfo, Expansions) :-
+		InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+		AliasMap0, AliasMap) :-
 	X = functor(ConsIdX, ArgsX),
 	Y = functor(ConsIdY, ArgsY),
 	( ConsIdX = ConsIdY ->
 		inst_list_matches_initial(ArgsX, InstMapA, ArgsY, InstMapB,
-				InstTable, ModuleInfo, Expansions),
+				InstTable, ModuleInfo, Expansions,
+				IgnoreAliasing, AliasMap0, AliasMap1),
 		bound_inst_list_matches_initial(Xs, InstMapA, Ys, InstMapB,
-				InstTable, ModuleInfo, Expansions)
+				InstTable, ModuleInfo, Expansions,
+				IgnoreAliasing, AliasMap1, AliasMap)
 	;
 		compare(>, ConsIdX, ConsIdY),
 			% ConsIdY does not occur in [X|Xs].
@@ -558,23 +609,48 @@
 			% automatically matches_initial Y.  We just need to
 			% check that [X|Xs] matches_initial Ys.
 		bound_inst_list_matches_initial([X|Xs], InstMapA, Ys,
-				InstMapB, InstTable, ModuleInfo, Expansions)
+				InstMapB, InstTable, ModuleInfo, Expansions,
+				IgnoreAliasing, AliasMap0, AliasMap)
 	).
 
 :- pred inst_list_matches_initial(list(inst), instmap, list(inst), instmap,
-				inst_table, module_info, expansions).
-:- mode inst_list_matches_initial(in, in, in, in, in, in, in) is semidet.
-
-inst_list_matches_initial([], _, [], _, _, _, _).
-inst_list_matches_initial([X|Xs], InstMapA, [Y|Ys], InstMapB,
-		InstTable, ModuleInfo, Expansions) :-
+	inst_table, module_info, expansions, bool, alias_map, alias_map).
+:- mode inst_list_matches_initial(in, in, in, in, in, in, in, in, in, out)
+	is semidet.
+
+inst_list_matches_initial([], _, [], _, _, _, _, _, AM, AM).
+inst_list_matches_initial([X|Xs], InstMapA, [Y|Ys], InstMapB, InstTable,
+		ModuleInfo, Expansions, IgnoreAliasing, AliasMap0, AliasMap) :-
 	inst_matches_initial_2(X, InstMapA, Y, InstMapB, InstTable,
-			ModuleInfo, Expansions),
-	inst_list_matches_initial(Xs, InstMapA, Ys, InstMapB,
-			InstTable, ModuleInfo, Expansions).
+			ModuleInfo, Expansions, IgnoreAliasing,
+			AliasMap0, AliasMap1),
+	inst_list_matches_initial(Xs, InstMapA, Ys, InstMapB, InstTable,
+			ModuleInfo, Expansions, IgnoreAliasing,
+			AliasMap1, AliasMap).
 
 %-----------------------------------------------------------------------------%
 
+:- pred inst_matches_aliasing(bool, inst, inst, alias_map, alias_map).
+:- mode inst_matches_aliasing(in, in, in, in, out) is semidet.
+
+inst_matches_aliasing(yes, _, _, AliasMap, AliasMap).
+inst_matches_aliasing(no, InstA, InstB, AliasMap0, AliasMap) :-
+	( InstB = alias(IKB) ->
+		( map__search(AliasMap0, IKB, MaybeIK) ->
+			MaybeIK = yes(IKA),
+			InstA = alias(IKA),
+			AliasMap = AliasMap0
+		; InstA = alias(IKA) ->
+			map__det_insert(AliasMap0, IKB, yes(IKA), AliasMap)
+		;
+			map__det_insert(AliasMap0, IKB, no, AliasMap)
+		)
+	;
+		AliasMap = AliasMap0
+	).
+
+%-----------------------------------------------------------------------------%
+
 inst_expand(InstMap, InstTable, ModuleInfo, Inst0, Inst) :-
 	( Inst0 = defined_inst(InstName) ->
 		inst_lookup(InstTable, ModuleInfo, InstName, Inst1),
@@ -597,45 +673,61 @@
 
 %-----------------------------------------------------------------------------%
 
-inst_matches_final(InstA, InstMapA, InstB, InstMapB, InstTable, ModuleInfo) :-
+inst_matches_final(InstA, InstMapA, InstB, InstMapB, InstTable, ModuleInfo,
+		AliasMap0, AliasMap) :-
 	set__init(Expansions),
-	inst_matches_final_2(InstA, InstMapA, InstB, InstMapB,
-			InstTable, ModuleInfo, Expansions).
+	IgnoreAliasing = no,
+	inst_matches_final_2(InstA, InstMapA, InstB, InstMapB, InstTable,
+		ModuleInfo, Expansions, IgnoreAliasing, AliasMap0, AliasMap).
 
+inst_matches_final_ignore_aliasing(InstA, InstMapA, InstB, InstMapB,
+		InstTable, ModuleInfo) :-
+	set__init(Expansions),
+	map__init(AliasMap0),
+	IgnoreAliasing = yes,
+	inst_matches_final_2(InstA, InstMapA, InstB, InstMapB, InstTable,
+		ModuleInfo, Expansions, IgnoreAliasing, AliasMap0, _AliasMap).
+
 :- pred inst_matches_final_2(inst, instmap, inst, instmap, inst_table,
-		module_info, expansions).
-:- mode inst_matches_final_2(in, in, in, in, in, in, in) is semidet.
+		module_info, expansions, bool, alias_map, alias_map).
+:- mode inst_matches_final_2(in, in, in, in, in, in, in, in, in, out)
+		is semidet.
 
 inst_matches_final_2(InstA, InstMapA, InstB, InstMapB, InstTable,
-		ModuleInfo, Expansions) :-
+		ModuleInfo, Expansions, IgnoreAliasing, AliasMap0, AliasMap) :-
 	ThisExpansion = InstA - InstB,
 	( set__member(ThisExpansion, Expansions) ->
-		true
+		AliasMap = AliasMap0
 	; InstA = InstB ->
-		true
+		AliasMap = AliasMap0
 	;
+		inst_matches_aliasing(IgnoreAliasing, InstA, InstB,
+			AliasMap0, AliasMap1),
+
 		inst_expand(InstMapA, InstTable, ModuleInfo, InstA, InstA2),
 		inst_expand(InstMapB, InstTable, ModuleInfo, InstB, InstB2),
 		set__insert(Expansions, ThisExpansion, Expansions2),
 		inst_matches_final_3(InstA2, InstMapA, InstB2, InstMapB,
-				InstTable, ModuleInfo, Expansions2)
+			InstTable, ModuleInfo, Expansions2, IgnoreAliasing,
+			AliasMap1, AliasMap)
 	).
 
 :- pred inst_matches_final_3(inst, instmap, inst, instmap, inst_table,
-		module_info, expansions).
-:- mode inst_matches_final_3(in, in, in, in, in, in, in) is semidet.
+		module_info, expansions, bool, alias_map, alias_map).
+:- mode inst_matches_final_3(in, in, in, in, in, in, in, in, in, out)
+		is semidet.
 
-inst_matches_final_3(any(UniqA), _, any(UniqB), _, _, _, _) :-
+inst_matches_final_3(any(UniqA), _, any(UniqB), _, _, _, _, _, AM, AM) :-
 	unique_matches_final(UniqA, UniqB).
-inst_matches_final_3(free(unique), _, any(Uniq), _, _, _, _) :-
+inst_matches_final_3(free(unique), _, any(Uniq), _, _, _, _, _, AM, AM) :-
 	% We do not yet allow `free' to match `any',
 	% unless the `any' is `clobbered_any' or `mostly_clobbered_any'.
 	% Among other things, changing this would break compare_inst
 	% in modecheck_call.m.
 	( Uniq = clobbered ; Uniq = mostly_clobbered ).
-inst_matches_final_3(free(Aliasing), _, free(Aliasing), _, _, _, _).
+inst_matches_final_3(free(Aliasing), _, free(Aliasing), _, _, _, _, _, AM, AM).
 inst_matches_final_3(bound(UniqA, ListA), InstMapA, any(UniqB), _InstMapB,
-		InstTable, ModuleInfo, _) :-
+		InstTable, ModuleInfo, _, _, AM, AM) :-
 	unique_matches_final(UniqA, UniqB),
 	bound_inst_list_matches_uniq(ListA, UniqB, InstMapA, InstTable,
 			ModuleInfo),
@@ -645,21 +737,23 @@
 	bound_inst_list_is_ground_or_any(ListA, InstMapA, InstTable,
 			ModuleInfo).
 inst_matches_final_3(bound(UniqA, ListA), InstMapA, bound(UniqB, ListB),
-		InstMapB, InstTable, ModuleInfo, Expansions) :-
+		InstMapB, InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+		AliasMap0, AliasMap) :-
 	unique_matches_final(UniqA, UniqB),
 	bound_inst_list_matches_final(ListA, InstMapA, ListB, InstMapB,
-			InstTable, ModuleInfo, Expansions).
+		InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+		AliasMap0, AliasMap).
 inst_matches_final_3(bound(UniqA, ListA), InstMapA, ground(UniqB, no),
-		_InstMapB, InstTable, ModuleInfo, _Exps) :-
+		_InstMapB, InstTable, ModuleInfo, _Exps, _, AM, AM) :-
 	unique_matches_final(UniqA, UniqB),
 	bound_inst_list_is_ground(ListA, InstMapA, InstTable, ModuleInfo),
 	bound_inst_list_matches_uniq(ListA, UniqB, InstMapA, InstTable,
 			ModuleInfo).
 inst_matches_final_3(ground(UniqA, _), _, any(UniqB), _, _InstTable,
-		_ModuleInfo, _Expansions) :-
+		_ModuleInfo, _Expansions, _, AM, AM) :-
 	unique_matches_final(UniqA, UniqB).
 inst_matches_final_3(ground(UniqA, _), _, bound(UniqB, ListB), InstMapB,
-		InstTable, ModuleInfo, _Exps) :-
+		InstTable, ModuleInfo, _Exps, _, AM, AM) :-
 	unique_matches_final(UniqA, UniqB),
 	uniq_matches_bound_inst_list(UniqA, ListB, InstMapB, InstTable,
 			ModuleInfo).
@@ -669,17 +763,18 @@
 	%%% error("not implemented: `ground' matches_final `bound(...)'").
 inst_matches_final_3(ground(UniqA, PredInstA), InstMapA,
 		ground(UniqB, PredInstB), InstMapB,
-		InstTable, ModuleInfo, Expansions) :-
+		InstTable, ModuleInfo, Expansions, _, AM, AM) :-
 	maybe_pred_inst_matches_final(PredInstA, InstMapA, PredInstB, InstMapB,
 		InstTable, ModuleInfo, Expansions),
 	unique_matches_final(UniqA, UniqB).
-inst_matches_final_3(abstract_inst(_, _), _, any(shared), _, _, _, _).
+inst_matches_final_3(abstract_inst(_, _), _, any(shared), _, _, _, _, _,
+		AM, AM).
 inst_matches_final_3(abstract_inst(Name, ArgsA), InstMapA,
-		abstract_inst(Name, ArgsB), InstMapB,
-		InstTable, ModuleInfo, Expansions) :-
-	inst_list_matches_final(ArgsA, InstMapA, ArgsB, InstMapB,
-		InstTable, ModuleInfo, Expansions).
-inst_matches_final_3(not_reached, _, _, _, _, _, _).
+		abstract_inst(Name, ArgsB), InstMapB, InstTable, ModuleInfo,
+		Expansions, IgnoreAliasing, AliasMap0, AliasMap) :-
+	inst_list_matches_final(ArgsA, InstMapA, ArgsB, InstMapB, InstTable,
+		ModuleInfo, Expansions, IgnoreAliasing,AliasMap0, AliasMap).
+inst_matches_final_3(not_reached, _, _, _, _, _, _, _, AM, AM).
 
 :- pred maybe_pred_inst_matches_final(maybe(pred_inst_info), instmap,
 	maybe(pred_inst_info), instmap, inst_table, module_info, expansions).
@@ -693,16 +788,20 @@
 			InstTable, ModuleInfo, Expansions).
 
 :- pred inst_list_matches_final(list(inst), instmap, list(inst), instmap,
-			inst_table, module_info, expansions).
-:- mode inst_list_matches_final(in, in, in, in, in, in, in) is semidet.
+	inst_table, module_info, expansions, bool, alias_map, alias_map).
+:- mode inst_list_matches_final(in, in, in, in, in, in, in, in, in, out)
+	is semidet.
 
-inst_list_matches_final([], _, [], _, _, _ModuleInfo, _).
+inst_list_matches_final([], _, [], _, _, _ModuleInfo, _, _, AM, AM).
 inst_list_matches_final([ArgA | ArgsA], InstMapA, [ArgB | ArgsB], InstMapB,
-			InstTable, ModuleInfo, Expansions) :-
+		InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+		AliasMap0, AliasMap) :-
 	inst_matches_final_2(ArgA, InstMapA, ArgB, InstMapB, InstTable,
-			ModuleInfo, Expansions),
+			ModuleInfo, Expansions, IgnoreAliasing,
+			AliasMap0, AliasMap1),
 	inst_list_matches_final(ArgsA, InstMapA, ArgsB, InstMapB, InstTable,
-			ModuleInfo, Expansions).
+			ModuleInfo, Expansions, IgnoreAliasing,
+			AliasMap1, AliasMap).
 
 	% Here we check that the functors in the first list are a
 	% subset of the functors in the second list. 
@@ -714,19 +813,23 @@
 	% are sorted.
 
 :- pred bound_inst_list_matches_final(list(bound_inst), instmap,
-	list(bound_inst), instmap, inst_table, module_info, expansions).
-:- mode bound_inst_list_matches_final(in, in, in, in, in, in, in) is semidet.
+	list(bound_inst), instmap, inst_table, module_info, expansions,
+	bool, alias_map, alias_map).
+:- mode bound_inst_list_matches_final(in, in, in, in, in, in, in, in, in, out)
+	is semidet.
 
-bound_inst_list_matches_final([], _, _, _, _, _, _).
+bound_inst_list_matches_final([], _, _, _, _, _, _, _, AM, AM).
 bound_inst_list_matches_final([X|Xs], InstMapA, [Y|Ys], InstMapB, InstTable,
-		ModuleInfo, Expansions) :-
+		ModuleInfo, Expansions, IgnoreAliasing, AliasMap0, AliasMap) :-
 	X = functor(ConsIdX, ArgsX),
 	Y = functor(ConsIdY, ArgsY),
 	( ConsIdX = ConsIdY ->
 		inst_list_matches_final(ArgsX, InstMapA, ArgsY, InstMapB,
-			InstTable, ModuleInfo, Expansions),
+			InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+			AliasMap0, AliasMap1),
 		bound_inst_list_matches_final(Xs, InstMapA, Ys, InstMapB,
-			InstTable, ModuleInfo, Expansions)
+			InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+			AliasMap1, AliasMap)
 	;
 		compare(>, ConsIdX, ConsIdY),
 			% ConsIdY does not occur in [X|Xs].
@@ -735,7 +838,8 @@
 			% automatically matches_final Y.  We just need to
 			% check that [X|Xs] matches_final Ys.
 		bound_inst_list_matches_final([X|Xs], InstMapA, Ys, InstMapB,
-			InstTable, ModuleInfo, Expansions)
+			InstTable, ModuleInfo, Expansions, IgnoreAliasing,
+			AliasMap0, AliasMap)
 	).
 
 inst_matches_binding(InstA, InstMapA, InstB, InstMapB, InstTable, ModuleInfo) :-
@@ -1412,8 +1516,8 @@
 
 inst_contains_instname_2(defined_inst(InstName1), InstMap, InstTable,
 		ModuleInfo, Expansions0, InstName) :-
-	(
-		InstName = InstName1
+	( InstName = InstName1 ->
+		true
 	;
 		not set__member(InstName1, Expansions0),
 		inst_lookup(InstTable, ModuleInfo, InstName1, Inst1),
Index: inst_table.m
===================================================================
RCS file: inst_table.m
diff -N inst_table.m
--- /dev/null	Fri Jul 23 17:20:16 1999
+++ inst_table.m	Thu Jul 22 16:52:55 1999
@@ -0,0 +1,495 @@
+%-----------------------------------------------------------------------------%
+% Copyright (C) 1999 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.
+%-----------------------------------------------------------------------------%
+
+% This module contains the definitition of the inst_table which holds
+% procedure-wide inst information.  This includes compiler-defined recursive
+% insts and the inst_key_table which holds alias information.
+
+% Main authors: bromage, dmo.
+
+:- module inst_table.
+
+:- interface.
+
+:- import_module prog_data, (inst).
+
+:- import_module map, set_bbbtree.
+
+:- type inst_table.
+
+:- type unify_inst_table ==	map(inst_name, maybe_inst_det).
+
+:- type unify_inst_pair	--->	unify_inst_pair(is_live, inst, inst,
+					unify_is_real).
+
+:- type merge_inst_table ==	map(merge_inst_pair, maybe_inst).
+
+:- type merge_inst_pair --->	merge_inst_pair(is_live, inst, inst).
+
+:- type ground_inst_table == 	map(inst_name, maybe_inst_det).
+
+:- type any_inst_table == 	map(inst_name, maybe_inst_det).
+
+:- type shared_inst_table == 	map(inst_name, maybe_inst).
+
+:- type mostly_uniq_inst_table == map(inst_name, maybe_inst).
+
+:- type clobbered_inst_table == map(inst_name, maybe_inst).
+
+	% The other_inst_table can be used when transforming a recursive inst
+	% into a new inst.  You should call `other_inst_table_new_id' at the
+	% start of each new use of the other_inst_table.
+	%
+	% XXX It would be possible to use the other_inst_table instead
+	%     of the shared_inst_table, mostly_uniq_inst_table
+	%     and clobbered_inst_table.
+	%     Maybe we should do this to reduce the overall complexity
+	%     of the inst_table.
+:- type other_inst_table.
+
+:- type inst_key_set == set_bbbtree(inst_key).
+
+:- type maybe_inst	--->	unknown
+			;	known(inst).
+
+:- type maybe_inst_det	--->	unknown
+			;	known(inst, determinism).
+
+%-----------------------------------------------------------------------------%
+
+:- pred inst_table_init(inst_table).
+:- mode inst_table_init(out) is det.
+
+:- pred inst_table_get_all_tables(inst_table, unify_inst_table,
+	merge_inst_table, ground_inst_table, any_inst_table, shared_inst_table,
+	mostly_uniq_inst_table, clobbered_inst_table, other_inst_table,
+	inst_key_table).
+:- mode inst_table_get_all_tables(in, out, out, out, out, out, out, out, out,
+	out) is det.
+
+:- pred inst_table_set_all_tables(inst_table, unify_inst_table,
+	merge_inst_table, ground_inst_table, any_inst_table, shared_inst_table,
+	mostly_uniq_inst_table, clobbered_inst_table, other_inst_table,
+	inst_key_table, inst_table).
+:- mode inst_table_set_all_tables(in, in, in, in, in, in, in, in, in, in, out)
+	is det.
+
+:- pred inst_table_get_unify_insts(inst_table, unify_inst_table).
+:- mode inst_table_get_unify_insts(in, out) is det.
+
+:- pred inst_table_get_merge_insts(inst_table, merge_inst_table).
+:- mode inst_table_get_merge_insts(in, out) is det.
+
+:- pred inst_table_get_ground_insts(inst_table, ground_inst_table).
+:- mode inst_table_get_ground_insts(in, out) is det.
+
+:- pred inst_table_get_any_insts(inst_table, any_inst_table).
+:- mode inst_table_get_any_insts(in, out) is det.
+
+:- pred inst_table_get_shared_insts(inst_table, shared_inst_table).
+:- mode inst_table_get_shared_insts(in, out) is det.
+
+:- pred inst_table_get_mostly_uniq_insts(inst_table, mostly_uniq_inst_table).
+:- mode inst_table_get_mostly_uniq_insts(in, out) is det.
+
+:- pred inst_table_get_clobbered_insts(inst_table, clobbered_inst_table).
+:- mode inst_table_get_clobbered_insts(in, out) is det.
+
+:- pred inst_table_get_other_insts(inst_table, other_inst_table).
+:- mode inst_table_get_other_insts(in, out) is det.
+
+:- pred inst_table_get_inst_key_table(inst_table, inst_key_table).
+:- mode inst_table_get_inst_key_table(in, out) is det.
+
+:- pred inst_table_set_unify_insts(inst_table, unify_inst_table, inst_table).
+:- mode inst_table_set_unify_insts(in, in, out) is det.
+
+:- pred inst_table_set_merge_insts(inst_table, merge_inst_table, inst_table).
+:- mode inst_table_set_merge_insts(in, in, out) is det.
+
+:- pred inst_table_set_ground_insts(inst_table, ground_inst_table, inst_table).
+:- mode inst_table_set_ground_insts(in, in, out) is det.
+
+:- pred inst_table_set_any_insts(inst_table, any_inst_table, inst_table).
+:- mode inst_table_set_any_insts(in, in, out) is det.
+
+:- pred inst_table_set_shared_insts(inst_table, shared_inst_table, inst_table).
+:- mode inst_table_set_shared_insts(in, in, out) is det.
+
+:- pred inst_table_set_mostly_uniq_insts(inst_table, mostly_uniq_inst_table,
+					inst_table).
+:- mode inst_table_set_mostly_uniq_insts(in, in, out) is det.
+
+:- pred inst_table_set_clobbered_insts(inst_table, clobbered_inst_table,
+					inst_table).
+:- mode inst_table_set_clobbered_insts(in, in, out) is det.
+
+:- pred inst_table_set_other_insts(inst_table, other_inst_table, inst_table).
+:- mode inst_table_set_other_insts(in, in, out) is det.
+
+:- pred inst_table_set_inst_key_table(inst_table, inst_key_table, inst_table).
+:- mode inst_table_set_inst_key_table(in, in, out) is det.
+
+%-----------------------------------------------------------------------------%
+
+	% Operations on the other_inst_table.
+
+	% other_inst_table_new_id should be called when starting a new 
+	% transformation on a set of insts. It increments an internal
+	% flag (of type other_inst_id) which is used to distinguish 
+	% insts created by this transformation from those created by 
+	% previous transformation.
+:- pred other_inst_table_new_id(other_inst_table, other_inst_table).
+:- mode other_inst_table_new_id(in, out) is det.
+
+	% Place the inst_name in the other_inst_table, marked with the
+	% current other_inst_id.
+:- pred other_inst_table_set(other_inst_table, inst_name, maybe_inst,
+		other_inst_table).
+:- mode other_inst_table_set(in, in, in, out) is det.
+
+	% Search for an entry in the other_inst_table containing the
+	% specified inst_name marked witht he current other_inst_id.
+:- pred other_inst_table_search(other_inst_table, inst_name, maybe_inst).
+:- mode other_inst_table_search(in, in, out) is semidet.
+
+:- pred other_inst_table_lookup(other_inst_table, other_inst_id, inst_name,
+		maybe_inst).
+:- mode other_inst_table_lookup(in, in, in, out) is det.
+
+	% Return an inst_name for the new derived_inst by marking the input
+	% inst_name with the current other_inst_id.
+:- pred other_inst_table_mark_inst_name(other_inst_table, inst_name,
+		inst_name).
+:- mode other_inst_table_mark_inst_name(in, in, out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- type inst_table_sub.
+
+:- pred inst_table_create_sub(inst_table, inst_table, inst_table_sub,
+		inst_table).
+:- mode inst_table_create_sub(in, in, out, out) is det.
+
+:- pred inst_apply_inst_table_sub(inst_table_sub, inst, inst).
+:- mode inst_apply_inst_table_sub(in, in, out) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list, std_util.
+
+:- type inst_table
+	--->	inst_table(
+			unit,
+			unify_inst_table,
+			merge_inst_table,
+			ground_inst_table,
+			any_inst_table,
+			shared_inst_table,
+			mostly_uniq_inst_table,
+			clobbered_inst_table,
+			other_inst_table,
+			inst_key_table
+		).
+
+:- type other_inst_table
+	--->	other_inst_table(
+			other_inst_id,		% the next other_inst_id to use.
+			map(other_inst, maybe_inst)
+		).
+
+:- type other_inst
+	--->	other_inst(
+			other_inst_id,
+			inst_name
+		).
+
+inst_table_init(inst_table(unit, UnifyInsts, MergeInsts, GroundInsts,
+		AnyInsts, SharedInsts, NondetLiveInsts, ClobberedInsts,
+		other_inst_table(init_other_inst_id, OtherInsts), InstKeys)) :-
+	map__init(UnifyInsts),
+	map__init(MergeInsts),
+	map__init(GroundInsts),
+	map__init(AnyInsts),
+	map__init(SharedInsts),
+	map__init(NondetLiveInsts),
+	map__init(ClobberedInsts),
+	map__init(OtherInsts),
+	inst_key_table_init(InstKeys).
+
+inst_table_get_all_tables(InstTable, UnifyInsts, MergeInsts,
+		GroundInsts, AnyInsts, SharedInsts, NondetLiveInsts,
+		ClobberedInsts, OtherInsts, InstKeys) :-
+	InstTable = inst_table(_, UnifyInsts, MergeInsts, GroundInsts,
+		AnyInsts, SharedInsts, NondetLiveInsts, ClobberedInsts,
+		OtherInsts, InstKeys).
+
+inst_table_set_all_tables(_InstTable0, UnifyInsts, MergeInsts,
+		GroundInsts, AnyInsts, SharedInsts, NondetLiveInsts,
+		ClobberedInsts, OtherInstTable, InstKeys, InstTable) :-
+	InstTable  = inst_table(unit, UnifyInsts, MergeInsts, GroundInsts,
+		AnyInsts, SharedInsts, NondetLiveInsts, ClobberedInsts,
+		OtherInstTable, InstKeys).
+
+inst_table_get_unify_insts(inst_table(_, UnifyInsts, _, _, _, _, _, _, _, _),
+			UnifyInsts).
+
+inst_table_get_merge_insts(inst_table(_, _, MergeInsts, _, _, _, _, _, _, _),
+			MergeInsts).
+
+inst_table_get_ground_insts(inst_table(_, _, _, GroundInsts, _, _, _, _, _, _),
+			GroundInsts).
+
+inst_table_get_any_insts(inst_table(_, _, _, _, AnyInsts, _, _, _, _, _),
+			AnyInsts).
+
+inst_table_get_shared_insts(inst_table(_, _, _, _, _, SharedInsts, _, _, _, _),
+			SharedInsts).
+
+inst_table_get_mostly_uniq_insts(
+			inst_table(_, _, _, _, _, _, NondetLiveInsts, _, _, _),
+			NondetLiveInsts).
+
+inst_table_get_clobbered_insts(
+			inst_table(_, _, _, _, _, _, _, ClobberedInsts, _, _),
+			ClobberedInsts).
+
+inst_table_get_other_insts(inst_table(_, _, _, _, _, _, _, _, OtherInsts, _),
+			OtherInsts).
+
+inst_table_get_inst_key_table(
+			inst_table(_, _, _, _, _, _, _, _, _, InstKeyTable),
+			InstKeyTable).
+
+inst_table_set_unify_insts(inst_table(A, _, C, D, E, F, G, H, I, J),
+			UnifyInsts,
+			inst_table(A, UnifyInsts, C, D, E, F, G, H, I, J)).
+
+inst_table_set_merge_insts(inst_table(A, B, _, D, E, F, G, H, I, J),
+			MergeInsts,
+			inst_table(A, B, MergeInsts, D, E, F, G, H, I, J)).
+
+inst_table_set_ground_insts(inst_table(A, B, C, _, E, F, G, H, I, J),
+			GroundInsts,
+			inst_table(A, B, C, GroundInsts, E, F, G, H, I, J)).
+
+inst_table_set_any_insts(inst_table(A, B, C, D, _, F, G, H, I, J), AnyInsts,
+			inst_table(A, B, C, D, AnyInsts, F, G, H, I, J)).
+
+inst_table_set_shared_insts(inst_table(A, B, C, D, E, _, G, H, I, J),
+			SharedInsts,
+			inst_table(A, B, C, D, E, SharedInsts, G, H, I, J)).
+
+inst_table_set_mostly_uniq_insts(inst_table(A, B, C, D, E, F, _, H, I, J),
+			NondetLiveInsts,
+			inst_table(A, B, C, D, E, F, NondetLiveInsts, H, I, J)).
+
+inst_table_set_clobbered_insts(inst_table(A, B, C, D, E, F, G, _, I, J),
+			ClobberedInsts,
+			inst_table(A, B, C, D, E, F, G, ClobberedInsts, I, J)).
+
+inst_table_set_other_insts(inst_table(A, B, C, D, E, F, G, H, _, J),
+			OtherInsts,
+			inst_table(A, B, C, D, E, F, G, H, OtherInsts, J)).
+
+inst_table_set_inst_key_table(inst_table(A, B, C, D, E, F, G, H, I, _),
+			InstKeys,
+			inst_table(A, B, C, D, E, F, G, H, I, InstKeys)).
+
+%-----------------------------------------------------------------------------%
+
+other_inst_table_new_id(other_inst_table(Id, Map),
+		other_inst_table(inc_other_inst_id(Id), Map)).
+
+other_inst_table_set(other_inst_table(Id, Map0), InstName, MaybeInst,
+		other_inst_table(Id, Map)) :-
+	map__set(Map0, other_inst(Id, InstName), MaybeInst, Map).
+
+other_inst_table_search(other_inst_table(Id, Map), InstName, MaybeInst) :-
+	map__search(Map, other_inst(Id, InstName), MaybeInst).
+
+other_inst_table_lookup(other_inst_table(_, Map), OtherInstId, InstName,
+		MaybeInst) :-
+	map__lookup(Map, other_inst(OtherInstId, InstName), MaybeInst).
+
+other_inst_table_mark_inst_name(other_inst_table(Id, _), InstName,
+		other_inst(Id, InstName)).
+
+%-----------------------------------------------------------------------------%
+
+:- type inst_table_sub
+	--->	inst_table_sub(
+			inst_key_sub,
+			other_inst_id_sub
+		).
+
+inst_table_create_sub(InstTable0, NewInstTable, Sub, InstTable) :-
+	inst_table_get_all_tables(InstTable0, UnifyInstTable0, MergeInstTable0,
+		GroundInstTable0, AnyInstTable0, SharedInstTable0,
+		ClobberedInstTable0, MostlyUniqInstTable0, OtherInstTable0,
+		IKT0),
+	inst_table_get_all_tables(NewInstTable, NewUnifyInstTable,
+		NewMergeInstTable, NewGroundInstTable, NewAnyInstTable,
+		NewSharedInstTable, NewMostlyUniqInstTable,
+		NewClobberedInstTable, NewOtherInstTable, NewIKT),
+	inst_key_table_create_sub(IKT0, NewIKT, IKSub, IKT),
+	OtherInstTable0 = other_inst_table(Id0, OtherInsts0),
+	OtherInstIdSub = other_inst_id_create_sub(Id0),
+	Sub = inst_table_sub(IKSub, OtherInstIdSub),
+
+	map_apply_sub(Sub, UnifyInstTable0, NewUnifyInstTable, UnifyInstTable),
+	map_apply_sub(Sub, MergeInstTable0, NewMergeInstTable, MergeInstTable),
+	map_apply_sub(Sub, GroundInstTable0, NewGroundInstTable,
+		GroundInstTable),
+	map_apply_sub(Sub, AnyInstTable0, NewAnyInstTable, AnyInstTable),
+	map_apply_sub(Sub, SharedInstTable0, NewSharedInstTable,
+		SharedInstTable),
+	map_apply_sub(Sub, MostlyUniqInstTable0, NewMostlyUniqInstTable,
+		MostlyUniqInstTable),
+	map_apply_sub(Sub, ClobberedInstTable0, NewClobberedInstTable,
+		ClobberedInstTable),
+
+	NewOtherInstTable = other_inst_table(NewId, NewOtherInsts),
+	map_apply_sub(Sub, OtherInsts0, NewOtherInsts, OtherInsts),
+	OtherInstId = other_inst_id_apply_sub(OtherInstIdSub, NewId),
+	OtherInstTable = other_inst_table(OtherInstId, OtherInsts),
+
+	inst_table_set_all_tables(InstTable0, UnifyInstTable,
+		MergeInstTable, GroundInstTable, AnyInstTable,
+		SharedInstTable, MostlyUniqInstTable, ClobberedInstTable,
+		OtherInstTable, IKT, InstTable).
+
+:- pred maybe_inst_apply_sub(inst_table_sub, maybe_inst, maybe_inst).
+:- mode maybe_inst_apply_sub(in, in, out) is det.
+
+maybe_inst_apply_sub(_, unknown, unknown).
+maybe_inst_apply_sub(Sub, known(I0), known(I)) :-
+	inst_apply_inst_table_sub(Sub, I0, I).
+
+:- pred maybe_inst_det_apply_sub(inst_table_sub, maybe_inst_det,
+		maybe_inst_det).
+:- mode maybe_inst_det_apply_sub(in, in, out) is det.
+
+maybe_inst_det_apply_sub(_, unknown, unknown).
+maybe_inst_det_apply_sub(Sub, known(I0, D), known(I, D)) :-
+	inst_apply_inst_table_sub(Sub, I0, I).
+
+:- pred merge_inst_pair_apply_sub(inst_table_sub, merge_inst_pair,
+		merge_inst_pair).
+:- mode merge_inst_pair_apply_sub(in, in, out) is det.
+
+merge_inst_pair_apply_sub(Sub, Pair0, Pair) :-
+	Pair0 = merge_inst_pair(IsLive, IA0, IB0),
+	inst_apply_inst_table_sub(Sub, IA0, IA),
+	inst_apply_inst_table_sub(Sub, IB0, IB),
+	Pair = merge_inst_pair(IsLive, IA, IB).
+
+:- pred other_inst_apply_sub(inst_table_sub, other_inst, other_inst).
+:- mode other_inst_apply_sub(in, in, out) is det.
+
+other_inst_apply_sub(Sub, other_inst(Id0, Name0), other_inst(Id, Name)) :-
+	Sub = inst_table_sub(_IKSub, IdSub),
+	Id = other_inst_id_apply_sub(IdSub, Id0),
+	inst_name_apply_sub(Sub, Name0, Name).
+
+:- pred map_apply_sub(inst_table_sub, map(K, V), map(K, V), map(K, V)) 
+		<= (inst_table_entry(K), inst_table_entry(V)).
+:- mode map_apply_sub(in, in, in, out) is det.
+
+map_apply_sub(Sub, Map0, NewMap, Map) :-
+	map__foldl((pred(K0::in, V0::in, M0::in, M::out) is det :-
+			inst_table_entry_apply_sub(Sub, K0, K),
+			inst_table_entry_apply_sub(Sub, V0, V),
+			map__set(M0, K, V, M)),
+		NewMap, Map0, Map).
+
+:- typeclass inst_table_entry(T) where [
+	pred inst_table_entry_apply_sub(inst_table_sub, T, T),
+	mode inst_table_entry_apply_sub(in, in, out) is det
+].
+
+:- instance inst_table_entry(inst_name) where [
+	pred(inst_table_entry_apply_sub/3) is inst_name_apply_sub
+].
+
+:- instance inst_table_entry(maybe_inst) where [
+	pred(inst_table_entry_apply_sub/3) is maybe_inst_apply_sub
+].
+
+:- instance inst_table_entry(maybe_inst_det) where [
+	pred(inst_table_entry_apply_sub/3) is maybe_inst_det_apply_sub
+].
+
+:- instance inst_table_entry(merge_inst_pair) where [
+	pred(inst_table_entry_apply_sub/3) is merge_inst_pair_apply_sub
+].
+
+:- instance inst_table_entry(other_inst) where [
+	pred(inst_table_entry_apply_sub/3) is other_inst_apply_sub
+].
+
+:- pred inst_name_apply_sub(inst_table_sub, inst_name, inst_name).
+:- mode inst_name_apply_sub(in, in, out) is det.
+
+inst_name_apply_sub(Sub, user_inst(Sym, Insts0), user_inst(Sym, Insts)) :-
+	list__map(inst_apply_inst_table_sub(Sub), Insts0, Insts).
+inst_name_apply_sub(Sub, merge_inst(IsLive, InstA0, InstB0),
+		merge_inst(IsLive, InstA, InstB)) :-
+	inst_apply_inst_table_sub(Sub, InstA0, InstA),
+	inst_apply_inst_table_sub(Sub, InstB0, InstB).
+inst_name_apply_sub(Sub, unify_inst(IsLive, InstA0, InstB0, IsReal),
+		unify_inst(IsLive, InstA, InstB, IsReal)) :-
+	inst_apply_inst_table_sub(Sub, InstA0, InstA),
+	inst_apply_inst_table_sub(Sub, InstB0, InstB).
+inst_name_apply_sub(Sub, ground_inst(Name0, IsLive, Uniq, IsReal),
+		ground_inst(Name, IsLive, Uniq, IsReal)) :-
+	inst_name_apply_sub(Sub, Name0, Name).
+inst_name_apply_sub(Sub, any_inst(Name0, IsLive, Uniq, IsReal),
+		any_inst(Name, IsLive, Uniq, IsReal)) :-
+	inst_name_apply_sub(Sub, Name0, Name).
+inst_name_apply_sub(Sub, shared_inst(Name0), shared_inst(Name)) :-
+	inst_name_apply_sub(Sub, Name0, Name).
+inst_name_apply_sub(Sub, mostly_uniq_inst(Name0),
+		mostly_uniq_inst(Name)) :-
+	inst_name_apply_sub(Sub, Name0, Name).
+inst_name_apply_sub(_Sub, typed_ground(Uniq, Type),
+		typed_ground(Uniq, Type)).
+inst_name_apply_sub(Sub, typed_inst(Type, Name0),
+		typed_inst(Type, Name)) :-
+	inst_name_apply_sub(Sub, Name0, Name).
+inst_name_apply_sub(Sub, other_inst(OtherInstId0, Name0),
+		other_inst(OtherInstId, Name)) :-
+	Sub = inst_table_sub(_IKSub, IdSub),
+	OtherInstId = other_inst_id_apply_sub(IdSub, OtherInstId0),
+	inst_name_apply_sub(Sub, Name0, Name).
+
+inst_apply_inst_table_sub(_Sub, any(Uniq), any(Uniq)).
+inst_apply_inst_table_sub(Sub, alias(Key0), Inst) :-
+	Sub = inst_table_sub(IKSub, _),
+	( map__search(IKSub, Key0, Key1) ->
+		inst_apply_inst_table_sub(Sub, alias(Key1), Inst)
+	;
+		Inst = alias(Key0)
+	).
+inst_apply_inst_table_sub(_Sub, free(Aliasing), free(Aliasing)).
+inst_apply_inst_table_sub(_Sub, free(Aliasing, Type), free(Aliasing, Type)).
+inst_apply_inst_table_sub(Sub, bound(Uniq, BoundInsts0),
+		bound(Uniq, BoundInsts)) :-
+	list__map((pred(functor(C, B0)::in, functor(C, B)::out) is det :-
+			list__map(inst_apply_inst_table_sub(Sub), B0, B)),
+		BoundInsts0, BoundInsts).
+inst_apply_inst_table_sub(_Sub, ground(Uniq, MaybePredInstInfo),
+		ground(Uniq, MaybePredInstInfo)).
+inst_apply_inst_table_sub(_Sub, not_reached, not_reached).
+inst_apply_inst_table_sub(_Sub, inst_var(V), inst_var(V)).
+inst_apply_inst_table_sub(Sub, defined_inst(Name0), defined_inst(Name)) :-
+	inst_name_apply_sub(Sub, Name0, Name).
+inst_apply_inst_table_sub(Sub, abstract_inst(SymName, Insts0),
+		abstract_inst(SymName, Insts)) :-
+	list__map(inst_apply_inst_table_sub(Sub), Insts0, Insts).
Index: inst_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/inst_util.m,v
retrieving revision 1.3.2.20
diff -u -u -r1.3.2.20 inst_util.m
--- inst_util.m	1999/07/13 04:43:21	1.3.2.20
+++ inst_util.m	1999/07/21 05:42:28
@@ -42,6 +42,8 @@
 :- interface.
 
 :- import_module hlds_module, hlds_data, prog_data, (inst), instmap.
+:- import_module inst_table.
+
 :- import_module list, map, std_util, set.
 
 :- pred abstractly_unify_inst(is_live, inst, inst, unify_is_real,
@@ -151,11 +153,6 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred inst_table_create_sub(inst_table, inst_table, inst_key_sub, inst_table).
-:- mode inst_table_create_sub(in, in, out, out) is det.
-
-%-----------------------------------------------------------------------------%
-
 :- type inst_fold_pred(T) == pred(inst, set(inst_name), T, T).
 :- mode inst_fold_pred :: (pred(in, in, in, out) is semidet).
 
@@ -2416,199 +2413,6 @@
 	).
 
 %-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-inst_table_create_sub(InstTable0, NewInstTable, Sub, InstTable) :-
-	inst_table_get_all_tables(InstTable0, SubInstTable0, UnifyInstTable0,
-		MergeInstTable0, GroundInstTable0, AnyInstTable0,
-		SharedInstTable0, ClobberedInstTable0, MostlyUniqInstTable0,
-		IKT0),
-	inst_table_get_all_tables(NewInstTable, NewSubInstTable,
-		NewUnifyInstTable, NewMergeInstTable, NewGroundInstTable,
-		NewAnyInstTable, NewSharedInstTable, NewMostlyUniqInstTable,
-		NewClobberedInstTable, NewIKT),
-	inst_key_table_create_sub(IKT0, NewIKT, Sub, IKT),
-
-	maybe_inst_det_table_apply_sub(UnifyInstTable0, NewUnifyInstTable,
-		UnifyInstTable, Sub),
-	merge_inst_table_apply_sub(MergeInstTable0, NewMergeInstTable,
-		MergeInstTable, Sub),
-	substitution_inst_table_apply_sub(SubInstTable0, NewSubInstTable,
-		SubInstTable, Sub),
-	maybe_inst_det_table_apply_sub(GroundInstTable0, NewGroundInstTable,
-		GroundInstTable, Sub),
-	maybe_inst_det_table_apply_sub(AnyInstTable0, NewAnyInstTable,
-		AnyInstTable, Sub),
-	maybe_inst_table_apply_sub(SharedInstTable0, NewSharedInstTable,
-		SharedInstTable, Sub),
-	maybe_inst_table_apply_sub(MostlyUniqInstTable0,
-		NewMostlyUniqInstTable, MostlyUniqInstTable, Sub),
-	maybe_inst_table_apply_sub(ClobberedInstTable0,
-		NewClobberedInstTable, ClobberedInstTable, Sub),
-
-	inst_table_set_all_tables(InstTable0, SubInstTable, UnifyInstTable,
-		MergeInstTable, GroundInstTable, AnyInstTable,
-		SharedInstTable, MostlyUniqInstTable, ClobberedInstTable, IKT,
-		InstTable).
-
-:- pred maybe_inst_table_apply_sub(map(inst_name, maybe_inst),
-		map(inst_name, maybe_inst), map(inst_name, maybe_inst),
-		inst_key_sub).
-:- mode maybe_inst_table_apply_sub(in, in, out, in) is det.
-
-maybe_inst_table_apply_sub(Table0, NewTable, Table, Sub) :-
-	( map__is_empty(NewTable) ->
-		% Optimise common case
-		Table = Table0
-	;
-		map__to_assoc_list(NewTable, NewTableAL),
-		maybe_inst_table_apply_sub_2(NewTableAL, Table0, Table, Sub)
-	).
-
-:- pred maybe_inst_table_apply_sub_2(assoc_list(inst_name, maybe_inst),
-		map(inst_name, maybe_inst), map(inst_name, maybe_inst),
-		inst_key_sub).
-:- mode maybe_inst_table_apply_sub_2(in, in, out, in) is det.
-
-maybe_inst_table_apply_sub_2([], Table, Table, _).
-maybe_inst_table_apply_sub_2([InstName0 - Inst0 | Rest], Table0, Table, Sub) :-
-	inst_name_apply_sub(Sub, InstName0, InstName),
-	( Inst0 = unknown,
-		Inst = unknown
-	; Inst0 = known(I0),
-		inst_apply_sub(Sub, I0, I),
-		Inst = known(I)
-	),
-	map__set(Table0, InstName, Inst, Table1),
-	maybe_inst_table_apply_sub_2(Rest, Table1, Table, Sub).
-
-:- pred maybe_inst_det_table_apply_sub(map(inst_name, maybe_inst_det),
-		map(inst_name, maybe_inst_det), map(inst_name, maybe_inst_det),
-		inst_key_sub).
-:- mode maybe_inst_det_table_apply_sub(in, in, out, in) is det.
-
-maybe_inst_det_table_apply_sub(Table0, NewTable, Table, Sub) :-
-	( map__is_empty(NewTable) ->
-		% Optimise common case
-		Table = Table0
-	;
-		map__to_assoc_list(NewTable, NewTableAL),
-		maybe_inst_det_table_apply_sub_2(NewTableAL, Table0, Table,
-			Sub)
-	).
-
-:- pred maybe_inst_det_table_apply_sub_2(assoc_list(inst_name, maybe_inst_det),
-		map(inst_name, maybe_inst_det), map(inst_name, maybe_inst_det),
-		inst_key_sub).
-:- mode maybe_inst_det_table_apply_sub_2(in, in, out, in) is det.
-
-maybe_inst_det_table_apply_sub_2([], Table, Table, _).
-maybe_inst_det_table_apply_sub_2([InstName0 - InstDet0 | Rest], Table0, Table, 
-		Sub) :-
-	inst_name_apply_sub(Sub, InstName0, InstName),
-	( InstDet0 = unknown,
-		InstDet = unknown
-	; InstDet0 = known(Inst0, Det),
-		inst_apply_sub(Sub, Inst0, Inst),
-		InstDet = known(Inst, Det)
-	),
-	map__set(Table0, InstName, InstDet, Table1),
-	maybe_inst_det_table_apply_sub_2(Rest, Table1, Table, Sub).
-
-:- pred merge_inst_table_apply_sub(merge_inst_table, merge_inst_table,
-		merge_inst_table, inst_key_sub).
-:- mode merge_inst_table_apply_sub(in, in, out, in) is det.
-
-merge_inst_table_apply_sub(Table0, NewTable, Table, Sub) :-
-	( map__is_empty(Table0) ->
-		% Optimise common case
-		Table = Table0
-	;
-		map__to_assoc_list(NewTable, NewTableAL),
-		merge_inst_table_apply_sub_2(NewTableAL, Table0, Table, Sub)
-	).
-
-:- pred merge_inst_table_apply_sub_2(assoc_list(merge_inst_pair, maybe_inst),
-		merge_inst_table, merge_inst_table, inst_key_sub).
-:- mode merge_inst_table_apply_sub_2(in, in, out, in) is det.
-
-merge_inst_table_apply_sub_2([], Table, Table, _).
-merge_inst_table_apply_sub_2([Pair0 - Inst0 | Rest], Table0, Table, Sub) :-
-	Pair0 = merge_inst_pair(IsLive, IA0, IB0),
-	inst_apply_sub(Sub, IA0, IA),
-	inst_apply_sub(Sub, IB0, IB),
-	( Inst0 = unknown,
-		Inst = unknown
-	; Inst0 = known(I0),
-		inst_apply_sub(Sub, I0, I),
-		Inst = known(I)
-	),
-	map__set(Table0, merge_inst_pair(IsLive, IA, IB), Inst, Table1),
-	merge_inst_table_apply_sub_2(Rest, Table1, Table, Sub).
-
-:- pred substitution_inst_table_apply_sub(substitution_inst_table,
-	substitution_inst_table, substitution_inst_table, inst_key_sub).
-:- mode substitution_inst_table_apply_sub(in, in, out, in) is det.
-
-substitution_inst_table_apply_sub(Table0, NewTable, Table, Sub) :-
-	( map__is_empty(Table0) ->
-		% Optimise common case
-		Table = Table0
-	;
-		map__to_assoc_list(NewTable, NewTableAL),
-		substitution_inst_table_apply_sub_2(NewTableAL, Table0, Table,
-			Sub)
-	).
-
-:- pred substitution_inst_table_apply_sub_2(assoc_list(substitution_inst,
-	maybe_inst), substitution_inst_table, substitution_inst_table,
-	inst_key_sub).
-:- mode substitution_inst_table_apply_sub_2(in, in, out, in) is det.
-
-substitution_inst_table_apply_sub_2([], Table, Table, _).
-substitution_inst_table_apply_sub_2(
-		[substitution_inst(InstName0, K, S) - Inst0 | Rest],
-		Table0, Table, Sub) :-
-	inst_name_apply_sub(Sub, InstName0, InstName),
-	( Inst0 = unknown,
-		Inst = unknown
-	; Inst0 = known(I0),
-		inst_apply_sub(Sub, I0, I),
-		Inst = known(I)
-	),
-	map__set(Table0, substitution_inst(InstName, K, S), Inst, Table1),
-	substitution_inst_table_apply_sub_2(Rest, Table1, Table, Sub).
-
-:- pred inst_name_apply_sub(inst_key_sub, inst_name, inst_name).
-:- mode inst_name_apply_sub(in, in, out) is det.
-
-inst_name_apply_sub(Sub, user_inst(Sym, Insts0), user_inst(Sym, Insts)) :-
-	list__map(inst_apply_sub(Sub), Insts0, Insts).
-inst_name_apply_sub(Sub, merge_inst(IsLive, InstA0, InstB0),
-		merge_inst(IsLive, InstA, InstB)) :-
-	inst_apply_sub(Sub, InstA0, InstA),
-	inst_apply_sub(Sub, InstB0, InstB).
-inst_name_apply_sub(Sub, unify_inst(IsLive, InstA0, InstB0, IsReal),
-		unify_inst(IsLive, InstA, InstB, IsReal)) :-
-	inst_apply_sub(Sub, InstA0, InstA),
-	inst_apply_sub(Sub, InstB0, InstB).
-inst_name_apply_sub(Sub, ground_inst(Name0, IsLive, Uniq, IsReal),
-		ground_inst(Name, IsLive, Uniq, IsReal)) :-
-	inst_name_apply_sub(Sub, Name0, Name).
-inst_name_apply_sub(Sub, any_inst(Name0, IsLive, Uniq, IsReal),
-		any_inst(Name, IsLive, Uniq, IsReal)) :-
-	inst_name_apply_sub(Sub, Name0, Name).
-inst_name_apply_sub(Sub, shared_inst(Name0), shared_inst(Name)) :-
-	inst_name_apply_sub(Sub, Name0, Name).
-inst_name_apply_sub(Sub, mostly_uniq_inst(Name0), mostly_uniq_inst(Name)) :-
-	inst_name_apply_sub(Sub, Name0, Name).
-inst_name_apply_sub(_Sub, typed_ground(Uniq, Type), typed_ground(Uniq, Type)).
-inst_name_apply_sub(Sub, typed_inst(Type, Name0), typed_inst(Type, Name)) :-
-	inst_name_apply_sub(Sub, Name0, Name).
-inst_name_apply_sub(Sub, substitution_inst(Name0, K, S),
-		substitution_inst(Name, K, S)) :-
-	inst_name_apply_sub(Sub, Name0, Name).
-
 %-----------------------------------------------------------------------------%
 
 inst_fold(InstMap, InstTable, ModuleInfo, Before, After, Merge, Inst) -->
Index: instmap.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/instmap.m,v
retrieving revision 1.15.2.22
diff -u -u -r1.15.2.22 instmap.m
--- instmap.m	1999/06/16 02:12:57	1.15.2.22
+++ instmap.m	1999/07/21 06:32:59
@@ -20,7 +20,7 @@
 :- interface.
 
 :- import_module hlds_module, prog_data, mode_info, (inst), mode_errors.
-:- import_module hlds_data.
+:- import_module hlds_data, inst_table.
 
 :- import_module map, bool, set, list, assoc_list, std_util.
 
@@ -406,7 +406,7 @@
 	instmap__lookup_var(InstMapB, VarB, FinalInst),
 
 	(
-		inst_matches_final(InitialInst, InstMapA,
+		inst_matches_final_ignore_aliasing(InitialInst, InstMapA,
 				FinalInst, InstMapB, InstTable, ModuleInfo)
 	->
 		ChangedVars = ChangedVars0
@@ -956,8 +956,11 @@
 		InstTable0, InstTable) :-
 	map__to_assoc_list(InstMapping0, AL0),
 	map__init(SeenIKs),
+	inst_table_get_other_insts(InstTable0, OtherInsts0),
+	other_inst_table_new_id(OtherInsts0, OtherInsts),
+	inst_table_set_other_insts(InstTable0, OtherInsts, InstTable1),
 	instmap__expand_subs_2(Keys, ModuleInfo, Sub, SeenIKs, AL0, AL,
-		InstTable0, InstTable),
+		InstTable1, InstTable),
 	map__from_assoc_list(AL, InstMapping).
 
 :- pred instmap__expand_subs_2(inst_key_set, module_info, inst_key_sub,
@@ -1047,25 +1050,22 @@
 		Insts0, Insts, InstTable0, InstTable).
 instmap__expand_inst_sub(Keys, ModuleInfo, Sub, SeenIKs0, SeenIKs,
 		defined_inst(InstName), Inst, InstTable0, InstTable) :-
-	inst_table_get_substitution_insts(InstTable0, SubInsts0),
-	SubInst = substitution_inst(InstName, Keys, Sub),
-	SubInstName = substitution_inst(InstName, Keys, Sub),
-	(
-		map__search(SubInsts0, SubInst, Result)
-	->
+	inst_table_get_other_insts(InstTable0, OtherInsts0),
+	other_inst_table_mark_inst_name(OtherInsts0, InstName, NewInstName),
+	( other_inst_table_search(OtherInsts0, InstName, Result) ->
 		( Result = known(Inst0) ->
 			Inst2 = Inst0
 		;
-			Inst2 = defined_inst(SubInstName)
+			Inst2 = defined_inst(NewInstName)
 		),
 		SeenIKs = SeenIKs0,
 		InstTable = InstTable0
 	;
-		% Insert the inst_name in the substitution_inst_table with
+		% Insert the inst_name in the other_inst_table with
 		% value `unknown' for the moment.
-		map__det_insert(SubInsts0, SubInst, unknown, SubInsts1),
-		inst_table_set_substitution_insts(InstTable0, SubInsts1,
-			InstTable1),
+		other_inst_table_set(OtherInsts0, InstName, unknown,
+			OtherInsts1),
+		inst_table_set_other_insts(InstTable0, OtherInsts1, InstTable1),
 
 		% Recursively expand the inst.
 		inst_lookup(InstTable1, ModuleInfo, InstName, Inst0),
@@ -1074,10 +1074,10 @@
 			SeenIKs, Inst1, Inst2, InstTable1, InstTable2),
 
 		% Update the substitution_inst_table with the known value.
-		inst_table_get_substitution_insts(InstTable2, SubInsts2),
-		map__det_update(SubInsts2, SubInst, known(Inst2), SubInsts),
-		inst_table_set_substitution_insts(InstTable2, SubInsts,
-			InstTable)
+		inst_table_get_other_insts(InstTable2, OtherInsts2),
+		other_inst_table_set(OtherInsts2, InstName, known(Inst2),
+			OtherInsts),
+		inst_table_set_other_insts(InstTable2, OtherInsts, InstTable)
 	),
 		% Avoid expanding recursive insts.
 	map__init(InstMapping),
@@ -1090,9 +1090,9 @@
 	;
 			% InstMapping is not used by inst_contains_instname.
 		inst_contains_instname(Inst2, reachable(InstMapping, Sub),
-			InstTable, ModuleInfo, SubInstName)
+			InstTable, ModuleInfo, NewInstName)
 	->
-		Inst = defined_inst(SubInstName)
+		Inst = defined_inst(NewInstName)
 	;
 		Inst = Inst2
 	).
-- 
David Overton       Department of Computer Science & Software Engineering
MEngSc Student      The University of Melbourne, Australia
+61 3 9344 9159     http://www.cs.mu.oz.au/~dmo
--------------------------------------------------------------------------
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