shithub: mc

Download patch

ref: 1ad08d5fdee3b975722f692e9222da1a0126d632
parent: 62f7dc8a82a51b9b043587ee0ca52c62c7420999
author: Ori Bernstein <[email protected]>
date: Wed Oct 17 14:05:26 EDT 2012

Labels are now Lit values, not their own toplev nodes.

--- a/6/isel.c
+++ b/6/isel.c
@@ -737,12 +737,7 @@
 
 static void isel(Isel *s, Node *n)
 {
-    Loc *lbl;
-
     switch (n->type) {
-        case Nlbl:
-            g(s, Ilbl, lbl = loclbl(n), NULL);
-            break;
         case Nexpr:
             selexpr(s, n);
             break;
@@ -857,7 +852,11 @@
                 writelit(fd, v->lit.seqval[i]->expr.args[0], size(v->lit.seqval[i]));
             break;
         case Lfunc:
-                        die("Generating this shit ain't ready yet ");
+            die("Generating this shit ain't ready yet ");
+            break;
+        case Llbl:
+            die("Can't generate literal labels, ffs. They're not data.");
+            break;
     }
 }
 
--- a/6/locs.c
+++ b/6/locs.c
@@ -90,10 +90,14 @@
     return l;
 }
 
-Loc *loclbl(Node *lbl)
+Loc *loclbl(Node *e)
 {
-    assert(lbl->type = Nlbl);
-    return locstrlbl(lbl->lbl.name);
+    Node *lbl;
+    assert(e->type == Nexpr);
+    lbl = e->expr.args[0];
+    assert(lbl->type == Nlit);
+    assert(lbl->lit.littype = Llbl);
+    return locstrlbl(lbl->lit.lblval);
 }
 
 Loc **locmap = NULL;
--- a/6/main.c
+++ b/6/main.c
@@ -30,11 +30,12 @@
     printf("\t-I path\tAdd 'path' to use search path\n");
     printf("\t-d\tPrint debug dumps. Recognized options: f r p i\n");
     printf("\t\t\tno options: print most common debug information\n");
-    printf("\t\t\tf: additionally log folded trees\n");
-    printf("\t\t\tl: additionally log lowered pre-cfg trees\n");
-    printf("\t\t\tT: additionally log tree immediately\n");
-    printf("\t\t\tr: additionally log register allocation activity\n");
-    printf("\t\t\ti: additionally log instruction selection activity\n");
+    printf("\t\t\tf: log folded trees\n");
+    printf("\t\t\tl: log lowered pre-cfg trees\n");
+    printf("\t\t\tT: log tree immediately\n");
+    printf("\t\t\tr: log register allocation activity\n");
+    printf("\t\t\ti: log instruction selection activity\n");
+    printf("\t\t\tu: log type unifications\n");
     printf("\t-o\tOutput to outfile\n");
     printf("\t-S\tGenerate assembly instead of object code\n");
 }
--- a/6/simp.c
+++ b/6/simp.c
@@ -1117,6 +1117,9 @@
                 case Lfunc:
                     r = simplit(s, n, &file->file.stmts, &file->file.nstmts);
                     break;
+                case Llbl:
+                    die("Don't support labels in expressions yet");
+                    break;
             }
             break;
         case Ovar:
@@ -1183,6 +1186,15 @@
     s->argsz += size(n);
 }
 
