コード例 #1
0
ファイル: cfs_mgr.cpp プロジェクト: Grainspring/xoc
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;
}
コード例 #2
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
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;
}
コード例 #3
0
ファイル: loop.cpp プロジェクト: Grainspring/xoc
/* 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;
}
コード例 #4
0
ファイル: cfs_mgr.cpp プロジェクト: Grainspring/xoc
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;
}
コード例 #5
0
ファイル: cfs_mgr.cpp プロジェクト: clear-wing/xoc
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;
}