⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reg.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		if(s == v->sym)		if(n == v->name)		if(o == v->offset)			goto out;		v++;	}	if(s)		if(s->name[0] == '.')			goto none;	if(nvar >= NVAR) {		if(debug['w'] > 1 && s)			warn(Z, "variable not optimized: %s", s->name);		goto none;	}	i = nvar;	nvar++;	v = &var[i];	v->sym = s;	v->offset = o;	v->etype = et;	v->name = n;	if(debug['R'])		print("bit=%2d et=%2d %D\n", i, et, a);out:	bit = blsh(i);	if(n == D_EXTERN || n == D_STATIC)		for(z=0; z<BITS; z++)			externs.b[z] |= bit.b[z];	if(n == D_PARAM)		for(z=0; z<BITS; z++)			params.b[z] |= bit.b[z];	if(v->etype != et || !typechlpfd[et])	/* funny punning */		for(z=0; z<BITS; z++)			addrs.b[z] |= bit.b[z];	if(t == D_CONST) {		if(s == S) {			for(z=0; z<BITS; z++)				consts.b[z] |= bit.b[z];			return bit;		}		if(et != TARRAY)			for(z=0; z<BITS; z++)				addrs.b[z] |= bit.b[z];		for(z=0; z<BITS; z++)			params.b[z] |= bit.b[z];		return bit;	}	if(t == D_OREG)		return bit;none:	return zbits;}voidprop(Reg *r, Bits ref, Bits cal){	Reg *r1, *r2;	int z;	for(r1 = r; r1 != R; r1 = r1->p1) {		for(z=0; z<BITS; z++) {			ref.b[z] |= r1->refahead.b[z];			if(ref.b[z] != r1->refahead.b[z]) {				r1->refahead.b[z] = ref.b[z];				change++;			}			cal.b[z] |= r1->calahead.b[z];			if(cal.b[z] != r1->calahead.b[z]) {				r1->calahead.b[z] = cal.b[z];				change++;			}		}		switch(r1->prog->as) {		case ABL:			for(z=0; z<BITS; z++) {				cal.b[z] |= ref.b[z] | externs.b[z];				ref.b[z] = 0;			}			break;		case ATEXT:			for(z=0; z<BITS; z++) {				cal.b[z] = 0;				ref.b[z] = 0;			}			break;		case ARET:			for(z=0; z<BITS; z++) {				cal.b[z] = externs.b[z];				ref.b[z] = 0;			}		}		for(z=0; z<BITS; z++) {			ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |				r1->use1.b[z] | r1->use2.b[z];			cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);			r1->refbehind.b[z] = ref.b[z];			r1->calbehind.b[z] = cal.b[z];		}		if(r1->active)			break;		r1->active = 1;	}	for(; r != r1; r = r->p1)		for(r2 = r->p2; r2 != R; r2 = r2->p2link)			prop(r2, r->refbehind, r->calbehind);}/* * find looping structure * * 1) find reverse postordering * 2) find approximate dominators, *	the actual dominators if the flow graph is reducible *	otherwise, dominators plus some other non-dominators. *	See Matthew S. Hecht and Jeffrey D. Ullman, *	"Analysis of a Simple Algorithm for Global Data Flow Problems", *	Conf.  Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts, *	Oct. 1-3, 1973, pp.  207-217. * 3) find all nodes with a predecessor dominated by the current node. *	such a node is a loop head. *	recursively, all preds with a greater rpo number are in the loop */longpostorder(Reg *r, Reg **rpo2r, long n){	Reg *r1;	r->rpo = 1;	r1 = r->s1;	if(r1 && !r1->rpo)		n = postorder(r1, rpo2r, n);	r1 = r->s2;	if(r1 && !r1->rpo)		n = postorder(r1, rpo2r, n);	rpo2r[n] = r;	n++;	return n;}longrpolca(long *idom, long rpo1, long rpo2){	long t;	if(rpo1 == -1)		return rpo2;	while(rpo1 != rpo2){		if(rpo1 > rpo2){			t = rpo2;			rpo2 = rpo1;			rpo1 = t;		}		while(rpo1 < rpo2){			t = idom[rpo2];			if(t >= rpo2)				fatal(Z, "bad idom");			rpo2 = t;		}	}	return rpo1;}intdoms(long *idom, long r, long s){	while(s > r)		s = idom[s];	return s == r;}intloophead(long *idom, Reg *r){	long src;	src = r->rpo;	if(r->p1 != R && doms(idom, src, r->p1->rpo))		return 1;	for(r = r->p2; r != R; r = r->p2link)		if(doms(idom, src, r->rpo))			return 1;	return 0;}voidloopmark(Reg **rpo2r, long head, Reg *r){	if(r->rpo < head || r->active == head)		return;	r->active = head;	r->loop += LOOP;	if(r->p1 != R)		loopmark(rpo2r, head, r->p1);	for(r = r->p2; r != R; r = r->p2link)		loopmark(rpo2r, head, r);}voidloopit(Reg *r, long nr){	Reg *r1;	long i, d, me;	if(nr > maxnr) {		rpo2r = alloc(nr * sizeof(Reg*));		idom = alloc(nr * sizeof(long));		maxnr = nr;	}	d = postorder(r, rpo2r, 0);	if(d > nr)		fatal(Z, "too many reg nodes");	nr = d;	for(i = 0; i < nr / 2; i++){		r1 = rpo2r[i];		rpo2r[i] = rpo2r[nr - 1 - i];		rpo2r[nr - 1 - i] = r1;	}	for(i = 0; i < nr; i++)		rpo2r[i]->rpo = i;	idom[0] = 0;	for(i = 0; i < nr; i++){		r1 = rpo2r[i];		me = r1->rpo;		d = -1;		if(r1->p1 != R && r1->p1->rpo < me)			d = r1->p1->rpo;		for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)			if(r1->rpo < me)				d = rpolca(idom, d, r1->rpo);		idom[i] = d;	}	for(i = 0; i < nr; i++){		r1 = rpo2r[i];		r1->loop++;		if(r1->p2 != R && loophead(idom, r1))			loopmark(rpo2r, i, r1);	}}voidsynch(Reg *r, Bits dif){	Reg *r1;	int z;	for(r1 = r; r1 != R; r1 = r1->s1) {		for(z=0; z<BITS; z++) {			dif.b[z] = (dif.b[z] &				~(~r1->refbehind.b[z] & r1->refahead.b[z])) |					r1->set.b[z] | r1->regdiff.b[z];			if(dif.b[z] != r1->regdiff.b[z]) {				r1->regdiff.b[z] = dif.b[z];				change++;			}		}		if(r1->active)			break;		r1->active = 1;		for(z=0; z<BITS; z++)			dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);		if(r1->s2 != R)			synch(r1->s2, dif);	}}ulongallreg(ulong b, Rgn *r){	Var *v;	int i;	v = var + r->varno;	r->regno = 0;	switch(v->etype) {	default:		diag(Z, "unknown etype %d/%d", bitno(b), v->etype);		break;	case TCHAR:	case TUCHAR:	case TSHORT:	case TUSHORT:	case TINT:	case TUINT:	case TLONG:	case TULONG:	case TIND:	case TARRAY:		i = BtoR(~b);		if(i && r->cost >= 0) {			r->regno = i;			return RtoB(i);		}		break;	case TVLONG:	case TDOUBLE:	case TFLOAT:		i = BtoF(~b);		if(i && r->cost >= 0) {			r->regno = i+NREG;			return FtoB(i);		}		break;	}	return 0;}voidpaint1(Reg *r, int bn){	Reg *r1;	Prog *p;	int z;	ulong bb;	z = bn/32;	bb = 1L<<(bn%32);	if(r->act.b[z] & bb)		return;	for(;;) {		if(!(r->refbehind.b[z] & bb))			break;		r1 = r->p1;		if(r1 == R)			break;		if(!(r1->refahead.b[z] & bb))			break;		if(r1->act.b[z] & bb)			break;		r = r1;	}	if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) {		change -= CLOAD * r->loop;		if(debug['R'] && debug['v'])			print("%ld%P\tld %B $%d\n", r->loop,				r->prog, blsh(bn), change);	}	for(;;) {		r->act.b[z] |= bb;		p = r->prog;		if(r->use1.b[z] & bb) {			change += CREF * r->loop;			if(debug['R'] && debug['v'])				print("%ld%P\tu1 %B $%d\n", r->loop,					p, blsh(bn), change);		}		if((r->use2.b[z]|r->set.b[z]) & bb) {			change += CREF * r->loop;			if(debug['R'] && debug['v'])				print("%ld%P\tu2 %B $%d\n", r->loop,					p, blsh(bn), change);		}		if(STORE(r) & r->regdiff.b[z] & bb) {			change -= CLOAD * r->loop;			if(debug['R'] && debug['v'])				print("%ld%P\tst %B $%d\n", r->loop,					p, blsh(bn), change);		}		if(r->refbehind.b[z] & bb)			for(r1 = r->p2; r1 != R; r1 = r1->p2link)				if(r1->refahead.b[z] & bb)					paint1(r1, bn);		if(!(r->refahead.b[z] & bb))			break;		r1 = r->s2;		if(r1 != R)			if(r1->refbehind.b[z] & bb)				paint1(r1, bn);		r = r->s1;		if(r == R)			break;		if(r->act.b[z] & bb)			break;		if(!(r->refbehind.b[z] & bb))			break;	}}ulongpaint2(Reg *r, int bn){	Reg *r1;	int z;	ulong bb, vreg;	z = bn/32;	bb = 1L << (bn%32);	vreg = regbits;	if(!(r->act.b[z] & bb))		return vreg;	for(;;) {		if(!(r->refbehind.b[z] & bb))			break;		r1 = r->p1;		if(r1 == R)			break;		if(!(r1->refahead.b[z] & bb))			break;		if(!(r1->act.b[z] & bb))			break;		r = r1;	}	for(;;) {		r->act.b[z] &= ~bb;		vreg |= r->regu;		if(r->refbehind.b[z] & bb)			for(r1 = r->p2; r1 != R; r1 = r1->p2link)				if(r1->refahead.b[z] & bb)					vreg |= paint2(r1, bn);		if(!(r->refahead.b[z] & bb))			break;		r1 = r->s2;		if(r1 != R)			if(r1->refbehind.b[z] & bb)				vreg |= paint2(r1, bn);		r = r->s1;		if(r == R)			break;		if(!(r->act.b[z] & bb))			break;		if(!(r->refbehind.b[z] & bb))			break;	}	return vreg;}voidpaint3(Reg *r, int bn, long rb, int rn){	Reg *r1;	Prog *p;	int z;	ulong bb;	z = bn/32;	bb = 1L << (bn%32);	if(r->act.b[z] & bb)		return;	for(;;) {		if(!(r->refbehind.b[z] & bb))			break;		r1 = r->p1;		if(r1 == R)			break;		if(!(r1->refahead.b[z] & bb))			break;		if(r1->act.b[z] & bb)			break;		r = r1;	}	if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)		addmove(r, bn, rn, 0);	for(;;) {		r->act.b[z] |= bb;		p = r->prog;		if(r->use1.b[z] & bb) {			if(debug['R'])				print("%P", p);			addreg(&p->from, rn);			if(debug['R'])				print("\t.c%P\n", p);		}		if((r->use2.b[z]|r->set.b[z]) & bb) {			if(debug['R'])				print("%P", p);			addreg(&p->to, rn);			if(debug['R'])				print("\t.c%P\n", p);		}		if(STORE(r) & r->regdiff.b[z] & bb)			addmove(r, bn, rn, 1);		r->regu |= rb;		if(r->refbehind.b[z] & bb)			for(r1 = r->p2; r1 != R; r1 = r1->p2link)				if(r1->refahead.b[z] & bb)					paint3(r1, bn, rb, rn);		if(!(r->refahead.b[z] & bb))			break;		r1 = r->s2;		if(r1 != R)			if(r1->refbehind.b[z] & bb)				paint3(r1, bn, rb, rn);		r = r->s1;		if(r == R)			break;		if(r->act.b[z] & bb)			break;		if(!(r->refbehind.b[z] & bb))			break;	}}voidaddreg(Adr *a, int rn){	a->sym = 0;	a->name = D_NONE;	a->type = D_REG;	a->reg = rn;	if(rn >= NREG) {		a->type = D_FREG;		a->reg = rn-NREG;	}}/* *	bit	reg *	0	R0 *	1	R1 *	...	... *	10	R10 */longRtoB(int r){	if(r < 2 || r >= REGTMP)		return 0;	return 1L << r;}intBtoR(long b){	b &= 0x07fcL;	if(b == 0)		return 0;	return bitno(b);}/* *	bit	reg *	18	F2 *	19	F3 *	...	... *	23	F7 */longFtoB(int f){	if(f < 2 || f > NFREG-1)		return 0;	return 1L << (f + 16);}intBtoF(long b){	b &= 0xfc0000L;	if(b == 0)		return 0;	return bitno(b) - 16;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -