Пример #1
0
//CVT with simply cvt-exp is copy-propagate candidate.
bool IR_CP::is_simp_cvt(IR const* ir) const
{
    if (!ir->is_cvt()) return false;

    for (;;) {
        if (ir->is_cvt()) {
            ir = CVT_exp(ir);
        } else if (ir->is_ld() || ir->is_const() || ir->is_pr()) {
            return true;
        } else {
            break;
        }
    }
    return false;
}
Пример #2
0
VN * IR_GVN::comp_vn(IR const* exp, bool & change)
{
	IS_TRUE0(exp);
	switch (IR_type(exp)) {
	case IR_ADD:
	case IR_SUB:
	case IR_MUL:
	case IR_DIV:
	case IR_REM:
	case IR_MOD:
	case IR_LAND: //logical and &&
	case IR_LOR: //logical or ||
	case IR_BAND: //inclusive and &
	case IR_BOR: //inclusive or |
	case IR_XOR: //exclusive or
	case IR_LT:
	case IR_LE:
	case IR_GT:
	case IR_GE:
	case IR_EQ: //==
	case IR_NE: //!=
	case IR_ASR:
	case IR_LSR:
	case IR_LSL:
		{
			VN * vn1 = comp_vn(BIN_opnd0(exp), change);
			VN * vn2 = comp_vn(BIN_opnd1(exp), change);
			if (vn1 == NULL || vn2 == NULL) {
				if (m_ir2vn.get(IR_id(exp)) != NULL) {
					m_ir2vn.set(IR_id(exp), NULL);
					change = true;
				}
				return NULL;
			}
			VN * x = register_bin_vn((IR_TYPE)IR_type(exp), vn1, vn2);
			if (m_ir2vn.get(IR_id(exp)) != x) {
				m_ir2vn.set(IR_id(exp), x);
				change = true;
			}
			return x;
		}
		break;
	case IR_BNOT: //bitwise not
	case IR_LNOT: //logical not
	case IR_NEG: //negative
		{
			VN * x = comp_vn(UNA_opnd0(exp), change);
			if (x == NULL) {
				if (m_ir2vn.get(IR_id(exp)) != NULL) {
					m_ir2vn.set(IR_id(exp), NULL);
					change = true;
				}
				return NULL;
			}
			x = register_uni_vn((IR_TYPE)IR_type(exp), x);
			if (m_ir2vn.get(IR_id(exp)) != x) {
				m_ir2vn.set(IR_id(exp), x);
				change = true;
			}
			return x;
		}
		break;
	case IR_CVT: //type convertion
		{
			VN * x = comp_vn(CVT_exp(exp), change);
			if (x == NULL) {
				if (m_ir2vn.get(IR_id(exp)) != NULL) {
					m_ir2vn.set(IR_id(exp), NULL);
					change = true;
				}
				return NULL;
			}
			x = register_uni_vn((IR_TYPE)IR_type(exp), x);
			if (m_ir2vn.get(IR_id(exp)) != x) {
				m_ir2vn.set(IR_id(exp), x);
				change = true;
			}
			return x;
		}
		break;
	case IR_LDA:
		{
			IR const* ldabase = LDA_base(exp);
			VN * basevn;
			if (IR_type(ldabase) == IR_ID) {
				MD const* emd = ldabase->get_exact_ref();
				if (emd == NULL) {
					//e.g: p = &"blabla", regard MD of "blabla" as inexact.
					IS_TRUE(ldabase->is_str(m_dm),
							("only string's MD can be inexact."));
					if (m_is_comp_lda_string) {
						emd = m_du->get_effect_use_md(ldabase);
						IS_TRUE(emd, ("string should have effect MD"));
						basevn = register_md_vn(emd);
					} else {
						basevn = NULL;
					}
				} else {
					IS_TRUE0(emd);
					basevn = register_md_vn(emd);
				}
			} else {
				basevn = comp_vn(LDA_base(exp), change);
			}
			if (basevn == NULL) {
				if (m_ir2vn.get(IR_id(exp)) != NULL) {
					m_ir2vn.set(IR_id(exp), NULL);
					change = true;
				}
				return NULL;
			}
			VN * ofstvn = register_int_vn(LDA_ofst(exp));
			VN * x = register_bin_vn(IR_LDA, basevn, ofstvn);
			if (m_ir2vn.get(IR_id(exp)) != x) {
				m_ir2vn.set(IR_id(exp), x);
				change = true;
			}
			return x;
		}
		break;
	//case IR_ID:
	case IR_LD:
	case IR_PR:
		return comp_sc(exp, change);
	case IR_ARRAY:
		return comp_array(exp, change);
	case IR_ILD:
		return comp_ild(exp, change);
	case IR_CONST:
		{
			VN * x = m_ir2vn.get(IR_id(exp));
			if (x != NULL) { return x; }
			if (exp->is_int(m_dm)) {
				x = register_int_vn(CONST_int_val(exp));
			} else if (exp->is_fp(m_dm)) {
				if (!m_is_vn_fp) {
					return NULL;
				}
				x = register_fp_vn(CONST_fp_val(exp));
			} else if (exp->is_str(m_dm)) {
				x = register_str_vn(CONST_str_val(exp));
			} else {
				IS_TRUE(0, ("unsupport const type"));
			}
			IS_TRUE0(x);
			m_ir2vn.set(IR_id(exp), x);
			change = true;
			return x;
		}
		break;
	default: break;
	}
	return NULL;
}