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 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 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); } }