Exemple #1
0
//Canonicalize det of IF.
//e.g: if (a=10,b+=3,c<a) {...}
//be replaced by
//     a = 10;
//     b += 3;
//     if (c<a) {...}
bool IR_CFS_OPT::hoistIf(IR ** head, IR * ir)
{
    ASSERT(ir->is_if(), ("need IF"));
    ASSERT(IF_det(ir), ("DET is NULL"));

    IR * det = IF_det(ir);
    INT i = 0;
    while (det != NULL) {
        i++;
        det = det->get_next();
    }

    IR * new_list = NULL;
    if (i > 1) {
        det = IF_det(ir);
        while (i > 1) {
            IR * c = det;
            ASSERT(c->is_stmt(),
                ("Non-stmt ir should be remove during reshape_ir_tree()"));
            det = det->get_next();
            xcom::remove(&IF_det(ir), c);
            xcom::add_next(&new_list, c);
            i--;
        }
        xcom::insertbefore(head, ir, new_list);
        return true;
    }
    return false;
}
Exemple #2
0
/* Canonicalize det of IF.
e.g: if (a=10,b+=3,c<a) {...}
be replaced by
	 a = 10;
	 b += 3;
	 if (c<a) {...} */
bool IR_CFS_OPT::hoist_if(IR ** head, IR * ir)
{
	IS_TRUE(IR_type(ir) == IR_IF, ("need IF"));
	IS_TRUE(IF_det(ir), ("DET is NULL"));

	IR * det = IF_det(ir);
	INT i = 0;
	while (det != NULL) {
		i++;
		det = IR_next(det);
	}

	IR * new_list = NULL;
	if (i > 1) {
		det = IF_det(ir);
		while (i > 1) {
			IR * c = det;
			IS_TRUE(c->is_stmt(),
				("Non-stmt ir should be remove during reshape_ir_tree()"));
			det = IR_next(det);
			remove(&IF_det(ir), c);
			add_next(&new_list, c);
			i--;
		}
		insertbefore(head, ir, new_list);
		return true;
	}
	return false;
}
Exemple #3
0
//The followed forms
//   if (cond) {
//
//   } else {
//       IR-list
//   }
//
//is replaced by
//
//   if (!cond) {
//       IR-list
//   }
bool IR_CFS_OPT::transformIf2(IR ** head, IR * ir)
{
    ASSERT(head && *head, ("invalid parameter"));
    if (ir == NULL || !ir->is_if()) { return false; }

    //Check true part
    if (IF_truebody(ir) == NULL) {
        if (IF_falsebody(ir) == NULL) {
            xcom::remove(head, ir);
            m_ru->freeIRTree(ir);
            return true;
        }
        m_ru->invertCondition(&IF_det(ir));
        IF_truebody(ir) = IF_falsebody(ir);
        IF_falsebody(ir) = NULL;
        return true;
    }

    return false;
}
Exemple #4
0
/* The followed forms

	if (cond) {

	} else {
		IR-list
	}

is replaced by

	if (!cond) {
		IR-list
	} */
