[m-rev.] [reuse] diff: sr_choice_graphing

Nancy Mazur Nancy.Mazur at cs.kuleuven.ac.be
Fri Jul 2 15:20:19 AEST 2004


Hi,


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


Estimated hours taken: reuse
Branches: 2

sr_choice_graphing.m:
	Document and clean. Increase the tests for a matching construction.
	Ultimately, this should lead to removing the responsability to find
	appropriate candidates for reuse in the sr_dead-phase. That phase
	should only be responsible for finding dead datastructures, and not for
	collecting information about assigning them. 


Index: sr_choice_graphing.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_choice_graphing.m,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 sr_choice_graphing.m
--- sr_choice_graphing.m	2 Jun 2004 10:30:52 -0000	1.1.2.5
+++ sr_choice_graphing.m	2 Jul 2004 05:09:37 -0000
@@ -152,59 +152,80 @@
 
 %-----------------------------------------------------------------------------%
 
-	% Type meant to keep a table of the dead cells and their
-	% possible reuses. 
-:- type values  == map(contextvar, value). 
-	
-	% Given a construction for which reuse of a dead cell would
-	% be possible, record the cons-ids the dead cell which it is 
-	% reusing might have, as well as the fields which don't need 
-	% explicit update. 
-	% XXX the cons-ids will always be at most one cons-id. There can 
-	% only be more in the case a cell dies in each of the branches
-	% of a disjunction. This is not yet supported. 
+	% In the process of choosing the most interesting
+	% deconstruction-construction combinations, we identify each
+	% deconstruction and each construction by a so called "contextvar". 
+	% This unique identification is done using the goal_path of the
+	% unification.  (the goal_path is filled by sr_direct__process_proc/7).
+:- type contextvar 
+	---> 	context(
+			pvar		:: prog_var, 
+			context		:: term__context,
+			path		:: goal_path
+		).
+
+	% To identify the reuse of a deconstructed cell by a specific
+	% construction unification, we keep track of a so called "context" of
+	% the reuse. This context consists of the identification of the
+	% construction, the cons-id of the deconstructed cell it could be set
+	% to reuse, and the type of reuse this would be. 
+	% Each construction can only reuse the cells of one specific
+	% deconstruction, hence only one cons-id (instead of a list as was kept
+	% before). 
 :- type context_reuse_var
 	---> 	context_reuse_var(
 			var		:: contextvar,
-			cons_ids	:: maybe(list(cons_id)),
-			reuse_fields	:: maybe(list(bool)),
+			cons_id		:: cons_id,
 			reuse_type	:: reuse_type
 		).
 
-	% Track extra documentation of the reuse. 
+	% The reuse-type is a basic identification of whether the cons-ids
+	% involved in the reuse are the same, what the arities of the old and
+	% new cells are, and which arguments don't have to be updated. 
 :- type reuse_type 
-	---> 	no_reuse
-	; 	reuse_type(
-			same_cons	:: bool, 
+	---> 	reuse_type(
+			same_cons	:: bool, 	
 			arity_old	:: int, 	% arity of dead cell
-			arity_new	:: int		% arity of new cell
-				% arity_diff = arity_old - arity_new
+			arity_new	:: int, 	% arity of new cell
+			reuse_fields 	:: list(bool) 	
+				% Each 'no' means that the corresponding
+				% argument within the constructed cell does not
+				% need to be updated. Note that
+				% list__length(reuse_fields) = arity_old. 
 		). 
-
+	
+	% For each deconstruction of a dead cell, we store a kind of "value"
+	% for reusing that dead cell. This value contains the reuse-condition
+	% of reusing the dead cell, the calculated best weight found for
+	% reusing that cell, the constructions that can reuse the dead cell at
+	% the given weight. Note that there can be more than one construction
+	% reusing the available cell from a deconstruction. 
+	% E.g.: 
+	% 	X => f(...), 
+	% 	( Y <= f(...) ; Y <= f(...) ). 
+	% In this case the dead cell of X can be reused for both constructions
+	% of variable Y. 
+	% Finally, a value also contains a notion of "degree", which records
+	% the number of constructions that can potentially reuse the dead cell. 
 :- type value 
 	---> 	entry( 
 			conds		:: reuse_condition, 
 			weight		:: maybe(float),   % computed value.
 			vars		:: list(context_reuse_var),
-						% variables involved 
-						% with reusing
-						% the dead var)
+					% variables involved with reusing the
+					% dead var
 			degree 		:: int
-						% keep track of how much
-						% constructions could be
-						% interested in reusing
-						% the dead var. 
+					% keep track of how much constructions
+					% could be interested in reusing the
+					% dead var. 
 		).
 
