ref: f131beb59eaa565ea09ed598f2c1327ba0aec7f7
parent: b9cf654b6dd5daabf8fd69854443ec04b0cfcea1
author: Ori Bernstein <[email protected]>
date: Thu Oct 30 09:27:35 EDT 2014
Unrename 'opt' -> 'mi'
--- a/6/Makefile
+++ b/6/Makefile
@@ -8,7 +8,7 @@
simp.o \
typeinfo.o \
-DEPS=../parse/libparse.a ../opt/libmi.a
+DEPS=../parse/libparse.a ../mi/libmi.a
include ../config.mk
include ../mk/c.mk
--- a/6/gen.c
+++ b/6/gen.c
@@ -10,7 +10,7 @@
#include <unistd.h>
#include "parse.h"
-#include "opt.h"
+#include "mi.h"
#include "asm.h"
#include "../config.h"
--- a/6/isel.c
+++ b/6/isel.c
@@ -12,7 +12,7 @@
#include <unistd.h>
#include "parse.h"
-#include "opt.h"
+#include "mi.h"
#include "asm.h"
#include "../config.h"
--- a/6/locs.c
+++ b/6/locs.c
@@ -11,7 +11,7 @@
#include <unistd.h>
#include "parse.h"
-#include "opt.h"
+#include "mi.h"
#include "asm.h"
#include "../config.h"
--- a/6/main.c
+++ b/6/main.c
@@ -13,7 +13,7 @@
#include <sys/wait.h>
#include "parse.h"
-#include "opt.h"
+#include "mi.h"
#include "asm.h"
#include "../config.h"
--- a/6/ra.c
+++ b/6/ra.c
@@ -7,7 +7,7 @@
#include <string.h>
#include "parse.h"
-#include "opt.h"
+#include "mi.h"
#include "asm.h"
#define Sizetbits (CHAR_BIT*sizeof(size_t)) /* used in graph reprs */
--- a/6/simp.c
+++ b/6/simp.c
@@ -10,7 +10,7 @@
#include <unistd.h>
#include "parse.h"
-#include "opt.h"
+#include "mi.h"
#include "asm.h"
#include "../config.h"
--- a/6/typeinfo.c
+++ b/6/typeinfo.c
@@ -10,7 +10,7 @@
#include <unistd.h>
#include "parse.h"
-#include "opt.h"
+#include "mi.h"
#include "asm.h"
#include "../config.h"
--- /dev/null
+++ b/mi/Makefile
@@ -1,0 +1,9 @@
+LIB=libmi.a
+OBJ=cfg.o \
+ fold.o \
+ match.o \
+ df.o \
+
+DEPS=../parse/libparse.a
+
+include ../mk/c.mk
--- /dev/null
+++ b/mi/cfg.c
@@ -1,0 +1,309 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parse.h"
+#include "mi.h"
+
+
+static Bb *mkbb(Cfg *cfg)
+{
+ Bb *bb;
+
+ bb = zalloc(sizeof(Bb));
+ bb->id = cfg->nextbbid++;
+ bb->pred = mkbs();
+ bb->succ = mkbs();
+ lappend(&cfg->bb, &cfg->nbb, bb);
+ 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 strlabel(Cfg *cfg, char *lbl, Bb *bb)
+{
+ htput(cfg->lblmap, lbl, bb);
+ lappend(&bb->lbls, &bb->nlbls, lbl);
+}
+
+static void label(Cfg *cfg, Node *lbl, Bb *bb)
+{
+ strlabel(cfg, lblstr(lbl), bb);
+}
+
+static int isnonretcall(Node *fn)
+{
+ Node *dcl;
+
+ if (exprop(fn) != Ovar)
+ return 0;
+ dcl = decls[fn->expr.did];
+ return dcl->decl.isnoret;
+}
+
+static int addnode(Cfg *cfg, Bb *bb, Node *n)
+{
+ switch (exprop(n)) {
+ case Ojmp:
+ case Ocjmp:
+ case Oret:
+ lappend(&bb->nl, &bb->nnl, n);
+ lappend(&cfg->fixjmp, &cfg->nfixjmp, n);
+ lappend(&cfg->fixblk, &cfg->nfixblk, bb);
+ return 1;
+ break;
+ case Ocall:
+ lappend(&bb->nl, &bb->nnl, n);
+ return isnonretcall(n->expr.args[0]);
+ break;
+ default:
+ lappend(&bb->nl, &bb->nnl, n);
+ break;
+ }
+ 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, Srcloc loc)
+{
+ /* 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(loc, Ojmp, mklbl(loc, lblstr(nl[i])), NULL));
+ }
+ if (bb->nnl)
+ bb = mkbb(cfg);
+ label(cfg, nl[i], bb);
+ return bb;
+}
+
+void delete(Cfg *cfg, Bb *bb)
+{
+ size_t i, j;
+
+ if (bb == cfg->start || bb == cfg->end)
+ return;
+ for (i = 0; bsiter(bb->pred, &i); i++) {
+ bsunion(cfg->bb[i]->succ, bb->succ);
+ bsdel(cfg->bb[i]->succ, bb->id);
+ }
+ for (i = 0; bsiter(bb->succ, &i); i++) {
+ bsunion(cfg->bb[i]->pred, bb->pred);
+ bsdel(cfg->bb[i]->pred, bb->id);
+ for (j = 0; j < bb->nlbls; j++)
+ strlabel(cfg, bb->lbls[j], cfg->bb[i]);
+ }
+ cfg->bb[bb->id] = NULL;
+}
+
+void trimdead(Bb *bb)
+{
+ size_t i;
+
+ for (i = 0; i < bb->nnl; i++) {
+ switch (exprop(bb->nl[i])) {
+ /* if we're jumping, we can't keep going
+ * within this BB */
+ case Ojmp:
+ case Ocjmp:
+ case Oret:
+ bb->nnl = i + 1;
+ return;
+ case Ocall:
+ if (!isnonretcall(bb->nl[i]->expr.args[0]))
+ break;
+ bb->nnl = i + 1;
+ return;
+ default:
+ /* nothing */
+ break;
+ }
+ }
+}
+
+void trim(Cfg *cfg)
+{
+ Bb *bb;
+ size_t i;
+
+ /* delete empty blocks and trivially unreachable code */
+ for (i = 0; i < cfg->nbb; i++) {
+
+ bb = cfg->bb[i];
+ if (bb->nnl == 0)
+ delete(cfg, bb);
+ else
+ trimdead(bb);
+ }
+}
+
+void delunreachable(Cfg *cfg)
+{
+ Bb *bb;
+ size_t i;
+ int deleted;
+
+ deleted = 1;
+ while (deleted) {
+ deleted = 0;
+ for (i = 0; i < cfg->nbb; i++) {
+ bb = cfg->bb[i];
+ if (bb == cfg->start || bb == cfg->end)
+ continue;
+ if (bb && bsisempty(bb->pred)) {
+ delete(cfg, bb);
+ deleted = 1;
+ }
+ }
+ }
+}
+
+Cfg *mkcfg(Node *fn, Node **nl, size_t nn)
+{
+ Cfg *cfg;
+ Bb *pre, *post;
+ Bb *bb, *targ;
+ Node *a, *b;
+ size_t i;
+
+ cfg = zalloc(sizeof(Cfg));
+ cfg->fn = fn;
+ cfg->lblmap = mkht(strhash, streq);
+ pre = mkbb(cfg);
+ bb = mkbb(cfg);
+ for (i = 0; i < nn; i++) {
+ switch (nl[i]->type) {
+ case Nexpr:
+ if (islabel(nl[i]))
+ bb = addlabel(cfg, bb, nl, i, nl[i]->loc);
+ else if (addnode(cfg, bb, nl[i]))
+ bb = mkbb(cfg);
+ break;
+ break;
+ case Ndecl:
+ break;
+ default:
+ die("Invalid node type %s in mkcfg", nodestr(nl[i]->type));
+ }
+ }
+ post = mkbb(cfg);
+ cfg->start = pre;
+ cfg->end = post;
+ bsput(pre->succ, cfg->bb[1]->id);
+ bsput(cfg->bb[1]->pred, pre->id);
+ bsput(cfg->bb[cfg->nbb - 2]->succ, post->id);
+ bsput(post->pred, cfg->bb[cfg->nbb - 2]->id);
+ trim(cfg);
+
+ for (i = 0; i < cfg->nfixjmp; i++) {
+ bb = cfg->fixblk[i];
+ switch (exprop(cfg->fixjmp[i])) {
+ case Ojmp:
+ a = cfg->fixjmp[i]->expr.args[0];
+ b = NULL;
+ break;
+ case Ocjmp:
+ a = cfg->fixjmp[i]->expr.args[1];
+ b = cfg->fixjmp[i]->expr.args[2];
+ break;
+ case Oret:
+ a = mklbl(cfg->fixjmp[i]->loc, cfg->end->lbls[0]);
+ b = NULL;
+ break;
+ default:
+ die("Bad jump fix thingy");
+ break;
+ }
+ if (a) {
+ targ = htget(cfg->lblmap, lblstr(a));
+ if (!targ)
+ die("No bb with label \"%s\"", lblstr(a));
+ bsput(bb->succ, targ->id);
+ bsput(targ->pred, bb->id);
+ }
+ if (b) {
+ targ = htget(cfg->lblmap, lblstr(b));
+ if (!targ)
+ die("No bb with label \"%s\"", lblstr(b));
+ bsput(bb->succ, targ->id);
+ bsput(targ->pred, bb->id);
+ }
+ }
+ delunreachable(cfg);
+ return cfg;
+}
+
+void dumpcfg(Cfg *cfg, FILE *fd)
+{
+ size_t i, j;
+ Bb *bb;
+ char *sep;
+
+ for (j = 0; j < cfg->nbb; j++) {
+ bb = cfg->bb[j];
+ if (!bb)
+ continue;
+ fprintf(fd, "\n");
+ fprintf(fd, "Bb: %d labels=(", bb->id);
+ sep = "";
+ for (i = 0; i < bb->nlbls; i++) {;
+ fprintf(fd, "%s%s", bb->lbls[i], sep);
+ sep = ",";
+ }
+ fprintf(fd, ")\n");
+
+ /* in edges */
+ fprintf(fd, "Pred: ");
+ sep = "";
+ for (i = 0; i < bsmax(bb->pred); i++) {
+ if (bshas(bb->pred, i)) {
+ fprintf(fd, "%s%zd", sep, i);
+ sep = ",";
+ }
+ }
+ fprintf(fd, "\n");
+
+ /* out edges */
+ fprintf(fd, "Succ: ");
+ sep = "";
+ for (i = 0; i < bsmax(bb->succ); i++) {
+ if (bshas(bb->succ, i)) {
+ fprintf(fd, "%s%zd", sep, i);
+ sep = ",";
+ }
+ }
+ fprintf(fd, "\n");
+
+ for (i = 0; i < bb->nnl; i++)
+ dump(bb->nl[i], fd);
+ fprintf(fd, "\n");
+ }
+}
--- /dev/null
+++ b/mi/df.c
@@ -1,0 +1,70 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parse.h"
+#include "mi.h"
+
+/*
+static void nodeuse(Node *n, Bitset *bs)
+{
+}
+
+static void nodedef(Node *n, Bitset *bs)
+{
+}
+
+static void bbuse(Bb *bb, Bitset *bs)
+{
+}
+
+static void bbdef(Bb *bb, Bitset *bs)
+{
+}
+*/
+
+static void checkreach(Cfg *cfg)
+{
+}
+
+static void checkpredret(Cfg *cfg, Bb *bb)
+{
+ Bb *pred;
+ size_t i;
+
+ for (i = 0; bsiter(bb->pred, &i); i++) {
+ pred = cfg->bb[i];
+ if (pred->nnl == 0) {
+ checkpredret(cfg, pred);
+ } else if (exprop(pred->nl[pred->nnl - 1]) != Oret) {
+ dumpcfg(cfg, stdout);
+ fatal(pred->nl[pred->nnl-1], "Reaches end of function without return\n");
+ }
+ }
+}
+
+static void checkret(Cfg *cfg)
+{
+ Type *ft;
+
+ ft = tybase(decltype(cfg->fn));
+ assert(ft->type == Tyfunc);
+ if (ft->sub[0]->type == Tyvoid)
+ return;
+
+ checkpredret(cfg, cfg->end);
+}
+
+void check(Cfg *cfg)
+{
+ checkret(cfg);
+ checkreach(cfg);
+}
--- /dev/null
+++ b/mi/fold.c
@@ -1,0 +1,216 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parse.h"
+#include "mi.h"
+
+static int islit(Node *n, vlong *v)
+{
+ Node *l;
+
+ if (exprop(n) != Olit)
+ return 0;
+ l = n->expr.args[0];
+ if (l->lit.littype != Lint)
+ return 0;
+ *v = l->lit.intval;
+ return 1;
+}
+
+static int isval(Node *n, vlong val)
+{
+ vlong v;
+
+ if (!islit(n, &v))
+ return 0;
+ return v == val;
+}
+
+static Node *val(Srcloc loc, vlong val, Type *t)
+{
+ Node *l, *n;
+
+ l = mkint(loc, val);
+ n = mkexpr(loc, Olit, l, NULL);
+ l->lit.type = t;
+ n->expr.type = t;
+ return n;
+}
+
+static int issmallconst(Node *dcl)
+{
+ Type *t;
+
+ if (!dcl->decl.isconst)
+ return 0;
+ if (!dcl->decl.init)
+ return 0;
+ t = tybase(exprtype(dcl->decl.init));
+ if (t->type <= Tyflt64)
+ return 1;
+ return 0;
+}
+
+static Node *foldcast(Node *n)
+{
+ Type *to, *from;
+ Node *sub;
+
+ sub = n->expr.args[0];
+ to = exprtype(n);
+ from = exprtype(sub);
+
+ switch (tybase(to)->type) {
+ case Tybool:
+ case Tyint8: case Tyint16: case Tyint32: case Tyint64:
+ case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
+ case Tyint: case Tyuint: case Tylong: case Tyulong:
+ case Tychar: case Tybyte:
+ case Typtr:
+ switch (tybase(from)->type) {
+ case Tybool:
+ case Tyint8: case Tyint16: case Tyint32: case Tyint64:
+ case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
+ case Tyint: case Tyuint: case Tylong: case Tyulong:
+ case Tychar: case Tybyte:
+ case Typtr:
+ if (exprop(sub) == Olit || tybase(from)->type == tybase(to)->type) {
+ sub->expr.type = to;
+ return sub;
+ } else {
+ return n;
+ }
+ default:
+ return n;
+ }
+ default:
+ return n;
+ }
+ return n;
+}
+
+
+
+Node *fold(Node *n, int foldvar)
+{
+ Node **args, *r;
+ Type *t;
+ vlong a, b;
+ size_t i;
+
+ if (!n)
+ return NULL;
+ if (n->type != Nexpr)
+ return n;
+
+ r = NULL;
+ args = n->expr.args;
+ for (i = 0; i < n->expr.nargs; i++)
+ args[i] = fold(args[i], foldvar);
+ switch (exprop(n)) {
+ case Ovar:
+ if (foldvar && issmallconst(decls[n->expr.did]))
+ r = fold(decls[n->expr.did]->decl.init, foldvar);
+ break;
+ case Oadd:
+ /* x + 0 = 0 */
+ if (isval(args[0], 0))
+ r = args[1];
+ if (isval(args[1], 0))
+ r = args[0];
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a + b, exprtype(n));
+ break;
+ case Osub:
+ /* x - 0 = 0 */
+ if (isval(args[1], 0))
+ r = args[0];
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a - b, exprtype(n));
+ break;
+ case Omul:
+ /* 1 * x = x */
+ if (isval(args[0], 1))
+ r = args[1];
+ if (isval(args[1], 1))
+ r = args[0];
+ /* 0 * x = 0 */
+ if (isval(args[0], 0))
+ r = args[0];
+ if (isval(args[1], 0))
+ r = args[1];
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a * b, exprtype(n));
+ break;
+ case Odiv:
+ /* x/1 = x */
+ if (isval(args[1], 1))
+ r = args[0];
+ /* 0/x = 0 */
+ if (isval(args[1], 0))
+ r = args[1];
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a / b, exprtype(n));
+ break;
+ case Omod:
+ /* x%1 = x */
+ if (isval(args[1], 0))
+ r = args[0];
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a % b, exprtype(n));
+ break;
+ case Oneg:
+ if (islit(args[0], &a))
+ r = val(n->loc, -a, exprtype(n));
+ break;
+ case Obsl:
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a << b, exprtype(n));
+ break;
+ case Obsr:
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a >> b, exprtype(n));
+ break;
+ case Obor:
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a | b, exprtype(n));
+ break;
+ case Oband:
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a & b, exprtype(n));
+ break;
+ case Obxor:
+ if (islit(args[0], &a) && islit(args[1], &b))
+ r = val(n->loc, a ^ b, exprtype(n));
+ break;
+ case Omemb:
+ t = tybase(exprtype(args[0]));
+ /* we only fold lengths right now */
+ if (t->type == Tyarray && !strcmp(namestr(args[1]), "len"))
+ r = t->asize;
+ break;
+ case Ocast:
+ r = foldcast(n);
+ break;
+ default:
+ break;
+ }
+
+ if (r && n->expr.idx)
+ r->expr.idx = n->expr.idx;
+
+ if (r)
+ return r;
+ else
+ return n;
+}
+
--- /dev/null
+++ b/mi/match.c
@@ -1,0 +1,194 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parse.h"
+#include "mi.h"
+
+typedef struct Dtree Dtree;
+struct Dtree {
+ /* If the values are equal, go to 'sub'. If 'val' is null, anything matches. */
+ Node **val; /* values to compare against */
+ size_t nval;
+ Node **load; /* values being loaded */
+ size_t nload;
+ Dtree **sub; /* submatches for an equal comparison */
+ size_t nsub;
+ Dtree *any; /* tree for a wildcard match. */
+
+ /* captured variables and action */
+ Node **cap;
+ size_t ncap;
+ Node *act;
+
+};
+
+static Dtree *addpat(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap);
+
+static Dtree *mkdtree()
+{
+ return zalloc(sizeof(Dtree));
+}
+
+static Dtree *addwild(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
+{
+ Node *dcl;
+
+ dcl = decls[pat->expr.did];
+ /* FIXME: Avoid duplicate constants */
+ if (dcl->decl.isconst)
+ return NULL;
+ if (t->any)
+ return t->any;
+ t->any = mkdtree();
+ lappend(cap, ncap, pat);
+ return t->any;
+}
+
+static Dtree *addunion(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
+{
+ Dtree *sub;
+ size_t i;
+
+ /* if we have the value already... */
+ sub = NULL;
+ for (i = 0; i < t->nval; i++) {
+ if (nameeq(t->val[i], pat->expr.args[0]))
+ return addpat(t->sub[i], pat->expr.args[1], NULL, cap, ncap);
+ }
+
+ sub = mkdtree();
+ lappend(&t->val, &t->nval, pat->expr.args[0]);
+ lappend(&t->sub, &t->nsub, sub);
+ if (pat->expr.nargs == 2)
+ sub = addpat(sub, pat->expr.args[1], NULL, cap, ncap);
+ return sub;
+}
+
+static Dtree *addlit(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
+{
+ Dtree *sub;
+ size_t i;
+
+ for (i = 0; i < t->nval; i++) {
+ if (liteq(t->val[i]->expr.args[0], pat->expr.args[0]))
+ return addpat(t->sub[i], pat->expr.args[1], NULL, cap, ncap);
+ }
+
+ sub = mkdtree();
+ lappend(&t->val, &t->nval, pat);
+ lappend(&t->sub, &t->nsub, sub);
+ return sub;
+}
+
+static Dtree *addtup(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
+{
+ size_t i;
+
+ for (i = 0; i < pat->expr.nargs; i++)
+ t = addpat(t, pat->expr.args[i], NULL, cap, ncap);
+ return t;
+}
+
+static Dtree *addarr(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
+{
+ size_t i;
+
+ for (i = 0; i < pat->expr.nargs; i++)
+ t = addpat(t, pat->expr.args[i], NULL, cap, ncap);
+ return t;
+}
+
+static Dtree *addstruct(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
+{
+ Node *elt;
+ size_t i, j;
+
+ for (i = 0; i < pat->expr.nargs; i++) {
+ elt = pat->expr.args[i];
+ for (j = 0; j < t->nval; j++) {
+ if (!strcmp(namestr(elt->expr.idx), namestr(t->val[j]->expr.idx)))
+ t = addpat(t, pat->expr.args[i], NULL, cap, ncap);
+ break;
+ }
+ }
+ return t;
+}
+
+static Dtree *addpat(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
+{
+ Dtree *ret;
+
+ if (pat == NULL)
+ return t;
+ switch (exprop(pat)) {
+ case Ovar:
+ ret = addwild(t, pat, val, cap, ncap);
+ break;
+ case Oucon:
+ ret = addunion(t, pat, val, cap, ncap);
+ break;
+ case Olit:
+ ret = addlit(t, pat, val, cap, ncap);
+ break;
+ case Otup:
+ ret = addtup(t, pat, val, cap, ncap);
+ break;
+ case Oarr:
+ ret = addarr(t, pat, val, cap, ncap);
+ break;
+ case Ostruct:
+ ret = addstruct(t, pat, val, cap, ncap);
+ break;
+ default:
+ ret = NULL;
+ fatal(pat, "unsupported pattern %s of type %s", opstr(exprop(pat)), tystr(exprtype(pat)));
+ break;
+ }
+
+ return ret;
+}
+
+static void checkcomprehensive(Dtree *dt)
+{
+}
+
+static Node *genmatch(Dtree *dt)
+{
+ return NULL;
+}
+
+Node *gensimpmatch(Node *m)
+{
+ Dtree *t, *leaf;
+ Node **pat, **cap;
+ size_t npat, ncap;
+ size_t i;
+
+ t = mkdtree();
+ pat = m->matchstmt.matches;
+ npat = m->matchstmt.nmatches;
+ cap = NULL;
+ ncap = 0;
+ for (i = 0; i < npat; i++) {
+ leaf = addpat(t, pat[i]->match.pat, NULL, &cap, &ncap);
+ /* TODO: NULL is returned by unsupported patterns. */
+ if (!leaf)
+ return NULL;
+ if (leaf->act)
+ fatal(pat[i], "pattern matched by earlier case");
+ leaf->act = pat[i]->match.block;
+ leaf->cap = cap;
+ leaf->ncap = ncap;
+ }
+ checkcomprehensive(t);
+ return genmatch(t);
+}
--- /dev/null
+++ b/mi/mi.h
@@ -1,0 +1,38 @@
+typedef struct Cfg Cfg;
+typedef struct Bb Bb;
+
+struct Cfg {
+ Node *fn;
+ Bb **bb;
+ Bb *start;
+ Bb *end;
+ size_t nbb;
+
+ /* for building bb */
+ int nextbbid;
+ Htab *lblmap; /* label => Bb mapping */
+ Node **fixjmp;
+ size_t nfixjmp;
+ Bb **fixblk;
+ size_t nfixblk;
+};
+
+struct Bb {
+ int id;
+ char **lbls;
+ size_t nlbls;
+ Node **nl;
+ size_t nnl;
+ Bitset *pred;
+ Bitset *succ;
+};
+
+/* expression folding */
+Node *fold(Node *n, int foldvar);
+/* Takes a reduced block, and returns a flow graph. */
+Cfg *mkcfg(Node *fn, Node **nl, size_t nn);
+void dumpcfg(Cfg *c, FILE *fd);
+void check(Cfg *cfg);
+
+/* pattern matching */
+Node *gensimpmatch(Node *m);
--- /dev/null
+++ b/mi/mkfile
@@ -1,0 +1,14 @@
+</$objtype/mkfile
+CC=pcc
+LD=pcc
+CFLAGS=-c -D_POSIX_SOURCE -D_SUSV2_SOURCE -D_C99_SNPRINTF_EXTENSION -I../parse
+
+LIB=libopt.a
+OFILES=cfg.$O \
+ fold.$O \
+ df.$O
+
+HFILES=opt.h
+
+</sys/src/cmd/mklib
+
--- a/opt/Makefile
+++ /dev/null
@@ -1,9 +1,0 @@
-LIB=libmi.a
-OBJ=cfg.o \
- fold.o \
- match.o \
- df.o \
-
-DEPS=../parse/libparse.a
-
-include ../mk/c.mk
--- a/opt/cfg.c
+++ /dev/null
@@ -1,309 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "parse.h"
-#include "opt.h"
-
-
-static Bb *mkbb(Cfg *cfg)
-{
- Bb *bb;
-
- bb = zalloc(sizeof(Bb));
- bb->id = cfg->nextbbid++;
- bb->pred = mkbs();
- bb->succ = mkbs();
- lappend(&cfg->bb, &cfg->nbb, bb);
- 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 strlabel(Cfg *cfg, char *lbl, Bb *bb)
-{
- htput(cfg->lblmap, lbl, bb);
- lappend(&bb->lbls, &bb->nlbls, lbl);
-}
-
-static void label(Cfg *cfg, Node *lbl, Bb *bb)
-{
- strlabel(cfg, lblstr(lbl), bb);
-}
-
-static int isnonretcall(Node *fn)
-{
- Node *dcl;
-
- if (exprop(fn) != Ovar)
- return 0;
- dcl = decls[fn->expr.did];
- return dcl->decl.isnoret;
-}
-
-static int addnode(Cfg *cfg, Bb *bb, Node *n)
-{
- switch (exprop(n)) {
- case Ojmp:
- case Ocjmp:
- case Oret:
- lappend(&bb->nl, &bb->nnl, n);
- lappend(&cfg->fixjmp, &cfg->nfixjmp, n);
- lappend(&cfg->fixblk, &cfg->nfixblk, bb);
- return 1;
- break;
- case Ocall:
- lappend(&bb->nl, &bb->nnl, n);
- return isnonretcall(n->expr.args[0]);
- break;
- default:
- lappend(&bb->nl, &bb->nnl, n);
- break;
- }
- 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, Srcloc loc)
-{
- /* 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(loc, Ojmp, mklbl(loc, lblstr(nl[i])), NULL));
- }
- if (bb->nnl)
- bb = mkbb(cfg);
- label(cfg, nl[i], bb);
- return bb;
-}
-
-void delete(Cfg *cfg, Bb *bb)
-{
- size_t i, j;
-
- if (bb == cfg->start || bb == cfg->end)
- return;
- for (i = 0; bsiter(bb->pred, &i); i++) {
- bsunion(cfg->bb[i]->succ, bb->succ);
- bsdel(cfg->bb[i]->succ, bb->id);
- }
- for (i = 0; bsiter(bb->succ, &i); i++) {
- bsunion(cfg->bb[i]->pred, bb->pred);
- bsdel(cfg->bb[i]->pred, bb->id);
- for (j = 0; j < bb->nlbls; j++)
- strlabel(cfg, bb->lbls[j], cfg->bb[i]);
- }
- cfg->bb[bb->id] = NULL;
-}
-
-void trimdead(Bb *bb)
-{
- size_t i;
-
- for (i = 0; i < bb->nnl; i++) {
- switch (exprop(bb->nl[i])) {
- /* if we're jumping, we can't keep going
- * within this BB */
- case Ojmp:
- case Ocjmp:
- case Oret:
- bb->nnl = i + 1;
- return;
- case Ocall:
- if (!isnonretcall(bb->nl[i]->expr.args[0]))
- break;
- bb->nnl = i + 1;
- return;
- default:
- /* nothing */
- break;
- }
- }
-}
-
-void trim(Cfg *cfg)
-{
- Bb *bb;
- size_t i;
-
- /* delete empty blocks and trivially unreachable code */
- for (i = 0; i < cfg->nbb; i++) {
-
- bb = cfg->bb[i];
- if (bb->nnl == 0)
- delete(cfg, bb);
- else
- trimdead(bb);
- }
-}
-
-void delunreachable(Cfg *cfg)
-{
- Bb *bb;
- size_t i;
- int deleted;
-
- deleted = 1;
- while (deleted) {
- deleted = 0;
- for (i = 0; i < cfg->nbb; i++) {
- bb = cfg->bb[i];
- if (bb == cfg->start || bb == cfg->end)
- continue;
- if (bb && bsisempty(bb->pred)) {
- delete(cfg, bb);
- deleted = 1;
- }
- }
- }
-}
-
-Cfg *mkcfg(Node *fn, Node **nl, size_t nn)
-{
- Cfg *cfg;
- Bb *pre, *post;
- Bb *bb, *targ;
- Node *a, *b;
- size_t i;
-
- cfg = zalloc(sizeof(Cfg));
- cfg->fn = fn;
- cfg->lblmap = mkht(strhash, streq);
- pre = mkbb(cfg);
- bb = mkbb(cfg);
- for (i = 0; i < nn; i++) {
- switch (nl[i]->type) {
- case Nexpr:
- if (islabel(nl[i]))
- bb = addlabel(cfg, bb, nl, i, nl[i]->loc);
- else if (addnode(cfg, bb, nl[i]))
- bb = mkbb(cfg);
- break;
- break;
- case Ndecl:
- break;
- default:
- die("Invalid node type %s in mkcfg", nodestr(nl[i]->type));
- }
- }
- post = mkbb(cfg);
- cfg->start = pre;
- cfg->end = post;
- bsput(pre->succ, cfg->bb[1]->id);
- bsput(cfg->bb[1]->pred, pre->id);
- bsput(cfg->bb[cfg->nbb - 2]->succ, post->id);
- bsput(post->pred, cfg->bb[cfg->nbb - 2]->id);
- trim(cfg);
-
- for (i = 0; i < cfg->nfixjmp; i++) {
- bb = cfg->fixblk[i];
- switch (exprop(cfg->fixjmp[i])) {
- case Ojmp:
- a = cfg->fixjmp[i]->expr.args[0];
- b = NULL;
- break;
- case Ocjmp:
- a = cfg->fixjmp[i]->expr.args[1];
- b = cfg->fixjmp[i]->expr.args[2];
- break;
- case Oret:
- a = mklbl(cfg->fixjmp[i]->loc, cfg->end->lbls[0]);
- b = NULL;
- break;
- default:
- die("Bad jump fix thingy");
- break;
- }
- if (a) {
- targ = htget(cfg->lblmap, lblstr(a));
- if (!targ)
- die("No bb with label \"%s\"", lblstr(a));
- bsput(bb->succ, targ->id);
- bsput(targ->pred, bb->id);
- }
- if (b) {
- targ = htget(cfg->lblmap, lblstr(b));
- if (!targ)
- die("No bb with label \"%s\"", lblstr(b));
- bsput(bb->succ, targ->id);
- bsput(targ->pred, bb->id);
- }
- }
- delunreachable(cfg);
- return cfg;
-}
-
-void dumpcfg(Cfg *cfg, FILE *fd)
-{
- size_t i, j;
- Bb *bb;
- char *sep;
-
- for (j = 0; j < cfg->nbb; j++) {
- bb = cfg->bb[j];
- if (!bb)
- continue;
- fprintf(fd, "\n");
- fprintf(fd, "Bb: %d labels=(", bb->id);
- sep = "";
- for (i = 0; i < bb->nlbls; i++) {;
- fprintf(fd, "%s%s", bb->lbls[i], sep);
- sep = ",";
- }
- fprintf(fd, ")\n");
-
- /* in edges */
- fprintf(fd, "Pred: ");
- sep = "";
- for (i = 0; i < bsmax(bb->pred); i++) {
- if (bshas(bb->pred, i)) {
- fprintf(fd, "%s%zd", sep, i);
- sep = ",";
- }
- }
- fprintf(fd, "\n");
-
- /* out edges */
- fprintf(fd, "Succ: ");
- sep = "";
- for (i = 0; i < bsmax(bb->succ); i++) {
- if (bshas(bb->succ, i)) {
- fprintf(fd, "%s%zd", sep, i);
- sep = ",";
- }
- }
- fprintf(fd, "\n");
-
- for (i = 0; i < bb->nnl; i++)
- dump(bb->nl[i], fd);
- fprintf(fd, "\n");
- }
-}
--- a/opt/df.c
+++ /dev/null
@@ -1,70 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "parse.h"
-#include "opt.h"
-
-/*
-static void nodeuse(Node *n, Bitset *bs)
-{
-}
-
-static void nodedef(Node *n, Bitset *bs)
-{
-}
-
-static void bbuse(Bb *bb, Bitset *bs)
-{
-}
-
-static void bbdef(Bb *bb, Bitset *bs)
-{
-}
-*/
-
-static void checkreach(Cfg *cfg)
-{
-}
-
-static void checkpredret(Cfg *cfg, Bb *bb)
-{
- Bb *pred;
- size_t i;
-
- for (i = 0; bsiter(bb->pred, &i); i++) {
- pred = cfg->bb[i];
- if (pred->nnl == 0) {
- checkpredret(cfg, pred);
- } else if (exprop(pred->nl[pred->nnl - 1]) != Oret) {
- dumpcfg(cfg, stdout);
- fatal(pred->nl[pred->nnl-1], "Reaches end of function without return\n");
- }
- }
-}
-
-static void checkret(Cfg *cfg)
-{
- Type *ft;
-
- ft = tybase(decltype(cfg->fn));
- assert(ft->type == Tyfunc);
- if (ft->sub[0]->type == Tyvoid)
- return;
-
- checkpredret(cfg, cfg->end);
-}
-
-void check(Cfg *cfg)
-{
- checkret(cfg);
- checkreach(cfg);
-}
--- a/opt/fold.c
+++ /dev/null
@@ -1,216 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "parse.h"
-#include "opt.h"
-
-static int islit(Node *n, vlong *v)
-{
- Node *l;
-
- if (exprop(n) != Olit)
- return 0;
- l = n->expr.args[0];
- if (l->lit.littype != Lint)
- return 0;
- *v = l->lit.intval;
- return 1;
-}
-
-static int isval(Node *n, vlong val)
-{
- vlong v;
-
- if (!islit(n, &v))
- return 0;
- return v == val;
-}
-
-static Node *val(Srcloc loc, vlong val, Type *t)
-{
- Node *l, *n;
-
- l = mkint(loc, val);
- n = mkexpr(loc, Olit, l, NULL);
- l->lit.type = t;
- n->expr.type = t;
- return n;
-}
-
-static int issmallconst(Node *dcl)
-{
- Type *t;
-
- if (!dcl->decl.isconst)
- return 0;
- if (!dcl->decl.init)
- return 0;
- t = tybase(exprtype(dcl->decl.init));
- if (t->type <= Tyflt64)
- return 1;
- return 0;
-}
-
-static Node *foldcast(Node *n)
-{
- Type *to, *from;
- Node *sub;
-
- sub = n->expr.args[0];
- to = exprtype(n);
- from = exprtype(sub);
-
- switch (tybase(to)->type) {
- case Tybool:
- case Tyint8: case Tyint16: case Tyint32: case Tyint64:
- case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
- case Tyint: case Tyuint: case Tylong: case Tyulong:
- case Tychar: case Tybyte:
- case Typtr:
- switch (tybase(from)->type) {
- case Tybool:
- case Tyint8: case Tyint16: case Tyint32: case Tyint64:
- case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
- case Tyint: case Tyuint: case Tylong: case Tyulong:
- case Tychar: case Tybyte:
- case Typtr:
- if (exprop(sub) == Olit || tybase(from)->type == tybase(to)->type) {
- sub->expr.type = to;
- return sub;
- } else {
- return n;
- }
- default:
- return n;
- }
- default:
- return n;
- }
- return n;
-}
-
-
-
-Node *fold(Node *n, int foldvar)
-{
- Node **args, *r;
- Type *t;
- vlong a, b;
- size_t i;
-
- if (!n)
- return NULL;
- if (n->type != Nexpr)
- return n;
-
- r = NULL;
- args = n->expr.args;
- for (i = 0; i < n->expr.nargs; i++)
- args[i] = fold(args[i], foldvar);
- switch (exprop(n)) {
- case Ovar:
- if (foldvar && issmallconst(decls[n->expr.did]))
- r = fold(decls[n->expr.did]->decl.init, foldvar);
- break;
- case Oadd:
- /* x + 0 = 0 */
- if (isval(args[0], 0))
- r = args[1];
- if (isval(args[1], 0))
- r = args[0];
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a + b, exprtype(n));
- break;
- case Osub:
- /* x - 0 = 0 */
- if (isval(args[1], 0))
- r = args[0];
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a - b, exprtype(n));
- break;
- case Omul:
- /* 1 * x = x */
- if (isval(args[0], 1))
- r = args[1];
- if (isval(args[1], 1))
- r = args[0];
- /* 0 * x = 0 */
- if (isval(args[0], 0))
- r = args[0];
- if (isval(args[1], 0))
- r = args[1];
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a * b, exprtype(n));
- break;
- case Odiv:
- /* x/1 = x */
- if (isval(args[1], 1))
- r = args[0];
- /* 0/x = 0 */
- if (isval(args[1], 0))
- r = args[1];
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a / b, exprtype(n));
- break;
- case Omod:
- /* x%1 = x */
- if (isval(args[1], 0))
- r = args[0];
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a % b, exprtype(n));
- break;
- case Oneg:
- if (islit(args[0], &a))
- r = val(n->loc, -a, exprtype(n));
- break;
- case Obsl:
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a << b, exprtype(n));
- break;
- case Obsr:
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a >> b, exprtype(n));
- break;
- case Obor:
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a | b, exprtype(n));
- break;
- case Oband:
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a & b, exprtype(n));
- break;
- case Obxor:
- if (islit(args[0], &a) && islit(args[1], &b))
- r = val(n->loc, a ^ b, exprtype(n));
- break;
- case Omemb:
- t = tybase(exprtype(args[0]));
- /* we only fold lengths right now */
- if (t->type == Tyarray && !strcmp(namestr(args[1]), "len"))
- r = t->asize;
- break;
- case Ocast:
- r = foldcast(n);
- break;
- default:
- break;
- }
-
- if (r && n->expr.idx)
- r->expr.idx = n->expr.idx;
-
- if (r)
- return r;
- else
- return n;
-}
-
--- a/opt/match.c
+++ /dev/null
@@ -1,194 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "parse.h"
-#include "opt.h"
-
-typedef struct Dtree Dtree;
-struct Dtree {
- /* If the values are equal, go to 'sub'. If 'val' is null, anything matches. */
- Node **val; /* values to compare against */
- size_t nval;
- Node **load; /* values being loaded */
- size_t nload;
- Dtree **sub; /* submatches for an equal comparison */
- size_t nsub;
- Dtree *any; /* tree for a wildcard match. */
-
- /* captured variables and action */
- Node **cap;
- size_t ncap;
- Node *act;
-
-};
-
-static Dtree *addpat(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap);
-
-static Dtree *mkdtree()
-{
- return zalloc(sizeof(Dtree));
-}
-
-static Dtree *addwild(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
-{
- Node *dcl;
-
- dcl = decls[pat->expr.did];
- /* FIXME: Avoid duplicate constants */
- if (dcl->decl.isconst)
- return NULL;
- if (t->any)
- return t->any;
- t->any = mkdtree();
- lappend(cap, ncap, pat);
- return t->any;
-}
-
-static Dtree *addunion(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
-{
- Dtree *sub;
- size_t i;
-
- /* if we have the value already... */
- sub = NULL;
- for (i = 0; i < t->nval; i++) {
- if (nameeq(t->val[i], pat->expr.args[0]))
- return addpat(t->sub[i], pat->expr.args[1], NULL, cap, ncap);
- }
-
- sub = mkdtree();
- lappend(&t->val, &t->nval, pat->expr.args[0]);
- lappend(&t->sub, &t->nsub, sub);
- if (pat->expr.nargs == 2)
- sub = addpat(sub, pat->expr.args[1], NULL, cap, ncap);
- return sub;
-}
-
-static Dtree *addlit(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
-{
- Dtree *sub;
- size_t i;
-
- for (i = 0; i < t->nval; i++) {
- if (liteq(t->val[i]->expr.args[0], pat->expr.args[0]))
- return addpat(t->sub[i], pat->expr.args[1], NULL, cap, ncap);
- }
-
- sub = mkdtree();
- lappend(&t->val, &t->nval, pat);
- lappend(&t->sub, &t->nsub, sub);
- return sub;
-}
-
-static Dtree *addtup(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
-{
- size_t i;
-
- for (i = 0; i < pat->expr.nargs; i++)
- t = addpat(t, pat->expr.args[i], NULL, cap, ncap);
- return t;
-}
-
-static Dtree *addarr(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
-{
- size_t i;
-
- for (i = 0; i < pat->expr.nargs; i++)
- t = addpat(t, pat->expr.args[i], NULL, cap, ncap);
- return t;
-}
-
-static Dtree *addstruct(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
-{
- Node *elt;
- size_t i, j;
-
- for (i = 0; i < pat->expr.nargs; i++) {
- elt = pat->expr.args[i];
- for (j = 0; j < t->nval; j++) {
- if (!strcmp(namestr(elt->expr.idx), namestr(t->val[j]->expr.idx)))
- t = addpat(t, pat->expr.args[i], NULL, cap, ncap);
- break;
- }
- }
- return t;
-}
-
-static Dtree *addpat(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap)
-{
- Dtree *ret;
-
- if (pat == NULL)
- return t;
- switch (exprop(pat)) {
- case Ovar:
- ret = addwild(t, pat, val, cap, ncap);
- break;
- case Oucon:
- ret = addunion(t, pat, val, cap, ncap);
- break;
- case Olit:
- ret = addlit(t, pat, val, cap, ncap);
- break;
- case Otup:
- ret = addtup(t, pat, val, cap, ncap);
- break;
- case Oarr:
- ret = addarr(t, pat, val, cap, ncap);
- break;
- case Ostruct:
- ret = addstruct(t, pat, val, cap, ncap);
- break;
- default:
- ret = NULL;
- fatal(pat, "unsupported pattern %s of type %s", opstr(exprop(pat)), tystr(exprtype(pat)));
- break;
- }
-
- return ret;
-}
-
-static void checkcomprehensive(Dtree *dt)
-{
-}
-
-static Node *genmatch(Dtree *dt)
-{
- return NULL;
-}
-
-Node *gensimpmatch(Node *m)
-{
- Dtree *t, *leaf;
- Node **pat, **cap;
- size_t npat, ncap;
- size_t i;
-
- t = mkdtree();
- pat = m->matchstmt.matches;
- npat = m->matchstmt.nmatches;
- cap = NULL;
- ncap = 0;
- for (i = 0; i < npat; i++) {
- leaf = addpat(t, pat[i]->match.pat, NULL, &cap, &ncap);
- /* TODO: NULL is returned by unsupported patterns. */
- if (!leaf)
- return NULL;
- if (leaf->act)
- fatal(pat[i], "pattern matched by earlier case");
- leaf->act = pat[i]->match.block;
- leaf->cap = cap;
- leaf->ncap = ncap;
- }
- checkcomprehensive(t);
- return genmatch(t);
-}
--- a/opt/mkfile
+++ /dev/null
@@ -1,14 +1,0 @@
-</$objtype/mkfile
-CC=pcc
-LD=pcc
-CFLAGS=-c -D_POSIX_SOURCE -D_SUSV2_SOURCE -D_C99_SNPRINTF_EXTENSION -I../parse
-
-LIB=libopt.a
-OFILES=cfg.$O \
- fold.$O \
- df.$O
-
-HFILES=opt.h
-
-</sys/src/cmd/mklib
-
--- a/opt/opt.h
+++ /dev/null
@@ -1,38 +1,0 @@
-typedef struct Cfg Cfg;
-typedef struct Bb Bb;
-
-struct Cfg {
- Node *fn;
- Bb **bb;
- Bb *start;
- Bb *end;
- size_t nbb;
-
- /* for building bb */
- int nextbbid;
- Htab *lblmap; /* label => Bb mapping */
- Node **fixjmp;
- size_t nfixjmp;
- Bb **fixblk;
- size_t nfixblk;
-};
-
-struct Bb {
- int id;
- char **lbls;
- size_t nlbls;
- Node **nl;
- size_t nnl;
- Bitset *pred;
- Bitset *succ;
-};
-
-/* expression folding */
-Node *fold(Node *n, int foldvar);
-/* Takes a reduced block, and returns a flow graph. */
-Cfg *mkcfg(Node *fn, Node **nl, size_t nn);
-void dumpcfg(Cfg *c, FILE *fd);
-void check(Cfg *cfg);
-
-/* pattern matching */
-Node *gensimpmatch(Node *m);