shithub: mc

Download patch

ref: 60cac7ad2c6dde9b5530b179c1b200c7c26339ae
parent: 0694ed170051479b1d992a269b886e5b3a0be46f
author: Ori Bernstein <[email protected]>
date: Tue Jun 5 14:27:47 EDT 2012

Optimize some common cases for indexing.

    Oload/Ostor(Add(val, val)) is folded.

--- a/8/isel.c
+++ b/8/isel.c
@@ -209,6 +209,7 @@
     Loc l;
     int i;
 
+    assert(m != ModeNone);
     l.reg = Rnone;
     for (i = 0; i < Nreg; i++) {
         if (!s->rtaken[i] && regmodes[i] == m) {
@@ -385,9 +386,44 @@
     return a;
 }
 
+/* We have a few common cases to optimize here:
+ *    Oadd(
+ *        reg,
+ *        reg||const))
+ * TODO:
+ *    Oadd(
+ *        reg,
+ *        Omul(reg,
+ *             2 || 4 || 8)))
+ */
+static Loc memloc(Isel *s, Node *e, Mode m)
+{
+    Node **args;
+    Loc l, b, o; /* location, base, offset */
+
+    if (exprop(e) == Oadd) {
+        args = e->expr.args;
+        b = selexpr(s, args[0]);
+        o = selexpr(s, args[1]);
+        if (b.type != Locreg)
+            b = inr(s, b);
+        if (o.type == Loclit) {
+            locmem(&l, o.lit, b.reg, Rnone, m);
+        } else if (o.type == Locreg) {
+            b = inr(s, b);
+            locmem(&l, 0, b.reg, o.reg, m);
+        }
+    } else {
+        l = selexpr(s, e);
+        if (l.type == Locreg)
+            locmem(&l, 0, l.reg, Rnone, m);
+    }
+    return l;
+}
+
 Loc selexpr(Isel *s, Node *n)
 {
-    Loc a, b, c, r, t;
+    Loc a, b, c, r;
     Node **args;
 
     args = n->expr.args;
@@ -439,22 +475,16 @@
             die("Unimplemented op %s", opstr(exprop(n)));
             break;
         case Ostor: /* reg -> mem */
-            a = selexpr(s, args[0]);
+            a = memloc(s, args[0], mode(n));
             b = selexpr(s, args[1]);
             b = inri(s, b);
-            stor(s, &b, &a);
+            g(s, Imov, &b, &a, NULL);
             r = b;
             break;
         case Oload: /* mem -> reg */
-            t = selexpr(s, args[0]);
-            b = getreg(s, t.mode);
-            if (t.type == Locreg)
-                locmem(&a, 0, t.reg, Rnone, t.mode);
-            else
-                a = t;
-            /* load() doesn't always do the mov */
-            g(s, Imov, &a, &b, NULL);
-            r = b;
+            b = memloc(s, args[0], mode(n));
+            r = getreg(s, mode(n));
+            g(s, Imov, &b, &r, NULL);
             break;
 
         case Ocall: die("Unimplemented op %s", opstr(exprop(n))); break;