[m-dev.] diff: improve performance of excess assignment removal

Simon Taylor stayl at cs.mu.OZ.AU
Thu Oct 26 16:34:15 AEDT 2000



Estimated hours taken: 1.5

compiler/simplify.m:
	Improve the efficiency of excess assignment removal
	by processing all of the assignments in a conjunction
	at once. This reduces the time taken by `mmc -C make_hlds'
	by almost 10%.

Index: simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.88
diff -u -u -r1.88 simplify.m
--- simplify.m	2000/10/13 13:55:56	1.88
+++ simplify.m	2000/10/25 15:08:12
@@ -476,7 +476,9 @@
 
 simplify__goal_2(conj(Goals0), GoalInfo0, Goal, GoalInfo, Info0, Info) :-
 	simplify_info_get_instmap(Info0, InstMap0),
-	simplify__conj(Goals0, [], Goals, GoalInfo0, Info0, Info1),
+	simplify__excess_assigns_in_conj(GoalInfo0,
+		Goals0, Goals1, Info0, Info1a),
+	simplify__conj(Goals1, [], Goals, GoalInfo0, Info1a, Info1),
 	simplify_info_set_instmap(Info1, InstMap0, Info2),
 	( Goals = [] ->
 		goal_info_get_context(GoalInfo0, Context),
@@ -1561,18 +1563,11 @@
 		),
 		list__reverse(RevGoals, Goals)
 	    ;
-		simplify__excess_assigns(Goal1, ConjInfo,
-			Goals0, Goals1, RevGoals0, RevGoals1,
-			GoalNeeded, Info1, Info2),
-		( GoalNeeded = yes ->
-			simplify__conjoin_goal_and_rev_goal_list(Goal1,
-				RevGoals1, RevGoals2)
-		;
-			RevGoals2 = RevGoals1
-		),
-		simplify_info_update_instmap(Info2, Goal1, Info3),
-		simplify__conj(Goals1, RevGoals2, Goals,
-			ConjInfo, Info3, Info)
+		simplify__conjoin_goal_and_rev_goal_list(Goal1,
+			RevGoals0, RevGoals1),
+		simplify_info_update_instmap(Info1, Goal1, Info2),
+		simplify__conj(Goals0, RevGoals1, Goals,
+			ConjInfo, Info2, Info)
 	    )
 	).
 
@@ -1610,26 +1605,18 @@
 		RevGoals0, RevGoals, GoalNeeded, Info0, Info) :-
 	(
 		simplify_do_excess_assigns(Info0),
-		Goal0 = unify(_, _, _, Unif, _) - _,
-		goal_info_get_nonlocals(ConjInfo, NonLocals),
-		Unif = assign(LeftVar, RightVar),
-		( \+ set__member(LeftVar, NonLocals) ->
-			LocalVar = LeftVar, ReplacementVar = RightVar
-		; \+ set__member(RightVar, NonLocals) ->
-			LocalVar = RightVar, ReplacementVar = LeftVar
-		;
-			fail
-		)
+		goal_info_get_nonlocals(ConjInfo, ConjNonLocals),
+		map__init(Subn0),
+		goal_is_excess_assign(ConjNonLocals, Goal0, Subn0, Subn)
 	->
 		GoalNeeded = no,
-		map__init(Subn0),
-		map__det_insert(Subn0, LocalVar, ReplacementVar, Subn),
 		goal_util__rename_vars_in_goals(Goals0, no,
 			Subn, Goals),
 		goal_util__rename_vars_in_goals(RevGoals0, no,
 			Subn, RevGoals),
 		simplify_info_get_varset(Info0, VarSet0),
-		varset__delete_var(VarSet0, LocalVar, VarSet),
+		map__keys(Subn0, RemovedVars),
+		varset__delete_vars(VarSet0, RemovedVars, VarSet),
 		simplify_info_set_varset(Info0, VarSet, Info)
 	;
 		GoalNeeded = yes,
@@ -1637,6 +1624,98 @@
 		RevGoals = RevGoals0,
 		Info = Info0
 	).
+
+
+:- pred simplify__excess_assigns_in_conj(hlds_goal_info::in,
+		list(hlds_goal)::in, list(hlds_goal)::out,
+		simplify_info::in, simplify_info::out) is det.
+
+simplify__excess_assigns_in_conj(ConjInfo, Goals0, Goals,
+		Info0, Info) :-
+	( simplify_do_excess_assigns(Info0) ->
+		goal_info_get_nonlocals(ConjInfo, ConjNonLocals),
+		map__init(Subn0),
+		simplify__find_excess_assigns_in_conj(ConjNonLocals,
+			Goals0, [], RevGoals, Subn0, Subn1),
+		( map__is_empty(Subn1) ->
+			Goals = Goals0,
+			Info = Info0
+		;
+			renaming_transitive_closure(Subn1, Subn),
+			list__reverse(RevGoals, Goals1),
+			MustSub = no,
+			goal_util__rename_vars_in_goals(Goals1, MustSub,
+				Subn, Goals),
+			simplify_info_get_varset(Info0, VarSet0),
+			map__keys(Subn0, RemovedVars),
+			varset__delete_vars(VarSet0, RemovedVars, VarSet),
+			simplify_info_set_varset(Info0, VarSet, Info)
+		)
+	;
+		Goals = Goals0,
+		Info = Info0
+	).
+
+:- type var_renaming == map(prog_var, prog_var).
+
+:- pred simplify__find_excess_assigns_in_conj(set(prog_var)::in,
+	list(hlds_goal)::in, list(hlds_goal)::in, list(hlds_goal)::out,
+	var_renaming::in, var_renaming::out) is det.
+
+simplify__find_excess_assigns_in_conj(_, [], RevGoals, RevGoals,
+			Subn, Subn).
+simplify__find_excess_assigns_in_conj(ConjNonLocals, [Goal | Goals],
+			RevGoals0, RevGoals, Subn0, Subn) :-
+	( goal_is_excess_assign(ConjNonLocals, Goal, Subn0, Subn1) ->
+		RevGoals1 = RevGoals0,
+		Subn2 = Subn1
+	;
+		RevGoals1 = [Goal | RevGoals0],
+		Subn2 = Subn0
+	),
+	simplify__find_excess_assigns_in_conj(ConjNonLocals, Goals,
+		RevGoals1, RevGoals, Subn2, Subn).
+
+:- pred goal_is_excess_assign(set(prog_var)::in, hlds_goal::in,
+	var_renaming::in, var_renaming::out) is semidet.
+
+goal_is_excess_assign(ConjNonLocals, Goal0, Subn0, Subn) :-
+	Goal0 = unify(_, _, _, Unif, _) - _,
+	Unif = assign(LeftVar0, RightVar0),
+
+	%
+	% Check if we've already substituted
+	% one or both of the variables.
+	%
+	find_renamed_var(Subn0, LeftVar0, LeftVar),
+	find_renamed_var(Subn0, RightVar0, RightVar),
+	( \+ set__member(LeftVar, ConjNonLocals) ->
+		map__det_insert(Subn0, LeftVar, RightVar, Subn)
+	; \+ set__member(RightVar, ConjNonLocals) ->
+		map__det_insert(Subn0, RightVar, LeftVar, Subn)
+	;
+		fail
+	).
+
+:- pred find_renamed_var(var_renaming, prog_var, prog_var).
+:- mode find_renamed_var(in, in, out) is det.
+
+find_renamed_var(Subn, Var0, Var) :-
+	( map__search(Subn, Var0, Var1) ->
+		find_renamed_var(Subn, Var1, Var)
+	;
+		Var = Var0
+	).
+
+	% Collapse chains of renamings.
+:- pred renaming_transitive_closure(var_renaming, var_renaming).
+:- mode renaming_transitive_closure(in, out) is det.
+
+renaming_transitive_closure(VarRenaming0, VarRenaming) :-
+	map__map_values(
+		(pred(_::in, Value0::in, Value::out) is det :-
+			find_renamed_var(VarRenaming0, Value0, Value)
+		), VarRenaming0, VarRenaming).
 
 %-----------------------------------------------------------------------------%
 

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