//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); }
//Check and replace 'ir' with 'cand_expr' if they are //equal, and update DU info. If 'cand_expr' is NOT leaf, //that will create redundant computation, and //depends on later Redundancy Elimination to reverse back. //exp: expression which will be replaced. // //cand_expr: substitute cand_expr for exp. // e.g: cand_expr is *p, cand_expr_md is MD3 // *p(MD3) = 10 //p point to MD3 // ... // g = *q(MD3) //q point to MD3 // //exp_use_ssadu: true if exp used SSA du info. // //NOTE: Do NOT handle stmt. void IR_CP::replaceExp(IR * exp, IR const* cand_expr, IN OUT CPCtx & ctx, bool exp_use_ssadu) { ASSERT0(exp && exp->is_exp() && cand_expr); 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); m_du->copyIRTreeDU(newir, cand_expr, true); ASSERT0(cand_expr->get_stmt()); if (exp_use_ssadu) { //Remove exp SSA use. ASSERT0(exp->get_ssainfo()); ASSERT0(exp->get_ssainfo()->get_uses().find(exp)); exp->removeSSAUse(); } else { m_du->removeUseOutFromDefset(exp); } CPC_change(ctx) = true; ASSERT0(exp->get_stmt()); bool doit = parent->replaceKid(exp, newir, false); ASSERT0(doit); UNUSED(doit); m_ru->freeIRTree(exp); }