removing redundant texture loads

This PR reduces the number of texture loads that Halide produces by about 3x in certain use cases.

The current glsl_texture_load intrinsic takes x, y, and c arguments. This PR separates the texel lookup at an x,y coordinate from channel swizzling, which allows CSE to pull out the texture lookup for a given texel so that Halide generates only one texture load for it. The first step takes spatial x and y coordinates and returns a width-4 result. The second step wraps the glsl_texture_load intrinsic in a shuffle_vector intrinsic to extract a single channel out of the texel. Logic is added to VectorizeLoops and GLSL codegen to handle the shuffle_vector intrinsic.

Previously, VectorizeLoops assumed that any expression in Halide could be vectorized. Call nodes were vectorized by widening the return type of the expression as well as widening each argument expression.  Logic had to be added to support the  shuffle_vector(glsl_texture_load(...),..) intrinisic pair- since both intrinsics are defined to behave differently than ordinary Calls: shuffle_vector returns a vector type if it is passed more than two arguments. Its first argument is a vector type, and all of its other arguments are scalar. Glsl_texture_load always returns a width-4 type and its third and fourth arguments must be scalar.  The changes in this branch allow VectorizeLoops to stop mutating at the shuffle_vector node by preserving let variables for scalar expressions. These scalar expressions may be used in the shuffle_vector argument expressions.

This PR resolves #558 

This PR was tested by "make run_tests" as wells as the opengl subtests on Mac.

PTAL

While this assert should be true also, the comment seems to suggest what you meant to assert was op->args.size() == 2 (only one channel selector argument), or equivalently, op->type.is_scalar() (assuming the Call node is well-formed).