Example #1
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;
}
Example #2
0
//The followed forms
// x is signed
//     IF(x > 0x7FFFFFFF) {a=1} ELSE {b=1}   =>  b=1
//     IF(x < 0x80000000) {a=1} ELSE {b=1}   =>  b=1
//
// x is unsigned
//     IF(x > 0xFFFFFFFF){a=1} ELSE {b=1}   =>  b=1
//     IF(x < 0x0) {a=1} ELSE {b=1}         =>  b=1
bool IR_CFS_OPT::transformIf3(IR ** head, IR * ir)
{
    ASSERT(head && *head, ("invalid parameter"));
    if (ir == NULL || !ir->is_if()) { return false; }

    IR * det = IF_det(ir);
    if (det->is_gt()) {
        IR * opnd0 = BIN_opnd0(det);
        IR * opnd1 = BIN_opnd1(det);
        if (opnd0->is_ld() &&
            opnd0->is_int() &&
            opnd1->is_const() &&
            opnd1->is_int() &&
            m_ru->getIntegerInDataTypeValueRange(opnd1) ==
              m_ru->getMaxInteger(m_tm->get_dtype_bitsize(
                TY_dtype(opnd1->get_type())), opnd1->is_signed())) {
            //e.g:
            //x is unsigned, if(x>0xFFFFFFFF) {a=1} else {b=1} => b=1
            //x is signed, if(x>0x7FFFFFFF) {a=1} else {b=1} =>  b=1
            IR * allocIR = NULL;
            if (IF_falsebody(ir) != NULL) {
                allocIR = m_ru->dupIRTree(IF_falsebody(ir));
            }

            xcom::replace(head, ir, allocIR);

            if (allocIR != NULL) {
                IR_parent(allocIR) = IR_parent(ir);
            }

            m_ru->freeIRTree(ir);
            return true;
        }
    } else if (det->is_lt()) {
        IR * opnd0 = BIN_opnd0(det);
        IR * opnd1 = BIN_opnd1(det);
        if (opnd0->is_ld() &&
            opnd0->is_int() &&
            opnd1->is_const() &&
            opnd1->is_int() &&
            m_ru->getIntegerInDataTypeValueRange(opnd1) ==
              m_ru->getMinInteger(m_tm->get_dtype_bitsize(
                TY_dtype(opnd1->get_type())), opnd1->is_signed())) {
            //x is signed, IF(x < 0x80000000) {a=1} ELSE {b=1}  =>  b=1
            IR * allocIR = NULL;
            if (IF_falsebody(ir) != NULL) {
                allocIR = m_ru->dupIRTree(IF_falsebody(ir));
            }

            xcom::replace(head, ir, allocIR);

            if (allocIR != NULL) {
                IR_parent(allocIR) = IR_parent(ir);
            }

            m_ru->freeIRTree(ir);
            return true;
        } else if (opnd0->is_ld() &&
                   opnd1->is_const() &&
                   opnd0->is_uint() &&
                   CONST_int_val(opnd1) == 0) {
            //x is unsigned, if(x<0) {a=1} else {b=1}  =>  b=1
            IR * allocIR = NULL;
            if (IF_falsebody(ir) != NULL) {
                allocIR = m_ru->dupIRTree(IF_falsebody(ir));
            }

            xcom::replace(head, ir, allocIR);

            if (allocIR != NULL) {
                IR_parent(allocIR) = IR_parent(ir);
            }

            m_ru->freeIRTree(ir);
            return true;
        }
    }

    return false;
}
Example #3
0
/* The followed forms
	x is signed
		IF(x > 0x7FFFFFFF) {a=1} ELSE {b=1}   =>  b=1
		IF(x < 0x80000000) {a=1} ELSE {b=1}   =>  b=1

	x is unsigned
		IF(x > 0xFFFFFFFF){a=1} ELSE {b=1}   =>  b=1
		IF(x < 0x0) {a=1} ELSE {b=1}         =>  b=1 */
bool IR_CFS_OPT::trans_if3(IR ** head, IR * ir)
{
	IS_TRUE(head && *head, ("invalid parameter"));
	if (ir == NULL || IR_type(ir) != IR_IF) { return false; }

	IR * det = IF_det(ir);
	if (IR_type(det) == IR_GT) {
		IR * opnd0 = BIN_opnd0(det);
		IR * opnd1 = BIN_opnd1(det);
		DTD const* op0_rty = opnd0->get_dtd(m_dm);
		DTD const* op1_rty = opnd1->get_dtd(m_dm);

		if (IR_type(opnd0) == IR_LD &&
			opnd1->is_const() &&
			opnd0->is_int(m_dm) &&
			CONST_int_val(opnd1) == MAX_INT_VALUE) {
			//x is signed, if(x>0x7FFFFFFF) {a=1} else {b=1} =>  b=1
			IR * new_ir = NULL;
			if (IF_falsebody(ir)) {
				new_ir = m_ru->dup_irs(IF_falsebody(ir));
			}
			replace(head, ir, new_ir);

			//Revise IR_parent.
			IR_parent(new_ir) = IR_parent(ir);

			m_ru->free_irs(ir);
			return true;
		} else if (IR_type(opnd0) == IR_LD &&
				   IR_is_const(opnd1) &&
				   opnd0->is_uint(m_dm) &&
				   CONST_int_val(opnd1) == MAX_UINT_VALUE) {
			//x is unsigned, if(x>0xFFFFFFFF) {a=1} else {b=1} => b=1
			IR * new_ir = NULL;
			if (IF_falsebody(ir)) {
				new_ir = m_ru->dup_irs(IF_falsebody(ir));
			}

			replace(head, ir, new_ir);

			//Revise IR_parent.
			IR_parent(new_ir) = IR_parent(ir);

			m_ru->free_irs(ir);
			return true;
		}
	} else if (IR_type(det) == IR_LT) {
		IR * opnd0 = BIN_opnd0(det);
		IR * opnd1 = BIN_opnd1(det);
		DTD const* op0_rty = opnd0->get_dtd(m_dm);
		DTD const* op1_rty = opnd1->get_dtd(m_dm);
		if (IR_type(opnd0) == IR_LD &&
			IR_is_const(opnd1) &&
			opnd0->is_int(m_dm) &&
			CONST_int_val(opnd1) == MIN_INT_VALUE) {
			//x is signed, IF(x < 0x80000000) {a=1} ELSE {b=1}  =>  b=1
			IR * new_ir = NULL;
			if (IF_falsebody(ir)) {
				new_ir = m_ru->dup_irs(IF_falsebody(ir));
			}
			replace(head, ir, new_ir);
			m_ru->free_irs(ir);
			return true;
		} else if (IR_type(opnd0) == IR_LD &&
					IR_is_const(opnd1) &&
					opnd0->is_uint(m_dm) &&
					CONST_int_val(opnd1) == 0) {
			//x is unsigned, if(x<0) {a=1} else {b=1}  =>  b=1
			IR * new_ir = NULL;
			if (IF_falsebody(ir)) {
				new_ir = m_ru->dup_irs(IF_falsebody(ir));
			}
			replace(head, ir, new_ir);

			//Revise IR_parent.
			IR_parent(new_ir) = IR_parent(ir);

			m_ru->free_irs(ir);
			return true;
		}
	}

	return false;
}