예제 #1
0
EDGE * GRAPH::get_edge(VERTEX const* from, VERTEX const* to)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (from == NULL || to == NULL) return NULL;
	EDGE_C * el = VERTEX_out_list(from);
	while (el != NULL) {
		EDGE * e = EC_edge(el);
		if (EDGE_from(e) == from && EDGE_to(e) == to) {
			return e;
		}
		if (!m_is_direction && 
			(EDGE_from(e) == to && EDGE_to(e) == from)) {
			return e;
		}
		el = EC_next(el);
	}
	
	if (!m_is_direction) {
		EDGE_C * el = VERTEX_out_list(to);
		while (el != NULL) {
			EDGE * e = EC_edge(el);
			if (EDGE_from(e) == to && EDGE_to(e) == from) {
				return e;
			}
			el = EC_next(el);
		}
	}
	return NULL;
}
예제 #2
0
EDGE * GRAPH::remove_edge(EDGE * e)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (e == NULL) return NULL;
	VERTEX * from = EDGE_from(e);
	VERTEX * to = EDGE_to(e);

	//remove out of out-list of 'from'
	EDGE_C * el = VERTEX_out_list(from);
	while (el != NULL) {
		if (EC_edge(el) == e) {	break; }
		el = EC_next(el);
	}
	IS_TRUE(el != NULL, ("can not find out-edge, it is illegal graph"));
	remove(&VERTEX_out_list(from), el);
	m_el_free_list.add_free_elem(el);

	//remove out of in-list of 'to'		
	el = VERTEX_in_list(to);
	while (el != NULL) {
		if (EC_edge(el) == e) break;
		el = EC_next(el);
	}
	IS_TRUE(el != NULL, ("can not find in-edge, it is illegal graph"));
	remove(&VERTEX_in_list(to), el);
	m_el_free_list.add_free_elem(el);

	//remove edge out of edge-hash
	e = m_edges.removed(e);	
	m_e_free_list.add_free_elem(e);
	return e;
}
예제 #3
0
bool GRAPH::is_equal(GRAPH & g)
{
	if (get_vertex_num() != g.get_vertex_num() ||
		get_edge_num() != g.get_edge_num()) {
		return false;
	}
	
	BITSET vs;
	INT c;
	for (VERTEX * v1 = get_first_vertex(c); 
		 v1 != NULL; v1 = get_next_vertex(c)) {
		VERTEX * v2 = g.get_vertex(VERTEX_id(v1));
		if (v2 == NULL) {
			return false; 
		}

		vs.clean();
		EDGE_C * el = VERTEX_out_list(v1);		
		EDGE * e = NULL;
		UINT v1_succ_n = 0;
		if (el == NULL) {
			if (VERTEX_out_list(v2) != NULL) {
				return false;
			}
			continue;
		}
		for (e = EC_edge(el); e != NULL; el = EC_next(el), 
			 e = el ? EC_edge(el) : NULL) {
			vs.bunion(VERTEX_id(EDGE_to(e)));
			v1_succ_n++;
		}

		UINT v2_succ_n = 0;
		el = VERTEX_out_list(v2);
		for (e = EC_edge(el); e != NULL; el = EC_next(el), 
			 e = el ? EC_edge(el) : NULL) {
			v2_succ_n++;
			if (!vs.is_contain(VERTEX_id(EDGE_to(e)))) {
				return false;
			}			
		}
		
		if (v1_succ_n != v2_succ_n) { 
			return false; 
		}
	}
	return true;
}
예제 #4
0
void DGRAPH::sort_dom_tree_in_postorder(IN GRAPH & dom_tree, IN VERTEX * root,
										OUT LIST<VERTEX*> & lst)
{
	IS_TRUE0(root);
	BITSET is_visited;

	//Find the leaf node.
	VERTEX * v;
	SSTACK<VERTEX*> stk;
	stk.push(root);
	while ((v = stk.pop()) != NULL) {
		//Visit children first.
		EDGE_C * el = VERTEX_out_list(v);
		bool find = false; //find unvisited kid.
		VERTEX * succ;
		while (el != NULL) {
			succ = EDGE_to(EC_edge(el));
			if (!is_visited.is_contain(VERTEX_id(succ))) {
				stk.push(v);
				stk.push(succ);
				find = true;
				break;
			}
			el = EC_next(el);
		}
		if (!find) {
			is_visited.bunion(VERTEX_id(v));
			//The only place to process vertex.
			lst.append_tail(v);
		}
	}	
}
예제 #5
0
void DGRAPH::sort_dom_tree_in_preorder(IN GRAPH & dom_tree, IN VERTEX * root,
									   OUT LIST<VERTEX*> & lst)
{
	IS_TRUE0(root);
	BITSET is_visited;
	is_visited.bunion(VERTEX_id(root));
	lst.append_tail(root);
	
	VERTEX * v;
	SSTACK<VERTEX*> stk;
	stk.push(root);
	while ((v = stk.pop()) != NULL) {
		if (!is_visited.is_contain(VERTEX_id(v))) {
			is_visited.bunion(VERTEX_id(v));
			stk.push(v);
			//The only place to process vertex.
			lst.append_tail(v);			
		}
		
		//Visit children.
		EDGE_C * el = VERTEX_out_list(v);
		VERTEX * succ;
		while (el != NULL) {
			succ = EDGE_to(EC_edge(el));
			if (!is_visited.is_contain(VERTEX_id(succ))) {
				stk.push(v);
				stk.push(succ);
				break;
			}
			el = EC_next(el);
		}		
	}
}
예제 #6
0
/*
Sort vertice by rporder, and 
record to vlst in incremental order.
*/
void DGRAPH::compute_rpo_norec(IN VERTEX * root, OUT LIST<VERTEX*> & vlst)
{
	BITSET is_visited;
	SSTACK<VERTEX*> stk;
	stk.push(root);
	VERTEX * v;
	while ((v = stk.pop()) != NULL) {
		is_visited.bunion(VERTEX_id(v));
		EDGE_C * el = VERTEX_out_list(v);
		bool find = false; //find unvisited kid.
		while (el != NULL) {
			VERTEX * succ = EDGE_to(EC_edge(el));
			if (!is_visited.is_contain(VERTEX_id(succ))) {
				stk.push(v);
				stk.push(succ);
				find = true;
				break;				
			}
			el = EC_next(el);
		}
		if (!find) {			
			vlst.append_head(v);
		}
	}
}
예제 #7
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);
        }
    }
}
예제 #8
0
파일: loop.cpp 프로젝트: Grainspring/xoc
/* Find the bb that is the start of the unqiue backedge of loop.
   BB1: loop start bb
   BB2: body start bb
   BB3: goto loop start bb

   BB2 is the loop header fallthrough bb. */
