[m-dev.] for review: compressing RTTI using non-word creates (part 1)

Zoltan Somogyi zs at cs.mu.OZ.AU
Mon Apr 26 17:37:11 AEST 1999


For review by Tyson.

Estimated hours taken: 16

Allow the compiler to handle create rvals whose arguments have a size
which is different from the size of a word. Use this capability to reduce
the size of RTTI information, in two ways.

The first way is by rearranging the way in which we represent information
about the live values at a label. Instead of an array with an entry for
each live value, the entry being a pair of Words containing a shape
representation and a location description respectively, use an array
of shape representations (still Words), followed by an array of 32-bit ints
(which may be smaller than Word) describing locations whose descriptions
don't fit into 8 bits, followed by an array of 8-bit ints describing
locations whose descriptions do fit into 8 bits.

The second way is by reducing the sizes of some fields in the C structs
used for RTTI. Several of these had to be bigger than necessary in the
past because their fields were represented by the args of a create rval.

On cyclone, this reduces the size of the object file for queens.m by 3.4%.

IMPORTANT
Until this change is reflected in the installed compiler, you will not be
able to use any modules compiled with debugging in your workspaces if the
workspace has been updated to include this change. This is because the RTTI
data structures generated by the old installed compiler will not be compatible
with the new structure definitions.

The workaround is simple: if your workspace contains modules compiled with
debugging, don't do a cvs update until this change has been installed.

configure.in:
	Check whether <stdint.h> is present. If not, autoconfigure
	types that are at least 8, 16 and 32 bits in size.

runtime/mercury_conf.h.in:
	Mention the macros used by the configure script, INT32_TYPE
	and INT16_TYPE.

runtime/mercury_conf_param.h:
	Document the macros used by the configure script, INT32_TYPE
	and INT16_TYPE.

runtime/mercury_types.h:
	If <stdint.h> is available, get the basic integer types (intptr_t,
	int_least8_t, etc) from there. Otherwise, get them from the
	autoconfigure script. Define types such as Word in terms of these
	(eventually) standard types.

runtime/mercury_stack_layout.h:
	Add macros for manipulating short location descriptions, update the
	types and macros for manipulating long location descriptions.
	Modify the way the variable count is represented (since it now must
	count locations with long and short descriptions separately),
	and move it to the structure containing the arrays it describes.

	Reduce the size of the some fields in structs. This required some
	reordering of fields to avoid the insertion of padding by the compiler,
	and changes to the definitions of some types (e.g. MR_determinism).

runtime/mercury_layout_util.[ch]:
runtime/mercury_stack_trace.c:
runtime/mercury_accurate_gc.c:
trace/mercury_trace.c:
trace/mercury_trace_external.c:
trace/mercury_trace_internal.c:
	Update the code to conform to the changes to stack_layout.h.

compiler/llds.m:
	Modify the create rval in two ways. First, add an extra argument to
	represent the types of the arguments, which used to always be implicit
	always a word in size, but may now be explicit and possibly smaller
	(e.g. uint8). Second, since the code generator would do the wrong
	thing with creates with smaller than wordsize arguments, replace
	the old must-be-unique vs may-be-nonunique bool with a three-valued
	marker, must_be_dynamic vs must_be_static vs can_be_either.

	Add uint8, uint16, uint32 and string as llds_types.

	Add a couple of utility predicates for checking whether an llds_type
	denotes a type whose size is the same as word.

compiler/llds_out.m:
	Use explicitly given argument types when declaring the arguments
	of a cell, if they are given.

compiler/llds_common.m:
	Don't conflate creates with identical argument values but different
	argument types.

compiler/stack_layout.m:
	Use the new representation of creates to generate the new versions of
	RTTI data structures.

compiler/code_exprn.m:
	If a create is marked must_be_static, don't inspect the arguments
	to decide whether it can be static or not.

compiler/base_type_info.m:
compiler/base_type_layout.m:
compiler/base_typeclass_info.m.m:
compiler/code_util.m:
compiler/dupelim.m:
compiler/exprn_aux.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/lookup_switch.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/string_switch.m:
compiler/unify_gen.m:
compiler/vn_cost.m:
compiler/vn_filter.m:
compiler/vn_flush.m:
compiler/vn_order.m:
compiler/vn_type.m:
compiler/vn_util.m:
compiler/vn_verify.m:
	Minor changes required by the change in create.

library/benchmarking.m:
library/std_util.m:
	Use the new macros in hand-constructing proc layout structures.

library/Mmakefile:
	Add explicit dependencies for benchmarking.o and std_util.o
	on ../runtime/mercury_stack_layout.h. Although this is only a subset
	of the truth (in reality, all library objects depend on most of the
	runtime headers), it is a good tradeoff between safety and efficiency.
	The other runtime header files tend not to change in incompatible ways.

trace/Mmakefile:
	Add explicit dependencies for all the object files on
	../runtime/mercury_stack_layout.h, for similar reasons.

Zoltan.

cvs diff: Diffing .
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.162
diff -u -b -u -r1.162 configure.in
--- configure.in	1999/04/22 06:13:50	1.162
+++ configure.in	1999/04/26 01:10:14
@@ -663,8 +663,13 @@
 	fi
 fi
 #-----------------------------------------------------------------------------#
-AC_MSG_CHECKING(for an integer type with the same size as a pointer)
-AC_CACHE_VAL(mercury_cv_word_type,
+AC_CHECK_HEADER(stdint.h, HAVE_STDINT_H=1)
+if test "$HAVE_STDINT_H" = 1; then
+	AC_DEFINE(HAVE_STDINT)
+else
+#-----------------------------------------------------------------------------#
+	AC_MSG_CHECKING(for an integer type with the same size as a pointer)
+	AC_CACHE_VAL(mercury_cv_word_type,
 	AC_TRY_RUN([
 	#include <stdio.h>
 	int main() {
@@ -692,8 +697,8 @@
 	[mercury_cv_word_type=`cat conftest.tags`],
 	[mercury_cv_word_type=unknown],
 	[mercury_cv_word_type=unknown])
-)
-if test "$mercury_cv_word_type" = unknown; then
+	)
+	if test "$mercury_cv_word_type" = unknown; then
 	AC_TRY_RUN([
 	#include <stdio.h>
 	int main() {
@@ -715,11 +720,82 @@
 	[mercury_cv_word_type=`cat conftest.tags`],
 	[mercury_cv_word_type=unknown],
 	[mercury_cv_word_type=unknown])
-fi
-AC_MSG_RESULT($mercury_cv_word_type)
-AC_DEFINE_UNQUOTED(WORD_TYPE, $mercury_cv_word_type)
-WORD_TYPE=$mercury_cv_word_type
-AC_SUBST(WORD_TYPE)
+	fi
+	AC_MSG_RESULT($mercury_cv_word_type)
+	AC_DEFINE_UNQUOTED(WORD_TYPE, $mercury_cv_word_type)
+	WORD_TYPE=$mercury_cv_word_type
+	AC_SUBST(WORD_TYPE)
+#-----------------------------------------------------------------------------#
+	AC_MSG_CHECKING(for a 32-bit integer type)
+	AC_CACHE_VAL(mercury_cv_int32_type,
+		AC_TRY_RUN([
+		#include <stdio.h>
+		int main() {
+			FILE *fp;
+
+			fp = fopen("conftest.tags", "w");
+			if (fp == NULL)
+				exit(1);
+
+			if (sizeof(int) >= 4)
+			{
+				fprintf(fp, "int\n");
+				exit(0);
+			}
+
+			if (sizeof(long) >= 4)
+			{
+				fprintf(fp, "long\n");
+				exit(0);
+			}
+
+			fprintf(fp, "unknown\n");
+			exit(1);
+		}],
+		[mercury_cv_int32_type=`cat conftest.tags`],
+		[mercury_cv_int32_type=unknown],
+		[mercury_cv_int32_type=unknown])
+	)
+	AC_MSG_RESULT($mercury_cv_int32_type)
+	AC_DEFINE_UNQUOTED(INT32_TYPE, $mercury_cv_int32_type)
+	INT32_TYPE=$mercury_cv_int32_type
+	AC_SUBST(INT32_TYPE)
+#-----------------------------------------------------------------------------#
+	AC_MSG_CHECKING(for a 16-bit integer type)
+	AC_CACHE_VAL(mercury_cv_int16_type,
+		AC_TRY_RUN([
+		#include <stdio.h>
+		int main() {
+			FILE *fp;
+
+			fp = fopen("conftest.tags", "w");
+			if (fp == NULL)
+				exit(1);
+
+			if (sizeof(short) >= 2)
+			{
+				fprintf(fp, "short\n");
+				exit(0);
+			}
+
+			if (sizeof(int) >= 2)
+			{
+				fprintf(fp, "int\n");
+				exit(0);
+			}
+
+			fprintf(fp, "unknown\n");
+			exit(1);
+		}],
+		[mercury_cv_int16_type=`cat conftest.tags`],
+		[mercury_cv_int16_type=unknown],
+		[mercury_cv_int16_type=unknown])
+	)
+	AC_MSG_RESULT($mercury_cv_int16_type)
+	AC_DEFINE_UNQUOTED(INT16_TYPE, $mercury_cv_int16_type)
+	INT16_TYPE=$mercury_cv_int16_type
+	AC_SUBST(INT16_TYPE)
+fi # ! HAVE_STDINT_H = 1
 #-----------------------------------------------------------------------------#
 AC_MSG_CHECKING(the number of low tag bits available)
 AC_CACHE_VAL(mercury_cv_low_tag_bits,
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/base_type_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_type_info.m,v
retrieving revision 1.24
diff -u -b -u -r1.24 base_type_info.m
--- base_type_info.m	1999/04/20 02:33:12	1.24
+++ base_type_info.m	1999/04/23 07:15:18
@@ -174,7 +174,7 @@
 	),
 	DataName = type_ctor(info, TypeName, TypeArity),
 	CModule = comp_gen_c_data(ModuleName, DataName, Exported,
-		[ArityArg | FinalArgs], Procs),
+		[ArityArg | FinalArgs], uniform(no), Procs),
 	base_type_info__construct_type_ctor_infos(BaseGenInfos, ModuleInfo,
 		CModules).
 
Index: compiler/base_type_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_type_layout.m,v
retrieving revision 1.42
diff -u -b -u -r1.42 base_type_layout.m
--- base_type_layout.m	1999/04/22 01:04:04	1.42
+++ base_type_layout.m	1999/04/23 07:16:28
@@ -421,10 +421,10 @@
 	;
 		LayoutDataName = type_ctor(layout, TypeName, TypeArity),
 		LayoutCData = comp_gen_c_data(ModuleName, LayoutDataName,
-			Exported, LayoutTypeData, []),
+			Exported, LayoutTypeData, uniform(no), []),
 		FunctorsDataName = type_ctor(functors, TypeName, TypeArity),
 		FunctorsCData = comp_gen_c_data(ModuleName, FunctorsDataName,
-			Exported, FunctorsTypeData, []),
+			Exported, FunctorsTypeData, uniform(no), []),
 		base_type_layout__add_c_data(LayoutInfo3, LayoutCData, 
 			LayoutInfo4),
 		base_type_layout__add_c_data(LayoutInfo4, FunctorsCData, 
@@ -530,20 +530,20 @@
 	% containing the tag and one containing the pointer.
 	
 :- pred base_type_layout__encode_create(layout_info, int, list(maybe(rval)),
-		bool, int, list(maybe(rval))).
+	static_or_dynamic, int, list(maybe(rval))).
 :- mode base_type_layout__encode_create(in, in, in, in, in, out) is det.
-base_type_layout__encode_create(LayoutInfo, Tag, Rvals0, Unique, CellNumber, 
+base_type_layout__encode_create(LayoutInfo, Tag, Rvals0, StatDyn, CellNumber, 
 		Rvals) :-
 	base_type_layout__get_max_tags(LayoutInfo, MaxTags),
 	(
 		MaxTags < 4
 	->
 		Rvals = [yes(const(int_const(Tag))), 
-			yes(create(0, Rvals0, Unique, CellNumber,
-				"type_layout"))]
+			yes(create(0, Rvals0, uniform(no), StatDyn,
+				CellNumber, "type_layout"))]
 	;
-		Rvals = [yes(create(Tag, Rvals0, Unique, CellNumber,
-			"type_layout"))]
+		Rvals = [yes(create(Tag, Rvals0, uniform(no), StatDyn,
+			CellNumber, "type_layout"))]
 	).
 
 	% Encode a cons tag (unshared or shared) in rvals.
@@ -629,7 +629,7 @@
 		LayoutInfo),
 	base_type_layout__tag_value_const(Tag),
 	base_type_layout__encode_create(LayoutInfo, Tag, 
-		VectorRvals, no, NextCellNumber, Rval),
+		VectorRvals, must_be_static, NextCellNumber, Rval),
 
 		% Duplicate it MaxTags times.
 	base_type_layout__get_max_tags(LayoutInfo, MaxTags),
