Overloading Lazy Vs. Non-Lazy

Steven Schveighoffer schveiguy at yahoo.com
Fri Aug 13 06:21:00 PDT 2010


On Thu, 12 Aug 2010 16:47:40 -0400, dsimcha <dsimcha at yahoo.com> wrote:

> == 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.

In principle, we should be able to inline enforce.  Great.  When is this  
going to happen?  Well, we can inline all calls to enforce *today* if we  
simply remove the lazy attribute, and apply a lazy version in a small  
number of places.  I think it's worth doing it, because the inlining fixes  
are not going to happen for a while.  It's easy to switch it back once we  
can inline trivial lazy parameters.

-Steve


More information about the Digitalmars-d mailing list