[m-rev.] [reuse] diff: compile time garbage collection identification

Peter Ross peter.ross at miscrit.be
Mon Mar 19 03:57:49 AEDT 2001


Hi,


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


Estimated hours taken: 6
Branches: reuse

Mark cells which die unconditionally as compile time garbage
collectable.

compiler/sr_choice.m:
    Add a new pass which determines which cells die unconditionally and
    are not reused and hence can be compile time garbage collected.

compiler/mlds.m:
    Add to the delete object instruction a field that records how big
    the lval to be cgc'd is.

compiler/ml_unify_gen.m:
    If a cell can be compile time garbage collected, calculate the size
    of the cell by taking into account whether or not the cell has a
    secondary tag.
    
compiler/mlds_to_c.m:
    Don't abort if delete_object is encountered in the instruction
    stream, just do nothing for the moment.  This is because I have
    seperated the changes for identifying the cgc and using the
    information.

compiler/ml_elim_nested.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
    Handle the changes to the delete_object instruction.


Index: ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.11.2.6
diff -u -r1.11.2.6 ml_elim_nested.m
--- ml_elim_nested.m	2001/03/05 12:05:53	1.11.2.6
+++ ml_elim_nested.m	2001/03/18 16:46:47
@@ -911,7 +911,7 @@
 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_atomic_stmt(delete_object(Lval0, Size), delete_object(Lval, Size)) -->
 	fixup_lval(Lval0, Lval).
 fixup_atomic_stmt(new_object(Target0, MaybeTag, Type, MaybeSize, MaybeCtorName,
 			Args0, ArgTypes),
Index: ml_unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.16.2.13
diff -u -r1.16.2.13 ml_unify_gen.m
--- ml_unify_gen.m	2001/03/16 09:09:55	1.16.2.13
+++ ml_unify_gen.m	2001/03/18 16:46:49
@@ -148,12 +148,12 @@
 		{ CanFail = can_fail },
 		{ ExpectedCodeModel = model_semi },
 		ml_gen_semi_deconstruct(Var, ConsId, Args, ArgModes, Context,
-			MLDS_Decls, MLDS_Unif_Statements)
+			HasSecondaryTag, MLDS_Decls, MLDS_Unif_Statements)
 	;
 		{ CanFail = cannot_fail },
 		{ ExpectedCodeModel = model_det },
 		ml_gen_det_deconstruct(Var, ConsId, Args, ArgModes, Context,
-			MLDS_Decls, MLDS_Unif_Statements)
+			HasSecondaryTag, MLDS_Decls, MLDS_Unif_Statements)
 	),
 	(
 		%
@@ -163,7 +163,15 @@
 		%
 		{ CanCGC = yes },
 		ml_gen_var(Var, VarLval),
-		{ MLDS_Stmt = atomic(delete_object(VarLval)) },
+		{ 
+			HasSecondaryTag = yes,
+			SecondaryTagSize = 1
+		; 
+			HasSecondaryTag = no,
+			SecondaryTagSize = 0
+		},
+		{ MLDS_Stmt = atomic(delete_object(VarLval,
+				list__length(Args) + SecondaryTagSize)) },
 		{ MLDS_CGC_Statements = [mlds__statement(MLDS_Stmt,
 				mlds__make_context(Context)) ] }
 	;
@@ -1277,9 +1285,10 @@
 	% need to generate a test.
 	%
 :- pred ml_gen_det_deconstruct(prog_var, cons_id, prog_vars, list(uni_mode),
-		prog_context, mlds__defns, mlds__statements,
+		prog_context, bool, mlds__defns, mlds__statements,
 		ml_gen_info, ml_gen_info).
-:- mode ml_gen_det_deconstruct(in, in, in, in, in, out, out, in, out) is det.
+:- mode ml_gen_det_deconstruct(in,
+		in, in, in, in, out, out, out, in, out) is det.
 
 %	det (cannot_fail) deconstruction:
 %		<do (X => f(A1, A2, ...))>
@@ -1289,7 +1298,7 @@
 %		...
 
 ml_gen_det_deconstruct(Var, ConsId, Args, Modes, Context,
-		MLDS_Decls, MLDS_Statements) -->
+		HasSecondaryTag, MLDS_Decls, MLDS_Statements) -->
 	{ MLDS_Decls = [] },
 	ml_variable_type(Var, Type),
 	ml_cons_id_to_tag(ConsId, Type, Tag),
