tccgen.c: Optimise 0<<x, 0>>x, -1>>x, x&0, x*0, x|-1, x%1.

More precisely, treat (0 << x) and so on as constant expressions, but
not if const_wanted as we do not want to allow "case (x*0):", ...

Do not optimise (0 / x) and (0 % x) here as x might be zero, though
for an architecture that does not generate an exception for division
by zero the back end might choose to optimise those.
master
Edmund Grimley Evans 2015-03-07 11:25:27 +00:00
parent 9163393476
commit ac70e6b840
1 changed files with 25 additions and 10 deletions

View File

@ -1476,16 +1476,31 @@ static void gen_opic(int op)
c2 = c1; //c = c1, c1 = c2, c2 = c; c2 = c1; //c = c1, c1 = c2, c2 = c;
l2 = l1; //l = l1, l1 = l2, l2 = l; l2 = l1; //l = l1, l1 = l2, l2 = l;
} }
/* Filter out NOP operations like x*1, x-0, x&-1... */ if (!const_wanted &&
if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || c1 && ((l1 == 0 &&
op == TOK_PDIV) && (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
l2 == 1) || (l1 == -1 && op == TOK_SAR))) {
((op == '+' || op == '-' || op == '|' || op == '^' || /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && vtop--;
l2 == 0) || } else if (!const_wanted &&
(op == '&' && c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
l2 == -1))) { (l2 == -1 && op == '|') ||
/* nothing to do */ (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
(l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
/* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
if (l2 == 1)
vtop->c.ll = 0;
vswap();
vtop--;
} else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
op == TOK_PDIV) &&
l2 == 1) ||
((op == '+' || op == '-' || op == '|' || op == '^' ||
op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
l2 == 0) ||
(op == '&' &&
l2 == -1))) {
/* filter out NOP operations like x*1, x-0, x&-1... */
vtop--; vtop--;
} else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
/* try to use shifts instead of muls or divs */ /* try to use shifts instead of muls or divs */