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; }
ABS_NODE * CFS_MGR::construct_abs_tree( IN IR_BB * entry, IN ABS_NODE * parent, IN BITSET * cur_region, IN GRAPH & cur_graph, IN OUT BITSET & visited) { IR_CFG * cfg = m_ru->get_cfg(); ABS_NODE * lst = NULL; IR_BB * bb = entry; GRAPH g; g.clone(cur_graph); VERTEX * next = NULL; VERTEX * v; if (cur_region != NULL) { if (cur_region->get_elem_count() == 0) { visited.clean(); return NULL; } INT c; for (v = g.get_first_vertex(c); v != NULL; v = next) { next = g.get_next_vertex(c); if (cur_region->is_contain(VERTEX_id(v))) { continue; } g.remove_vertex(v); } } BITSET loc_visited; while (bb != NULL && (cur_region == NULL || cur_region->is_contain(IR_BB_id(bb)))) { ABS_NODE * node = NULL; loc_visited.clean(); LI<IR_BB> * li = cfg->map_bb2li(bb); if (li != NULL) { node = construct_abs_loop(bb, parent, LI_bb_set(li), g, loc_visited); } else { IR * last_xr = cfg->get_last_xr(bb); if (last_xr != NULL && //'bb' is branching node of IF. last_xr->is_cond_br()) { IS_TRUE0(map_ir2cfsinfo(last_xr) != NULL); /* There might not exist ipdom. e.g: if (x) //BB1 return 1; return 2; BB1 does not have a ipdom. */ UINT ipdom = ((DGRAPH*)cfg)->get_ipdom(IR_BB_id(bb)); IS_TRUE(ipdom > 0, ("bb does not have ipdom")); node = construct_abs_if(bb, parent, g, loc_visited); } else { node = construct_abs_bb(bb, parent); loc_visited.bunion(IR_BB_id(bb)); } } insertbefore_one(&lst, lst, node); visited.bunion(loc_visited); //Remove visited vertex. next = NULL; INT c; for (v = g.get_first_vertex(c); v != NULL; v = next) { next = g.get_next_vertex(c); if (!loc_visited.is_contain(VERTEX_id(v))) { continue; } g.remove_vertex(v); } IR_BB * cand = NULL; for (v = g.get_first_vertex(c); v != NULL; v = g.get_next_vertex(c)) { if (g.get_in_degree(v) == 0) { IS_TRUE(cand == NULL, ("multiple immediate-post-dominators")); cand = cfg->get_bb(VERTEX_id(v)); } } if (cand == NULL) { //Cannot find leading BB, there might be exist cycle in graph. bb = cfg->get_ipdom(bb); } else { bb = cand; } if (parent != NULL && bb == ABS_NODE_bb(parent)) { //Here control-flow is cyclic. break; } } lst = reverse_list(lst); return lst; }