[m-dev.] [reuse] diff: do local reuse only

Peter Ross peter.ross at miscrit.be
Thu Mar 8 04:19:32 AEDT 2001


Hi,


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


Estimated hours taken: 8
Branches: reuse

Optimize the following situation, where g and h both of reuse versions
and the types of all the variables are the same.

f(X, Y) :-
    g(X, Y0), 
    h(Y0, Y).

What we would like to do is update the non-reuse version of the f so
that it only does local reuse, ie it calls the non-reuse version of g
(because globally we might still need a reference to X) but the reuse
version of h, since the only reference to Y0 is local to this predicate.
There will still also be a full reuse version of f which can be called
provided X can be safely reused.

compiler/sr_split.m:
    Change process_goal so that it can decides whether or not to do a
    reuse action based on whether or not the reuse action is local.
    For the non-reuse version of a predicate, now keep all the reuse
    actions which are local.
    
compiler/sr_data.m:
    Record for calls and construction unifications whether this reuse
    action introduces a condition to which must be satisfied before the
    reuse version of the predicate can be called.

compiler/sr_choice.m:
    Record whether or not the construction unification introduces a
    condition.
    
compiler/sr_indirect.m:
    Record for a call whether or not the call introduces a condition.

compiler/hlds_out.m:
    Output whether a reuse call or construction unification is
    conditional on the head variables.

compiler/sr_profile_run.m:
    Update for new fields.


Index: hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.243.2.13
diff -u -r1.243.2.13 hlds_out.m
--- hlds_out.m	2001/02/07 14:29:05	1.243.2.13
+++ hlds_out.m	2001/03/07 17:01:12
@@ -1178,15 +1178,29 @@
 			->
 				io__write_string("cell just died (deconstruction).\n") 
 			;
-				{ REUSE = reuse(cell_reused(ProgVar)) }
+				{ REUSE = reuse(cell_reused(ProgVar,
+						IntroducesCondition)) }
 			->
-				io__write_string("cell ("),
+				io__write_string("cell "),
 				mercury_output_var(ProgVar, VarSet, 
 					AppendVarnums),
-				io__write_string(") just reused (construction).\n")
+				io__write_string(
+					" just reused in a construction "),
+				( { IntroducesCondition = yes } ->
+					io__write_string("conditionally.")
+				;
+					io__write_string("*unconditionally*.")
+				),
+				io__nl
 			;
-				{ REUSE = reuse(reuse_call) }
+				{ REUSE = reuse(
+					reuse_call(IntroducesCondition)) }
 			->
+				( { IntroducesCondition = yes } ->
+					io__write_string("Conditional ")
+				;
+					io__write_string("*Unconditional* ")
+				),
 				io__write_string("call to procedure with reuse.\n")
 			;
 				{ REUSE = reuse(missed_reuse_call(Causes)) } 
Index: pa_alias_as.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/pa_alias_as.m,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 pa_alias_as.m
--- pa_alias_as.m	2001/03/05 17:06:51	1.1.2.11
+++ pa_alias_as.m	2001/03/07 17:01:12
@@ -195,8 +195,8 @@
 :- func alias_limit = int. 
 :- func top_limit = int. 
 
-alias_limit = 500. % 100
-top_limit = 200.
+alias_limit = 500000. % 100
+top_limit = 200000.
 
 %-----------------------------------------------------------------------------%
 
Index: sr_choice.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_choice.m,v
retrieving revision 1.1.2.12
diff -u -r1.1.2.12 sr_choice.m
--- sr_choice.m	2001/02/07 14:30:36	1.1.2.12
+++ sr_choice.m	2001/03/07 17:01:14
@@ -50,7 +50,7 @@
 :- implementation.
 
 :- import_module hlds_data, prog_data.
-:- import_module assoc_list, int, multi_map, require, set.
+:- import_module assoc_list, bool, int, multi_map, require, set.
 
 process_goal(Strategy, Goal0, Goal, MaybeReuseConditions) :-
 	Strategy = strategy(Constraint, SelectionRule),
