Any thoughts on this? There are lots of opportunities to introduce a bug here so it would be good if someone else could take a look.
I'll push it at the weekend if there are no objections. From: Edmund Grimley Evans <[email protected]> Date: Wed, 4 Mar 2015 23:39:06 +0000 Subject: [PATCH] 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. --- tccgen.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/tccgen.c b/tccgen.c index e86ff4a..a7251fb 100644 --- a/tccgen.c +++ b/tccgen.c @@ -1476,16 +1476,30 @@ static void gen_opic(int op) c2 = c1; //c = c1, c1 = c2, c2 = c; l2 = l1; //l = l1, l1 = l2, l2 = l; } - /* Filter out NOP operations like x*1, x-0, x&-1... */ - 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))) { - /* nothing to do */ + if (!const_wanted && + c1 && ((l1 == 0 && + (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) || + (l1 == -1 && op == TOK_SAR))) { + /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */ + vtop--; + } else if (!const_wanted && + c2 && ((l2 == 0 && (op == '&' || op == '*')) || + (l2 == -1 && op == '|') || + (l2 == 1 && (op == '%' || op == TOK_UMOD)))) { + /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */ + if (l2 == 1) + memset(&vtop->c, 0, sizeof(vtop->c)); + 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--; } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { /* try to use shifts instead of muls or divs */ -- 1.7.10.4 _______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
