Thread overview
[dmd-internals] opApply with alias instead of delegate?
Jan 09, 2011
David Simcha
Jan 09, 2011
Walter Bright
Jan 09, 2011
Brad Roberts
January 09, 2011
I found this goodie in opover.c of the DMD source, and am wondering if/when it will be implemented fully.  I think that opApply with an alias instead of a delegate would be a great thing to have, rather than having to rely on a "sufficiently smart compiler" to inline delegates for opApply (LDC does this sometimes, though not very reliably) or not being able to use opApply in ultra performance-critical situations (status quo with DMD).  Is there any fundamental reason design reason why this didn't work out, or is it just yet another low-priority todo?

/*******************************************
  * Infer foreach arg types from a template function opApply which looks
like:
  *    int opApply(alias int func(ref uint))() { ... }
  */

#if 0
void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments)
{
     for (TemplateDeclaration *td = tstart; td; td = td->overnext)
     {
         if (!td->scope)
         {
             error("forward reference to template %s", td->toChars());
             return;
         }
         if (!td->onemember ||
!td->onemember->toAlias()->isFuncDeclaration())
         {
             error("is not a function template");
             return;
         }
         if (!td->parameters || td->parameters->dim != 1)
             continue;
         TemplateParameter *tp = (TemplateParameter
*)td->parameters->data[0];
         TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
         if (!tap || !tap->specType || tap->specType->ty != Tfunction)
             continue;
         TypeFunction *tf = (TypeFunction *)tap->specType;
         if (inferApplyArgTypesY(tf, arguments) == 0)    // found it
             return;
     }
}
#endif

January 09, 2011
I wrote that a very long time ago, and don't remember the details.

David Simcha wrote:
> I found this goodie in opover.c of the DMD source, and am wondering if/when it will be implemented fully.  I think that opApply with an alias instead of a delegate would be a great thing to have, rather than having to rely on a "sufficiently smart compiler" to inline delegates for opApply (LDC does this sometimes, though not very reliably) or not being able to use opApply in ultra performance-critical situations (status quo with DMD).  Is there any fundamental reason design reason why this didn't work out, or is it just yet another low-priority todo?
>
> /*******************************************
>  * Infer foreach arg types from a template function opApply which
> looks like:
>  *    int opApply(alias int func(ref uint))() { ... }
>  */
>
> #if 0
> void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters
> *arguments)
> {
>     for (TemplateDeclaration *td = tstart; td; td = td->overnext)
>     {
>         if (!td->scope)
>         {
>             error("forward reference to template %s", td->toChars());
>             return;
>         }
>         if (!td->onemember ||
> !td->onemember->toAlias()->isFuncDeclaration())
>         {
>             error("is not a function template");
>             return;
>         }
>         if (!td->parameters || td->parameters->dim != 1)
>             continue;
>         TemplateParameter *tp = (TemplateParameter
> *)td->parameters->data[0];
>         TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
>         if (!tap || !tap->specType || tap->specType->ty != Tfunction)
>             continue;
>         TypeFunction *tf = (TypeFunction *)tap->specType;
>         if (inferApplyArgTypesY(tf, arguments) == 0)    // found it
>             return;
>     }
> }
> #endif
>
> _______________________________________________
> dmd-internals mailing list
> dmd-internals at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-internals
>
>
January 09, 2011
Personally, I think that the d front end ought to be changed to take the op apply code and insert it at the call point around the loop body.  Essentially inlining the loop infrastructure rather than having it called as a function.

Even if left as a function call + a delegate, that's about the easiest case of
inlining a delegate.  I'd really like to see that part of the inliner fixed
since it'd result in a general improvement rather than a specific one.  I took a
crack at it a while back and ran into some roadblocks -- fixable ones, I think.
 Once this 64 bit stuff is mostly put to bed, maybe I can meet with Walter and
we can work out a solution.

I do agree that the performance cost of opApply is unfortunate.

On 1/9/2011 12:03 PM, David Simcha wrote:
> I found this goodie in opover.c of the DMD source, and am wondering if/when it will be implemented fully.  I think that opApply with an alias instead of a delegate would be a great thing to have, rather than having to rely on a "sufficiently smart compiler" to inline delegates for opApply (LDC does this sometimes, though not very reliably) or not being able to use opApply in ultra performance-critical situations (status quo with DMD).  Is there any fundamental reason design reason why this didn't work out, or is it just yet another low-priority todo?
> 
> /*******************************************
>  * Infer foreach arg types from a template function opApply which looks like:
>  *    int opApply(alias int func(ref uint))() { ... }
>  */
> 
> #if 0
> void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments)
> {
>     for (TemplateDeclaration *td = tstart; td; td = td->overnext)
>     {
>         if (!td->scope)
>         {
>             error("forward reference to template %s", td->toChars());
>             return;
>         }
>         if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration())
>         {
>             error("is not a function template");
>             return;
>         }
>         if (!td->parameters || td->parameters->dim != 1)
>             continue;
>         TemplateParameter *tp = (TemplateParameter *)td->parameters->data[0];
>         TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
>         if (!tap || !tap->specType || tap->specType->ty != Tfunction)
>             continue;
>         TypeFunction *tf = (TypeFunction *)tap->specType;
>         if (inferApplyArgTypesY(tf, arguments) == 0)    // found it
>             return;
>     }
> }
> #endif
> 
> _______________________________________________
> dmd-internals mailing list
> dmd-internals at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-internals

January 10, 2011
I'll take this opportunity to bring up a long-standing wish of mine:

http://d.puremagic.com/issues/show_bug.cgi?id=2498

And also, this would be nice to fix as well:

http://d.puremagic.com/issues/show_bug.cgi?id=2443

-Steve



----- Original Message ----
> From: Walter Bright <walter at digitalmars.com>
> To: Discuss the internals of DMD <dmd-internals at puremagic.com>
> Sent: Sun, January 9, 2011 3:23:08 PM
> Subject: Re: [dmd-internals] opApply with alias instead of delegate?
> 
> I wrote that a very long time ago, and don't remember the details.
> 
> David  Simcha wrote:
> > I found this goodie in opover.c of the DMD source, and am  wondering if/when
>it will be implemented fully.  I think that opApply with  an alias instead of a delegate would be a great thing to have, rather than  having to rely on a "sufficiently smart compiler" to inline delegates for  opApply (LDC does this sometimes, though not very reliably) or not being able to  use opApply in ultra performance-critical situations (status quo with  DMD).  Is there any fundamental reason design reason why this didn't work  out, or is it just yet another low-priority todo?