Ejemplo n.º 1
0
/*
 * NAME:	optimize->asgnexp()
 * DESCRIPTION:	optimize an assignment expression
 */
static Uint opt_asgnexp(node **m, bool pop)
{
    node *n, *t;
    Uint d1, d2;

    n = *m;
    d2 = opt_expr(&n->r.right, FALSE);

    if ((n->r.right->type == N_INT || n->r.right->type == N_FLOAT) &&
	n->l.left->mod == n->r.right->mod) {
	switch (n->type) {
	case N_ADD_EQ:
	case N_ADD_EQ_FLOAT:
	    if (NFLT_ISZERO(n->r.right)) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (NFLT_ISONE(n->r.right)) {
		n->type = N_ADD_EQ_1_FLOAT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (NFLT_ISMONE(n->r.right)) {
		n->type = N_SUB_EQ_1_FLOAT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_ADD_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == 1) {
		n->type = N_ADD_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (n->r.right->l.number == -1) {
		n->type = N_SUB_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_AND_EQ_INT:
	    if (n->r.right->l.number == 0) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == -1) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_MULT_EQ:
	case N_MULT_EQ_FLOAT:
	    if (NFLT_ISZERO(n->r.right)) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    /* fall through */
	case N_DIV_EQ:
	case N_DIV_EQ_FLOAT:
	    if (NFLT_ISONE(n->r.right)) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_MULT_EQ_INT:
	    if (n->r.right->l.number == 0) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    /* fall through */
	case N_DIV_EQ_INT:
	    if (n->r.right->l.number == 1) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_LSHIFT_EQ_INT:
	case N_RSHIFT_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_MOD_EQ_INT:
	    if (n->r.right->l.number == 1) {
		n->type = N_ASSIGN;
		n->r.right->l.number = 0;
		return opt_expr(m, pop);
	    }
	    break;

	case N_OR_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == -1) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    break;

	case N_SUB_EQ:
	case N_SUB_EQ_FLOAT:
	    if (NFLT_ISZERO(n->r.right)) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (NFLT_ISONE(n->r.right)) {
		n->type = N_SUB_EQ_1_FLOAT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (NFLT_ISMONE(n->r.right)) {
		n->type = N_ADD_EQ_1_FLOAT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_SUB_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == 1) {
		n->type = N_SUB_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (n->r.right->l.number == -1) {
		n->type = N_ADD_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_XOR_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;
	}
    }

    d1 = opt_lvalue(n->l.left) + 1;

    if (n->type == N_SUM_EQ) {
	d1++;
	return max2(d1, ((d1 < 6) ? d1 : 6) + d2);
    }
    if (n->type == N_ADD_EQ &&
	(n->mod == T_STRING || (n->mod & T_REF) != 0) &&
	(n->r.right->mod == T_STRING || (n->r.right->mod & T_REF) != 0 ||
	 n->r.right->type == N_RANGE)) {
	/*
	 * see if the summand operator can be used
	 */
	switch (n->r.right->type) {
	case N_ADD:
	    n->r.right->type = N_SUM;
	    d2 += 2;				/* SUM_SIMPLE on both sides */
	    if (n->r.right->l.left->type == N_RANGE) {
		d1++;
	    }
	    n->type = N_SUM_EQ;
	    d1++;				/* add SUM_SIMPLE */
	    return max2(d1, ((d1 < 6) ? d1 : 6) + d2);

	case N_AGGR:
	    d2++;				/* add SUM_SIMPLE */
	    n->type = N_SUM_EQ;
	    d1++;				/* add SUM_SIMPLE */
	    return max2(d1, ((d1 < 6) ? d1 : 6) + d2);

	case N_RANGE:
	    d2 = max2(d2, 3);			/* at least 3 */
	    /* fall through */
	case N_SUM:
	    n->type = N_SUM_EQ;
	    d1++;				/* add SUM_SIMPLE */
	    return max2(d1, ((d1 < 6) ? d1 : 6) + d2);

	case N_FUNC:
	    if (n->r.right->r.number == kd_allocate ||
		n->r.right->r.number == kd_allocate_int ||
		n->r.right->r.number == kd_allocate_float) {
		t = n->r.right->l.left->r.right;
		if (t != (node *) NULL && t->type != N_PAIR &&
		    t->type != N_SPREAD && t->mod == T_INT) {
		    d2++;			/* add SUM_ALLOCATE */
		    n->type = N_SUM_EQ;
		    d1++;			/* add SUM_SIMPLE */
		    return max2(d1, ((d1 < 6) ? d1 : 6) + d2);
		}
	    }
	    break;
	}
    }

    return max2(d1, ((d1 < 5) ? d1 : 5) + d2);
}
Ejemplo n.º 2
0
/*
 * NAME:	optimize->asgnexp()
 * DESCRIPTION:	optimize an assignment expression
 */
static Uint opt_asgnexp(node **m, bool pop)
{
    node *n;
    Uint d1, d2;

    n = *m;
    d2 = opt_expr(&n->r.right, FALSE);

    if ((n->r.right->type == N_INT || n->r.right->type == N_FLOAT) &&
	n->l.left->mod == n->r.right->mod) {
	switch (n->type) {
	case N_ADD_EQ:
	    if (NFLT_ISZERO(n->r.right)) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (NFLT_ISONE(n->r.right)) {
		n->type = N_ADD_EQ_1;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (NFLT_ISMONE(n->r.right)) {
		n->type = N_SUB_EQ_1;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_ADD_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == 1) {
		n->type = N_ADD_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (n->r.right->l.number == -1) {
		n->type = N_SUB_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_AND_EQ_INT:
	    if (n->r.right->l.number == 0) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == -1) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_MULT_EQ:
	    if (NFLT_ISZERO(n->r.right)) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    /* fall through */
	case N_DIV_EQ:
	    if (NFLT_ISONE(n->r.right)) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_MULT_EQ_INT:
	    if (n->r.right->l.number == 0) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    /* fall through */
	case N_DIV_EQ_INT:
	    if (n->r.right->l.number == 1) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_LSHIFT_EQ_INT:
	case N_RSHIFT_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;

	case N_MOD_EQ_INT:
	    if (n->r.right->l.number == 1) {
		n->type = N_ASSIGN;
		n->r.right->l.number = 0;
		return opt_expr(m, pop);
	    }
	    break;

	case N_OR_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == -1) {
		n->type = N_ASSIGN;
		return opt_expr(m, pop);
	    }
	    break;

	case N_SUB_EQ:
	    if (NFLT_ISZERO(n->r.right)) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (NFLT_ISONE(n->r.right)) {
		n->type = N_SUB_EQ_1;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (NFLT_ISMONE(n->r.right)) {
		n->type = N_ADD_EQ_1;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_SUB_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    if (n->r.right->l.number == 1) {
		n->type = N_SUB_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    if (n->r.right->l.number == -1) {
		n->type = N_ADD_EQ_1_INT;
		return opt_lvalue(n->l.left) + 1;
	    }
	    break;

	case N_XOR_EQ_INT:
	    if (n->r.right->l.number == 0) {
		*m = n->l.left;
		return opt_expr(m, pop);
	    }
	    break;
	}
    }

    d1 = opt_lvalue(n->l.left) + 1;

    if (n->type == N_SUM_EQ) {
	d1++;
	return max2(d1, ((d1 < 5) ? d1 : 5) + d2);
    }
    if (n->type == N_ADD_EQ &&
	(n->mod == T_STRING || (n->mod & T_REF) != 0) &&
	(n->r.right->mod == T_STRING || (n->r.right->mod & T_REF) != 0 ||
	 n->r.right->type == N_RANGE)) {
	/*
	 * see if the summand operator can be used
	 */
	switch (n->r.right->type) {
	case N_ADD:
	    n->r.right->type = N_SUM;
	    d2 += 2;				/* (-2) on both sides */
	    if (n->r.right->l.left->type == N_RANGE) {
		d1++;
	    }
	    n->type = N_SUM_EQ;
	    d1++;				/* add (-2) */
	    return max2(d1, ((d1 < 5) ? d1 : 5) + d2);

	case N_AGGR:
	    d2++;				/* add (-2) */
	    n->type = N_SUM_EQ;
	    d1++;				/* add (-2) */
	    return max2(d1, ((d1 < 5) ? d1 : 5) + d2);

	case N_RANGE:
	    d2 = max2(d2, 3);			/* at least 3 */
	    /* fall through */
	case N_SUM:
	    n->type = N_SUM_EQ;
	    d1++;				/* add (-2) */
	    return max2(d1, ((d1 < 5) ? d1 : 5) + d2);
	}
    }

    return max2(d1, ((d1 < 4) ? d1 : 4) + d2);
}