+static int islbl(Node *n)
+{
+    Node *l;
+    if (exprop(n) != Olit)
+        return 0;
+    l = n->expr.args[0];
+    return l->type == Nlit && l->lit.littype == Llbl;
+}
+
 static Node *simp(Simp *s, Node *n)
 {
     Node *r, *t, *u;
@@ -1192,14 +1204,15 @@
         return NULL;
     r = NULL;
     switch (n->type) {
-        case Nlit:       r = n;                 break;
-        case Nlbl:       append(s, n);          break;
         case Nblock:     simpblk(s, n);         break;
         case Nifstmt:    simpif(s, n, NULL);    break;
         case Nloopstmt:  simploop(s, n);        break;
         case Nmatchstmt: simpmatch(s, n);       break;
         case Nexpr:
-            r = rval(s, n, NULL);
+            if (islbl(n))
+                append(s, n);
+            else
+                r = rval(s, n, NULL);
             if (r)
                 append(s, r);
             /* drain the increment queue for this expr */
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -4,7 +4,6 @@
     chartype.myr \
     die.myr \
     fmt.myr \
-    option.myr \
     rand.myr \
     sys.myr \
     types.myr \
--- a/mi/cfg.c
+++ b/mi/cfg.c
@@ -26,10 +26,18 @@
     return bb;
 }
 
+static char *lblstr(Node *n)
+{
+    assert(exprop(n) == Olit);
+    assert(n->expr.args[0]->type == Nlit);
+    assert(n->expr.args[0]->lit.littype == Llbl);
+    return n->expr.args[0]->lit.lblval;
+}
+
 static void label(Cfg *cfg, Node *lbl, Bb *bb)
 {
-    htput(cfg->lblmap, lbl->lbl.name, bb);
-    lappend(&bb->lbls, &bb->nlbls, lbl->lbl.name);
+    htput(cfg->lblmap, lblstr(lbl), bb);
+    lappend(&bb->lbls, &bb->nlbls, lblstr(lbl));
 }
 
 static int addnode(Cfg *cfg, Bb *bb, Node *n)
@@ -49,6 +57,34 @@
     return 0;
 }
 
