Exemplo n.º 1
0
static rcc_node_ty visit(Node p) {
	Symbol q;
	rcc_node_ty left = NULL, right = NULL;
	int suffix = optype(p->op), size = opsize(p->op);

	assert(p);
	for (q = temps; q; q = q->u.t.next)
		if (q->u.t.cse == p) {
			q->u.t.cse = NULL;
			return rcc_CSE(0, 0, symboluid(q), visit(p));
		}
	if (p->kids[0] != NULL)
		left = visit(p->kids[0]);
	if (p->kids[1] != NULL)
		right = visit(p->kids[1]);
	switch (specific(p->op)) {
	case CNST+F:
		assert(p->syms[0]);
		return rcc_CNSTF(suffix, size, mk_real(size, p->syms[0]->u.c.v));
	case CALL+B:
		assert(p->syms[0]);
		assert(p->syms[0]->type);
		return rcc_CALLB(suffix, size, left, right, typeuid(p->syms[0]->type));
	case RET+V:
		return rcc_RET(suffix, size);
	case LABEL+V:
		assert(p->syms[0]);
		return rcc_LABEL(suffix, size, p->syms[0]->u.l.label);
	}
	switch (generic(p->op)) {
	case CNST:
		assert(p->syms[0]);
		return rcc_CNST(suffix, size, p->syms[0]->u.c.v.i);	/* FIXME */
	case ARG:
		assert(p->syms[0]);
		return rcc_ARG(suffix, size, left, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i);
	case ASGN:
		assert(p->syms[0]);
		assert(p->syms[1]);
		return rcc_ASGN(suffix, size, left, right, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i);
	case CVF: case CVI: case CVP: case CVU:
		assert(p->syms[0]);
		return rcc_CVT(suffix, size, generic(p->op), left, p->syms[0]->u.c.v.i);
	case CALL:
		assert(p->syms[0]);
		assert(p->syms[0]->type);
		return rcc_CALL(suffix, size, left, typeuid(p->syms[0]->type));
#define xx(op) case op: return rcc_##op(suffix, size, symboluid(p->syms[0]))
	xx(ADDRG);
	xx(ADDRF);
#undef xx
	case ADDRL:
		if (!p->syms[0]->defined)
			(*IR->local)(p->syms[0]);
		p->syms[0]->defined = 1;
		return rcc_ADDRL(suffix, size, symboluid(p->syms[0]));
	case JUMP:
		if (p->syms[0] != NULL)
			return rcc_BRANCH(suffix, size, p->syms[0]->u.l.label);
		return rcc_Unary(suffix, size, generic(p->op), left);
	case INDIR: case RET: case NEG: case BCOM: 
		return rcc_Unary(suffix, size, generic(p->op), left);
	case BOR: case BAND: case BXOR: case RSH: case LSH:
	case ADD: case SUB: case DIV: case MUL: case MOD:
		return rcc_Binary(suffix, size, generic(p->op), left, right);
	case EQ: case NE: case GT: case GE: case LE: case LT:
		assert(p->syms[0]);
		return rcc_Compare(suffix, size, generic(p->op), left, right, p->syms[0]->u.l.label);
	}
	assert(0);
	return NULL;
}
Exemplo n.º 2
0
static void dumptree(Node p) {
    switch (specific(p->op)) {
    case ASGN+B:
        assert(p->kids[0]);
        assert(p->kids[1]);
        assert(p->syms[0]);
        dumptree(p->kids[0]);
        dumptree(p->kids[1]);
        print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.u);
        return;
    case RET+V:
        assert(!p->kids[0]);
        assert(!p->kids[1]);
        print("%s\n", opname(p->op));
        return;
    }
    switch (generic(p->op)) {
    case CNST:
    case ADDRG:
    case ADDRF:
    case ADDRL:
    case LABEL:
        assert(!p->kids[0]);
        assert(!p->kids[1]);
        assert(p->syms[0] && p->syms[0]->x.name);
        print("%s %s\n", opname(p->op), p->syms[0]->x.name);
        return;
    case CVF:
    case CVI:
    case CVP:
    case CVU:
        assert(p->kids[0]);
        assert(!p->kids[1]);
        assert(p->syms[0]);
        dumptree(p->kids[0]);
        print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.i);
        return;
    case ARG:
    case BCOM:
    case NEG:
    case INDIR:
    case JUMP:
    case RET:
        assert(p->kids[0]);
        assert(!p->kids[1]);
        dumptree(p->kids[0]);
        print("%s\n", opname(p->op));
        return;
    case CALL:
        assert(p->kids[0]);
        assert(!p->kids[1]);
        assert(optype(p->op) != B);
        dumptree(p->kids[0]);
        print("%s\n", opname(p->op));
        return;
    case ASGN:
    case BOR:
    case BAND:
    case BXOR:
    case RSH:
    case LSH:
    case ADD:
    case SUB:
    case DIV:
    case MUL:
    case MOD:
        assert(p->kids[0]);
        assert(p->kids[1]);
        dumptree(p->kids[0]);
        dumptree(p->kids[1]);
        print("%s\n", opname(p->op));
        return;
    case EQ:
    case NE:
    case GT:
    case GE:
    case LE:
    case LT:
        assert(p->kids[0]);
        assert(p->kids[1]);
        assert(p->syms[0]);
        assert(p->syms[0]->x.name);
        dumptree(p->kids[0]);
        dumptree(p->kids[1]);
        print("%s %s\n", opname(p->op), p->syms[0]->x.name);
        return;
    }
    assert(0);
}
Exemplo n.º 3
0
static Tree root1(Tree p) {
	if (p == NULL)
		return p;
	if (p->type == voidtype)
		warn++;
	switch (generic(p->op)) {
	case COND: {
		Tree q = p->kids[1];
		assert(q && q->op == RIGHT);
		if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN)
			q->kids[0] = root1(q->kids[0]->kids[1]);
		else
			q->kids[0] = root1(q->kids[0]);
		if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN)
			q->kids[1] = root1(q->kids[1]->kids[1]);
		else
			q->kids[1] = root1(q->kids[1]);
		p->u.sym = 0;
		if (q->kids[0] == 0 && q->kids[1] == 0)
			p = root1(p->kids[0]);
		}
		break;
	case AND: case OR:
		if ((p->kids[1] = root1(p->kids[1])) == 0)
			p = root1(p->kids[0]);
		break;
	case NOT:
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case RIGHT:
		if (p->kids[1] == 0)
			return root1(p->kids[0]);
		if (p->kids[0] && p->kids[0]->op == CALL+B
		&&  p->kids[1] && p->kids[1]->op == INDIR+B)
			/* avoid premature release of the CALL+B temporary */
			return p->kids[0];
		if (p->kids[0] && p->kids[0]->op == RIGHT
		&&  p->kids[1] == p->kids[0]->kids[0])
			/* de-construct e++ construction */
			return p->kids[0]->kids[1];
		p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1]));
		return p->kids[0] || p->kids[1] ? p : (Tree)0;
	case EQ:  case NE:  case GT:   case GE:  case LE:  case LT:
	case ADD: case SUB: case MUL:  case DIV: case MOD:
	case LSH: case RSH: case BAND: case BOR: case BXOR:
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1]));
		return p->kids[0] || p->kids[1] ? p : (Tree)0;
	case INDIR:
		if (p->type->size == 0 && unqual(p->type) != voidtype)
			warning("reference to `%t' elided\n", p->type);
		if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
			warning("reference to `volatile %t' elided\n", p->type);
		/* fall thru */
	case NEG: case BCOM: case FIELD:
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case ADDRL: case ADDRG: case ADDRF: case CNST:
		if (needconst)
			return p;
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		return NULL;
	case CVF:
		if (optype(p->op) == I
		|| p->type->size < p->kids[0]->type->size)
			if (warn++ == 0)
				warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case CVI:
		if ((optype(p->op) == U || optype(p->op) == I)
		&& p->type->size < p->kids[0]->type->size
		&& specific(p->kids[0]->op) != CALL+I)
			if (warn++ == 0)
				warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case CVU: case CVP:
		if ((optype(p->op) == U && p->type->size <  p->kids[0]->type->size)
		||  (optype(p->op) == I && p->type->size <= p->kids[0]->type->size))
			if (warn++ == 0)
				warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case ARG: case ASGN: case CALL: case JUMP: case LABEL:
		break;
	default: assert(0);
	}
	return p;
}