halide/Halide — pull request #446 by kree-colemcalughlin (2014-09-02 17:40:54+00:00)
Title: Specialize All Clamped Ramps

This change recursively applies the specialize_clamped_ramps mutator until the stmt is fixed. This allows us to specialize all of the clamped ramps rather than just the outermost. So, for example, we were previously generating stmts like:

```
produce output {
for (output.s0.x.x, 0, ((output.extent.0 + 15)/16)) {
let output.s0.x.tmp.base = min(((output.s0.x.x*16) + output.min.0), ((output.min.0 + output.extent.0) + -16))
if ((((output.s0.x.tmp.base - input.extent.0) + 15) <= input.min.0)) {
output[ramp((output.s0.x.tmp.base - output.min.0), 1, 16)] = uint8x16(max(min((((int16x16(input[ramp((output.s0.x.tmp.base - input.min.0), 1, 16)])*x16(int16(3))) + int16x16(input[(max(ramp((output.s0.x.tmp.base + -1), 1, 16), x16(input.min.0)) - x16(input.min.0))]))/x16(int16(4))), x16(int16(255))), x16(int16(0))))
} else {
output[ramp((output.s0.x.tmp.base - output.min.0), 1, 16)] = uint8x16(max(min((((int16x16(input[ramp((output.s0.x.tmp.base - input.min.0), 1, 16)])*x16(int16(3))) + int16x16(input[(max((min(ramp(output.s0.x.tmp.base, 1, 16), x16((input.min.0 + input.extent.0))) + x16(-1)), x16(input.min.0)) - x16(input.min.0))]))/x16(int16(4))), x16(int16(255))), x16(int16(0))))
}
}
}
```

After this change, we would generate the stmt:

```
produce output {
for (output.s0.x.x, 0, ((output.extent.0 + 15)/16)) {
let output.s0.x.tmp.base = min(((output.s0.x.x*16) + output.min.0), ((output.min.0 + output.extent.0) + -16))
if ((((output.s0.x.tmp.base - input.extent.0) + 15) <= input.min.0)) {
if (((input.min.0 + 1) <= output.s0.x.tmp.base)) {
output[ramp((output.s0.x.tmp.base - output.min.0), 1, 16)] = uint8x16(max(min((((int16x16(input[ramp((output.s0.x.tmp.base - input.min.0), 1, 16)])*x16(int16(3))) + int16x16(input[ramp(((output.s0.x.tmp.base - input.min.0) + -1), 1, 16)]))/x16(int16(4))), x16(int16(255))), x16(int16(0))))
} else {
output[ramp((output.s0.x.tmp.base - output.min.0), 1, 16)] = uint8x16(max(min((((int16x16(input[ramp((output.s0.x.tmp.base - input.min.0), 1, 16)])*x16(int16(3))) + int16x16(input[(max(ramp((output.s0.x.tmp.base + -1), 1, 16), x16(input.min.0)) - x16(input.min.0))]))/x16(int16(4))), x16(int16(255))), x16(int16(0))))
}
} else {
output[ramp((output.s0.x.tmp.base - output.min.0), 1, 16)] = uint8x16(max(min((((int16x16(input[ramp((output.s0.x.tmp.base - input.min.0), 1, 16)])*x16(int16(3))) + int16x16(input[(max((min(ramp(output.s0.x.tmp.base, 1, 16), x16((input.min.0 + input.extent.0))) + x16(-1)), x16(input.min.0)) - x16(input.min.0))]))/x16(int16(4))), x16(int16(255))), x16(int16(0))))
}
}
}
```