Beispiel #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;
}
Beispiel #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;
}
Beispiel #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;
}
Beispiel #4
0
/* Find the bb that is the start of the unqiue backedge of loop.
   BB1: loop start bb
   BB2: body start bb
   BB3: goto loop start bb

   BB2 is the loop header fallthrough bb. */
bool find_loop_header_two_succ_bb(LI<IR_BB> const* li, IR_CFG * cfg,
								UINT * succ1, UINT * succ2)
{
	IS_TRUE0(li && cfg && succ1 && succ2);
	IR_BB * head = LI_loop_head(li);

	VERTEX * headvex = cfg->get_vertex(IR_BB_id(head));
	if (cfg->get_out_degree(headvex) != 2) {
		//Not natural loop.
		return false;
	}

	EDGE_C const* ec = VERTEX_out_list(headvex);
	IS_TRUE0(ec && EC_next(ec));

	*succ1 = VERTEX_id(EDGE_to(EC_edge(ec)));
	*succ2 = VERTEX_id(EDGE_to(EC_edge(EC_next(ec))));
	return true;
}
Beispiel #5
0
/* Find the bb that is the start of the unqiue backedge of loop.
   BB1: loop start bb
   BB2: body
   BB3: goto loop start bb

   BB3 is the backedge start bb. */
IR_BB * find_single_backedge_start_bb(LI<IR_BB> const* li, IR_CFG * cfg)
{
	IS_TRUE0(li && cfg);
	IR_BB * head = LI_loop_head(li);

	UINT backedgebbid = 0;
	UINT backedgecount = 0;
	EDGE_C const* ec = VERTEX_in_list(cfg->get_vertex(IR_BB_id(head)));
	while (ec != NULL) {
		backedgecount++;
		UINT pred = VERTEX_id(EDGE_from(EC_edge(ec)));
		if (li->inside_loop(pred)) {
			backedgebbid = pred;
		}
		ec = EC_next(ec);
	}
	IS_TRUE0(backedgebbid > 0 && cfg->get_bb(backedgebbid));
	if (backedgecount > 2) {
		//There are multiple backedges.
		return NULL;
	}
	return cfg->get_bb(backedgebbid);
}