imageworks/OpenShadingLanguage — pull request #153 by lgritz (2012-09-11 17:17:12+00:00)
Title: Fix confusing oddity about code generation for Ci = val * closure()

This was generating ops like this:

closure Ci "closurename"
mul Ci Ci val

But if 'val' is an input parameter, needed for the first time and therefore
triggering a call to an earlier layer, which itself assigns to Ci, you end
up with the following confusing sequence underneath:

closure Ci "emission"
useparam val <--- this itself assigns something to Ci,
let's say 'diffuse', for the sake of example
mul Ci Ci val

Now that point, you will have Ci == diffuse*val, instead of the expected
emission*val. Very counter-intuitive to debug, even though all caveats have
been given about having side effects on globals like Ci in earlier layers.

So this patch alters the code generation for binary ops involving closure
variables, if it notices that the destination is a global (Ci is the only
case at this point, but we keep the notion general) to the following:

closure tmp "closurename"
(useparam val)
mul Ci tmp val

And that is completely safe, even if the 'useparam' triggers execution of
a layer that also writes to Ci. Ci will get what the later layer thinks
it's assigning, instead of a strange mashup of the two, as was the case
before.