/**
 * Place operands of node into an address mode.
 *
 * @param addr    the address mode data so far
 * @param node    the node
 * @param flags   the flags
 *
 * @return the folded node
 */
static ir_node *eat_immediates(x86_address_t *addr, ir_node *node,
                               x86_create_am_flags_t flags,
                               bool basereg_usable)
{
	if (!(flags & x86_create_am_force)
	    && x86_is_non_address_mode_node(node)
	    && (!(flags & x86_create_am_double_use) || get_irn_n_edges(node) > 2))
		return node;

	if (is_Add(node)) {
		ir_node *left  = get_Add_left(node);
		ir_node *right = get_Add_right(node);
		if (eat_immediate(addr, left, basereg_usable))
			return eat_immediates(addr, right, x86_create_am_normal,
			                      basereg_usable);
		if (eat_immediate(addr, right, basereg_usable))
			return eat_immediates(addr, left, x86_create_am_normal,
			                      basereg_usable);
	} else if (is_Member(node)) {
		assert(addr->imm.entity == NULL);
		addr->imm.entity = get_Member_entity(node);
		addr->imm.kind   = X86_IMM_FRAMEENT;
		ir_node *ptr = get_Member_ptr(node);
		assert(is_Start(get_Proj_pred(ptr)));
		return ptr;
	}

	return node;
}
Exemple #2
0
/**
 * Pre-Walker: Copies blocks and nodes from the original method graph
 * to the copied graph.
 *
 * @param n    A node from the original method graph.
 * @param env  The copied graph.
 */
static void copy_all_nodes(ir_node *node, void *env)
{
	ir_graph *irg      = (ir_graph*)env;
	ir_node  *new_node = irn_copy_into_irg(node, irg);

	set_irn_link(node, new_node);

	/* fix access to entities on the stack frame */
	if (is_Member(new_node)) {
		ir_entity *ent = get_Member_entity(new_node);
		ir_type   *tp  = get_entity_owner(ent);

		if (is_frame_type(tp)) {
			/* replace by the copied entity */
			ent = (ir_entity*)get_entity_link(ent);

			assert(is_entity(ent));
			assert(get_entity_owner(ent) == get_irg_frame_type(irg));
			set_Member_entity(new_node, ent);
		}
	}
}
Exemple #3
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_Member: {
		ir_graph *const old_irg = get_irn_irg(n);
		ir_node  *const old_ptr = get_Member_ptr(n);
		if (old_ptr == get_irg_frame(old_irg)) {
			dbg_info  *const dbgi  = get_irn_dbg_info(n);
			ir_node   *const block = get_irg_start_block(irg);
			ir_entity *const ent   = get_entity_link(get_Member_entity(n));
			nn = new_rd_Member(dbgi, block, old_ptr, ent);
		}
		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);
}