Layer/connection simplification improvements

I've been working on some additional runtime optimization improvements for OSL.  They all involve quantities computed in one layer and passed through an output to the input of a downstream layer.

1. We previously noticed when layer A has an output which is determined to be a constant, then wired up to the input of another layer, and removed the connection by turning the downstream layer's parameter into a constant with the right value.  But I noticed that the test required the upstream output to never be used; it seems to me that its being read by the earlier layer is immaterial, the only important thing is that it's not WRITTEN (other than its initial constant value).  Changing this to the less restrictive condition increases the number of constants thus propagated.

2. Another idiom is if the upstream layer has an output that is unconditionally assigned a global variable (like P, N, u, v).  We didn't do anything with that before.  Now I have code that notices this case and will sever the connection and alias the downstream layer's parameter to the global.

3. Middleman elimination: this addresses a case where there are three layers involved (call them A, B, and C), and the middle layer B only serves to copy an input (which is connected from one of A's outputs) to an output, with no further processing, and that output is in turn connected to one of C's inputs.  We recognize this case and change the connections to hook A's output directly to C's input (thus "cutting out the middle-man" B).

These may seem like trivial cases, but in addition to coming up surprisingly often in complex production shader networks, it's also common to have the shaders start out much more complicated, but in the process of heavy runtime optimization, they only then become trivial assignments of globals, constants, or copies of input parameters.

I'm finding that on very complex production frames, this is yielding around a 4-5% speedup of rendering.