예제 #1
0
파일: semc1.c 프로젝트: 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);
}
예제 #2
0
파일: reaching.c 프로젝트: kirbyfan64/mc
void bsdump(Bitset *bs)
{
	size_t i;
	for (i = 0; bsiter(bs, &i); i++)
		printf("%zd ", i);
	printf("\n");
}
예제 #3
0
파일: reaching.c 프로젝트: kirbyfan64/mc
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;
}
예제 #4
0
파일: pipe.c 프로젝트: aiju/hdl
static void
addeq(BitSet *t, ASTNode **n, int p)
{
	int i;
	Nodes *r;
	ASTNode *m;
	
	i = bsiter(t, -1);
	if(i < 0) return;
	if(*n != nil)
		r = nl(*n);
	else
		r = nil;
	for(; i >= 0; i = bsiter(t, i)){
		m = node(ASTSYMB, stcur->vars[i]);
		r = nlcat(r, nl(node(ASTASS, OPNOP, p != 0 ? node(ASTPRIME, m) : m, m)));
	}
	*n = node(ASTBLOCK, r);
}
예제 #5
0
파일: dfcheck.c 프로젝트: PuerkitoBio/mc
static void checkpredret(Cfg *cfg, Bb *bb)
{
    Bb *pred;
    Op op;
    size_t i;

    for (i = 0; bsiter(bb->pred, &i); i++) {
        pred = cfg->bb[i];
        if (pred->nnl == 0) {
            checkpredret(cfg, pred);
        } else {
            op = exprop(pred->nl[pred->nnl - 1]);
            if (op != Oret && op != Odead) {
                fatal(pred->nl[pred->nnl-1], "Reaches end of function without return\n");
            }
        }
    }
}
예제 #6
0
파일: use.c 프로젝트: 8l/myrddin
/* Writes types to a file. Errors on
 * internal only types like Tyvar that
 * will not be meaningful in another file*/
static void typickle(FILE *fd, Type *ty)
{
    size_t i;

    if (!ty) {
        die("trying to pickle null type\n");
        return;
    }
    wrbyte(fd, ty->type);
    wrbyte(fd, ty->vis);
    /* tid is generated; don't write */
    /* FIXME: since we only support hardcoded traits, we just write
     * out the set of them. we should write out the trait list as
     * well */
    if (!ty->traits) {
        wrint(fd, 0);
    } else {
        wrint(fd, bscount(ty->traits));
        for (i = 0; bsiter(ty->traits, &i); i++) {
            if (i < Ntraits)
                wrint(fd, i | Builtinmask);
            else
                wrint(fd, i);
        }
    }
    wrint(fd, ty->nsub);
    switch (ty->type) {
        case Tyunres:
            pickle(fd, ty->name);
            break;
        case Typaram:
            wrstr(fd, ty->pname);
            break;
        case Tystruct:
            wrint(fd, ty->nmemb);
            for (i = 0; i < ty->nmemb; i++)
                pickle(fd, ty->sdecls[i]);
            break;
        case Tyunion:
            wrint(fd, ty->nmemb);
            for (i = 0; i < ty->nmemb; i++)
                wrucon(fd, ty->udecls[i]);
            break;
        case Tyarray:
            wrtype(fd, ty->sub[0]);
            pickle(fd, ty->asize);
            break;
        case Tyslice:
            wrtype(fd, ty->sub[0]);
            break;
        case Tyvar:
            die("Attempting to pickle %s. This will not work.\n", tystr(ty));
            break;
        case Tyname:
            pickle(fd, ty->name);
            wrbool(fd, ty->issynth);
            wrint(fd, ty->narg);
            for (i = 0; i < ty->narg; i++)
                wrtype(fd, ty->arg[i]);
            wrtype(fd, ty->sub[0]);
            break;
        case Tygeneric:
            pickle(fd, ty->name);
            wrbool(fd, ty->issynth);
            wrint(fd, ty->ngparam);
            for (i = 0; i < ty->ngparam; i++)
                wrtype(fd, ty->gparam[i]);
            wrtype(fd, ty->sub[0]);
            break;
        default:
            for (i = 0; i < ty->nsub; i++)
                wrtype(fd, ty->sub[i]);
            break;
    }
}
예제 #7
0
파일: live.c 프로젝트: 8l/qbe
/* liveness analysis
 * requires rpo computation
 */
