예제 #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::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));
}
예제 #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
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;
}
예제 #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
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);
}
예제 #7
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);
		}
	}
}
예제 #8
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);
		}
	}	
}
예제 #9
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);
        }
    }
}
예제 #10
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;
}
예제 #11
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);
    }
}
예제 #12
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;
}
예제 #13
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);
	}
}
예제 #14
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;
}
예제 #15
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;
}
예제 #16
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;	
}
예제 #17
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;
}
예제 #18
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;
}
예제 #19
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);
	}
}
예제 #20
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;
}
예제 #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
파일: 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;
}
예제 #23
0
/*---------------------------------------------------------------*/
void* get_edge(GRAPH *g, VINDEX from, VINDEX to)
{
    EINDEX e;


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

    e = VERTEX_from(&GRAPH_v_i(g, from));

    while ( e != INVALID_EINDEX ) {
        if(EDGE_to(&GRAPH_e_i(g,e)) == to)
            break;
        e = (EDGE_nfrom(&GRAPH_e_i(g,e)));
    }
    return EDGE_user(&GRAPH_e_i(g,e));
}
예제 #24
0
/*---------------------------------------------------------------*/
int
edge_count(GRAPH* g, VINDEX from, VINDEX to)
{
    int count= 0;
    EINDEX e;

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

    e = VERTEX_from(&GRAPH_v_i(g, from));

    while ( e != INVALID_EINDEX ) {
        if(EDGE_to(&GRAPH_e_i(g,e)) == to)
            ++count;
        e = (EDGE_nfrom(&GRAPH_e_i(g,e)));
    }
    return count;
}
예제 #25
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);
		}
	}
}
예제 #26
0
/*---------------------------------------------------------------*/
VINDEX first_v_succs(V_ITER *v_i)
{
    EINDEX e;
    VINDEX to;

    /* get the first from edge */
    if ( V_ITER_from_e(v_i) == INVALID_EINDEX )
    {
        MEM_POOL_FREE(V_ITER_m(v_i),v_i);
        return INVALID_VINDEX;
    }

    /* return it's to vertex */
    e =  V_ITER_from_e(v_i);
    to = EDGE_to(&GRAPH_e_i(V_ITER_g(v_i),e));
    V_ITER_nfrom(v_i) =  EDGE_nfrom(&GRAPH_e_i(V_ITER_g(v_i),e));

    /* store the current edge */
    V_ITER_c_e(v_i) = e;
    return to;
}
예제 #27
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);
        }
    }
}
예제 #28
0
/*---------------------------------------------------------------*/
VINDEX next_v_succs(V_ITER *v_i)
{
    EINDEX ei;
    VINDEX to;

    /* get the next from edge */
    if(V_ITER_nfrom(v_i) == -1)
    {
        MEM_POOL_FREE(V_ITER_m(v_i),v_i);

        return INVALID_VINDEX;
    }

    /* return it's to vertex */
    ei = V_ITER_nfrom(v_i);
    to = EDGE_to(&GRAPH_e_i(V_ITER_g(v_i), ei));
    V_ITER_nfrom(v_i) = EDGE_nfrom(&GRAPH_e_i(V_ITER_g(v_i),ei));

    /* store the current edge */
    V_ITER_c_e(v_i) = ei;
    return to;
}
예제 #29
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;
}
예제 #30
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;
}