예제 #1
0
파일: peep.c 프로젝트: BGCX261/znos-git
void
peep(void)
{
	Reg *r, *r1, *r2;
	Prog *p, *p1;
	int t;
/*
 * complete R structure
 */
	t = 0;
	for(r=firstr; r!=R; r=r1) {
		r1 = r->link;
		if(r1 == R)
			break;
		p = r->prog->link;
		while(p != r1->prog)
		switch(p->as) {
		default:
			r2 = rega();
			r->link = r2;
			r2->link = r1;

			r2->prog = p;
			r2->p1 = r;
			r->s1 = r2;
			r2->s1 = r1;
			r1->p1 = r2;

			r = r2;
			t++;

		case ADATA:
		case AGLOBL:
		case ANAME:
		case ASIGNAME:
			p = p->link;
		}
	}

loop1:
	t = 0;
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		if(p->as == ASLL || p->as == ASRL || p->as == ASRA) {
			/*
			 * elide shift into D_SHIFT operand of subsequent instruction
			 */
			if(shiftprop(r)) {
				excise(r);
				t++;
			}
		}
		if(p->as == AMOVW || p->as == AMOVF || p->as == AMOVD)
		if(regtyp(&p->to)) {
			if(p->from.type == D_CONST)
				constprop(&p->from, &p->to, r->s1);
			else if(regtyp(&p->from))
			if(p->from.type == p->to.type) {
				if(copyprop(r)) {
					excise(r);
					t++;
				} else
				if(subprop(r) && copyprop(r)) {
					excise(r);
					t++;
				}
			}
		}
	}
	if(t)
		goto loop1;
	/*
	 * look for MOVB x,R; MOVB R,R
	 */
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		switch(p->as) {
		default:
			continue;
		case AEOR:
			/*
			 * EOR -1,x,y => MVN x,y
			 */
			if(p->from.type == D_CONST && p->from.offset == -1) {
				p->as = AMVN;
				p->from.type = D_REG;
				if(p->reg != NREG)
					p->from.reg = p->reg;
				else
					p->from.reg = p->to.reg;
				p->reg = NREG;
			}
			continue;
		case AMOVH:
		case AMOVHU:
		case AMOVB:
		case AMOVBU:
			if(p->to.type != D_REG)
				continue;
			break;
		}
		r1 = r->link;
		if(r1 == R)
			continue;
		p1 = r1->prog;
		if(p1->as != p->as)
			continue;
		if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
			continue;
		if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
			continue;
		excise(r1);
	}

	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case AMOVW:
		case AMOVB:
		case AMOVBU:
			if(p->from.type == D_OREG && p->from.offset == 0)
				xtramodes(r, &p->from);
			else if(p->to.type == D_OREG && p->to.offset == 0)
				xtramodes(r, &p->to);
			else
				continue;
			break;
		case ACMP:
			/*
			 * elide CMP $0,x if calculation of x can set condition codes
			 */
			if(p->from.type != D_CONST || p->from.offset != 0)
				continue;
			r2 = r->s1;
			if(r2 == R)
				continue;
			t = r2->prog->as;
			switch(t) {
			default:
				continue;
			case ABEQ:
			case ABNE:
			case ABMI:
			case ABPL:
				break;
			case ABGE:
				t = ABPL;
				break;
			case ABLT:
				t = ABMI;
				break;
			case ABHI:
				t = ABNE;
				break;
			case ABLS:
				t = ABEQ;
				break;
			}
			r1 = r;
			do
				r1 = uniqp(r1);
			while (r1 != R && r1->prog->as == ANOP);
			if(r1 == R)
				continue;
			p1 = r1->prog;
			if(p1->to.type != D_REG)
				continue;
			if(p1->to.reg != p->reg)
			if(!(p1->as == AMOVW && p1->from.type == D_REG && p1->from.reg == p->reg))
				continue;
			switch(p1->as) {
			default:
				continue;
			case AMOVW:
				if(p1->from.type != D_REG)
					continue;
			case AAND:
			case AEOR:
			case AORR:
			case ABIC:
			case AMVN:
			case ASUB:
			case ARSB:
			case AADD:
			case AADC:
			case ASBC:
			case ARSC:
				break;
			}
			p1->scond |= C_SBIT;
			r2->prog->as = t;
			excise(r);
			continue;
		}
	}

	predicate();
}
예제 #2
0
파일: peep.c 프로젝트: cloudaice/golang
void
peep(Prog *firstp)
{
	Flow *r;
	Graph *g;
	Prog *p;
	int t;

	g = flowstart(firstp, sizeof(Flow));
	if(g == nil)
		return;
	for(r=g->start, t=0; r!=nil; r=r->link, t++)
		r->active = t;

loop1:
	if(debug['P'] && debug['v'])
		dumpit("loop1", g->start, 0);

	t = 0;
	for(r=g->start; r!=nil; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case ASLL:
		case ASRL:
		case ASRA:
			/*
			 * elide shift into D_SHIFT operand of subsequent instruction
			 */
//			if(shiftprop(r)) {
//				excise(r);
//				t++;
//				break;
//			}
			break;

		case AMOVB:
		case AMOVH:
		case AMOVW:
		case AMOVF:
		case AMOVD:
			if(regtyp(&p->from))
			if(p->from.type == p->to.type)
			if(p->scond == C_SCOND_NONE) {
				if(copyprop(g, r)) {
					excise(r);
					t++;
					break;
				}
				if(subprop(r) && copyprop(g, r)) {
					excise(r);
					t++;
					break;
				}
			}
			break;

		case AMOVHS:
		case AMOVHU:
		case AMOVBS:
		case AMOVBU:
			if(p->from.type == D_REG) {
				if(shortprop(r))
					t++;
			}
			break;

#ifdef NOTDEF
			if(p->scond == C_SCOND_NONE)
			if(regtyp(&p->to))
			if(isdconst(&p->from)) {
				constprop(&p->from, &p->to, r->s1);
			}
			break;
#endif
		}
	}
	if(t)
		goto loop1;

	for(r=g->start; r!=nil; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case AEOR:
			/*
			 * EOR -1,x,y => MVN x,y
			 */
			if(isdconst(&p->from) && p->from.offset == -1) {
				p->as = AMVN;
				p->from.type = D_REG;
				if(p->reg != NREG)
					p->from.reg = p->reg;
				else
					p->from.reg = p->to.reg;
				p->reg = NREG;
			}
			break;
		}
	}

	for(r=g->start; r!=nil; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case AMOVW:
		case AMOVB:
		case AMOVBS:
		case AMOVBU:
			if(p->from.type == D_OREG && p->from.offset == 0)
				xtramodes(g, r, &p->from);
			else
			if(p->to.type == D_OREG && p->to.offset == 0)
				xtramodes(g, r, &p->to);
			else
				continue;
			break;
//		case ACMP:
//			/*
//			 * elide CMP $0,x if calculation of x can set condition codes
//			 */
//			if(isdconst(&p->from) || p->from.offset != 0)
//				continue;
//			r2 = r->s1;
//			if(r2 == nil)
//				continue;
//			t = r2->prog->as;
//			switch(t) {
//			default:
//				continue;
//			case ABEQ:
//			case ABNE:
//			case ABMI:
//			case ABPL:
//				break;
//			case ABGE:
//				t = ABPL;
//				break;
//			case ABLT:
//				t = ABMI;
//				break;
//			case ABHI:
//				t = ABNE;
//				break;
//			case ABLS:
//				t = ABEQ;
//				break;
//			}
//			r1 = r;
//			do
//				r1 = uniqp(r1);
//			while (r1 != nil && r1->prog->as == ANOP);
//			if(r1 == nil)
//				continue;
//			p1 = r1->prog;
//			if(p1->to.type != D_REG)
//				continue;
//			if(p1->to.reg != p->reg)
//			if(!(p1->as == AMOVW && p1->from.type == D_REG && p1->from.reg == p->reg))
//				continue;
//
//			switch(p1->as) {
//			default:
//				continue;
//			case AMOVW:
//				if(p1->from.type != D_REG)
//					continue;
//			case AAND:
//			case AEOR:
//			case AORR:
//			case ABIC:
//			case AMVN:
//			case ASUB:
//			case ARSB:
//			case AADD:
//			case AADC:
//			case ASBC:
//			case ARSC:
//				break;
//			}
//			p1->scond |= C_SBIT;
//			r2->prog->as = t;
//			excise(r);
//			continue;
		}
	}

//	predicate(g);

	flowend(g);
}