Beispiel #1
0
//'cur_region' covered 'entry'.
ABS_NODE * CFS_MGR::construct_abs_if(
						IN IR_BB * entry,
						IN ABS_NODE * parent,
						IN GRAPH & cur_graph,
						IN OUT BITSET & visited)
{
	ABS_NODE * node = new_abs_node(ABS_IF);
	set_map_bb2abs(entry, node);
	ABS_NODE_parent(node) = parent;
	ABS_NODE_if_head(node) = entry;

	IR_BB * true_body, * false_body;
	IR_CFG * cfg = m_ru->get_cfg();
	cfg->get_if_three_kids(entry, &true_body, &false_body, NULL);
	CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry));
	IS_TRUE0(ci != NULL && CFS_INFO_head(ci) == entry);

	BITSET loc_visited;
	ABS_NODE_true_body(node) = construct_abs_tree(true_body, node, CFS_INFO_true_body(ci), cur_graph, loc_visited);
	visited.bunion(loc_visited);
	loc_visited.clean();
	ABS_NODE_false_body(node) = construct_abs_tree(false_body, node, CFS_INFO_false_body(ci), cur_graph, loc_visited);
	visited.bunion(loc_visited);
	visited.bunion(IR_BB_id(entry));
	return node;
}
Beispiel #2
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;
}
Beispiel #3
0
//'cur_region' covered 'entry'.
AbsNode * CfsMgr::constructAbsIf(
        IN IRBB * entry,
        IN AbsNode * parent,
        IN Graph & cur_graph,
        IN OUT BitSet & visited)
{
    AbsNode * node = new_abs_node(ABS_IF);
    set_map_bb2abs(entry, node);
    ABS_NODE_parent(node) = parent;
    ABS_NODE_if_head(node) = entry;

    IRBB * true_body, * false_body;
    IR_CFG * cfg = m_ru->getCFG();
    cfg->getKidOfIF(entry, &true_body, &false_body, NULL);
    CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry));
    ASSERT0(ci != NULL && CFS_INFO_head(ci) == entry);

    BitSet loc_visited;
    ABS_NODE_true_body(node) = constructAbsTree(true_body, node,
        CFS_INFO_true_body(ci), cur_graph, loc_visited);
    visited.bunion(loc_visited);
    loc_visited.clean();
    ABS_NODE_false_body(node) = constructAbsTree(false_body, node,
        CFS_INFO_false_body(ci), cur_graph, loc_visited);
    visited.bunion(loc_visited);
    visited.bunion(BB_id(entry));
    return node;
}
Beispiel #4
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;
}
Beispiel #5
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;
}
Beispiel #6
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;
}