ABS_NODE * CFS_MGR::construct_abs_loop( IN IR_BB * entry, IN ABS_NODE * parent, IN BITSET * cur_region, IN GRAPH & cur_graph, IN OUT BITSET & visited) { IS_TRUE0(cur_region == NULL || cur_region->is_contain(IR_BB_id(entry))); IR_CFG * cfg = m_ru->get_cfg(); LI<IR_BB> * li = cfg->map_bb2li(entry); IS_TRUE0(li != NULL && LI_loop_head(li) == entry); ABS_NODE * node = new_abs_node(ABS_LOOP); set_map_bb2abs(entry, node); ABS_NODE_parent(node) = parent; ABS_NODE_loop_head(node) = entry; IR_BB * body_start; cfg->get_loop_two_kids(entry, NULL, &body_start); IS_TRUE0(body_start != NULL); CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry)); IS_TRUE0(ci != NULL && CFS_INFO_head(ci) == entry); IS_TRUE0(CFS_INFO_loop_body(ci)->is_contain(*LI_bb_set(li))); BITSET loc_visited; ABS_NODE_loop_body(node) = construct_abs_tree(body_start, node, LI_bb_set(li), cur_graph, loc_visited); visited.bunion(loc_visited); visited.bunion(IR_BB_id(entry)); return node; }
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; }