@@ -680,7 +680,7 @@
 	base_type_layout__tag_value_equiv(Tag),
 
 	base_type_layout__encode_create(LayoutInfo, Tag, 
-			VectorRvals, no, NextCellNumber, Rval),
+			VectorRvals, must_be_static, NextCellNumber, Rval),
 
 	base_type_layout__get_max_tags(LayoutInfo, MaxTags),
 	list__duplicate(MaxTags, Rval, RvalsList),
@@ -751,7 +751,8 @@
 		base_type_layout__get_next_cell_number(NextCellNumber, 
 			LayoutInfo1, LayoutInfo),
 		base_type_layout__encode_create(LayoutInfo, Tag, 
-			[IndicatorRval, Rval0], no, NextCellNumber, Rval)
+			[IndicatorRval, Rval0], must_be_static,
+			NextCellNumber, Rval)
 	),
 	base_type_layout__get_max_tags(LayoutInfo, MaxTags),
 	list__duplicate(MaxTags, Rval, RvalsList),
@@ -864,8 +865,8 @@
 		LayoutInfo),
 	base_type_layout__tag_value(shared_local, Tag),
 	base_type_layout__encode_create(LayoutInfo, Tag, 
-		[Rval0, Rval1 | CtorNameRvals], no, NextCellNumber, Rval).
-
+		[Rval0, Rval1 | CtorNameRvals], must_be_static,
+		NextCellNumber, Rval).
 
 	% For unshared tags:
 	%
@@ -881,8 +882,8 @@
 	base_type_layout__get_next_cell_number(NextCellNumber, LayoutInfo1,
 		LayoutInfo),
 	base_type_layout__tag_value(unshared, Tag),
-	base_type_layout__encode_create(LayoutInfo, Tag, EndRvals, no, 
-		NextCellNumber, Rval).
+	base_type_layout__encode_create(LayoutInfo, Tag, EndRvals,
+		must_be_static, NextCellNumber, Rval).
 
 	% Create a functor descriptor.
 	%
@@ -953,7 +954,8 @@
 
 	base_type_layout__tag_value(shared_remote, Tag),
 	base_type_layout__encode_create(LayoutInfo, Tag, 
-		[NumSharersRval | SharedRvals], no, NextCellNumber, Rval).
+		[NumSharersRval | SharedRvals], must_be_static,
+		NextCellNumber, Rval).
 
 %---------------------------------------------------------------------------%
 
@@ -997,8 +999,8 @@
 		LayoutInfo),
 	base_type_layout__functors_value(enum, EnumIndicator),
 	EnumRval = yes(const(int_const(EnumIndicator))),
-	CreateRval = yes(create(0, VectorRvals, no, NextCellNumber,
-		"type_layout")),
+	CreateRval = yes(create(0, VectorRvals, uniform(no), must_be_static,
+		NextCellNumber, "type_layout")),
 	Rvals = [EnumRval, CreateRval].
 
 	% type_ctor_functors of a no_tag:
@@ -1017,8 +1019,8 @@
 
 	base_type_layout__get_next_cell_number(NextCellNumber, LayoutInfo1,
 		LayoutInfo),
-	CreateRval = yes(create(0, VectorRvals, no, NextCellNumber,
-		"type_layout")),
+	CreateRval = yes(create(0, VectorRvals, uniform(no), must_be_static,
+		NextCellNumber, "type_layout")),
 
 	base_type_layout__functors_value(no_tag, NoTagIndicator),
 	NoTagRval = yes(const(int_const(NoTagIndicator))),
@@ -1046,8 +1048,9 @@
 				LayoutInfoA, LayoutInfoB, VectorRvalList),
 			base_type_layout__get_next_cell_number(NextCellNumber,
 				LayoutInfoB, LayoutInfoC),
-			VectorRval = yes(create(0, VectorRvalList, no, 
-				NextCellNumber, "type_layout")),
+			VectorRval = yes(create(0, VectorRvalList, uniform(no),
+				must_be_static, NextCellNumber,
+				"type_layout")),
 			Rvals1 = [VectorRval | Rvals0],
 			NewAcc = Rvals1 - LayoutInfoC)),
 		ConsList, [] - LayoutInfo0, VectorRvals - LayoutInfo),
@@ -1134,8 +1137,8 @@
 
 		list__append(RealArityArg, PseudoArgs1, PseudoArgs),
 
-		Pseudo = create(0, [Pseudo0 | PseudoArgs], no, 
-			CNum0, "type_layout")
+		Pseudo = create(0, [Pseudo0 | PseudoArgs], uniform(no),
+			must_be_static, CNum0, "type_layout")
 	;
 		type_util__var(Type, Var)
 	->
@@ -1157,7 +1160,7 @@
 
 base_type_layout__remove_create(Rval0, Rval) :-
 	(
-		Rval0 = create(_, [PTI], _, _, _)
+		Rval0 = create(_, [PTI], _, _, _, _)
 	->
 		Rval = PTI
 	;
Index: compiler/base_typeclass_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_typeclass_info.m,v
retrieving revision 1.11
diff -u -b -u -r1.11 base_typeclass_info.m
--- base_typeclass_info.m	1999/02/12 03:46:52	1.11
+++ base_typeclass_info.m	1999/04/23 07:46:53
@@ -106,7 +106,7 @@
 		Status = yes,
 
 		CModule = comp_gen_c_data(ModuleName, DataName,
-			Status, Rvals, Procs),
+			Status, Rvals, uniform(no), Procs),
 		CModules = [CModule | CModules1]
 	;
 			% The instance decl is from another module,