@@ -1297,30 +1306,39 @@
 	% the value of the constant, so MLDS_Statements = [].
 	(
 		{ Tag = string_constant(_String) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = int_constant(_Int) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = float_constant(_Float) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = pred_closure_tag(_, _, _) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = code_addr_constant(_, _) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = type_ctor_info_constant(_, _, _) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = base_typeclass_info_constant(_, _, _) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = tabling_pointer_constant(_, _) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] }
 	;
 		{ Tag = no_tag },
+		{ HasSecondaryTag = no },
 		( { Args = [Arg], Modes = [Mode] } ->
 			ml_variable_type(Arg, ArgType),
 			ml_gen_var(Arg, ArgLval),
@@ -1332,6 +1350,7 @@
 		)
 	;
 		{ Tag = unshared_tag(UnsharedTag) },
+		{ HasSecondaryTag = no },
 		ml_gen_var(Var, VarLval),
 		ml_variable_types(Args, ArgTypes),
 		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
@@ -1341,6 +1360,7 @@
 				UnsharedTag, Context, MLDS_Statements)
 	;
 		{ Tag = shared_remote_tag(PrimaryTag, _SecondaryTag) },
+		{ HasSecondaryTag = yes },
 		ml_gen_var(Var, VarLval),
 		ml_variable_types(Args, ArgTypes),
 		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
@@ -1350,6 +1370,7 @@
 				PrimaryTag, Context, MLDS_Statements)
 	;
 		{ Tag = shared_local_tag(_Bits1, _Num1) },
+		{ HasSecondaryTag = no },
 		{ MLDS_Statements = [] } % if this is det, then nothing happens
 	).
 
@@ -1662,9 +1683,10 @@
 	% (which is executed only if the tag test succeeds).
 	%
 :- pred ml_gen_semi_deconstruct(prog_var, cons_id, prog_vars, list(uni_mode),
-		prog_context, mlds__defns, mlds__statements,
+		prog_context, bool, mlds__defns, mlds__statements,
 		ml_gen_info, ml_gen_info).
-:- mode ml_gen_semi_deconstruct(in, in, in, in, in, out, out, in, out) is det.
+:- mode ml_gen_semi_deconstruct(in,
+		in, in, in, in, out, out, out, in, out) is det.
 
 %	semidet (can_fail) deconstruction:
 %		<succeeded = (X => f(A1, A2, ...))>
@@ -1677,12 +1699,12 @@
 %		}
 
 ml_gen_semi_deconstruct(Var, ConsId, Args, ArgModes, Context,
-		MLDS_Decls, MLDS_Statements) -->
+		HasSecondaryTag, MLDS_Decls, MLDS_Statements) -->
 	ml_gen_tag_test(Var, ConsId, TagTestDecls, TagTestStatements,
 		TagTestExpression),
 	ml_gen_set_success(TagTestExpression, Context, SetTagTestResult),
 	ml_gen_det_deconstruct(Var, ConsId, Args, ArgModes, Context,
-		GetArgsDecls, GetArgsStatements),
+		HasSecondaryTag, GetArgsDecls, GetArgsStatements),
 	{ GetArgsDecls = [], GetArgsStatements = [] ->
 		MLDS_Decls = TagTestDecls,
 		MLDS_Statements = list__append(TagTestStatements,
Index: mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.34.2.5
diff -u -r1.34.2.5 mlds.m
--- mlds.m	2001/03/05 12:05:54	1.34.2.5
+++ mlds.m	2001/03/18 16:46:54
@@ -963,9 +963,10 @@
 	% heap management
 	%
 
-	;	delete_object(mlds__lval)
+	;	delete_object(mlds__lval, int)
 			% Compile time garbage collect (ie explicitly
-			% deallocate) the memory used by the lval.
+			% deallocate) the memory used by the lval of 
+			% the size recorded in the integer.
 
 			% 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.55.2.8
diff -u -r1.55.2.8 mlds_to_c.m
--- mlds_to_c.m	2001/03/09 14:11:47	1.55.2.8
+++ mlds_to_c.m	2001/03/18 16:47:03
@@ -2390,14 +2390,33 @@
 	%
 	% 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, delete_object(_Lval, _Size), _) -->
