示例#1
0
文件: ir_cp.cpp 项目: stevenknown/xoc
//Check and replace 'exp' with 'cand_expr' if they are
//equal, and update SSA info. If 'cand_expr' is NOT leaf,
//that will create redundant computation, and
//depends on later Redundancy Elimination to reverse back.
//
//'cand_expr': substitute cand_expr for exp.
//    e.g: exp is pr1 of S2, cand_expr is 10.
//        pr1 = 10 //S1
//        g = pr1 //S2
//    =>
//        pr1 = 10
//        g = 10
//
//NOTE: Do NOT handle stmt.
void IR_CP::replaceExpViaSSADu(IR * exp, IR const* cand_expr,
                                    IN OUT CPCtx & ctx)
{
    ASSERT0(exp && exp->is_exp() && cand_expr && cand_expr->is_exp());
    ASSERT0(exp->get_exact_ref());

    if (!checkTypeConsistency(exp, cand_expr)) {
        return;
    }

    IR * parent = IR_parent(exp);
    if (parent->is_ild()) {
        CPC_need_recomp_aa(ctx) = true;
    } else if (parent->is_ist() && exp == IST_base(parent)) {
        if (!cand_expr->is_ld() &&
            !cand_expr->is_pr() &&
            !cand_expr->is_lda()) {
            return;
        }
        CPC_need_recomp_aa(ctx) = true;
    }

    IR * newir = m_ru->dupIRTree(cand_expr);

    if (cand_expr->is_read_pr() && PR_ssainfo(cand_expr) != NULL) {
        PR_ssainfo(newir) = PR_ssainfo(cand_expr);
        SSA_uses(PR_ssainfo(newir)).append(newir);
    } else {
        m_du->copyIRTreeDU(newir, cand_expr, true);
    }

    //cand_expr may be IR tree. And there might be PR or LD on the tree.
    newir->copyRefForTree(cand_expr, m_ru);

    //Add SSA use for new exp.
    SSAInfo * cand_ssainfo = NULL;
    if ((cand_ssainfo = cand_expr->get_ssainfo()) != NULL) {
        SSA_uses(cand_ssainfo).append(newir);
    }

    //Remove old exp SSA use.
    SSAInfo * exp_ssainfo = exp->get_ssainfo();
    ASSERT0(exp_ssainfo);
    ASSERT0(SSA_uses(exp_ssainfo).find(exp));
    SSA_uses(exp_ssainfo).remove(exp);

    CPC_change(ctx) = true;

    ASSERT0(exp->get_stmt());
    bool doit = parent->replaceKid(exp, newir, false);
    ASSERT0(doit);
    UNUSED(doit);
    m_ru->freeIRTree(exp);
}