Skip to content

Commit

Permalink
Keep operand order when removing parens around + and - operators (#406)
Browse files Browse the repository at this point in the history
Followup to #151 

This transformation preserves the order of the operands (x, y, z), but
it changes the order of evaluation of the operators. This should be fine
for + and -.

For the multiplication: we preserve the evaluation order of the
multiplications (because of float precision), but we swap the operands
only when it's pure.

---------

Co-authored-by: Eldritch Conundrum <eldritch.conundrum@gmail.com>
  • Loading branch information
laurentlb and eldritchconundrum committed May 24, 2024
1 parent 4c33ec7 commit 22a118b
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 15 deletions.
8 changes: 4 additions & 4 deletions src/rewriter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,12 @@ module private RewriterImpl =

// Swap operands to get rid of parentheses
// x*(y*z) -> y*z*x
| FunCall(Op "*", [NoParen x; FunCall(Op "*", [y; z])]) ->
| FunCall(Op "*", [NoParen x; FunCall(Op "*", [y; z])]) when isPure x && isPure y && isPure z ->
FunCall(Op "*", [FunCall(Op "*", [y; z]); x]) |> env.fExpr env
// x+(y+z) -> y+z+x
// x+(y-z) -> y-z+a
// x+(y+z) -> x+y+z
// x+(y-z) -> x+y-z
| FunCall(Op "+", [NoParen x; FunCall(Op ("+"|"-") as op, [y; z])]) ->
FunCall(Op "+", [FunCall(op, [y; z]); x]) |> env.fExpr env
FunCall(op, [FunCall(Op "+", [x; y]); z]) |> env.fExpr env
// x-(y+z) -> x-y-z
| FunCall(Op "-", [x; FunCall(Op "+", [y; z])]) ->
FunCall(Op "-", [FunCall(Op "-", [x; y]); z]) |> env.fExpr env
Expand Down
6 changes: 3 additions & 3 deletions tests/compression_results.log
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ ed-209.frag 7672 => 1338.529
elevated.hlsl 3401 => 602.542
endeavour.frag 2568 => 529.992
from-the-seas-to-the-stars.frag 14211 => 2282.423
frozen-wasteland.frag 4513 => 804.591
frozen-wasteland.frag 4515 => 804.953
kinder_painter.frag 2832 => 442.132
leizex.frag 2252 => 506.309
lunaquatic.frag 5222 => 1043.256
mandelbulb.frag 2317 => 532.741
ohanami.frag 3246 => 711.753
ohanami.frag 3246 => 712.723
orchard.frag 5394 => 1003.067
oscars_chair.frag 4648 => 986.069
robin.frag 6196 => 1039.087
Expand All @@ -21,4 +21,4 @@ terrarium.frag 3575 => 747.116
the_real_party_is_in_your_pocket.frag 11986 => 1774.550
valley_ball.glsl 4307 => 881.820
yx_long_way_from_home.frag 2936 => 598.845
Total: 133422 => 23299.280
Total: 133424 => 23300.612
2 changes: 1 addition & 1 deletion tests/real/frozen-wasteland.frag.expected
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ float map(vec3 p)
{
p.y+=height(p.zx);
float d=smin(smin(p.y+.5,vine(p+vec3(.8,0,0),30.,3.3)),vine(p.zyx+vec3(0,0,17),33.,1.4));
d+=p.y*1.2*Noise3d(p*.05);
d+=Noise3d(p*.05)*(p.y*1.2);
p.xz*=.3;
return d+Noise3d(p*.3);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/real/monjori.frag.expected
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void main()
i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*.025*6.)*(r+h/3.);
h=sin(f*.025)*144.-sin(e*.025)*212.*p.x;
h=(h+(f-e)*q+sin(r-(a+h)/7.)*10.+i/4.)*.025;
i=mod((cos(h*2.3*sin(a/350.-q))*184.*sin(q-(r*4.3+a/12.)*.025)+tan(r*.025+h)*184.*cos(r*.025+h)+i)/5.6,256.)/64.;
i=mod((i+cos(h*2.3*sin(a/350.-q))*184.*sin(q-(r*4.3+a/12.)*.025)+tan(r*.025+h)*184.*cos(r*.025+h))/5.6,256.)/64.;
if(i<0.)
i+=4.;
if(i>=2.)
Expand Down
2 changes: 1 addition & 1 deletion tests/real/ohanami.frag.expected
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void main()
if(gl_TexCoord[0].w>.5)
{
ti=max(0,time)/3.;
ti=floor(ti)+clamp(fract(ti)*2,0,1)+noise(floor(gl_FragCoord.xy));
ti=noise(floor(gl_FragCoord.xy))+floor(ti)+clamp(fract(ti)*2,0,1);
ti=floor(ti);
float zoom=1.5;
vec2 filmoffset=vec2(0);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/arg-inlining.expected
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ float f()
s+=s+noinline_canInlineWhenArgIsInlinable5();
s+=s+noinline_canInlineWhenArgIsInlinable6();
s+=s+noinline_cannotInlineWhenArgIsNotInlinable(s);
return s+noinline_cannotInlineWhenArgIsNotInlinable(acos(s))+s;
return s+s+noinline_cannotInlineWhenArgIsNotInlinable(acos(s));
}
void main()
{
Expand Down
9 changes: 7 additions & 2 deletions tests/unit/operators.expected
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"}"
"int no_parens(int a,int b,int c)"
"{"
"return b+c+a+a+b*c;"
"return a+b+c+a+b*c;"
"}"
"int no_parens2(int a,int b,int c)"
"{"
Expand Down Expand Up @@ -47,7 +47,12 @@
"g/=-g+g;"
"g-=-g--- --g;"
"g*=g+g;"
"return--g-++g+g;"
"return g+--g-++g;"
"}"
"float swap_op_order(float g)"
"{"
"float a=g*(g--*g--),b=(g+2.)*(g+3.)*g;"
"return a*b*g;"
"}",

#endif
7 changes: 7 additions & 0 deletions tests/unit/operators.frag
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,10 @@ float cool_ops(float g)
f += --f + (- +(++f));
return f;
}

float swap_op_order(float g)
{
float a = g*((g--)*(g--));
float b = g*((g+2.)*(g+3.));
return a*b*g;
}
2 changes: 1 addition & 1 deletion tests/unit/shadowing.frag.expected
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
float f(float g)
{
g=0.;
return g+++ ++g+g;
return g+g+++ ++g;
}
float g(float f)
{
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/simplify.expected
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ float baz(float a)
{
a=a+4.+sin(a);
a=a+5.+sin(a);
return-a-a+a;
return a-a-a;
}
out vec3 outputvar;
void notMain(float x)
Expand Down

0 comments on commit 22a118b

Please sign in to comment.