Example #1
0
ir_graph *create_irg_copy(ir_graph *irg)
{
	ir_graph *res = alloc_graph();

	res->irg_pinned_state = irg->irg_pinned_state;

	/* clone the frame type here for safety */
	irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK);
	res->frame_type  = clone_frame_type(irg->frame_type);

	ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);

	/* copy all nodes from the graph irg to the new graph res */
	irg_walk_anchors(irg, copy_all_nodes, rewire, res);

	/* copy the Anchor node */
	res->anchor = get_new_node(irg->anchor);

	/* -- The end block -- */
	set_irg_end_block (res, get_new_node(get_irg_end_block(irg)));
	set_irg_end       (res, get_new_node(get_irg_end(irg)));

	/* -- The start block -- */
	set_irg_start_block(res, get_new_node(get_irg_start_block(irg)));
	set_irg_no_mem     (res, get_new_node(get_irg_no_mem(irg)));
	set_irg_start      (res, get_new_node(get_irg_start(irg)));

	/* Proj results of start node */
	set_irg_initial_mem(res, get_new_node(get_irg_initial_mem(irg)));

	ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
	irp_free_resources(irp, IRP_RESOURCE_ENTITY_LINK);

	return res;
}
Example #2
0
/**
 * Copies a node to a new irg. The Ins of the new node point to
 * the predecessors on the old irg.  n->link points to the new node.
 *
 * @param n    The node to be copied
 * @param irg  the new irg
 *
 * Does NOT copy standard nodes like Start, End etc that are fixed
 * in an irg. Instead, the corresponding nodes of the new irg are returned.
 * Note further, that the new nodes have no block.
 */
static void copy_irn_to_irg(ir_node *n, ir_graph *irg)
{
    /* do not copy standard nodes */
    ir_node *nn = NULL;
    switch (get_irn_opcode(n)) {
    case iro_NoMem:
        nn = get_irg_no_mem(irg);
        break;

    case iro_Block: {
        ir_graph *old_irg = get_irn_irg(n);
        if (n == get_irg_start_block(old_irg))
            nn = get_irg_start_block(irg);
        else if (n == get_irg_end_block(old_irg))
            nn = get_irg_end_block(irg);
        break;
    }

    case iro_Start:
        nn = get_irg_start(irg);
        break;

    case iro_End:
        nn = get_irg_end(irg);
        break;

    case iro_Proj: {
        ir_graph *old_irg = get_irn_irg(n);
        if (n == get_irg_frame(old_irg))
            nn = get_irg_frame(irg);
        else if (n == get_irg_initial_mem(old_irg))
            nn = get_irg_initial_mem(irg);
        else if (n == get_irg_args(old_irg))
            nn = get_irg_args(irg);
        break;
    }
    }

    if (nn) {
        set_irn_link(n, nn);
        return;
    }

    nn = new_ir_node(get_irn_dbg_info(n),
                     irg,
                     NULL,            /* no block yet, will be set later */
                     get_irn_op(n),
                     get_irn_mode(n),
                     get_irn_arity(n),
                     get_irn_in(n));


    /* Copy the attributes.  These might point to additional data.  If this
       was allocated on the old obstack the pointers now are dangling.  This
       frees e.g. the memory of the graph_arr allocated in new_immBlock. */
    copy_node_attr(irg, n, nn);
    set_irn_link(n, nn);
}
Example #3
0
ir_node *be_get_Start_proj(ir_graph *const irg, arch_register_t const *const reg)
{
	ir_node *const start = get_irg_start(irg);
	/* do a naive linear search... */
	be_foreach_out(start, i) {
		arch_register_t const *const out_reg = arch_get_irn_register_out(start, i);
		if (out_reg == reg)
			return be_get_or_make_Proj_for_pn(start, i);
	}
Example #4
0
ir_node *be_get_start_proj(ir_graph *const irg, be_start_info_t *const info)
{
	if (!info->irn) {
		/* This is already the transformed start node. */
		ir_node                     *const start = get_irg_start(irg);
		arch_register_class_t const *const cls   = arch_get_irn_register_req_out(start, info->pos)->cls;
		info->irn = new_r_Proj(start, cls ? cls->mode : mode_M, info->pos);
	}
	return info->irn;
}
Example #5
0
static unsigned get_start_reg_index(ir_graph *irg, const arch_register_t *reg)
{
	/* do a naive linear search... */
	ir_node *start  = get_irg_start(irg);
	be_foreach_out(start, i) {
		arch_register_req_t const *const out_req
			= arch_get_irn_register_req_out(start, i);
		if (out_req->limited == NULL)
			continue;
		if (out_req->cls != reg->cls)
			continue;
		if (!rbitset_is_set(out_req->limited, reg->index))
			continue;
		return i;
	}
Example #6
0
	ir_node  *const incsp      = be_new_IncSP(sp_reg, block, sp, -frame_size,
	                                          true);
	set_irn_n(ret, n_arm_Return_sp, incsp);
	sched_add_before(ret, incsp);
}

static void introduce_prolog_epilog(ir_graph *irg)
{
	/* introduce epilog for every return node */
	foreach_irn_in(get_irg_end_block(irg), i, ret) {
		assert(is_arm_Return(ret));
		introduce_epilog(ret);
	}

	const arch_register_t *sp_reg     = &arm_registers[REG_SP];
	ir_node               *start      = get_irg_start(irg);
	ir_node               *block      = get_nodes_block(start);
	ir_node               *initial_sp = be_get_Start_proj(irg, sp_reg);
	ir_type               *frame_type = get_irg_frame_type(irg);
	unsigned               frame_size = get_type_size(frame_type);

	ir_node *const incsp = be_new_IncSP(sp_reg, block, initial_sp, frame_size,
	                                    false);
	edges_reroute_except(initial_sp, incsp, incsp);
	sched_add_after(start, incsp);
}


static void arm_determine_frameoffset(ir_node *node, int sp_offset)
{
	if (be_is_MemPerm(node)) {
Example #7
0
ir_node *be_get_Start_mem(ir_graph *const irg)
{
	ir_node *const start = get_irg_start(irg);
	return be_get_or_make_Proj_for_pn(start, 0);
}