//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; }
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; }