[m-dev.] for review: if-then-else and acc introduction

Peter Ross petdr at cs.mu.OZ.AU
Tue Jun 27 01:09:12 AEST 2000


Hi,

For Simon to review.

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


Estimated hours taken: 4

Introduce accumulators into predicates which have if-then-elses and
disjunctions.

mercury/compiler/accumulator.m:
    Introduce accumulators into predicates which have if-then-elses and
    disjunctions.
    
mercury/compiler/options.m:
    Add the --introduce-accumulators option at -O3.

tests/general/accumulator/Mmakefile:
    The tests no longer require that unused arg elimination needs to be
    turned off.
    Add the two new tests.

tests/general/accumulator/func.m:
tests/general/accumulator/func.exp:
    Add a test case, which makes sure that functions can have
    accumulators introduced.

tests/general/accumulator/ite.m:
tests/general/accumulator/ite.exp:
    Add a test case for if-then-elses.

tests/general/accumulator/runtests:
    Modify the runtests script so that we cut out line number
    information from the predicate names.  This should mean that the
    INTRODUCED file should change less often.

tests/general/accumulator/INTRODUCED:
    Add the two new tests results, and cut the line numbers out of all
    the old results.

Index: update/compiler/accumulator.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/accumulator.m,v
retrieving revision 1.10
diff -u -r1.10 accumulator.m
--- update/compiler/accumulator.m	2000/04/12 09:48:15	1.10
+++ update/compiler/accumulator.m	2000/06/26 14:36:01
@@ -338,9 +338,10 @@
 
 	standardize(Goal0, Goal),
 
-	identify_goal_type(PredId, ProcId, Goal, TopLevel, Base, Rec),
+	identify_goal_type(PredId, ProcId, Goal, InitialInstMap,
+			TopLevel, Base, BaseInstMap, Rec, RecInstMap),
 
-	C = initialize_goal_store(Rec, Base, InitialInstMap),
+	C = initialize_goal_store(Rec, RecInstMap, Base, BaseInstMap),
 
 	identify_recursive_calls(PredId, ProcId, C, RecCallIds),
 
@@ -444,9 +445,11 @@
 	% transformation doesn't depend on what is in the base case.
 	%
 :- pred identify_goal_type(pred_id::in, proc_id::in, hlds_goal::in,
-		top_level::out, hlds_goals::out, hlds_goals::out) is semidet.
+		instmap::in, top_level::out, hlds_goals::out, instmap::out,
+		hlds_goals::out, instmap::out) is semidet.
 
-identify_goal_type(PredId, ProcId, Goal, Type, Base, Rec) :-
+identify_goal_type(PredId, ProcId, Goal, InitialInstMap,
+		Type, Base, BaseInstMap, Rec, RecInstMap) :-
 	(
 		Goal = switch(_Var, _CanFail, Cases, _StoreMap) - _GoalInfo,
 		Cases = [case(_IdA, GoalA), case(_IdB, GoalB)],
@@ -467,6 +470,64 @@
 			Rec = GoalBList
 		;
 			fail
+		),
+		BaseInstMap = InitialInstMap,
+		RecInstMap = InitialInstMap
+	;
+		Goal = disj(Goals, _StoreMap) - _GoalInfo,
+		Goals = [GoalA, GoalB],
+		goal_to_conj_list(GoalA, GoalAList),
+		goal_to_conj_list(GoalB, GoalBList)
+	->
+		(
+			is_recursive_case(GoalAList, proc(PredId, ProcId))
+		->
+			Type = disj_rec_base,
+			Base = GoalBList,
+			Rec = GoalAList
+		;
+			is_recursive_case(GoalBList, proc(PredId, ProcId))
+		->
+			Type = disj_base_rec,
+			Base = GoalAList,
+			Rec = GoalBList
+		;
+			fail
+		),
+		BaseInstMap = InitialInstMap,
+		RecInstMap = InitialInstMap
+	;
+		Goal = if_then_else(_Vars, If, Then, Else, _StoreMap) -
+				_GoalInfo,
+
+		If = _IfGoal - IfGoalInfo,
+		goal_info_get_instmap_delta(IfGoalInfo, IfInstMapDelta),
+
+		goal_to_conj_list(Then, GoalAList),
+		goal_to_conj_list(Else, GoalBList)
+	->
+		(
+			is_recursive_case(GoalAList, proc(PredId, ProcId))
+		->
+			Type = ite_rec_base,
+			Base = GoalBList,
+			Rec = GoalAList,
+
+			BaseInstMap = InitialInstMap,
+			instmap__apply_instmap_delta(InitialInstMap,
+					IfInstMapDelta, RecInstMap)
+		;
+			is_recursive_case(GoalBList, proc(PredId, ProcId))
+		->
+			Type = ite_base_rec,
+			Base = GoalAList,
+			Rec = GoalBList,
+
+			RecInstMap = InitialInstMap,
+			instmap__apply_instmap_delta(InitialInstMap,
+					IfInstMapDelta, BaseInstMap)
+		;
+			fail
 		)
 	;
 		fail
