shithub: mc

Download patch

ref: 2f4ca4b7632f55634b7954ff2f0532677d6cfe11
parent: 500dd060a6b4dfbdf6ffe1c1a6b18069876e9611
parent: 8f668b2261b225f96d5835c17880a833447ebbcd
author: Ori Bernstein <[email protected]>
date: Sun Aug 12 19:25:32 EDT 2012

Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc2

--- a/6/simp.c
+++ b/6/simp.c
@@ -51,6 +51,7 @@
 static Node *rval(Simp *s, Node *n, Node *dst);
 static Node *lval(Simp *s, Node *n);
 static void declarelocal(Simp *s, Node *n);
+static void simpcond(Simp *s, Node *n, Node *ltrue, Node *lfalse);
 
 /* useful constants */
 static Type *tyintptr;
@@ -343,7 +344,6 @@
 {
     Node *l1, *l2, *l3;
     Node *iftrue, *iffalse;
-    Node *c;
 
     l1 = genlbl();
     l2 = genlbl();
@@ -355,8 +355,7 @@
     iftrue = n->ifstmt.iftrue;
     iffalse = n->ifstmt.iffalse;
 
-    c = rval(s, n->ifstmt.cond, NULL);
-    cjmp(s, c, l1, l2);
+    simpcond(s, n->ifstmt.cond, l1, l2);
     simp(s, l1);
     simp(s, iftrue);
     jmp(s, l3);
@@ -390,7 +389,6 @@
     Node *lbody;
     Node *lend;
     Node *lcond;
-    Node *t;
 
     lbody = genlbl();
     lcond = genlbl();
@@ -402,8 +400,7 @@
     simp(s, n->loopstmt.body);  /* body */
     simp(s, n->loopstmt.step);  /* step */
     simp(s, lcond);             /* test lbl */
-    t = rval(s, n->loopstmt.cond, NULL);  /* test */
-    cjmp(s, t, lbody, lend);    /* repeat? */
+    simpcond(s, n->loopstmt.cond, lbody, lend);    /* repeat? */
     simp(s, lend);              /* exit */
 }
 
@@ -446,14 +443,14 @@
         return load(addk(addr(n, t), off));
 }
 
-static Node *ucompare(Simp *s, Node *a, Node *b, Type *t, size_t off)
+static void ucompare(Simp *s, Node *a, Node *b, Type *t, size_t off, Node *iftrue, Node *iffalse)
 {
-    Node *r, *v, *x, *y;
+    Node *v, *x, *y;
+    Node *next;
     Ucon *uc;
 
     assert(a->type == Nexpr);
     t = tybase(t);
-    r = NULL;
     switch (t->type) {
         case Tyvoid: case Tybad: case Tyvalist: case Tyvar:
         case Typaram: case Tyunres: case Tyname: case Ntypes:
@@ -468,8 +465,8 @@
         case Typtr: case Tyfunc:
             x = uval(a, off, t);
             y = uval(b, off, t);
-            r = mkexpr(a->line, Oeq, x, y, NULL);
-            r->expr.type = tyintptr;
+            v = mkexpr(a->line, Oeq, x, y, NULL);
+            cjmp(s, v, iftrue, iffalse);
             break;
         case Tyunion:
             x = uconid(a, off);
@@ -478,19 +475,17 @@
             if (!uc)
                 uc = finducon(b);
 
-            r = mkexpr(a->line, Oeq, x, y, NULL);
-            r->expr.type = tyintptr;
+            next = genlbl();
+            v = mkexpr(a->line, Oeq, x, y, NULL);
+            v->expr.type = tyintptr;
+            cjmp(s, v, next, iffalse);
+            append(s, next);
             if (uc->etype) {
                 off += Wordsz;
-                v = ucompare(s, a, b, uc->etype, off);
-                r = mkexpr(a->line, Oland, r, v, NULL);
-                r->expr.type = tyintptr;
-                r = rval(s, r, NULL); /* Oland needs to be reduced */
+                ucompare(s, a, b, uc->etype, off, iftrue, iffalse);
             }
             break;
     }
-    return r;
-            
 }
 
 FILE *f;