Index: compiler/code_exprn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_exprn.m,v
retrieving revision 1.59
diff -u -b -u -r1.59 code_exprn.m
--- code_exprn.m	1998/11/20 04:07:06	1.59
+++ code_exprn.m	1999/04/23 08:01:10
@@ -1,5 +1,5 @@
 %-----------------------------------------------------------------------------%
-% Copyright (C) 1995-1998 The University of Melbourne.
+% Copyright (C) 1995-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.
 %-----------------------------------------------------------------------------%
@@ -414,7 +414,7 @@
 		code_exprn__filter_out_reg_depending(Rvals0, Vars, Rvals),
 		set__empty(Rvals)
 	).
-code_exprn__rval_depends_on_reg(create(_, Rvals, _, _, _), Vars) :-
+code_exprn__rval_depends_on_reg(create(_, Rvals, _, _, _, _), Vars) :-
 	code_exprn__args_depend_on_reg(Rvals, Vars).
 code_exprn__rval_depends_on_reg(mkword(_Tag, Rval), Vars) :-
 	code_exprn__rval_depends_on_reg(Rval, Vars).
@@ -616,7 +616,7 @@
 code_exprn__add_rval_reg_dependencies(lval(Lval)) -->
 	code_exprn__add_lval_reg_dependencies(Lval).
 code_exprn__add_rval_reg_dependencies(var(_Var)) --> [].
-code_exprn__add_rval_reg_dependencies(create(_, Rvals, _, _, _)) -->
+code_exprn__add_rval_reg_dependencies(create(_, Rvals, _, _, _, _)) -->
 	code_exprn__add_arg_reg_dependencies(Rvals).
 code_exprn__add_rval_reg_dependencies(mkword(_Tag, Rval)) -->
 	code_exprn__add_rval_reg_dependencies(Rval).
@@ -689,7 +689,7 @@
 code_exprn__rem_rval_reg_dependencies(lval(Lval)) -->
 	code_exprn__rem_lval_reg_dependencies(Lval).
 code_exprn__rem_rval_reg_dependencies(var(_Var)) --> [].
-code_exprn__rem_rval_reg_dependencies(create(_, Rvals, _, _, _)) -->
+code_exprn__rem_rval_reg_dependencies(create(_, Rvals, _, _, _, _)) -->
 	code_exprn__rem_arg_reg_dependencies(Rvals).
 code_exprn__rem_rval_reg_dependencies(mkword(_Tag, Rval)) -->
 	code_exprn__rem_rval_reg_dependencies(Rval).
@@ -917,11 +917,16 @@
 		mkword(Tag, Expr)) :-
 	code_exprn__expr_is_constant(Expr0, Vars, ExprnOpts, Expr).
 
-code_exprn__expr_is_constant(create(Tag, Args0, Unique, Label, Msg),
-		Vars, ExprnOpts, create(Tag, Args, Unique, Label, Msg)) :-
+code_exprn__expr_is_constant(create(Tag, Args0, ArgTypes, StatDyn, Label, Msg),
+		Vars, ExprnOpts, NewRval) :-
+	( StatDyn = must_be_static ->
+		NewRval = create(Tag, Args0, ArgTypes, StatDyn, Label, Msg)
+	;
 	ExprnOpts = nlg_asm_sgt_ubf(_, _, StaticGroundTerms, _),
 	StaticGroundTerms = yes,
-	code_exprn__args_are_constant(Args0, Vars, ExprnOpts, Args).
+		code_exprn__args_are_constant(Args0, Vars, ExprnOpts, Args),
+		NewRval = create(Tag, Args, ArgTypes, StatDyn, Label, Msg)
+	).
 
 code_exprn__expr_is_constant(var(Var), Vars, ExprnOpts, Rval) :-
 	map__search(Vars, Var, Stat),
