Overloading Lazy Vs. Non-Lazy

dsimcha dsimcha at yahoo.com
Thu Aug 12 13:47:40 PDT 2010


== Quote from Don (nospam at nospam.com)'s article
> Steven Schveighoffer wrote:
> > On Thu, 12 Aug 2010 02:00:00 -0400, Brad Roberts <braddr at puremagic.com>
> > wrote:
> >
> >> On 8/11/2010 6:19 AM, dsimcha wrote:
> >>> An issue that's come up here several times before is that enforce()
> >>> effectively disables inlining of the function it's used in.  From
> >>> reading some
> >>> disassemblies, the reason seems to be because of all the ASM code that's
> >>> required for lazy parameters.  I wonder if either of the following is
> >>> feasible:
> >>>
> >>> 1.  When a function takes a lazy parameter, the compiler automatically
> >>> generates two versions under the hood:  One that actually takes a
> >>> non-lazy
> >>> parameter and is used when the value is known at compile time and
> >>> another that
> >>> works like current lazy functions.  The only problem here is that
> >>> this might
> >>> create issues when using function pointers/delegates.
> >>>
> >>> 2.  Allow overloading of lazy and non-lazy functions, with the rule
> >>> that the
> >>> lazy version gets called whenever the value must be computed at
> >>> runtime and
> >>> the non-lazy version gets called if the value is statically known and
> >>> thus
> >>> there's no evaluation to speak of.
> >>
> >> It's the throw that blocks inlining right now.  Lazy might also
> >> disable inlining
> >> too, I haven't looked for that case.  Either way, that's purely a
> >> quality of
> >> implementation issue.  I don't think it'd be a good idea to bend the
> >> library all
> >> that much to work around that kind of limitation.  It's something that
> >> will get
> >> better as time permits.
> >
> > Well, there's something to be said about preventing the bloated
> > generation of code that accompanies lazy.
> Inlining a lazy function that only returns a compile-time constant could
> inline very nicely. The delegate would disappear completely.

Just to clarify:  enforce() calls a function called bailOut() if necessary that
actually does the throwing.  This of course is not inlined w.r.t. enforce().
However, the lazy parameter also prevents inlining of enforce() itself and
generates a ton of code at the ASM level.

Don is right, though.  In principle, when a statically known delegate D (lazy is
just syntactic sugar for delegates) that returns a statically known constant is
passed to a statically known function F, D can be inlined w.r.t. F and F can be
inlined w.r.t. its caller.

The problem, though, is that F needs to be inlined first so that the compiler can
optimize F w.r.t. the parameters passed to it from a specific caller.  However, F
won't look worth inlining until the compiler realizes that it can inline D w.r.t.
F.  Therefore, the compiler would need an inliner that uses something more
sophisticated than a simple greedy algorithm to discover this optimization
opportunity.


More information about the Digitalmars-d mailing list