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