== Quote from Don (nos...@nospam.com)'s article > Steven Schveighoffer wrote: > > On Thu, 12 Aug 2010 02:00:00 -0400, Brad Roberts <bra...@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.