summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-08-18 21:07:06 -0700
committerOri Bernstein <ori@eigenstate.org>2018-08-18 21:07:06 -0700
commitd861ac1aa2d18ba89b389785ea23b9e72e1edaa1 (patch)
tree31f4f426a27b23b38e35eb18848a136028d51410
parentda1c3640344a42e464266f75c71c813181303b7e (diff)
downloadmc-d861ac1aa2d18ba89b389785ea23b9e72e1edaa1.tar.gz
Clean up draining incqueues.
We tried to be too smart, and we made bugs. let's do it simpler.
-rw-r--r--mi/flatten.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/mi/flatten.c b/mi/flatten.c
index e4817d3..813dabd 100644
--- a/mi/flatten.c
+++ b/mi/flatten.c
@@ -58,7 +58,7 @@ static Node *flatten(Flattenctx *s, Node *n);
static Node *rval(Flattenctx *s, Node *n);
static Node *lval(Flattenctx *s, Node *n);
static Node *assign(Flattenctx *s, Node *lhs, Node *rhs);
-static Node *draininc(Flattenctx *c, Node *protect, int free);
+static void draininc(Flattenctx *c);
static void
append(Flattenctx *s, Node *n)
@@ -467,24 +467,14 @@ assign(Flattenctx *s, Node *lhs, Node *rhs)
* If protect is not null, returns a node with the
* unmodified value.
*/
-static Node*
-draininc(Flattenctx *fc, Node *protect, int free)
+static void
+draininc(Flattenctx *fc)
{
- Node *tmp;
size_t i;
- tmp = NULL;
- if (!fc->nqueue)
- return protect;
- if (protect) {
- tmp = temp(fc, protect);
- append(fc, assign(fc, tmp, protect));
- }
for (i = 0; i < fc->nqueue; i++)
append(fc, fc->incqueue[i]);
- if (free)
- lfree(&fc->incqueue, &fc->nqueue);
- return tmp;
+ lfree(&fc->incqueue, &fc->nqueue);
}
/* returns 1 when the exit jump needs to be emitted */
@@ -637,10 +627,10 @@ rval(Flattenctx *s, Node *n)
break;;
case Oret:
v = rval(s, args[0]);
- t = draininc(s, v, 1);
if (!s->tret)
s->tret = temp(s, v);
- flatten(s, asn(lval(s, s->tret), t));
+ flatten(s, asn(lval(s, s->tret), v));
+ draininc(s);
if (exitscope(s, NULL, Zloc, Xret))
append(s, mkexpr(n->loc, Oret, s->tret, NULL));
break;
@@ -779,10 +769,10 @@ flattenloop(Flattenctx *s, Node *n)
flatten(s, lcond); /* test lbl */
flattencond(s, n->loopstmt.cond, ldec, lend); /* repeat? */
flatten(s, ldec); /* drain decrements */
- draininc(s, NULL, 0);
+ draininc(s);
jmp(s, lbody); /* goto test */
flatten(s, lend); /* exit */
- draininc(s, NULL, 1);
+ draininc(s);
s->inloop--;
s->loop = l;
@@ -795,7 +785,7 @@ static void
flattenif(Flattenctx *s, Node *n, Node *exit)
{
Node *l1, *l2, *l3;
- Node *iftrue, *iffalse;
+ Node *cond, *iftrue, *iffalse, *t;
l1 = genlbl(n->loc);
l2 = genlbl(n->loc);
@@ -804,17 +794,24 @@ flattenif(Flattenctx *s, Node *n, Node *exit)
else
l3 = genlbl(n->loc);
+ cond = rval(s, n->ifstmt.cond);
iftrue = n->ifstmt.iftrue;
iffalse = n->ifstmt.iffalse;
+ if (s->incqueue) {
+ t = temp(s, cond);
+ flatten(s, asn(t, cond));
+ draininc(s);
+ cond = t;
+ }
- flattencond(s, n->ifstmt.cond, l1, l2);
+ flattencond(s, cond, l1, l2);
flatten(s, l1);
- draininc(s, NULL, 0);
+ draininc(s);
/* goto test */
flatten(s, iftrue);
jmp(s, l3);
flatten(s, l2);
- draininc(s, NULL, 1);
+ draininc(s);
/* because lots of bunched up end labels are ugly,
* coalesce them by handling 'elif'-like construct
* separately */
@@ -1022,15 +1019,17 @@ flatteniter(Flattenctx *s, Node *n)
static void
flattenmatch(Flattenctx *fc, Node *n)
{
- Node *val, **match;
+ Node *v, *r, **match;
size_t i, nmatch;
- val = rval(fc, n->matchstmt.val);
- val = draininc(fc, val, 1);
+ r = rval(fc, n->matchstmt.val);
+ v = temp(fc, r);
+ flatten(fc, asn(v, r));
+ draininc(fc);
match = NULL;
nmatch = 0;
- genmatch(n, val, &match, &nmatch);
+ genmatch(n, v, &match, &nmatch);
for (i = 0; i < nmatch; i++)
flatten(fc, match[i]);
}
@@ -1047,7 +1046,7 @@ flattenexpr(Flattenctx *fc, Node *n)
r = rval(fc, n);
if (r)
append(fc, r);
- draininc(fc, NULL, 1);
+ draininc(fc);
}
static Node *