bool IR_CFS_OPT::trans_if2(IR ** head, IR * ir)
{
	IS_TRUE(head && *head, ("invalid parameter"));
	if (ir == NULL || IR_type(ir) != IR_IF) { return false; }

	//Check true part
	if (!IF_truebody(ir)) {
		if (IF_falsebody(ir) == NULL) {
			remove(head, ir);
			m_ru->free_irs(ir);
			return true;
		}
		m_ru->invert_cond(&IF_det(ir));
		IF_truebody(ir) = IF_falsebody(ir);
		IF_falsebody(ir) = NULL;
		return true;
	}

	return false;
}
Exemple #5
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;
}
Exemple #6
0
//The followed forms
//   if (cond) {
//       t=1
//       a=1
//       goto L1;
//   }
//   f=1
//   goto L2;
//   L1:
//
//is replaced with
//
//   if (!cond) {
//       f=1
//       goto L2;
//   }
//   t=1
//   a=1
//   L1:
//
//'goto L1' is removed and free, and L1 is removed if it is not a target
//of some other instruction.
bool IR_CFS_OPT::transformIf1(IR ** head, IR * ir)
{
    ASSERT(head && *head, ("invalid parameter"));

    if (ir == NULL || !ir->is_if()) { return false; }

    //Check true part.
    IR * t = IF_truebody(ir);
    while (t != NULL) {
        if (!is_non_branch_ir(t)) {
            break;
        }
        t = t->get_next();
    }

    if (t != NULL && t->get_next() == NULL && t->is_goto()) {
        IR * first_goto = t;
        t = ir->get_next();
        while (t != NULL) {
            if (!is_non_branch_ir(t)) { break; }
            t = t->get_next();
        }

        if (t != NULL && t->is_goto()) {
            IR * second_goto = t;
            if (IR_next(second_goto) != NULL &&
                IR_next(second_goto)->is_lab() &&
                isSameLabel(GOTO_lab(first_goto),
                            LAB_lab(IR_next(second_goto)))) {

                //Start transforming.
                m_ru->invertCondition(&IF_det(ir));
                IR * new_list1 = NULL;
                IR * new_list2 = NULL;

                t = IF_truebody(ir);

                //Split true body of IF.
                IR * last = NULL;
                while (t != first_goto) {
                    IR * c = t;
                    t = t->get_next();
                    xcom::remove(&IF_truebody(ir), c);
                    xcom::add_next(&new_list1, &last, c);
                }
                ASSERT(t && t == first_goto, ("invalid control flow"));

                xcom::remove(&IF_truebody(ir), first_goto);
                m_ru->freeIRTree(first_goto);

                //Split all irs between IF and L1.
                t = ir->get_next();
                while (t != second_goto) {
                    IR * c = t;
                    t = t->get_next();
                    xcom::remove(head, c);
                    xcom::add_next(&new_list2, c);
                }
                ASSERT(t != NULL && t == second_goto, ("???"));
                xcom::remove(head, second_goto);
                xcom::add_next(&new_list2, second_goto);

                //Swap new_list1 and new_list2
                xcom::insertbefore(&IF_truebody(ir), IF_truebody(ir), new_list2);

                //Update the IR_parent for new_list2.
                for (IR * tmp = new_list2; tmp != NULL; tmp = IR_next(tmp)) {
                    IR_parent(tmp) = ir;
                }

                ASSERT(IF_truebody(ir) == new_list2, ("illegal insertbefore<T>"));

                xcom::insertafter(&ir, new_list1);

                //Update the IR_parent for new_list1.
                for (IR * tmp = new_list1; tmp != NULL; tmp = IR_next(tmp)) {
                    IR_parent(tmp) = IR_parent(ir);
                }

                return true;
            }
        }
    }

    return false;
}
Exemple #7
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;
}
Exemple #8
0
/* The followed forms
	if (cond) {
		t=1
		a=1
		goto L1;
	}
	f=1
	goto L2;
	L1:

is replaced by

	if (!cond) {
		f=1
		goto L2;
	}
	t=1
	a=1
	L1:

'goto L1' is removed and free, and L1 is removed if it is not a target
of some other instruction. */
bool IR_CFS_OPT::trans_if1(IR ** head, IR * ir)
{
	IS_TRUE(head && *head, ("invalid parameter"));

	if (ir == NULL || IR_type(ir) != IR_IF) { return false; }

	//Check true part.
	IR * t = IF_truebody(ir);
	while (t != NULL) {
		if (!is_non_branch_ir(t)) {
			break;
		}
		t = IR_next(t);
	}

	if (t != NULL && IR_next(t) == NULL && IR_type(t) == IR_GOTO) {
		IR * first_goto = t;
		t = IR_next(ir);
		while (t != NULL) {
			if (!is_non_branch_ir(t)) break;
			t = IR_next(t);
		}

		if (t != NULL && IR_type(t) == IR_GOTO) {
			IR * second_goto = t;
			if (IR_next(second_goto) != NULL &&
				IR_next(second_goto)->is_lab() &&
				is_same_label(GOTO_lab(first_goto),
							  LAB_lab(IR_next(second_goto)))) {

				//Here we start to transform...
				m_ru->invert_cond(&IF_det(ir));
				IR * new_list1 = NULL;
				IR * new_list2 = NULL;

				t = IF_truebody(ir);

				//Split true body of IF.
				IR * last = NULL;
				while (t != first_goto) {
					IR * c = t;
					t = IR_next(t);
					remove(&IF_truebody(ir), c);
					add_next(&new_list1, &last, c);
				}
				IS_TRUE(t && t == first_goto, ("invalid control flow"));

				remove(&IF_truebody(ir), first_goto);
				m_ru->free_irs(first_goto);

				//Split all irs between IF and L1.
				t = IR_next(ir);
				while (t != second_goto) {
					IR * c = t;
					t = IR_next(t);
					remove(head, c);
					add_next(&new_list2, c);
				}
				IS_TRUE(t != NULL && t == second_goto, ("???"));
				remove(head, second_goto);
				add_next(&new_list2, second_goto);

				//Swap new_list1 and new_list2
				insertbefore(&IF_truebody(ir), IF_truebody(ir), new_list2);

				//Update the IR_parent for new_list2.
				for (IR * tmp = new_list2; tmp != NULL; tmp = IR_next(tmp)) {
					IR_parent(tmp) = ir;
				}

				IS_TRUE(IF_truebody(ir) == new_list2,
						("illegal insertbefore<T>"));

				insertafter(&ir, new_list1);

				//Update the IR_parent for new_list1.
				for (IR * tmp = new_list1; tmp != NULL; tmp = IR_next(tmp)) {
					IR_parent(tmp) = IR_parent(ir);
				}
				return true;
			}
		}
	}

	return false;
}