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