@@ -1249,7 +1254,7 @@
 
 code_exprn__rval_is_real_create(Rval) -->
 	(
-		{ Rval = create(_, _, _, _, _) },
+		{ Rval = create(_, _, _, _, _, _) },
 		code_exprn__get_vars(Vars0),
 		code_exprn__get_options(ExprnOpts),
 		{ \+ code_exprn__expr_is_constant(Rval, Vars0, ExprnOpts, _) }
@@ -1275,8 +1280,11 @@
 code_exprn__construct_code(Lval, VarName, Rval0, Code) -->
 	{ exprn_aux__simplify_rval(Rval0, Rval) },
 	(
-		{ Rval = create(Tag, Rvals, _Unique, _Label, Msg) }
+		{ Rval = create(Tag, Rvals, ArgTypes, _StatDyn, _Label, Msg) }
 	->
+		{ require(lambda([] is semidet,
+			(llds__all_args_are_word_size(ArgTypes, yes))),
+		"trying to construct heap cell with non-word-size arg(s)") },
 		{ list__length(Rvals, Arity) },
 		(
 			{ Arity = 0 }
@@ -1381,7 +1389,7 @@
 			;
 				RvalX = unop(_, _)
 			;
-				RvalX = create(_, _, _, _, _)
+				RvalX = create(_, _, _, _, _, _)
 			;
 				RvalX = mkword(_, _)
 			}
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.107
diff -u -b -u -r1.107 code_util.m
--- code_util.m	1999/04/16 06:04:23	1.107
+++ code_util.m	1999/04/19 02:52:42
@@ -932,7 +932,7 @@
 code_util__lvals_in_rval(lval(Lval), [Lval | Lvals]) :-
 	code_util__lvals_in_lval(Lval, Lvals).
 code_util__lvals_in_rval(var(_), []).
-code_util__lvals_in_rval(create(_, _, _, _, _), []).
+code_util__lvals_in_rval(create(_, _, _, _, _, _), []).
 code_util__lvals_in_rval(mkword(_, Rval), Lvals) :-
 	code_util__lvals_in_rval(Rval, Lvals).
 code_util__lvals_in_rval(const(_), []).
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.38
diff -u -b -u -r1.38 dupelim.m
--- dupelim.m	1999/04/16 06:04:29	1.38
+++ dupelim.m	1999/04/20 09:00:59
@@ -441,7 +441,7 @@
 		Rval1 = var(_),
 		error("var in standardize_rval")
 	;
-		Rval1 = create(_, _, _, _, _),
+		Rval1 = create(_, _, _, _, _, _),
 		Rval = Rval1
 	;
 		Rval1 = mkword(_, _),
@@ -735,7 +735,7 @@
 		Rval1 = var(_),
 		error("var in most_specific_rval")
 	;
-		Rval1 = create(_, _, _, _, _),
+		Rval1 = create(_, _, _, _, _, _),
 		Rval2 = Rval1,
 		Rval = Rval1
 	;
@@ -896,8 +896,8 @@
 dupelim__replace_labels_rval(lval(Lval0), ReplMap, lval(Lval)) :-
 	dupelim__replace_labels_lval(Lval0, ReplMap, Lval).
 dupelim__replace_labels_rval(var(Var), _, var(Var)).
-dupelim__replace_labels_rval(create(Tag, Rvals, Unique, N, Msg), _,
-		create(Tag, Rvals, Unique, N, Msg)).
+dupelim__replace_labels_rval(create(Tag, Rvals, ArgTypes, StatDyn, N, Msg), _,
+		create(Tag, Rvals, ArgTypes, StatDyn, N, Msg)).
 dupelim__replace_labels_rval(mkword(Tag, Rval0), ReplMap, mkword(Tag, Rval)) :-
 	dupelim__replace_labels_rval(Rval0, ReplMap, Rval).
 dupelim__replace_labels_rval(const(Const0), ReplMap, const(Const)) :-
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.33
diff -u -b -u -r1.33 exprn_aux.m
--- exprn_aux.m	1999/04/16 06:04:31	1.33
+++ exprn_aux.m	1999/04/19 02:55:06
@@ -191,7 +191,7 @@
 
 exprn_aux__rval_contains_lval(lval(Lval0), Lval) :-
 	exprn_aux__lval_contains_lval(Lval0, Lval).
-exprn_aux__rval_contains_lval(create(_, Rvals, _, _, _), Lval) :-
+exprn_aux__rval_contains_lval(create(_, Rvals, _, _, _, _), Lval) :-
 	exprn_aux__args_contain_lval(Rvals, Lval).
 exprn_aux__rval_contains_lval(mkword(_, Rval), Lval) :-
 	exprn_aux__rval_contains_lval(Rval, Lval).
@@ -251,7 +251,7 @@
 			Rval0 = lval(Lval),
 			exprn_aux__lval_contains_rval(Lval, Rval)
 		;
-			Rval0 = create(_, Rvals, _, _, _),
+			Rval0 = create(_, Rvals, _, _, _, _),
 			exprn_aux__args_contain_rval(Rvals, Rval)
 		;
 			Rval0 = mkword(_, Rval1),
@@ -293,7 +293,7 @@
 exprn_aux__vars_in_rval(lval(Lval), Vars) :-
 	exprn_aux__vars_in_lval(Lval, Vars).
 exprn_aux__vars_in_rval(var(Var), [Var]).
-exprn_aux__vars_in_rval(create(_, Rvals, _, _, _), Vars) :-
+exprn_aux__vars_in_rval(create(_, Rvals, _, _, _, _), Vars) :-
 	exprn_aux__vars_in_args(Rvals, Vars).
 exprn_aux__vars_in_rval(mkword(_, Rval), Vars) :-
 	exprn_aux__vars_in_rval(Rval, Vars).
@@ -369,10 +369,10 @@
 		Rval0 = var(_Var),
 		Rval = Rval0
 	;
-		Rval0 = create(Tag, Rvals0, Unique, Num, Msg),
+		Rval0 = create(Tag, Rvals0, ArgTypes, StatDyn, Num, Msg),
 		exprn_aux__substitute_lval_in_args(OldLval, NewLval,
 			Rvals0, Rvals),
-		Rval = create(Tag, Rvals, Unique, Num, Msg)
+		Rval = create(Tag, Rvals, ArgTypes, StatDyn, Num, Msg)
 	;
 		Rval0 = mkword(Tag, Rval1),
 		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
@@ -535,10 +535,10 @@
 			Rval0 = var(_),
 			Rval = Rval0
 		;
-			Rval0 = create(Tag, Rvals0, Unique, Num, Msg),
+			Rval0 = create(Tag, Rvals0, ATs, StatDyn, Num, Msg),
 			exprn_aux__substitute_rval_in_args(OldRval, NewRval,
 				Rvals0, Rvals),
-			Rval = create(Tag, Rvals, Unique, Num, Msg)
+			Rval = create(Tag, Rvals, ATs, StatDyn, Num, Msg)
 		;
 			Rval0 = mkword(Tag, Rval1),
 			exprn_aux__substitute_rval_in_rval(OldRval, NewRval,
@@ -731,7 +731,7 @@
 exprn_aux__simplify_rval_2(Rval0, Rval) :-
 	(
 		Rval0 = lval(field(MaybeTag, Base, Field)),
-		Base = create(Tag, Args, _, _, _),
+		Base = create(Tag, Args, _, _, _, _),
 		(
 			MaybeTag = yes(Tag)
 		;
@@ -746,11 +746,11 @@
 	->
 		Rval = lval(field(MaybeTag, Rval2, Num))
 	;
-		Rval0 = create(Tag, Args0, Unique, CNum, Msg),
+		Rval0 = create(Tag, Args0, ArgTypes, StatDyn, CNum, Msg),
 		exprn_aux__simplify_args(Args0, Args),
 		Args \= Args0
 	->
-		Rval = create(Tag, Args, Unique, CNum, Msg)
+		Rval = create(Tag, Args, ArgTypes, StatDyn, CNum, Msg)
 	;
 		Rval0 = unop(UnOp, Rval1),
 		exprn_aux__simplify_rval_2(Rval1, Rval2)
@@ -793,7 +793,7 @@
 exprn_aux__rval_addrs(lval(Lval), CodeAddrs, DataAddrs) :-
 	exprn_aux__lval_addrs(Lval, CodeAddrs, DataAddrs).
 exprn_aux__rval_addrs(var(_), [], []).
-exprn_aux__rval_addrs(create(_, MaybeRvals, _, _, _), CodeAddrs, DataAddrs) :-
+exprn_aux__rval_addrs(create(_, MaybeRvals, _,_,_,_), CodeAddrs, DataAddrs) :-
 	exprn_aux__maybe_rval_list_addrs(MaybeRvals, CodeAddrs, DataAddrs).
 exprn_aux__rval_addrs(mkword(_Tag, Rval), CodeAddrs, DataAddrs) :-
 	exprn_aux__rval_addrs(Rval, CodeAddrs, DataAddrs).
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.44
diff -u -b -u -r1.44 jumpopt.m
--- jumpopt.m	1998/07/20 10:00:53	1.44
+++ jumpopt.m	1999/04/20 11:01:01
@@ -1,5 +1,5 @@
 %-----------------------------------------------------------------------------%
-% Copyright (C) 1994-1998 The University of Melbourne.
+% Copyright (C) 1994-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.
 %-----------------------------------------------------------------------------%
@@ -641,8 +641,8 @@
 	jumpopt__short_labels_lval(Lval0, Instrmap, Lval).
 jumpopt__short_labels_rval(var(_), _, _) :-
 	error("var rval in jumpopt__short_labels_rval").
-jumpopt__short_labels_rval(create(Tag, Rvals0, Unique, Cell, Type), Instrmap,
-		create(Tag, Rvals, Unique, Cell, Type)) :-
+jumpopt__short_labels_rval(create(Tag, Rvals0, ArgTypes, StatDyn, Cell, Type),
+		Instrmap, create(Tag, Rvals, ArgTypes, StatDyn, Cell, Type)) :-
 	jumpopt__short_labels_maybe_rvals(Rvals0, Instrmap, Rvals).
 jumpopt__short_labels_rval(mkword(Tag, Rval0), Instrmap,
 		mkword(Tag, Rval)) :-
Index: compiler/livemap.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/livemap.m,v
retrieving revision 1.40
diff -u -b -u -r1.40 livemap.m
--- livemap.m	1999/04/16 06:04:34	1.40
+++ livemap.m	1999/04/20 07:57:33
@@ -429,7 +429,7 @@
 	),
 	opt_util__lval_access_rvals(Lval, AccessRvals),
 	livemap__make_live_in_rvals(AccessRvals, Live1, Live).
-livemap__make_live_in_rval(create(_, _, _, _, _), Live, Live).
+livemap__make_live_in_rval(create(_, _, _, _, _, _), Live, Live).
 	% All terms inside creates in the optimizer must be static.
 livemap__make_live_in_rval(mkword(_, Rval), Live0, Live) :-
 	livemap__make_live_in_rval(Rval, Live0, Live).
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.238
diff -u -b -u -r1.238 llds.m
--- llds.m	1999/04/16 06:04:37	1.238
+++ llds.m	1999/04/26 03:41:37
@@ -17,7 +17,7 @@
 :- interface.
 
 :- import_module hlds_pred, hlds_data, tree, prog_data, (inst).
-:- import_module bool, list, map, set, std_util.
+:- import_module bool, assoc_list, list, map, set, std_util.
 
 %-----------------------------------------------------------------------------%
 
@@ -105,6 +105,8 @@
 						% redundant; see linkage/2
 						% in llds_out.m.
 			list(maybe(rval)),	% The arguments of the create.
+			create_arg_types,	% May specify the types of the
+						% arguments of the create.
 			list(pred_proc_id)	% The procedures referenced.
 						% Used by dead_proc_elim.
 		).
@@ -595,8 +597,10 @@
 		% but should not be present in the LLDS at any
 		% stage after code generation.
 
-	;	create(tag, list(maybe(rval)), bool, int, string)
-		% create(Tag, Arguments, IsUnique, LabelNumber):
+	;	create(tag, list(maybe(rval)), create_arg_types,
+			static_or_dynamic, int, string)
+		% create(Tag, Arguments, MaybeArgTypes, StaticOrDynamic,
+		%	LabelNumber, CellKind):
 		% A `create' instruction is used during code generation
 		% for creating a term, either on the heap or
 		% (if the term is constant) as a static constant.
@@ -604,12 +608,20 @@
 		% should be present in the LLDS, others will get transformed
 		% to incr_hp(..., Tag, Size) plus assignments to the fields.
 		%
-		% The boolean should be true if the term
-		% must be unique (e.g. if we're doing to do
-		% destructive update on it).  This will prevent the term
-		% from being used for other purposes as well; unique terms
-		% are always created on the heap, not as constants, and
-		% we must not do common term elimination on them.
+		% MaybeArgTypes may explicitly give the C level types of
+		% the arguments, although usually these types will be implicit.
+		%
+		% StaticOrDynamic may say that the cell must be allocated
+		% dynamically on the heap, because the resulting data structure
+		% must be unique (e.g. if we're doing to do destructive update
+		% on it). It may say that the cell must be allocated
+		% statically, e.g. because the MaybeArgTypes includes
+		% explicitly specified types that differ in size from Word
+		% (the code generator cannot fill in such cells).
+		% Or it may say that this cell can be allocated either way,
+		% subject to other constraints (e.g. a cell cannot be allocated
+		% statically unless all of its components are statically
+		% allocated as well.
 		%
 		% The label number is needed for the case when
 		% we can construct the term at compile-time
@@ -618,6 +630,13 @@
 		% The last argument gives the name of the type constructor
 		% of the function symbol of which this is a cell, for use
 		% in memory profiling.
+		%
+		% For the time being, you must leave the argument types
+		% implicit if you the cell is to be unique. This is because
+		% (a) the code generator assumes that each argument of a cell
+		% it creates on the heap is the same size as a Word; (b)
+		% this assumption may be incorrect with explicitly defined
+		% argument types.
 
 	;	mkword(tag, rval)
 		% Given a pointer and a tag, mkword returns a tagged pointer.
@@ -632,6 +651,34 @@
 		% The address of a word in the heap, the det stack or
 		% the nondet stack.
 
+:- type static_or_dynamic
+	--->	must_be_static
+	;	can_be_either
+	;	must_be_dynamic.
+
+	% Values of this type specify the C types and therefore the sizes
+	% of the arguments of a create rval.
+	%
+	% If the type is given as yes(LldsType), then the type is the C type
+	% corresponding to LldsType. If the type is given as no, then the
+	% type is implicit; it is llds_out__rval_type_as_arg says when given
+	% the actual argument.
+:- type create_arg_types
+	--->	uniform(maybe(llds_type))	% All the arguments have
+						% the given C type.
+	;	initial(initial_arg_types, create_arg_types)
+						% Each element of the assoc
+						% list N - T specifies that
+						% the next N arguments have
+						% type T. The types of the
+						% remainder of the arguments
+						% are given by the recursive
+						% create_arg_types.
+	;	none.				% There ought to be no more
+						% arguments.
+
+:- type initial_arg_types == assoc_list(int, maybe(llds_type)).
+
 :- type mem_ref
 	--->	stackvar_ref(int)		% stack slot number
 	;	framevar_ref(int)		% stack slot number
@@ -791,26 +838,53 @@
 	% choosing the right sort of register for a given value
 	% to avoid unnecessary boxing/unboxing of floats.
 :- type llds_type
-	--->	bool		% a boolean value
-				% represented using the C type `Integer'
-	;	integer		% a Mercury `int', represented in C as a
+	--->	bool		% A boolean value
+				% represented using the C type `Integer'.
+	;	int8		% A signed value that fits that contains
+				% at least eight bits, represented using the
+				% C type int_least8_t. Intended for use in
+				% static data declarations, not for data
+				% that gets stored in registers, stack slots
+				% etc.
+	;	uint8		% An unsigned version of int8, represented
+				% using the C type uint_least8_t.
+	;	int16		% A signed value that fits that contains
+				% at least sixteen bits, represented using the
+				% C type int_least16_t. Intended for use in
+				% static data declarations, not for data
+				% that gets stored in registers, stack slots
+				% etc.
+	;	uint16		% An unsigned version of int16, represented
+				% using the C type uint_least16_t.
+	;	int32		% A signed value that fits that contains
+				% at least 32 bits, represented using the
+				% C type int_least32_t. Intended for use in
+				% static data declarations, not for data
+				% that gets stored in registers, stack slots
+				% etc.
+	;	uint32		% An unsigned version of int32, represented
+				% using the C type uint_least32_t.
+	;	integer		% A Mercury `int', represented in C as a
 				% value of type `Integer' (which is
 				% a signed integral type of the same
-				% size as a pointer)
-	;	unsigned	% something whose C type is `Unsigned'
-				% (the unsigned equivalent of `Integer')
-	;	float		% a Mercury `float', represented in C as a
+				% size as a pointer).
+	;	unsigned	% Something whose C type is `Unsigned'
+				% (the unsigned equivalent of `Integer').
+	;	float		% A Mercury `float', represented in C as a
 				% value of type `Float' (which may be either
-				% `float' or `double', but is usually `double')
-	;	data_ptr	% a pointer to data; represented in C
-				% as a value of C type `Word *'
-	;	code_ptr	% a pointer to code; represented in C
-				% as a value of C type `Code *'
-	;	word.		% something that can be assigned to a value
+				% `float' or `double', but is usually
+				% `double').
+	;	string		% A string; represented in C as a value of
+				% type `String'.
+	;	data_ptr	% A pointer to data; represented in C
+				% as a value of C type `Word *'.
+	;	code_ptr	% A pointer to code; represented in C
+				% as a value of C type `Code *'.
+	;	word.		% Something that can be assigned to a value
 				% of C type `Word', i.e., something whose
 				% size is a word but which may be either
 				% signed or unsigned
-				% (used for registers, stack slots, etc.)
+				% (used for registers, stack slots, etc).
 
 	% given a non-var rval, figure out its type
 :- pred llds__rval_type(rval::in, llds_type::out) is det.
@@ -833,6 +907,13 @@
 	% given a register, figure out its type
 :- pred llds__register_type(reg_type::in, llds_type::out) is det.
 
+	% check whether the types of all argument are the same size as word
+:- pred llds__all_args_are_word_size(create_arg_types::in, bool::out) is det.
+
+	% check whether an arg of the given type is the same size as word
+	% (floats may be bigger than a word, but if so, they are boxed)
+:- pred llds__type_is_word_size_as_arg(llds_type::in, bool::out) is det.
+
 :- implementation.
 :- import_module require.
 
@@ -861,7 +942,7 @@
 	llds__lval_type(Lval, Type).
 llds__rval_type(var(_), _) :-
 	error("var unexpected in llds__rval_type").
-llds__rval_type(create(_, _, _, _, _), data_ptr).
+llds__rval_type(create(_, _, _, _, _, _), data_ptr).
 	%
 	% Note that create and mkword must both be of type data_ptr,
 	% not of type word, to ensure that static consts containing
@@ -952,3 +1033,33 @@
 
 llds__register_type(r, word).
 llds__register_type(f, float).
+
+llds__all_args_are_word_size(uniform(MaybeType), AllWordSize) :-
+	llds__maybe_type_is_word_size(MaybeType, AllWordSize).
+llds__all_args_are_word_size(initial(Init, Rest), AllWordSize) :-
+	assoc_list__values(Init, MaybeTypes),
+	list__map(llds__maybe_type_is_word_size, MaybeTypes, InitWordSizes),
+	llds__all_args_are_word_size(Rest, RestWordSize),
+	bool__and_list([RestWordSize | InitWordSizes], AllWordSize).
+llds__all_args_are_word_size(none, yes).
+
+:- pred llds__maybe_type_is_word_size(maybe(llds_type)::in, bool::out) is det.
+
+llds__maybe_type_is_word_size(no, yes).
+llds__maybe_type_is_word_size(yes(Type), IsWordSize) :-
+	llds__type_is_word_size_as_arg(Type, IsWordSize).
+
+llds__type_is_word_size_as_arg(int8,     no).
+llds__type_is_word_size_as_arg(uint8,    no).
+llds__type_is_word_size_as_arg(int16,    no).
+llds__type_is_word_size_as_arg(uint16,   no).
+llds__type_is_word_size_as_arg(int32,    no).
+llds__type_is_word_size_as_arg(uint32,   no).
+llds__type_is_word_size_as_arg(bool,     yes).
+llds__type_is_word_size_as_arg(integer,  yes).
+llds__type_is_word_size_as_arg(unsigned, yes).
+llds__type_is_word_size_as_arg(float,    yes).
+llds__type_is_word_size_as_arg(string,   yes).
+llds__type_is_word_size_as_arg(data_ptr, yes).
+llds__type_is_word_size_as_arg(code_ptr, yes).
+llds__type_is_word_size_as_arg(word,     yes).
Index: compiler/llds_common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_common.m,v
retrieving revision 1.21
diff -u -b -u -r1.21 llds_common.m
--- llds_common.m	1998/11/19 06:13:28	1.21
+++ llds_common.m	1999/04/20 08:16:34
@@ -31,7 +31,6 @@
 :- implementation.
 
 :- import_module llds_out.
-
 :- import_module bool, int, assoc_list, map, std_util, require.
 
 :- type cell_info
@@ -39,13 +38,17 @@
 			int		% what is the number of the cell?
 		).
 
+:- type cell_content	==	pair(list(maybe(rval)), create_arg_types).
+:- type cell_map	==	map(cell_content, cell_info).
+:- type cell_list	==	assoc_list(cell_content, cell_info).
+
 :- type common_info
 	--->	common_info(
 			module_name,	% base file name
 			int,		% next cell number
-			map(list(maybe(rval)), cell_info)
-					% map cell contents to cell declaration
-					% information
+			cell_map
+					% map cell contents (including types)
+					% to cell declaration information
 		).
 
 llds_common(Procedures0, Data0, BaseName, Procedures, Data) :-
@@ -64,24 +67,26 @@
 	llds_common__cell_pairs_to_modules(CellPairs, BaseName, CommonData),
 	list__append(CommonData, Data1, Data).
 
-:- pred llds_common__cell_pairs_to_modules(
-	assoc_list(list(maybe(rval)), cell_info)::in, module_name::in,
+:- pred llds_common__cell_pairs_to_modules(cell_list::in, module_name::in,
 	list(comp_gen_c_data)::out) is det.
 
 llds_common__cell_pairs_to_modules([], _, []).
-llds_common__cell_pairs_to_modules([Args - CellInfo | CellPairs], BaseName,
-		[Common | Commons]) :-
+llds_common__cell_pairs_to_modules([CellContent - CellInfo | CellPairs],
+		BaseName, [Common | Commons]) :-
 	CellInfo = cell_info(VarNum),
-	Common = comp_gen_c_data(BaseName, common(VarNum), no, Args, []),
+	CellContent = Args - ArgTypes,
+	Common = comp_gen_c_data(BaseName, common(VarNum), no,
+		Args, ArgTypes, []),
 	llds_common__cell_pairs_to_modules(CellPairs, BaseName, Commons).
 
 :- pred llds_common__process_create(tag::in, list(maybe(rval))::in,
-	rval::out, common_info::in, common_info::out) is det.
+	create_arg_types::in, rval::out, common_info::in, common_info::out)
+	is det.
 
-llds_common__process_create(Tag, Args0, Rval, Info0, Info) :-
+llds_common__process_create(Tag, Args0, ArgTypes, Rval, Info0, Info) :-
 	llds_common__process_maybe_rvals(Args0, Args, Info0, Info1),
 	Info1 = common_info(BaseName, NextCell0, CellMap0),
-	( map__search(CellMap0, Args, CellInfo0) ->
+	( map__search(CellMap0, Args - ArgTypes, CellInfo0) ->
 		CellInfo0 = cell_info(VarNum),
 		DataConst = data_addr_const(
 			data_addr(BaseName, common(VarNum))),
@@ -93,7 +98,7 @@
 		Rval = mkword(Tag, const(DataConst)),
 		CellInfo = cell_info(NextCell0),
 		NextCell is NextCell0 + 1,
-		map__det_insert(CellMap0, Args, CellInfo, CellMap),
+		map__det_insert(CellMap0, Args - ArgTypes, CellInfo, CellMap),
 		Info = common_info(BaseName, NextCell, CellMap)
 	).
 
@@ -114,8 +119,8 @@
 	common_info::in, common_info::out) is det.
 
 llds_common__process_data(
-		comp_gen_c_data(Name, DataName, Export, Args0, Refs),
-		comp_gen_c_data(Name, DataName, Export, Args, Refs),
+		comp_gen_c_data(Name, DataName, Export, Args0, ArgTypes, Refs),
+		comp_gen_c_data(Name, DataName, Export, Args, ArgTypes, Refs),
 		Info0, Info) :-
 	llds_common__process_maybe_rvals(Args0, Args, Info0, Info).
 
@@ -271,9 +276,9 @@
 		Rval0 = var(_),
 		error("var rval found in llds_common__process_rval")
 	;
-		Rval0 = create(Tag, Args, Unique, _LabelNo, _Msg),
-		( Unique = no ->
-			llds_common__process_create(Tag, Args, Rval,
+		Rval0 = create(Tag, Args, ArgTypes, StatDyn, _LabelNo, _Msg),
+		( StatDyn \= must_be_dynamic ->
+			llds_common__process_create(Tag, Args, ArgTypes, Rval,
 				Info0, Info)
 		;
 			Rval = Rval0,
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.106
diff -u -b -u -r1.106 llds_out.m
--- llds_out.m	1999/04/16 06:04:40	1.106
+++ llds_out.m	1999/04/26 01:00:55
@@ -517,7 +517,7 @@
 output_c_data_init_list([]) --> [].
 output_c_data_init_list([Data | Datas]) -->
 	(
-		{ Data = comp_gen_c_data(ModuleName, DataName, _, _, _) },
+		{ Data = comp_gen_c_data(ModuleName, DataName, _, _, _, _) },
 		{ DataName = type_ctor(info, TypeName, Arity) }
 	->
 		io__write_string("\t\tMR_INIT_TYPE_CTOR_INFO(\n\t\t"),
@@ -613,7 +613,7 @@
 :- mode output_c_data_def(in, in, out, di, uo) is det.
 
 output_c_data_def(comp_gen_c_data(ModuleName, VarName, ExportedFromModule,
-		ArgVals, _Refs), DeclSet0, DeclSet) -->
+		ArgVals, ArgTypes, _Refs), DeclSet0, DeclSet) -->
 	io__write_string("\n"),
 	{ DataAddr = data_addr(data_addr(ModuleName, VarName)) },
 
@@ -640,7 +640,7 @@
 		{ ExportedFromFile = SplitFiles }
 	),
 
-	output_const_term_decl(ArgVals, DataAddr, ExportedFromFile, 
+	output_const_term_decl(ArgVals, ArgTypes, DataAddr, ExportedFromFile, 
 			yes, yes, no, "", "", 0, _),
 	{ decl_set_insert(DeclSet0, DataAddr, DeclSet) }.
 
@@ -706,8 +706,8 @@
 :- pred output_comp_gen_c_data(comp_gen_c_data::in,
 	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
 
-output_comp_gen_c_data(comp_gen_c_data(ModuleName, VarName,
-		ExportedFromModule, ArgVals, _Refs), DeclSet0, DeclSet) -->
+output_comp_gen_c_data(comp_gen_c_data(ModuleName, VarName, ExportedFromModule,
+		ArgVals, ArgTypes, _Refs), DeclSet0, DeclSet) -->
 	io__write_string("\n"),
 	{ DataAddr = data_addr(data_addr(ModuleName, VarName)) },
 	output_cons_arg_decls(ArgVals, "", "", 0, _, DeclSet0, DeclSet1),
@@ -740,8 +740,8 @@
 		globals__io_lookup_bool_option(split_c_files, SplitFiles),
 		{ ExportedFromFile = SplitFiles }
 	),
-	output_const_term_decl(ArgVals, DataAddr, ExportedFromFile, no, yes,
-		yes, "", "", 0, _),
+	output_const_term_decl(ArgVals, ArgTypes, DataAddr, ExportedFromFile,
+		no, yes, yes, "", "", 0, _),
 	{ decl_set_insert(DeclSet1, DataAddr, DeclSet) }.
 
 :- pred output_user_c_code_list(list(user_c_code)::in,
@@ -1991,18 +1991,18 @@
 	    { N = N2 },
 	    { DeclSet = DeclSet2 }
 	).
-output_rval_decls(create(_Tag, ArgVals, _, Label, _), FirstIndent, LaterIndent,
-		N0, N, DeclSet0, DeclSet) -->
+output_rval_decls(create(_Tag, ArgVals, CreateArgTypes, _StatDyn, Label, _),
+		FirstIndent, LaterIndent, N0, N, DeclSet0, DeclSet) -->
 	{ CreateLabel = create_label(Label) },
 	( { decl_set_is_member(CreateLabel, DeclSet0) } ->
 		{ N = N0 },
 		{ DeclSet = DeclSet0 }
 	;
 		{ decl_set_insert(DeclSet0, CreateLabel, DeclSet1) },
-		output_cons_arg_decls(ArgVals, FirstIndent, LaterIndent, N0, N1,
-			DeclSet1, DeclSet),
-		output_const_term_decl(ArgVals, CreateLabel, no, yes, yes, yes,
-			FirstIndent, LaterIndent, N1, N)
+		output_cons_arg_decls(ArgVals, FirstIndent, LaterIndent,
+			N0, N1, DeclSet1, DeclSet),
+		output_const_term_decl(ArgVals, CreateArgTypes, CreateLabel,
+			no, yes, yes, yes, FirstIndent, LaterIndent, N1, N)
 	).
 output_rval_decls(mem_addr(MemRef), FirstIndent, LaterIndent,
 		N0, N, DeclSet0, DeclSet) -->
@@ -2110,13 +2110,13 @@
 	% are conditionally output are Def, Decl and Init.  It is an
 	% error for Init to be yes and Decl to be no.
 
-:- pred output_const_term_decl(list(maybe(rval)), decl_id, bool, bool, bool, 
-		bool, string, string, int, int, io__state, io__state).
-:- mode output_const_term_decl(in, in, in, in, in,
+:- pred output_const_term_decl(list(maybe(rval)), create_arg_types, decl_id,
+	bool, bool, bool, bool, string, string, int, int, io__state, io__state).
+:- mode output_const_term_decl(in, in, in, in, in, in,
 		in, in, in, in, out, di, uo) is det.
 
-output_const_term_decl(ArgVals, DeclId, Exported, Def, Decl, Init, FirstIndent, 
-		LaterIndent, N1, N) -->
+output_const_term_decl(ArgVals, CreateArgTypes, DeclId, Exported,
+		Def, Decl, Init, FirstIndent, LaterIndent, N1, N) -->
 	(
 		{ Init = yes }, { Decl = no }
 	->
@@ -2161,7 +2161,7 @@
 		{ Def = yes }
 	->
 		io__write_string(" {\n"),
-		output_cons_arg_types(ArgVals, "\t", 1),
+		output_cons_arg_types(ArgVals, CreateArgTypes, "\t", 1),
 		io__write_string("} ")
 	;
 		[]
@@ -2175,7 +2175,7 @@
 			{ Init = yes }
 		->
 			io__write_string(" = {\n"),
-			output_cons_args(ArgVals, "\t"),
+			output_cons_args(ArgVals, CreateArgTypes, "\t"),
 			io__write_string(LaterIndent),
 			io__write_string("};\n")
 		;
@@ -2219,33 +2219,97 @@
 output_decl_id(pragma_c_struct(_Name)) -->
 	{ error("output_decl_id: pragma_c_struct unexpected") }.
 
-:- pred output_cons_arg_types(list(maybe(rval)), string, int, 
-				io__state, io__state).
-:- mode output_cons_arg_types(in, in, in, di, uo) is det.
+:- pred output_cons_arg_types(list(maybe(rval))::in, create_arg_types::in,
+	string::in, int::in, io__state::di, io__state::uo) is det.
 
-output_cons_arg_types([], _, _) --> [].
-output_cons_arg_types([Arg | Args], Indent, ArgNum) -->
+output_cons_arg_types(Args, uniform(MaybeType), Indent, ArgNum) -->
+	output_uniform_cons_arg_types(Args, MaybeType, Indent, ArgNum).
+output_cons_arg_types(Args, initial(InitialTypes, RestTypes),
+		Indent, ArgNum) -->
+	output_initial_cons_arg_types(Args, InitialTypes, RestTypes,
+		Indent, ArgNum).
+output_cons_arg_types(Args, none, _, _) -->
+	{ require(unify(Args, []), "too many args for specified arg types") }.
+
+:- pred output_uniform_cons_arg_types(list(maybe(rval))::in,
+	maybe(llds_type)::in, string::in, int::in,
+	io__state::di, io__state::uo) is det.
+
+output_uniform_cons_arg_types([], _, _, _) --> [].
+output_uniform_cons_arg_types([Arg | Args], MaybeType, Indent, ArgNum) -->
 	( { Arg = yes(Rval) } ->
 		io__write_string(Indent),
-		llds_out__rval_type_as_arg(Rval, Type),
+		llds_arg_type(Rval, MaybeType, Type),
 		output_llds_type(Type),
 		io__write_string(" f"),
 		io__write_int(ArgNum),
-		io__write_string(";\n")
+		io__write_string(";\n"),
+		{ ArgNum1 is ArgNum + 1 },
+		output_uniform_cons_arg_types(Args, MaybeType, Indent, ArgNum1)
 	;
-		{ error("output_cons_arg_types: missing arg") }
-	),
+		{ error("output_uniform_cons_arg_types: missing arg") }
+	).
+
+:- pred output_initial_cons_arg_types(list(maybe(rval))::in,
+	initial_arg_types::in, create_arg_types::in, string::in, int::in,
+	io__state::di, io__state::uo) is det.
+
+output_initial_cons_arg_types(Args, [], RestTypes, Indent, ArgNum) -->
+	output_cons_arg_types(Args, RestTypes, Indent, ArgNum).
+output_initial_cons_arg_types(Args, [N - MaybeType | InitTypes], RestTypes,
+		Indent, ArgNum) -->
+	output_initial_cons_arg_types_2(Args, N, MaybeType, InitTypes,
+		RestTypes, Indent, ArgNum).
+
+:- pred output_initial_cons_arg_types_2(list(maybe(rval))::in, int::in,
+	maybe(llds_type)::in, initial_arg_types::in, create_arg_types::in,
+	string::in, int::in, io__state::di, io__state::uo) is det.
+
+output_initial_cons_arg_types_2([], N, _, _, _, _, _) -->
+	{ require(unify(N, 0), "not enough args for specified arg types") }.
+output_initial_cons_arg_types_2([Arg | Args], N, MaybeType, InitTypes,
+		RestTypes, Indent, ArgNum) -->
+	( { N = 0 } ->
+		output_initial_cons_arg_types([Arg | Args], InitTypes,
+			RestTypes, Indent, ArgNum)
+	;
+		( { Arg = yes(Rval) } ->
+			io__write_string(Indent),
+			llds_arg_type(Rval, MaybeType, Type),
+			output_llds_type(Type),
+			io__write_string(" f"),
+			io__write_int(ArgNum),
+			io__write_string(";\n"),
 	{ ArgNum1 is ArgNum + 1 },
-	output_cons_arg_types(Args, Indent, ArgNum1).
+			{ N1 is N - 1 },
+			output_initial_cons_arg_types_2(Args, N1, MaybeType,
+				InitTypes, RestTypes, Indent, ArgNum1)
+		;
+			{ error("output_initial_cons_arg_types: missing arg") }
+		)
+	).
+
+	% Given an rval, figure out the type it would have as an argument,
+	% if it is not explicitly specified.
+
+:- pred llds_arg_type(rval::in, maybe(llds_type)::in, llds_type::out,
+	io__state::di, io__state::uo) is det.
+
+llds_arg_type(Rval, MaybeType, Type) -->
+	( { MaybeType = yes(SpecType) } ->
+		{ Type = SpecType }
+	;
+		llds_out__rval_type_as_arg(Rval, Type)
+	).
 
 	% Given an rval, figure out the type it would have as
 	% an argument.  Normally that's the same as its usual type;
 	% the exception is that for boxed floats, the type is data_ptr
 	% (i.e. the type of the boxed value) rather than float
 	% (the type of the unboxed value).
-	%
-:- pred llds_out__rval_type_as_arg(rval, llds_type, io__state, io__state).
-:- mode llds_out__rval_type_as_arg(in, out, di, uo) is det.
+
+:- pred llds_out__rval_type_as_arg(rval::in, llds_type::out,
+	io__state::di, io__state::uo) is det.
 
 llds_out__rval_type_as_arg(Rval, ArgType) -->
 	{ llds__rval_type(Rval, Type) },
@@ -2256,20 +2320,26 @@
 		{ ArgType = Type }
 	).
 
-:- pred output_llds_type(llds_type, io__state, io__state).
-:- mode output_llds_type(in, di, uo) is det.
+:- pred output_llds_type(llds_type::in, io__state::di, io__state::uo) is det.
 
+output_llds_type(int8)     --> io__write_string("int_least8_t").
+output_llds_type(uint8)    --> io__write_string("uint_least8_t").
+output_llds_type(int16)    --> io__write_string("int_least16_t").
+output_llds_type(uint16)   --> io__write_string("uint_least16_t").
+output_llds_type(int32)    --> io__write_string("int_least32_t").
+output_llds_type(uint32)   --> io__write_string("uint_least32_t").
 output_llds_type(bool)     --> io__write_string("Integer").
 output_llds_type(integer)  --> io__write_string("Integer").
 output_llds_type(unsigned) --> io__write_string("Unsigned").
 output_llds_type(float)    --> io__write_string("Float").
 output_llds_type(word)     --> io__write_string("Word").
+output_llds_type(string)   --> io__write_string("String").
 output_llds_type(data_ptr) --> io__write_string("Word *").
 output_llds_type(code_ptr) --> io__write_string("Code *").
 
-:- pred output_cons_arg_decls(list(maybe(rval)), string, string, int, int,
-	decl_set, decl_set, io__state, io__state).
-:- mode output_cons_arg_decls(in, in, in, in, out, in, out, di, uo) is det.
+:- pred output_cons_arg_decls(list(maybe(rval))::in, string::in, string::in,
+	int::in, int::out, decl_set::in, decl_set::out,
+	io__state::di, io__state::uo) is det.
 
 output_cons_arg_decls([], _, _, N, N, DeclSet, DeclSet) --> [].
 output_cons_arg_decls([Arg | Args], FirstIndent, LaterIndent, N0, N,
@@ -2284,27 +2354,79 @@
 	output_cons_arg_decls(Args, FirstIndent, LaterIndent, N1, N,
 		DeclSet1, DeclSet).
 
-:- pred output_cons_args(list(maybe(rval)), string, io__state, io__state).
-:- mode output_cons_args(in, in, di, uo) is det.
-% 	output_cons_args(Args, Indent):
-%	output the arguments, each on its own line prefixing with Indent.
+	% Output the arguments, each on its own line prefixing with Indent,
+	% and with a cast appropriate to its type if necessary.
 
-output_cons_args([], _) --> [].
-output_cons_args([Arg | Args], Indent) -->
+:- pred output_cons_args(list(maybe(rval))::in, create_arg_types::in,
+	string::in, io__state::di, io__state::uo) is det.
+
+output_cons_args(Args, uniform(MaybeType), Indent) -->
+	output_uniform_cons_args(Args, MaybeType, Indent).
+output_cons_args(Args, initial(InitTypes, RestTypes), Indent) -->
+	output_initial_cons_args(Args, InitTypes, RestTypes, Indent).
+output_cons_args(Args, none, _) -->
+	{ require(unify(Args, []), "too many args for specified arg types") }.
+
+:- pred output_uniform_cons_args(list(maybe(rval))::in, maybe(llds_type)::in,
+	string::in, io__state::di, io__state::uo) is det.
+
+output_uniform_cons_args([], _, _) --> [].
+output_uniform_cons_args([Arg | Args], MaybeType, Indent) -->
 	( { Arg = yes(Rval) } ->
 		io__write_string(Indent),
-		llds_out__rval_type_as_arg(Rval, TypeAsArg),
-		output_rval_as_type(Rval, TypeAsArg)
+		llds_arg_type(Rval, MaybeType, Type),
+		output_rval_as_type(Rval, Type),
+		( { Args \= [] } ->
+			io__write_string(",\n"),
+			output_uniform_cons_args(Args, MaybeType, Indent)
+		;
+			io__write_string("\n")
+		)
 	;
 		% `Arg = no' means the argument is uninitialized,
 		% but that would mean the term isn't ground
-		{ error("output_cons_args: missing argument") }
-	),
+		{ error("output_uniform_cons_args: missing argument") }
+	).
+
+:- pred output_initial_cons_args(list(maybe(rval))::in, initial_arg_types::in,
+	create_arg_types::in, string::in, io__state::di, io__state::uo) is det.
+
+output_initial_cons_args(Args, [], RestTypes, Indent) -->
+	output_cons_args(Args, RestTypes, Indent).
+output_initial_cons_args(Args, [N - MaybeType | InitTypes], RestTypes,
+		Indent) -->
+	output_initial_cons_args_2(Args, N, MaybeType, InitTypes, RestTypes,
+		Indent).
+
+:- pred output_initial_cons_args_2(list(maybe(rval))::in, int::in,
+	maybe(llds_type)::in, initial_arg_types::in, create_arg_types::in,
+	string::in, io__state::di, io__state::uo) is det.
+
+output_initial_cons_args_2([], N, _, _, _, _) -->
+	{ require(unify(N, 0), "not enough args for specified arg types") }.
+output_initial_cons_args_2([Arg | Args], N, MaybeType, InitTypes, RestTypes,
+		Indent) -->
+	( { N = 0 } ->
+		output_initial_cons_args([Arg | Args], InitTypes, RestTypes,
+			Indent)
+	;
+		( { Arg = yes(Rval) } ->
+			{ N1 is N - 1 },
+			io__write_string(Indent),
+			llds_arg_type(Rval, MaybeType, Type),
+			output_rval_as_type(Rval, Type),
 	( { Args \= [] } ->
 		io__write_string(",\n"),
-		output_cons_args(Args, Indent)
+				output_initial_cons_args_2(Args, N1, MaybeType,
+					InitTypes, RestTypes, Indent)
 	;
+				{ require(unify(N1, 0),
+				"not enough args for specified arg types") },
 		io__write_string("\n")
+			)
+		;
+			{ error("output_initial_cons_arg: missing argument") }
+		)
 	).
 
 %-----------------------------------------------------------------------------%
@@ -3312,7 +3434,7 @@
 	;
 		output_lval(Lval)
 	).
