[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