@@ -497,21 +492,23 @@
 static void simpmatch(Simp *s, Node *n)
 {
     Node *end, *cur, *next; /* labels */
-    Node *val, *cond; /* intermediates */
+    Node *val, *tmp;
     Node *m;
     size_t i;
     f = stdout;
 
     end = genlbl();
-    val = rval(s, n->matchstmt.val, NULL); /* FIXME: don't recompute, even if pure */
+    val = temp(s, n->matchstmt.val);
+    tmp = rval(s, n->matchstmt.val, val);
+    if (val != tmp)
+        append(s, set(val, tmp));
     for (i = 0; i < n->matchstmt.nmatches; i++) {
         m = n->matchstmt.matches[i];
 
         /* check pattern */
-        cond = ucompare(s, val, m->match.pat, val->expr.type, 0);
         cur = genlbl();
         next = genlbl();
-        cjmp(s, cond, cur, next);
+        ucompare(s, val, m->match.pat, val->expr.type, 0, cur, next);
 
         /* do the action if it matches */
         append(s, cur);
@@ -680,25 +677,33 @@
     return r;
 }
 
-static Node *simplazy(Simp *s, Node *n, Node *r)
+static void simpcond(Simp *s, Node *n, Node *ltrue, Node *lfalse)
 {
-    Node *a, *b;
-    Node *next;
-    Node *end;
+    Node **args;
+    Node *v, *lnext;
 
-    next = genlbl();
-    end = genlbl();
-    a = rval(s, n->expr.args[0], NULL);
-    append(s, set(r, a));
-    if (exprop(n) == Oland)
-        cjmp(s, r, next, end);
-    else if (exprop(n) == Olor)
-        cjmp(s, a, end, next);
-    append(s, next);
-    b = rval(s, n->expr.args[1], NULL);
-    append(s, set(r, b));
-    append(s, end);
-    return r;
+    args = n->expr.args;
+    switch (exprop(n)) {
+        case Oland:
+            lnext = genlbl();
+            simpcond(s, args[0], lnext, lfalse);
+            append(s, lnext);
+            simpcond(s, args[1], ltrue, lfalse);
+            break;
+        case Olor:
+            lnext = genlbl();
+            simpcond(s, args[0], ltrue, lnext);
+            append(s, lnext);
+            simpcond(s, args[1], ltrue, lfalse);
+            break;
+        case Olnot:
+            simpcond(s, n, lfalse, ltrue);
+            break;
+        default:
+            v = rval(s, n, NULL);
+            cjmp(s, v, ltrue, lfalse);
+            break;
+    }
 }
 
 static Node *simpcast(Simp *s, Node *val, Type *to)
@@ -935,6 +940,50 @@
     return tmp;
 }
 
+/* simplifies 
+ *      a || b
+ * to
+ *      if a || b
+ *              t = true
+ *      else
+ *              t = false
+ *      ;;
+ */
+static Node *simplazy(Simp *s, Node *n)
+{
+    Node *r, *t, *u;
+    Node *ltrue, *lfalse, *ldone;
+
+    /* set up temps and labels */
+    r = temp(s, n);
+    ltrue = genlbl();
+    lfalse = genlbl();
+    ldone = genlbl();
+
+    /* simp the conditional */
+    simpcond(s, n, ltrue, lfalse);
+
+    /* if true */
+    append(s, ltrue);
+    u = mkexpr(n->line, Olit, mkbool(n->line, 1), NULL);
+    u->expr.type = mkty(n->line, Tybool);
+    t = set(r, u);
+    append(s, t);
+    jmp(s, ldone);
+
+    /* if false */
+    append(s, lfalse);
+    u = mkexpr(n->line, Olit, mkbool(n->line, 0), NULL);
+    u->expr.type = mkty(n->line, Tybool);
+    t = set(r, u);
+    append(s, t);
+    jmp(s, ldone);
+
+    /* finish */
+    append(s, ldone);
+    return r;
+}
+
 static Node *rval(Simp *s, Node *n, Node *dst)
 {
     Node *r; /* expression result */
@@ -960,8 +1009,7 @@
     switch (exprop(n)) {
         case Obad:
         case Olor: case Oland:
-            r = temp(s, n);
-            simplazy(s, n, r);
+            r = simplazy(s, n);
             break;
         case Osize:
             r = mkintlit(n->line, size(args[0]));
--- a/opt/df.c
+++ b/opt/df.c
@@ -15,5 +15,5 @@
 
 void flow(Cfg *cfg)
 {
-    die("Flow analysis not implemented");
 }
+