[m-dev.] for review: improvements/bug fixes for simplify.m

Simon Taylor stayl at cs.mu.OZ.AU
Tue Oct 26 12:10:05 AEST 1999



Estimated hours taken: 1

compiler/simplify.m:
	Remove unnecessary explicit quantification goals before working
	out whether a goal can cause a stack flush.

	Don't increase the non-locals set of an explicit quantification
	goal through common structure elimination because that could change
	the determinism.

	Don't optimize a singleton switch into a test followed
	by the case goal if the constructor being tested against
	is existentially quantified. This is necessary because
	the code to produce the test uses type_util__get_cons_id_arg_types,
	which does not correctly handle the existentially quantified
	type variables or the type-infos for those type variables.


Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.73
diff -u -u -r1.73 simplify.m
--- simplify.m	1999/10/25 03:49:38	1.73
+++ simplify.m	1999/10/26 01:56:48
@@ -417,12 +417,23 @@
 		Goal1 = Goal0,
 		Info3 = Info0
 	),
-	simplify_info_maybe_clear_structs(before, Goal1, Info3, Info4),
-	Goal1 = GoalExpr1 - GoalInfo1,
-	simplify__goal_2(GoalExpr1, GoalInfo1, Goal, GoalInfo2, Info4, Info5),
-	simplify_info_maybe_clear_structs(after, Goal - GoalInfo2,
+
+	%
+	% Remove unnecessary explicit quantifications before working
+	% out whether the goal can cause a stack flush.
+	%
+	( Goal1 = some(SomeVars, CanRemove, SomeGoal1) - GoalInfo1 ->
+		simplify__nested_somes(CanRemove, SomeVars, SomeGoal1,
+			GoalInfo1, Goal2)
+	;
+		Goal2 = Goal1	
+	),
+	simplify_info_maybe_clear_structs(before, Goal2, Info3, Info4),
+	Goal2 = GoalExpr2 - GoalInfo2,
+	simplify__goal_2(GoalExpr2, GoalInfo2, Goal, GoalInfo3, Info4, Info5),
+	simplify_info_maybe_clear_structs(after, Goal - GoalInfo3,
 		Info5, Info6),
-	simplify__enforce_invariant(GoalInfo2, GoalInfo, Info6, Info).
+	simplify__enforce_invariant(GoalInfo3, GoalInfo, Info6, Info).
 
 :- pred simplify__enforce_invariant(hlds_goal_info, hlds_goal_info,
 		simplify_info, simplify_info).
@@ -571,9 +582,33 @@
 		% a possibly can_fail unification with the functor on the front.
 		cons_id_arity(ConsId, Arity),
 		(
-			SwitchCanFail = can_fail,
-			MaybeConsIds \= yes([ConsId])
+		    SwitchCanFail = can_fail,
+		    MaybeConsIds \= yes([ConsId])
 		->
+			%
+			% Don't optimize in the case of an existentially
+			% typed constructor because currently 
+			% simplify__create_test_unification does not
+			% handle the existential type variables
+			% in the types of the constructor arguments
+			% or their type-infos.
+			%
+		    simplify_info_get_var_types(Info1, VarTypes1),
+		    map__lookup(VarTypes1, Var, Type),
+		    simplify_info_get_module_info(Info1, ModuleInfo1),
+		    ( 
+			type_util__get_existq_cons_defn(ModuleInfo1,
+					Type, ConsId, _)
+		    ->
+		    	Goal = switch(Var, SwitchCanFail, Cases, SM),
+			goal_info_get_nonlocals(GoalInfo0, NonLocals),
+			merge_instmap_deltas(InstMap0, NonLocals, InstMaps,
+				NewDelta, ModuleInfo1, ModuleInfo2),
+			simplify_info_set_module_info(Info1,
+				ModuleInfo2, Info4),
+			goal_info_set_instmap_delta(GoalInfo0,
+				NewDelta, GoalInfo)
+		    ;
 			simplify__create_test_unification(Var, ConsId, Arity,
 				UnifyGoal, Info1, Info2),
 
@@ -587,11 +622,9 @@
 			set__insert(NonLocals0, Var, NonLocals),
 			goal_info_get_instmap_delta(GoalInfo0, InstMapDelta0),
 			simplify_info_get_instmap(Info2, InstMap),
-			simplify_info_get_var_types(Info2, VarTypes),
-			map__lookup(VarTypes, Var, Type),
 			instmap_delta_bind_var_to_functor(Var, Type, ConsId, 	
 				InstMap, InstMapDelta0, InstMapDelta, 
-				ModuleInfo0, ModuleInfo),
+				ModuleInfo1, ModuleInfo),
 			simplify_info_set_module_info(Info2, 
 				ModuleInfo, Info3),	
 			goal_info_get_determinism(GoalInfo0, CaseDetism),
@@ -602,11 +635,12 @@
 			simplify_info_set_requantify(Info3, Info4),
 			Goal = conj(GoalList),
 			GoalInfo = CombinedGoalInfo
+		    )
 		;
-			% The var can only be bound to this cons_id, so
-			% a test is unnecessary.
-			SingleGoal = Goal - GoalInfo,
-			Info4 = Info1
+		    % The var can only be bound to this cons_id, so
+		    % a test is unnecessary.
+		    SingleGoal = Goal - GoalInfo,
+		    Info4 = Info1
 		),
 		pd_cost__eliminate_switch(CostDelta),
 		simplify_info_incr_cost_delta(Info4, CostDelta, Info)
