/* Dump dom set, pdom set, idom, ipdom. 'dump_dom_tree': set to be true to dump dominate tree, and post dominate Tree. */ void DGRAPH::dump_dom(FILE * h, bool dump_dom_tree) { if (h == NULL) return; fprintf(h, "\n\n\n\n========= DUMP DOM/PDOM/IDOM/IPDOM ======="); INT c; for (VERTEX * v = m_vertexs.get_first(c); v != NULL; v = m_vertexs.get_next(c)) { INT vid = VERTEX_id(v); fprintf(h, "\nVERTEX(%d) dom: ", vid); BITSET * bs; if ((bs = m_dom_set.get(vid)) != NULL) { for (INT id = bs->get_first(); id != -1 ; id = bs->get_next(id)) { if (id != vid) { fprintf(h, "%d ", id); } } } fprintf(h, "\n pdom: "); if ((bs = m_pdom_set.get(vid)) != NULL) { for (INT id = bs->get_first(); id != -1; id = bs->get_next(id)) { if (id != vid) { fprintf(h, "%d ", id); } } } if (m_idom_set.get(vid) != 0) { fprintf(h, "\n idom: %d", m_idom_set.get(vid)); } else { fprintf(h, "\n"); } if (m_ipdom_set.get(vid) != 0) { fprintf(h, "\n ipdom: %d", m_ipdom_set.get(vid)); } else { fprintf(h, "\n"); } } //end for each vertexs fprintf(h, "\n"); fflush(h); if (dump_dom_tree) { GRAPH dom; get_dom_tree(dom); dom.dump_vcg("graph_dom_tree.vcg"); dom.erasure(); get_pdom_tree(dom); dom.dump_vcg("graph_pdom_tree.vcg"); } }
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(); }
/* 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 }
bool DGRAPH::compute_ipdom() { bool change = true; //Initialize ipdom-set for each BB. m_ipdom_set.clean(); //Processing in reverse-topological order. INT c; for (VERTEX * v = m_vertexs.get_last(c); v != NULL; v = m_vertexs.get_prev(c)) { INT cur_id = VERTEX_id(v); if (is_graph_exit(v)) { continue; } else if (m_pdom_set.get(cur_id)->get_elem_count() > 1) { BITSET * p = m_pdom_set.get(cur_id); IS_TRUE(p != NULL, ("should compute pdom first")); if (p->get_elem_count() == 1) { //There is no ipdom if 'pdom' set only contain itself. IS_TRUE0(m_ipdom_set.get(cur_id) == 0); continue; } p->diff(cur_id); #define TRICKY_METHOD #ifdef TRICKY_METHOD INT i; for (i = p->get_first(); i != -1; i = p->get_next(i)) { if (m_pdom_set.get(i)->is_equal(*p)) { IS_TRUE0(m_ipdom_set.get(cur_id) == 0); m_ipdom_set.set(cur_id, i); break; } } //IS_TRUE(i != -1, ("not find ipdom")); //Not find. #else /* //Then , we can find a node which is not //post-dominate any other elems reside in 'tmp'. for (INT i = tmp.get_first(); i != -1; i = tmp.get_next(i)) { for (INT j = tmp.get_first(); j != -1; j = tmp.get_next(j)) { if (i == j) { continue; } if (m_pdom_set.get(j)->is_contain(i)) { tmp.diff(i); i = tmp.get_first(); j = i; } //end if } //end for } //end for //There is only one elemment in 'tmp' IS_TRUE(tmp.get_elem_count() == 1, ("illegal in compute_ipdom")); INT i = tmp.get_first(); IS_TRUE(i != -1, ("cannot find ipdom of BB:%d", cur_id)); IS_TRUE(m_ipdom_set.get(cur_id) == 0, ("recompute ipdom for BB:%d", cur_id)); m_ipdom_set.set(cur_id, i); */ #endif p->bunion(cur_id); } //end else if } //end for return true; }
bool DGRAPH::compute_idom() { bool change = true; //Initialize idom-set for each BB. m_idom_set.clean(); //Access with topological order. INT c; for (VERTEX * v = m_vertexs.get_first(c); v != NULL; v = m_vertexs.get_next(c)) { INT cur_id = VERTEX_id(v); if (is_graph_entry(v)) { continue; } else if (m_dom_set.get(cur_id)->get_elem_count() >= 2) { BITSET * p = m_dom_set.get(cur_id); IS_TRUE(p != NULL, ("should compute dom first")); if (p->get_elem_count() == 1) { //There is no idom if 'dom' set only contain itself. IS_TRUE0(m_idom_set.get(cur_id) == 0); continue; } p->diff(cur_id); #define TRICKY_METHOD #ifdef TRICKY_METHOD INT i; for (i = p->get_first(); i != -1; i = p->get_next(i)) { if (m_dom_set.get(i)->is_equal(*p)) { IS_TRUE0(m_idom_set.get(cur_id) == 0); m_idom_set.set(cur_id, i); break; } } IS_TRUE(i != -1, ("not find idom?")); #else /* We can find a node that is not dominate any other elems in 'tmp'. INT i; for (i = tmp.get_first(); i != -1; i = tmp.get_next(i)) { for (INT j = tmp.get_first(); j != -1; j = tmp.get_next(j)) { if (i == j) { continue; } if (m_dom_set.get(j)->is_contain(i)) { tmp.diff(i); //Search 'tmp' over again. i = tmp.get_first(); j = i; } } } //There is only one elemment in 'tmp' i = tmp.get_first(); IS_TRUE(i != -1, ("cannot find idom of BB:%d", cur_id)); IS_TRUE(m_idom_set.get(cur_id) == 0, ("recompute idom for BB:%d", cur_id)); m_idom_set.set(cur_id, i); */ #endif p->bunion(cur_id); } //end else if } //end for return true; }