Handle Load and Store nodes correctly for OpenGL

Three main parts:

- Load operations inside kernel loops are encoded as
  Load((x-min[0])/extent[0], ...) since OpenGL expects normalized coordinates.

- Before generating GLSL code, we perform an additional pass over the IR to
  implement Load semantics via texture lookups. This generally involves some
  type conversion and arithmetic since texture2D always returns a normalized
  float.

- Some peephole optimizations are performed so that expressions like
  "Cast(Float(32), input()) / 255.f)" map directly to texture2D