-output_rval(create(Tag, _Args, _Unique, CellNum, _Msg)) -->
+output_rval(create(Tag, _Args, _ArgTypes, _StatDyn, CellNum, _Msg)) -->
 		% emit a reference to the static constant which we
 		% declared in output_rval_decls.
 	io__write_string("mkword(mktag("),
Index: compiler/lookup_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lookup_switch.m,v
retrieving revision 1.32
diff -u -b -u -r1.32 lookup_switch.m
--- lookup_switch.m	1998/11/20 04:08:13	1.32
+++ lookup_switch.m	1999/04/23 07:34:26
@@ -1,5 +1,5 @@
 %-----------------------------------------------------------------------------%
-% Copyright (C) 1996-1998 The University of Melbourne.
+% Copyright (C) 1996-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.
 %-----------------------------------------------------------------------------%
@@ -246,10 +246,14 @@
 	lookup_switch__rval_is_constant(Exprn1, ExprnOpts).
 lookup_switch__rval_is_constant(mkword(_, Exprn0), ExprnOpts) :-
 	lookup_switch__rval_is_constant(Exprn0, ExprnOpts).
-lookup_switch__rval_is_constant(create(_, Args, _, _, _), ExprnOpts) :-
+lookup_switch__rval_is_constant(create(_, Args, _, StatDyn, _,_), ExprnOpts) :-
+	(
+		StatDyn = must_be_static
+	;
 	ExprnOpts = nlg_asm_sgt_ubf(_, _, StaticGroundTerms, _),
 	StaticGroundTerms = yes,
-	lookup_switch__rvals_are_constant(Args, ExprnOpts).
+		lookup_switch__rvals_are_constant(Args, ExprnOpts)
+	).
 
 :- pred lookup_switch__rvals_are_constant(list(maybe(rval)), exprn_opts).
 :- mode lookup_switch__rvals_are_constant(in, in) is semidet.
