static void checkreach(Cfg *cfg) { Bitset *reach, *kill; size_t i, j, k; Reaching *r; Node *n, *m; 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++) { n = bb->nl[j]; if (exprop(n) == Oundef) { bsput(reach, n->nid); } else { m = assignee(n); if (m) for (k = 0; k < r->ndefs[m->expr.did]; k++) bsput(kill, r->defs[m->expr.did][k]); checkundef(n, r, reach, kill); } } bsfree(reach); bsfree(kill); } }
Reaching *reaching(Cfg *cfg) { Bitset **in, **out; Bitset **gen, **kill; Bitset *bbin, *bbout; Reaching *reaching; size_t **defs; /* mapping from did => [def,list] */ size_t *ndefs; size_t i, j; int changed; in = zalloc(cfg->nbb * sizeof(Bb*)); out = zalloc(cfg->nbb * sizeof(Bb*)); gen = zalloc(cfg->nbb * sizeof(Bb*)); kill = zalloc(cfg->nbb * sizeof(Bb*)); defs = zalloc(ndecls * sizeof(size_t*)); ndefs = zalloc(ndecls * sizeof(size_t)); collectdefs(cfg, defs, ndefs); for (i = 0; i < cfg->nbb; i++) { in[i] = mkbs(); out[i] = mkbs(); gen[i] = mkbs(); kill[i] = mkbs(); if (cfg->bb[i]) genkill(cfg->bb[i], defs, ndefs, gen[i], kill[i]); } do { changed = 0; for (i = 0; i < cfg->nbb; i++) { if (!cfg->bb[i]) continue; bbin = mkbs(); for (j = 0; bsiter(cfg->bb[i]->pred, &j); j++) 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; bsfree(in[i]); bsfree(out[i]); in[i] = bbin; out[i] = bbout; } } } while (changed); reaching = xalloc(sizeof(Reaching)); reaching->in = in; reaching->out = out; reaching->defs = defs; reaching->ndefs = ndefs; return reaching; }
static void doif(ASTNode *n, int ctxt) { BitSet *g, *k, *kp; BitSet *g1, *k1, *k1p; BitSet *g2, *k2, *k2p, *t; PipeStage *p; p = stcur; t = bsnew(p->nvars); findstages(n->n1, ctxt); g = p->gen; k = p->kill; kp = p->killp; p->gen = g1 = bsdup(g); p->kill = k1 = bsdup(k); p->killp = k1p = bsdup(kp); findstages(n->n2, ctxt); p->gen = g2 = bsdup(g); p->kill = k2 = bsdup(k); p->killp = k2p = bsdup(kp); findstages(n->n3, ctxt); bsunion(g, g1, g); bsunion(g, g2, g); bsunion(k, k1, k); bsunion(k, k2, k); bsunion(kp, k1p, kp); bsunion(kp, k2p, kp); bsminus(t, k1, k2); addeq(t, &n->n3, 0); bsunion(g, t, g); bsminus(t, k2, k1); addeq(t, &n->n2, 0); bsunion(g, t, g); bsminus(t, k1p, k2p); addeq(t, &n->n3, 1); bsunion(g, t, g); bsminus(t, k2p, k1p); addeq(t, &n->n2, 1); bsunion(g, t, g); p->gen = g; p->kill = k; p->killp = kp; bsfree(g1); bsfree(g2); bsfree(k1); bsfree(k2); bsfree(k1p); bsfree(k2p); bsfree(t); }
static Nodes * process(ASTNode *n) { Nodes *r, *s, *t; int ours; BitSet *ks; if(n == nil) return nil; switch(n->t){ case ASTPIPEL: t = nil; s = nil; for(r = n->nl; r != nil; r = r->next) if(r->n->t == ASTSTATE){ if(stcur == nil) stcur = stlist.next; else stcur = stcur->next; assert(stcur != nil && stcur->sym == r->n->sym); bsreset(killed); if(s != nil) t = nlcat(t, nl(node(ASTBLOCK, s))); s = nil; }else s = nlcat(s, process(r->n)); if(s != nil) t = nlcat(t, nl(node(ASTBLOCK, s))); return t; case ASTSYMB: if(stcur != nil && n->sym->pipeidx >= 0) if(bstest(killed, n->sym->pipeidx)) n->sym = stcur->outvars[n->sym->pipeidx]; else n->sym = stcur->invars[n->sym->pipeidx]; return nl(n); case ASTPRIME: ours = 0; return nl(lvalfix(n, 0, &ours)); case ASTASS: n = nodedup(n); n->n2 = onlyone(process(n->n2)); ours = 0; n->n1 = lvalfix(n->n1, LVAL, &ours); return nl(n); case ASTDECL: return nil; case ASTBLOCK: n = nodedup(n); s = nil; for(r = n->nl; r != nil; r = r->next) s = nlcat(s, process(r->n)); n->nl = s; return nl(n); case ASTCINT: case ASTCONST: return nl(n); case ASTOP: case ASTTERN: n = nodedup(n); n->n1 = onlyone(process(n->n1)); n->n2 = onlyone(process(n->n2)); n->n3 = onlyone(process(n->n3)); n->n4 = onlyone(process(n->n4)); return nl(n); case ASTIF: n = nodedup(n); n->n1 = onlyone(process(n->n1)); ks = killed; killed = bsdup(ks); n->n2 = onlyone(process(n->n2)); bsfree(killed); killed = ks; n->n3 = onlyone(process(n->n3)); return nl(n); default: warn(n, "process: unknown %A", n->t); } return nl(n); }