+	[].
+	% Commented out until MR_compile_time_gc implemented.
+	% mlds_indent(Indent),
+	% io__write_string("MR_compile_time_gc(MR_strip_tag("),
+	% mlds_output_lval(Lval),
+	% io__write_string("), "),
+	% io__write_int(Size),
+	% io__write_string(");\n").
 
 mlds_output_atomic_stmt(Indent, FuncInfo, NewObject, Context) -->
 	{ NewObject = new_object(Target, MaybeTag, Type, MaybeSize,
 		MaybeCtorName, Args, ArgTypes) },
 	mlds_indent(Indent),
 	io__write_string("{\n"),
+
+	/* XXX measure how likely we are to reuse a cgc cell
+	mlds_indent(Context, Indent + 1),
+	io__write_string("MR_update_cell_cache_statistics("),
+	( { MaybeSize = yes(LSize) } ->
+		mlds_output_rval(LSize)
+	;
+		% XXX what should we do here?
+		io__write_int(-1)
+	),
+	io__write_string(");\n"),
+	*/
 
 	{ FuncInfo = func_info(FuncName, _) },
 	mlds_maybe_output_heap_profile_instr(Context, Indent + 1, Args,
Index: mlds_to_gcc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_gcc.m,v
retrieving revision 1.30.6.3
diff -u -r1.30.6.3 mlds_to_gcc.m
--- mlds_to_gcc.m	2001/03/05 12:05:57	1.30.6.3
+++ mlds_to_gcc.m	2001/03/18 16:47:14
@@ -2833,7 +2833,7 @@
 	%
 	% heap management
 	%
-gen_atomic_stmt(_DefnInfo, delete_object(_Lval), _) -->
+gen_atomic_stmt(_DefnInfo, delete_object(_Lval, _Size), _) -->
 	% XXX not yet implemented
 	% we should generate a call to GC_free()
 	% (would be easy to do, but not needed so far, since
Index: mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.6.2.5
diff -u -r1.6.2.5 mlds_to_il.m
--- mlds_to_il.m	2001/03/12 20:24:41	1.6.2.5
+++ mlds_to_il.m	2001/03/18 16:47:21
@@ -962,7 +962,7 @@
 atomic_statement_to_il(comment(Comment), Instrs) -->
 	{ Instrs = node([comment(Comment)]) }.
 
-atomic_statement_to_il(delete_object(Target), Instrs) -->
+atomic_statement_to_il(delete_object(Target, _Size), Instrs) -->
 		% XXX we assume the code generator knows what it is
 		% doing and is only going to delete real objects (e.g.
 		% reference types).  It would perhaps be prudent to
Index: mlds_to_java.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_java.m,v
retrieving revision 1.1.4.2
diff -u -r1.1.4.2 mlds_to_java.m
--- mlds_to_java.m	2001/03/05 12:05:58	1.1.4.2
+++ mlds_to_java.m	2001/03/18 16:47:28
@@ -1766,7 +1766,7 @@
 	%
 	% heap management
 	%
-output_atomic_stmt(_Indent, _FuncInfo, delete_object(_Lval), _) -->
+output_atomic_stmt(_Indent, _FuncInfo, delete_object(_Lval, _Size), _) -->
 	{ error("mlds_to_java.m: delete_object not supported in Java.") }.
 
 output_atomic_stmt(Indent, _FuncInfo, NewObject, Context) -->
Index: sr_choice.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_choice.m,v
retrieving revision 1.1.2.18
diff -u -r1.1.2.18 sr_choice.m
--- sr_choice.m	2001/03/16 09:09:56	1.1.2.18
+++ sr_choice.m	2001/03/18 16:47:31
@@ -61,7 +61,8 @@
 		Goal0, Goal, MaybeReuseConditions) :-
 	Strategy = strategy(Constraint, SelectionRule),
 	apply_constraint(Constraint, VarTypes, ModuleInfo, Goal0, Goal1),
-	select_reuses(SelectionRule, Goal1, Goal, ReuseConditions),
+	select_reuses(SelectionRule, Goal1, Goal2, ReusedVars, ReuseConditions),
+	determine_cgc(ReusedVars, Goal2, Goal),
 	( ReuseConditions = [] ->
 		MaybeReuseConditions = no
 	;
@@ -261,24 +262,8 @@
 			choice(construct(set__list_to_set(Candidates))),
 			GoalInfo) }.
 
