diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-05-08 20:22:21 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-05-08 20:22:21 -0700 |
commit | 8c8335a2471a99d29e26ca60788ec7dc6dd5e768 (patch) | |
tree | 5be5286364828f7ae0fef88437aa941db39d45e9 | |
parent | ae3b82a3fa5ee691c7f25bdb80be2b9c62a2b3cc (diff) | |
download | mc-8c8335a2471a99d29e26ca60788ec7dc6dd5e768.tar.gz |
Use before def checking is closer to working.
Reduce spurious errors.
-rw-r--r-- | 6/isel.c | 1 | ||||
-rw-r--r-- | 6/simp.c | 62 | ||||
-rw-r--r-- | mi/dfcheck.c | 21 | ||||
-rw-r--r-- | mi/reaching.c | 7 | ||||
-rw-r--r-- | parse/gram.y | 13 | ||||
-rw-r--r-- | parse/infer.c | 9 | ||||
-rw-r--r-- | parse/ops.def | 1 | ||||
-rw-r--r-- | test/derefassign.myr | 1 |
8 files changed, 84 insertions, 31 deletions
@@ -778,6 +778,7 @@ Loc *selexpr(Isel *s, Node *n) break; case Odead: case Oundef: + case Odef: /* nothing */ break; @@ -70,6 +70,21 @@ Type *tyword; Type *tyvoid; Node *abortoob; +static void append(Simp *s, Node *n) +{ + lappend(&s->stmts, &s->nstmts, n); +} + +static int ispure(Node *n) +{ + return opispure[exprop(n)]; +} + +static int isconstfn(Node *s) +{ + return s->decl.isconst && decltype(s)->type == Tyfunc; +} + size_t alignto(size_t sz, Type *t) { size_t a; @@ -253,6 +268,15 @@ static Node *set(Node *a, Node *b) return n; } +static void def(Simp *s, Node *var) +{ + Node *d; + + d = mkexpr(var->loc, Odef, var, NULL); + d->expr.type = mktype(var->loc, Tyvoid); + append(s, d); +} + static Node *disp(Srcloc loc, uint v) { Node *n; @@ -271,21 +295,6 @@ static Node *word(Srcloc loc, uint v) return n; } -static void append(Simp *s, Node *n) -{ - lappend(&s->stmts, &s->nstmts, n); -} - -static int ispure(Node *n) -{ - return opispure[exprop(n)]; -} - -static int isconstfn(Node *s) -{ - return s->decl.isconst && decltype(s)->type == Tyfunc; -} - static Node *gentemp(Simp *simp, Node *e, Type *ty, Node **dcl) { char buf[128]; @@ -470,6 +479,7 @@ static void simpiter(Simp *s, Node *n) append(s, assign(s, idx, zero)); jmp(s, lcond); simp(s, lbody); + /* body */ simp(s, n->iterstmt.body); /* step */ @@ -1363,6 +1373,9 @@ static Node *rval(Simp *s, Node *n, Node *dst) case Ostruct: if (!dst) dst = temp(s, n); + u = mkexpr(dst->loc, Odef, dst, NULL); + u->expr.type = mktype(u->loc, Tyvoid); + append(s, u); t = addr(s, dst, exprtype(dst)); ty = exprtype(n); /* we only need to clear if we don't have things fully initialized */ @@ -1475,8 +1488,13 @@ static Node *rval(Simp *s, Node *n, Node *dst) else r = temp(s, n); linsert(&n->expr.args, &n->expr.nargs, 1, addr(s, r, exprtype(n))); - for (i = 0; i < n->expr.nargs; i++) + for (i = 0; i < n->expr.nargs; i++) { n->expr.args[i] = rval(s, n->expr.args[i], NULL); + if (exprop(n->expr.args[i]) == Oaddr) + if (exprop(n->expr.args[i]->expr.args[0]) == Ovar) + def(s, n->expr.args[i]->expr.args[0]); + } + def(s, r); append(s, n); } else { r = visit(s, n); @@ -1588,18 +1606,16 @@ static Node *simp(Simp *s, Node *n) case Ndecl: declarelocal(s, n); t = mkexpr(n->loc, Ovar, n->decl.name, NULL); - if (!n->decl.init) { - u = mkexpr(n->loc, Oundef, t, NULL); - u->expr.type = mktype(n->loc, Tyvoid); - } else { + if (n->decl.init) { u = mkexpr(n->loc, Oasn, t, n->decl.init, NULL); u->expr.type = n->decl.type; + t->expr.type = n->decl.type; + t->expr.did = n->decl.did; + simp(s, u); } - t->expr.type = n->decl.type; - t->expr.did = n->decl.did; - simp(s, u); break; default: + dump(n, stderr); die("bad node passsed to simp()"); break; } diff --git a/mi/dfcheck.c b/mi/dfcheck.c index a5fc7c9..fbd536d 100644 --- a/mi/dfcheck.c +++ b/mi/dfcheck.c @@ -17,12 +17,16 @@ static void checkundef(Node *n, Reaching *r, Bitset *reach, Bitset *kill) { size_t i, j, did; Node *def; + Type *t; if (n->type != Nexpr) return; if (exprop(n) == Ovar) { did = n->expr.did; for (j = 0; j < r->ndefs[did]; j++) { + t = tybase(exprtype(n)); + if (t->type == Tystruct || t->type == Tyunion || t->type == Tyarray || t->type == Tytuple) + continue; if (bshas(kill, r->defs[did][j])) continue; if (!bshas(reach, r->defs[did][j])) @@ -38,6 +42,17 @@ static void checkundef(Node *n, Reaching *r, Bitset *reach, Bitset *kill) case Oblit: checkundef(n->expr.args[1], r, reach, kill); break; + case Oaddr: + case Oslice: + /* these don't actually look at the of args[0], so they're ok. */ + for (i = 1; i < n->expr.nargs; i++) + checkundef(n->expr.args[i], r, reach, kill); + break; + case Ocall: + for (i = 1; i < n->expr.nargs; i++) + if (exprop(n->expr.args[i]) != Oaddr) + checkundef(n->expr.args[i], r, reach, kill); + break; default: for (i = 0; i < n->expr.nargs; i++) checkundef(n->expr.args[i], r, reach, kill); @@ -55,8 +70,11 @@ static void checkreach(Cfg *cfg) Bb *bb; r = reaching(cfg); +// dumpcfg(cfg, stdout); for (i = 0; i < cfg->nbb; i++) { bb = cfg->bb[i]; + if (!bb) + continue; reach = bsdup(r->in[i]); kill = mkbs(); for (j = 0; j < bb->nnl; j++) { @@ -110,6 +128,5 @@ static void checkret(Cfg *cfg) void check(Cfg *cfg) { checkret(cfg); - if (0) - checkreach(cfg); + if(0) checkreach(cfg); } diff --git a/mi/reaching.c b/mi/reaching.c index fbfcd05..01bd798 100644 --- a/mi/reaching.c +++ b/mi/reaching.c @@ -18,7 +18,7 @@ Node *assignee(Node *n) Node *a; switch (exprop(n)) { - case Oundef: + case Oundef: case Odef: case Oset: case Oasn: case Oaddeq: case Osubeq: case Omuleq: @@ -29,10 +29,11 @@ Node *assignee(Node *n) return n->expr.args[0]; break; case Oblit: + case Oclear: a = n->expr.args[0]; if (exprop(a) != Oaddr) break; - a = n->expr.args[0]; + a = a->expr.args[0]; if (exprop(a) != Ovar) break; return a; @@ -156,7 +157,7 @@ Reaching *reaching(Cfg *cfg) // printf("\tout: "); // bsdump(out[i]); // } -// + reaching = xalloc(sizeof(Reaching)); reaching->in = in; reaching->out = out; diff --git a/parse/gram.y b/parse/gram.y index 47f3f0a..c241951 100644 --- a/parse/gram.y +++ b/parse/gram.y @@ -876,10 +876,19 @@ block : blkbody Tendblk blkbody : decl { size_t i; + Node *n, *d, *u; + $$ = mkblock($1.loc, mkstab()); for (i = 0; i < $1.nn; i++) { - putdcl($$->block.scope, $1.nl[i]); - lappend(&$$->block.stmts, &$$->block.nstmts, $1.nl[i]); + d = $1.nl[i]; + putdcl($$->block.scope, d); + if (!d->decl.init) { + n = mkexpr(d->loc, Ovar, d->decl.name, NULL); + u = mkexpr(n->loc, Oundef, n, NULL); + n->expr.did = d->decl.did; + lappend(&$$->block.stmts, &$$->block.nstmts, u); + } + lappend(&$$->block.stmts, &$$->block.nstmts, d); } } | stmt { diff --git a/parse/infer.c b/parse/infer.c index aa840a0..937f116 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -1448,8 +1448,15 @@ static void inferexpr(Inferstate *st, Node **np, Type *ret, int *sawret) } settype(st, n, type(st, args[0])); break; + case Oundef: + infersub(st, n, ret, sawret, &isconst); + settype(st, n, mktype(n->loc, Tyvoid)); + break; + case Odef: + case Odead: + n->expr.type = mktype(n->loc, Tyvoid); + break; case Obad: case Ocjmp: case Ojtab: case Oset: - case Odead: case Oundef: case Oslbase: case Osllen: case Outag: case Oblit: case Oclear: case Oudata: case Otrunc: case Oswiden: case Ozwiden: diff --git a/parse/ops.def b/parse/ops.def index 9b8de94..c5c3643 100644 --- a/parse/ops.def +++ b/parse/ops.def @@ -58,6 +58,7 @@ O(Oarr, 1, OTmisc, NULL) /* all below this point are backend-only */ O(Odead, 0, OTmisc, "DEAD") /* dead code */ O(Oundef, 0, OTmisc, "UNDEF") /* undefined var */ +O(Odef, 0, OTmisc, "DEF") /* defined var */ O(Ocjmp, 1, OTmisc, "CJMP") /* conditional jump */ O(Ojtab, 1, OTmisc, "JTAB") /* jump table */ O(Oset, 1, OTbin, "=") /* store to var */ diff --git a/test/derefassign.myr b/test/derefassign.myr index 5a06335..18fb726 100644 --- a/test/derefassign.myr +++ b/test/derefassign.myr @@ -4,6 +4,7 @@ const main = { var p var v + v = 0 p = &v p# = 123 std.exit(v) |