[m-rev.] for review: disable_warnings scope

Zoltan Somogyi zoltan.somogyi at runbox.com
Wed Jan 11 14:13:57 AEDT 2017

On Wed, 11 Jan 2017 13:44:02 +1100, Paul Bone <paul at bone.id.au> wrote:     
> > > If we wanted to unify these parts of the compiler we'd probably need to
> > > re-implement most of the MLDS tail call code.
> > 
> > What MLDS tail call code? And why?
> Any code that "decides" which is a tail call and which is not.  I beleive it
> is better if one module decide what is a tail call and other modules act on
> this decision (via the mark in the HLDS for example).  The code that makes
> that decision for MLDS grades would need to be moved to the the
> mark_tail_calls.m module.

I had another look at the code that ml_tailcalls.m calls to make that decision.
Since this code involves mostly MLDS-level data, moving it mark_tail_calls.m
would not be a good idea.

Instead, I think I can implement the disabling of warnings generated by
ml_tailcalls.m by

- adding a field to the state of the HLDS-to-MLDS code generator that gives
   a list of the warnings disabled by any disable_warnings scopes surrounding
   the goal it is currently translating,
- when it translates a call, marking the ml_stmt_call it generates with the
   disabled warnings applicable to that calls (currently only the warning
   we are talking about now, but later possible others as well),
- having ml_tailcall.m not generate its warning if the call's markings
   say the warning should be disabled.

This gets information about suppressing the warning from the HLDS
to the MLDS without having to introduce a scope construct to the MLDS.

Alternatively, instead of marking calls at code generation time,
we could have an earlier pass (maybe simplification) attach a goal feature
to HLDS call goals, and the HLDS-to-MLDS code generator could mark
ml_stmt_calls based on the absence or presence of this feature.
The difference would be in whether we mark calls that are (a) in the scope
when the code generator sees it, or (b) in the scope in the source that
the programmer sees. The difference is in code transformations that can move
code in or out of scopes.

Can anyone see a reason why this wouldn't work? Does anyone have
any preference for (a) or (b)? (a) is a true reflection of reality at runtime,
while (b) is not, but (a) is not what the programmer controls *directly*.

For software engineering reasons, I also intend to delete all the code
in ml_tailcall.m that constructs the warnings messages themselves,
and replace them with calls to predicates in mark_tail_calls.m that do
the same thing (which will have to be exported).

> > >  If we decide want to do
> > > that, it should probably be done at the same time as my MLDS mutual
> > > recursion work.
> > 
> > Would you mind filling me on that?
> http://lists.mercurylang.org/archives/developers/2015-November/016458.html
> The whole thread is worth reading.

I remember the thread. I meant: Would you mind filling me on what parts, if any,
of that results of that discussion have you implemented?

> > The way things work for the LLDS backend at the moment is:
> > 
> > - if the user wants warnings for recursive calls that aren't tail recursive,
> >    we run mark_tail_calls.m to get the warnings;
> > - possibly we run some HLDS to HLDS transformations;
> > - we generate LLDS code; and
> > - while optimizing the LLDS code, we replace some calls with tail calls.
> > 
> > To make sure that step 1 generates the right warnings,
> > - it needs to know what calls the code generator and/or the optimizer
> >    will turn into tail calls, and
> > - it needs to be done late enough that none of the transformations
> >    done in step 2 change the code in ways that would invalidate
> >    that knowledge.
> Is the decision of what to make a tail call made twice?  Or do the later
> passes simply follow the marked tailcalls?

The former.


More information about the reviews mailing list