[m-rev.] for review: in_all_grades/in_tailrec_grades_only

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue May 19 11:46:45 AEST 2026



On Tue, 19 May 2026 10:40:30 +1000, Julien Fischer <jfischer at opturion.com> wrote:
> >      % Return a list of the proc_ids for all the modes of this predicate
> >      % that are not imported.
> > +    % ZZZ
> >      %
> >  :- func pred_info_all_non_imported_procids(pred_info) = list(proc_id).
> 
> Presuambly, this was in aid of something?

A reminder to give this predicate a non-misleading name. (It fails for status_imported,
but succeeds for status_opt_imported predicates.) I intended to cut that part
out of the diff I posted, but ...

> > +grade_supports_tail_recursion(ModuleInfo) :-
> > +    module_info_get_globals(ModuleInfo, Globals),
> > +    % XXX Are there any other grade components that disable tail recursion?
> > +    globals.lookup_bool_option(Globals, profile_deep, no),
> > +    globals.lookup_bool_option(Globals, exec_trace, no),
> > +    globals.lookup_bool_option(Globals, source_to_source_debug, no),
> > +    globals.lookup_bool_option(Globals, use_minimal_model_stack_copy, no),
> > +    globals.lookup_bool_option(Globals, use_minimal_model_own_stacks, no).
> 
> agc grades?

I have added them to the list.

> The diff looks fine.

Thanks.

Looking at the tests, I remembered that there is one more difference between LLDS
and MLDS grades wrt tail recursion, beside the one in my last email. It applies to situations
where two predicates such as even and odd in the invalid require_tailrec_? tests, call each
other, but only the calls in one direction are tail calls; the calls in the other direction are not.

In such situations, the LLDS code generator can make the tail calls reuse the stack frame
(because it controls the code generated for the call), while the MLDS code generator
cannot do that (since in that case, it is the target language compiler that is in control).
Basically, the LLDS code generator works on tail *calls*, while the MLDS one works on
*TSSCs*, meaning SCCs of procedures that *all* call each other via *tail* calls.

I am inclined to ignore this difference, and let the new "in_tailrec_grades_only" mean
grades that support *either* kind of tail recursion. We *could* split in_tailrec_grades_only,
but I don't see much point. This is because

- in such cases, the MLDS cannot reuse any stack frames, but even the LLDS can reuse
  only half of the stack frames, so running out of stack is still a problem,

- pretty much everyone will want to use an MLDS grade in production at some point,
  at which time they need to conform to its requirements,

- the diagnostic we generate for the mutually recursive calls whose behavior differs between
  LLDS and MLDS explains those requirements quite well, and

- most cases of mutual recursion can be made to conform to those requirements,
  if they do not naturally conform to begin with.

Do you guys agree?

Zoltan.




More information about the reviews mailing list