Esempio n. 1
0
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);
    }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
File: semc1.c Progetto: aiju/hdl
static Nodes *
circbreak1(ASTNode *n)
{
    ASTNode *idx;
    BitSet *visit;
    ASTNode *m;
    int r;

    if(n->t == ASTASS && n->n2 != nil && n->n2->t == ASTISUB) {
        idx = n->n2->n1;
        assert(idx != nil && idx->t == ASTIDX);
        if(n->n1->t == ASTSSA && idx->n1->t == ASTSSA && idx->n1->semv == idx->n1->semv->sym->semc[1]) {
            visit = bsnew(nvars);
            r = findcircles(idx->n1->semv, n->n1->semv, visit);
            bsfree(visit);
            if(r) {
                m = nodedup(n);
                m->n2 = nodedup(m->n2);
                m->n2->n1 = nodedup(m->n2->n1);
                m->n2->n1->n1 = node(ASTSSA, idx->n1->semv->sym->semc[0]);
                circbroken++;
                return nl(m);
            }
        }
    }
    return nl(n);
}
Esempio n. 4
0
File: semc1.c Progetto: aiju/hdl
/* copy blocks and create definitions for the primed values as needed */
static void
makenext(void)
{
    SemBlock *b, *c;
    BitSet *copy;
    int i, j, ch;

    copy = bsnew(nblocks);
    for(i = 0; i < nblocks; i++) {
        b = blocks[i];
        if(descendsum(b->phi, countnext) + descendsum(b->cont, countnext) > 0)
            bsadd(copy, i);
    }
    do {
        ch = 0;
        for(i = -1; i = bsiter(copy, i), i >= 0; ) {
            b = blocks[i];
            for(j = 0; j < b->nto; j++)
                ch += bsadd(copy, b->to[j]->idx) == 0;
            for(j = 0; j < b->nfrom; j++)
                ch += bsadd(copy, b->from[j]->idx) == 0;
        }
    } while(ch != 0);
    dupl = emalloc(nblocks * sizeof(SemBlock *));
    for(i = -1; i = bsiter(copy, i), i >= 0; )
        dupl[i] = newblock();
    for(i = -1; i = bsiter(copy, i), i >= 0; ) {
        b = blocks[i];
        c = dupl[i];
        c->nto = b->nto;
        c->to = emalloc(sizeof(SemBlock *) * c->nto);
        c->nfrom = b->nfrom;
        c->from = emalloc(sizeof(SemBlock *) * c->nfrom);
        for(j = 0; j < b->nto; j++) {
            c->to[j] = dupl[b->to[j]->idx];
            assert(c->to[j] != nil);
        }
        for(j = 0; j < b->nfrom; j++) {
            c->from[j] = dupl[b->from[j]->idx];
            assert(c->from[j] != nil);
        }
        c->phi = mkblock(descend(b->phi, nil, makenext1));
        c->cont = mkblock(descend(b->cont, nil, makenext1));
        c->jump = mkblock(descend(b->jump, nil, makenext1));
    }
    for(i = 0; i < nblocks; i++) {
        b = blocks[i];
        b->phi = mkblock(descend(b->phi, nil, deldefs));
        b->cont = mkblock(descend(b->cont, nil, deldefs));
    }
    bsfree(copy);
}
Esempio n. 5
0
File: pipe.c Progetto: aiju/hdl
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);
}
Esempio n. 6
0
File: semc1.c Progetto: aiju/hdl
static void
circdefs(void)
{
    int i;
    BitSet *visit;

    visit = bsnew(nvars);
    for(i = 0; i < nvars; i++) {
        bsreset(visit);
        if(vars[i] == vars[i]->sym->semc[0] && findcircles(vars[i], vars[i], visit))
            error(vars[i]->sym, "combinational loop involving %s", vars[i]->sym->name);
        bsreset(visit);
        if(vars[i] == vars[i]->sym->semc[1] && findcircles(vars[i], vars[i], visit))
            error(vars[i]->sym, "combinational loop involving %s'", vars[i]->sym->name);
    }
    bsfree(visit);
}
Esempio n. 7
0
File: pipe.c Progetto: aiju/hdl
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);
}