for review: Accumulator introduction
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Sep 3 14:20:33 AEST 1998
On 25-Aug-1998, Peter David ROSS <petdr at cs.mu.OZ.AU> wrote:
>
> Add the optimization to automatically introduce accumulators.
>
> compiler/accumulator.m:
> Does the optimization.
>
> compiler/inst_match.m:
> Add a utility predicate which determines whether or not an inst
> contains a 'any' inst.
>
> compiler/mercury_compile.m:
> Call the accumulator module.
>
> compiler/mode_util.m:
> Make the prediate insts_to_mode public.
>
> compiler/options.m:
> Add the option to run the optimization.
You need to modify doc/user_guide.texi to document the new option.
> Index: mode_util.m
> ===================================================================
> RCS file: /home/staff/zs/imp/mercury/compiler/mode_util.m,v
> retrieving revision 1.111
> diff -u -r1.111 mode_util.m
> --- mode_util.m 1998/07/08 20:56:54 1.111
> +++ mode_util.m 1998/08/25 01:34:18
> @@ -94,6 +94,12 @@
> :- pred inst_lists_to_mode_list(list(inst), list(inst), list(mode)).
> :- mode inst_lists_to_mode_list(in, in, out) is det.
>
> + % insts_to_mode(InitialInst, FinalInst, Mode):
> + % Given the initial and final insts, return the mode which maps
> + % from the initial inst to the final inst.
> +:- pred insts_to_mode(inst, inst, mode).
> +:- mode insts_to_mode(in, in, out) is det.
s/the mode/a mode/
Also you should document the purpose of this predicate --
why not just use `Mode = (InitialInst -> FinalInst)'?
options.m:
> + "\t--introduce-accumulators\n",
> + "\t\tEnable the introduction of accumulators.\n",
The documentation here doesn't really explain things.
A more detailed explanation, e.g. something vaguely similar to the
following comment from accumulator.m
% Identify procedures which would become tail recursive if some of the
% output variables are accumulated and then transform them to the tail
% recursive form.
would be better.
accumulator.m:
> % Identify procedures which would become tail recursive if some of the
> % output variables are accumulated and then transform them to the tail
> % recursive form.
> %
> % Every variable mentioned is a set of variables.
> % Mode IN is one where the instantiatedness of the variable stays the
> % same, while mode OUT is one where a variable becomes more
> % instantiated.
I suggest that you add
% The transformation works according to the schema shown below.
% In this schema, ...
before "every variable mentioned ...".
> % :- pred p(T::IN, U::OUT, V::OUT, X::IN, Y::OUT) is SomeMode.
s/SomeMode/SomeDeterminism/
> % p(X, Ys, Os) -->
> % minimal(X),
> % { identity(Ys) },
> % { constant(Os) },
> % threaded.
> % p(X, Ys, Os) -->
> % decompose(X, Xh, Xr),
> % process(Xh, Hs),
> % p(X, Y0s, Os),
> % { compose(Hs, Y0s, Ys) }.
> %
> % can be transformed into
> %
> % p(X, Ys, Os) -->
> % { identity(As) },
> % { constant(Os) },
> % p'(X, As, Ys, Os).
> %
> % p'(X, As, Ys, Os) -->
> % minimal(X),
> % { Ys = As },
> % threaded.
> % p'(X, As, Ys, Os) -->
> % decompose(X, Xh, Xr),
> % process(Xh, Hs)
> % { compose(As, Hs, A1s) },
> % p'(X, A1s, Ys, Os).
> %
> % Then as long as the compose section of the predicate obeys the
> % following constraints.
Delete the word "Then".
I think it would probably be a bit clearer if you actually expand out
the DCG notation, using some explicit state variables (say S0, S1, ..., S).
> % Either
> % compose(A, B, C) <=> compose(B, A, C)
> % or
> % compose(A, B, AB), compose(AB, C, ABC) <=>
> % compose(B, C, BC), compose(A, BC, ABC)
> % identity(A), compose(A, B, C) <=> identity(A), compose(B, A, C)
> %
> % The above conditions states that the compose goal must either be
> % commutative OR if it isn't commutative, then it must be associative
> % with the base case initialising the accumulator to being the identity
> % element for the compose function.
> %
> % p(X,Ys) :-
> % identity(As),
> % p'(X, As, Ys).
> %
> % p'(X, As, Ys) :-
> % minimal(X),
> % Ys = As.
> % p'(X, As, Ys) :-
> % decompose(X, Xh, Xr),
> % process(Xh, Hs),
> % compose(Xh, As, A1s),
> % p'(Xr, A1s, Ys).
This simpler schema is missing the untransformed version.
I think it might be good to keep the simpler schema, and
to first give the simpler schema (both untransformed
and transformed versions) and then show the more general one.
> % A simple heuristic is used to ensure that the new version is more
> % efficient then the old version. The heursitic is that if a call
> % requires thats its arguments to be rearranged then we must also state
> % the set of postitions where static variables must be after the
> % rearranging. For example for append/3 the first argument must be
> % static after rearrangement.
s/heursitic/heuristic/
How does this heuristic ensure that the new version is more efficient?
What's a static variable?
> %
> % XXX In the future this phase should also transform procedures for which
> % only construction unifications remain after p' inside p'. As
> % the last call modulo constructor optimization (in lco.m) will
> % continue the transformation into a tail recursive procedure.
s/. As/, because/
[... to be continued.]
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list