Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/* Find preheader BB. If it does not exist, insert one before loop 'li'.

'insert_bb': return true if this function insert a new bb before loop,
	otherwise return false.

'force': force to insert preheader BB whatever it has exist.
	Return the new BB if insertion is successful.

Note if we find the preheader, the last IR of it may be call.
So if you are going to insert IR at the tail of preheader, the best is
force to insert a new bb. */
IR_BB * find_and_insert_prehead(LI<IR_BB> const* li, REGION * ru,
								OUT bool & insert_bb,
								bool force)
{
	IS_TRUE0(li && ru);
	insert_bb = false;
	IR_CFG * cfg = ru->get_cfg();
	IR_BB_LIST * bblst = ru->get_bb_list();
	IR_BB * head = LI_loop_head(li);

	C<IR_BB*> * bbholder = NULL;
	bblst->find(head, &bbholder);
	IS_TRUE0(bbholder);
	C<IR_BB*> * tt = bbholder;
	IR_BB * prev = bblst->get_prev(&tt);

	//Find appropriate BB to be prehead.
	bool find_appropriate_prev_bb = false;
	EDGE_C const* ec = VERTEX_in_list(cfg->get_vertex(IR_BB_id(head)));
	while (ec != NULL) {
		UINT pred = VERTEX_id(EDGE_from(EC_edge(ec)));
		if (pred == IR_BB_id(prev)) {
			find_appropriate_prev_bb = true;
			break;
		}
		ec = EC_next(ec);
	}

	if (!force && find_appropriate_prev_bb) { return prev; }

	LIST<IR_BB*> preds;
	cfg->get_preds(preds, head);
	insert_bb = true;
	IR_BB * newbb = ru->new_bb();
	bblst->insert_before(newbb, bbholder);
	BITSET * loop_body = LI_bb_set(li);
	for (IR_BB * p = preds.get_head(); p != NULL; p = preds.get_next()) {
		if (loop_body->is_contain(IR_BB_id(p))) {
			continue;
		}
		cfg->add_bb(newbb);
		cfg->insert_vertex_between(IR_BB_id(p), IR_BB_id(head),
								   IR_BB_id(newbb));
		IR_BB_is_fallthrough(newbb) = 1;
	}
	return newbb;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}