void
filllive(Fn *f)
{
	Blk *b;
	Ins *i;
	int k, t, m[2], n, chg, nlv[2];
	BSet u[1], v[1];
	Mem *ma;

	bsinit(u, f->ntmp);
	bsinit(v, f->ntmp);
	for (b=f->start; b; b=b->link) {
		bsinit(b->in, f->ntmp);
		bsinit(b->out, f->ntmp);
		bsinit(b->gen, f->ntmp);
	}
	chg = 1;
Again:
	for (n=f->nblk-1; n>=0; n--) {
		b = f->rpo[n];

		bscopy(u, b->out);
		if (b->s1) {
			liveon(v, b, b->s1);
			bsunion(b->out, v);
		}
		if (b->s2) {
			liveon(v, b, b->s2);
			bsunion(b->out, v);
		}
		chg |= !bsequal(b->out, u);

		memset(nlv, 0, sizeof nlv);
		b->out->t[0] |= T.rglob;
		bscopy(b->in, b->out);
		for (t=0; bsiter(b->in, &t); t++)
			nlv[KBASE(f->tmp[t].cls)]++;
		if (rtype(b->jmp.arg) == RCall) {
			assert((int)bscount(b->in) == T.nrglob &&
				nlv[0] == T.nrglob &&
				nlv[1] == 0);
			b->in->t[0] |= T.retregs(b->jmp.arg, nlv);
		} else
			bset(b->jmp.arg, b, nlv, f->tmp);
		for (k=0; k<2; k++)
			b->nlive[k] = nlv[k];
		for (i=&b->ins[b->nins]; i!=b->ins;) {
			if ((--i)->op == Ocall && rtype(i->arg[1]) == RCall) {
				b->in->t[0] &= ~T.retregs(i->arg[1], m);
				for (k=0; k<2; k++) {
					nlv[k] -= m[k];
					/* caller-save registers are used
					 * by the callee, in that sense,
					 * right in the middle of the call,
					 * they are live: */
					nlv[k] += T.nrsave[k];
					if (nlv[k] > b->nlive[k])
						b->nlive[k] = nlv[k];
				}
				b->in->t[0] |= T.argregs(i->arg[1], m);
				for (k=0; k<2; k++) {
					nlv[k] -= T.nrsave[k];
					nlv[k] += m[k];
				}
			}
			if (!req(i->to, R)) {
				assert(rtype(i->to) == RTmp);
				t = i->to.val;
				if (bshas(b->in, i->to.val))
					nlv[KBASE(f->tmp[t].cls)]--;
				bsset(b->gen, t);
				bsclr(b->in, t);
			}
			for (k=0; k<2; k++)
				switch (rtype(i->arg[k])) {
				case RMem:
					ma = &f->mem[i->arg[k].val];
					bset(ma->base, b, nlv, f->tmp);
					bset(ma->index, b, nlv, f->tmp);
					break;
				default:
					bset(i->arg[k], b, nlv, f->tmp);
					break;
				}
			for (k=0; k<2; k++)
				if (nlv[k] > b->nlive[k])
					b->nlive[k] = nlv[k];
		}
	}
	if (chg) {
		chg = 0;
		goto Again;
	}

	if (debug['L']) {
		fprintf(stderr, "\n> Liveness analysis:\n");
		for (b=f->start; b; b=b->link) {
			fprintf(stderr, "\t%-10sin:   ", b->name);
			dumpts(b->in, f->tmp, stderr);
			fprintf(stderr, "\t          out:  ");
			dumpts(b->out, f->tmp, stderr);
			fprintf(stderr, "\t          gen:  ");
			dumpts(b->gen, f->tmp, stderr);
			fprintf(stderr, "\t          live: ");
			fprintf(stderr, "%d %d\n", b->nlive[0], b->nlive[1]);
		}
	}
}