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; }
/* * Optimize the frame type of an irg by removing * never touched entities. */ void opt_frame_irg(ir_graph *irg) { ir_type *frame_tp = get_irg_frame_type(irg); ir_entity *ent, *list; ir_node *frame, *sel; size_t i, n = get_class_n_members(frame_tp); int o; if (n <= 0) return; assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK); /* clear all entity links */ for (i = n; i > 0;) { ent = get_class_member(frame_tp, --i); set_entity_link(ent, NULL); } /* look for uses */ frame = get_irg_frame(irg); /* mark all used entities */ for (o = get_irn_n_outs(frame) - 1; o >= 0; --o) { sel = get_irn_out(frame, o); if (is_Sel(sel)) { ent = get_Sel_entity(sel); /* only entities on the frame */ if (get_entity_owner(ent) == frame_tp) set_entity_link(ent, ent); } } /* link unused ones */ list = NULL; for (i = n; i > 0;) { ent = get_class_member(frame_tp, --i); /* beware of inner functions: those are NOT unused */ if (get_entity_link(ent) == NULL && !is_method_entity(ent)) { set_entity_link(ent, list); list = ent; } } if (list != NULL) { /* delete list members */ for (ent = list; ent; ent = list) { list = (ir_entity*)get_entity_link(ent); free_entity(ent); } /* we changed the frame type, its layout should be redefined */ set_type_state(frame_tp, layout_undefined); } irp_free_resources(irp, IRP_RESOURCE_ENTITY_LINK); /* we changed the type, this affects none of the currently known graph * properties, but I don't use ALL because I don't know if someone adds * type-based properties at some point */ confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW | IR_GRAPH_PROPERTY_NO_BADS | IR_GRAPH_PROPERTY_NO_TUPLES | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES | IR_GRAPH_PROPERTY_CONSISTENT_OUTS | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE | IR_GRAPH_PROPERTY_MANY_RETURNS); }