/** * 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; }
/** * 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); }