void IR_GVN::process_bb(IR_BB * bb, bool & change) { C<IR*> * ct; for (IR * ir = IR_BB_ir_list(bb).get_head(&ct); ir != NULL; ir = IR_BB_ir_list(bb).get_next(&ct)) { switch (IR_type(ir)) { case IR_ST: case IR_STPR: case IR_IST: process_st(ir, change); break; case IR_CALL: case IR_ICALL: process_call(ir, change); break; case IR_TRUEBR: case IR_FALSEBR: comp_vn(BR_det(ir), change); break; case IR_SWITCH: comp_vn(SWITCH_vexp(ir), change); break; case IR_IGOTO: comp_vn(IGOTO_vexp(ir), change); break; case IR_RETURN: comp_vn(RET_exp(ir), change); break; case IR_REGION: process_region(ir, change); break; case IR_PHI: process_phi(ir, change); break; case IR_GOTO: break; default: IS_TRUE0(0); } } }
/* Encode expression for single BB. Scan IR statement literally, and encoding it for generating the unique id for each individual expressions, and update the 'GEN-SET' and 'KILL-SET' of IR-EXPR for BB as well as. */ void IR_EXPR_TAB::encode_bb(IRBB * bb) { C<IR*> * ct; for (IR * ir = BB_irlist(bb).get_head(&ct); ir != NULL; ir = BB_irlist(bb).get_next(&ct)) { ASSERT0(ir->is_stmt()); switch (IR_code(ir)) { case IR_ST: { ExpRep * ie = encode_expr(ST_rhs(ir)); if (ie != NULL) { set_map_ir2ir_expr(ST_rhs(ir), ie); } } break; case IR_STPR: { ExpRep * ie = encode_expr(STPR_rhs(ir)); if (ie != NULL) { set_map_ir2ir_expr(STPR_rhs(ir), ie); } } break; case IR_STARRAY: { ExpRep * ie = encode_expr(ARR_base(ir)); if (ie != NULL) { set_map_ir2ir_expr(ARR_base(ir), ie); } for (IR * sub = ARR_sub_list(ir); sub != NULL; sub = IR_next(sub)) { ExpRep * ie = encode_expr(sub); if (ie != NULL) { set_map_ir2ir_expr(sub, ie); } } ie = encode_expr(STARR_rhs(ir)); if (ie != NULL) { set_map_ir2ir_expr(STARR_rhs(ir), ie); } } break; case IR_IST: { ExpRep * ie = encode_expr(IST_rhs(ir)); if (ie != NULL) { set_map_ir2ir_expr(IST_rhs(ir), ie); } ie = encode_istore_memaddr(IST_base(ir)); if (ie != NULL) { set_map_ir2ir_expr(IST_base(ir), ie); } } break; case IR_ICALL: //indirective call { ExpRep * ie = encode_expr(ICALL_callee(ir)); if (ie != NULL) { set_map_ir2ir_expr(ICALL_callee(ir), ie); } } case IR_CALL: { IR * parm = CALL_param_list(ir); while (parm != NULL) { ExpRep * ie = encode_expr(parm); if (ie != NULL) { set_map_ir2ir_expr(parm, ie); } parm = IR_next(parm); } } break; case IR_GOTO: break; case IR_IGOTO: { ExpRep * ie = encode_expr(IGOTO_vexp(ir)); if (ie != NULL) { set_map_ir2ir_expr(IGOTO_vexp(ir), ie); } } break; case IR_DO_WHILE: case IR_WHILE_DO: case IR_DO_LOOP: //loop with init , boundary , and step info case IR_IF: ASSERT(0, ("High level IR should be simplified")); break; case IR_LABEL: break; case IR_CASE: case IR_REGION: break; case IR_TRUEBR: case IR_FALSEBR: { ExpRep * ie = encode_expr(BR_det(ir)); if (ie != NULL) { set_map_ir2ir_expr(BR_det(ir), ie); } } break; case IR_SWITCH: { ExpRep * ie = encode_expr(SWITCH_vexp(ir)); if (ie != NULL) { set_map_ir2ir_expr(SWITCH_vexp(ir), ie); } } break; case IR_RETURN: { ExpRep * ie = encode_expr(RET_exp(ir)); if (ie != NULL) { set_map_ir2ir_expr(RET_exp(ir), ie); } } break; case IR_PHI: break; default: ASSERT0(0); } //end switch } //end for IR //dump_ir_expr_tab(); }
//Remove all expr for given stmt out of occ list in expr-tab. void IR_EXPR_TAB::remove_occs(IR * ir) { ASSERT0(ir->is_stmt()); switch (IR_code(ir)) { case IR_ST: { IR * stv = ST_rhs(ir); if (stv->is_const()) { return; } this->remove_occ(stv); } break; case IR_IST: { IR * stv = IST_rhs(ir); if (!stv->is_const()) { this->remove_occ(stv); } IR * m = IST_base(ir); if (m->is_const()) { return; } this->remove_occ(m); } break; case IR_CALL: case IR_ICALL: { IR * p = CALL_param_list(ir); while (p != NULL) { if (!p->is_const()) { this->remove_occ(p); } p = IR_next(p); } } break; case IR_TRUEBR: case IR_FALSEBR: this->remove_occ(BR_det(ir)); break; case IR_SWITCH: ASSERT0(SWITCH_vexp(ir)); if (!SWITCH_vexp(ir)->is_const()) { this->remove_occ(SWITCH_vexp(ir)); } break; case IR_IGOTO: ASSERT0(IGOTO_vexp(ir)); if (!IGOTO_vexp(ir)->is_const()) { this->remove_occ(IGOTO_vexp(ir)); } break; case IR_RETURN: if (RET_exp(ir) != NULL) { if (!RET_exp(ir)->is_const()) { this->remove_occ(RET_exp(ir)); } } break; case IR_GOTO: case IR_DO_WHILE: case IR_WHILE_DO: case IR_DO_LOOP: case IR_IF: case IR_LABEL: case IR_CASE: case IR_BREAK: case IR_CONTINUE: case IR_PHI: break; default: ASSERT0(0); } }
void IR_GVN::dump_bb(UINT bbid) { if (g_tfile == NULL) { return; } IR_BB * bb = m_ru->get_bb(bbid); IS_TRUE0(bb); CIR_ITER ii; fprintf(g_tfile, "\n-- BB%d ", IR_BB_id(bb)); dump_bb_labs(IR_BB_lab_list(bb)); fprintf(g_tfile, "\n"); for (IR * ir = IR_BB_first_ir(bb); ir != NULL; ir = IR_BB_next_ir(bb)) { dump_ir(ir, m_ru->get_dm()); fprintf(g_tfile, "\n"); VN * x = m_ir2vn.get(IR_id(ir)); if (x != NULL) { fprintf(g_tfile, "vn%d", VN_id(x)); } fprintf(g_tfile, " <- {"); switch (IR_type(ir)) { case IR_ST: ii.clean(); for (IR const* k = ir_iter_init_c(ST_rhs(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } break; case IR_STPR: ii.clean(); for (IR const* k = ir_iter_init_c(STPR_rhs(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } break; case IR_IST: ii.clean(); for (IR const* k = ir_iter_init_c(IST_rhs(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } ii.clean(); for (IR const* k = ir_iter_init_c(IST_base(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } break; case IR_CALL: case IR_ICALL: { ii.clean(); for (IR const* k = ir_iter_init_c(CALL_param_list(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } } break; case IR_TRUEBR: case IR_FALSEBR: ii.clean(); for (IR const* k = ir_iter_init_c(BR_det(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } break; case IR_SWITCH: ii.clean(); for (IR const* k = ir_iter_init_c(SWITCH_vexp(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } break; case IR_IGOTO: ii.clean(); for (IR const* k = ir_iter_init_c(IGOTO_vexp(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } break; case IR_RETURN: ii.clean(); for (IR const* k = ir_iter_init_c(RET_exp(ir), ii); k != NULL; k = ir_iter_next_c(ii)) { VN * x = m_ir2vn.get(IR_id(k)); dump_h1(k, x); } break; case IR_GOTO: break; case IR_REGION: IS_TRUE0(0); //TODO break; default: IS_TRUE0(0); } fprintf(g_tfile, " }"); } fflush(g_tfile); }
void PRDF::computeLocal(IRBB * bb, List<IR const*> & lst) { DefSBitSetCore * gen = get_def(BB_id(bb)); DefSBitSetCore * use = get_use(BB_id(bb)); gen->clean(m_sbs_mgr); use->clean(m_sbs_mgr); for (IR * x = BB_last_ir(bb); x != NULL; x = BB_prev_ir(bb)) { ASSERT0(x->is_stmt()); switch (IR_code(x)) { case IR_ST: lst.clean(); processOpnd(ST_rhs(x), lst, use, gen); break; case IR_STPR: gen->bunion(STPR_no(x), m_sbs_mgr); use->diff(STPR_no(x), m_sbs_mgr); processMay(x, gen, use, true); lst.clean(); processOpnd(STPR_rhs(x), lst, use, gen); break; case IR_SETELEM: gen->bunion(SETELEM_prno(x), m_sbs_mgr); use->diff(SETELEM_prno(x), m_sbs_mgr); processMay(x, gen, use, true); lst.clean(); processOpnd(SETELEM_rhs(x), lst, use, gen); lst.clean(); processOpnd(SETELEM_ofst(x), lst, use, gen); break; case IR_GETELEM: gen->bunion(GETELEM_prno(x), m_sbs_mgr); use->diff(GETELEM_prno(x), m_sbs_mgr); processMay(x, gen, use, true); lst.clean(); processOpnd(GETELEM_base(x), lst, use, gen); lst.clean(); processOpnd(GETELEM_ofst(x), lst, use, gen); break; case IR_STARRAY: lst.clean(); processOpnd(x, lst, use, gen); break; case IR_IST: lst.clean(); processOpnd(x, lst, use, gen); break; case IR_SWITCH: lst.clean(); processOpnd(SWITCH_vexp(x), lst, use, gen); break; case IR_IGOTO: lst.clean(); processOpnd(IGOTO_vexp(x), lst, use, gen); break; case IR_GOTO: break; case IR_CALL: case IR_ICALL: if (x->hasReturnValue()) { gen->bunion(CALL_prno(x), m_sbs_mgr); use->diff(CALL_prno(x), m_sbs_mgr); processMay(x, gen, use, true); } lst.clean(); processOpnd(CALL_param_list(x), lst, use, gen); if (x->is_icall() && ICALL_callee(x)->is_pr()) { use->bunion(PR_no(ICALL_callee(x)), m_sbs_mgr); processMay(ICALL_callee(x), gen, use, false); } break; case IR_TRUEBR: case IR_FALSEBR: lst.clean(); processOpnd(BR_det(x), lst, use, gen); break; case IR_RETURN: lst.clean(); processOpnd(RET_exp(x), lst, use, gen); break; case IR_PHI: gen->bunion(PHI_prno(x), m_sbs_mgr); use->diff(PHI_prno(x), m_sbs_mgr); processMay(x, gen, use, true); lst.clean(); processOpnd(PHI_opnd_list(x), lst, use, gen); break; case IR_REGION: break; default: ASSERT0(0); } } }