[m-dev.] for review: MLDS backend to do structure reuse and compile time gc

Peter Ross peter.ross at miscrit.be
Fri Oct 6 21:36:02 AEDT 2000


On Fri, Oct 06, 2000 at 03:07:21AM +1100, Fergus Henderson wrote:
> On 05-Oct-2000, Peter Ross <Peter.Ross at cs.kuleuven.ac.be> wrote:
> > Update the MLDS backend to handle structure reuse and compile time gc.
> > Note that currently no pass on the main branch currently generates this
> > information yet.
> ...
> > mlds.m:
> >     Update the assign instruction with a field that says whether or not
> >     the LHS of the assigment needs to use a different tag to the RHS of
> >     the assignment and what that tag is.
> 
> Why not just use different rvals, rather than different forms of
> the `assign' instruction?
> 
> I think it would be much better to just generate an MLDS instruction
> of the form
> 
> 	assign(Lval, mkword(ml_gen_mktag(NewTag),
> 		binop(body, Rval, ml_gen_mktag(OldTag))))
> 
> where ml_gen_mktag/1 is defined by
> 
> 	:- func ml_gen_mktag(int) = rval.
> 	ml_gen_mktag(Tag) = unary_op(mktag, const(int_const(Tag)).
> 
> This will also be more efficient than using MR_strip_tag,
> and shouldn't be a problem, since you know what the old tag
> is from the cons_id in the reuse_cell/3 constructor.
> Alternatively, if for some reason you need to use strip_tag,
> then you can add that as a new unary_op.
> 
> There is one problem with using `body' -- currently there is a bug in
> builtin_ops.m, "body" should be a binop but currently it is listed as
> a unary op.  But that should be fairly easily fixed.
> 
> Anyway, this approach of using rvals keeps the MLDS data structure
> simpler, which keeps the code that traverses it simpler.
> 
No this approach is much nicer, I just didn't think of it.

Here is an incremental diff, and full diff following it with all you
suggestions.

===================================================================


Estimated hours taken: 20

Update the MLDS backend to handle structure reuse and compile time gc.
Note that currently no pass on the main branch currently generates this
information yet.

mlds.m:
    Add a new instruction delete_object which is to be inserted
    whenever a lval can be compile time garbage collected.

ml_unify_gen.m:
    Handle the case where the HowToConstruct field of a construction
    is reuse_cell(_).
    Handle the case where a deconstruction can be compile time gc'd.