@@ -1027,23 +1061,18 @@
 	).
 
 simplify__goal_2(some(Vars1, CanRemove0, Goal1), SomeInfo,
-		Goal, GoalInfo, Info0, Info) :-
-	simplify__goal(Goal1, Goal2, Info0, Info),
-	simplify__nested_somes(CanRemove0, Vars1, Goal2,
-		CanRemove, Vars, Goal3),
-	Goal3 = GoalExpr3 - GoalInfo3,
-	(
-		goal_info_get_determinism(GoalInfo3, Detism),
-		goal_info_get_determinism(SomeInfo, Detism),
-		CanRemove = can_remove
-	->
-		% If the inner and outer detisms match the `some'
-		% is unnecessary.
-		Goal = GoalExpr3,
-		GoalInfo = GoalInfo3
+		GoalExpr, GoalInfo, Info0, Info) :-
+	simplify_info_get_common_info(Info0, Common),
+	simplify__goal(Goal1, Goal2, Info0, Info1),
+	simplify__nested_somes(CanRemove0, Vars1, Goal2, SomeInfo, Goal),
+	Goal = GoalExpr - GoalInfo,
+	( Goal = some(_, _, _) - _ ->
+		% Don't increase the set of non-locals of a goal within
+		% a commit through common structure elimination because
+		% that may change the determinism.
+		simplify_info_set_common_info(Info1, Common, Info)
 	;
-		Goal = some(Vars, CanRemove, Goal3),
-		GoalInfo = SomeInfo
+		Info = Info1
 	).
 
 simplify__goal_2(Goal0, GoalInfo, Goal, GoalInfo, Info0, Info) :-
@@ -1300,10 +1329,29 @@
 
 	% replace nested `some's with a single `some',
 :- pred simplify__nested_somes(can_remove::in, list(prog_var)::in,
+		hlds_goal::in, hlds_goal_info::in, hlds_goal::out) is det.
+
+simplify__nested_somes(CanRemove0, Vars1, Goal0, OrigGoalInfo, Goal) :-
+	simplify__nested_somes_2(CanRemove0, Vars1, Goal0,
+		CanRemove, Vars, Goal1),
+	Goal1 = GoalExpr1 - GoalInfo1,
+	(
+		goal_info_get_determinism(GoalInfo1, Detism),
+		goal_info_get_determinism(OrigGoalInfo, Detism),
+		CanRemove = can_remove
+	->
+		% If the inner and outer detisms match the `some'
+		% is unnecessary.
+		Goal = GoalExpr1 - GoalInfo1
+	;
+		Goal = some(Vars, CanRemove, Goal1) - OrigGoalInfo
+	).
+
+:- pred simplify__nested_somes_2(can_remove::in, list(prog_var)::in,
 		hlds_goal::in, can_remove::out, list(prog_var)::out,
 		hlds_goal::out) is det.
 
-simplify__nested_somes(CanRemove0, Vars0, Goal0, CanRemove, Vars, Goal) :-
+simplify__nested_somes_2(CanRemove0, Vars0, Goal0, CanRemove, Vars, Goal) :-
 	( Goal0 = some(Vars1, CanRemove1, Goal1) - _ ->
 		(
 			( CanRemove0 = cannot_remove
@@ -1315,7 +1363,7 @@
 			CanRemove2 = can_remove
 		),
 		list__append(Vars0, Vars1, Vars2),
-		simplify__nested_somes(CanRemove2, Vars2, Goal1,
+		simplify__nested_somes_2(CanRemove2, Vars2, Goal1,
 			CanRemove, Vars, Goal)
 	;
 		CanRemove = CanRemove0,
--------------------------------------------------------------------------
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