@@ -501,14 +562,15 @@
 	%
 	% Initialise the goal_store, which will hold the C_{a,b} goals.
 	%
-:- func initialize_goal_store(hlds_goals, hlds_goals, instmap) = goal_store.
+:- func initialize_goal_store(hlds_goals, instmap,
+		hlds_goals, instmap) = goal_store.
 
-initialize_goal_store(Rec, Base, InitialInstMap) = C :-
+initialize_goal_store(Rec, RecInstMap, Base, BaseInstMap) = C :-
 	goal_store__init(C0),
-	list__foldl(store(rec), Rec, store_info(1, InitialInstMap, C0), 
+	list__foldl(store(rec), Rec, store_info(1, RecInstMap, C0), 
 			store_info(_, _, C1)),
 	list__foldl(store(base), Base,
-			store_info(1, InitialInstMap, C1), 
+			store_info(1, BaseInstMap, C1), 
 			store_info(_, _, C)).
 
 	%
@@ -1522,7 +1584,12 @@
 	Substs = substs(AccVarSubst, _RecCallSubst, _AssocCallSubst,
 			_UpdateSubst),
 	list__map(map__lookup(AccVarSubst), Accs0, Accs),
-	HeadVars = HeadVars0 `append` Accs,
+
+		% We place the extra accumulator variables at the start,
+		% because placing them at the end breaks the convention
+		% that the last variable of a function is the output
+		% variable.
+	HeadVars = Accs `append` HeadVars0,
 
 		% XXX we don't want to use the inst of the var as it can
 		% be more specific than it should be. ie int_const(1)
@@ -1532,7 +1599,7 @@
 	Inst = ground(shared, no),
 	inst_lists_to_mode_list([Inst], [Inst], Mode),
 	list__duplicate(list__length(Accs), list__det_head(Mode), AccModes),
-	HeadModes = HeadModes0 `append` AccModes,
+	HeadModes = AccModes `append` HeadModes0,
 
 	list__map(map__lookup(VarTypes), Accs, AccTypes),
 
@@ -1570,7 +1637,7 @@
 	term__context_line(Context, Line),
 	Counter = 0,
 
-	list__append(Types0, NewTypes, Types),
+	Types = NewTypes `append` Types0,
 
 	make_pred_name_with_context(ModuleName, "AccFrom", PredOrFunc, Name,
 		Line, Counter, SymName),
@@ -1623,7 +1690,7 @@
 
 create_acc_call(OrigCall, Accs, AccPredId, AccProcId, AccName) = Call :-
 	OrigCall = call(_PredId, _ProcId, Args, Builtin, Context, _Name) - GI,
-	Call = call(AccPredId, AccProcId, Args `append` Accs,
+	Call = call(AccPredId, AccProcId, Accs `append` Args,
 			Builtin, Context, AccName) - GI.
 
 	%
Index: update/compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.281
diff -u -r1.281 options.m
--- update/compiler/options.m	2000/05/24 05:18:08	1.281
+++ update/compiler/options.m	2000/06/26 14:36:10
@@ -1346,6 +1346,7 @@
 	optimize_higher_order	-	bool(yes),
 	deforestation		-	bool(yes),
 	constant_propagation	-	bool(yes),
+	introduce_accumulators	-	bool(yes),
 	optimize_repeat		-	int(4)
 ]).
 