+static int islabel(Node *n)
+{
+    Node *l;
+    if (n->type != Nexpr)
+        return 0;
+    if (exprop(n) != Olit)
+        return 0;
+    l = n->expr.args[0];
+    if (l->type != Nlit)
+        return 0;
+    if (l->lit.littype != Llbl)
+        return 0;
+    return 1;
+}
+
+static Bb *addlabel(Cfg *cfg, Bb *bb, Node **nl, size_t i)
+{
+    /* if the current block assumes fall-through, insert an explicit jump */
+    if (i > 0 && nl[i - 1]->type == Nexpr) {
+        if (exprop(nl[i - 1]) != Ocjmp && exprop(nl[i - 1]) != Ojmp)
+            addnode(cfg, bb, mkexpr(-1, Ojmp, mklbl(-1, lblstr(nl[i])), NULL));
+    }
+    if (bb->nnl)
+        bb = mkbb(cfg);
+    label(cfg, nl[i], bb);
+    return bb;
+}
+
 Cfg *mkcfg(Node **nl, size_t nn)
 {
     Cfg *cfg;
@@ -63,20 +99,13 @@
     bb = mkbb(cfg);
     for (i = 0; i < nn; i++) {
         switch (nl[i]->type) {
-            case Nlbl:
-                /* if the current block assumes fall-through, insert an explicit jump */
-                if (i > 0 && nl[i - 1]->type == Nexpr) {
-                    if (exprop(nl[i - 1]) != Ocjmp && exprop(nl[i - 1]) != Ojmp)
-                        addnode(cfg, bb, mkexpr(-1, Ojmp, mklbl(-1, nl[i]->lbl.name), NULL));
-                }
-                if (bb->nnl)
-                    bb = mkbb(cfg);
-                label(cfg, nl[i], bb);
-                break;
             case Nexpr:
-                if (addnode(cfg, bb, nl[i]))
+                if (islabel(nl[i]))
+                    bb = addlabel(cfg, bb, nl, i);
+                else if (addnode(cfg, bb, nl[i]))
                     bb = mkbb(cfg);
                 break;
+                break;
             case Ndecl:
                 break;
             default:
@@ -104,16 +133,16 @@
                 break;
         }
         if (a) {
-            targ = htget(cfg->lblmap, a->lbl.name);
+            targ = htget(cfg->lblmap, lblstr(a));
             if (!targ)
-                die("No bb with label %s", a->lbl.name);
+                die("No bb with label %s", lblstr(a));
             bsput(bb->succ, targ->id);
             bsput(targ->pred, bb->id);
         }
         if (b) {
-            targ = htget(cfg->lblmap, b->lbl.name);
+            targ = htget(cfg->lblmap, lblstr(b));
             if (!targ)
-                die("No bb with label %s", b->lbl.name);
+                die("No bb with label %s", lblstr(b));
             bsput(bb->succ, targ->id);
             bsput(targ->pred, bb->id);
         }
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -185,6 +185,7 @@
                 case Lint:      fprintf(fd, " Lint %llu\n", n->lit.intval); break;
                 case Lflt:      fprintf(fd, " Lflt %lf\n", n->lit.fltval); break;
                 case Lstr:      fprintf(fd, " Lstr %s\n", n->lit.strval); break;
+                case Llbl:      fprintf(fd, " Llbl %s\n", n->lit.lblval); break;
                 case Lfunc:
                     fprintf(fd, " Lfunc\n");
                     outnode(n->lit.fnval, fd, depth+1);
@@ -204,9 +205,6 @@
             indent(fd, depth);
             fprintf(fd, ")\n");
             outnode(n->func.body, fd, depth+1);
-            break;
-        case Nlbl:
-            fprintf(fd, "(lbl = %s)\n", n->lbl.name);
             break;
         case Nname:
             fprintf(fd, "(");
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -319,6 +319,7 @@
         case Lint:      return mktylike(n->line, Tyint);                        break;
         case Lflt:      return mktylike(n->line, Tyfloat32);                    break;
         case Lstr:      return mktyslice(n->line, mktype(n->line, Tybyte));     break;
+        case Llbl:      return mktyptr(n->line, mktype(n->line, Tyvoid));       break;
         case Lfunc:     return n->lit.fnval->func.type;                         break;
         case Lseq:      return NULL; break;
     };
@@ -528,8 +529,8 @@
 /* Unifies two types, or errors if the types are not unifiable. */
 static Type *unify(Inferstate *st, Node *ctx, Type *a, Type *b)
 {
-    Type *t;
-    Type *r;
+    Type *t, *r;
+    char *from, *to;
     size_t i;
 
     /* a ==> b */
@@ -537,6 +538,8 @@
     b = tf(st, b);
     if (a == b)
         return a;
+
+    /* we unify from lower to higher ranked types */
     if (tyrank(b) < tyrank(a)) {
         t = a;
         a = b;
@@ -543,6 +546,14 @@
         b = t;
     }
 
+    if (debugopt['u']) {
+        from = tystr(a);
+        to = tystr(b);
+        printf("Unify %s => %s", from, to);
+        free(from);
+        free(to);
+    }
+
     r = NULL;
     if (a->type == Tyvar) {
         tytab[a->tid] = b;
@@ -1131,7 +1142,6 @@
         case Nname:
         case Nlit:
         case Nuse:
-        case Nlbl:
             break;
         case Nnone:
             die("Nnone should not be seen as node type!");
@@ -1332,7 +1342,6 @@
             break;
         case Nname:
         case Nuse:
-        case Nlbl:
             break;
         case Nnone:
             die("Nnone should not be seen as node type!");
--- a/parse/lits.def
+++ b/parse/lits.def
@@ -5,3 +5,4 @@
 L(Lstr)
 L(Lfunc)
 L(Lseq)
+L(Llbl)
--- a/parse/node.c
+++ b/parse/node.c
@@ -181,9 +181,11 @@
 {
     Node *n;
 
-    n = mknode(line, Nlbl);
-    n->lbl.name = strdup(lbl);
-    return n;
+    assert(lbl != NULL);
+    n = mknode(line, Nlit);
+    n->lit.littype = Llbl;
+    n->lit.lblval = strdup(lbl);
+    return mkexpr(line, Olit, n, NULL);
 }
 
 Node *mkstr(int line, char *val)
--- a/parse/nodes.def
+++ b/parse/nodes.def
@@ -11,4 +11,3 @@
 N(Nname)
 N(Ndecl)
 N(Nfunc)
-N(Nlbl)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -182,6 +182,7 @@
                 double   fltval;
                 unichar  chrval;
                 char    *strval;
+                char    *lblval;
                 int      boolval;
                 Node    *fnval;
                 Node    **seqval;
@@ -217,10 +218,6 @@
             size_t nstmts;
             Node **stmts;
         } block;
-
-        struct {
-            char *name;
-        } lbl;
 
         struct {
             size_t did;
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -339,6 +339,7 @@
                 case Lint:      wrint(fd, n->lit.intval);       break;
                 case Lflt:      wrflt(fd, n->lit.fltval);       break;
                 case Lstr:      wrstr(fd, n->lit.strval);       break;
+                case Llbl:      wrstr(fd, n->lit.lblval);       break;
                 case Lbool:     wrbool(fd, n->lit.boolval);     break;
                 case Lfunc:     pickle(n->lit.fnval, fd);       break;
                 case Lseq:
@@ -374,9 +375,6 @@
             for (i = 0; i < n->block.nstmts; i++)
                 pickle(n->block.stmts[i], fd);
             break;
-        case Nlbl:
-            wrstr(fd, n->lbl.name);
-            break;
         case Ndecl:
             /* sym */
             pickle(n->decl.name, fd);
@@ -460,6 +458,7 @@
                 case Lint:      n->lit.intval = rdint(fd);       break;
                 case Lflt:      n->lit.fltval = rdflt(fd);       break;
                 case Lstr:      n->lit.strval = rdstr(fd);       break;
+                case Llbl:      n->lit.lblval = rdstr(fd);       break;
                 case Lbool:     n->lit.boolval = rdbool(fd);     break;
                 case Lfunc:     n->lit.fnval = unpickle(fd);       break;
                 case Lseq:
@@ -498,9 +497,6 @@
             for (i = 0; i < n->block.nstmts; i++)
                 n->block.stmts[i] = unpickle(fd);
             popstab();
-            break;
-        case Nlbl:
-            n->lbl.name = rdstr(fd);
             break;
         case Ndecl:
             n->decl.did = maxdid++; /* unique within file */
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -129,7 +129,8 @@
                     for (i = 0; i < n->lit.nelt; i++)
                         fixup(n->lit.seqval[i]);
                     break;
-                case Lchr: case Lint: case Lflt: case Lstr: case Lbool:
+                case Lchr: case Lint: case Lflt:
+                case Lstr: case Llbl: case Lbool:
                     break;
             }
             break;
@@ -166,7 +167,7 @@
             fixup(n->func.body);
             popstab();
             break;
-        case Nnone: case Nlbl: case Nname:
+        case Nnone: case Nname:
             break;
     }
 }
@@ -212,6 +213,7 @@
                 case Lint:      r->lit.intval = n->lit.intval;       break;
                 case Lflt:      r->lit.fltval = n->lit.fltval;       break;
                 case Lstr:      r->lit.strval = n->lit.strval;       break;
+                case Llbl:      r->lit.lblval = n->lit.lblval;       break;
                 case Lbool:     r->lit.boolval = n->lit.boolval;     break;
                 case Lfunc:     r->lit.fnval = specializenode(n->lit.fnval, tsmap);       break;
                 case Lseq:
@@ -251,9 +253,6 @@
             for (i = 0; i < n->block.nstmts; i++)
                 r->block.stmts[i] = specializenode(n->block.stmts[i], tsmap);
             popstab();
-            break;
-        case Nlbl:
-            r->lbl.name = strdup(n->lbl.name);
             break;
         case Ndecl:
             r->decl.did = maxdid++;