tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH] tccgen.c: Optimise 0<<x, 0>>x, -1>>x, x&0, x*0,


From: Edmund Grimley Evans
Subject: [Tinycc-devel] [PATCH] tccgen.c: Optimise 0<<x, 0>>x, -1>>x, x&0, x*0, x|-1, x%1.
Date: Thu, 5 Mar 2015 22:09:22 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

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 <address@hidden>
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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]