Beispiel #1
0
EDGE * GRAPH::new_edge(VERTEX * from, VERTEX * to)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (from == NULL || to == NULL) return NULL;
	EDGE teste;
	VERTEX testfrom, testto;
	if (m_is_unique) {
		VERTEX_id(&testfrom) = VERTEX_id(from);
		VERTEX_id(&testto) = VERTEX_id(to);
		EDGE_from(&teste) = &testfrom;
		EDGE_to(&teste) = &testto;
		if (m_is_direction) {			
			return m_edges.append((ULONG)&teste, NULL);
		} else {
			EDGE * e = NULL;
			if (m_edges.find(&teste, &e)) {
				IS_TRUE0(e);
				return e;
			}
			
			//Both check from->to and to->from
			EDGE_from(&teste) = &testto;
			EDGE_to(&teste) = &testfrom;
			return m_edges.append((ULONG)&teste, NULL);
		}
		IS_TRUE0(0);
	}
	return m_edges.append(new_edge_c(from, to));
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
0
void GRAPH::dump_dot(CHAR const* name)
{
	if (name == NULL) {
		name = "graph.dot";
	}
	unlink(name);
	FILE * h = fopen(name, "a+");
	IS_TRUE(h, ("%s create failed!!!", name));

	fprintf(h, "digraph G {\n");
	//Print node
	INT c;
	for (VERTEX const* v = m_vertexs.get_first(c); 
		 v != NULL; v = m_vertexs.get_next(c)) {
		fprintf(h, "\nnode%d [shape = Mrecord, label=\"{BB%d}\"];", 
				VERTEX_id(v), VERTEX_id(v));
	}

	//Print edge
	for (EDGE const* e = m_edges.get_first(c); 
		 e != NULL; e = m_edges.get_next(c)) {
		fprintf(h, "\nnode%d->node%d[label=\"%s\"]",
					VERTEX_id(EDGE_from(e)), 
					VERTEX_id(EDGE_to(e)),
					""); 
	}
	fprintf(h, "\n}\n");
	fclose(h);
}
Beispiel #5
0
/*------------------------------------------------------------------------*/
static void grow_edge(GRAPH *g)
{
    EINDEX max, i, diff;
    MEM_POOL *m = GRAPH_m(g);

    if (GRAPH_emax(g) < 8)
        max = 16;
    else
        max = GRAPH_emax(g)*2;        /* set max to double current size */


    GR_ASSERT(max > GRAPH_emax(g), "grow_edge graph_emax >= max\n");
    GRAPH_e(g) = (EDGE*) MEM_POOL_Realloc(m,GRAPH_e(g), sizeof(EDGE)*GRAPH_emax(g),
                                          sizeof(EDGE)*max);
    /*  diff = max - GRAPH_emax(g); */
    /*  memset(&GRAPH_e_i(g,GRAPH_emax(g)), 0, sizeof(EDGE)*(diff));  */

    for (i = GRAPH_emax(g); i<max; ++i) {
        EDGE_nfrom(&GRAPH_e_i(g,i)) = i+1; /* set the linked list of free edges */
        EDGE_from(&GRAPH_e_i(g,i)) = INVALID_EINDEX; /* edge is not being used */
    }

    /* last free vertex points to no entry */
    EDGE_nfrom(&GRAPH_e_i(g, max-1)) = INVALID_EINDEX;

    GRAPH_efree(g) = GRAPH_emax(g); /* free edges = total added edges */
    GRAPH_emax(g) = max;            /* max edges = new maximum */
}
Beispiel #6
0
/*------------------------------------------------------------------------*/
GRAPH* build_graph_u(VINDEX vertex_size, EINDEX edge_size, MEM_POOL* m)
{
    GRAPH *g;
    int i;


    GR_ASSERT(vertex_size >= 0, "build_graph_u vertex_size < 0\n");
    GR_ASSERT(edge_size >= 0, "build_graph_u edge_size < 0\n");

    g = (GRAPH*) MEM_POOL_Alloc(m, sizeof(GRAPH));
    GR_ASSERT (g != 0, "build_graph_u g == 0\n");
    memset(g, 0, sizeof(GRAPH));

    if (vertex_size != 0)    /* build the vertices */
    {
        GRAPH_v(g) = (VERTEX*) MEM_POOL_Alloc(m, sizeof(VERTEX)*vertex_size);
        GR_ASSERT (GRAPH_v(g) != 0, "build_graph_u graph_v(g) == 0\n");
        memset(GRAPH_v(g), 0, sizeof(VERTEX)*vertex_size);
    }

    if (edge_size != 0)      /* build the edges    */
    {
        GRAPH_e(g) = (EDGE*) MEM_POOL_Alloc(m, sizeof(EDGE)*edge_size);
        GR_ASSERT (GRAPH_e(g) != 0, "build_graph_u graph_e(g) == 0\n");
        memset(GRAPH_e(g), 0, sizeof(EDGE)*edge_size);
    }

    /*----------------------------set up the vertices-------------------------*/
    GRAPH_vcnt(g) = 0;               /* used vertices   */

    for (i = 0; i<vertex_size; ++i)
    {
        VERTEX_from(&GRAPH_v_i(g,i)) = i+1; /* set the linked list of free vertices */
        VERTEX_fcnt(&GRAPH_v_i(g,i)) = -1;  /* node is not being used               */
    }

    /* last free vertex points to no entry  */
    VERTEX_from(&GRAPH_v_i(g,vertex_size-1)) = INVALID_VINDEX;
    GRAPH_vfree(g) = 0;              /* free vertices = total added vertices */
    GRAPH_vmax(g)  = vertex_size;    /* max vertices = new maximum           */


    /*----------------------------set up the edges----------------------------*/
    GRAPH_ecnt(g) = 0;               /* used edges      */
    for (i = 0; i<edge_size; ++i)
    {
        EDGE_nfrom(&GRAPH_e_i(g,i)) = i+1; /* set the linked list of free edges */
        EDGE_from(&GRAPH_e_i(g,i)) = INVALID_VINDEX; /* edge is not being used */
    }

    /* last free edge points to no entry */
    EDGE_nfrom(&GRAPH_e_i(g, edge_size-1)) = -1;
    GRAPH_efree(g) = 0;    /* free edges      */
    GRAPH_emax(g) = edge_size;     /* total edges     */


    GRAPH_root(g) = INVALID_VINDEX; /* no root         */
    GRAPH_m(g) = m;
    return g;
}
Beispiel #7
0
/*---------------------------------------------------------------*/
VINDEX  next_v_preds(V_ITER *v_i)
{
    EINDEX e;
    VINDEX from;

    /* get the next to edge */
    if(V_ITER_nto(v_i) == -1)
    {

        MEM_POOL_FREE(V_ITER_m(v_i),v_i);

        return INVALID_VINDEX;
    }

    /* get the next to edge */
    e = V_ITER_nto(v_i);

    /* return it's from vertex */
    from = EDGE_from(&GRAPH_e_i(V_ITER_g(v_i), e));
    V_ITER_nto(v_i) = EDGE_nto(&GRAPH_e_i(V_ITER_g(v_i),e));

    /* store the current edge */
    V_ITER_c_e(v_i) = e;
    return from;
}
Beispiel #8
0
//
//START EDGE_HASH
//
EDGE * EDGE_HASH::create(ULONG v)
{
	EDGE * t = (EDGE*)v;
	VERTEX * from = m_g->get_vertex(VERTEX_id(EDGE_from(t)));
	VERTEX * to = m_g->get_vertex(VERTEX_id(EDGE_to(t)));
	IS_TRUE0(from && to);
	t = m_g->new_edge_c(from, to);
	return t;
}
Beispiel #9
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;
}
Beispiel #10
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);
	}
}
Beispiel #11
0
/*----------------------------------------------------------------------*/
EINDEX add_edge(GRAPH *g, VINDEX from, VINDEX to, void *user)
{
    EINDEX new_edge, e2;
    MEM_POOL *m = GRAPH_m(g);

    GR_ASSERT(is_vertex(g,from), "add_edge is_vertex(g, from\n");
    GR_ASSERT(is_vertex(g,from), "add_edge is_vertex(g, to\n");

    /* are there any free edges? */
    if(GRAPH_efree(g) == -1)

        /* grow the edge list if no free edges */
        grow_edge(g);

    /* get a free edge */
    new_edge = GRAPH_efree(g);

    /* reset the free edge pointer */
    GRAPH_efree(g)=  EDGE_nfrom(&GRAPH_e_i(g,new_edge));

    /* store the user information  */
    EDGE_user(&GRAPH_e_i(g,new_edge)) = user;

    /* from vertex is = from       */
    EDGE_from(&GRAPH_e_i(g,new_edge)) = from;

    /* to vertex is = to           */
    EDGE_to(&GRAPH_e_i(g,new_edge)) = to;

    /* incr. from count for from vertex */
    VERTEX_fcnt(&GRAPH_v_i(g,from))++;

    /* incr. to count for to vertex */
    VERTEX_tcnt(&GRAPH_v_i(g,to))++;

    /* incr. total used edge count  */
    GRAPH_ecnt(g)++;

    /* set up the list of from edges for the from vertex */
    e2 =  VERTEX_from(&GRAPH_v_i(g,from));
    EDGE_nfrom(&GRAPH_e_i(g,new_edge)) = e2;
    VERTEX_from(&GRAPH_v_i(g,from)) = new_edge;

    /* set up the list of to edges for the to vertex */
    e2 = VERTEX_to(&GRAPH_v_i(g,to));
    EDGE_nto(&GRAPH_e_i(g,new_edge)) = e2;
    VERTEX_to(&GRAPH_v_i(g,to)) = new_edge;

    /* set the recursive edge field to be zero */
    EDGE_etype(&GRAPH_e_i(g,new_edge)) = 0;

    return new_edge;
}
Beispiel #12
0
EDGE * GRAPH::new_edge_c(VERTEX * from, VERTEX * to)
{
	EDGE * e = m_e_free_list.get_free_elem();
	if (e == NULL) {
		e = (EDGE*)_xmalloc(sizeof(EDGE));
	}
	EDGE_from(e) = from;
	EDGE_to(e) = to;
	add_in_list(to, e);
	add_out_list(from, e);
	return e;	
}
Beispiel #13
0
//Reverse edge direction
EDGE * GRAPH::rev_edge(EDGE * e)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	IS_TRUE(m_is_direction, ("graph is indirection"));
	void * einfo = EDGE_info(e);
	VERTEX * from = EDGE_from(e);
	VERTEX * to = EDGE_to(e);
	remove_edge(e);
	e = add_edge(VERTEX_id(to), VERTEX_id(from));
	EDGE_info(e) = einfo;
	return e;
}
Beispiel #14
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;
	}
}
Beispiel #15
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;
}
Beispiel #16
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);
}
Beispiel #17
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);
}
Beispiel #18
0
bool GRAPH::clone(GRAPH & src)
{
	erasure();
	m_is_unique = src.m_is_unique; 
	m_is_direction = src.m_is_direction; 

	//Clone vertexs
	INT c;
	for (VERTEX * srcv = src.get_first_vertex(c); 
		 srcv != NULL; srcv = src.get_next_vertex(c)) {
		VERTEX * v = add_vertex(VERTEX_id(srcv));

		/*
		Calls inherited class method.
		Vertex info of memory should allocated by inherited class method
		*/
		if (VERTEX_info(srcv) != NULL) {
			VERTEX_info(v) = clone_vertex_info(srcv);
		}
	}

	//Clone edges
	for (EDGE * srce = src.get_first_edge(c); 
		 srce != NULL; srce = src.get_next_edge(c)) {
		EDGE * e = add_edge(VERTEX_id(EDGE_from(srce)), 
							VERTEX_id(EDGE_to(srce)));

		/*Calls inherited class method.
		 *Edge info of memory should allocated by inherited class method
		 * */
		if (EDGE_info(srce) != NULL) {
			EDGE_info(e) = clone_edge_info(srce);
		}
	}
	return true;
}
Beispiel #19
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;
}
Beispiel #20
0
/*---------------------------------------------------------------------*/
BOOL is_edge(GRAPH *g, EINDEX edge)
{
    return ( ( edge < GRAPH_emax(g) )
             && EDGE_from(&GRAPH_e_i(g,edge)) != INVALID_VINDEX );
}
Beispiel #21
0
/*---------------------------------------------------------------------*/
void delete_edge(GRAPH *g, EINDEX edge)
{

    VINDEX from_vertex, to_vertex;
    EINDEX next_edge, head_edge;

    GR_ASSERT(is_edge(g, edge), "delete_edge is_edge\n");

    /* update the information for the from vertex */
    /* get the from vertex */
    from_vertex =  EDGE_from(&GRAPH_e_i(g,edge));

    /* decrement from count */
    VERTEX_fcnt(&GRAPH_v_i(g,from_vertex))--;

    /* get the next edge in linked list */
    next_edge = EDGE_nfrom(&GRAPH_e_i(g,edge));

    /* get the first edge in linked list */
    head_edge = VERTEX_from(&GRAPH_v_i(g,from_vertex));

    /* if the head is set to edge */
    if (head_edge == edge)

        /* set it to next from edge */
        VERTEX_from(&GRAPH_v_i(g,from_vertex)) = next_edge;

    /* else walk the list of edges */
    else
    {
        /* unlink the edge from listofedges */
        while (EDGE_nfrom(&GRAPH_e_i(g,head_edge)) != edge)
            head_edge = EDGE_nfrom(&GRAPH_e_i(g,head_edge));
        EDGE_nfrom(&GRAPH_e_i(g,head_edge)) = next_edge;
    }

    /*---- update the information for the to vertex ----*/

    /* get the to vertex */
    to_vertex =  EDGE_to(&GRAPH_e_i(g,edge));

    /* decrement to count */
    VERTEX_tcnt(&GRAPH_v_i(g,to_vertex))--;

    /* get the next edge in linked list */
    next_edge = EDGE_nto(&GRAPH_e_i(g,edge));

    /* get the first edge in linked list */
    head_edge = VERTEX_to(&GRAPH_v_i(g,to_vertex));

    /* if head is set to edge */
    if (head_edge == edge)
        /* set it to next to edge */
        VERTEX_to(&GRAPH_v_i(g,to_vertex)) = next_edge;

    else
        /* else walk the list of edges */
    {
        /* unlink the edge from the list of to edges */
        while (g->e[head_edge].nto != edge)
            head_edge = EDGE_nto(&GRAPH_e_i(g,head_edge));
        EDGE_nto(&GRAPH_e_i(g,head_edge)) = next_edge;
    }

    /* add the free edge to the linked list of free edges */
    EDGE_nfrom(&GRAPH_e_i(g,edge)) = GRAPH_efree(g);
    EDGE_from(&GRAPH_e_i(g,edge)) = INVALID_VINDEX;
    GRAPH_efree(g) = edge;
    GRAPH_ecnt(g)--;                            /* decrement edge count */
}
Beispiel #22
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();
}
Beispiel #23
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;
}
Beispiel #24
0
void GRAPH::dump_vcg(CHAR const* name)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (name == NULL) {
		name = "graph.vcg";
	}
	unlink(name);
	FILE * h = fopen(name, "a+");
	IS_TRUE(h, ("%s create failed!!!",name));
	fprintf(h, "graph: {"
			  "title: \"GRAPH\"\n"
			  "shrink:  15\n"
			  "stretch: 27\n"
			  "layout_downfactor: 1\n"
			  "layout_upfactor: 1\n"
			  "layout_nearfactor: 1\n"
			  "layout_splinefactor: 70\n"
			  "spreadlevel: 1\n"
			  "treefactor: 0.500000\n"
			  "node_alignment: center\n"
			  "orientation: top_to_bottom\n"
			  "late_edge_labels: no\n"
			  "display_edge_labels: yes\n"
			  "dirty_edge_labels: no\n"
			  "finetuning: no\n"
			  "nearedges: no\n"
			  "splines: yes\n"
			  "ignoresingles: no\n"
			  "straight_phase: no\n"
			  "priority_phase: no\n"
			  "manhatten_edges: no\n"
			  "smanhatten_edges: no\n"
			  "port_sharing: no\n"
			  "crossingphase2: yes\n"
			  "crossingoptimization: yes\n"
			  "crossingweight: bary\n"
			  "arrow_mode: free\n"
			  "layoutalgorithm: mindepthslow\n"
			  "node.borderwidth: 2\n" 
			  "node.color: lightcyan\n"
			  "node.textcolor: black\n"
			  "node.bordercolor: blue\n" 
			  "edge.color: darkgreen\n");

	//Print node
	INT c;
	for (VERTEX const* v = m_vertexs.get_first(c); 
		 v != NULL; v = m_vertexs.get_next(c)) {
		fprintf(h, "\nnode: { title:\"%d\" label:\"%d\" "
				"shape:circle fontname:\"courB\" color:gold}",
				VERTEX_id(v), VERTEX_id(v));
	}

	//Print edge
	for (EDGE const* e = m_edges.get_first(c); 
		 e != NULL; e = m_edges.get_next(c)) {
		fprintf(h, "\nedge: { sourcename:\"%d\" targetname:\"%d\" %s}",
				VERTEX_id(EDGE_from(e)), 
				VERTEX_id(EDGE_to(e)), 
				m_is_direction ? "" : "arrowstyle:none" );
	}
	fprintf(h, "\n}\n");
	fclose(h);
}
Beispiel #25
0
/*
Remove transitive edge.
e.g: Given edges of G, there are v1->v2->v3, v1->v3, then v1->v3 named
transitive edge.

Algo: 
	INPUT: Graph with N edges.
	1. Sort vertices in topological order.
	2. Associate each edges with indicator respective, 
	   and recording them in one matrix(N*N) 	   
		e.g: e1:v0->v2, e2:v1->v2, e3:v0->v1
			  0   1    2
			0 --  e3   e1 
			1 --  --   e2
			2 --  --   --

	3. Scan vertices according to toplogical order, 
	   remove all edges which the target-node has been 
	   marked at else rows.
		e.g: There are dependence edges: v0->v1, v0->v2.
		 If v1->v2 has been marked, we said v0->v2 is removable, 
		 and the same goes for the rest of edges.
*/
void GRAPH::remove_transitive_edge()
{
	BITSET_MGR bs_mgr;
	SVECTOR<UINT> vex_vec;
	sort_in_toplog_order(vex_vec, true);
	SVECTOR<UINT> vid2pos_in_bitset_map; //Map from VERTEX-ID to BITSET.
	INT i;

	//Mapping vertex id to its position in 'vex_vec'.
	for (i = 0; i <= vex_vec.get_last_idx(); i++) {
		vid2pos_in_bitset_map.set(vex_vec.get(i), i); 
	}

	//Associate each edges with indicator respective.
	UINT vex_num = get_vertex_num();
	SVECTOR<BITSET*> edge_indicator; //container of bitset.
	INT c;
	for (EDGE * e = m_edges.get_first(c); e != NULL; e = m_edges.get_next(c)) {
		UINT from = VERTEX_id(EDGE_from(e));
		UINT to = VERTEX_id(EDGE_to(e));
	
		UINT frompos = vid2pos_in_bitset_map.get(from);
		BITSET * bs = edge_indicator.get(frompos);
		if (bs == NULL) {
			bs = bs_mgr.create();
			edge_indicator.set(frompos, bs);
		}
		
		//Each from-vertex is associated with 
		//a bitset to record all to-vertices.
		bs->bunion(vid2pos_in_bitset_map.get(to));
	} //end for each of edge
	
	//Scanning vertexs in topological order.
	for (i = 0; i < vex_vec.get_last_idx(); i++) {
		//Get the successor vector.
		BITSET * bs = edge_indicator.get(i); 
		if (bs != NULL && bs->get_elem_count() >= 2) {
			//Do NOT remove the first edge. Position in bitset 
			//has been sorted in topological order.
			for (INT pos_i = bs->get_first(); pos_i >= 0; 
				 pos_i = bs->get_next(pos_i)) {
				INT kid_from_vid = vex_vec.get(pos_i);
				INT kid_from_pos = vid2pos_in_bitset_map.get(kid_from_vid);

				//Get bitset that 'pos_i' associated.
				BITSET * kid_from_bs = edge_indicator.get(kid_from_pos);
				if (kid_from_bs != NULL) {
					for (INT pos_j = bs->get_next(pos_i); pos_j >= 0; 
						 pos_j = bs->get_next(pos_j)) {
						if (kid_from_bs->is_contain(pos_j)) {
							//The edge 'i->pos_j' is redundant.
							INT to_vid = vex_vec.get(pos_j);
							UINT src_vid = vex_vec.get(i);
							remove_edge(get_edge(src_vid, to_vid));
							bs->diff(pos_j);
						}
					}
				} //end if
			} //end for
		} //end if
	} //end for each vertex
}