[m-dev.] for review: add structure reuse information to LLDS

Simon Taylor stayl at cs.mu.OZ.AU
Thu Jan 13 11:19:06 AEDT 2000


Hi,

Zoltan, could you please review this.
It's pretty trivial.

Simon.


Estimated hours taken: 2

Add information required for structure reuse and compile time garbage
collection to the LLDS. The code generator does not yet generate
this information. 

This will be committed to the main branch to avoid CVS conflicts.

compiler/llds.m:
	Add an LLDS instruction `free_heap(rval)', which applies the
	MR_free_heap macro to its argument.

	Add a `maybe(rval)' field to `create' rvals to hold the address
	of a cell to reuse. This field should always be `no' after
	code generation, because all non-constant creates are converted
	into lower-level operations during code generation.

compiler/value_number.m:
	Don't reorder instructions around a `free_heap' instruction
	to avoid generating code which looks at deallocated memory.

compiler/*.m:
	Handle the new instruction and field.



Index: compiler/base_type_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_type_layout.m,v
retrieving revision 1.50
diff -u -u -r1.50 base_type_layout.m
--- base_type_layout.m	1999/12/13 05:22:57	1.50
+++ base_type_layout.m	2000/01/12 02:25:10
@@ -563,12 +563,14 @@
 	(
 		MaxTags < 4
 	->
+		Reuse = no,
 		Rvals = [yes(const(int_const(Tag))), 
 			yes(create(0, Rvals0, uniform(no), StatDyn,
-				CellNumber, "type_layout"))]
+				CellNumber, "type_layout", Reuse))]
 	;
+		Reuse = no,
 		Rvals = [yes(create(Tag, Rvals0, uniform(no), StatDyn,
-			CellNumber, "type_layout"))]
+			CellNumber, "type_layout", Reuse))]
 	).
 
 	% Encode a cons tag (unshared or shared) in rvals.
@@ -1178,8 +1180,9 @@
 		LayoutInfo),
 	base_type_layout__functors_value(enum, EnumIndicator),
 	EnumRval = yes(const(int_const(EnumIndicator))),
+	Reuse = no,
 	CreateRval = yes(create(0, VectorRvals, uniform(no), must_be_static,
-		NextCellNumber, "type_layout")),
+		NextCellNumber, "type_layout", Reuse)),
 	Rvals = [EnumRval, CreateRval].
 
 	% type_ctor_functors of a no_tag:
@@ -1198,8 +1201,9 @@
 
 	base_type_layout__get_next_cell_number(NextCellNumber, LayoutInfo1,
 		LayoutInfo),
+	Reuse = no,
 	CreateRval = yes(create(0, VectorRvals, uniform(no), must_be_static,
-		NextCellNumber, "type_layout")),
+		NextCellNumber, "type_layout", Reuse)),
 
 	base_type_layout__functors_value(no_tag, NoTagIndicator),
 	NoTagRval = yes(const(int_const(NoTagIndicator))),
@@ -1227,9 +1231,10 @@
 				LayoutInfoA, LayoutInfoB, VectorRvalList),
 			base_type_layout__get_next_cell_number(NextCellNumber,
 				LayoutInfoB, LayoutInfoC),
+			Reuse = no,
 			VectorRval = yes(create(0, VectorRvalList, uniform(no),
 				must_be_static, NextCellNumber,
-				"type_layout")),
+				"type_layout", Reuse)),
 			Rvals1 = [VectorRval | Rvals0],
 			NewAcc = Rvals1 - LayoutInfoC)),
 		ConsList, [] - LayoutInfo0, VectorRvals - LayoutInfo),
@@ -1334,8 +1339,9 @@
 
 		list__append(RealArityArg, PseudoArgs1, PseudoArgs),
 
+		Reuse = no,
 		Pseudo = create(0, [Pseudo0 | PseudoArgs], uniform(no),
-			must_be_static, CNum1, "type_layout")
+			must_be_static, CNum1, "type_layout", Reuse)
 	;
 		type_util__var(Type, Var)
 	->
@@ -1384,7 +1390,7 @@
 
 base_type_layout__remove_create(Rval0, Rval) :-
 	(
-		Rval0 = create(_, [PTI], _, _, _, _)
+		Rval0 = create(_, [PTI], _, _, _, _, _)
 	->
 		Rval = PTI
 	;
Index: compiler/code_exprn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_exprn.m,v
retrieving revision 1.60
diff -u -u -r1.60 code_exprn.m
--- code_exprn.m	1999/04/30 06:19:13	1.60
+++ code_exprn.m	2000/01/12 05:03:38
@@ -414,8 +414,8 @@
 		code_exprn__filter_out_reg_depending(Rvals0, Vars, Rvals),
 		set__empty(Rvals)
 	).
-code_exprn__rval_depends_on_reg(create(_, Rvals, _, _, _, _), Vars) :-
-	code_exprn__args_depend_on_reg(Rvals, Vars).
+code_exprn__rval_depends_on_reg(create(_, Rvals, _, _, _, _, Reuse), Vars) :-
+	code_exprn__args_depend_on_reg([Reuse | Rvals], Vars).
 code_exprn__rval_depends_on_reg(mkword(_Tag, Rval), Vars) :-
 	code_exprn__rval_depends_on_reg(Rval, Vars).
 code_exprn__rval_depends_on_reg(const(_Const), _Vars) :-
@@ -616,8 +616,8 @@
 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_arg_reg_dependencies(Rvals).
+code_exprn__add_rval_reg_dependencies(create(_, Rvals, _, _, _, _, Reuse)) -->
+	code_exprn__add_arg_reg_dependencies([Reuse | Rvals]).
 code_exprn__add_rval_reg_dependencies(mkword(_Tag, Rval)) -->
 	code_exprn__add_rval_reg_dependencies(Rval).
 code_exprn__add_rval_reg_dependencies(const(_Const)) --> [].
@@ -689,8 +689,8 @@
 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_arg_reg_dependencies(Rvals).
+code_exprn__rem_rval_reg_dependencies(create(_, Rvals, _, _, _, _, Reuse)) -->
+	code_exprn__rem_arg_reg_dependencies([Reuse | Rvals]).
 code_exprn__rem_rval_reg_dependencies(mkword(_Tag, Rval)) -->
 	code_exprn__rem_rval_reg_dependencies(Rval).
 code_exprn__rem_rval_reg_dependencies(const(_Const)) --> [].
@@ -917,15 +917,19 @@
 		mkword(Tag, Expr)) :-
 	code_exprn__expr_is_constant(Expr0, Vars, ExprnOpts, Expr).
 
-code_exprn__expr_is_constant(create(Tag, Args0, ArgTypes, StatDyn, Label, Msg),
+code_exprn__expr_is_constant(create(Tag, Args0, ArgTypes, StatDyn,
+		Label, Msg, Reuse),
 		Vars, ExprnOpts, NewRval) :-
+	Reuse = no,
 	( StatDyn = must_be_static ->
-		NewRval = create(Tag, Args0, ArgTypes, StatDyn, Label, Msg)
+		NewRval = create(Tag, Args0, ArgTypes, StatDyn,
+			Label, Msg, Reuse)
 	;
 		ExprnOpts = nlg_asm_sgt_ubf(_, _, StaticGroundTerms, _),
 		StaticGroundTerms = yes,
 		code_exprn__args_are_constant(Args0, Vars, ExprnOpts, Args),
-		NewRval = create(Tag, Args, ArgTypes, StatDyn, Label, Msg)
+		NewRval = create(Tag, Args, ArgTypes, StatDyn,
+			Label, Msg, Reuse)
 	).
 
 code_exprn__expr_is_constant(var(Var), Vars, ExprnOpts, Rval) :-
@@ -1254,7 +1258,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, _) }
@@ -1280,8 +1284,12 @@
 code_exprn__construct_code(Lval, VarName, Rval0, Code) -->
 	{ exprn_aux__simplify_rval(Rval0, Rval) },
 	(
-		{ Rval = create(Tag, Rvals, ArgTypes, _StatDyn, _Label, Msg) }
+		{ Rval = create(Tag, Rvals, ArgTypes, _StatDyn, _Label,
+			Msg, Reuse) }
 	->
+		{ require(unify(Reuse, no),
+	"code_exprn__construct_code: structure reuse not yet implemented") },
+
 		{ require(lambda([] is semidet,
 			(llds__all_args_are_word_size(ArgTypes, yes))),
 		"trying to construct heap cell with non-word-size arg(s)") },
@@ -1389,7 +1397,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.114
diff -u -u -r1.114 code_util.m
--- code_util.m	1999/10/26 23:22:17	1.114
+++ code_util.m	2000/01/12 04:04:47
@@ -942,7 +942,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.44
diff -u -u -r1.44 dupelim.m
--- dupelim.m	1999/11/15 00:42:21	1.44
+++ dupelim.m	2000/01/12 02:31:28
@@ -327,6 +327,10 @@
 		standardize_rval(Rval1, Rval),
 		Instr = restore_hp(Rval)
 	;
+		Instr1 = free_heap(Rval1),
+		standardize_rval(Rval1, Rval),
+		Instr = free_heap(Rval)
+	;
 		Instr1 = store_ticket(Lval1),
 		standardize_lval(Lval1, Lval),
 		Instr = store_ticket(Lval)
@@ -442,7 +446,7 @@
 		Rval1 = var(_),
 		error("var in standardize_rval")
 	;
-		Rval1 = create(_, _, _, _, _, _),
+		Rval1 = create(_, _, _, _, _, _, _),
 		Rval = Rval1
 	;
 		Rval1 = mkword(_, _),
@@ -604,6 +608,11 @@
 		most_specific_rval(Rval1, Rval2, Rval),
 		Instr = restore_hp(Rval)
 	;
+		Instr1 = free_heap(Rval1),
+		Instr2 = free_heap(Rval2),
+		most_specific_rval(Rval1, Rval2, Rval),
+		Instr = free_heap(Rval)
+	;
 		Instr1 = store_ticket(Lval1),
 		Instr2 = store_ticket(Lval2),
 		most_specific_lval(Lval1, Lval2, Lval),
@@ -736,7 +745,7 @@
 		Rval1 = var(_),
 		error("var in most_specific_rval")
 	;
-		Rval1 = create(_, _, _, _, _, _),
+		Rval1 = create(_, _, _, _, _, _, _),
 		Rval2 = Rval1,
 		Rval = Rval1
 	;
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.37
diff -u -u -r1.37 exprn_aux.m
--- exprn_aux.m	1999/08/24 08:51:57	1.37
+++ exprn_aux.m	2000/01/12 04:11:29
@@ -198,8 +198,8 @@
 
 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__args_contain_lval(Rvals, Lval).
+exprn_aux__rval_contains_lval(create(_, Rvals, _, _, _, _, Reuse), Lval) :-
+	exprn_aux__args_contain_lval([Reuse | Rvals], Lval).
 exprn_aux__rval_contains_lval(mkword(_, Rval), Lval) :-
 	exprn_aux__rval_contains_lval(Rval, Lval).
 exprn_aux__rval_contains_lval(unop(_, Rval), Lval) :-
@@ -258,8 +258,8 @@
 			Rval0 = lval(Lval),
 			exprn_aux__lval_contains_rval(Lval, Rval)
 		;
-			Rval0 = create(_, Rvals, _, _, _, _),
-			exprn_aux__args_contain_rval(Rvals, Rval)
+			Rval0 = create(_, Rvals, _, _, _, _, Reuse),
+			exprn_aux__args_contain_rval([Reuse | Rvals], Rval)
 		;
 			Rval0 = mkword(_, Rval1),
 			exprn_aux__rval_contains_rval(Rval1, Rval)
@@ -300,8 +300,8 @@
 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_args(Rvals, Vars).
+exprn_aux__vars_in_rval(create(_, Rvals, _, _, _, _, Reuse), Vars) :-
+	exprn_aux__vars_in_args([Reuse | Rvals], Vars).
 exprn_aux__vars_in_rval(mkword(_, Rval), Vars) :-
 	exprn_aux__vars_in_rval(Rval, Vars).
 exprn_aux__vars_in_rval(const(_Conts), []).
@@ -376,10 +376,13 @@
 		Rval0 = var(_Var),
 		Rval = Rval0
 	;
-		Rval0 = create(Tag, Rvals0, ArgTypes, StatDyn, Num, Msg),
+		Rval0 = create(Tag, Rvals0, ArgTypes, StatDyn,
+				Num, Msg, Reuse0),
 		exprn_aux__substitute_lval_in_args(OldLval, NewLval,
 			Rvals0, Rvals),
-		Rval = create(Tag, Rvals, ArgTypes, StatDyn, Num, Msg)
+		exprn_aux__substitute_lval_in_arg(OldLval, NewLval,
+			Reuse0, Reuse),
+		Rval = create(Tag, Rvals, ArgTypes, StatDyn, Num, Msg, Reuse)
 	;
 		Rval0 = mkword(Tag, Rval1),
 		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
@@ -516,6 +519,14 @@
 
 exprn_aux__substitute_lval_in_args(_OldLval, _NewLval, [], []).
 exprn_aux__substitute_lval_in_args(OldLval, NewLval, [M0 | Ms0], [M | Ms]) :-
+	exprn_aux__substitute_lval_in_arg(OldLval, NewLval, M0, M),
+	exprn_aux__substitute_lval_in_args(OldLval, NewLval, Ms0, Ms).
+
+:- pred exprn_aux__substitute_lval_in_arg(lval, lval,
+				maybe(rval), maybe(rval)).
+:- mode exprn_aux__substitute_lval_in_arg(in, in, in, out) is det.
+
+exprn_aux__substitute_lval_in_arg(OldLval, NewLval, M0, M) :-
 	(
 		M0 = yes(Rval0)
 	->
@@ -524,8 +535,7 @@
 		M = yes(Rval)
 	;
 		M = M0
-	),
-	exprn_aux__substitute_lval_in_args(OldLval, NewLval, Ms0, Ms).
+	).
 
 exprn_aux__substitute_rval_in_rval(OldRval, NewRval, Rval0, Rval) :-
 	(
@@ -542,10 +552,14 @@
 			Rval0 = var(_),
 			Rval = Rval0
 		;
-			Rval0 = create(Tag, Rvals0, ATs, StatDyn, Num, Msg),
+			Rval0 = create(Tag, Rvals0, ATs, StatDyn,
+					Num, Msg, Reuse0),
 			exprn_aux__substitute_rval_in_args(OldRval, NewRval,
 				Rvals0, Rvals),
-			Rval = create(Tag, Rvals, ATs, StatDyn, Num, Msg)
+			exprn_aux__substitute_rval_in_arg(OldRval, NewRval,
+				Reuse0, Reuse),
+			Rval = create(Tag, Rvals, ATs, StatDyn,
+					Num, Msg, Reuse)
 		;
 			Rval0 = mkword(Tag, Rval1),
 			exprn_aux__substitute_rval_in_rval(OldRval, NewRval,
@@ -670,6 +684,14 @@
 
 exprn_aux__substitute_rval_in_args(_OldRval, _NewRval, [], []).
 exprn_aux__substitute_rval_in_args(OldRval, NewRval, [M0 | Ms0], [M | Ms]) :-
+	exprn_aux__substitute_rval_in_arg(OldRval, NewRval, M0, M),
+	exprn_aux__substitute_rval_in_args(OldRval, NewRval, Ms0, Ms).
+
+:- pred exprn_aux__substitute_rval_in_arg(rval, rval,
+				maybe(rval), maybe(rval)).
+:- mode exprn_aux__substitute_rval_in_arg(in, in, in, out) is det.
+
+exprn_aux__substitute_rval_in_arg(OldRval, NewRval, M0, M) :-
 	(
 		M0 = yes(Rval0)
 	->
@@ -678,8 +700,7 @@
 		M = yes(Rval)
 	;
 		M = M0
-	),
-	exprn_aux__substitute_rval_in_args(OldRval, NewRval, Ms0, Ms).
+	).
 
 %------------------------------------------------------------------------------%
 
@@ -738,7 +759,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)
 		;
@@ -753,11 +774,15 @@
 	->
 		Rval = lval(field(MaybeTag, Rval2, Num))
 	;
-		Rval0 = create(Tag, Args0, ArgTypes, StatDyn, CNum, Msg),
+		Rval0 = create(Tag, Args0, ArgTypes, StatDyn,
+				CNum, Msg, Reuse0),
 		exprn_aux__simplify_args(Args0, Args),
-		Args \= Args0
+		exprn_aux__simplify_arg(Reuse0, Reuse),
+		( Args \= Args0
+		; Reuse \= Reuse0
+		)
 	->
-		Rval = create(Tag, Args, ArgTypes, StatDyn, CNum, Msg)
+		Rval = create(Tag, Args, ArgTypes, StatDyn, CNum, Msg, Reuse)
 	;
 		Rval0 = unop(UnOp, Rval1),
 		exprn_aux__simplify_rval_2(Rval1, Rval2)
@@ -783,6 +808,12 @@
 exprn_aux__simplify_args([], []).
 exprn_aux__simplify_args([MR0 | Ms0], [MR | Ms]) :-
 	exprn_aux__simplify_args(Ms0, Ms),
+	exprn_aux__simplify_arg(MR0, MR).
+
+:- pred exprn_aux__simplify_arg(maybe(rval), maybe(rval)).
+:- mode exprn_aux__simplify_arg(in, out) is det.
+
+exprn_aux__simplify_arg(MR0, MR) :-
 	(
 		MR0 = yes(Rval0),
 		exprn_aux__simplify_rval_2(Rval0, Rval)
@@ -800,8 +831,10 @@
 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__maybe_rval_list_addrs(MaybeRvals, CodeAddrs, DataAddrs).
+exprn_aux__rval_addrs(create(_, MaybeRvals, _,_,_,_, Reuse),
+		CodeAddrs, DataAddrs) :-
+	exprn_aux__maybe_rval_list_addrs([Reuse | MaybeRvals],
+		CodeAddrs, DataAddrs).
 exprn_aux__rval_addrs(mkword(_Tag, Rval), CodeAddrs, DataAddrs) :-
 	exprn_aux__rval_addrs(Rval, CodeAddrs, DataAddrs).
 exprn_aux__rval_addrs(const(Const), CodeAddrs, DataAddrs) :-
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.50
diff -u -u -r1.50 jumpopt.m
--- jumpopt.m	1999/12/10 04:23:16	1.50
+++ jumpopt.m	2000/01/12 04:16:51
@@ -741,9 +741,12 @@
 	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, ArgTypes, StatDyn, Cell, Type),
-		Instrmap, create(Tag, Rvals, ArgTypes, StatDyn, Cell, Type)) :-
-	jumpopt__short_labels_maybe_rvals(Rvals0, Instrmap, Rvals).
+jumpopt__short_labels_rval(
+		create(Tag, Rvals0, ArgTypes, StatDyn, Cell, Type, Reuse0),
+		Instrmap,
+		create(Tag, Rvals, ArgTypes, StatDyn, Cell, Type, Reuse)) :-
+	jumpopt__short_labels_maybe_rvals(Rvals0, Instrmap, Rvals),
+	jumpopt__short_labels_maybe_rval(Reuse0, Instrmap, Reuse).
 jumpopt__short_labels_rval(mkword(Tag, Rval0), Instrmap,
 		mkword(Tag, Rval)) :-
 	jumpopt__short_labels_rval(Rval0, Instrmap, Rval).
@@ -787,6 +790,13 @@
 jumpopt__short_labels_maybe_rvals([], _, []).
 jumpopt__short_labels_maybe_rvals([MaybeRval0 | MaybeRvals0], Instrmap,
 		[MaybeRval | MaybeRvals]) :-
+	jumpopt__short_labels_maybe_rval(MaybeRval0, Instrmap, MaybeRval),
+	jumpopt__short_labels_maybe_rvals(MaybeRvals0, Instrmap, MaybeRvals).
+
+:- pred jumpopt__short_labels_maybe_rval(maybe(rval), instrmap, maybe(rval)).
+:- mode jumpopt__short_labels_maybe_rval(in, in, out) is det.
+
+jumpopt__short_labels_maybe_rval(MaybeRval0, Instrmap, MaybeRval) :-
 	(
 		MaybeRval0 = no,
 		MaybeRval = no
@@ -794,8 +804,7 @@
 		MaybeRval0 = yes(Rval0),
 		jumpopt__short_labels_rval(Rval0, Instrmap, Rval),
 		MaybeRval = yes(Rval)
-	),
-	jumpopt__short_labels_maybe_rvals(MaybeRvals0, Instrmap, MaybeRvals).
+	).
 
 :- pred jumpopt__short_labels_lval(lval, instrmap, lval).
 :- mode jumpopt__short_labels_lval(in, in, out) is det.
Index: compiler/livemap.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/livemap.m,v
retrieving revision 1.45
diff -u -u -r1.45 livemap.m
--- livemap.m	1999/11/15 00:42:28	1.45
+++ livemap.m	2000/01/12 02:42:59
@@ -279,6 +279,12 @@
 		Instrs = Instrs0,
 		DontValueNumber = DontValueNumber0
 	;
+		Uinstr0 = free_heap(Rval),
+		livemap__make_live_in_rvals([Rval], Livevals0, Livevals),
+		Livemap = Livemap0,
+		Instrs = Instrs0,
+		DontValueNumber = DontValueNumber0
+	;
 		Uinstr0 = store_ticket(Lval),
 		set__delete(Livevals0, Lval, Livevals1),
 		opt_util__lval_access_rvals(Lval, Rvals),
@@ -435,7 +441,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.255
diff -u -u -r1.255 llds.m
--- llds.m	1999/12/16 11:36:37	1.255
+++ llds.m	2000/01/12 02:20:42
@@ -293,6 +293,13 @@
 			% The effect is to deallocate all the memory which
 			% was allocated since that call to mark_hp.
 
+	;	free_heap(rval)
+			% Notify the garbage collector that the heap space
+			% associated with the top-level cell of the rval is
+			% no longer needed.
+			% `free' is useless but harmless without conservative
+			% garbage collection.
+
 	;	store_ticket(lval)
 			% Allocate a new "ticket" and store it in the lval.
 
@@ -720,9 +727,9 @@
 		% stage after code generation.
 
 	;	create(tag, list(maybe(rval)), create_arg_types,
-			static_or_dynamic, int, string)
+			static_or_dynamic, int, string, maybe(rval))
 		% create(Tag, Arguments, MaybeArgTypes, StaticOrDynamic,
-		%	LabelNumber, CellKind):
+		%	LabelNumber, CellKind, CellToReuse):
 		% 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.
@@ -749,10 +756,13 @@
 		% we can construct the term at compile-time
 		% and just reference the label.
 		%
-		% The last argument gives the name of the type constructor
+		% The string argument gives the name of the type constructor
 		% of the function symbol of which this is a cell, for use
 		% in memory profiling.
 		%
+		% The maybe(rval) contains the location of a cell to reuse.
+		% This will always be `no' after code generation.
+		%
 		% For the time being, you must leave the argument types
 		% implicit if the cell is to be unique. This is because
 		% (a) the code generator assumes that each argument of a cell
@@ -1038,7 +1048,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
Index: compiler/llds_common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_common.m,v
retrieving revision 1.26
diff -u -u -r1.26 llds_common.m
--- llds_common.m	1999/12/14 04:52:45	1.26
+++ llds_common.m	2000/01/12 04:21:07
@@ -214,6 +214,10 @@
 		llds_common__process_rval(Rval0, Rval, Info0, Info),
 		Instr = restore_hp(Rval)
 	;
+		Instr0 = free_heap(_),
+		Instr = Instr0,
+		Info = Info0
+	;
 		Instr0 = store_ticket(_),
 		Instr = Instr0,
 		Info = Info0
@@ -276,7 +280,8 @@
 		Rval0 = var(_),
 		error("var rval found in llds_common__process_rval")
 	;
-		Rval0 = create(Tag, Args, ArgTypes, StatDyn, _LabelNo, _Msg),
+		Rval0 = create(Tag, Args, ArgTypes, StatDyn,
+				_LabelNo, _Msg, _Reuse),
 		( StatDyn \= must_be_dynamic ->
 			llds_common__process_create(Tag, Args, ArgTypes, Rval,
 				Info0, Info)
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.133
diff -u -u -r1.133 llds_out.m
--- llds_out.m	1999/12/16 11:36:39	1.133
+++ llds_out.m	2000/01/12 02:23:59
@@ -1312,6 +1312,8 @@
 	output_lval_decls(Lval, "", "", 0, _, DeclSet0, DeclSet).
 output_instruction_decls(restore_hp(Rval), DeclSet0, DeclSet) -->
 	output_rval_decls(Rval, "", "", 0, _, DeclSet0, DeclSet).
+output_instruction_decls(free_heap(Rval), DeclSet0, DeclSet) -->
+	output_rval_decls(Rval, "", "", 0, _, DeclSet0, DeclSet).
 output_instruction_decls(store_ticket(Lval), DeclSet0, DeclSet) -->
 	output_lval_decls(Lval, "", "", 0, _, DeclSet0, DeclSet).
 output_instruction_decls(reset_ticket(Rval, _Reason), DeclSet0, DeclSet) -->
@@ -1611,6 +1613,11 @@
 	output_rval_as_type(Rval, word),
 	io__write_string(");\n").
 
+output_instruction(free_heap(Rval), _) -->
+	io__write_string("\tfree_heap("),
+	output_rval_as_type(Rval, data_ptr),
+	io__write_string(");\n").
+
 output_instruction(store_ticket(Lval), _) -->
 	io__write_string("\tMR_store_ticket("),
 	output_lval_as_word(Lval),
@@ -2108,7 +2115,8 @@
 	    { N = N2 },
 	    { DeclSet = DeclSet2 }
 	).
-output_rval_decls(create(_Tag, ArgVals, CreateArgTypes, _StatDyn, Label, _),
+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) } ->
@@ -3672,7 +3680,7 @@
 	;
 		output_lval(Lval)
 	).
-output_rval(create(Tag, _Args, _ArgTypes, _StatDyn, CellNum, _Msg)) -->
+output_rval(create(Tag, _Args, _ArgTypes, _StatDyn, CellNum, _Msg, _Reuse)) -->
 		% emit a reference to the static constant which we
 		% declared in output_rval_decls.
 	io__write_string("MR_mkword(MR_mktag("),
@@ -3778,7 +3786,9 @@
 	io__write_string(")").
 output_static_rval(lval(_)) -->
 	{ error("Cannot output an lval(_) in a static initializer") }.
-output_static_rval(create(Tag, _Args, _ArgTypes, _StatDyn, CellNum, _Msg)) -->
+output_static_rval(
+		create(Tag, _Args, _ArgTypes, _StatDyn, CellNum, _Msg, _Reuse))
+	-->
 		% emit a reference to the static constant which we
 		% declared in output_rval_decls.
 	io__write_string("MR_mkword(MR_mktag("),
Index: compiler/lookup_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lookup_switch.m,v
retrieving revision 1.35
diff -u -u -r1.35 lookup_switch.m
--- lookup_switch.m	1999/07/10 07:19:52	1.35
+++ lookup_switch.m	2000/01/12 02:44:33
@@ -247,7 +247,8 @@
 	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, _, StatDyn, _,_), ExprnOpts) :-
+lookup_switch__rval_is_constant(create(_, Args, _, StatDyn, _, _, _),
+		ExprnOpts) :-
 	(
 		StatDyn = must_be_static
 	;
@@ -351,7 +352,7 @@
 		% low bits specify which bit.
 		%
 	{
-		BitVec = create(_, [yes(SingleWord)], _, _, _, _)
+		BitVec = create(_, [yes(SingleWord)], _, _, _, _, _)
 	->
 		Word = SingleWord,
 		BitNum = UIndex
@@ -395,8 +396,9 @@
 	{ map__to_assoc_list(BitMap, WordVals) },
 	{ generate_bit_vec_args(WordVals, 0, Args) },
 	code_info__get_next_cell_number(CellNo),
+	{ Reuse = no },
 	{ BitVec = create(0, Args, uniform(no), must_be_static,
-		CellNo, "lookup_switch_bit_vector") }.
+		CellNo, "lookup_switch_bit_vector", Reuse) }.
 
 :- pred generate_bit_vec_2(case_consts, int, int,
 			map(int, int), map(int, int)).
@@ -462,8 +464,9 @@
 	{ list__sort(Vals0, Vals) },
 	{ construct_args(Vals, 0, Args) },
 	code_info__get_next_cell_number(CellNo),
+	{ Reuse = no },
 	{ ArrayTerm = create(0, Args, uniform(no), must_be_static,
-		CellNo, "lookup_switch_data") },
+		CellNo, "lookup_switch_data", Reuse) },
 	{ 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.80
diff -u -u -r1.80 middle_rec.m
--- middle_rec.m	1999/11/15 00:42:37	1.80
+++ middle_rec.m	2000/01/12 02:45:13
@@ -413,6 +413,8 @@
 	middle_rec__find_used_registers_lval(Lval, Used0, Used).
 middle_rec__find_used_registers_instr(restore_hp(Rval), Used0, Used) :-
 	middle_rec__find_used_registers_rval(Rval, Used0, Used).
+middle_rec__find_used_registers_instr(free_heap(Rval), Used0, Used) :-
+	middle_rec__find_used_registers_rval(Rval, Used0, Used).
 middle_rec__find_used_registers_instr(store_ticket(Lval), Used0, Used) :-
 	middle_rec__find_used_registers_lval(Lval, Used0, Used).
 middle_rec__find_used_registers_instr(reset_ticket(Rval, _Rsn), Used0, Used) :-
@@ -492,9 +494,9 @@
 		Rval = var(_),
 		error("var found in middle_rec__find_used_registers_rval")
 	;
-		Rval = create(_, MaybeRvals, _, _, _, _),
-		middle_rec__find_used_registers_maybe_rvals(MaybeRvals,
-			Used0, Used)
+		Rval = create(_, MaybeRvals, _, _, _, _, Reuse),
+		middle_rec__find_used_registers_maybe_rvals(
+			[Reuse | MaybeRvals], Used0, Used)
 	;
 		Rval = mkword(_, Rval1),
 		middle_rec__find_used_registers_rval(Rval1, Used0, Used)
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.97
diff -u -u -r1.97 opt_debug.m
--- opt_debug.m	1999/11/15 00:42:40	1.97
+++ opt_debug.m	2000/01/12 05:09:05
@@ -318,6 +318,9 @@
 opt_debug__dump_vninstr(vn_restore_hp(Vn), Str) :-
 	opt_debug__dump_vn(Vn, Vn_str),
 	string__append_list(["restore_hp(", Vn_str, ")"], Str).
+opt_debug__dump_vninstr(vn_free_heap(Vn), Str) :-
+	opt_debug__dump_vn(Vn, Vn_str),
+	string__append_list(["free_heap(", Vn_str, ")"], Str).
 opt_debug__dump_vninstr(vn_store_ticket(Vnlval), Str) :-
 	opt_debug__dump_vnlval(Vnlval, V_str),
 	string__append_list(["store_ticket(", V_str, ")"], Str).
@@ -634,7 +637,7 @@
 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),
 	(
@@ -919,6 +922,9 @@
 opt_debug__dump_instr(restore_hp(Rval), Str) :-
 	opt_debug__dump_rval(Rval, R_str),
 	string__append_list(["restore_hp(", R_str, ")"], Str).
+opt_debug__dump_instr(free_heap(Rval), Str) :-
+	opt_debug__dump_rval(Rval, R_str),
+	string__append_list(["free_heap(", R_str, ")"], Str).
 opt_debug__dump_instr(store_ticket(Lval), Str) :-
 	opt_debug__dump_lval(Lval, L_str),
 	string__append_list(["store_ticket(", L_str, ")"], Str).
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.104
diff -u -u -r1.104 opt_util.m
--- opt_util.m	1999/11/15 00:42:41	1.104
+++ opt_util.m	2000/01/12 04:27:39
@@ -693,7 +693,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).
@@ -850,6 +850,14 @@
 			opt_util__block_refers_stackvars(Instrs0, Need)
 		)
 	;
+		Uinstr0 = free_heap(Rval),
+		opt_util__rval_refers_stackvars(Rval, Use),
+		( Use = yes ->
+			Need = yes
+		;
+			opt_util__block_refers_stackvars(Instrs0, Need)
+		)
+	;
 		Uinstr0 = store_ticket(Lval),
 		opt_util__lval_refers_stackvars(Lval, Use),
 		( Use = yes ->
@@ -1007,6 +1015,7 @@
 opt_util__can_instr_branch_away(incr_hp(_, _, _, _), no).
 opt_util__can_instr_branch_away(mark_hp(_), no).
 opt_util__can_instr_branch_away(restore_hp(_), no).
+opt_util__can_instr_branch_away(free_heap(_), no).
 opt_util__can_instr_branch_away(store_ticket(_), no).
 opt_util__can_instr_branch_away(reset_ticket(_, _), no).
 opt_util__can_instr_branch_away(discard_ticket, no).
@@ -1071,6 +1080,7 @@
 opt_util__can_instr_fall_through(incr_hp(_, _, _, _), yes).
 opt_util__can_instr_fall_through(mark_hp(_), yes).
 opt_util__can_instr_fall_through(restore_hp(_), yes).
+opt_util__can_instr_fall_through(free_heap(_), yes).
 opt_util__can_instr_fall_through(store_ticket(_), yes).
 opt_util__can_instr_fall_through(reset_ticket(_, _), yes).
 opt_util__can_instr_fall_through(discard_ticket, yes).
@@ -1115,6 +1125,7 @@
 opt_util__can_use_livevals(incr_hp(_, _, _, _), no).
 opt_util__can_use_livevals(mark_hp(_), no).
 opt_util__can_use_livevals(restore_hp(_), no).
+opt_util__can_use_livevals(free_heap(_), no).
 opt_util__can_use_livevals(store_ticket(_), no).
 opt_util__can_use_livevals(reset_ticket(_, _), no).
 opt_util__can_use_livevals(discard_ticket, no).
@@ -1176,6 +1187,7 @@
 opt_util__instr_labels_2(incr_hp(_, _, _, _), [], []).
 opt_util__instr_labels_2(mark_hp(_), [], []).
 opt_util__instr_labels_2(restore_hp(_), [], []).
+opt_util__instr_labels_2(free_heap(_), [], []).
 opt_util__instr_labels_2(store_ticket(_), [], []).
 opt_util__instr_labels_2(reset_ticket(_, _), [], []).
 opt_util__instr_labels_2(discard_ticket, [], []).
@@ -1233,6 +1245,7 @@
 opt_util__possible_targets(incr_hp(_, _, _, _), []).
 opt_util__possible_targets(mark_hp(_), []).
 opt_util__possible_targets(restore_hp(_), []).
+opt_util__possible_targets(free_heap(_), []).
 opt_util__possible_targets(store_ticket(_), []).
 opt_util__possible_targets(reset_ticket(_, _), []).
 opt_util__possible_targets(discard_ticket, []).
@@ -1280,6 +1293,7 @@
 opt_util__instr_rvals_and_lvals(incr_hp(Lval, _, Rval, _), [Rval], [Lval]).
 opt_util__instr_rvals_and_lvals(mark_hp(Lval), [], [Lval]).
 opt_util__instr_rvals_and_lvals(restore_hp(Rval), [Rval], []).
+opt_util__instr_rvals_and_lvals(free_heap(Rval), [Rval], []).
 opt_util__instr_rvals_and_lvals(store_ticket(Lval), [], [Lval]).
 opt_util__instr_rvals_and_lvals(reset_ticket(Rval, _Reason), [Rval], []).
 opt_util__instr_rvals_and_lvals(discard_ticket, [], []).
@@ -1418,6 +1432,8 @@
 	opt_util__count_temps_lval(Lval, R0, R, F0, F).
 opt_util__count_temps_instr(restore_hp(Rval), R0, R, F0, F) :-
 	opt_util__count_temps_rval(Rval, R0, R, F0, F).
+opt_util__count_temps_instr(free_heap(Rval), R0, R, F0, F) :-
+	opt_util__count_temps_rval(Rval, R0, R, F0, F).
 opt_util__count_temps_instr(store_ticket(Lval), R0, R, F0, F) :-
 	opt_util__count_temps_lval(Lval, R0, R, F0, F).
 opt_util__count_temps_instr(reset_ticket(Rval, _Reason), R0, R, F0, F) :-
@@ -1580,7 +1596,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).
@@ -1662,7 +1678,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(_), _).
@@ -1827,6 +1843,15 @@
 		ReplData = no,
 		Rval = Rval0
 	).
+opt_util__replace_labels_instr(free_heap(Rval0), ReplMap, ReplData,
+		free_heap(Rval)) :-
+	(
+		ReplData = yes,
+		opt_util__replace_labels_rval(Rval0, ReplMap, Rval)
+	;
+		ReplData = no,
+		Rval = Rval0
+	).
 opt_util__replace_labels_instr(store_ticket(Lval0), ReplMap, ReplData,
 		store_ticket(Lval)) :-
 	(
@@ -1961,8 +1986,9 @@
 opt_util__replace_labels_rval(lval(Lval0), ReplMap, lval(Lval)) :-
 	opt_util__replace_labels_lval(Lval0, ReplMap, Lval).
 opt_util__replace_labels_rval(var(Var), _, var(Var)).
-opt_util__replace_labels_rval(create(Tag, Rvals, ArgTypes, StatDyn, N, Msg), _,
-		create(Tag, Rvals, ArgTypes, StatDyn, N, Msg)).
+opt_util__replace_labels_rval(
+		create(Tag, Rvals, ArgTypes, StatDyn, N, Msg, Reuse), _,
+		create(Tag, Rvals, ArgTypes, StatDyn, N, Msg, Reuse)).
 opt_util__replace_labels_rval(mkword(Tag, Rval0), ReplMap, mkword(Tag, Rval)) :-
 	opt_util__replace_labels_rval(Rval0, ReplMap, Rval).
 opt_util__replace_labels_rval(const(Const0), ReplMap, const(Const)) :-
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.42
diff -u -u -r1.42 stack_layout.m
--- stack_layout.m	1999/12/16 11:36:41	1.42
+++ stack_layout.m	2000/01/12 04:38:41
@@ -304,9 +304,10 @@
 		llds_out__sym_name_mangle(ModuleName, ModuleNameStr),
 		stack_layout__get_next_cell_number(ProcVectorCellNum,
 			LayoutInfo3, LayoutInfo4),
+		Reuse = no,
 		ProcLayoutVector = create(0, ProcLayoutArgs,
 			uniform(yes(data_ptr)), must_be_static, 
-			ProcVectorCellNum, "proc_layout_vector"),
+			ProcVectorCellNum, "proc_layout_vector", Reuse),
 		globals__lookup_bool_option(Globals, rtti_line_numbers,
 			LineNumbers),
 		( LineNumbers = yes ->
@@ -385,9 +386,10 @@
 		SourceFileRvals, LayoutInfo0, LayoutInfo1),
 	stack_layout__get_next_cell_number(SourceFileVectorCellNum,
 		LayoutInfo1, LayoutInfo),
+	Reuse = no,
 	SourceFilesVector = create(0, SourceFileRvals,
 		uniform(yes(data_ptr)), must_be_static, 
-		SourceFileVectorCellNum, "source_files_vector").
+		SourceFileVectorCellNum, "source_files_vector", Reuse).
 
 :- pred stack_layout__format_label_table(pair(string, label_table)::in,
 	maybe(rval)::out, stack_layout_info::in, stack_layout_info::out) is det.
@@ -437,16 +439,17 @@
 	list__map(ProjectLineNos, FlatLineNoList, LineNoRvals),
 	stack_layout__get_next_cell_number(LineNoVectorCellNum,
 		LayoutInfo1, LayoutInfo2),
+	Reuse = no,
 	LineNoVector = create(0, LineNoRvals,
 		uniform(yes(int_least16)), must_be_static, 
-		LineNoVectorCellNum, "line_number_vector"),
+		LineNoVectorCellNum, "line_number_vector", Reuse),
 
 	list__map(ProjectLabels, FlatLineNoList, LabelRvals),
 	stack_layout__get_next_cell_number(LabelsVectorCellNum,
 		LayoutInfo2, LayoutInfo3),
 	LabelsVector = create(0, LabelRvals,
 		uniform(yes(data_ptr)), must_be_static, 
-		LabelsVectorCellNum, "label_vector"),
+		LabelsVectorCellNum, "label_vector", Reuse),
 
 % We do not include the callees vector in the table because it makes references
 % to the proc layouts of procedures from other modules without knowing whether
@@ -468,7 +471,7 @@
 %		LayoutInfo3, LayoutInfo4),
 %	CalleesVector = create(0, CalleeRvals,
 %		uniform(no), must_be_static, 
-%		CalleesVectorCellNum, "callee_vector"),
+%		CalleesVectorCellNum, "callee_vector", Reuse),
 
 	SourceFileRvals = [
 		yes(const(string_const(FileName))),
@@ -483,7 +486,7 @@
 		initial([1 - yes(string), 1 - yes(integer),
 			2 - yes(data_ptr)], none),
 		must_be_static, 
-		SourceFileVectorCellNum, "source_file_vector").
+		SourceFileVectorCellNum, "source_file_vector", Reuse).
 
 :- pred stack_layout__flatten_label_table(
 	assoc_list(int, list(line_no_info))::in,
@@ -969,9 +972,10 @@
 		stack_layout__construct_tvar_rvals(TVarLocnMap,
 			Vector, VectorTypes),
 		CNum is CNum0 + 1,
+		Reuse = no,
 		TypeParamRval = create(0, Vector, VectorTypes,
 			must_be_static, CNum,
-			"stack_layout_type_param_locn_vector")
+			"stack_layout_type_param_locn_vector", Reuse)
 	).
 
 :- pred stack_layout__construct_tvar_rvals(map(tvar, set(layout_locn))::in,
@@ -1164,9 +1168,10 @@
 			ByteArrayLength - yes(uint_least8)] },
 	{ list__append(AllTypeTypes, LocnArgTypes, ArgTypes) },
 	stack_layout__get_next_cell_number(CNum1),
+	{ Reuse = no },
 	{ TypeLocnVector = create(0, TypeLocnVectorRvals,
 		initial(ArgTypes, none), must_be_static, CNum1,
-		"stack_layout_locn_vector") },
+		"stack_layout_locn_vector", Reuse) },
 
 	stack_layout__get_trace_stack_layout(TraceStackLayout),
 	( { TraceStackLayout = yes } ->
@@ -1176,7 +1181,7 @@
 		stack_layout__get_next_cell_number(CNum2),
 		{ NameVector = create(0, VarNumNameRvals,
 			uniform(yes(uint_least16)), must_be_static,
-			CNum2, "stack_layout_num_name_vector") }
+			CNum2, "stack_layout_num_name_vector", Reuse) }
 	;
 		{ NameVector = const(int_const(0)) }
 	).
Index: compiler/string_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/string_switch.m,v
retrieving revision 1.33
diff -u -u -r1.33 string_switch.m
--- string_switch.m	1999/07/10 07:19:54	1.33
+++ string_switch.m	2000/01/12 02:51:41
@@ -85,12 +85,13 @@
 
 		% Generate code which does the hash table lookup
 	{
+		Reuse = no,
 		NextSlotsTable = create(0, NextSlots, uniform(no),
 			must_be_static, NextSlotsTableNo,
-			"string_switch_next_slots_table"),
+			"string_switch_next_slots_table", Reuse),
 		StringTable = create(0, Strings, uniform(no),
 			must_be_static, StringTableNo,
-			"string_switch_string_table"),
+			"string_switch_string_table", Reuse),
 		HashLookupCode = node([
 			comment("hashed string switch") -
 			  "",
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.103
diff -u -u -r1.103 unify_gen.m
--- unify_gen.m	1999/10/26 14:50:32	1.103
+++ unify_gen.m	2000/01/12 02:52:18
@@ -309,8 +309,9 @@
 	{ unify_gen__var_type_msg(VarType, VarTypeMsg) },
 	% XXX Later we will need to worry about
 	% whether the cell must be unique or not.
+	{ Reuse = no },
 	{ Expr = create(UnsharedTag, RVals, uniform(no), can_be_either,
-		CellNo, VarTypeMsg) },
+		CellNo, VarTypeMsg, Reuse) },
 	code_info__cache_expression(Var, Expr).
 unify_gen__generate_construction_2(shared_remote_tag(Bits0, Num0),
 		Var, Args, Modes, _, Code) -->
@@ -326,8 +327,9 @@
 	{ unify_gen__var_type_msg(VarType, VarTypeMsg) },
 	% XXX Later we will need to worry about
 	% whether the cell must be unique or not.
+	{ Reuse = no },
 	{ Expr = create(Bits0, RVals, uniform(no), can_be_either,
-		CellNo, VarTypeMsg) },
+		CellNo, VarTypeMsg, Reuse) },
 	code_info__cache_expression(Var, Expr).
 unify_gen__generate_construction_2(shared_local_tag(Bits1, Num1),
 		Var, _Args, _Modes, _, Code) -->
@@ -533,9 +535,10 @@
 			ClosureLayoutArgTypes, CNum0, CNum) },
 		code_info__set_cell_count(CNum),
 		code_info__get_next_cell_number(ClosureLayoutCellNo),
+		{ Reuse = no },
 		{ ClosureLayout = create(0, ClosureLayoutMaybeRvals,
 			ClosureLayoutArgTypes, must_be_static,
-			ClosureLayoutCellNo, "closure_layout") },
+			ClosureLayoutCellNo, "closure_layout", Reuse) },
 		{ list__length(Args, NumArgs) },
 		{ proc_info_arg_info(ProcInfo, ArgInfo) },
 		{ unify_gen__generate_pred_args(Args, ArgInfo, PredArgs) },
@@ -547,7 +550,7 @@
 		] },
 		code_info__get_next_cell_number(ClosureCellNo),
 		{ Value = create(0, Vector, uniform(no), can_be_either,
-			ClosureCellNo, "closure") }
+			ClosureCellNo, "closure", Reuse) }
 	),
 	code_info__cache_expression(Var, Value).
 
Index: compiler/value_number.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/value_number.m,v
retrieving revision 1.100
diff -u -u -r1.100 value_number.m
--- value_number.m	1999/11/15 00:42:53	1.100
+++ value_number.m	2000/01/12 23:35:00
@@ -113,6 +113,10 @@
 	% deleted, and (b) uses of those control slots in the form of
 	% branches to do_redo and do_fail, since otherwise assignments
 	% to stack variables may be moved across them.
+	%
+	% Operations on a cell which is explicitly freed by a free_heap 
+	% instruction should not be reordered with the free_heap.
+	% We put labels before and after to avoid this.
 
 :- pred value_number__prepare_for_vn(list(instruction), proc_label,
 	bool, set(label), set(label), int, int, list(instruction)).
@@ -193,6 +197,8 @@
 			)
 		;
 			Uinstr0 = mkframe(_, _)
+		;
+			Uinstr0 = free_heap(_)
 		)
 	->
 		N1 is N0 + 1,
@@ -1090,6 +1096,7 @@
 value_number__boundary_instr(incr_hp(_, _, _, _), no).
 value_number__boundary_instr(mark_hp(_), no).
 value_number__boundary_instr(restore_hp(_), no).
+value_number__boundary_instr(free_heap(_), no).
 value_number__boundary_instr(store_ticket(_), no).
 value_number__boundary_instr(reset_ticket(_, _), no).
 value_number__boundary_instr(discard_ticket, no).
Index: compiler/vn_block.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_block.m,v
retrieving revision 1.61
diff -u -u -r1.61 vn_block.m
--- vn_block.m	1999/11/15 00:42:55	1.61
+++ vn_block.m	2000/01/12 02:56:40
@@ -314,6 +314,13 @@
 	vn_block__new_ctrl_node(vn_restore_hp(Vn), Livemap,
 		Params, VnTables1, VnTables,
 		Liveset0, Liveset, Tuple0, Tuple).
+vn_block__handle_instr(free_heap(Rval),
+		Livemap, Params, VnTables0, VnTables, Liveset0, Liveset,
+		SeenIncr, SeenIncr, Tuple0, Tuple) :-
+	vn_util__rval_to_vn(Rval, Vn, VnTables0, VnTables1),
+	vn_block__new_ctrl_node(vn_free_heap(Vn), Livemap,
+		Params, VnTables1, VnTables,
+		Liveset0, Liveset, Tuple0, Tuple).
 vn_block__handle_instr(store_ticket(Lval),
 		Livemap, Params, VnTables0, VnTables, Liveset0, Liveset,
 		SeenIncr, SeenIncr, Tuple0, Tuple) :-
@@ -466,6 +473,13 @@
 		LabelNo = LabelNo0,
 		Parallels = []
 	;
+		VnInstr = vn_free_heap(_),
+		VnTables = VnTables0,
+		Liveset = Liveset0,
+		FlushEntry = FlushEntry0,
+		LabelNo = LabelNo0,
+		Parallels = []
+	;
 		VnInstr = vn_store_ticket(Vnlval),
 		( vn_table__search_desired_value(Vnlval, Vn_prime, VnTables0) ->
 			Vn = Vn_prime,
@@ -907,6 +921,7 @@
 vn_block__is_ctrl_instr(incr_hp(_, _, _, _), no).
 vn_block__is_ctrl_instr(mark_hp(_), yes).
 vn_block__is_ctrl_instr(restore_hp(_), yes).
+vn_block__is_ctrl_instr(free_heap(_), yes).
 vn_block__is_ctrl_instr(store_ticket(_), yes).
 vn_block__is_ctrl_instr(reset_ticket(_, _), yes).
 vn_block__is_ctrl_instr(discard_ticket, yes).
Index: compiler/vn_cost.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_cost.m,v
retrieving revision 1.39
diff -u -u -r1.39 vn_cost.m
--- vn_cost.m	1999/11/15 00:42:55	1.39
+++ vn_cost.m	2000/01/12 02:57:08
@@ -153,6 +153,10 @@
 		vn_cost__rval_cost(Rval, Params, RvalCost),
 		Cost = RvalCost
 	;
+		Uinstr = free_heap(Rval),
+		vn_cost__rval_cost(Rval, Params, RvalCost),
+		Cost = RvalCost
+	;
 		Uinstr = store_ticket(Lval),
 		vn_cost__lval_cost(Lval, Params, LvalCost),
 		Cost = LvalCost
@@ -306,7 +310,7 @@
 		Rval = var(_),
 		error("var found in rval_cost")
 	;
-		Rval = create(_, _, _, _, _, _),
+		Rval = create(_, _, _, _, _, _, _),
 		Cost = 0
 	;
 		Rval = mkword(_, Rval1),
Index: compiler/vn_filter.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_filter.m,v
retrieving revision 1.23
diff -u -u -r1.23 vn_filter.m
--- vn_filter.m	1999/11/15 00:42:56	1.23
+++ vn_filter.m	2000/01/12 02:59:16
@@ -146,6 +146,7 @@
 vn_filter__user_instr(incr_hp(_, _, Rval, _), yes(Rval)).
 vn_filter__user_instr(mark_hp(_), no).
 vn_filter__user_instr(restore_hp(Rval), yes(Rval)).
+vn_filter__user_instr(free_heap(Rval), yes(Rval)).
 vn_filter__user_instr(store_ticket(_), no).
 vn_filter__user_instr(reset_ticket(Rval, _Reason), yes(Rval)).
 vn_filter__user_instr(discard_ticket, no).
@@ -205,6 +206,9 @@
 vn_filter__replace_in_user_instr(restore_hp(Rval0), Temp, Defn,
 		restore_hp(Rval)) :-
 	vn_filter__replace_in_rval(Rval0, Temp, Defn, Rval).
+vn_filter__replace_in_user_instr(free_heap(Rval0), Temp, Defn,
+		free_heap(Rval)) :-
+	vn_filter__replace_in_rval(Rval0, Temp, Defn, Rval).
 vn_filter__replace_in_user_instr(store_ticket(_), _, _, _) :-
 	error("non-user instruction in vn_filter__replace_in_user_instr").
 vn_filter__replace_in_user_instr(reset_ticket(Rval0, Reason), Temp, Defn,
@@ -253,6 +257,7 @@
 vn_filter__defining_instr(incr_hp(Lval, _, _, _), yes(Lval)).
 vn_filter__defining_instr(mark_hp(Lval), yes(Lval)).
 vn_filter__defining_instr(restore_hp(_), no).
+vn_filter__defining_instr(free_heap(_), no).
 vn_filter__defining_instr(store_ticket(Lval), yes(Lval)).
 vn_filter__defining_instr(reset_ticket(_, _), no).
 vn_filter__defining_instr(discard_ticket, no).
@@ -310,6 +315,8 @@
 	vn_filter__replace_in_lval(Lval0, Temp, Defn, Lval).
 vn_filter__replace_in_defining_instr(restore_hp(_), _, _, _) :-
 	error("non-def instruction in vn_filter__replace_in_defining_instr").
+vn_filter__replace_in_defining_instr(free_heap(_), _, _, _) :-
+	error("non-def instruction in vn_filter__replace_in_defining_instr").
 vn_filter__replace_in_defining_instr(store_ticket(Lval0), Temp, Defn,
 		store_ticket(Lval)) :-
 	vn_filter__replace_in_lval(Lval0, Temp, Defn, Lval).
@@ -388,8 +395,8 @@
 	).
 vn_filter__replace_in_rval(var(_), _, _, _) :-
 	error("found var in vn_filter__replace_in_rval").
-vn_filter__replace_in_rval(create(Tag, Args, AT, StatDyn, Label, Msg), _, _,
-		create(Tag, Args, AT, StatDyn, Label, Msg)).
+vn_filter__replace_in_rval(create(Tag, Args, AT, StatDyn, Label, Msg, Reuse),
+		_, _, create(Tag, Args, AT, StatDyn, Label, Msg, Reuse)).
 vn_filter__replace_in_rval(mkword(Tag, Rval0), Temp, Defn, mkword(Tag, Rval)) :-
 	vn_filter__replace_in_rval(Rval0, Temp, Defn, Rval).
 vn_filter__replace_in_rval(const(Const), _, _, const(Const)).
Index: compiler/vn_flush.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_flush.m,v
retrieving revision 1.50
diff -u -u -r1.50 vn_flush.m
--- vn_flush.m	1999/11/15 00:42:56	1.50
+++ vn_flush.m	2000/01/12 03:00:20
@@ -242,6 +242,12 @@
 		Instr = restore_hp(Rval) - "",
 		list__append(FlushInstrs, [Instr], Instrs)
 	;
+		Vn_instr = vn_free_heap(Vn),
+		vn_flush__vn(Vn, [src_ctrl(N)], [], Rval, VnTables0, VnTables,
+			Templocs0, Templocs, Params, FlushInstrs),
+		Instr = free_heap(Rval) - "",
+		list__append(FlushInstrs, [Instr], Instrs)
+	;
 		Vn_instr = vn_store_ticket(Vnlval),
 		vn_flush__access_path(Vnlval, [src_ctrl(N)], [], Lval,
 			VnTables0, VnTables1, Templocs0, Templocs, Params,
@@ -693,7 +699,9 @@
 	;
 		Vnrval = vn_create(Tag, MaybeRvals, ArgTypes, StatDyn,
 			Label, Msg),
-		Rval = create(Tag, MaybeRvals, ArgTypes, StatDyn, Label, Msg),
+		Reuse = no,
+		Rval = create(Tag, MaybeRvals, ArgTypes, StatDyn,
+			Label, Msg, Reuse),
 		VnTables = VnTables0,
 		Templocs = Templocs0,
 		Instrs = []
Index: compiler/vn_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_order.m,v
retrieving revision 1.49
diff -u -u -r1.49 vn_order.m
--- vn_order.m	1999/11/15 00:42:57	1.49
+++ vn_order.m	2000/01/12 04:48:31
@@ -364,6 +364,11 @@
 				VnTables0, VnTables1,
 				Succmap0, Succmap1, Predmap0, Predmap1)
 		;
+			Vn_instr = vn_free_heap(Vn),
+			vn_order__find_links(Vn, node_ctrl(Ctrl),
+				VnTables0, VnTables1,
+				Succmap0, Succmap1, Predmap0, Predmap1)
+		;
 			Vn_instr = vn_store_ticket(Vnlval),
 			vn_util__vnlval_access_vns(Vnlval, Vns),
 			vn_order__find_all_links(Vns, node_ctrl(Ctrl),
Index: compiler/vn_type.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_type.m,v
retrieving revision 1.42
diff -u -u -r1.42 vn_type.m
--- vn_type.m	1999/11/15 00:42:58	1.42
+++ vn_type.m	2000/01/12 03:01:03
@@ -79,6 +79,7 @@
 			;	vn_if_val(vn, code_addr)
 			;	vn_mark_hp(vnlval)
 			;	vn_restore_hp(vn)
+			;	vn_free_heap(vn)
 			;	vn_store_ticket(vnlval)
 			;	vn_reset_ticket(vn, reset_trail_reason)
 			;	vn_discard_ticket
Index: compiler/vn_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_util.m,v
retrieving revision 1.67
diff -u -u -r1.67 vn_util.m
--- vn_util.m	1999/11/15 00:42:58	1.67
+++ vn_util.m	2000/01/12 03:01:51
@@ -148,7 +148,7 @@
 		Rval = var(_),
 		error("value_number should never get rval: var")
 	;
-		Rval = create(Tag, Args, ArgTypes, StatDyn, Label, Msg),
+		Rval = create(Tag, Args, ArgTypes, StatDyn, Label, Msg, _),
 		vn_util__vnrval_to_vn(vn_create(Tag, Args, ArgTypes,
 			StatDyn, Label, Msg), Vn, VnTables0, VnTables)
 	;
@@ -1076,7 +1076,7 @@
 		Rval = var(_),
 		error("var found in vn_util__find_lvals_in_rval")
 	;
-		Rval = create(_, _, _, _, _, _),
+		Rval = create(_, _, _, _, _, _, _),
 		Lvals = []
 	;
 		Rval = mkword(_, Rval1),
@@ -1254,6 +1254,10 @@
 				VnTables0, VnTables1)
 		;
 			VnInstr = vn_restore_hp(Vn),
+			vn_util__record_use(Vn, src_ctrl(Ctrl),
+				VnTables0, VnTables1)
+		;
+			VnInstr = vn_free_heap(Vn),
 			vn_util__record_use(Vn, src_ctrl(Ctrl),
 				VnTables0, VnTables1)
 		;
Index: compiler/vn_verify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_verify.m,v
retrieving revision 1.23
diff -u -u -r1.23 vn_verify.m
--- vn_verify.m	1999/11/15 00:42:59	1.23
+++ vn_verify.m	2000/01/12 04:51:05
@@ -228,7 +228,9 @@
 	vn_verify__lval(Vnlval, VnTables, Lval).
 vn_verify__subst_sub_vns(vn_mkword(Tag, _), [R], _, mkword(Tag, R)).
 vn_verify__subst_sub_vns(vn_const(Const), [], _, const(Const)).
-vn_verify__subst_sub_vns(vn_create(T,A,AT,U,L,M), [], _, create(T,A,AT,U,L,M)).
+vn_verify__subst_sub_vns(vn_create(T,A,AT,U,L,M), [], _,
+		create(T,A,AT,U,L,M, Reuse)) :-
+	Reuse = no.
 vn_verify__subst_sub_vns(vn_unop(Op, _), [R], _, unop(Op, R)).
 vn_verify__subst_sub_vns(vn_binop(Op, _, _), [R1, R2], _, binop(Op, R1, R2)).
 
@@ -338,6 +340,11 @@
 		NoDeref = NoDeref0,
 		Tested = Tested0
 	;
+		Instr = free_heap(Rval),
+		vn_verify__tags_rval(Rval, NoDeref0),
+		NoDeref = NoDeref0,
+		Tested = Tested0
+	;
 		Instr = store_ticket(Lval),
 		vn_verify__tags_lval(Lval, NoDeref0),
 		NoDeref = NoDeref0,
@@ -410,7 +417,7 @@
 	vn_verify__tags_lval(Lval, NoDeref).
 vn_verify__tags_rval(var(_), _) :-
 	error("found var in vn_verify__tags_rval").
-vn_verify__tags_rval(create(_, _, _, _, _, _), _).
+vn_verify__tags_rval(create(_, _, _, _, _, _, _), _).
 vn_verify__tags_rval(mkword(_, Rval), NoDeref) :-
 	vn_verify__tags_rval(Rval, NoDeref).
 vn_verify__tags_rval(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