Example #1
0
File: pass.c Project: pipul/lab
static void
xfol(Prog *p, Prog **last)
{
	Prog *q;
	int i;
	enum as a;

loop:
	if(p == P)
		return;
	if(p->as == AJMP)
	if((q = p->pcond) != P && q->as != ATEXT) {
		/* mark instruction as done and continue layout at target of jump */
		p->mark = 1;
		p = q;
		if(p->mark == 0)
			goto loop;
	}
	if(p->mark) {
		/* 
		 * p goes here, but already used it elsewhere.
		 * copy up to 4 instructions or else branch to other copy.
		 */
		for(i=0,q=p; i<4; i++,q=q->link) {
			if(q == P)
				break;
			if(q == *last)
				break;
			a = q->as;
			if(a == ANOP) {
				i--;
				continue;
			}
			if(nofollow(a) || pushpop(a))	
				break;	// NOTE(rsc): arm does goto copy
			if(q->pcond == P || q->pcond->mark)
				continue;
			if(a == ACALL || a == ALOOP)
				continue;
			for(;;) {
				if(p->as == ANOP) {
					p = p->link;
					continue;
				}
				q = copyp(p);
				p = p->link;
				q->mark = 1;
				(*last)->link = q;
				*last = q;
				if(q->as != a || q->pcond == P || q->pcond->mark)
					continue;

				q->as = relinv(q->as);
				p = q->pcond;
				q->pcond = q->link;
				q->link = p;
				xfol(q->link, last);
				p = q->link;
				if(p->mark)
					return;
				goto loop;
			}
		} /* */
		q = prg();
		q->as = AJMP;
		q->line = p->line;
		q->to.type = D_BRANCH;
		q->to.offset = p->pc;
		q->pcond = p;
		p = q;
	}
	
	/* emit p */
	p->mark = 1;
	(*last)->link = p;
	*last = p;
	a = p->as;

	/* continue loop with what comes after p */
	if(nofollow(a))
		return;
	if(p->pcond != P && a != ACALL) {
		/*
		 * some kind of conditional branch.
		 * recurse to follow one path.
		 * continue loop on the other.
		 */
		q = brchain(p->link);
		if(q != P && q->mark)
		if(a != ALOOP) {
			p->as = relinv(a);
			p->link = p->pcond;
			p->pcond = q;
		}
		xfol(p->link, last);
		q = brchain(p->pcond);
		if(q->mark) {
			p->pcond = q;
			return;
		}
		p = q;
		goto loop;
	}
	p = p->link;
	goto loop;
}
Example #2
0
File: pass.c Project: 99years/plan9
void
xfol(Prog *p)
{
    Prog *q;
    int i;
    enum as a;

loop:
    if(p == P)
        return;
    if(p->as == ATEXT)
        curtext = p;
    if(p->as == AJMP)
        if((q = p->pcond) != P) {
            p->mark = 1;
            p = q;
            if(p->mark == 0)
                goto loop;
        }
    if(p->mark) {
        /* copy up to 4 instructions to avoid branch */
        for(i=0,q=p; i<4; i++,q=q->link) {
            if(q == P)
                break;
            if(q == lastp)
                break;
            a = q->as;
            if(a == ANOP) {
                i--;
                continue;
            }
            switch(a) {
            case AJMP:
            case ARET:
            case AIRETL:

            case APUSHL:
            case APUSHFL:
            case APUSHW:
            case APUSHFW:
            case APOPL:
            case APOPFL:
            case APOPW:
            case APOPFW:
                goto brk;
            }
            if(q->pcond == P || q->pcond->mark)
                continue;
            if(a == ACALL || a == ALOOP)
                continue;
            for(;;) {
                if(p->as == ANOP) {
                    p = p->link;
                    continue;
                }
                q = copyp(p);
                p = p->link;
                q->mark = 1;
                lastp->link = q;
                lastp = q;
                if(q->as != a || q->pcond == P || q->pcond->mark)
                    continue;

                q->as = relinv(q->as);
                p = q->pcond;
                q->pcond = q->link;
                q->link = p;
                xfol(q->link);
                p = q->link;
                if(p->mark)
                    return;
                goto loop;
            }
        } /* */
brk:
        ;
        q = prg();
        q->as = AJMP;
        q->line = p->line;
        q->to.type = D_BRANCH;
        q->to.offset = p->pc;
        q->pcond = p;
        p = q;
    }
    p->mark = 1;
    lastp->link = p;
    lastp = p;
    a = p->as;
    if(a == AJMP || a == ARET || a == AIRETL)
        return;
    if(p->pcond != P)
        if(a != ACALL) {
            q = brchain(p->link);
            if(q != P && q->mark)
                if(a != ALOOP) {
                    p->as = relinv(a);
                    p->link = p->pcond;
                    p->pcond = q;
                }
            xfol(p->link);
            q = brchain(p->pcond);
            if(q->mark) {
                p->pcond = q;
                return;
            }
            p = q;
            goto loop;
        }
    p = p->link;
    goto loop;
}
Example #3
0
void
xfol(Prog *p)
{
	Prog *q, *r;
	int a, i;

loop:
	if(p == P)
		return;
	setarch(p);
	a = p->as;
	if(a == ATEXT)
		curtext = p;
	if(!curtext->from.sym->reachable) {
		p = p->cond;
		goto loop;
	}
	if(a == AB) {
		q = p->cond;
		if(q != P) {
			p->mark |= FOLL;
			p = q;
			if(!(p->mark & FOLL))
				goto loop;
		}
	}
	if(p->mark & FOLL) {
		for(i=0,q=p; i<4; i++,q=q->link) {
			if(q == lastp)
				break;
			a = q->as;
			if(a == ANOP) {
				i--;
				continue;
			}
			if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
				goto copy;
			if(!q->cond || (q->cond->mark&FOLL))
				continue;
			if(a != ABEQ && a != ABNE)
				continue;
		copy:
			for(;;) {
				r = prg();
				*r = *p;
				if(!(r->mark&FOLL))
					print("cant happen 1\n");
				r->mark |= FOLL;
				if(p != q) {
					p = p->link;
					lastp->link = r;
					lastp = r;
					continue;
				}
				lastp->link = r;
				lastp = r;
				if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
					return;
				r->as = ABNE;
				if(a == ABNE)
					r->as = ABEQ;
				r->cond = p->link;
				r->link = p->cond;
				if(!(r->link->mark&FOLL))
					xfol(r->link);
				if(!(r->cond->mark&FOLL))
					print("cant happen 2\n");
				return;
			}
		}
		a = AB;
		q = prg();
		q->as = a;
		q->line = p->line;
		q->to.type = D_BRANCH;
		q->to.offset = p->pc;
		q->cond = p;
		p = q;
	}
	p->mark |= FOLL;
	lastp->link = p;
	lastp = p;
	if(a == AB || (a == ARET && p->scond == 14) || a == ARFE){
		return;
	}
	if(p->cond != P)
	if(a != ABL && a != ABX && p->link != P) {
		q = brchain(p->link);
		if(a != ATEXT && a != ABCASE)
		if(q != P && (q->mark&FOLL)) {
			p->as = relinv(a);
			p->link = p->cond;
			p->cond = q;
		}
		xfol(p->link);
		q = brchain(p->cond);
		if(q == P)
			q = p->cond;
		if(q->mark&FOLL) {
			p->cond = q;
			return;
		}
		p = q;
		goto loop;
	}
	p = p->link;
	goto loop;
}
Example #4
0
File: pass.c Project: gnanderson/go
static void
xfol(Prog *p, Prog **last)
{
	Prog *q, *r;
	int a, i;

loop:
	if(p == P)
		return;
	a = p->as;
	if(a == AB) {
		q = p->cond;
		if(q != P && q->as != ATEXT) {
			p->mark |= FOLL;
			p = q;
			if(!(p->mark & FOLL))
				goto loop;
		}
	}
	if(p->mark & FOLL) {
		for(i=0,q=p; i<4; i++,q=q->link) {
			if(q == *last || q == nil)
				break;
			a = q->as;
			if(a == ANOP) {
				i--;
				continue;
			}
			if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF)
				goto copy;
			if(q->cond == P || (q->cond->mark&FOLL))
				continue;
			if(a != ABEQ && a != ABNE)
				continue;
		copy:
			for(;;) {
				r = prg();
				*r = *p;
				if(!(r->mark&FOLL))
					print("can't happen 1\n");
				r->mark |= FOLL;
				if(p != q) {
					p = p->link;
					(*last)->link = r;
					*last = r;
					continue;
				}
				(*last)->link = r;
				*last = r;
				if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF)
					return;
				r->as = ABNE;
				if(a == ABNE)
					r->as = ABEQ;
				r->cond = p->link;
				r->link = p->cond;
				if(!(r->link->mark&FOLL))
					xfol(r->link, last);
				if(!(r->cond->mark&FOLL))
					print("can't happen 2\n");
				return;
			}
		}
		a = AB;
		q = prg();
		q->as = a;
		q->line = p->line;
		q->to.type = D_BRANCH;
		q->to.offset = p->pc;
		q->cond = p;
		p = q;
	}
	p->mark |= FOLL;
	(*last)->link = p;
	*last = p;
	if(a == AB || (a == ARET && p->scond == 14) || a == ARFE || a == AUNDEF){
		return;
	}
	if(p->cond != P)
	if(a != ABL && a != ABX && p->link != P) {
		q = brchain(p->link);
		if(a != ATEXT && a != ABCASE)
		if(q != P && (q->mark&FOLL)) {
			p->as = relinv(a);
			p->link = p->cond;
			p->cond = q;
		}
		xfol(p->link, last);
		q = brchain(p->cond);
		if(q == P)
			q = p->cond;
		if(q->mark&FOLL) {
			p->cond = q;
			return;
		}
		p = q;
		goto loop;
	}
	p = p->link;
	goto loop;
}