bool find_loop_header_two_succ_bb(LI<IR_BB> const* li, IR_CFG * cfg,
								UINT * succ1, UINT * succ2)
{
	IS_TRUE0(li && cfg && succ1 && succ2);
	IR_BB * head = LI_loop_head(li);

	VERTEX * headvex = cfg->get_vertex(IR_BB_id(head));
	if (cfg->get_out_degree(headvex) != 2) {
		//Not natural loop.
		return false;
	}

	EDGE_C const* ec = VERTEX_out_list(headvex);
	IS_TRUE0(ec && EC_next(ec));

	*succ1 = VERTEX_id(EDGE_to(EC_edge(ec)));
	*succ2 = VERTEX_id(EDGE_to(EC_edge(EC_next(ec))));
	return true;
}
예제 #9
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);
    }
}
예제 #10
0
파일: cdg.cpp 프로젝트: Grainspring/xoc
void CDG::get_cd_succs(UINT id, OUT LIST<VERTEX*> & lst)
{
	VERTEX * v = get_vertex(id);
	IS_TRUE0(v != NULL);
	EDGE_C * out = VERTEX_out_list(v);
	while (out != NULL) {
		VERTEX * succ = EDGE_to(EC_edge(out));
		lst.append_tail(succ);
		out = EC_next(out);
	}
}
예제 #11
0
//Return true if 'pred' is predecessor of 'v'.
bool GRAPH::is_pred(VERTEX * v, VERTEX * pred)
{
	EDGE_C * e = VERTEX_in_list(v);
	while (e != NULL) {
		if (EDGE_from(EC_edge(e)) == pred) {
			return true;
		}
		e = EC_next(e);
	}
	return false;
}
예제 #12
0
파일: cdg.cpp 프로젝트: Grainspring/xoc
void CDG::get_cd_preds(UINT id, OUT LIST<VERTEX*> & lst)
{
	VERTEX * v = get_vertex(id);
	IS_TRUE0(v != NULL);
	EDGE_C * in = VERTEX_in_list(v);
	while (in != NULL) {
		VERTEX * pred = EDGE_from(EC_edge(in));
		lst.append_tail(pred);
		in = EC_next(in);
	}
}
예제 #13
0
//Return true if 'succ' is successor of 'v'.
bool GRAPH::is_succ(VERTEX * v, VERTEX * succ)
{
	EDGE_C * e = VERTEX_out_list(v);
	while (e != NULL) {
		if (EDGE_to(EC_edge(e)) == succ) {
			return true;
		}
		e = EC_next(e);
	}
	return false;
}
예제 #14
0
파일: cdg.cpp 프로젝트: Grainspring/xoc
bool CDG::is_only_cd_self(UINT id)
{
	VERTEX * v = get_vertex(id);
	IS_TRUE0(v != NULL);
	EDGE_C * out = VERTEX_out_list(v);
	while (out != NULL) {
		VERTEX * succ = EDGE_to(EC_edge(out));
		if (succ != v) return false;
		out = EC_next(out);
	}
	return true;
}
예제 #15
0
UINT GRAPH::get_out_degree(VERTEX const* vex) const
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (vex == NULL) return 0;
	UINT degree = 0;
	EDGE_C * el = VERTEX_out_list(vex);
	while (el != NULL) {
		degree++;
		el = EC_next(el);
	}
	return degree;
}
예제 #16
0
void DGRAPH::_remove_unreach_node(UINT id, BITSET & visited)
{
	visited.bunion(id);
	VERTEX * vex = get_vertex(id);
	EDGE_C * el = VERTEX_out_list(vex);	
	while (el != NULL) {
		UINT succ = VERTEX_id(EDGE_to(EC_edge(el)));
		if (!visited.is_contain(succ)) {
			_remove_unreach_node(succ, visited);
		}	
		el = EC_next(el);
	}
}
예제 #17
0
//Add 'e' into out-edges of 'vex'
void GRAPH::add_out_list(VERTEX * vex, EDGE * e)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (vex == NULL || e == NULL)return;

	EDGE_C * el = VERTEX_out_list(vex);
	while (el != NULL) {
		if (EC_edge(el) == e) return;
		el = EC_next(el);
	}
	el = new_ec(e);
	add_next(&VERTEX_out_list(vex), el);
}
예제 #18
0
파일: cdg.cpp 프로젝트: Grainspring/xoc
//Return true if b is control dependent on a.
bool CDG::is_cd(UINT a, UINT b)
{
	IS_TRUE0(get_vertex(b));
	VERTEX * v = get_vertex(a);
	IS_TRUE0(v != NULL);
	EDGE_C * out = VERTEX_out_list(v);
	while (out != NULL) {
		if (VERTEX_id(EDGE_to(EC_edge(out))) == b) {
			return true;
		}
		out = EC_next(out);
	}
	return false;
}
예제 #19
0
VERTEX * GRAPH::remove_vertex(VERTEX * vex)
{	
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (vex == NULL) return NULL;
	EDGE_C * el = VERTEX_out_list(vex);
	//remove all out-edge
	while (el != NULL) {
		EDGE_C * tmp = el;
		el = EC_next(el);
		remove_edge(EC_edge(tmp));
	}

	//remove all in-edge
	el = VERTEX_in_list(vex);
	while (el != NULL) {
		EDGE_C * tmp = el;
		el = EC_next(el);
		remove_edge(EC_edge(tmp));
	}
	vex = m_vertexs.removed(vex);
	m_v_free_list.add_free_elem(vex);
	return vex;
}
예제 #20
0
/*
Return all neighbors of 'vid' on graph.
Return false if 'vid' is not on graph.
*/
bool GRAPH::get_neighbor_list(OUT LIST<UINT> & ni_list, IN UINT vid)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	UINT degree = 0;
	VERTEX * vex  = m_vertexs.find(vid);
	if (vex == NULL) return false;
	EDGE_C * el = VERTEX_in_list(vex);
	while (el != NULL) {
		INT v = VERTEX_id(EDGE_from(EC_edge(el)));
		if (!ni_list.find(v)) {
			ni_list.append_tail(v);
		}
		el = EC_next(el);
	}
	el = VERTEX_out_list(vex);
	while (el != NULL) {
		INT v = VERTEX_id(EDGE_to(EC_edge(el)));
		if (!ni_list.find(v)) {
			ni_list.append_tail(v);
		}	
		el = EC_next(el);
	}
	return true;
}
예제 #21
0
//Remove all edges between v1 and v2.
void GRAPH::remove_edges_between(VERTEX * v1, VERTEX * v2)
{
	EDGE_C * ec = VERTEX_out_list(v1);	
	while (ec != NULL) {
		EDGE_C * next = EC_next(ec);
		EDGE * e = EC_edge(ec);
		if ((EDGE_from(e) == v1 && EDGE_to(e) == v2) ||
			(EDGE_from(e) == v2 && EDGE_to(e) == v1)) {
			remove_edge(e);
		}		
		ec = next;
	}

	ec = VERTEX_in_list(v1);
	while (ec != NULL) {
		EDGE_C * next = EC_next(ec);
		EDGE * e = EC_edge(ec);
		if ((EDGE_from(e) == v1 && EDGE_to(e) == v2) ||
			(EDGE_from(e) == v2 && EDGE_to(e) == v1)) {
			remove_edge(e);
		}		
		ec = next;
	}
}
예제 #22
0
파일: loop.cpp 프로젝트: Grainspring/xoc
/* Find preheader BB. If it does not exist, insert one before loop 'li'.

'insert_bb': return true if this function insert a new bb before loop,
	otherwise return false.

'force': force to insert preheader BB whatever it has exist.
	Return the new BB if insertion is successful.

Note if we find the preheader, the last IR of it may be call.
So if you are going to insert IR at the tail of preheader, the best is
force to insert a new bb. */
IR_BB * find_and_insert_prehead(LI<IR_BB> const* li, REGION * ru,
								OUT bool & insert_bb,
								bool force)
{
	IS_TRUE0(li && ru);
	insert_bb = false;
	IR_CFG * cfg = ru->get_cfg();
	IR_BB_LIST * bblst = ru->get_bb_list();
	IR_BB * head = LI_loop_head(li);

	C<IR_BB*> * bbholder = NULL;
	bblst->find(head, &bbholder);
	IS_TRUE0(bbholder);
	C<IR_BB*> * tt = bbholder;
	IR_BB * prev = bblst->get_prev(&tt);

	//Find appropriate BB to be prehead.
	bool find_appropriate_prev_bb = false;
	EDGE_C const* ec = VERTEX_in_list(cfg->get_vertex(IR_BB_id(head)));
	while (ec != NULL) {
		UINT pred = VERTEX_id(EDGE_from(EC_edge(ec)));
		if (pred == IR_BB_id(prev)) {
			find_appropriate_prev_bb = true;
			break;
		}
		ec = EC_next(ec);
	}

	if (!force && find_appropriate_prev_bb) { return prev; }

	LIST<IR_BB*> preds;
	cfg->get_preds(preds, head);
	insert_bb = true;
	IR_BB * newbb = ru->new_bb();
	bblst->insert_before(newbb, bbholder);
	BITSET * loop_body = LI_bb_set(li);
	for (IR_BB * p = preds.get_head(); p != NULL; p = preds.get_next()) {
		if (loop_body->is_contain(IR_BB_id(p))) {
			continue;
		}
		cfg->add_bb(newbb);
		cfg->insert_vertex_between(IR_BB_id(p), IR_BB_id(head),
								   IR_BB_id(newbb));
		IR_BB_is_fallthrough(newbb) = 1;
	}
	return newbb;
}
예제 #23
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;
}
예제 #24
0
//'order_buf': record the bfs-order for each vertex.
void DGRAPH::sort_in_bfs_order(SVECTOR<UINT> & order_buf, GRAPH & domtree,
							   VERTEX * root)
{		
	LIST<VERTEX*> worklst;
	worklst.append_tail(root);
	UINT order = 1;
	while (worklst.get_elem_count() > 0) {
		VERTEX * sv = worklst.remove_head();
		order_buf.set(VERTEX_id(sv), order);
		order++;
		EDGE_C * el = VERTEX_out_list(sv);
		while (el != NULL) {
			VERTEX * to = EDGE_to(EC_edge(el));
			worklst.append_tail(to);
			el = EC_next(el);
		}
	}
}
예제 #25
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);
        }
    }
}
예제 #26
0
//Is there exist a path connect 'from' and 'to'.
bool GRAPH::is_reachable(VERTEX * from, VERTEX * to)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	IS_TRUE(from != NULL && to != NULL, ("parameters cannot be NULL"));
	EDGE_C * el = VERTEX_out_list(from);
	EDGE * e = NULL;
	if (el == NULL) return false;
	
	//Walk through each succ of 'from'
	for (e = EC_edge(el); e != NULL; el = EC_next(el), 
		 e = el ? EC_edge(el):NULL) {
		VERTEX * succ = EDGE_to(e);
		if (VERTEX_id(succ) == VERTEX_id(to)) {
			return true;
		} else {
			if (is_reachable(succ, to)) {
				return true;
			}
		}
	} //end for
	return false;
}
예제 #27
0
파일: loop.cpp 프로젝트: Grainspring/xoc
/* Find the bb that is the start of the unqiue backedge of loop.
   BB1: loop start bb
   BB2: body
   BB3: goto loop start bb

   BB3 is the backedge start bb. */