hlds_goal.m:
    Add a new field, can_cgc, to deconstruction unifications.  This
    field is `yes' if the deconstruction unification can be compile time
    garbage collected.
    
hlds_out.m:
    Output the can_cgc field.  Output unification information if we
    request the structure reuse information.

ml_elim_nested.m:
mlds_to_c.m:
    Handle the delete_object instruction.

builtin_ops.m:
    Fix a bug where body was an unary op instead of a binary op.

bytecode.m:
c_util.m:
llds.m:
opt_debug.m:
vn_cost.m:
    Changes to reflect that body is a binary op.

bytecode_gen.m:
code_aux.m:
common.m:
cse_detection.m:
dependency_graph.m:
det_analysis.m:
goal_util.m:
higher_order.m:
mark_static_terms.m:
mode_util.m:
modecheck_unify.m:
pd_cost.m:
pd_util.m:
prog_rep.m:
rl_exprn.m:
rl_key.m:
simplify.m:
switch_detection.m:
term_traversal.m:
unify_gen.m:
unused_args.m:
    Handle the can compile time gc field in deconstruction unifications.


*** Incremental Diff ***
--- hlds_goal.m
+++ hlds_goal.m
@@ -414 +414,4 @@
-	% The cell is available for compile time garbage collected.
+	% `yes' iff the cell is available for compile time garbage collection.
+	% Compile time garbage collection is when the compiler
+	% recognises that a memory cell is no longer needed and can be
+	% safely deallocated (ie by inserting an explicit call to free).
@@ -485 +488,3 @@
-			can_cgc		% Can compile time GC this cell
+			can_cgc		% Can compile time GC this cell,
+					% ie explicitly deallocate it
+					% after the deconstruction.
--- hlds_out.m
+++ hlds_out.m
@@ -1500,2 +1500,7 @@
-	( { string__contains_char(Verbose, 'u') 
-			; string__contains_char(Verbose, 'p') } ->
+	(
+		{
+			string__contains_char(Verbose, 'u') 
+		;
+			string__contains_char(Verbose, 'p')
+		}
+	->
--- ml_code_util.m	2000/10/05 14:16:04
+++ ml_code_util.m	2000/09/18 11:51:30	1.22
@@ -32,11 +32,6 @@
 	% Generate an MLDS assignment statement.
 :- func ml_gen_assign(mlds__lval, mlds__rval, prog_context) = mlds__statement.
 
-	% Generate an MLDS assignment statement where the lval must use
-	% the tag.
-:- func ml_gen_assign_with_tag(mlds__lval, mlds__rval,
-		mlds__tag, prog_context) = mlds__statement.
-
 	% Generate a block statement, i.e. `{ <Decls>; <Statements>; }'.
 	% But if the block consists only of a single statement with no
 	% declarations, then just return that statement.
@@ -598,16 +593,8 @@
 %
 
 	% Generate an MLDS assignment statement.
+ml_gen_assign(Lval, Rval, Context) = MLDS_Statement :-
+	Assign = assign(Lval, Rval),
-ml_gen_assign(Lval, Rval, Context) = ml_gen_assign(Lval, Rval, no, Context).
-
-ml_gen_assign_with_tag(Lval, Rval, Tag, Context)
-	= ml_gen_assign(Lval, Rval, yes(Tag), Context).
-
-:- func ml_gen_assign(mlds__lval, mlds__rval,
-		maybe(mlds__tag), prog_context) = mlds__statement.
-
-ml_gen_assign(Lval, Rval, MaybeTag, Context) = MLDS_Statement :-
-	Assign = assign(Lval, Rval, MaybeTag),
 	MLDS_Stmt = atomic(Assign),
 	MLDS_Statement = mlds__statement(MLDS_Stmt,
 		mlds__make_context(Context)).
@@ -1329,7 +1316,7 @@
 	%
 ml_gen_set_success(Value, Context, MLDS_Statement) -->
 	ml_success_lval(Succeeded),
+	{ MLDS_Statement = ml_gen_assign(Succeeded, Value, Context) }.
-	{ MLDS_Statement = ml_gen_assign(Succeeded, Value, no, Context) }.
 
 %-----------------------------------------------------------------------------%
 
@@ -1352,7 +1339,7 @@
 	
 ml_gen_set_cond_var(CondVar, Value, Context, MLDS_Statement) -->
 	ml_cond_var_lval(CondVar, CondVarLval),
+	{ MLDS_Statement = ml_gen_assign(CondVarLval, Value, Context) }.
-	{ MLDS_Statement = ml_gen_assign(CondVarLval, Value, no, Context) }.
 
 %-----------------------------------------------------------------------------%
 
--- ml_elim_nested.m
+++ ml_elim_nested.m
@@ -283 +283 @@
-		AssignToEnv = assign(EnvArgLval, ArgRval, no),
+		AssignToEnv = assign(EnvArgLval, ArgRval),
@@ -418 +418 @@
-		EnvPtrVal), no),
+		EnvPtrVal)),
@@ -748 +748 @@
-fixup_atomic_stmt(assign(Lval0, Rval0, Tag), assign(Lval, Rval, Tag)) -->
+fixup_atomic_stmt(assign(Lval0, Rval0), assign(Lval, Rval)) -->
@@ -751 +751 @@
-fixup_atomic_stmt(compile_time_gc(Lval0), compile_time_gc(Lval)) -->
+fixup_atomic_stmt(delete_object(Lval0), delete_object(Lval)) -->
@@ -1214 +1214 @@
-atomic_stmt_contains_var(assign(Lval, Rval, _MaybeTag), Name) :-
+atomic_stmt_contains_var(assign(Lval, Rval), Name) :-
--- ml_optimize.m	2000/10/05 14:16:04
+++ ml_optimize.m	2000/09/17 09:18:57	1.2
@@ -248,7 +248,7 @@
 			Statement = statement(
 				atomic(assign(
 					var(QualVarName),
+					lval(var(QualTempName)))), 
-					lval(var(QualTempName)), no)), 
 				OptInfo ^ context),
 			generate_assign_args(OptInfo, Rest, Args, Statements0,
 				TempDefns0),
--- ml_unify_gen.m
+++ ml_unify_gen.m
@@ -88,3 +88,19 @@
-		MLDS_Defns, MLDS_Statements) -->
-	ml_gen_assign_unification(Var1, Var2, no, CodeModel, Context,
-			MLDS_Defns, MLDS_Statements).
+		[], MLDS_Statements) -->
+	{ require(unify(CodeModel, model_det),
+		"ml_code_gen: assign not det") },
+	(
+		%
+		% skip dummy argument types, since they will not have
+		% been declared
+		%
+		ml_variable_type(Var1, Type),
+		{ type_util__is_dummy_argument_type(Type) }
+	->
+		{ MLDS_Statements = [] }
+	;
+		ml_gen_var(Var1, Var1Lval),
+		ml_gen_var(Var2, Var2Lval),
+		{ MLDS_Statement = ml_gen_assign(Var1Lval, lval(Var2Lval),
+			Context) },
+		{ MLDS_Statements = [MLDS_Statement] }
+	).
@@ -137,0 +154,4 @@
+			% Note that we can deallocate a cell even if the 
+			% unification fails, it is the responsibility of
+			% the structure reuse phase to ensure that this
+			% is safe.
@@ -140 +160 @@
-		{ MLDS_Stmt = atomic(compile_time_gc(VarLval)) },
+		{ MLDS_Stmt = atomic(delete_object(VarLval)) },
@@ -154,36 +173,0 @@
-	% Generate MLDS code for an assignment unification where the 
-	% LHS of the unification may need to use a different tag to the
-	% RHS.
-:- pred ml_gen_assign_unification(prog_var::in, prog_var::in,
-		maybe(mlds__tag)::in, code_model::in, prog_context::in,
-		mlds__defns::out, mlds__statements::out,
-		ml_gen_info::in, ml_gen_info::out) is det.
-
-ml_gen_assign_unification(Var1, Var2, MaybeTag, CodeModel, Context,
-		[], MLDS_Statements) -->
-	{ require(unify(CodeModel, model_det),
-		"ml_code_gen: assign not det") },
-	(
-		%
-		% skip dummy argument types, since they will not have
-		% been declared
-		%
-		ml_variable_type(Var1, Type),
-		{ type_util__is_dummy_argument_type(Type) }
-	->
-		{ MLDS_Statements = [] }
-	;
-		ml_gen_var(Var1, Var1Lval),
-		ml_gen_var(Var2, Var2Lval),
-		(
-			{ MaybeTag = no },
-			{ MLDS_Statement = ml_gen_assign(Var1Lval,
-					lval(Var2Lval), Context) }
-		;
-			{ MaybeTag = yes(Tag) },
-			{ MLDS_Statement = ml_gen_assign_with_tag(Var1Lval,
-					lval(Var2Lval), Tag, Context) }
-		),
-		{ MLDS_Statements = [MLDS_Statement] }
-	).
-
@@ -1034,0 +1019,2 @@
+		ml_gen_var(Var, Var1Lval),
+		ml_gen_var(ReuseVar, Var2Lval),
@@ -1036 +1022 @@
-			MaybeRetagLval = no
+			Var2Rval = lval(Var2Lval)
@@ -1038 +1024,3 @@
-			MaybeRetagLval = yes(PrimaryTag)
+			Var2Rval = mkword(PrimaryTag,
+					binop(body, lval(Var2Lval),
+					ml_gen_mktag(ReusePrimaryTag)))
@@ -1041,3 +1029 @@
-		ml_gen_assign_unification(Var, ReuseVar, MaybeRetagLval,
-				model_det, Context,
-				MLDS_Decls, MLDS_StatementsA),
+		{ MLDS_Statement = ml_gen_assign(Var1Lval, Var2Rval, Context) },
@@ -1053 +1039 @@
-				ArgNum, PrimaryTag, Context, MLDS_StatementsB),
+				ArgNum, PrimaryTag, Context, MLDS_Statements0),
@@ -1055 +1041,2 @@
-		{ MLDS_Statements = MLDS_StatementsA `append` MLDS_StatementsB }
+		{ MLDS_Decls = [] },
+		{ MLDS_Statements = [MLDS_Statement | MLDS_Statements0] }
@@ -1056,0 +1044,3 @@
+
+:- func ml_gen_mktag(int) = mlds__rval.
+ml_gen_mktag(Tag) = unop(std_unop(mktag), const(int_const(Tag))).
--- mlds.m
+++ mlds.m
@@ -824,2 +824,2 @@
-	;	assign(mlds__lval, mlds__rval, maybe(mlds__tag))
-			% assign(Location, Value, MaybeTag):
+	;	assign(mlds__lval, mlds__rval)
+			% assign(Location, Value):
@@ -827,2 +827 @@
-			% specified by lval.  Possibly changing the tag
-			% on the lval, if required.
+			% specified by lval.
@@ -834,3 +833,3 @@
-	;	compile_time_gc(mlds__lval)
-			% Compile time garbage collect the memory used
-			% by the lval.
+	;	delete_object(mlds__lval)
+			% Compile time garbage collect (ie explicitly
+			% deallocate) the memory used by the lval.
--- mlds_to_c.m
+++ mlds_to_c.m
@@ -2182 +2182 @@
-mlds_output_atomic_stmt(Indent, _FuncInfo, assign(Lval, Rval, MaybeTag), _) -->
+mlds_output_atomic_stmt(Indent, _FuncInfo, assign(Lval, Rval), _) -->
@@ -2187,13 +2187 @@
-	io__write_string(";\n"),
-	(
-		{ MaybeTag = yes(Tag) },
-		mlds_indent(Indent),
-		mlds_output_lval(Lval),
-		io__write_string(" = (MR_Word) MR_mkword(MR_strip_tag("),
-		mlds_output_lval(Lval),
-		io__write_string("), "),
-		mlds_output_tag(Tag),
-		io__write_string(");\n")
-	;
-		{ MaybeTag = no }
-	).
+	io__write_string(";\n").
@@ -2204,2 +2192,2 @@
-mlds_output_atomic_stmt(_Indent, _FuncInfo, compile_time_gc(_Lval), _) -->
-	{ error("mlds_to_c.m: sorry, compile time gc not implemented") }.
+mlds_output_atomic_stmt(_Indent, _FuncInfo, delete_object(_Lval), _) -->
+	{ error("mlds_to_c.m: sorry, delete_object not implemented") }.
--- vn_cost.m	2000/04/26 05:40:43	1.42
+++ vn_cost.m	2000/10/06 09:56:45
@@ -370,7 +370,6 @@
 vn_cost__assign_cost_unop(tag).
 vn_cost__assign_cost_unop(unmktag).
 vn_cost__assign_cost_unop(mkbody).
-vn_cost__assign_cost_unop(body).
 vn_cost__assign_cost_unop(unmkbody).
 vn_cost__assign_cost_unop(bitwise_complement).
 
@@ -391,6 +390,7 @@
 vn_cost__assign_cost_binop('|').
 vn_cost__assign_cost_binop(and).
 vn_cost__assign_cost_binop(or).
+vn_cost__assign_cost_binop(body).
 
 % These unary operations cost zero instructions.
 
--- opt_debug.m	2000/08/11 08:19:14	1.105
+++ opt_debug.m	2000/10/06 09:56:33
@@ -803,7 +803,6 @@
 opt_debug__dump_unop(tag, "tag").
 opt_debug__dump_unop(unmktag, "unmktag").
 opt_debug__dump_unop(mkbody, "mkbody").
-opt_debug__dump_unop(body, "body").
 opt_debug__dump_unop(unmkbody, "unmkbody").
 opt_debug__dump_unop(not, "not").
 opt_debug__dump_unop(hash_string, "hash_string").
--- llds.m	2000/10/04 05:23:06	1.264
+++ llds.m	2000/10/06 09:56:23
@@ -1141,7 +1141,6 @@
 llds__unop_return_type(unmktag, word).
 llds__unop_return_type(mkbody, word).
 llds__unop_return_type(unmkbody, word).
-llds__unop_return_type(body, word).
 llds__unop_return_type(cast_to_unsigned, unsigned).
 llds__unop_return_type(hash_string, integer).
 llds__unop_return_type(bitwise_complement, integer).
@@ -1152,7 +1151,6 @@
 llds__unop_arg_type(unmktag, word).
 llds__unop_arg_type(mkbody, word).
 llds__unop_arg_type(unmkbody, word).
-llds__unop_arg_type(body, word).
 llds__unop_arg_type(cast_to_unsigned, word).
 llds__unop_arg_type(hash_string, word).
 llds__unop_arg_type(bitwise_complement, integer).
@@ -1193,6 +1191,7 @@
 llds__binop_return_type(float_gt, bool).
 llds__binop_return_type(float_le, bool).
 llds__binop_return_type(float_ge, bool).
+llds__binop_return_type(body, word).
 
 llds__register_type(r, word).
 llds__register_type(f, float).
--- c_util.m	2000/08/14 09:08:43	1.4
+++ c_util.m	2000/10/06 09:56:16
@@ -204,7 +204,6 @@
 c_util__unary_prefix_op(tag,			"MR_tag").
 c_util__unary_prefix_op(unmktag,		"MR_unmktag").
 c_util__unary_prefix_op(mkbody,			"MR_mkbody").
-c_util__unary_prefix_op(body,			"MR_body").
 c_util__unary_prefix_op(unmkbody,		"MR_unmkbody").
 c_util__unary_prefix_op(hash_string,		"MR_hash_string").
 c_util__unary_prefix_op(bitwise_complement,	"~").
--- bytecode.m	2000/04/17 10:51:52	1.40
+++ bytecode.m	2000/10/06 09:56:16
@@ -1010,6 +1010,7 @@
 binop_code(float_gt,		32).
 binop_code(float_le,		33).
 binop_code(float_ge,		34).
+binop_code(body,		35).
 
 :- pred binop_debug(binary_op, string).
 :- mode binop_debug(in, out) is det.
@@ -1049,6 +1050,7 @@
 binop_debug(float_gt,		"float_gt").
 binop_debug(float_le,		"float_le").
 binop_debug(float_ge,		"float_ge").
+binop_debug(body,		"body").
 
 :- pred unop_code(unary_op, int).
 :- mode unop_code(in, out) is det.
@@ -1057,12 +1059,11 @@
 unop_code(tag,			 1).
 unop_code(unmktag,		 2).
 unop_code(mkbody,		 3).
-unop_code(body,			 4).
-unop_code(unmkbody,		 5).
-unop_code(cast_to_unsigned,	 6).
-unop_code(hash_string,		 7).
-unop_code(bitwise_complement,	 8).
-unop_code((not),		 9).
+unop_code(unmkbody,		 4).
+unop_code(cast_to_unsigned,	 5).
+unop_code(hash_string,		 6).
+unop_code(bitwise_complement,	 7).
+unop_code((not),		 8).
 
 :- pred unop_debug(unary_op, string).
 :- mode unop_debug(in, out) is det.
@@ -1071,7 +1072,6 @@
 unop_debug(tag,			"tag").
 unop_debug(unmktag,		"unmktag").
 unop_debug(mkbody,		"mkbody").
-unop_debug(body,		"body").
 unop_debug(unmkbody,		"unmkbody").
 unop_debug(cast_to_unsigned,	"cast_to_unsigned").
 unop_debug(hash_string,		"has_string").
--- builtin_ops.m	2000/03/15 08:30:50	1.2
+++ builtin_ops.m	2000/10/06 09:56:15
@@ -25,7 +25,6 @@
 	;	tag
 	;	unmktag
 	;	mkbody
-	;	body
 	;	unmkbody
 	;	cast_to_unsigned
 	;	hash_string
@@ -49,6 +48,7 @@
 	;	(or)	% logical or
 	;	eq	% ==
 	;	ne	% !=
+	;	body
 	;	array_index
 	;	str_eq	% string comparisons
 	;	str_ne

*** Full Diff ***
Index: builtin_ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/builtin_ops.m,v
retrieving revision 1.2
diff -u -r1.2 builtin_ops.m
--- builtin_ops.m	2000/03/15 08:30:50	1.2
+++ builtin_ops.m	2000/10/06 09:56:15
@@ -25,7 +25,6 @@
 	;	tag
 	;	unmktag
 	;	mkbody
-	;	body
 	;	unmkbody
 	;	cast_to_unsigned
 	;	hash_string
@@ -49,6 +48,7 @@
 	;	(or)	% logical or
 	;	eq	% ==
 	;	ne	% !=
+	;	body
 	;	array_index
 	;	str_eq	% string comparisons
 	;	str_ne
Index: bytecode.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/bytecode.m,v
retrieving revision 1.40
diff -u -r1.40 bytecode.m
--- bytecode.m	2000/04/17 10:51:52	1.40
+++ bytecode.m	2000/10/06 09:56:16
@@ -1010,6 +1010,7 @@
 binop_code(float_gt,		32).
 binop_code(float_le,		33).
 binop_code(float_ge,		34).
+binop_code(body,		35).
 
 :- pred binop_debug(binary_op, string).
 :- mode binop_debug(in, out) is det.
@@ -1049,6 +1050,7 @@
 binop_debug(float_gt,		"float_gt").
 binop_debug(float_le,		"float_le").
 binop_debug(float_ge,		"float_ge").
+binop_debug(body,		"body").
 
 :- pred unop_code(unary_op, int).
 :- mode unop_code(in, out) is det.
@@ -1057,12 +1059,11 @@
 unop_code(tag,			 1).
 unop_code(unmktag,		 2).
 unop_code(mkbody,		 3).
-unop_code(body,			 4).
-unop_code(unmkbody,		 5).
-unop_code(cast_to_unsigned,	 6).
-unop_code(hash_string,		 7).
-unop_code(bitwise_complement,	 8).
-unop_code((not),		 9).
+unop_code(unmkbody,		 4).
+unop_code(cast_to_unsigned,	 5).
+unop_code(hash_string,		 6).
+unop_code(bitwise_complement,	 7).
+unop_code((not),		 8).
 
 :- pred unop_debug(unary_op, string).
 :- mode unop_debug(in, out) is det.
@@ -1071,7 +1072,6 @@
 unop_debug(tag,			"tag").
 unop_debug(unmktag,		"unmktag").
 unop_debug(mkbody,		"mkbody").
-unop_debug(body,		"body").
 unop_debug(unmkbody,		"unmkbody").
 unop_debug(cast_to_unsigned,	"cast_to_unsigned").
 unop_debug(hash_string,		"has_string").
Index: bytecode_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.50
diff -u -r1.50 bytecode_gen.m
--- bytecode_gen.m	2000/09/20 00:21:36	1.50
+++ bytecode_gen.m	2000/10/06 09:56:16
@@ -472,8 +472,8 @@
 				Pairs)])
 		)
 	).
-bytecode_gen__unify(deconstruct(Var, ConsId, Args, UniModes, _), _, _, ByteInfo,
-		Code) :-
+bytecode_gen__unify(deconstruct(Var, ConsId, Args, UniModes, _, _), _, _,
+		ByteInfo, Code) :-
 	bytecode_gen__map_var(ByteInfo, Var, ByteVar),
 	bytecode_gen__map_vars(ByteInfo, Args, ByteArgs),
 	bytecode_gen__map_cons_id(ByteInfo, Var, ConsId, ByteConsId),
Index: c_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/c_util.m,v
retrieving revision 1.4
diff -u -r1.4 c_util.m
--- c_util.m	2000/08/14 09:08:43	1.4
+++ c_util.m	2000/10/06 09:56:16
@@ -204,7 +204,6 @@
 c_util__unary_prefix_op(tag,			"MR_tag").
 c_util__unary_prefix_op(unmktag,		"MR_unmktag").
 c_util__unary_prefix_op(mkbody,			"MR_mkbody").
-c_util__unary_prefix_op(body,			"MR_body").
 c_util__unary_prefix_op(unmkbody,		"MR_unmkbody").
 c_util__unary_prefix_op(hash_string,		"MR_hash_string").
 c_util__unary_prefix_op(bitwise_complement,	"~").
Index: code_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_aux.m,v
retrieving revision 1.58
diff -u -r1.58 code_aux.m
--- code_aux.m	2000/08/09 07:46:18	1.58
+++ code_aux.m	2000/10/06 09:56:17
@@ -98,7 +98,7 @@
 	;
 		Uni = construct(_, _, _, _, _, _, _)
 	;
-		Uni = deconstruct(_, _, _, _, _)
+		Uni = deconstruct(_, _, _, _, _, _)
 	).
 		% Complicated unifies are _non_builtin_
 
@@ -178,7 +178,7 @@
 	;
 		Uni = construct(_, _, _, _, _, _, _)
 	;
-		Uni = deconstruct(_, _, _, _, _)
+		Uni = deconstruct(_, _, _, _, _, _)
 	).
 		% Complicated unifies are _non_builtin_
 	
Index: common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/common.m,v
retrieving revision 1.57
diff -u -r1.57 common.m
--- common.m	2000/08/07 07:23:51	1.57
+++ common.m	2000/10/06 09:56:17
@@ -162,7 +162,8 @@
 			common__record_cell(Var, ConsId, ArgVars, Info0, Info)
 		)
 	;
-		Unification0 = deconstruct(Var, ConsId, ArgVars, UniModes, _),
+		Unification0 = deconstruct(Var, ConsId,
+				ArgVars, UniModes, _, _),
 		simplify_info_get_module_info(Info0, ModuleInfo),
 		(
 				% Don't optimise partially instantiated
Index: cse_detection.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.63
diff -u -r1.63 cse_detection.m
--- cse_detection.m	2000/09/07 01:46:16	1.63
+++ cse_detection.m	2000/10/06 09:56:18
@@ -560,9 +560,10 @@
 		Typemap0, Typemap, Replacements) :-
 	(
 		GoalExpr0 = unify(_, Term, Umode, Unif0, Ucontext),
-		Unif0 = deconstruct(_, Consid, Args, Submodes, CanFail)
+		Unif0 = deconstruct(_, Consid, Args, Submodes, CanFail, CanCGC)
 	->
-		Unif = deconstruct(Var, Consid, Args, Submodes, CanFail),
+		Unif = deconstruct(Var, Consid, Args,
+				Submodes, CanFail, CanCGC),
 		( Term = functor(_, _) ->
 			GoalExpr1 = unify(Var, Term, Umode, Unif, Ucontext)
 		;
@@ -605,9 +606,9 @@
 find_similar_deconstruct(OldUnifyGoal, NewUnifyGoal, Context, Replacements) :-
 	(
 		OldUnifyGoal = unify(_OT1, _OT2, _OM, OldUnifyInfo, OC) - _,
-		OldUnifyInfo = deconstruct(_OV, OF, OFV, _OUM, _OCF),
+		OldUnifyInfo = deconstruct(_OV, OF, OFV, _OUM, _OCF, _OCGC),
 		NewUnifyGoal = unify(_NT1, _NT2, _NM, NewUnifyInfo, _NC) - _,
-		NewUnifyInfo = deconstruct(_NV, NF, NFV, _NUM, _NCF)
+		NewUnifyInfo = deconstruct(_NV, NF, NFV, _NUM, _NCF, _NCGC)
 	->
 		OF = NF,
 		list__length(OFV, OFVC),
Index: dependency_graph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.48
diff -u -r1.48 dependency_graph.m
--- dependency_graph.m	2000/08/09 07:46:23	1.48
+++ dependency_graph.m	2000/10/06 09:56:18
@@ -267,7 +267,7 @@
 	; Unify = construct(_, Cons, _, _, _, _, _),
 	    dependency_graph__add_arcs_in_cons(Cons, Caller,
 				DepGraph0, DepGraph)
-	; Unify = deconstruct(_, Cons, _, _, _),
+	; Unify = deconstruct(_, Cons, _, _, _, _),
 	    dependency_graph__add_arcs_in_cons(Cons, Caller,
 				DepGraph0, DepGraph)
 	; Unify = complicated_unify(_, _, _),
Index: det_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_analysis.m,v
retrieving revision 1.145
diff -u -r1.145 det_analysis.m
--- det_analysis.m	2000/08/09 07:46:24	1.145
+++ det_analysis.m	2000/10/06 09:56:19
@@ -900,7 +900,7 @@
 :- pred det_infer_unify_examines_rep(unification::in, bool::out) is det.
 det_infer_unify_examines_rep(assign(_, _), no).
 det_infer_unify_examines_rep(construct(_, _, _, _, _, _, _), no).
-det_infer_unify_examines_rep(deconstruct(_, _, _, _, _), yes).
+det_infer_unify_examines_rep(deconstruct(_, _, _, _, _, _), yes).
 det_infer_unify_examines_rep(simple_test(_, _), yes).
 det_infer_unify_examines_rep(complicated_unify(_, _, _), no).
 	% Some complicated modes of complicated unifications _do_
@@ -922,7 +922,7 @@
 :- pred det_infer_unify_canfail(unification, can_fail).
 :- mode det_infer_unify_canfail(in, out) is det.
 
-det_infer_unify_canfail(deconstruct(_, _, _, _, CanFail), CanFail).
+det_infer_unify_canfail(deconstruct(_, _, _, _, CanFail, _), CanFail).
 det_infer_unify_canfail(assign(_, _), cannot_fail).
 det_infer_unify_canfail(construct(_, _, _, _, _, _, _), cannot_fail).
 det_infer_unify_canfail(simple_test(_, _), can_fail).
Index: goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.64
diff -u -r1.64 goal_util.m
--- goal_util.m	2000/09/04 22:33:36	1.64
+++ goal_util.m	2000/10/06 09:56:19
@@ -447,8 +447,9 @@
 		How0 = construct_statically(_),
 		How = How0
 	).
-goal_util__rename_unify(deconstruct(Var0, ConsId, Vars0, Modes, Cat),
-		Must, Subn, deconstruct(Var, ConsId, Vars, Modes, Cat)) :-
+goal_util__rename_unify(deconstruct(Var0, ConsId, Vars0, Modes, Cat, CanCGC),
+		Must, Subn,
+		deconstruct(Var, ConsId, Vars, Modes, Cat, CanCGC)) :-
 	goal_util__rename_var(Var0, Must, Subn, Var),
 	goal_util__rename_var_list(Vars0, Must, Subn, Vars).
 goal_util__rename_unify(assign(L0, R0), Must, Subn, assign(L, R)) :-
@@ -984,7 +985,8 @@
 	list__map(InstToUniMode, ArgInsts, UniModes),
 	UniMode = (Inst0 -> Inst0) - (Inst0 -> Inst0),
 	UnifyContext = unify_context(explicit, []),
-	Unification = deconstruct(Var, ConsId, ArgVars, UniModes, can_fail),
+	Unification = deconstruct(Var, ConsId, ArgVars, UniModes,
+			can_fail, no),
 	ExtraGoal = unify(Var, functor(ConsId, ArgVars),
 		UniMode, Unification, UnifyContext),
 	set__singleton_set(NonLocals, Var),
Index: higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.74
diff -u -r1.74 higher_order.m
--- higher_order.m	2000/09/25 04:22:33	1.74
+++ higher_order.m	2000/10/06 09:56:20
@@ -647,7 +647,7 @@
 	maybe_add_alias(Var1, Var2).
 
 	% deconstructing a higher order term is not allowed
-check_unify(deconstruct(_, _, _, _, _)) --> [].
+check_unify(deconstruct(_, _, _, _, _, _)) --> [].
 
 check_unify(construct(LVar, ConsId, Args, _Modes, _, _, _), Info0, Info) :-
 	Info0 = info(PredVars0, Requests, NewPreds, PredProcId,
@@ -2056,7 +2056,7 @@
 	goal_info_init(NonLocals, InstMapDelta, det, GoalInfo),
 	Goal = unify(Arg, functor(ConsId, [UnwrappedArg]), In - Out,
 		deconstruct(Arg, ConsId, [UnwrappedArg], UniModes,
-			cannot_fail),
+			cannot_fail, no),
 		unify_context(explicit, [])) - GoalInfo.
 
 %-------------------------------------------------------------------------------
Index: hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.76
diff -u -r1.76 hlds_goal.m
--- hlds_goal.m	2000/09/07 01:46:21	1.76
+++ hlds_goal.m	2000/10/06 09:56:21
@@ -411,6 +411,12 @@
 	;	modes_are_ok
 	.
 
+	% `yes' iff the cell is available for compile time garbage collection.
+	% Compile time garbage collection is when the compiler
+	% recognises that a memory cell is no longer needed and can be
+	% safely deallocated (ie by inserting an explicit call to free).
+:- type can_cgc == bool.
+
 :- type unification
 		% A construction unification is a unification with a functor
 		% or lambda expression which binds the LHS variable,
@@ -477,8 +483,11 @@
 					% e.g. [X] in the above example.
 			list(uni_mode), % The lists of modes of the argument
 					% sub-unifications.
-			can_fail	% Whether or not the unification
+			can_fail,	% Whether or not the unification
 					% could possibly fail.
+			can_cgc		% Can compile time GC this cell,
+					% ie explicitly deallocate it
+					% after the deconstruction.
 		)
 
 		% Y = X where the top node of Y is output,
Index: hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.245
diff -u -r1.245 hlds_out.m
--- hlds_out.m	2000/09/25 04:22:34	1.245
+++ hlds_out.m	2000/10/06 09:56:22
@@ -1497,7 +1497,13 @@
 	hlds_out__write_unify_rhs_2(B, ModuleInfo, VarSet, InstVarSet,
 		AppendVarnums, Indent, Follow, VarType, TypeQual),
 	globals__io_lookup_string_option(dump_hlds_options, Verbose),
-	( { string__contains_char(Verbose, 'u') } ->
+	(
+		{
+			string__contains_char(Verbose, 'u') 
+		;
+			string__contains_char(Verbose, 'p')
+		}
+	->
 		(
 			% don't output bogus info if we haven't been through
 			% mode analysis yet
@@ -1763,8 +1769,12 @@
 		ModuleInfo, ProgVarSet, InstVarSet, AppendVarnums, Indent).
 
 hlds_out__write_unification(deconstruct(Var, ConsId, ArgVars, ArgModes,
-		CanFail), ModuleInfo, ProgVarSet, InstVarSet, AppendVarnums,
-		Indent) -->
+		CanFail, CanCGC),
+		ModuleInfo, ProgVarSet, InstVarSet, AppendVarnums, Indent) -->
+	hlds_out__write_indent(Indent),
+	io__write_string("% Compile time garbage collect: "),
+	io__write(CanCGC),
+	io__nl,
 	hlds_out__write_indent(Indent),
 	io__write_string("% "),
 	mercury_output_var(Var, ProgVarSet, AppendVarnums),
Index: llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.264
diff -u -r1.264 llds.m
--- llds.m	2000/10/04 05:23:06	1.264
+++ llds.m	2000/10/06 09:56:23
@@ -1141,7 +1141,6 @@
 llds__unop_return_type(unmktag, word).
 llds__unop_return_type(mkbody, word).
 llds__unop_return_type(unmkbody, word).
-llds__unop_return_type(body, word).
 llds__unop_return_type(cast_to_unsigned, unsigned).
 llds__unop_return_type(hash_string, integer).
 llds__unop_return_type(bitwise_complement, integer).
@@ -1152,7 +1151,6 @@
 llds__unop_arg_type(unmktag, word).
 llds__unop_arg_type(mkbody, word).
 llds__unop_arg_type(unmkbody, word).
-llds__unop_arg_type(body, word).
 llds__unop_arg_type(cast_to_unsigned, word).
 llds__unop_arg_type(hash_string, word).
 llds__unop_arg_type(bitwise_complement, integer).
@@ -1193,6 +1191,7 @@
 llds__binop_return_type(float_gt, bool).
 llds__binop_return_type(float_le, bool).
 llds__binop_return_type(float_ge, bool).
+llds__binop_return_type(body, word).
 
 llds__register_type(r, word).
 llds__register_type(f, float).
Index: mark_static_terms.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mark_static_terms.m,v
retrieving revision 1.2
diff -u -r1.2 mark_static_terms.m
--- mark_static_terms.m	2000/08/09 07:47:06	1.2
+++ mark_static_terms.m	2000/10/06 09:56:23
@@ -167,7 +167,7 @@
 		)
 	;
 		Unification0 = deconstruct(_Var, _ConsId, _ArgVars, _UniModes,
-			_CanFail),
+			_CanFail, _CanCGC),
 		Unification = Unification0,
 		StaticVars = StaticVars0
 /*****************
Index: ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.11
diff -u -r1.11 ml_elim_nested.m
--- ml_elim_nested.m	2000/08/02 14:13:04	1.11
+++ ml_elim_nested.m	2000/10/06 09:56:25
@@ -748,6 +748,8 @@
 fixup_atomic_stmt(assign(Lval0, Rval0), assign(Lval, Rval)) -->
 	fixup_lval(Lval0, Lval),
 	fixup_rval(Rval0, Rval).
+fixup_atomic_stmt(delete_object(Lval0), delete_object(Lval)) -->
+	fixup_lval(Lval0, Lval).
 fixup_atomic_stmt(new_object(Target0, MaybeTag, Type, MaybeSize, MaybeCtorName,
 			Args0, ArgTypes),
 		new_object(Target, MaybeTag, Type, MaybeSize, MaybeCtorName,
Index: ml_unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.17
diff -u -r1.17 ml_unify_gen.m
--- ml_unify_gen.m	2000/09/18 11:51:31	1.17
+++ ml_unify_gen.m	2000/10/06 09:56:26
@@ -132,28 +132,40 @@
 	;
 		true
 	},
-	{ HowToConstruct = reuse_cell(_) ->
-		sorry("cell reuse")
-	;
-		true
-	},
 	ml_gen_construct(Var, ConsId, Args, ArgModes, HowToConstruct, Context,
 		MLDS_Decls, MLDS_Statements).
-ml_gen_unification(deconstruct(Var, ConsId, Args, ArgModes, CanFail),
+
+ml_gen_unification(deconstruct(Var, ConsId, Args, ArgModes, CanFail, CanCGC),
 		CodeModel, Context, MLDS_Decls, MLDS_Statements) -->
 	(
 		{ CanFail = can_fail },
 		{ require(unify(CodeModel, model_semi),
 			"ml_code_gen: can_fail deconstruct not semidet") },
 		ml_gen_semi_deconstruct(Var, ConsId, Args, ArgModes, Context,
-			MLDS_Decls, MLDS_Statements)
+			MLDS_Decls, MLDS_Unif_Statements)
 	;
 		{ CanFail = cannot_fail },
 		{ require(unify(CodeModel, model_det),
 			"ml_code_gen: cannot_fail deconstruct not det") },
 		ml_gen_det_deconstruct(Var, ConsId, Args, ArgModes, Context,
-			MLDS_Decls, MLDS_Statements)
-	).
+			MLDS_Decls, MLDS_Unif_Statements)
+	),
+	(
+			% Note that we can deallocate a cell even if the 
+			% unification fails, it is the responsibility of
+			% the structure reuse phase to ensure that this
+			% is safe.
+		{ CanCGC = yes },
+		ml_gen_var(Var, VarLval),
+		{ MLDS_Stmt = atomic(delete_object(VarLval)) },
+		{ MLDS_CGC_Statements = [mlds__statement(MLDS_Stmt,
+				mlds__make_context(Context)) ] }
+	;
+		{ CanCGC = no },
+		{ MLDS_CGC_Statements = [] }
+	),
+	{ MLDS_Statements = MLDS_Unif_Statements `list__append`
+			MLDS_CGC_Statements }.
 
 ml_gen_unification(complicated_unify(_, _, _), _, _, [], []) -->
 	% simplify.m should convert these into procedure calls
@@ -453,7 +465,7 @@
 	% generate a `new_object' statement (or static constant)
 	% for the closure
 	%
-	ml_gen_new_object(Tag, CtorName, Var, ExtraArgRvals, ExtraArgTypes,
+	ml_gen_new_object(no, Tag, CtorName, Var, ExtraArgRvals, ExtraArgTypes,
 			ArgVars, ArgModes, HowToConstruct, Context,
 			MLDS_Decls, MLDS_Statements).
 
@@ -861,9 +873,9 @@
 		ExtraRvals = [],
 		ExtraArgTypes = []
 	},
-	ml_gen_new_object(Tag, CtorName, Var, ExtraRvals, ExtraArgTypes,
-			ArgVars, ArgModes, HowToConstruct, Context,
-			MLDS_Decls, MLDS_Statements).
+	ml_gen_new_object(yes(ConsId), Tag, CtorName, Var,
+			ExtraRvals, ExtraArgTypes, ArgVars, ArgModes,
+			HowToConstruct, Context, MLDS_Decls, MLDS_Statements).
 
 	%
 	% ml_gen_new_object:
@@ -873,14 +885,15 @@
 	%	additional constants to insert at the start of the
 	%	argument list.
 	%
-:- pred ml_gen_new_object(mlds__tag, ctor_name, prog_var, list(mlds__rval),
-		list(mlds__type), prog_vars, list(uni_mode), how_to_construct,
+:- pred ml_gen_new_object(maybe(cons_id), mlds__tag, ctor_name, prog_var,
+		list(mlds__rval), list(mlds__type), prog_vars,
+		list(uni_mode), how_to_construct,
 		prog_context, mlds__defns, mlds__statements,
 		ml_gen_info, ml_gen_info).
-:- mode ml_gen_new_object(in, in, in, in, in, in, in, in, in, out, out, in, out)
-		is det.
+:- mode ml_gen_new_object(in, in, in, in, in, in, in, in, in, in, out, out,
+		in, out) is det.
 
-ml_gen_new_object(Tag, CtorName, Var, ExtraRvals, ExtraTypes,
+ml_gen_new_object(MaybeConsId, Tag, CtorName, Var, ExtraRvals, ExtraTypes,
 		ArgVars, ArgModes, HowToConstruct, Context,
 		MLDS_Decls, MLDS_Statements) -->
 	%
@@ -984,10 +997,54 @@
 		{ MLDS_Decls = list__append(BoxConstDefns, [ConstDefn]) },
 		{ MLDS_Statements = [AssignStatement] }
 	;
-		{ HowToConstruct = reuse_cell(_) },
-		{ sorry("cell reuse") }
+		{ HowToConstruct = reuse_cell(CellToReuse) },
+		{ CellToReuse = cell_to_reuse(ReuseVar, ReuseConsId, _) },
+
+		{ MaybeConsId = yes(ConsId0) ->
+			ConsId = ConsId0
+		;
+			error("ml_gen_new_object: unknown cons id")
+		},
+
+		ml_variable_type(ReuseVar, ReuseType),
+		ml_cons_id_to_tag(ReuseConsId, ReuseType, ReuseConsIdTag),
+		{ ml_tag_offset_and_argnum(ReuseConsIdTag,
+				ReusePrimaryTag, _ReuseOffSet, _ReuseArgNum) },
+
+		ml_cons_id_to_tag(ConsId, Type, ConsIdTag),
+		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
+		{ ml_tag_offset_and_argnum(ConsIdTag,
+				PrimaryTag, OffSet, ArgNum) },
+
+		ml_gen_var(Var, Var1Lval),
+		ml_gen_var(ReuseVar, Var2Lval),
+		{ ReusePrimaryTag = PrimaryTag ->
+			Var2Rval = lval(Var2Lval)
+		;
+			Var2Rval = mkword(PrimaryTag,
+					binop(body, lval(Var2Lval),
+					ml_gen_mktag(ReusePrimaryTag)))
+		},
+
+		{ MLDS_Statement = ml_gen_assign(Var1Lval, Var2Rval, Context) },
+
+		%
+		% For each field in the construction unification we need
+		% to generate an rval.
+		% XXX we do more work then we need to here, as some of
+		% the cells may already contain the correct values.
+		%
+		ml_gen_unify_args(ConsId, ArgVars, ArgModes, ArgTypes,
+				Fields, Type, VarLval, OffSet,
+				ArgNum, PrimaryTag, Context, MLDS_Statements0),
+
+		{ MLDS_Decls = [] },
+		{ MLDS_Statements = [MLDS_Statement | MLDS_Statements0] }
 	).
 
+:- func ml_gen_mktag(int) = mlds__rval.
+ml_gen_mktag(Tag) = unop(std_unop(mktag), const(int_const(Tag))).
+
 :- pred ml_gen_box_const_rval_list(list(mlds__type), list(mlds__rval),
 		prog_context, mlds__defns, list(mlds__rval),
 		ml_gen_info, ml_gen_info).
@@ -1230,19 +1287,75 @@
 		ml_gen_var(Var, VarLval),
 		ml_variable_types(Args, ArgTypes),
 		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
+		{ ml_tag_offset_and_argnum(Tag, _, OffSet, ArgNum) },
 		ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, Type,
-			VarLval, 0, 1, UnsharedTag, Context, MLDS_Statements)
+				VarLval, OffSet, ArgNum,
+				UnsharedTag, Context, MLDS_Statements)
 	;
 		{ Tag = shared_remote_tag(PrimaryTag, _SecondaryTag) },
 		ml_gen_var(Var, VarLval),
 		ml_variable_types(Args, ArgTypes),
 		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
+		{ ml_tag_offset_and_argnum(Tag, _, OffSet, ArgNum) },
 		ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, Type,
-			VarLval, 1, 1, PrimaryTag, Context, MLDS_Statements)
+				VarLval, OffSet, ArgNum,
+				PrimaryTag, Context, MLDS_Statements)
 	;
 		{ Tag = shared_local_tag(_Bits1, _Num1) },
 		{ MLDS_Statements = [] } % if this is det, then nothing happens
 	).
+
+	% Calculate the integer offset used to reference the first field
+	% of a structure for lowlevel data or the first argument number
+	% to access the field using the highlevel data representation.
+	% Abort if the tag indicates that the data doesn't have any
+	% fields.
+:- pred ml_tag_offset_and_argnum(cons_tag::in, tag_bits::out,
+		int::out, int::out) is det.
+
+ml_tag_offset_and_argnum(Tag, TagBits, OffSet, ArgNum) :-
+	(
+		Tag = unshared_tag(UnsharedTag),
+		TagBits = UnsharedTag,
+		OffSet = 0,
+		ArgNum = 1
+	;
+		Tag = shared_remote_tag(PrimaryTag, _SecondaryTag),
+		TagBits = PrimaryTag,
+		OffSet = 1,
+		ArgNum = 1
+	;
+		Tag = string_constant(_String),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = int_constant(_Int),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = float_constant(_Float),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = pred_closure_tag(_, _, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = code_addr_constant(_, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = type_ctor_info_constant(_, _, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = base_typeclass_info_constant(_, _, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = tabling_pointer_constant(_, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = no_tag,
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = shared_local_tag(_Bits1, _Num1),
+		error("ml_tag_offset_and_argnum")
+	).
+
 
 	% Given a type and a cons_id, and also the types of the actual
 	% arguments of that cons_id in some particular use of it,
Index: mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.34
diff -u -r1.34 mlds.m
--- mlds.m	2000/09/06 05:20:58	1.34
+++ mlds.m	2000/10/06 09:56:27
@@ -830,6 +830,10 @@
 	% heap management
 	%
 
+	;	delete_object(mlds__lval)
+			% Compile time garbage collect (ie explicitly
+			% deallocate) the memory used by the lval.
+
 		% XXX the following is still quite tentative
 			% new_object(Target, Tag, Type,
 			%	Size, CtorName, Args, ArgTypes):
Index: mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.57
diff -u -r1.57 mlds_to_c.m
--- mlds_to_c.m	2000/09/18 11:51:31	1.57
+++ mlds_to_c.m	2000/10/06 09:56:28
@@ -2189,6 +2189,9 @@
 	%
 	% heap management
 	%
+mlds_output_atomic_stmt(_Indent, _FuncInfo, delete_object(_Lval), _) -->
+	{ error("mlds_to_c.m: sorry, delete_object not implemented") }.
+
 mlds_output_atomic_stmt(Indent, FuncInfo, NewObject, Context) -->
 	{ NewObject = new_object(Target, MaybeTag, Type, MaybeSize,
 		MaybeCtorName, Args, ArgTypes) },
Index: mode_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_util.m,v
retrieving revision 1.130
diff -u -r1.130 mode_util.m
--- mode_util.m	2000/09/20 12:12:03	1.130
+++ mode_util.m	2000/10/06 09:56:29
@@ -1426,7 +1426,7 @@
 	% that can require updating of the instmap_delta after simplify.m
 	% has been run.
 	(
-		Uni = deconstruct(Var, _ConsId, Vars, UniModes, _)
+		Uni = deconstruct(Var, _ConsId, Vars, UniModes, _, _CanCGC)
 	->
 		% Get the final inst of the deconstructed var, which
 		% will be the same as in the old instmap.
Index: modecheck_unify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.42
diff -u -r1.42 modecheck_unify.m
--- modecheck_unify.m	2000/05/22 18:00:22	1.42
+++ modecheck_unify.m	2000/10/06 09:56:29
@@ -133,7 +133,8 @@
 		% fields created by polymorphism.m
 		Unification0 \= construct(_, code_addr_const(_, _),
 			_, _, _, _, _),
-		Unification0 \= deconstruct(_, code_addr_const(_, _), _, _, _)
+		Unification0 \= deconstruct(_,
+				code_addr_const(_, _), _, _, _, _)
 	->
 		%
 		% convert the pred term to a lambda expression
@@ -623,7 +624,7 @@
 				Unification, ArgVars, ExtraGoals) -->
 	(
 		{ Unification0 = deconstruct(X, ConsId, ArgVars0, ArgModes0,
-			Det) }
+			Det, CanCGC) }
 	->
 		(
 			split_complicated_subunifies_2(ArgVars0, ArgModes0,
@@ -632,7 +633,7 @@
 			{ ExtraGoals = ExtraGoals1 },
 			{ ArgVars = ArgVars1 },
 			{ Unification = deconstruct(X, ConsId, ArgVars,
-							ArgModes0, Det) }
+					ArgModes0, Det, CanCGC) }
 		;
 			{ error("split_complicated_subunifies_2 failed") }
 		)
@@ -985,7 +986,7 @@
 	( Unification0 = construct(_, ConsId0, _, _, _, _, AditiInfo0) ->
 		AditiInfo = AditiInfo0,
 		ConsId = ConsId0
-	; Unification0 = deconstruct(_, ConsId1, _, _, _) ->
+	; Unification0 = deconstruct(_, ConsId1, _, _, _, _) ->
 		AditiInfo = no,
 		ConsId = ConsId1
 	;
@@ -1082,7 +1083,7 @@
 	% if we are re-doing mode analysis, preserve the existing cons_id
 	( Unification0 = construct(_, ConsId0, _, _, _, _, _) ->
 		ConsId = ConsId0
-	; Unification0 = deconstruct(_, ConsId1, _, _, _) ->
+	; Unification0 = deconstruct(_, ConsId1, _, _, _, _) ->
 		ConsId = ConsId1
 	;
 		ConsId = NewConsId
@@ -1148,7 +1149,8 @@
 				ModeInfo = ModeInfo0
 			)
 		),
-		Unification = deconstruct(X, ConsId, ArgVars, ArgModes, CanFail)
+		Unification = deconstruct(X, ConsId, ArgVars,
+				ArgModes, CanFail, no)
 	).
 
 	% Check that any type_info or type_class_info variables
Index: opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.105
diff -u -r1.105 opt_debug.m
--- opt_debug.m	2000/08/11 08:19:14	1.105
+++ opt_debug.m	2000/10/06 09:56:33
@@ -803,7 +803,6 @@
 opt_debug__dump_unop(tag, "tag").
 opt_debug__dump_unop(unmktag, "unmktag").
 opt_debug__dump_unop(mkbody, "mkbody").
-opt_debug__dump_unop(body, "body").
 opt_debug__dump_unop(unmkbody, "unmkbody").
 opt_debug__dump_unop(not, "not").
 opt_debug__dump_unop(hash_string, "hash_string").
Index: pd_cost.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/pd_cost.m,v
retrieving revision 1.8
diff -u -r1.8 pd_cost.m
--- pd_cost.m	2000/08/09 07:47:34	1.8
+++ pd_cost.m	2000/10/06 09:56:33
@@ -128,7 +128,7 @@
 		Cost = 0
 	).
 
-pd_cost__unify(NonLocals, deconstruct(_, _, Args, _, CanFail), Cost) :-
+pd_cost__unify(NonLocals, deconstruct(_, _, Args, _, CanFail, _), Cost) :-
 	( CanFail = can_fail ->
 		pd_cost__simple_test(Cost0)
 	;
Index: pd_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/pd_util.m,v
retrieving revision 1.11
diff -u -r1.11 pd_util.m
--- pd_util.m	2000/09/07 01:46:44	1.11
+++ pd_util.m	2000/10/06 09:56:34
@@ -934,9 +934,9 @@
 				NewArgs = [NewVar | NewArgs1]
 			;
 				OldUnification = deconstruct(OldVar, ConsId,
-							OldArgs1, _, _),
+							OldArgs1, _, _, _),
 				NewUnification = deconstruct(NewVar, ConsId,
-							NewArgs1, _, _),
+							NewArgs1, _, _, _),
 				OldArgs = [OldVar | OldArgs1],
 				NewArgs = [NewVar | NewArgs1]
 			)	
Index: prog_rep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.1
diff -u -r1.1 prog_rep.m
--- prog_rep.m	2000/09/25 04:37:12	1.1
+++ prog_rep.m	2000/10/06 09:56:34
@@ -108,7 +108,7 @@
 		list__map(term__var_to_int, Args, ArgsRep),
 		AtomicGoalRep = unify_construct_rep(VarRep, ConsIdRep, ArgsRep)
 	;
-		Uni = deconstruct(Var, ConsId, Args, _, _),
+		Uni = deconstruct(Var, ConsId, Args, _, _, _),
 		term__var_to_int(Var, VarRep),
 		prog_rep__represent_cons_id(ConsId, ConsIdRep),
 		list__map(term__var_to_int, Args, ArgsRep),
Index: rl_exprn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_exprn.m,v
retrieving revision 1.16
diff -u -r1.16 rl_exprn.m
--- rl_exprn.m	2000/08/09 07:47:46	1.16
+++ rl_exprn.m	2000/10/06 09:56:35
@@ -1150,7 +1150,7 @@
 		{ error("rl_exprn__unify: unsupported cons_id - tabling_pointer_const") }
 	).
 		
-rl_exprn__unify(deconstruct(Var, ConsId, Args, UniModes, CanFail),
+rl_exprn__unify(deconstruct(Var, ConsId, Args, UniModes, CanFail, _CanCGC),
 		GoalInfo, Fail, Code) -->
 	rl_exprn_info_lookup_var(Var, VarLoc),
 	rl_exprn_info_lookup_var_type(Var, Type),
Index: rl_key.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_key.m,v
retrieving revision 1.7
diff -u -r1.7 rl_key.m
--- rl_key.m	2000/09/18 11:51:43	1.7
+++ rl_key.m	2000/10/06 09:56:36
@@ -793,7 +793,7 @@
 rl_key__extract_key_range_unify(construct(Var, ConsId, Args, _, _, _, _)) -->
 	rl_key__unify_functor(Var, ConsId, Args).
 rl_key__extract_key_range_unify(
-		deconstruct(Var, ConsId, Args, _, _)) -->
+		deconstruct(Var, ConsId, Args, _, _, _)) -->
 	rl_key__unify_functor(Var, ConsId, Args).
 rl_key__extract_key_range_unify(complicated_unify(_, _, _)) -->
 	{ error("rl_key__extract_key_range_unify") }.
Index: simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.86
diff -u -r1.86 simplify.m
--- simplify.m	2000/09/18 08:57:26	1.86
+++ simplify.m	2000/10/06 09:56:40
@@ -1730,7 +1730,7 @@
 	UniMode = (Inst0 -> Inst0) - (Inst0 -> Inst0),
 	UnifyContext = unify_context(explicit, []),
 	Unification = deconstruct(Var, ConsId,
-		ArgVars, UniModes, can_fail),
+		ArgVars, UniModes, can_fail, no),
 	ExtraGoal = unify(Var, functor(ConsId, ArgVars),
 		UniMode, Unification, UnifyContext),
 	set__singleton_set(NonLocals, Var),
Index: switch_detection.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/switch_detection.m,v
retrieving revision 1.90
diff -u -r1.90 switch_detection.m
--- switch_detection.m	2000/08/09 07:47:53	1.90
+++ switch_detection.m	2000/10/06 09:56:40
@@ -436,14 +436,14 @@
 		_Result0, Result, _, unit) :-
 	(
 		Goal0 = unify(A, B, C, UnifyInfo0, E) - GoalInfo,
-		UnifyInfo0 = deconstruct(A, Functor, F, G, _)
+		UnifyInfo0 = deconstruct(A, Functor, F, G, _, I)
 	->
 		Result = yes(Functor),
 			% The deconstruction unification now becomes
 			% deterministic, since the test will get
 			% carried out in the switch.
 		UnifyInfo = deconstruct(A, Functor, F, G,
-			cannot_fail),
+			cannot_fail, I),
 		Goals = [unify(A, B, C, UnifyInfo, E) - GoalInfo]
 	;
 		error("find_bind_var_for_switch_in_deconstruct")
@@ -479,7 +479,7 @@
 		(
 			% check whether the unification is a deconstruction
 			% unification on Var or a variable aliased to Var
-			UnifyInfo0 = deconstruct(UnifyVar, _, _, _, _),
+			UnifyInfo0 = deconstruct(UnifyVar, _, _, _, _, _),
 			term__apply_rec_substitution(
 				term__variable(Var),
 				Substitution0, term__variable(Var1)),
Index: term_traversal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/term_traversal.m,v
retrieving revision 1.13
diff -u -r1.13 term_traversal.m
--- term_traversal.m	2000/08/09 07:47:56	1.13
+++ term_traversal.m	2000/10/06 09:56:44
@@ -130,7 +130,7 @@
 			Info = Info0
 		)
 	;
-		Unification = deconstruct(InVar, ConsId, Args, Modes, _),
+		Unification = deconstruct(InVar, ConsId, Args, Modes, _, _),
 		(
 			unify_change(InVar, ConsId, Args, Modes, Params,
 				Gamma0, InVars0, OutVars)
Index: unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.110
diff -u -r1.110 unify_gen.m
--- unify_gen.m	2000/09/25 04:24:16	1.110
+++ unify_gen.m	2000/10/06 09:56:44
@@ -70,7 +70,8 @@
 			{ Code = empty }
 		)
 	;
-		{ Uni = deconstruct(Var, ConsId, Args, Modes, _CanFail) },
+		{ Uni = deconstruct(Var, ConsId, Args, Modes,
+				_CanFail, _CanCGC) },
 		( { CodeModel = model_det } ->
 			unify_gen__generate_det_deconstruction(Var, ConsId,
 				Args, Modes, Code)
Index: unused_args.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.67
diff -u -r1.67 unused_args.m
--- unused_args.m	2000/09/07 01:47:00	1.67
+++ unused_args.m	2000/10/06 09:56:45
@@ -455,7 +455,8 @@
 	).
 
 traverse_goal(ModuleInfo,
-		unify(Var1, _, _, deconstruct(_, _, Args, Modes, CanFail), _),
+		unify(Var1, _, _,
+			deconstruct(_, _, Args, Modes, CanFail, _), _),
 		UseInf0, UseInf) :-
 	partition_deconstruct_args(ModuleInfo, Args,
 		Modes, InputVars, OutputVars),
@@ -1353,7 +1354,7 @@
 	\+ list__member(LVar, UnusedVars).
 	
 fixup_unify(ModuleInfo, UnusedVars, Changed, Unify, Unify) :-
-	Unify =	deconstruct(LVar, _, ArgVars, ArgModes, CanFail),
+	Unify =	deconstruct(LVar, _, ArgVars, ArgModes, CanFail, _CanCGC),
 	\+ list__member(LVar, UnusedVars),
 	(
 			% are any of the args unused, if so we need to 	
Index: vn_cost.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_cost.m,v
retrieving revision 1.42
diff -u -r1.42 vn_cost.m
--- vn_cost.m	2000/04/26 05:40:43	1.42
+++ vn_cost.m	2000/10/06 09:56:45
@@ -370,7 +370,6 @@
 vn_cost__assign_cost_unop(tag).
 vn_cost__assign_cost_unop(unmktag).
 vn_cost__assign_cost_unop(mkbody).
-vn_cost__assign_cost_unop(body).
 vn_cost__assign_cost_unop(unmkbody).
 vn_cost__assign_cost_unop(bitwise_complement).
 
@@ -391,6 +390,7 @@
 vn_cost__assign_cost_binop('|').
 vn_cost__assign_cost_binop(and).
 vn_cost__assign_cost_binop(or).
+vn_cost__assign_cost_binop(body).
 
 % These unary operations cost zero instructions.
 


--------------------------------------------------------------------------
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