@@ -506,8 +506,15 @@
 	),
 	( { Candidates = [ReuseVar - ReuseCond | _] } ->
 		{ set__insert(LocalReused0, ReuseVar, LocalReused) },
+		{
+			ReuseCond = always,
+			ConditionalReuse = no
+		;
+			ReuseCond = condition(_, _, _),
+			ConditionalReuse = yes
+		},
 		{ goal_info_set_reuse(GoalInfo0,
-				reuse(cell_reused(ReuseVar)),
+				reuse(cell_reused(ReuseVar, ConditionalReuse)),
 				GoalInfo) },
 		ReuseConditions =^ reuse_conds,
 		^ reuse_conds := [ReuseCond | ReuseConditions]
Index: sr_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_data.m,v
retrieving revision 1.1.2.12
diff -u -r1.1.2.12 sr_data.m
--- sr_data.m	2001/02/07 10:19:11	1.1.2.12
+++ sr_data.m	2001/03/07 17:01:14
@@ -15,7 +15,7 @@
 :- module sr_data.
 :- interface.
 
-:- import_module map, set, std_util, list, io, term.
+:- import_module bool, map, set, std_util, list, io, term.
 :- import_module pa_alias_as, pa_datastruct.
 :- import_module sr_live.
 :- import_module hlds_pred, hlds_module, prog_data.
@@ -34,8 +34,16 @@
 :- type short_reuse_info --->
 				no_reuse 
 			; 	cell_died
-			; 	cell_reused(prog_var)
-			; 	reuse_call
+
+					% The variable we have selected
+					% for reuse and whether the
+					% reuse is conditional
+			; 	cell_reused(prog_var, bool)
+
+					% Call the reuse version of the
+					% call and wheter calling the
+					% reuse version is conditional.
+			; 	reuse_call(bool)
 			; 	missed_reuse_call(list(string)). 
 
 :- type reuse_var == pair(prog_var, reuse_condition).
Index: sr_indirect.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_indirect.m,v
retrieving revision 1.1.2.17
diff -u -r1.1.2.17 sr_indirect.m
--- sr_indirect.m	2001/02/07 14:30:37	1.1.2.17
+++ sr_indirect.m	2001/03/07 17:01:15
@@ -1,4 +1,4 @@
-				%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
 % Copyright (C) 2000-2001 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
@@ -772,8 +772,10 @@
 		->
 			indirect_reuse_pool_add( HLDS, ProcInfo,
 				Memo, LFUi, LBUi, 
-				Alias0, Pool0, Pool),
-			goal_info_set_reuse(Info0, reuse(reuse_call), Info),
+				Alias0, ConditionalReuse, Pool0, Pool),
+			goal_info_set_reuse(Info0,
+					reuse(reuse_call(ConditionalReuse)),
+					Info),
 			YesNo = yes
 		;
 			Pool = Pool0,
@@ -928,7 +930,7 @@
 		indirect_reuse_pool::out ) is det.
 :- pred indirect_reuse_pool_add( module_info::in, proc_info::in, 
 		memo_reuse::in, 
-		set(prog_var)::in, set(prog_var)::in, alias_as::in, 
+		set(prog_var)::in, set(prog_var)::in, alias_as::in, bool::out,
 		indirect_reuse_pool::in, indirect_reuse_pool::out) is det. 
 :- pred indirect_reuse_pool_add_unconditional(indirect_reuse_pool::in, 
 		indirect_reuse_pool::out) is det.
@@ -959,7 +961,7 @@
 	Pool = pool(HVS, Memo). 
 
 indirect_reuse_pool_add( HLDS, ProcInfo, MemoReuse, 	
-		LFUi, LBUi, Alias0, Pool0, Pool) :- 
+		LFUi, LBUi, Alias0, ConditionalReuse, Pool0, Pool) :- 
 
 	(
 		MemoReuse = yes(OldConditions)
@@ -977,11 +979,18 @@
 			OldConditions,
 			NewConditions0),
 		reuse_conditions_simplify(NewConditions0, NewConditions), 
+			% Does this reuse introduce any new conditions
+			% on the head variables.
+		( NewConditions = [] ->
+			ConditionalReuse = no
+		;
+			ConditionalReuse = yes
+		),
 		memo_reuse_merge(ExistingMemo, yes(NewConditions), 
 				NewMemo), 
 		Pool = pool( HVS, NewMemo )
 	;
-		Pool = Pool0
+		error("indirect_reuse_pool_add: never enter.")
 	).
 
 indirect_reuse_pool_add_unconditional( Pool0, Pool ) :- 