IR_BB * find_single_backedge_start_bb(LI<IR_BB> const* li, IR_CFG * cfg)
{
	IS_TRUE0(li && cfg);
	IR_BB * head = LI_loop_head(li);

	UINT backedgebbid = 0;
	UINT backedgecount = 0;
	EDGE_C const* ec = VERTEX_in_list(cfg->get_vertex(IR_BB_id(head)));
	while (ec != NULL) {
		backedgecount++;
		UINT pred = VERTEX_id(EDGE_from(EC_edge(ec)));
		if (li->inside_loop(pred)) {
			backedgebbid = pred;
		}
		ec = EC_next(ec);
	}
	IS_TRUE0(backedgebbid > 0 && cfg->get_bb(backedgebbid));
	if (backedgecount > 2) {
		//There are multiple backedges.
		return NULL;
	}
	return cfg->get_bb(backedgebbid);
}
예제 #28
0
파일: cdg.cpp 프로젝트: Grainspring/xoc
//
//START CDG
//
void CDG::dump()
{
	dump_vcg("graph_cd_tree.vcg");
	if (g_tfile == NULL) return;
	fprintf(g_tfile, "\n==---- DUMP Control Dependence ----==");
	INT c;
	for (VERTEX * v = get_first_vertex(c);
		 v != NULL; v = get_next_vertex(c)) {
		EDGE_C * in = VERTEX_in_list(v);
		if (in == NULL) {
			fprintf(g_tfile, "\nBB%d has NO ctrl BB", VERTEX_id(v));
			continue;
		}
		fprintf(g_tfile, "\nBB%d ctrl BB is: ", VERTEX_id(v));
		while (in != NULL) {
			VERTEX * pred = EDGE_from(EC_edge(in));
			fprintf(g_tfile, "%d,", VERTEX_id(pred));
			in = EC_next(in);
		}
	}
	fprintf(g_tfile, "\n");
	fflush(g_tfile);
}
예제 #29
0
파일: cdg.cpp 프로젝트: Grainspring/xoc
void CDG::build(IN OUT OPT_CTX & oc, DGRAPH & cfg)
{
	if (cfg.get_vertex_num() == 0) { return; }
	START_TIMER("CDG");
	IS_TRUE0(OPTC_is_cfg_valid(oc));
	m_ru->check_valid_and_recompute(&oc, OPT_PDOM, OPT_UNDEF);

	GRAPH pdom_tree;
	cfg.get_pdom_tree(pdom_tree);
	if (pdom_tree.get_vertex_num() == 0) { return; }

	SVECTOR<UINT> top_order;
	pdom_tree.sort_in_toplog_order(top_order, false);
	//dump_vec(top_order);

	BITSET_MGR bs_mgr;
	SVECTOR<BITSET*> cd_set;
	for (INT j = 0; j <= top_order.get_last_idx(); j++) {
		UINT ii = top_order.get(j);
		VERTEX * v = cfg.get_vertex(ii);
		IS_TRUE0(v != NULL);
		add_vertex(VERTEX_id(v));
		BITSET * cd_of_v = cd_set.get(VERTEX_id(v));
		if (cd_of_v == NULL) {
			cd_of_v = bs_mgr.create();
			cd_set.set(VERTEX_id(v), cd_of_v);
		}

		EDGE_C * in = VERTEX_in_list(v);
		while (in != NULL) {
			VERTEX * pred = EDGE_from(EC_edge(in));
			if (VERTEX_id(v) != ((DGRAPH&)cfg).get_ipdom(VERTEX_id(pred))) {
				cd_of_v->bunion(VERTEX_id(pred));
				//if (pred != v)
				{
					add_edge(VERTEX_id(pred), VERTEX_id(v));
				}
			}
			in = EC_next(in);
		}
		INT c;
		for (VERTEX * z = cfg.get_first_vertex(c);
			 z != NULL; z = cfg.get_next_vertex(c)) {
			if (((DGRAPH&)cfg).get_ipdom(VERTEX_id(z)) == VERTEX_id(v)) {
				BITSET * cd = cd_set.get(VERTEX_id(z));
				if (cd == NULL) {
					cd = bs_mgr.create();
					cd_set.set(VERTEX_id(z), cd);
				}
				for (INT i = cd->get_first(); i != -1; i = cd->get_next(i)) {
					if (VERTEX_id(v) != ((DGRAPH&)cfg).get_ipdom(i)) {
						cd_of_v->bunion(i);
						//if (i != (INT)VERTEX_id(v))
						{
							add_edge(i, VERTEX_id(v));
						}
					}
				}
			}
		}
	} //end for

	OPTC_is_cdg_valid(oc) = true;
	END_TIMER();
}
예제 #30
0
/*
Vertexs should have been sorted in topological order.
And we access them by reverse-topological order.
'vlst': compute dominator for vertices in vlst if it 
	is not empty or else compute all graph.
'uni': universe.	
*/
bool DGRAPH::compute_dom(IN LIST<VERTEX*> * vlst, BITSET const* uni)
{
	LIST<VERTEX*> tmpvlst;
	LIST<VERTEX*> * pvlst = &tmpvlst;
	if (vlst != NULL) {
		pvlst = vlst;
	} else {
		INT c;
		for (VERTEX * u = get_first_vertex(c); 
			 u != NULL; u = get_next_vertex(c)) {
			pvlst->append_tail(u);
		}
	}

	BITSET const* luni = NULL;
	if (uni != NULL) {
		luni = uni;
	} else {
		BITSET * x = new BITSET();	
		for (VERTEX * u = pvlst->get_head(); 
			 u != NULL; u = pvlst->get_next()) {
			x->bunion(VERTEX_id(u));		
		}
		luni = x;
	}

	//Initialize dom-set for each BB.	
	for (VERTEX * v = pvlst->get_head();
		 v != NULL; v = pvlst->get_next()) {
		if (is_graph_entry(v)) {
			BITSET * dom = get_dom_set(v);
			dom->clean();
			dom->bunion(VERTEX_id(v));
		} else {
			get_dom_set(v)->copy(*luni);
		}
	}
	
	/*
	DOM[entry] = {entry}
	DOM[n] = {n} ¡È { ¡É(DOM[pred] of predecessor of 'n') }	
	*/
	bool change = true;
	BITSET tmp;
	UINT count = 0;
	while (change && count < 10) {
		count++;
		change = false;
		for (VERTEX * v = pvlst->get_head(); 
			 v != NULL; v = pvlst->get_next()) {
			UINT vid = VERTEX_id(v);
			if (is_graph_entry(v)) {
				continue;
			} else {
				//Access each preds
				EDGE_C * ec = VERTEX_in_list(v);
				while (ec != NULL) {
					VERTEX * pred = EDGE_from(EC_edge(ec));
					if (ec == VERTEX_in_list(v)) {
						tmp.copy(*m_dom_set.get(VERTEX_id(pred)));		
					} else {
						tmp.intersect(*m_dom_set.get(VERTEX_id(pred)));
					}
					ec = EC_next(ec);
				}
				tmp.bunion(vid);

				BITSET * dom = m_dom_set.get(VERTEX_id(v));
				if (!dom->is_equal(tmp)) {
					dom->copy(tmp);
					change = true;
				}				
			} //end else
		} //end for
	}//end while
	IS_TRUE0(!change);
	if (uni == NULL && luni != NULL) {
		delete luni;
	}
	return true;
}