-	% Each construction/deconstruction has to be identified 
-	% uniquely. This is done using the goal_path of the unification. 
-	% (the goal_path is filled by sr_direct__process_proc/7).
-:- type contextvar 
-	---> 	context(
-			pvar		:: prog_var, 
-			context		:: term__context,
-			path		:: goal_path
-		).
+	% Finally, during the process, we build a map of deconstructions with
+	% their values. 
+:- type values  == map(contextvar, value). 
+	
+
+
 			
 
 %-----------------------------------------------------------------------------%
@@ -289,17 +310,13 @@
 		io__state::di, io__state::uo) is det.
 dump_context_reuse_var(ContextReuseVar) -->
 	{ ReuseType = ContextReuseVar ^ reuse_type },
-	(
-		{ReuseType = reuse_type(SameCons, Aold, Anew)}
-	->
-		{ ( SameCons = yes  -> S1 = "y" ; S1 = "n") },  
-		{ string__int_to_string(arity_diff(ReuseType), S2) }, 
-		{ string__int_to_string(Aold, S3) }, 
-		{ string__int_to_string(Anew, S4) }, 
-		{ string__append_list([S1,"-",S2,"-",S3,"-",S4], String) }
-	;
- 		{ String = "no" }
-	),
+	{ ReuseType = reuse_type(SameCons, Aold, Anew, 
+				_ReuseFields)}, 
+	{ ( SameCons = yes  -> S1 = "y" ; S1 = "n") },  
+	{ string__int_to_string(arity_diff(ReuseType), S2) }, 
+	{ string__int_to_string(Aold, S3) }, 
+	{ string__int_to_string(Anew, S4) }, 
+	{ string__append_list([S1,"-",S2,"-",S3,"-",S4], String) },
 	io__write_string(String).
 	
 
