AbsNode * CfsMgr::constructAbsLoop( IN IRBB * entry, IN AbsNode * parent, IN BitSet * cur_region, IN Graph & cur_graph, IN OUT BitSet & visited) { DUMMYUSE(cur_region); ASSERT0(cur_region == NULL || cur_region->is_contain(BB_id(entry))); IR_CFG * cfg = m_ru->getCFG(); LI<IRBB> * li = cfg->mapBB2LabelInfo(entry); ASSERT0(li != NULL && LI_loop_head(li) == entry); AbsNode * node = new_abs_node(ABS_LOOP); set_map_bb2abs(entry, node); ABS_NODE_parent(node) = parent; ABS_NODE_loop_head(node) = entry; IRBB * body_start; cfg->getKidOfLoop(entry, NULL, &body_start); ASSERT0(body_start != NULL); CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry)); CHECK_DUMMYUSE(ci); ASSERT0(CFS_INFO_head(ci) == entry); ASSERT0(CFS_INFO_loop_body(ci)->is_contain(*LI_bb_set(li))); BitSet loc_visited; ABS_NODE_loop_body(node) = constructAbsTree(body_start, node, LI_bb_set(li), cur_graph, loc_visited); visited.bunion(loc_visited); visited.bunion(BB_id(entry)); return node; }
AbsNode * CfsMgr::constructAbsTree( IN IRBB * entry, IN AbsNode * parent, IN BitSet * cur_region, IN Graph & cur_graph, IN OUT BitSet & visited) { IR_CFG * cfg = m_ru->getCFG(); AbsNode * lst = NULL; IRBB * 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.removeVertex(v); } } BitSet loc_visited; while (bb != NULL && (cur_region == NULL || cur_region->is_contain(BB_id(bb)))) { AbsNode * node = NULL; loc_visited.clean(); LI<IRBB> * li = cfg->mapBB2LabelInfo(bb); if (li != NULL) { node = constructAbsLoop(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->isConditionalBr()) { ASSERT0(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(BB_id(bb)); DUMMYUSE(ipdom); ASSERT(ipdom > 0, ("bb does not have ipdom")); node = constructAbsIf(bb, parent, g, loc_visited); } else { node = constructAbsBB(bb, parent); loc_visited.bunion(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.removeVertex(v); } IRBB * cand = NULL; for (v = g.get_first_vertex(c); v != NULL; v = g.get_next_vertex(c)) { if (g.get_in_degree(v) == 0) { ASSERT(cand == NULL, ("multiple immediate-post-dominators")); cand = cfg->getBB(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; }