imageworks/OpenShadingLanguage — pull request #299 by lgritz (2013-11-29 00:34:50+00:00)
Title: Dramatically speed up LLVM optimization & JIT of small shaders.

In the process of compiling a shader group, we were handing LLVM an buffer containing the IR bitcode for all the built-in functions that could possibly be called. This was a big contributing factor to compilation overhead -- when compiling trivial shaders like

shader constant (color Cs) { Ci = Cs*emission(); }

it was taking approximately 0.1-0.25s for LLVM optimization + JIT (depending on the machine on which I tested).

This patch changes the strategy for feeding LLVM the bitcode, changing from llvm::ParseBitcodeFile to llvm::getLazyBitcodeModule, which reads just the header but deserializes the individual functions in the bitcode lazily, if/when they are needed. For small shaders that reference only a tiny portion of the built-in standard library functions we supply, this means that the vast majority are never deserialized. On the 'constant' shader above (as measured by testshade), the LLVM optimize+JIT time was reduced to < 0.01s!!!

I don't expect you to see a big difference when compiling huge production shaders (maybe shave off 0.05-0.10s for each shader group, big deal), but if you are compiling a lot of small shaders, this could reduce the time substantially, from 200ms to perhaps just a few ms per shader. It's easy to imagine that this unlocks entirely new uses for OSL as a small expression language or places where you'd frequently wish to compile many small shaders without a noticable hiccup in your app, which was impossible before but seems too-good-to-be-true easy with this change.

I will backport to the recently-branched RB-1.3 if this works out, but because it seems like black magic, I'd like to keep it just in master for a couple weeks, until SPI has used it enough that I feel confident in switching everybody else to it.