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

📄 reg.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
out:	bit = blsh(i);	if(t == D_EXTERN || t == D_STATIC)		for(z=0; z<BITS; z++)			externs.b[z] |= bit.b[z];	if(t == D_PARAM)		for(z=0; z<BITS; z++)			params.b[z] |= bit.b[z];	if(a->etype != v->etype || !typechlpfd[a->etype])		for(z=0; z<BITS; z++)			addrs.b[z] |= bit.b[z];	/* funny punning */	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];				changer++;			}			cal.b[z] |= r1->calahead.b[z];			if(cal.b[z] != r1->calahead.b[z]) {				r1->calahead.b[z] = cal.b[z];				changer++;			}		}		switch(r1->prog->as) {		case ABSR:			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 ARTS:			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];				changer++;			}		}		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, j;	v = var + r->varno;	r->regno = D_NONE;	switch(v->etype) {	default:		diag(Z, "unknown etype");		break;	case TCHAR:	case TUCHAR:	case TSHORT:	case TUSHORT:	case TINT:	case TUINT:	case TLONG:	case TULONG:	case TIND:		i = BtoR(~b);		j = BtoA(~b);		if(r->costa == r->costr)			if(i > j)				i = NREG;		if(j < NREG && r->costa > 0)		if(r->costa > r->costr || i >= NREG) {			r->regno = D_A0 + j;			return AtoB(j);		}		if(i < NREG && r->costr > 0) {			r->regno = D_R0 + i;			return RtoB(i);		}		break;	case TDOUBLE:	case TFLOAT:		i = BtoF(~b);		if(i < NREG) {			r->regno = D_F0 + i;			return FtoB(i);		}		break;	}	return 0;}voidpaint1(Reg *r, int bn){	Reg *r1;	Prog *p;	int z;	ulong bb;	int x;	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) {		changer -= CLOAD * r->loop;		changea -= CLOAD * r->loop;		if(debug['R'] && debug['v'])			print("%ld%P\tld %B $%d.%d\n", r->loop,				r->prog, blsh(bn), changer, changea);	}	for(;;) {		r->act.b[z] |= bb;		p = r->prog;		if(r->use1.b[z] & bb) {			changer += CREF * r->loop;			changea += CREF * r->loop;			x = p->from.index;			if(x == D_NONE) {				switch(p->as) {				default:					changea = -CINF;				case AADDL:				case ASUBL:				case AMOVL:				case ACMPL:					break;				}			} else {				changer += (CXREF-CREF) * r->loop;				if(x != (I_INDEX3|D_NONE))					changer = -CINF;				if((x&I_MASK) == I_INDEX1)					changea = -CINF;			}			if(p->as == AMOVL) {				x = p->to.type;				if(x >= D_R0 && x < D_R0+NREG)					changer += r->loop;				if(x >= D_A0 && x < D_A0+NREG)					changea += r->loop;			}			if(debug['R'] && debug['v'])				print("%ld%P\tu1 %B $%d.%d\n", r->loop,					p, blsh(bn), changer, changea);		}		if((r->use2.b[z]|r->set.b[z]) & bb) {			changer += CREF * r->loop;			changea += CREF * r->loop;			x = p->to.index;			if(x == D_NONE)				switch(p->as) {				default:					changea = -CINF;					break;				case AMOVL:				case AADDL:				case ACMPL:				case ASUBL:				case ACLRL:	/* can be faked */				case ATSTL:	/* can be faked */					break;				}			else {				changer += (CXREF-CREF) * r->loop;				if(x != (I_INDEX3|D_NONE))					changer = -CINF;				if((x&I_MASK) == I_INDEX1)					changea = -CINF;			}			if(p->as == AMOVL) {				x = p->from.type;				if(x >= D_R0 && x < D_R0+NREG)					changer += r->loop;				if(x >= D_A0 && x < D_A0+NREG)					changea += r->loop;			}			if(debug['R'] && debug['v'])				print("%ld%P\tu2 %B $%d.%d\n", r->loop,					p, blsh(bn), changer, changea);		}		if(STORE(r) & r->regdiff.b[z] & bb) {			changer -= CLOAD * r->loop;			changea -= CLOAD * r->loop;			if(debug['R'] && debug['v'])				print("%ld%P\tst %B $%d.%d\n", r->loop,					p, blsh(bn), changer, changea);		}		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, ulong 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){	int x;	a->sym = 0;	x = a->index;	if(rn >= D_R0 && rn < D_R0+NREG)		goto addr;	if(x == (I_INDEX3|D_NONE)) {		a->type = rn | I_INDIR;		a->index = D_NONE;		a->offset = a->displace;		a->displace = 0;		return;	}	if(x != D_NONE) {		a->type = rn | I_INDIR;		a->index += I_INDEX1 - I_INDEX2;		a->offset = a->displace;		a->displace = 0;		return;	}	a->type = rn | (a->type & I_INDIR);	return;addr:	if(x == (I_INDEX3|D_NONE)) {		a->type = D_NONE|I_INDIR;		a->index += I_INDEX1 + rn - D_NONE - I_INDEX3;		a->scale = 4;	/* .L*1 */		a->offset = a->displace;		a->displace = 0;		return;	}	a->type = rn | (a->type & I_INDIR);}/* *	bit	reg *	0-7	R0-R7 *	8-15	A0-A7 *	16-23	F0-F7 */ulongRtoB(int r){	if(r < 0 || r >= NREG)		return 0;	return 1L << (r + 0);}intBtoR(ulong b){	b &= 0x0000ffL;	if(b == 0)		return NREG;	return bitno(b) - 0;}ulongAtoB(int a){	if(a < 0 || a >= NREG)		return 0;	return 1L << (a + NREG);}intBtoA(ulong b){	b &= 0x00ff00L;	if(b == 0)		return NREG;	return bitno(b) - NREG;}ulongFtoB(int f){	if(f < 0 || f >= NREG)		return 0;	return 1L << (f + NREG+NREG);}intBtoF(ulong b){	b &= 0xff0000L;	if(b == 0)		return NREG;	return bitno(b) - NREG-NREG;}

⌨️ 快捷键说明

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