예제 #1
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);
        }
    }
}
예제 #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);
        }
    }
}
예제 #3
0
파일: cfs_mgr.cpp 프로젝트: Grainspring/xoc
ABS_NODE * CFS_MGR::construct_abs_tree(
						IN IR_BB * entry,
						IN ABS_NODE * parent,
						IN BITSET * cur_region,
						IN GRAPH & cur_graph,
						IN OUT BITSET & visited)
{
	IR_CFG * cfg = m_ru->get_cfg();
	ABS_NODE * lst = NULL;
	IR_BB * 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.remove_vertex(v);
		}
	}
	BITSET loc_visited;
	while (bb != NULL &&
		   (cur_region == NULL ||
		    cur_region->is_contain(IR_BB_id(bb)))) {
		ABS_NODE * node = NULL;
		loc_visited.clean();
		LI<IR_BB> * li = cfg->map_bb2li(bb);
		if (li != NULL) {
			node = construct_abs_loop(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->is_cond_br()) {
				IS_TRUE0(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(IR_BB_id(bb));
				IS_TRUE(ipdom > 0, ("bb does not have ipdom"));
				node = construct_abs_if(bb, parent, g, loc_visited);
			} else {
				node = construct_abs_bb(bb, parent);
				loc_visited.bunion(IR_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.remove_vertex(v);
		}

		IR_BB * cand = NULL;
		for (v = g.get_first_vertex(c); v != NULL; v = g.get_next_vertex(c)) {
			if (g.get_in_degree(v) == 0) {
				IS_TRUE(cand == NULL, ("multiple immediate-post-dominators"));
				cand = cfg->get_bb(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;
}