-apply_constraint_unification(_Constraint, Unif, GoalInfo0, GoalInfo) -->
+apply_constraint_unification(_Constraint, Unif, GoalInfo, GoalInfo) -->
 	{ Unif = deconstruct(Var, ConsId, Vars, _Modes, _CanFail, _CanCGC) },
-
-	{ goal_info_get_reuse(GoalInfo0, ReuseInfo) },
-	{ ReuseInfo = choice(deconstruct(MaybeDies)) ->
-		(
-			MaybeDies = yes(_Condition),
-			goal_info_set_reuse(GoalInfo0, reuse(cell_died),
-					GoalInfo)
-		;
-			MaybeDies = no,
-			goal_info_set_reuse(GoalInfo0, reuse(no_reuse),
-					GoalInfo)
-		)
-	;
-		error("sr_choice__apply_constraint_unification")
-	},
-
 	Map0 =^ map,
 	has_secondary_tag(Var, ConsId, SecondaryTag),
 	{ multi_map__set(Map0, Var, data(ConsId, Vars, SecondaryTag), Map) },
@@ -443,70 +428,71 @@
 selection_info_init = selection_info(set__init, set__init, [], lifo([],[],[])).
 
 :- pred select_reuses(selection::in, hlds_goal::in, hlds_goal::out,
-		list(reuse_condition)::out) is det.
+		set(prog_var)::out, list(reuse_condition)::out) is det.
 
-select_reuses(SelectionRule, Goal0, Goal, ReuseConditions) :-
-	select_reuses(SelectionRule, Goal0, Goal, selection_info_init, Info),
+select_reuses(SelectionRule, Goal0, Goal, ReusedVars, ReuseConditions) :-
+	select_reuses_2(SelectionRule, Goal0, Goal, selection_info_init, Info),
+	ReusedVars = Info ^ local_used `union` Info ^ global_used,
 	ReuseConditions = Info ^ reuse_conds.
 