Index: tests/general/accumulator/INTRODUCED
===================================================================
RCS file: /home/mercury1/repository/tests/general/accumulator/INTRODUCED,v
retrieving revision 1.2
diff -u -r1.2 INTRODUCED
--- tests/general/accumulator/INTRODUCED	2000/04/12 09:45:30	1.2
+++ tests/general/accumulator/INTRODUCED	2000/06/26 14:36:22
@@ -1,9 +1,12 @@
-	% mode  0 `base:AccFrom__pred__p__23__0/4' (det):
-	% mode  0 `call_in_base:AccFrom__pred__l__23__0/4' (det):
-	% mode  0 `chain:AccFrom__pred__pa__39__0/4' (det):
-	% mode  0 `construct:AccFrom__pred__p2__46__0/5' (det):
-	% mode  0 `dcg:AccFrom__pred__p__38__0/7' (det):
-	% mode  0 `disj:AccFrom__pred__p__47__0/3' (multi):
-	% mode  0 `identity:AccFrom__pred__r__25__0/4' (det):
-	% mode  0 `inter:AccFrom__pred__rl__26__0/6' (det):
-	% mode  0 `swap:AccFrom__pred__rev__24__0/4' (det):
+	% mode  0 `base:AccFrom__pred__p/4' (det):
+	% mode  0 `call_in_base:AccFrom__pred__l/4' (det):
+	% mode  0 `chain:AccFrom__pred__pa/4' (det):
+	% mode  0 `construct:AccFrom__pred__p2/5' (det):
+	% mode  0 `dcg:AccFrom__pred__p/7' (det):
+	% mode  0 `disj:AccFrom__pred__p/3' (multi):
+	% mode  0 `func:AccFrom__func__sumlist/2' (det):
+	% mode  0 `identity:AccFrom__pred__r/4' (det):
+	% mode  0 `inter:AccFrom__pred__rl/6' (det):
+	% mode  0 `ite:AccFrom__func__factorial/2' (det):
+	% mode  0 `ite:AccFrom__pred__sort_of_factorial/3' (det):
+	% mode  0 `swap:AccFrom__pred__rev/4' (det):
Index: tests/general/accumulator/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/general/accumulator/Mmakefile,v
retrieving revision 1.11
diff -u -r1.11 Mmakefile
--- tests/general/accumulator/Mmakefile	2000/04/12 09:45:31	1.11
+++ tests/general/accumulator/Mmakefile	2000/06/26 14:36:22
@@ -24,10 +24,12 @@
 		deconstruct	\
 		dcg		\
 		disj		\
+		func		\
 		highorder	\
 		heuristic	\
 		identity	\
 		inter		\
+		ite		\
 		nonrec		\
 		out_to_in	\
 		qsort		\
@@ -39,7 +41,7 @@
 		--intermodule-optimization
 
 	# Optimizations to turn off/on.
-OPT_FLAGS = --no-optimize-unused-args --trace-optimized
+OPT_FLAGS = --trace-optimized
 
 	# Ensure that the accumulator introduction flags are passed
 	# after EXTRA_MCFLAGS, so that we can override things set in
Index: tests/general/accumulator/func.exp
===================================================================
RCS file: func.exp
diff -N func.exp
--- /dev/null	Wed May 28 10:49:58 1997
+++ func.exp	Tue Jun 27 00:36:22 2000
@@ -0,0 +1 @@
+sumlist: 18
Index: tests/general/accumulator/func.m
===================================================================
RCS file: func.m
diff -N func.m
--- /dev/null	Wed May 28 10:49:58 1997
+++ func.m	Tue Jun 27 00:36:22 2000
@@ -0,0 +1,23 @@
+	% Test that accumulators are introduced into functions.
+:- module (func).
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module list, int.
+
+main -->
+	io__write_string("sumlist: "),
+	{ Sum = sumlist([5,6,7]) },
+	io__write(Sum),
+	io__nl.
+
+:- func sumlist(list(int)) = int.
+
+sumlist([]) = 0.
+sumlist([H|T]) = H + sumlist(T).
Index: tests/general/accumulator/ite.exp
===================================================================
RCS file: ite.exp
diff -N ite.exp
--- /dev/null	Wed May 28 10:49:58 1997
+++ ite.exp	Tue Jun 27 00:36:22 2000
@@ -0,0 +1,2 @@
+factorial: 5040
+sort_of_factorial: 48
Index: tests/general/accumulator/ite.m
===================================================================
RCS file: ite.m
diff -N ite.m
--- /dev/null	Wed May 28 10:49:58 1997
+++ ite.m	Tue Jun 27 00:36:22 2000
@@ -0,0 +1,41 @@
+	% Tests that if-then-elses are handled correctly.
+:- module ite.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module int.
+
+main -->
+	io__write_string("factorial: "),
+	{ Factorial = factorial(7) },
+	io__write(Factorial),
+	io__nl,
+	io__write_string("sort_of_factorial: "),
+	{ sort_of_factorial(3, Factorial2) },
+	io__write(Factorial2),
+	io__nl.
+
+:- func factorial(int) = int.
+
+factorial(Num)
+	= ( Num = 0 -> 1 ; Num * factorial(Num - 1)).
+
+:- pred sort_of_factorial(int, int).
+
+	% Here we bind a value in the If goals and use it in the Then
+	% goals, in an attempt to confuse the compiler.
+sort_of_factorial(Num, Fac) :-
+	( 
+		(Num \= 0, X = 2)
+	->
+		sort_of_factorial(Num - 1, Fac0),
+		Fac = X * Num * Fac0
+	;
+		Fac = 1
+	).
Index: tests/general/accumulator/runtests
===================================================================
RCS file: /home/mercury1/repository/tests/general/accumulator/runtests,v
retrieving revision 1.8
diff -u -r1.8 runtests
--- tests/general/accumulator/runtests	2000/02/21 01:31:35	1.8
+++ tests/general/accumulator/runtests	2000/06/26 14:36:22
@@ -22,8 +22,9 @@
 cat *.res > .allres
 if test ! -s .allres -a "$checkstatus" = 0
 then
-    grep -h "% mode.*AccFrom" *hlds*acc* | sed -e 's/number//' \
-        | sed -e 's/ of predicate//g' > I.$$
+    grep -h "% mode.*AccFrom" *hlds*acc* | \
+   	 sed -e 's/number//' -e 's/ of predicate//' -e 's/ of function//' \
+	 -e 's,__[0-9]*__[0-9]*/,/,' > I.$$
     diff -u INTRODUCED I.$$ > INTRODUCED.diff
     rm -f I.$$
 

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