Example #1
0
//Check that all basic blocks should only end with terminator IR.
void IRBB::verify()
{
    UINT c = 0;
    C<IR*> * ct;
    for (IR * ir = BB_irlist(this).get_head(&ct);
         ir != NULL; ir = BB_irlist(this).get_next(&ct)) {
        ASSERT0(ir->is_single());
        ASSERT0(ir->get_bb() == this);
        switch (IR_code(ir)) {
        case IR_ST:
        case IR_STPR:
        case IR_STARRAY:
        case IR_IST:
        case IR_PHI:
        case IR_REGION:
        case IR_CALL:
        case IR_ICALL:
        case IR_GOTO:
        case IR_IGOTO:
        case IR_TRUEBR:
        case IR_FALSEBR:
        case IR_RETURN:
        case IR_SWITCH:
            break;
        default: ASSERT(0, ("BB does not supported this kind of IR."));
        }

        if (is_bb_down_boundary(ir)) {
            ASSERT(ir == BB_last_ir(this), ("invalid BB down boundary."));
        }

        c++;
    }
    ASSERT0(c == getNumOfIR());
}
Example #2
0
//Could ir be looked as a last stmt in basic block?
bool IRBB::is_bb_down_boundary(IR * ir)
{
    ASSERT(ir->isStmtInBB() || ir->is_lab(), ("illegal stmt in bb"));
    switch (IR_code(ir)) {
    case IR_CALL:
    case IR_ICALL: //indirective call
        return ((CCall*)ir)->isMustBBbound();
    case IR_GOTO:
    case IR_IGOTO:
        return true;
    case IR_SWITCH:
        ASSERT(SWITCH_body(ir) == NULL,
               ("Peel switch-body to enable switch in bb-list construction"));
        return true;
    case IR_TRUEBR:
    case IR_FALSEBR:
        return true;
    case IR_RETURN:
    case IR_REGION:
        return true;
    default:
        break;
    }
    return false;
}
Example #3
0
//Get the value expression that to be propagated.
inline static IR * get_propagated_value(IR * stmt)
{
    switch (IR_code(stmt)) {
    case IR_ST: return ST_rhs(stmt);
    case IR_STPR: return STPR_rhs(stmt);
    case IR_IST: return IST_rhs(stmt);
    case IR_PHI: return PHI_opnd_list(stmt);
    default:;
    }
    UNREACH();
    return NULL;
}
Example #4
0
ExpRep * IR_EXPR_TAB::encode_expr(IN IR * ir)
{
    if (ir == NULL) return NULL;

    ASSERT0(ir->is_exp());
    switch (IR_code(ir)) {
    case IR_ID:
    case IR_LD:
    case IR_LDA:
    case IR_CONST:
    case IR_PR:
        return NULL;
    case IR_ILD:
    case IR_ADD:
    case IR_SUB:
    case IR_MUL:
    case IR_DIV:
    case IR_REM:
    case IR_MOD:
    case IR_LAND: //logical and &&
    case IR_LOR: //logical or ||
    case IR_BAND: //bit and &
    case IR_BOR: //bit or |
    case IR_XOR:
    case IR_BNOT: //bitwise not
    case IR_LNOT: //logical not
    case IR_NEG:
    case IR_LT:
    case IR_LE:
    case IR_GT:
    case IR_GE:
    case IR_EQ:
    case IR_NE:
    case IR_ARRAY:
    case IR_ASR:
    case IR_LSR:
    case IR_LSL:
    case IR_CVT: //type convertion
    case IR_SELECT: //formulized determinate-expr?exp:exp
        {
            ExpRep * ie = append_expr(ir);
            ASSERT(!EXPR_occ_list(ie).find(ir),
                    ("process same IR repeated."));
            EXPR_occ_list(ie).append_tail(ir);
            return ie;
        }
    default: ASSERT0(0);
    }
    return NULL;
}
Example #5
0
UINT IR_EXPR_TAB::compute_hash_key(IR const* ir)
{
    ASSERT0(ir != NULL);
    UINT hval = IR_code(ir) + (ir->get_offset() + 1) + (UINT)(size_t)IR_dt(ir);
    if (ir->is_id()) {
        VAR * var = ID_info(ir);
        /*
        SYM * name = VAR_name(id_info);
        CHAR * s = SYM_name(name);
        UINT v = 0 ;
        while (*s != 0) {
            v += (UINT)(*s++);
        }
        hval += v;
        */
        hval += 5 * (UINT)(size_t)var;
    }
    return hval;
}
Example #6
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();
}
Example #7
0
//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);
    }
}
Example #8
0
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);
        }
    }
}