[m-dev.] for review: MLDS code generator design

Zoltan Somogyi zs at cs.mu.OZ.AU
Fri Aug 6 15:22:50 AEST 1999


> %		jmp_buf buf;
> %		void success() {
> %			longjmp(buf, TRUE);
> %		}

The second arg of longjmp is an int, not a bool. It should be 1, the canonical
non-zero value, but not via the TRUE macro.

> % Code for conjunctions

You must also say what you do for empty conjunctions.

> %	model_non goal (unoptimized)
> %		<Goal, Goals>
> % 	===>
> %	{
> %		entry_func() {
> %			<Goal && succ_func()>;
> %		}
> %		succ_func() {
> %			<Goals && SUCCEED()>;
> %	 	}
> %
> %		entry_func();
> %	}
> %
> %	model_non goal (optimized):
> %		<Goal, Goals>
> % 	===>
> %	{
> %	        succ_func() {
> %			<Goals && SUCCEED()>;
> %	        }
> %
> %	        <Goal && succ_func()>;
> %	}

I don't see the point of generating the non-optimized version, and then
optimizing it. You may as well generate the optimized version first, given
that the code for doing so is trivial.

> %
> % Code for disjunctions
> %

Again you must say what you do for empty disjunctions. If I were you,
I would treat empty and nonempty disjunctions differently, so there are
three cases you must deal with:

	disj([])

	disj([Goal1, Goal2 | Goals])
	disj([Goal1])

The first is fail, the second and third are the nonlast and last disjunct
cases of a non-empty disjunction.

> %	model_det goal:
> %		<(Goal ; Goals) && SUCCEED()>

This (and others like this) would clearer if it read "model_det Goal".

> %
> % Code for if-then-else
> %

I think you also need to deal with conditions that are det. Probably
due to the extra sequencing required for ites, they are not transformed
into conjunctions.

> %	/*
> %	** XXX The following transformation does not do as good a job of GC
> %	**     as it could.  Ideally we ought to ensure that stuff used only
> %	**     in the `Else' part will be reclaimed if a GC occurs during
> %	**     the `Then' part.  But that is a bit tricky to achieve.
> %	*/
> %
> %	model_non cond:
> %		<(Cond -> Then ; Else)>
> %	===>
> %	{
> %		bool succeeded;
> %
> %		void then_func() {
> %			succeeded = TRUE;
> %			<Then>
> %		}
> %
> %		succeeded = FALSE;
> %		<Cond && then_func()>
> %		if (!succeeded) {
> %			<Else>
> %		}
> %	}

I don't think the XXX is warranted at all. At the point just before <Then>,
you can clobber (set to NULL) all variables only needed in the Else path,
and vice versa.

Apart from these, the scheme is fine. My only other piece of advice would be
not to use nested functions at all, and instead go straight for passing around
pointers to blocks of variables. Do you know of any platforms on which the
overheads of nested functions will be significantly smaller than simulating
them ourselves?

You must also beware of the "upward funarg" problem, which is keeping the
address of a nested function after the stack frame that created it has
returned. Even without higher-order code in the Mercury source being
translated, the MLDS will create closures to support nondeterminism.

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