コード例 #1
0
ファイル: prdf.cpp プロジェクト: onecoolx/xoc
//
//START PRDF
//
void PRDF::dump()
{
    if (g_tfile == NULL) {
        return;
    }
    fprintf(g_tfile, "\n==---- DUMP PRDF : liveness of PR ----==\n");
    List<IRBB*> * bbl = m_ru->get_bb_list();
    g_indent = 2;
    for (IRBB * bb = bbl->get_head(); bb != NULL; bb = bbl->get_next()) {
        fprintf(g_tfile, "\n\n\n-- BB%d --", BB_id(bb));
        DefSBitSetCore * live_in = get_livein(BB_id(bb));
        DefSBitSetCore * live_out = get_liveout(BB_id(bb));
        DefSBitSetCore * def = get_def(BB_id(bb));
        DefSBitSetCore * use = get_use(BB_id(bb));

        fprintf(g_tfile, "\nLIVE-IN: ");
        live_in->dump(g_tfile);

        fprintf(g_tfile, "\nLIVE-OUT: ");
        live_out->dump(g_tfile);

        fprintf(g_tfile, "\nDEF: ");
        def->dump(g_tfile);

        fprintf(g_tfile, "\nUSE: ");
        use->dump(g_tfile);
    }
    fflush(g_tfile);
}
コード例 #2
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
AbsNode * CfsMgr::constructAbsLoop(
        IN IRBB * entry,
        IN AbsNode * parent,
        IN BitSet * cur_region,
        IN Graph & cur_graph,
        IN OUT BitSet & visited)
{
    DUMMYUSE(cur_region);
    ASSERT0(cur_region == NULL || cur_region->is_contain(BB_id(entry)));
    IR_CFG * cfg = m_ru->getCFG();
    LI<IRBB> * li = cfg->mapBB2LabelInfo(entry);
    ASSERT0(li != NULL && LI_loop_head(li) == entry);

    AbsNode * node = new_abs_node(ABS_LOOP);
    set_map_bb2abs(entry, node);
    ABS_NODE_parent(node) = parent;
    ABS_NODE_loop_head(node) = entry;
    IRBB * body_start;
    cfg->getKidOfLoop(entry, NULL, &body_start);
    ASSERT0(body_start != NULL);

    CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry));
    CHECK_DUMMYUSE(ci);
    ASSERT0(CFS_INFO_head(ci) == entry);

    ASSERT0(CFS_INFO_loop_body(ci)->is_contain(*LI_bb_set(li)));
    BitSet loc_visited;
    ABS_NODE_loop_body(node) = constructAbsTree(body_start, node,
        LI_bb_set(li), cur_graph, loc_visited);
    visited.bunion(loc_visited);
    visited.bunion(BB_id(entry));
    return node;
}
コード例 #3
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
void CfsMgr::dump_abs_tree(AbsNode * an, UINT indent)
{
    while (an != NULL) {
        switch (ABS_NODE_type(an)) {
        case ABS_BB:
            fprintf(g_tfile, "\n"); dump_indent(indent);
            fprintf(g_tfile, "BB%d", BB_id(ABS_NODE_bb(an)));
            break;
        case ABS_LOOP:
            fprintf(g_tfile, "\n"); dump_indent(indent);
            fprintf(g_tfile, "LOOP: HEAD=BB%d", BB_id(ABS_NODE_loop_head(an)));
            dump_abs_tree(ABS_NODE_loop_body(an), indent + 4);
            break;
        case ABS_IF:
            fprintf(g_tfile, "\n"); dump_indent(indent);
            fprintf(g_tfile, "IF: HEAD=BB%d", BB_id(ABS_NODE_if_head(an)));
            if (ABS_NODE_true_body(an) != NULL) {
                fprintf(g_tfile, "\n"); dump_indent(indent);
                fprintf(g_tfile, "TRUE_BODY:");
                dump_abs_tree(ABS_NODE_true_body(an), indent + 4);
            }
            if (ABS_NODE_false_body(an) != NULL) {
                fprintf(g_tfile, "\n"); dump_indent(indent);
                fprintf(g_tfile, "FALSE_BODY:");
                dump_abs_tree(ABS_NODE_false_body(an), indent + 4);
            }
            break;
        }
        an = ABS_NODE_next(an);
    }
}
コード例 #4
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
//'cur_region' covered 'entry'.
AbsNode * CfsMgr::constructAbsIf(
        IN IRBB * entry,
        IN AbsNode * parent,
        IN Graph & cur_graph,
        IN OUT BitSet & visited)
{
    AbsNode * node = new_abs_node(ABS_IF);
    set_map_bb2abs(entry, node);
    ABS_NODE_parent(node) = parent;
    ABS_NODE_if_head(node) = entry;

    IRBB * true_body, * false_body;
    IR_CFG * cfg = m_ru->getCFG();
    cfg->getKidOfIF(entry, &true_body, &false_body, NULL);
    CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry));
    ASSERT0(ci != NULL && CFS_INFO_head(ci) == entry);

    BitSet loc_visited;
    ABS_NODE_true_body(node) = constructAbsTree(true_body, node,
        CFS_INFO_true_body(ci), cur_graph, loc_visited);
    visited.bunion(loc_visited);
    loc_visited.clean();
    ABS_NODE_false_body(node) = constructAbsTree(false_body, node,
        CFS_INFO_false_body(ci), cur_graph, loc_visited);
    visited.bunion(loc_visited);
    visited.bunion(BB_id(entry));
    return node;
}
コード例 #5
0
ファイル: ir_bb.cpp プロジェクト: onecoolx/xoc
//Before removing bb, revising phi opnd if there are phis
//in one of bb's successors.
void IRBB::removeSuccessorPhiOpnd(CFG<IRBB, IR> * cfg)
{
    IR_CFG * ircfg = (IR_CFG*)cfg;
    Region * ru = ircfg->get_ru();
    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);

        UINT const pos = ircfg->WhichPred(this, 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)) ==
                     cnt_list(VERTEX_in_list(succ_vex)));

            IR * opnd;
            UINT lpos = pos;
            for (opnd = PHI_opnd_list(ir);
                 lpos != 0; opnd = IR_next(opnd)) {
                ASSERT0(opnd);
                lpos--;
            }

            opnd->removeSSAUse();
            ((CPhi*)ir)->removeOpnd(opnd);
            ru->freeIRTree(opnd);
        }
    }
}
コード例 #6
0
ファイル: ir_bb.cpp プロジェクト: alibaba/xoc
//Before removing bb or change bb successor,
//you need remove the related PHI operand if BB successor has PHI stmt.
void IRBB::removeSuccessorPhiOpnd(CFG<IRBB, IR> * cfg)
{
    Vertex * vex = cfg->get_vertex(BB_id(this));
    ASSERT0(vex);
    for (EdgeC * out = VERTEX_out_list(vex); out != NULL; out = EC_next(out)) {
        IRBB * succ = ((IR_CFG*)cfg)->get_bb(VERTEX_id(EDGE_to(EC_edge(out))));
        ASSERT0(succ);
        removeSuccessorDesignatePhiOpnd(cfg, succ);
    }
}
コード例 #7
0
ファイル: ir_cp.cpp プロジェクト: stevenknown/xoc
//Return true if 'occ' does not be modified till meeting 'use_ir'.
//e.g:
//    xx = occ  //def_ir
//    ..
//    ..
//    yy = xx  //use_ir
//
//'def_ir': ir stmt.
//'occ': opnd of 'def_ir'
//'use_ir': stmt in use-list of 'def_ir'.
bool IR_CP::is_available(IR const* def_ir, IR const* occ, IR * use_ir)
{
    if (def_ir == use_ir) {    return false; }
    if (occ->is_const()) { return true; }

    //Need check overlapped MDSet.
    //e.g: Suppose occ is '*p + *q', p->a, q->b.
    //occ can NOT reach 'def_ir' if one of p, q, a, b
    //modified during the path.

    IRBB * defbb = def_ir->get_bb();
    IRBB * usebb = use_ir->get_bb();
    if (defbb == usebb) {
        //Both def_ir and use_ir are in same BB.
        C<IR*> * ir_holder = NULL;
        bool f = BB_irlist(defbb).find(const_cast<IR*>(def_ir), &ir_holder);
        CK_USE(f);
        IR * ir;
        for (ir = BB_irlist(defbb).get_next(&ir_holder);
             ir != NULL && ir != use_ir;
             ir = BB_irlist(defbb).get_next(&ir_holder)) {
            if (m_du->is_may_def(ir, occ, true)) {
                return false;
            }
        }
        if (ir == NULL) {
            ;//use_ir appears prior to def_ir. Do more check via live_in_expr.
        } else {
            ASSERT(ir == use_ir, ("def_ir should be in same bb to use_ir"));
            return true;
        }
    }

    ASSERT0(use_ir->is_stmt());
    DefDBitSetCore const* availin_expr =
        m_du->getAvailInExpr(BB_id(usebb), NULL);
    ASSERT0(availin_expr);

    if (availin_expr->is_contain(IR_id(occ))) {
        IR * u;
        for (u = BB_first_ir(usebb); u != use_ir && u != NULL;
             u = BB_next_ir(usebb)) {
            //Check if 'u' override occ's value.
            if (m_du->is_may_def(u, occ, true)) {
                return false;
            }
        }
        ASSERT(u != NULL && u == use_ir,
                ("Not find use_ir in bb, may be it has "
                 "been removed by other optimization"));
        return true;
    }
    return false;
}
コード例 #8
0
ファイル: ir_cp.cpp プロジェクト: stevenknown/xoc
bool IR_CP::perform(OptCtx & oc)
{
    START_TIMER_AFTER();
    ASSERT0(OC_is_cfg_valid(oc));

    if (m_prop_kind == CP_PROP_CONST) {

        m_ru->checkValidAndRecompute(&oc, PASS_DOM, PASS_DU_REF,
            PASS_DU_CHAIN, PASS_UNDEF);
    } else {
        m_ru->checkValidAndRecompute(&oc, PASS_DOM, PASS_DU_REF,
            PASS_LIVE_EXPR, PASS_DU_CHAIN, PASS_UNDEF);
    }

    if (!OC_is_du_chain_valid(oc)) {
        END_TIMER_AFTER(get_pass_name());
        return false;
    }

    bool change = false;
    IRBB * entry = m_ru->get_cfg()->get_entry();
    ASSERT(entry, ("Not unique entry, invalid Region"));
    Graph domtree;
    m_cfg->get_dom_tree(domtree);
    List<Vertex*> lst;
    Vertex * root = domtree.get_vertex(BB_id(entry));
    m_cfg->sortDomTreeInPreorder(root, lst);
    Vector<IR*> usevec;

    for (Vertex * v = lst.get_head(); v != NULL; v = lst.get_next()) {
        IRBB * bb = m_cfg->get_bb(VERTEX_id(v));
        ASSERT0(bb);
        change |= doProp(bb, usevec);
    }

    if (change) {
        doFinalRefine();
        OC_is_expr_tab_valid(oc) = false;
        OC_is_aa_valid(oc) = false;
        OC_is_du_chain_valid(oc) = true; //already update.
        OC_is_ref_valid(oc) = true; //already update.
        ASSERT0(m_ru->verifyMDRef() && m_du->verifyMDDUChain());
        ASSERT0(verifySSAInfo(m_ru));
    }

    END_TIMER_AFTER(get_pass_name());
    return change;
}
コード例 #9
0
ファイル: ir_bb.cpp プロジェクト: alibaba/xoc
//Return true if one of bb's successor has a phi.
bool IRBB::successorHasPhi(CFG<IRBB, IR> * cfg)
{
    Vertex * vex = cfg->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 = cfg->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()) { return true; }
        }
    }
    return false;
}
コード例 #10
0
ファイル: ir_bb.cpp プロジェクト: onecoolx/xoc
void IRBB::dump(Region * ru)
{
    if (g_tfile == NULL) { return; }

    g_indent = 0;

    fprintf(g_tfile, "\n----- BB%d ------", BB_id(this));
    if (get_lab_list().get_elem_count() > 0) {
        fprintf(g_tfile, "\nLABEL:");
        dumpBBLabel(get_lab_list(), g_tfile);
    }

    //Attributes
    fprintf(g_tfile, "\nATTR:");
    if (BB_is_entry(this)) {
        fprintf(g_tfile, "entry_bb ");
    }

    //if (BB_is_exit(this)) {
    //    fprintf(g_tfile, "exit_bb ");
    //}

    if (BB_is_fallthrough(this)) {
        fprintf(g_tfile, "fall_through ");
    }

    if (BB_is_target(this)) {
        fprintf(g_tfile, "branch_target ");
    }

    //IR list
    fprintf(g_tfile, "\nSTMT NUM:%d", getNumOfIR());
    g_indent += 3;
    TypeMgr * dm = ru->get_type_mgr();
    for (IR * ir = BB_first_ir(this);
        ir != NULL; ir = BB_irlist(this).get_next()) {
        ASSERT0(IR_next(ir) == NULL && IR_prev(ir) == NULL);
        ASSERT0(ir->get_bb() == this);
        dump_ir(ir, dm, NULL, true, true, false);
    }
    g_indent -= 3;
    fprintf(g_tfile, "\n");
    fflush(g_tfile);
}
コード例 #11
0
ファイル: ir_bb.cpp プロジェクト: learneverydayma/xoc
//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);
        }
    }
}
コード例 #12
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
void CfsMgr::set_map_bb2abs(IRBB const* bb, AbsNode * abs)
{
    m_map_bb2abs.set(BB_id(bb), abs);
}
コード例 #13
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
AbsNode * CfsMgr::constructAbsTree(
        IN IRBB * entry,
        IN AbsNode * parent,
        IN BitSet * cur_region,
        IN Graph & cur_graph,
        IN OUT BitSet & visited)
{
    IR_CFG * cfg = m_ru->getCFG();
    AbsNode * lst = NULL;
    IRBB * bb = entry;
    Graph g;
    g.clone(cur_graph);
    Vertex * next = NULL;
    Vertex * v;
    if (cur_region != NULL) {
        if (cur_region->get_elem_count() == 0) {
            visited.clean();
            return NULL;
        }
        INT c;
        for (v = g.get_first_vertex(c); v != NULL; v = next) {
            next = g.get_next_vertex(c);
            if (cur_region->is_contain(VERTEX_id(v))) {
                continue;
            }
            g.removeVertex(v);
        }
    }
    BitSet loc_visited;
    while (bb != NULL &&
           (cur_region == NULL ||
            cur_region->is_contain(BB_id(bb)))) {
        AbsNode * node = NULL;
        loc_visited.clean();
        LI<IRBB> * li = cfg->mapBB2LabelInfo(bb);
        if (li != NULL) {
            node = constructAbsLoop(bb, parent, LI_bb_set(li),
                                    g, loc_visited);
        } else {
            IR * last_xr = cfg->get_last_xr(bb);
            if (last_xr != NULL && //'bb' is branching node of IF.
                last_xr->isConditionalBr()) {
                ASSERT0(map_ir2cfsinfo(last_xr) != NULL);

                //There might not exist ipdom.
                //e.g:
                //  if (x) //BB1
                //      return 1;
                //  return 2;
                //
                //  BB1 does not have a ipdom.
                UINT ipdom = ((DGraph*)cfg)->get_ipdom(BB_id(bb));
                DUMMYUSE(ipdom);
                ASSERT(ipdom > 0, ("bb does not have ipdom"));
                node = constructAbsIf(bb, parent, g, loc_visited);
            } else {
                node = constructAbsBB(bb, parent);
                loc_visited.bunion(BB_id(bb));
            }
        }
        insertbefore_one(&lst, lst, node);

        visited.bunion(loc_visited);
        //Remove visited vertex.
        next = NULL;
        INT c;
        for (v = g.get_first_vertex(c); v != NULL; v = next) {
            next = g.get_next_vertex(c);
            if (!loc_visited.is_contain(VERTEX_id(v))) {
                continue;
            }
            g.removeVertex(v);
        }

        IRBB * cand = NULL;
        for (v = g.get_first_vertex(c); v != NULL; v = g.get_next_vertex(c)) {
            if (g.get_in_degree(v) == 0) {
                ASSERT(cand == NULL, ("multiple immediate-post-dominators"));
                cand = cfg->getBB(VERTEX_id(v));
            }
        }

        if (cand == NULL) {
            //Cannot find leading BB, there might be exist cycle in graph.
            bb = cfg->get_ipdom(bb);
        } else {
            bb = cand;
        }

        if (parent != NULL && bb == ABS_NODE_bb(parent)) {
            //Here control-flow is cyclic.
            break;
        }
    }
    lst = reverse_list(lst);
    return lst;
}
コード例 #14
0
ファイル: prdf.cpp プロジェクト: onecoolx/xoc
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);
        }
    }
}
コード例 #15
0
ファイル: prdf.cpp プロジェクト: onecoolx/xoc
void PRDF::computeGlobal()
{
    ASSERT0(BB_is_entry(m_cfg->get_entry_list()->get_head()) &&
            m_cfg->get_entry_list()->get_elem_count() == 1);

    //Rpo should be available.
    List<IRBB*> * vlst = m_cfg->get_bblist_in_rpo();
    ASSERT0(vlst->get_elem_count() == m_ru->get_bb_list()->get_elem_count());

    C<IRBB*> * ct;
    for (vlst->get_head(&ct); ct != vlst->end(); ct = vlst->get_next(ct)) {
        IRBB * bb = ct->val();
        ASSERT0(bb);
        UINT bbid = BB_id(bb);
        get_livein(bbid)->clean(m_sbs_mgr);
        get_liveout(bbid)->clean(m_sbs_mgr);
    }

    bool change;
    UINT count = 0;
    UINT thres = 1000;
    DefSBitSetCore news;
    do {
        change = false;
        C<IRBB*> * ct;
        for (vlst->get_tail(&ct); ct != vlst->end(); ct = vlst->get_prev(ct)) {
            IRBB * bb = ct->val();
            ASSERT0(bb);
            UINT bbid = BB_id(bb);

            DefSBitSetCore * out = m_liveout.get(bbid);
            news.copy(*out, m_sbs_mgr);

            ASSERT0(m_def.get(bbid));
            news.diff(*m_def.get(bbid), m_sbs_mgr);
            news.bunion(*m_use.get(bbid), m_sbs_mgr);
            m_livein.get(bbid)->copy(news, m_sbs_mgr);

            EdgeC const* ec = VERTEX_out_list(m_cfg->get_vertex(BB_id(bb)));
            if (ec != NULL) {
                INT succ = VERTEX_id(EDGE_to(EC_edge(ec)));
                news.copy(*m_livein.get(succ), m_sbs_mgr);
                ec = EC_next(ec);

                for (; ec != NULL; ec = EC_next(ec)) {
                    news.bunion(*m_livein.get(succ), m_sbs_mgr);
                }

                if (!out->is_equal(news)) {
                    out->copy(news, m_sbs_mgr);
                    change = true;
                }
            }
        }
        count++;
    } while (change && count < thres);
    ASSERT(!change, ("result of equation is convergent slowly"));

    news.clean(m_sbs_mgr);

#ifdef STATISTIC_PRDF
    g_max_times = MAX(g_max_times, count);
    FILE * h = fopen("prdf.sat.dump", "a+");
    fprintf(h, "\n%s run %u times, maxtimes %u",
            m_ru->get_ru_name(), count, g_max_times);
    fclose(h);
#endif
}
コード例 #16
0
ファイル: ir_cp.cpp プロジェクト: stevenknown/xoc
//'usevec': for local used.
bool IR_CP::doProp(IN IRBB * bb, Vector<IR*> & usevec)
{
    bool change = false;
    C<IR*> * cur_iter, * next_iter;

    for (BB_irlist(bb).get_head(&cur_iter),
         next_iter = cur_iter; cur_iter != NULL; cur_iter = next_iter) {

        IR * def_stmt = cur_iter->val();

        BB_irlist(bb).get_next(&next_iter);

        if (!is_copy(def_stmt)) { continue; }

        DUSet const* useset = NULL;
        UINT num_of_use = 0;
        SSAInfo * ssainfo = NULL;
        bool ssadu = false;
        if ((ssainfo = def_stmt->get_ssainfo()) != NULL &&
            SSA_uses(ssainfo).get_elem_count() != 0) {
            //Record use_stmt in another vector to facilitate this function
            //if it is not in use-list any more after copy-propagation.
            SEGIter * sc;
            for    (INT u = SSA_uses(ssainfo).get_first(&sc);
                 u >= 0; u = SSA_uses(ssainfo).get_next(u, &sc)) {
                IR * use = m_ru->get_ir(u);
                ASSERT0(use);
                usevec.set(num_of_use, use);
                num_of_use++;
            }
            ssadu = true;
        } else if (def_stmt->get_exact_ref() == NULL &&
                   !def_stmt->is_void()) {
            //Allowing copy propagate exact or VOID value.
            continue;
        } else if ((useset = def_stmt->readDUSet()) != NULL &&
                   useset->get_elem_count() != 0) {
            //Record use_stmt in another vector to facilitate this function
            //if it is not in use-list any more after copy-propagation.
            DUIter di = NULL;
            for (INT u = useset->get_first(&di);
                 u >= 0; u = useset->get_next(u, &di)) {
                IR * use = m_ru->get_ir(u);
                usevec.set(num_of_use, use);
                num_of_use++;
            }
        } else  {
            continue;
        }

        IR const* prop_value = get_propagated_value(def_stmt);

        for (UINT i = 0; i < num_of_use; i++) {
            IR * use = usevec.get(i);
            ASSERT0(use->is_exp());
            IR * use_stmt = use->get_stmt();
            ASSERT0(use_stmt->is_stmt());

            ASSERT0(use_stmt->get_bb() != NULL);
            IRBB * use_bb = use_stmt->get_bb();
            if (!ssadu &&
                !(bb == use_bb && bb->is_dom(def_stmt, use_stmt, true)) &&
                !m_cfg->is_dom(BB_id(bb), BB_id(use_bb))) {
                //'def_stmt' must dominate 'use_stmt'.
                //e.g:
                //    if (...) {
                //        g = 10; //S1
                //    }
                //    ... = g; //S2
                //g can not be propagted since S1 is not dominate S2.
                continue;
            }

            if (!is_available(def_stmt, prop_value, use_stmt)) {
                //The value that will be propagated can
                //not be killed during 'ir' and 'use_stmt'.
                //e.g:
                //    g = a; //S1
                //    if (...) {
                //        a = ...; //S3
                //    }
                //    ... = g; //S2
                //g can not be propagted since a is killed by S3.
                continue;
            }

            if (!ssadu && !m_du->isExactAndUniqueDef(def_stmt, use)) {
                //Only single definition is allowed.
                //e.g:
                //    g = 20; //S3
                //    if (...) {
                //        g = 10; //S1
                //    }
                //    ... = g; //S2
                //g can not be propagted since there are
                //more than one definitions are able to get to S2.
                continue;
            }

            if (!canBeCandidate(prop_value)) {
                continue;
            }

            CPCtx lchange;
            IR * old_use_stmt = use_stmt;

            replaceExp(use, prop_value, lchange, ssadu);

            ASSERT(use_stmt && use_stmt->is_stmt(),
                    ("ensure use_stmt still legal"));
            change |= CPC_change(lchange);

            if (!CPC_change(lchange)) { continue; }

            //Indicate whether use_stmt is the next stmt of def_stmt.
            bool is_next = false;
            if (next_iter != NULL && use_stmt == next_iter->val()) {
                is_next = true;
            }

            RefineCtx rf;
            use_stmt = m_ru->refineIR(use_stmt, change, rf);
            if (use_stmt == NULL && is_next) {
                //use_stmt has been optimized and removed by refineIR().
                next_iter = cur_iter;
                BB_irlist(bb).get_next(&next_iter);
            }

            if (use_stmt != NULL && use_stmt != old_use_stmt) {
                //use_stmt has been removed and new stmt generated.
                ASSERT(old_use_stmt->is_undef(), ("the old one should be freed"));

                C<IR*> * irct = NULL;
                BB_irlist(use_bb).find(old_use_stmt, &irct);
                ASSERT0(irct);
                BB_irlist(use_bb).insert_before(use_stmt, irct);
                BB_irlist(use_bb).remove(irct);
            }
        } //end for each USE
    } //end for IR
    return change;
}
コード例 #17
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
AbsNode * CfsMgr::map_bb2abs(IRBB const* bb)
{
    return m_map_bb2abs.get(BB_id(bb));
}