Index: sr_profile_run.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_profile_run.m,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 sr_profile_run.m
--- sr_profile_run.m	2001/02/07 14:30:37	1.1.2.3
+++ sr_profile_run.m	2001/03/07 17:01:15
@@ -169,7 +169,7 @@
 	goal_info_get_reuse( Info, Reuse ),
 	(
 		Reuse = reuse(ShortReuse),
-		ShortReuse = reuse_call
+		ShortReuse = reuse_call(_)
 	->
 		inc_reuse_calls( Prof1, Prof )
 	;
Index: sr_split.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_split.m,v
retrieving revision 1.1.2.8
diff -u -r1.1.2.8 sr_split.m
--- sr_split.m	2001/02/07 14:30:37	1.1.2.8
+++ sr_split.m	2001/03/07 17:01:15
@@ -37,7 +37,7 @@
 
 :- implementation.
 
-:- import_module std_util, require, list, set, map.
+:- import_module bool, std_util, require, list, set, map.
 :- import_module hlds_pred. 
 :- import_module hlds_goal, prog_data, hlds_data, prog_util. 
 :- import_module sr_data. 
@@ -84,10 +84,19 @@
 	map__lookup( ProcTable0, ProcId, ProcInfo0), 
 	proc_info_reuse_information( ProcInfo0 , Memo ), 
 	(
-		Memo = yes(_)
+		Memo = yes(Conditions)
 	->
 		proc_info_goal( ProcInfo0, Goal0), 
-		process_goal( Goal0, Goal, HLDS, _ ), 
+			% If the conditions on the reuse are empty, then
+			% we have unconditional reuse, so make sure when
+			% processing the goal we don't do any actions
+			% which would introduce a condition.
+		( Conditions = [] ->
+			LocalReuseOnly = yes
+		;
+			LocalReuseOnly = no
+		),
+		process_goal(LocalReuseOnly, Goal0, Goal, HLDS, _ ), 
 		proc_info_set_goal( ProcInfo0, Goal, ProcInfo), 
 		map__det_update( ProcTable0, ProcId, ProcInfo, ProcTable)
 	;
@@ -167,12 +176,16 @@
 			module_info_set_predicate_table(WorkingHLDS1, 
 					PredTable, WorkingHLDS2),
 
-			% reprocess the goal
-			% this has moved to an extra little pass. 
+				% Change the conditions on this version
+				% to be unconditional.  This ensures
+				% that when process_goal is run on this
+				% procedure only the reuse which is
+				% unconditional is kept.
+			proc_info_set_reuse_information(ProcInfo0,
+					yes([]), ProcInfo),
 
-			% and put a clean procedure back in place 
 			module_info_set_pred_proc_info( WorkingHLDS2,
-				PredProcId, PredInfo0, CleanProcInfo, HLDS)
+				PredProcId, PredInfo0, ProcInfo, HLDS)
 		;
 			% memo_reuse is unconditional -- perfect -- 
 			% nothing to be done! (processing the goal is
@@ -264,83 +277,106 @@
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
-:- pred process_goal(hlds_goal::in, hlds_goal::out,
+:- pred process_goal(bool::in, hlds_goal::in, hlds_goal::out,
 		module_info::in, module_info::out) is det.
 
-process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+process_goal(LocalReuseOnly, Goal0 - GoalInfo0, Goal - GoalInfo) -->
 	{ Goal0 = call(PredId0, ProcId0, Args, Builtin, MaybeContext, Name0) },
 	=(ModuleInfo),
 	{ module_info_structure_reuse_info(ModuleInfo, ReuseInfo) },
 	{ ReuseInfo = structure_reuse_info(ReuseMap) },
 	{
-		goal_info_get_reuse(GoalInfo, reuse(reuse_call)),
+		goal_info_get_reuse(GoalInfo0, Reuse),
+		Reuse = reuse(reuse_call(ConditionalReuse)),
 		map__search(ReuseMap, proc(PredId0, ProcId0), Result)
 	->
-		Result = proc(PredId, ProcId) - Name
+		( ConditionalReuse = yes, LocalReuseOnly = yes ->
+			PredId = PredId0,
+			ProcId = ProcId0,
+			Name = Name0,
+			goal_info_set_reuse(GoalInfo0, reuse(no_reuse),
+					GoalInfo)
+		;
+			Result = proc(PredId, ProcId) - Name,
+			GoalInfo = GoalInfo0
+		)
 	;
 		PredId = PredId0,
 		ProcId = ProcId0,
-		Name = Name0
+		Name = Name0,
+		GoalInfo = GoalInfo0
 	},
 	{ Goal = call(PredId, ProcId, Args, Builtin, MaybeContext, Name) }.
 
-process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+process_goal(LocalReuseOnly, Goal0 - GoalInfo0, Goal - GoalInfo) -->
 	{ Goal0 = unify(_Var, _Rhs, _Mode, _Unification0, _Ctxt) },
+	{
+		goal_info_get_reuse(GoalInfo0, Reuse),
+		Reuse = reuse(cell_reused(_ReuseVar, ConditionalReuse)),
+		ConditionalReuse = yes,
+		LocalReuseOnly = yes
+	->
+		goal_info_set_reuse(GoalInfo0, reuse(no_reuse), GoalInfo)
+	;
+		GoalInfo = GoalInfo0
+	},
 	{ Goal = Goal0 }.
-process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+process_goal(_, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = generic_call(_, _, _, _) },
 	{ Goal = Goal0 }.
-process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+process_goal(_, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = pragma_foreign_code(_, _, _, _, _, _, _) },
 	{ Goal = Goal0 }.
-process_goal(Goal0 - _GoalInfo, _) -->
+process_goal(_, Goal0 - _GoalInfo, _) -->
 	{ Goal0 = bi_implication(_, _) },
 	{ error("structure_reuse: bi_implication.\n") }.
 
-process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+process_goal(LocalReuseOnly, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = if_then_else(Vars, If0, Then0, Else0, SM) },
-	process_goal(If0, If),
-	process_goal(Then0, Then),
-	process_goal(Else0, Else),
+	process_goal(LocalReuseOnly, If0, If),
+	process_goal(LocalReuseOnly, Then0, Then),
+	process_goal(LocalReuseOnly, Else0, Else),
 	{ Goal = if_then_else(Vars, If, Then, Else, SM) }.
 
-process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+process_goal(LocalReuseOnly, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = switch(Var, CanFail, Cases0, StoreMap) },
-	process_goal_cases(Cases0, Cases),
+	process_goal_cases(LocalReuseOnly, Cases0, Cases),
 	{ Goal = switch(Var, CanFail, Cases, StoreMap) }.
 
-process_goal(Goal0 - GoalInfo, Goal - GoalInfo) -->
+process_goal(LocalReuseOnly, Goal0 - GoalInfo, Goal - GoalInfo) -->
 	{ Goal0 = some(Vars, CanRemove, SomeGoal0) },
-	process_goal(SomeGoal0, SomeGoal),
+	process_goal(LocalReuseOnly, SomeGoal0, SomeGoal),
 	{ Goal = some(Vars, CanRemove, SomeGoal) }.
 
-process_goal(not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
-	process_goal(Goal0, Goal).
-process_goal(conj(Goal0s) - GoalInfo, conj(Goals) - GoalInfo) -->
-	process_goal_list(Goal0s, Goals).
-process_goal(disj(Goal0s, SM) - GoalInfo, disj(Goals, SM) - GoalInfo) -->
-	process_goal_list(Goal0s, Goals).
-process_goal(par_conj(Goal0s, SM) - GoalInfo,
+process_goal(LocalReuseOnly, not(Goal0) - GoalInfo, not(Goal) - GoalInfo) -->
+	process_goal(LocalReuseOnly, Goal0, Goal).
+process_goal(LocalReuseOnly, conj(Goal0s) - GoalInfo,
+		conj(Goals) - GoalInfo) -->
+	process_goal_list(LocalReuseOnly, Goal0s, Goals).
+process_goal(LocalReuseOnly, disj(Goal0s, SM) - GoalInfo,
+		disj(Goals, SM) - GoalInfo) -->
+	process_goal_list(LocalReuseOnly, Goal0s, Goals).
+process_goal(LocalReuseOnly, par_conj(Goal0s, SM) - GoalInfo,
 		par_conj(Goals, SM) - GoalInfo) -->
-	process_goal_list(Goal0s, Goals).
+	process_goal_list(LocalReuseOnly, Goal0s, Goals).
 
-:- pred process_goal_cases(list(case)::in, list(case)::out,
+:- pred process_goal_cases(bool::in, list(case)::in, list(case)::out,
 		module_info::in, module_info::out) is det.
 
-process_goal_cases([], []) --> [].
-process_goal_cases([Case0 | Case0s], [Case | Cases]) -->
+process_goal_cases(_, [], []) --> [].
+process_goal_cases(LocalReuseOnly, [Case0 | Case0s], [Case | Cases]) -->
 	{ Case0 = case(ConsId, Goal0) },
-	process_goal(Goal0, Goal),
+	process_goal(LocalReuseOnly, Goal0, Goal),
 	{ Case = case(ConsId, Goal) },
-	process_goal_cases(Case0s, Cases).
+	process_goal_cases(LocalReuseOnly, Case0s, Cases).
 
-:- pred process_goal_list(hlds_goals::in, hlds_goals::out,
+:- pred process_goal_list(bool::in, hlds_goals::in, hlds_goals::out,
 		module_info::in, module_info::out) is det.
 
-process_goal_list([], []) --> [].
-process_goal_list([Goal0 | Goal0s], [Goal | Goals]) -->
-	process_goal(Goal0, Goal),
-	process_goal_list(Goal0s, Goals).
+process_goal_list(_, [], []) --> [].
+process_goal_list(LocalReuseOnly, [Goal0 | Goal0s], [Goal | Goals]) -->
+	process_goal(LocalReuseOnly, Goal0, Goal),
+	process_goal_list(LocalReuseOnly, Goal0s, Goals).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

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