summaryrefslogtreecommitdiff
path: root/mi
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-05-08 01:47:40 -0700
committerOri Bernstein <ori@eigenstate.org>2015-05-08 01:47:40 -0700
commit1cb86ecfd69335631474bea4bb8a102e4559408a (patch)
treed0cb158e5f381385863c1e3bd6c0284b4f06159f /mi
parent3b2a10f280a9c927bd678199a90a96f8cddab89c (diff)
downloadmc-1cb86ecfd69335631474bea4bb8a102e4559408a.tar.gz
A few more fixes for dataflow checks.
Diffstat (limited to 'mi')
-rw-r--r--mi/dfcheck.c28
-rw-r--r--mi/reaching.c50
2 files changed, 58 insertions, 20 deletions
diff --git a/mi/dfcheck.c b/mi/dfcheck.c
index 7c91b3f..a5fc7c9 100644
--- a/mi/dfcheck.c
+++ b/mi/dfcheck.c
@@ -25,25 +25,27 @@ static void checkundef(Node *n, Reaching *r, Bitset *reach, Bitset *kill)
for (j = 0; j < r->ndefs[did]; j++) {
if (bshas(kill, r->defs[did][j]))
continue;
- if (bshas(reach, r->defs[did][j]))
- def = nodes[r->defs[did][j]];
+ if (!bshas(reach, r->defs[did][j]))
+ continue;
+ def = nodes[r->defs[did][j]];
if (exprop(def) == Oundef)
fatal(n, "%s used before definition", namestr(n->expr.args[0]));
}
} else {
- for (i = 0; i < n->expr.nargs; i++)
- checkundef(n->expr.args[i], r, reach, kill);
+ switch (exprop(n)) {
+ case Oset:
+ case Oasn:
+ case Oblit:
+ checkundef(n->expr.args[1], r, reach, kill);
+ break;
+ default:
+ for (i = 0; i < n->expr.nargs; i++)
+ checkundef(n->expr.args[i], r, reach, kill);
+ break;
+ }
}
}
-void bsdump(Bitset *bs)
-{
- size_t i;
- for (i = 0; bsiter(bs, &i); i++)
- printf("%zd ", i);
- printf("\n");
-}
-
static void checkreach(Cfg *cfg)
{
Bitset *reach, *kill;
@@ -108,6 +110,6 @@ static void checkret(Cfg *cfg)
void check(Cfg *cfg)
{
checkret(cfg);
- if(0)
+ if (0)
checkreach(cfg);
}
diff --git a/mi/reaching.c b/mi/reaching.c
index 7e7f640..fbfcd05 100644
--- a/mi/reaching.c
+++ b/mi/reaching.c
@@ -15,6 +15,8 @@
Node *assignee(Node *n)
{
+ Node *a;
+
switch (exprop(n)) {
case Oundef:
case Oset:
@@ -26,6 +28,14 @@ Node *assignee(Node *n)
case Obsreq:
return n->expr.args[0];
break;
+ case Oblit:
+ a = n->expr.args[0];
+ if (exprop(a) != Oaddr)
+ break;
+ a = n->expr.args[0];
+ if (exprop(a) != Ovar)
+ break;
+ return a;
default:
break;
}
@@ -64,12 +74,22 @@ static void genkill(Bb *bb, size_t **defs, size_t *ndefs, Bitset *gen, Bitset *k
if (!n)
continue;
did = n->expr.did;
- bsput(gen, bb->nl[i]->nid);
- for (j = 0; j < ndefs[did]; j++)
+ for (j = 0; j < ndefs[did]; j++) {
bsput(kill, defs[did][j]);
+ bsdel(gen, defs[did][j]);
+ }
+ bsput(gen, bb->nl[i]->nid);
+ bsdel(kill, bb->nl[i]->nid);
}
}
+void bsdump(Bitset *bs)
+{
+ size_t i;
+ for (i = 0; bsiter(bs, &i); i++)
+ printf("%zd ", i);
+ printf("\n");
+}
Reaching *reaching(Cfg *cfg)
{
@@ -104,12 +124,12 @@ Reaching *reaching(Cfg *cfg)
for (i = 0; i < cfg->nbb; i++) {
if (!cfg->bb[i])
continue;
- bbout = mkbs();
+ bbin = mkbs();
for (j = 0; bsiter(cfg->bb[i]->pred, &j); j++)
- bsunion(bbout, in[j]);
- bbin = bsdup(bbout);
- bsdiff(bbin, kill[i]);
- bsunion(bbin, gen[i]);
+ bsunion(bbin, out[j]);
+ bbout = bsdup(bbin);
+ bsdiff(bbout, kill[i]);
+ bsunion(bbout, gen[i]);
if (!bseq(out[i], bbout) || !bseq(in[i], bbin)) {
changed = 1;
@@ -121,6 +141,22 @@ Reaching *reaching(Cfg *cfg)
}
} while (changed);
+// for (i = 0; i < ndecls; i++) {
+// if (defs[i])
+// printf("\t%zd: ", i);
+// for (j = 0; j < ndefs[i]; j++)
+// printf("%zd ", defs[i][j]);
+// if (defs[i])
+// printf("\n");
+// }
+// for (i = 0; i < cfg->nbb; i++) {
+// printf("bb %zd\n", i);
+// printf("\tin: ");
+// bsdump(in[i]);
+// printf("\tout: ");
+// bsdump(out[i]);
+// }
+//
reaching = xalloc(sizeof(Reaching));
reaching->in = in;
reaching->out = out;