@@ -346,7 +350,7 @@
 		% low bits specify which bit.
 		%
 	{
-		BitVec = create(_, [yes(SingleWord)], _, _, _)
+		BitVec = create(_, [yes(SingleWord)], _, _, _, _)
 	->
 		Word = SingleWord,
 		BitNum = UIndex
@@ -390,7 +394,8 @@
 	{ map__to_assoc_list(BitMap, WordVals) },
 	{ generate_bit_vec_args(WordVals, 0, Args) },
 	code_info__get_next_cell_number(CellNo),
-	{ BitVec = create(0, Args, no, CellNo, "lookup_switch_bit_vector") }.
+	{ BitVec = create(0, Args, uniform(no), must_be_static,
+		CellNo, "lookup_switch_bit_vector") }.
 
 :- pred generate_bit_vec_2(case_consts, int, int,
 			map(int, int), map(int, int)).
@@ -456,7 +461,8 @@
 	{ list__sort(Vals0, Vals) },
 	{ construct_args(Vals, 0, Args) },
 	code_info__get_next_cell_number(CellNo),
-	{ ArrayTerm = create(0, Args, no, CellNo, "lookup_switch_data") },
+	{ ArrayTerm = create(0, Args, uniform(no), must_be_static,
+		CellNo, "lookup_switch_data") },
 	{ LookupTerm = lval(field(yes(0), ArrayTerm, Index)) },
 	code_info__cache_expression(Var, LookupTerm),
 	lookup_switch__generate_terms_2(Index, Vars, Map).
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/middle_rec.m,v
retrieving revision 1.75
diff -u -b -u -r1.75 middle_rec.m
--- middle_rec.m	1998/11/20 04:08:23	1.75
+++ middle_rec.m	1999/04/20 08:14:48
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1994-1998 The University of Melbourne.
+% Copyright (C) 1994-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.
 %---------------------------------------------------------------------------%
@@ -484,7 +484,7 @@
 		Rval = var(_),
 		error("var found in middle_rec__find_used_registers_rval")
 	;
-		Rval = create(_, MaybeRvals, _, _, _),
+		Rval = create(_, MaybeRvals, _, _, _, _),
 		middle_rec__find_used_registers_maybe_rvals(MaybeRvals,
 			Used0, Used)
 	;
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.90
diff -u -b -u -r1.90 opt_debug.m
--- opt_debug.m	1999/04/16 06:04:45	1.90
+++ opt_debug.m	1999/04/20 11:15:12
@@ -540,7 +540,7 @@
 opt_debug__dump_vnrval(vn_const(C), Str) :-
 	opt_debug__dump_const(C, C_str),
 	string__append_list(["vn_const(", C_str, ")"], Str).
-opt_debug__dump_vnrval(vn_create(T, MA, _U, L, _M), Str) :-
+opt_debug__dump_vnrval(vn_create(T, MA, _TA, _U, L, _M), Str) :-
 	string__int_to_string(T, T_str),
 	opt_debug__dump_maybe_rvals(MA, 3, MA_str),
 	string__int_to_string(L, L_str),
@@ -634,15 +634,18 @@
 opt_debug__dump_rval(const(C), Str) :-
 	opt_debug__dump_const(C, C_str),
 	string__append_list(["const(", C_str, ")"], Str).
-opt_debug__dump_rval(create(T, MA, U, L, _), Str) :-
+opt_debug__dump_rval(create(T, MA, _, U, L, _), Str) :-
 	string__int_to_string(T, T_str),
 	opt_debug__dump_maybe_rvals(MA, 3, MA_str),
 	(
-		U = yes,
-		U_str = "yes"
+		U = must_be_static,
+		U_str = "static"
 	;
-		U = no,
-		U_str = "no"
+		U = can_be_either,
+		U_str = "either"
+	;
+		U = must_be_dynamic,
+		U_str = "dynamic"
 	),
 	string__int_to_string(L, L_str),
 	string__append_list(["create(", T_str, ", ", MA_str, ", ",
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.98
diff -u -b -u -r1.98 opt_util.m
--- opt_util.m	1999/04/16 06:04:46	1.98
+++ opt_util.m	1999/04/20 08:15:20
@@ -669,7 +669,7 @@
 	opt_util__lval_refers_stackvars(Lval, Refers).
 opt_util__rval_refers_stackvars(var(_), _) :-
 	error("found var in rval_refers_stackvars").
-opt_util__rval_refers_stackvars(create(_, Rvals, _, _, _), Refers) :-
+opt_util__rval_refers_stackvars(create(_, Rvals, _, _, _, _), Refers) :-
 	opt_util__rvals_refer_stackvars(Rvals, Refers).
 opt_util__rval_refers_stackvars(mkword(_, Rval), Refers) :-
 	opt_util__rval_refers_stackvars(Rval, Refers).
@@ -1478,7 +1478,7 @@
 opt_util__touches_nondet_ctrl_rval(lval(Lval), Touch) :-
 	opt_util__touches_nondet_ctrl_lval(Lval, Touch).
 opt_util__touches_nondet_ctrl_rval(var(_), no).
-opt_util__touches_nondet_ctrl_rval(create(_, _, _, _, _), no).
+opt_util__touches_nondet_ctrl_rval(create(_, _, _, _, _, _), no).
 opt_util__touches_nondet_ctrl_rval(mkword(_, Rval), Touch) :-
 	opt_util__touches_nondet_ctrl_rval(Rval, Touch).
 opt_util__touches_nondet_ctrl_rval(const(_), no).
@@ -1558,7 +1558,7 @@
 	opt_util__rvals_free_of_lval(Rvals, Forbidden).
 opt_util__rval_free_of_lval(var(_), _) :-
 	error("found var in opt_util__rval_free_of_lval").
-opt_util__rval_free_of_lval(create(_, _, _, _, _), _).
+opt_util__rval_free_of_lval(create(_, _, _, _, _, _), _).
 opt_util__rval_free_of_lval(mkword(_, Rval), Forbidden) :-
 	opt_util__rval_free_of_lval(Rval, Forbidden).
 opt_util__rval_free_of_lval(const(_), _).
--------------------------------------------------------------------------
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