Пример #1
0
//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);
}
Пример #2
0
//Duplicate and add an operand that indicated by opnd_pos at phi stmt
//in one of bb's successors.
void IRBB::dupSuccessorPhiOpnd(CFG<IRBB, IR> * cfg, Region * ru, UINT opnd_pos)
{
    IR_CFG * ircfg = (IR_CFG*)cfg;
    Vertex * vex = ircfg->get_vertex(BB_id(this));
    ASSERT0(vex);
    for (EdgeC * out = VERTEX_out_list(vex);
            out != NULL; out = EC_next(out)) {
        Vertex * succ_vex = EDGE_to(EC_edge(out));
        IRBB * succ = ircfg->get_bb(VERTEX_id(succ_vex));
        ASSERT0(succ);

        for (IR * ir = BB_first_ir(succ);
                ir != NULL; ir = BB_next_ir(succ)) {
            if (!ir->is_phi()) {
                break;
            }

            ASSERT0(cnt_list(PHI_opnd_list(ir)) >= opnd_pos);

            IR * opnd;
            UINT lpos = opnd_pos;
            for (opnd = PHI_opnd_list(ir);
                    lpos != 0; opnd = opnd->get_next()) {
                ASSERT0(opnd);
                lpos--;
            }

            IR * newopnd = ru->dupIRTree(opnd);
            if (opnd->is_read_pr()) {
                newopnd->copyRef(opnd, ru);
                ASSERT0(PR_ssainfo(opnd));
                PR_ssainfo(newopnd) = PR_ssainfo(opnd);
                SSA_uses(PR_ssainfo(newopnd)).append(newopnd);
            }

            ((CPhi*)ir)->addOpnd(newopnd);
        }
    }
}