Exemple #1
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;
}
Exemple #2
0
//Add 'e' into in-edges of 'vex'
void GRAPH::add_in_list(VERTEX * vex, EDGE * e)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (vex == NULL || e == NULL) return;

	EDGE_C * el = VERTEX_in_list(vex);
	while (el != NULL) {
		if (EC_edge(el) == e) return;
		el = EC_next(el);
	}
	el = new_ec(e);
	add_next(&VERTEX_in_list(vex), el);
}
Exemple #3
0
//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);
        }
    }
}
Exemple #4
0
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);
	}
}
Exemple #5
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;
}
Exemple #6
0
UINT GRAPH::get_in_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_in_list(vex);
	while (el != NULL) {
		degree++;
		el = EC_next(el);
	}
	return degree;
}
Exemple #7
0
/* 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;
}
Exemple #8
0
//
//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);
}
Exemple #9
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;
}
Exemple #10
0
/* 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);
}
Exemple #11
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;
	}
}
Exemple #12
0
/*
Sort graph vertices in topological order. 
'vex_vec': record nodes with topological sort.
NOTE: current graph will be empty at function return.
	If one need to keep the graph unchanged, clone graph
	as a tmpgraph and operate on the tmpgraph.
	e.g: GRAPH org; 
		And org must be unchanged, 
		GRAPH tmp(org);
		tmp.sort_in_toplog_order(...)	
*/
bool GRAPH::sort_in_toplog_order(OUT SVECTOR<UINT> & vex_vec, bool is_topdown)
{
	IS_TRUE(m_pool != NULL, ("Graph still not yet initialize."));
	if (get_vertex_num() == 0) {
		return true;
	}
	LIST<VERTEX*> vlst;
	UINT pos = 0;
	vex_vec.clean();
	vex_vec.grow(get_vertex_num());
	while (this->get_vertex_num() != 0) {
		vlst.clean();
		VERTEX * v;
		INT c;
		for (v = this->get_first_vertex(c);
			 v != NULL; v = this->get_next_vertex(c)) {
			if (is_topdown) {
				if (VERTEX_in_list(v) == NULL) {
					vlst.append_tail(v);
				}
			} else if (VERTEX_out_list(v) == NULL) {
				vlst.append_tail(v);				
			}
		}
		if (vlst.get_elem_count() == 0 && this->get_vertex_num() != 0) {
			IS_TRUE(0, ("exist cycle in graph"));
			return false;
		}
		for (v = vlst.get_head(); v != NULL; v = vlst.get_next()) {
			vex_vec.set(pos, VERTEX_id(v));
			pos++;
			this->remove_vertex(v);
		}
	}
	return true;
}
Exemple #13
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;
}
Exemple #14
0
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();
}
Exemple #15
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;
}