@@ -375,7 +392,10 @@
 	goal_info_get_reuse(Info, ReuseInfo), 
 	(
 		ReuseInfo = choice(deconstruct(yes(Condition))), 
-		Unification = deconstruct(Var, _, _, _, _, _)
+		Unification = deconstruct(Var, _, _, _, _, _),
+			% XXX this test should move to sr_dead! 
+		\+ no_tag_type(Background ^ module_info, 
+			Background ^ vartypes, Var)
 	->
 		value_init(Condition, Val0), 
 		conjunction_value_of_dead_cel(Background, Unification, 
@@ -513,51 +533,66 @@
 value_of_dead_cel_in_goal(Background, 
 		Deconstruct, Goal - Info, Val0, Value):- 
 	Goal = unify(_, _, _, Unification, _Context),
-	ModuleInfo = Background ^ module_info, 
-	Vartypes = Background ^ vartypes, 
 	(
 		Unification = construct(Var, Cons, Args, _, _, _, _),
 		Deconstruct = deconstruct(DeadVar, DeadCons, 
 					DeadArgs, _, _, _),
-		goal_info_get_reuse(Info, choice(construct(ReuseVars))), 
-		PureReuseVars = set__map(
+			% Can fail if the construction can not reuse the
+			% deconstructed cell. 
+		compute_new_value(Background, Var, DeadVar, Cons,
+				DeadCons, Args, DeadArgs, Weight, ReuseType),
+		% The construction is still looking for reuse-possibilities... 
+		goal_info_get_reuse(Info, choice(_)), 
+		
+		% XXX scope: this should be automatically satisfied, given
+		% the way continuations are used to compute the reuse value in
+		% the first place
+		(
+			goal_info_get_reuse(Info,
+				choice(construct(ReuseVars)))
+		-> 
+			PureReuseVars = set__map(
 					func(RV) = V :-
 					    ( V = RV ^ var ),
 					ReuseVars),
-		set__contains(PureReuseVars, DeadVar),
-		% XXX this should be moved to the place where the
-		% ReuseVars are computed. 
-		\+ no_tag_type(ModuleInfo, Vartypes, DeadVar)
+			( 
+				set__contains(PureReuseVars, DeadVar)
+			-> 
+				true
+			; 
+				ReuseVarsStrings = 
+					list__map(int_to_string, 
+					    list__map(var_to_int, 
+						to_sorted_list(PureReuseVars))),
+				string__append_list([
+					"(sr_choice_graphing) ", 
+					"value_of_dead_cel: ", 
+					"scoping error.\n",
+					"Dead Variable ", 
+					int_to_string(
+						var_to_int(DeadVar)),
+					" is not in the list ", 
+					" of available vars: [", 
+					join_list(", ", ReuseVarsStrings), 
+					"]. \n"], Msg), 
+				error(Msg)
+			)
+		; 
+			string__append_list([
+				"(sr_choice_graphing) ", 
+				"value_of_dead_cel: ", 
+				"reuse for construction that didn't ", 
+				"have any candidates for reuse."], Msg), 
+			error(Msg)
+		)
 	-> 
-		% if all the conditions above are met, reuse is possible
-		has_secondary_tag(ModuleInfo, Vartypes, Var, Cons, SecTag), 
-		has_secondary_tag(ModuleInfo, Vartypes, DeadVar, DeadCons, 
-				DeadSecTag), 
-		ReuseFields = already_correct_fields(SecTag, Args, 
-				DeadSecTag - DeadArgs),
 		make_contextvar(Var, Info, ContextVar), 
-		compute_new_value(Background ^ constraint, 
-			Cons, DeadCons, 
-			list__length(Args), 
-			list__length(DeadArgs), 
-			list__length(list__delete_all(ReuseFields, no)),
-			MaybeResult, ReuseType), 
-
 		ContextReuseVar = context_reuse_var(
 					ContextVar, 
-					yes([DeadCons]),
-					yes(ReuseFields), 
+					DeadCons,
 					ReuseType), 
-	
-		(
-			MaybeResult = yes(Int)
-		-> 
-			Value = entry(Val0 ^ conds, yes(float(Int)),
+		Value = entry(Val0 ^ conds, yes(float(Weight)),
 					[ContextReuseVar], 1)
-		; 
-			Value = Val0
-		)
 	; 
 		Value = Val0
 	). 
@@ -611,58 +646,65 @@
 
 	% compute_new_value(Constraint, ArityNewCell, ArityDeadCell, 
 	%	UptoDateFields, MaybeFloat).
-:- pred compute_new_value(sr_choice_util__constraint::in, 
-		cons_id::in, cons_id::in, int::in, 
-		int::in, int::in, maybe(int)::out, 
-		reuse_type::out) is det.
-
-compute_new_value(Constraint, NewCons, DeadCons, ArityNewCell, ArityDeadCell, 
-		UpToDateFields, MaybeResult, ReuseType):- 
-	DiffArity = ArityDeadCell - ArityNewCell, 
-	(
-		NewCons = DeadCons
-	-> 
-		SameCons = yes		
-	; 
-		SameCons = no	
-	), 
-	(
-		( (
+
+:- func alfa_value = int is det.
+:- func gamma_value = int is det.
+:- func beta_value = int is det.
+alfa_value = 5. 
+gamma_value = 1.
+beta_value = 1. 
+
+:- pred compute_new_value(background_info::in, 
+		prog_var::in, prog_var::in, 
+		cons_id::in, cons_id::in, 
+		list(prog_var)::in, list(prog_var)::in, 
+		int::out, reuse_type::out) is semidet.
+
+compute_new_value(Background, NewVar, DeadVar, NewCons, DeadCons, 
+		NewCellArgs, DeadCellArgs, Weight, ReuseType) :- 
+	Constraint = Background ^ constraint, 
+	ModuleInfo = Background ^ module_info, 
+	Vartypes   = Background ^ vartypes, 
+	NewArity = list__length(NewCellArgs), 
+	DeadArity = list__length(DeadCellArgs), 
+	% 1. if the new cell has arity zero, it shouldn't be allowed to reuse
+	% anything. 
+	NewArity \= 0, 
+
+	% 2. the new cell may not be bigger than the dead cell
+	NewArity =< DeadArity,
+
+	% 3. verify the reuse constraint, either same cons, or within a certain
+	% arity difference: 
+	DiffArity = DeadArity - NewArity, 
+	( NewCons = DeadCons -> SameCons = yes ; SameCons = no), 
+	( 
 			Constraint = within_n_cells_difference(N),
 			DiffArity =< N
-		)
-		; 
-		(
+	; 
 			Constraint = same_cons_id, 
 			SameCons = yes
-		) )
-	->
-		Alfa = 5, Gamma = 1, Beta = 1, 
-		( SameCons = yes -> SameConsV = 0; SameConsV = 1),
-	 	Int = ( (Alfa + Gamma) * ArityNewCell + Beta
-	 		- Gamma * (ArityNewCell - UpToDateFields)
-			- Beta * SameConsV
-			- Alfa * DiffArity ),
-	% 	Int1 = 2 * Alfa * ArityNewCell + Gamma * UpToDateFields, 
-	%	Int = Int1 - Alfa * ArityDeadCell, 
-		(
-			Int > 0
-		->
-			MaybeResult = yes(Int), 
-			ReuseType = reuse_type(SameCons, 
-				ArityDeadCell, ArityNewCell)
-			
-		; 
-			MaybeResult = no,
-			ReuseType = no_reuse
-		)	
-	;
-		MaybeResult = no,
-		ReuseType = no_reuse
-	). 
-			
-	
+	),
 
+	% 4. if all the checks are satisfied, determine the number of fields
+	% that would not need an update if the construction would use the
+	% deconstructed cell: 
+	has_secondary_tag(ModuleInfo, Vartypes, NewVar, NewCons, SecTag), 
+	has_secondary_tag(ModuleInfo, Vartypes, DeadVar, DeadCons, DeadSecTag), 
+	ReuseFields = already_correct_fields(SecTag, NewCellArgs, 
+			DeadSecTag - DeadCellArgs),
+	UpToDateFields = list__length(list__delete_all(ReuseFields, no)),
+	%
+	% Finally, compute the weight of this reuse-configuration.
+	( SameCons = yes -> SameConsV = 0; SameConsV = 1),
+	Weight = ( (alfa_value + gamma_value) * NewArity + beta_value
+	 		- gamma_value * (NewArity - UpToDateFields)
+			- beta_value * SameConsV
+			- alfa_value * DiffArity ),
+
+	Weight > 0, 
+	ReuseType = reuse_type(SameCons, DeadArity, NewArity, 
+			ReuseFields).
 
 %-----------------------------------------------------------------------------%
 
@@ -733,10 +775,9 @@
 		; 
 			NoDups = list__remove_dups(ReuseVars), 
 			NoDups = [ReuseVar], 
-			ReuseVar = context_reuse_var(_, MConsIds, 
-				MReuseFields, _),
-			MConsIds = yes(ConsIds), 
-			MReuseFields = yes(ReuseFields)
+			ReuseVar = context_reuse_var(_, ConsId, 
+				ReuseType),
+			ReuseFields = ReuseType ^ reuse_fields
 		->
 			Cond = Value ^ conds,
 			(
@@ -746,9 +787,9 @@
 				Cond = condition(_,_,_),
 				Conditional = yes
 			),
-			CellReused = cell_reused( DeadContextVar ^ pvar, 
+			CellReused = cell_reused(DeadContextVar ^ pvar, 
 					Conditional,
-					ConsIds, ReuseFields),
+					[ConsId], ReuseFields),
 			(
 				Conditional = yes, 
 				KindReuse = potential_reuse(CellReused)
@@ -931,13 +972,8 @@
 
 :- func arity_diff(reuse_type) = int. 
 arity_diff(T) = R :- 
-	( 
-		T = reuse_type(_, O, N)
-	-> 
-		R = O - N
-	;  
-		require__error("(sr_choice_graphing) arity_diff: no reuse, so no old or new arities.")
-	). 
+	T = reuse_type(_, O, N, _),
+	R = O - N.
 	
 %-----------------------------------------------------------------------------%
 	% After the selection pass, a final pass is needed to clean up


-- 
nancy.mazur at cs.kuleuven.ac.be ------------ Katholieke Universiteit Leuven -
tel: +32-16-327596 - fax: +32-16-327996 ------- Dept. of Computer Science -
--------------------------------------------------------------------------
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