-:- pred select_reuses(selection::in, hlds_goal::in, hlds_goal::out,
+:- pred select_reuses_2(selection::in, hlds_goal::in, hlds_goal::out,
 		selection_info::in, selection_info::out) is det.
 
-select_reuses(_Selection, Goal - GoalInfo, Goal - GoalInfo) -->
+select_reuses_2(_Selection, Goal - GoalInfo, Goal - GoalInfo) -->
 	{ Goal = call(_PredId, _ProcId, _Args, _Builtin, _MaybeCtxt, _Name) }.
 
-select_reuses(Selection, Goal - GoalInfo0, Goal - GoalInfo) -->
+select_reuses_2(Selection, Goal - GoalInfo0, Goal - GoalInfo) -->
 	{ Goal = unify(_Var, _Rhs, _Mode, Unification, _Ctxt) },
 	select_reuses_unification(Selection, Unification, GoalInfo0, GoalInfo).
 
-select_reuses(_Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
+select_reuses_2(_Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = generic_call(_, _, _, _) },
 	{ Goal = Goal0 }.
-select_reuses(_Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
+select_reuses_2(_Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = pragma_foreign_code(_, _, _, _, _, _, _) },
 	{ Goal = Goal0 }.
-select_reuses(_Selection, Goal0 - _GoalInfo, _) -->
+select_reuses_2(_Selection, Goal0 - _GoalInfo, _) -->
 	{ Goal0 = bi_implication(_, _) },
 	{ error("structure_reuse: bi_implication.\n") }.
 
-select_reuses(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
+select_reuses_2(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = if_then_else(Vars, If0, Then0, Else0, SM) },
 	selection_start_branch,
 	=(BeforeIfInfo),
-	{ select_reuses(Selection, If0, If, BeforeIfInfo, IfInfo) },
-	{ select_reuses(Selection, Then0, Then, IfInfo, ThenInfo) },
+	{ select_reuses_2(Selection, If0, If, BeforeIfInfo, IfInfo) },
+	{ select_reuses_2(Selection, Then0, Then, IfInfo, ThenInfo) },
 	selection_merge(ThenInfo),
-	{ select_reuses(Selection, Else0, Else, BeforeIfInfo, ElseInfo) },
+	{ select_reuses_2(Selection, Else0, Else, BeforeIfInfo, ElseInfo) },
 	selection_merge(ElseInfo),
 	selection_end_branch,
 	{ Goal = if_then_else(Vars, If, Then, Else, SM) }.
 
-select_reuses(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
+select_reuses_2(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = switch(Var, CanFail, Cases0, StoreMap) },
 	selection_start_branch,
 	=(InitSwitchInfo),
 	select_reuses_cases(Selection, InitSwitchInfo, Cases0, Cases),
 	{ Goal = switch(Var, CanFail, Cases, StoreMap) }.
 
-select_reuses(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
+select_reuses_2(Selection, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = some(Vars, CanRemove, SomeGoal0) },
-	select_reuses(Selection, SomeGoal0, SomeGoal),
+	select_reuses_2(Selection, SomeGoal0, SomeGoal),
 	{ Goal = some(Vars, CanRemove, SomeGoal) }.
 
-select_reuses(Selection, not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
-	select_reuses(Selection, Goal0, Goal).
+select_reuses_2(Selection, not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
+	select_reuses_2(Selection, Goal0, Goal).
 
-select_reuses(Selection, conj(Goal0s) - GoalInfo,
+select_reuses_2(Selection, conj(Goal0s) - GoalInfo,
 		conj(Goals) - GoalInfo) -->
 	select_reuses_list(Selection, Goal0s, Goals).
 
-select_reuses(Selection, disj(Goal0s, SM) - GoalInfo,
+select_reuses_2(Selection, disj(Goal0s, SM) - GoalInfo,
 		disj(Goals, SM) - GoalInfo) -->
 	selection_start_branch,
 	=(InitDisjInfo),
 	select_reuses_disj(Selection, InitDisjInfo, Goal0s, Goals).
 
-select_reuses(Selection, par_conj(Goal0s, SM) - GoalInfo,
+select_reuses_2(Selection, par_conj(Goal0s, SM) - GoalInfo,
 		par_conj(Goals, SM) - GoalInfo) -->
 	select_reuses_list(Selection, Goal0s, Goals).
 
@@ -517,7 +503,7 @@
 select_reuses_cases(_Selection, _Info0, [], []) --> selection_end_branch.
 select_reuses_cases(Selection, Info0, [Case0 | Case0s], [Case | Cases]) -->
 	{ Case0 = case(ConsId, Goal0) },
-	{ select_reuses(Selection, Goal0, Goal, Info0, Info) },
+	{ select_reuses_2(Selection, Goal0, Goal, Info0, Info) },
 	selection_merge(Info),
 	{ Case = case(ConsId, Goal) },
 	select_reuses_cases(Selection, Info0, Case0s, Cases).
@@ -527,7 +513,7 @@
 
 select_reuses_list(_Selection, [], []) --> [].
 select_reuses_list(Selection, [Goal0 | Goal0s], [Goal | Goals]) -->
-	select_reuses(Selection, Goal0, Goal),
+	select_reuses_2(Selection, Goal0, Goal),
 	select_reuses_list(Selection, Goal0s, Goals).
 
 :- pred select_reuses_disj(selection::in,
@@ -536,7 +522,7 @@
 
 select_reuses_disj(_Selection, _Info0, [], []) --> selection_end_branch.
 select_reuses_disj(Selection, Info0, [Goal0 | Goal0s], [Goal | Goals]) -->
-	{ select_reuses(Selection, Goal0, Goal, Info0, Info) },
+	{ select_reuses_2(Selection, Goal0, Goal, Info0, Info) },
 	selection_merge(Info),
 	select_reuses_disj(Selection, Info0, Goal0s, Goals).
 
@@ -715,8 +701,144 @@
 	{ Unif = simple_test(_, _) }.
 select_reuses_unification(_Selection, Unif, GoalInfo, GoalInfo) -->
 	{ Unif = complicated_unify(_, _, _) }.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- type cgc_info
+	--->	cgc_info.
+
+:- pred determine_cgc(set(prog_var)::in, hlds_goal::in, hlds_goal::out) is det.
+
+determine_cgc(ReuseVars, Goal0, Goal) :-
+	determine_cgc(ReuseVars, Goal0, Goal, cgc_info, _Info).
+
+:- pred determine_cgc(set(prog_var)::in, hlds_goal::in, hlds_goal::out,
+		cgc_info::in, cgc_info::out) is det.
+
+determine_cgc(_ReusedVars, Goal - GoalInfo, Goal - GoalInfo) -->
+	{ Goal = call(_PredId, _ProcId, _Args, _Builtin, _MaybeCtxt, _Name) }.
+
+determine_cgc(ReusedVars, Goal0 - GoalInfo0, Goal - GoalInfo) -->
+	{ Goal0 = unify(Var, Rhs, Mode, Unif0, Ctxt) },
+	determine_cgc_unification(ReusedVars, Unif0, Unif, GoalInfo0, GoalInfo),
+	{ Goal = unify(Var, Rhs, Mode, Unif, Ctxt) }.
+
+determine_cgc(_ReusedVars, Goal0 - GoalInfo, Goal - GoalInfo) -->
+	{ Goal0 = generic_call(_, _, _, _) },
+	{ Goal = Goal0 }.
+determine_cgc(_ReusedVars, Goal0 - GoalInfo, Goal - GoalInfo) -->
+	{ Goal0 = pragma_foreign_code(_, _, _, _, _, _, _) },
+	{ Goal = Goal0 }.
+determine_cgc(_ReusedVars, Goal0 - _GoalInfo, _) -->
+	{ Goal0 = bi_implication(_, _) },
+	{ error("structure_reuse: bi_implication.\n") }.
+
+determine_cgc(ReusedVars, Goal0 - GoalInfo, Goal - GoalInfo) -->
+	{ Goal0 = if_then_else(Vars, If0, Then0, Else0, SM) },
+	determine_cgc(ReusedVars, If0, If),
+	determine_cgc(ReusedVars, Then0, Then),
+	determine_cgc(ReusedVars, Else0, Else),
+	{ Goal = if_then_else(Vars, If, Then, Else, SM) }.
+
+determine_cgc(ReusedVars, Goal0 - GoalInfo, Goal - GoalInfo) -->
+	{ Goal0 = switch(Var, CanFail, Cases0, StoreMap) },
+	determine_cgc_cases(ReusedVars, Cases0, Cases),
+	{ Goal = switch(Var, CanFail, Cases, StoreMap) }.
+
+determine_cgc(ReusedVars, Goal0 - GoalInfo, Goal - GoalInfo) -->
+	{ Goal0 = some(Vars, CanRemove, SomeGoal0) },
+	determine_cgc(ReusedVars, SomeGoal0, SomeGoal),
+	{ Goal = some(Vars, CanRemove, SomeGoal) }.
+
+determine_cgc(ReusedVars, not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
+	determine_cgc(ReusedVars, Goal0, Goal).
 
-%-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------%
+determine_cgc(ReusedVars, conj(Goal0s) - GoalInfo,
+		conj(Goals) - GoalInfo) -->
+	determine_cgc_list(ReusedVars, Goal0s, Goals).
+
+determine_cgc(ReusedVars, disj(Goal0s, SM) - GoalInfo,
+		disj(Goals, SM) - GoalInfo) -->
+	determine_cgc_list(ReusedVars, Goal0s, Goals).
+
+determine_cgc(ReusedVars, par_conj(Goal0s, SM) - GoalInfo,
+		par_conj(Goals, SM) - GoalInfo) -->
+	determine_cgc_list(ReusedVars, Goal0s, Goals).
+
+:- pred determine_cgc_cases(set(prog_var)::in, list(case)::in, list(case)::out,
+		cgc_info::in, cgc_info::out) is det.
+
+determine_cgc_cases(_ReusedVars, [], []) --> [].
+determine_cgc_cases(ReusedVars, [Case0 | Case0s], [Case | Cases]) -->
+	{ Case0 = case(ConsId, Goal0) },
+	determine_cgc(ReusedVars, Goal0, Goal),
+	{ Case = case(ConsId, Goal) },
+	determine_cgc_cases(ReusedVars, Case0s, Cases).
+
+:- pred determine_cgc_list(set(prog_var)::in, hlds_goals::in, hlds_goals::out,
+		cgc_info::in, cgc_info::out) is det.
+
+determine_cgc_list(_ReusedVars, [], []) --> [].
+determine_cgc_list(ReusedVars, [Goal0 | Goal0s], [Goal | Goals]) -->
+	determine_cgc(ReusedVars, Goal0, Goal),
+	determine_cgc_list(ReusedVars, Goal0s, Goals).
+
+:- pred determine_cgc_unification(set(prog_var)::in,
+		unification::in, unification::out,
+		hlds_goal_info::in, hlds_goal_info::out,
+		cgc_info::in, cgc_info::out) is det.
+
+determine_cgc_unification(_ReusedVars, Unif, Unif, GoalInfo, GoalInfo) -->
+	{ Unif = construct(_Var, _ConsId, _Vars, _Ms, _HTC, _IsUniq, _Aditi) }.
+
+determine_cgc_unification(ReusedVars, Unif0, Unif, GoalInfo0, GoalInfo) -->
+	{ Unif0 = deconstruct(Var, ConsId, Vars, Modes, CanFail, _CanCGC) },
+
+	{ goal_info_get_reuse(GoalInfo0, ReuseInfo) },
+	{ ReuseInfo = choice(deconstruct(MaybeDies)) ->
+		(
+			MaybeDies = yes(Condition),
+			goal_info_set_reuse(GoalInfo0, reuse(cell_died),
+					GoalInfo),
+			( set__member(Var, ReusedVars) ->
+				CanCGC = no
+			;
+				% XXX Currently we only compile time gc
+				% cells which don't introduce a reuse
+				% condition on the predicate.
+				(
+					Condition = always,
+					CanCGC = yes
+				;
+					Condition = condition(_, _, _),
+					CanCGC = no
+				)
+			)
+
+		;
+			MaybeDies = no,
+			CanCGC = no,
+			goal_info_set_reuse(GoalInfo0, reuse(no_reuse),
+					GoalInfo)
+		)
+	;
+		error("determine_cgc_unification")
+	},
+	{ Unif = deconstruct(Var, ConsId, Vars, Modes, CanFail, CanCGC) }.
+
+
+determine_cgc_unification(_ReusedVars, Unif, Unif, GoalInfo, GoalInfo) -->
+	{ Unif = assign(_, _) }.
+determine_cgc_unification(_ReusedVars, Unif, Unif, GoalInfo, GoalInfo) -->
+	{ Unif = simple_test(_, _) }.
+determine_cgc_unification(_ReusedVars, Unif, Unif, GoalInfo, GoalInfo) -->
+	{ Unif = complicated_unify(_, _, _) }.
+
+
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 
 get_strategy(Strategy, ModuleInfo0, ModuleInfo) -->
 	io_lookup_string_option(structure_reuse_constraint, ConstraintStr),

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list