[m-rev.] for review: heap reclamation on failure for MLDS back-end

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Nov 23 07:03:32 AEDT 2001


On 22-Nov-2001, Peter Ross <peter.ross at miscrit.be> wrote:
> On Fri, Nov 23, 2001 at 02:51:55AM +1100, Fergus Henderson wrote:
> > +%-----------------------------------------------------------------------------%
> > +
> > +% XXX check goal_infos for correctness
>
> Have you checked the goal_infos for correctness? ;)

Nope.

> > +goal_expr_add_heap_ops(not(InnerGoal), OuterGoalInfo, Goal) -->
> > +	%
> > +	% We handle negations by converting them into if-then-elses:
> > +	%	not(G)  ===>  (if G then fail else true)
> > +	%
> > +	{ goal_info_get_context(OuterGoalInfo, Context) },
> > +	{ InnerGoal = _ - InnerGoalInfo },
> > +	{ goal_info_get_determinism(InnerGoalInfo, Determinism) },
> > +	{ determinism_components(Determinism, _CanFail, NumSolns) },
> > +	{ true_goal(Context, True) },
> > +	{ fail_goal(Context, Fail) },
> > +	{ map__init(SM) },
> > +	{ NumSolns = at_most_zero ->
> > +		% The "then" part of the if-then-else will be unreachable,
> > +		% but to preserve the invariants that the MLDS back-end
> > +		% relies on, we need to make sure that it can't fail.
> > +		% So we use `true' rather than `fail' for the "then" part.
> > +		NewOuterGoal = if_then_else([], InnerGoal, True, True, SM)
> > +	;
> > +		NewOuterGoal = if_then_else([], InnerGoal, Fail, True, SM)
> > +	},
> > +	goal_expr_add_heap_ops(NewOuterGoal, OuterGoalInfo, Goal).
> 
> Inside the then part I think it would be better to throw an exception.

That's probably a good idea.
Shall do.

> > +goal_expr_add_heap_ops(if_then_else(A, Cond0, Then0, Else0, E), GoalInfo,
> > +		Goal - GoalInfo) -->
> > +	goal_add_heap_ops(Cond0, Cond),
> > +	goal_add_heap_ops(Then0, Then),
> > +	goal_add_heap_ops(Else0, Else1),
> > +	%
> > +	% Save the heap pointer so that we can
> > +	% restore it if the condition fails.
> > +	%
> > +	new_saved_hp_var(SavedHeapPointerVar),
> > +	{ goal_info_get_context(GoalInfo, Context) },
> > +	gen_mark_hp(SavedHeapPointerVar, Context, MarkHeapPointerGoal),
> > +	%
> > +	% Generate code to restore the heap pointer,
> > +	% and insert that code at the start of the Else branch.
> > +	%
> > +	gen_restore_hp(SavedHeapPointerVar, Context, RestoreHeapPointerGoal),
> > +	{ Else1 = _ - Else1GoalInfo },
> > +	{ Else = conj([RestoreHeapPointerGoal, Else1]) - Else1GoalInfo },
> > +	{ IfThenElse = if_then_else(A, Cond, Then, Else, E) - GoalInfo },
> > +	{ Goal = conj([MarkHeapPointerGoal, IfThenElse]) }.
>
> Isn't it a condition of the HLDS that all the conjunctions have been
> flattened?

Only before mode analysis, according to hlds_goal.m:

 |     % Note: conjunctions must be fully flattened before
 |     % mode analysis.  As a general rule, it is a good idea
 |     % to keep them flattened.

However, I can easily keep it flattened here, so I will.

> > +goal_expr_add_heap_ops(PragmaForeign, GoalInfo, Goal) -->
> > +	{ PragmaForeign = foreign_proc(_,_,_,_,_,_,Impl) },
> > +	( { Impl = nondet(_,_,_,_,_,_,_,_,_) } ->
> > +		% XXX Implementing heap reclamation for nondet pragma
> > +		% foreign_code via transformation is difficult,
> > +		% because there's nowhere in the HLDS pragma_foreign_code
> > +		% goal where we can insert the heap reclamation operations.
> > +		% For now, we don't support this.
> > +		% Instead, we just generate a call to a procedure which
> > +		% will at runtime call error/1 with an appropriate
> > +		% "Sorry, not implemented" error message.
> > +		ModuleInfo =^ module_info,
> > +		{ goal_info_get_context(GoalInfo, Context) },
> > +		{ generate_call("reclaim_heap_nondet_pragma_foreign_code",
> > +			[], det, no, [], ModuleInfo, Context,
> > +			SorryNotImplementedCode) },
> > +		{ Goal = SorryNotImplementedCode }
> > +	;
> > +		{ Goal = PragmaForeign - GoalInfo }
> > +	).
> Do you have any plans to implement this?

The plan is to do an HLDS->HLDS transformation that eliminates nondet
foreign_procs, replacing them with a set of model_det and/or model_semi
foreign_procs and some nondet Mercury code.  Zoltan was working on this,
I think.

That pass would precede this one.

> > +% XXX copied from table_gen.m
> > +
> > +:- pred generate_call(string::in, list(prog_var)::in, determinism::in,
> > +	maybe(goal_feature)::in, assoc_list(prog_var, inst)::in,
> > +	module_info::in, term__context::in, hlds_goal::out) is det.
>
> I would suggest putting this into a new module then.

I wondered how long I was going to get away with that one ;-)
I'll find somewhere appropriate to put it.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list