glsl: Add frexp signatures and implementation.
authorMatt Turner <mattst88@gmail.com>
Mon, 9 Sep 2013 18:13:20 +0000 (11:13 -0700)
committerMatt Turner <mattst88@gmail.com>
Wed, 18 Sep 2013 00:01:58 +0000 (17:01 -0700)
commitd56bbd04415d439b8e04c8f27e911485813f01e4
tree9e9577192c871f6fe4cd944ec868da9ffa4156eb
parentc43d6060b196c3e25b16a0985caa561ae1449ce8
glsl: Add frexp signatures and implementation.

I initially implemented frexp() as an IR opcode with a lowering pass,
but since it returns a value and has an out-parameter, it would break
assumptions our optimization passes make about ir_expressions being pure
(i.e., having no side effects).

For example, if opt_tree_grafting encounters this code:

uniform float u;
void main()
{
  int exp;
  float f = frexp(u, out exp);
  float g = float(exp)/256.0;
  float h = float(exp) + 1.0;
  gl_FragColor = vec4(f, g, h, g + h);
}

it may try to optimize it to this:

uniform float u;
void main()
{
  int exp;
  float g = float(exp)/256.0;
  float h = float(exp) + 1.0;
  gl_FragColor = vec4(frexp(u, out exp), g, h, g + h);
}

Some hardware has an instruction which performs frexp(), but we would
need some other compiler infrastructure to be able to generate it, such
as an intrinsics system that would allow backends to emit specific code
for particular bits of IR.

Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/glsl/builtin_functions.cpp