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); }
void free_ir_graph(ir_graph *irg) { assert(irg->kind == k_ir_graph); remove_irp_irg(irg); confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE); free_irg_outs(irg); del_identities(irg); if (irg->ent) { set_entity_irg(irg->ent, NULL); /* not set in const code irg */ } free_End(get_irg_end(irg)); obstack_free(&irg->obst, NULL); if (irg->loc_descriptions) free(irg->loc_descriptions); irg->kind = k_BAD; free_graph(irg); }
void remove_tuples(ir_graph *irg) { bool changed = false; irg_walk_graph(irg, exchange_tuple_projs, NULL, &changed); /* remove Tuples only held by keep-alive edges */ ir_node *end = get_irg_end(irg); for (int i = get_End_n_keepalives(end); i-- > 0; ) { ir_node *irn = get_End_keepalive(end, i); if (is_Tuple(irn)) { remove_End_n(end, i); changed = true; } } confirm_irg_properties(irg, changed ? IR_GRAPH_PROPERTIES_CONTROL_FLOW | IR_GRAPH_PROPERTY_ONE_RETURN | IR_GRAPH_PROPERTY_MANY_RETURNS | IR_GRAPH_PROPERTY_NO_BADS : IR_GRAPH_PROPERTIES_ALL); add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_TUPLES); }
void Worklist::walk_topological(ir_graph* irg, std::function<void (ir_node*, void*)> walker, void* env) { inc_irg_visited(irg); walk_topo_helper(get_irg_end(irg), walker, env); }
void irg_walk_graph(ir_graph *irg, irg_walk_func *pre, irg_walk_func *post, void *env) { irg_walk(get_irg_end(irg), pre, post, env); }