Example #1
0
/*
 * Compare two trees; return 1 if equal and 0 if not.
 */
int
treecmp(NODE *p1, NODE *p2)
{
	if (p1->n_op != p2->n_op)
		return 0;

	switch (p1->n_op) {
	case SCONV:
	case UMUL:
		return treecmp(p1->n_left, p2->n_left);

	case OREG:
		if (getlval(p1) != getlval(p2) || p1->n_rval != p2->n_rval)
			return 0;
		break;

	case NAME:
	case ICON:
		if (strcmp(p1->n_name, p2->n_name))
			return 0;
		/* FALLTHROUGH */
		if (getlval(p1) != getlval(p2))
			return 0;
		break;

	case TEMP:
#ifdef notyet
		/* SSA will put assignment in separate register */
		/* Help out by accepting different regs here */
		if (xssa)
			break;
#endif
	case REG:
		if (p1->n_rval != p2->n_rval)
			return 0;
		break;
	case LS:
	case RS:
	case PLUS:
	case MINUS:
	case MUL:
	case DIV:
		if (treecmp(p1->n_left, p2->n_left) == 0 ||
		    treecmp(p1->n_right, p2->n_right) == 0)
			return 0;
		break;

	default:
		return 0;
	}
	return 1;
}
Example #2
0
static int
inctree(NODE *p)
{
	if (p->n_op == MINUS && p->n_left->n_op == ASSIGN && 
	    p->n_left->n_right->n_op == PLUS &&
	    treecmp(p->n_left->n_left, p->n_left->n_right->n_left) &&
	    p->n_right->n_op == ICON && p->n_right->n_lval == 1 &&
	    p->n_left->n_right->n_right->n_op == ICON &&
	    p->n_left->n_right->n_right->n_lval == 1) {
		/* post-increment by 1; (r0)+ */
		if (isreg(p->n_left->n_left)) /* Ignore if index not in reg */
			return 1;
	}
	return 0;
}
Example #3
0
long treestack_push(Dataptr matrix, Treestack *sp, const Branch *const barray, const long root)
{
    long i;			/* loop counter */
    Branch *stacktree = NULL;	/* current tree on stack */
    long stackroot;		/* root of current tree */

    /* return before push if not a new topology */
    /* check backwards as similar trees may be discovered together */
    for (i = sp->next - 1; i >= 0; i--) {
        stacktree = sp->stack[i].tree;
        stackroot = sp->stack[i].root;
        if (treecmp(matrix, stacktree, stackroot, barray, root) == 0) return 0;
    }

    /* topology is new so must be pushed */
    dopush(matrix, sp, barray, root);
    return 1;

} /* end treestack_push() */
Example #4
0
/*
 * Try to find constructs like "a = a + 1;" and match them together
 * with instructions like "incl a" or "addl $1,a".
 *
 * Level assignment for priority:
 *	left	right	prio
 *	-	-	-
 *	direct	direct	1
 *	direct	REG	2
 *	direct	OREG	3
 *	OREG	direct	4
 *	OREG	REG	5
 *	OREG	OREG	6
 */
int
findmops(NODE *p, int cookie)
{
	extern int *qtable[];
	struct optab *q;
	int i, sh, shl, shr, lvl = 10;
	NODE *l, *r;
	int *ixp;
	struct optab *qq = NULL; /* XXX gcc */
	int idx = 0, gol = 0, gor = 0;

	shl = shr = 0;

	F2DEBUG(("findmops tree: %s\n", prcook(cookie)));
	F2WALK(p);

	l = getlr(p, 'L');
	r = getlr(p, 'R');
	/* See if this is a usable tree to work with */
	/* Currently only check for leaves */
	if (optype(r->n_op) != BITYPE || treecmp(l, r->n_left) == 0)
		return FFAIL;

	F2DEBUG(("findmops is useable\n"));

	/* We can try to find a match.  Use right op */
	ixp = qtable[r->n_op];
	l = getlr(r, 'L');
	r = getlr(r, 'R');

	for (i = 0; ixp[i] >= 0; i++) {
		q = &table[ixp[i]];

		F2DEBUG(("findmops: ixp %d\n", ixp[i]));
		if (!acceptable(q))		/* target-dependent filter */
			continue;

		if (ttype(l->n_type, q->ltype) == 0 ||
		    ttype(r->n_type, q->rtype) == 0)
			continue; /* Types must be correct */

		F2DEBUG(("findmops got types\n"));

		switch (cookie) {
		case FOREFF:
			if ((q->visit & FOREFF) == 0)
				continue; /* Not only for side effects */
			break;
		case FORCC:
			if ((q->visit & FORCC) == 0)
				continue; /* Not only for side effects */
			break;
		default:
			if ((cookie & q->visit) == 0)
				continue; /* Won't match requested shape */
			if (((cookie & INREGS & q->lshape) == 0) || !isreg(l))
				continue; /* Bad return register */
			break;
		}
		F2DEBUG(("findmops cookie\n"));

		/*
		 * left shape must match left node.
		 */
		if ((shl = tshape(l, q->lshape)) != SRDIR && (shl != SROREG))
			continue;

		F2DEBUG(("findmops lshape %s\n", srtyp[shl]));
		F2WALK(l);

		if ((shr = chcheck(r, q->rshape, 0)) == SRNOPE)
			continue;

		F2DEBUG(("findmops rshape %s\n", srtyp[shr]));

		/*
		 * Only allow RLEFT. XXX
		 */
		if ((q->rewrite & (RLEFT|RRIGHT)) != RLEFT)
			continue;

		F2DEBUG(("rewrite OK\n"));

		F2WALK(r);
		if (q->needs & REWRITE)
			break;	/* Done here */

		if (lvl <= (shl + shr))
			continue;

		lvl = shl + shr;
		qq = q;
		idx = ixp[i];
		gol = shl;
		gor = shr;
	}

	if (lvl == 10)
		return FFAIL;
	F2DEBUG(("findmops entry %d(%s,%s)\n", idx, srtyp[gol], srtyp[gor]));

	/*
	 * Now we're here and have a match. left is semi-direct and 
	 * right may be anything.
	 */

	sh = -1;
	sh = shswitch(sh, p->n_left, qq->lshape, cookie,
	    qq->rewrite & RLEFT, gol);
	sh = shswitch(sh, r, qq->rshape, cookie, 0, gor);

	if (sh == -1) {
		if (cookie & (FOREFF|FORCC))
			sh = 0;
		else
			sh = ffs(cookie & qq->visit & INREGS)-1;
	}
	F2DEBUG(("findmops done: node %p class %d\n", p, sh));

	/* Trickery:  Set table index on assign to op instead */
	/* gencode() will remove useless nodes */
	p->n_su = MKIDX(idx, 0);
	p->n_su |= ISMOPS; /* XXX tell gencode to reduce the right tree */
	SCLASS(p->n_su, sh);

	return sh;
}