2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Entry point to the representation of procedure code.
23 * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
39 #include "irgraph_t.h"
41 #include "irgraph_t.h"
51 #include "irbackedge_t.h"
52 #include "iredges_t.h"
56 #define INITIAL_IDX_IRN_MAP_SIZE 1024
59 * Indicates, whether additional data can be registered to graphs.
60 * If set to 1, this is not possible anymore.
62 static int forbid_new_data = 0;
65 * The amount of additional space for custom data to be allocated upon
66 * creating a new graph.
68 static size_t additional_graph_data_size = 0;
70 ir_graph *current_ir_graph;
71 ir_graph *get_current_ir_graph(void) {
72 return current_ir_graph;
75 void set_current_ir_graph(ir_graph *graph) {
76 current_ir_graph = graph;
79 #ifdef INTERPROCEDURAL_VIEW
80 int firm_interprocedural_view = 0;
82 int (get_interprocedural_view)(void) {
83 return _get_interprocedural_view();
86 void (set_interprocedural_view)(int state) {
87 firm_interprocedural_view = state;
89 /* set function vectors for faster access */
91 _get_irn_arity = _get_irn_inter_arity;
92 _get_irn_n = _get_irn_inter_n;
95 _get_irn_arity = _get_irn_intra_arity;
96 _get_irn_n = _get_irn_intra_n;
101 /** contains the suffix for frame type names */
102 static ident *frame_type_suffix = NULL;
104 /* initialize the IR graph module */
105 void firm_init_irgraph(void) {
106 frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
111 * Allocate a new IR graph.
112 * This function respects the registered graph data. The only reason for
113 * this function is, that there are two locations, where graphs are
114 * allocated (new_r_ir_graph, new_const_code_irg).
115 * @return Memory for a new graph.
117 static ir_graph *alloc_graph(void) {
119 size_t size = sizeof(ir_graph) + additional_graph_data_size;
120 char *ptr = xmalloc(size);
121 memset(ptr, 0, size);
123 res = (ir_graph *)(ptr + additional_graph_data_size);
124 res->kind = k_ir_graph;
126 /* initialize the idx->node map. */
127 res->idx_irn_map = NEW_ARR_F(ir_node *, INITIAL_IDX_IRN_MAP_SIZE);
128 memset(res->idx_irn_map, 0, INITIAL_IDX_IRN_MAP_SIZE * sizeof(res->idx_irn_map[0]));
134 * Frees an allocated IR graph
136 static void free_graph(ir_graph *irg) {
137 char *ptr = (char *)irg;
138 free(ptr - additional_graph_data_size);
141 #if USE_EXPLICIT_PHI_IN_STACK
142 /* really defined in ircons.c */
143 typedef struct Phi_in_stack Phi_in_stack;
144 Phi_in_stack *new_Phi_in_stack();
145 void free_Phi_in_stack(Phi_in_stack *s);
149 * Set the number of locals for a given graph.
151 * @param irg the graph
152 * @param n_loc number of locals
154 void irg_set_nloc(ir_graph *res, int n_loc) {
155 assert(res->phase_state == phase_building);
157 if (get_opt_precise_exc_context()) {
158 res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
159 dereferenced in this graph plus one for
160 the store plus one for links to fragile
161 operations. n_loc is not the number of
162 parameters to the procedure! */
164 res->n_loc = n_loc + 1; /* number of local variables that are never
165 dereferenced in this graph plus one for
166 the store. This is not the number of parameters
169 if (res->loc_descriptions) {
170 xfree(res->loc_descriptions);
171 res->loc_descriptions = NULL;
175 /* Allocates a list of nodes:
176 - The start block containing a start node and Proj nodes for it's four
177 results (X, M, P, Tuple).
178 - The end block containing an end node. This block is not matured after
179 new_ir_graph as predecessors need to be added to it.
180 - The current block, which is empty and also not matured.
181 Further it allocates several datastructures needed for graph construction
184 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
186 ir_node *first_block;
187 ir_node *end, *start, *start_block, *initial_mem, *projX;
191 /* inform statistics here, as blocks will be already build on this graph */
192 hook_new_graph(res, ent);
194 current_ir_graph = res;
196 /*-- initialized for each graph. --*/
197 res->kind = k_ir_graph;
198 res->obst = xmalloc (sizeof(*res->obst));
199 obstack_init(res->obst);
201 res->phase_state = phase_building;
202 irg_set_nloc(res, n_loc);
204 /* descriptions will be allocated on demand */
205 res->loc_descriptions = NULL;
207 res->visited = 0; /* visited flag, for the ir walker */
208 res->block_visited = 0; /* visited flag, for the 'block'-walker */
210 #if USE_EXPLICIT_PHI_IN_STACK
211 res->Phi_in_stack = new_Phi_in_stack(); /* A stack needed for automatic Phi
214 res->extbb_obst = NULL;
216 res->last_node_idx = 0;
218 res->value_table = new_identities (); /* value table for global value
219 numbering for optimizing use in iropt.c */
222 res->inline_property = irg_inline_any;
223 res->additional_properties = mtp_property_inherited; /* inherited from type */
225 res->irg_pinned_state = op_pin_state_pinned;
226 res->outs_state = outs_none;
227 res->dom_state = dom_none;
228 res->pdom_state = dom_none;
229 res->typeinfo_state = ir_typeinfo_none;
230 set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
231 res->callee_info_state = irg_callee_info_none;
232 res->loopinfo_state = loopinfo_none;
233 res->class_cast_state = ir_class_casts_transitive;
234 res->extblk_state = ir_extblk_info_none;
235 res->execfreq_state = exec_freq_none;
236 res->fp_model = fp_model_precise;
237 res->entity_usage_state = ir_entity_usage_not_computed;
238 res->mem_disambig_opt = aa_opt_inherited;
240 /*-- Type information for the procedure of the graph --*/
242 set_entity_irg(ent, res);
244 /*-- a class type so that it can contain "inner" methods as in Pascal. --*/
245 res->frame_type = new_type_frame(mangle(get_entity_ident(ent), frame_type_suffix));
247 /* the Anchor node must be created first */
248 res->anchor = new_Anchor(res);
250 /*-- Nodes needed in every graph --*/
251 set_irg_end_block (res, new_immBlock());
253 set_irg_end (res, end);
254 set_irg_end_reg (res, end);
255 set_irg_end_except(res, end);
257 start_block = new_immBlock();
258 set_irg_start_block(res, start_block);
259 set_irg_bad (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
260 set_irg_no_mem (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
262 set_irg_start (res, start);
264 /* Proj results of start node */
265 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
266 set_irg_initial_exec (res, projX);
267 set_irg_frame (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
268 set_irg_tls (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
269 set_irg_args (res, new_Proj(start, mode_T, pn_Start_T_args));
270 set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
271 initial_mem = new_Proj(start, mode_M, pn_Start_M);
272 set_irg_initial_mem(res, initial_mem);
274 add_immBlock_pred(start_block, projX);
275 set_store(initial_mem);
277 res->index = get_irp_new_irg_idx();
279 res->graph_nr = get_irp_new_node_nr();
283 * The code generation needs it. leave it in now.
284 * Use of this edge is matter of discussion, unresolved. Also possible:
285 * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
287 mature_immBlock(res->current_block);
289 /*-- Make a block to start with --*/
290 first_block = new_immBlock();
291 add_immBlock_pred(first_block, projX);
293 res->method_execution_frequency = -1.0;
294 res->estimated_node_count = 0;
299 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
300 ir_graph *res = new_r_ir_graph(ent, n_loc);
301 add_irp_irg(res); /* remember this graph global. */
305 /* Make a rudimentary IR graph for the constant code.
306 Must look like a correct irg, spare everything else. */
307 ir_graph *new_const_code_irg(void) {
309 ir_node *end, *start_block, *start, *projX;
313 /* inform statistics here, as blocks will be already build on this graph */
314 hook_new_graph(res, NULL);
316 current_ir_graph = res;
317 res->n_loc = 1; /* Only the memory. */
318 res->visited = 0; /* visited flag, for the ir walker */
319 res->block_visited = 0; /* visited flag, for the 'block'-walker */
320 #if USE_EXPLICIT_PHI_IN_STACK
321 res->Phi_in_stack = NULL;
323 res->obst = xmalloc(sizeof(*res->obst));
324 obstack_init (res->obst);
325 res->extbb_obst = NULL;
327 res->last_node_idx = 0;
329 res->phase_state = phase_building;
330 res->irg_pinned_state = op_pin_state_pinned;
331 res->extblk_state = ir_extblk_info_none;
332 res->fp_model = fp_model_precise;
334 res->value_table = new_identities(); /* value table for global value
335 numbering for optimizing use in
338 res->frame_type = NULL;
340 /* the Anchor node must be created first */
341 res->anchor = new_Anchor(res);
343 /* -- The end block -- */
344 set_irg_end_block (res, new_immBlock());
346 set_irg_end (res, end);
347 set_irg_end_reg (res, end);
348 set_irg_end_except(res, end);
349 mature_immBlock(get_cur_block()); /* mature the end block */
351 /* -- The start block -- */
352 start_block = new_immBlock();
353 set_irg_start_block(res, start_block);
354 set_irg_bad (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
355 set_irg_no_mem (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
357 set_irg_start (res, start);
359 /* Proj results of start node */
360 set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
361 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
362 add_immBlock_pred(start_block, projX);
363 mature_immBlock (start_block); /* mature the start block */
365 add_immBlock_pred(new_immBlock(), projX);
366 mature_immBlock (get_cur_block()); /* mature the 'body' block for expressions */
368 /* Set the visited flag high enough that the blocks will never be visited. */
369 set_irn_visited(get_cur_block(), -1);
370 set_Block_block_visited(get_cur_block(), -1);
371 set_Block_block_visited(start_block, -1);
372 set_irn_visited(start_block, -1);
373 set_irn_visited(get_irg_bad(res), -1);
374 set_irn_visited(get_irg_no_mem(res), -1);
376 res->phase_state = phase_high;
382 * Pre-Walker: Copies blocks and nodes from the original method graph
383 * to the copied graph.
385 * @param n A node from the original method graph.
386 * @param env The copied graph.
388 static void copy_all_nodes(ir_node *n, void *env) {
390 ir_op *op = get_irn_op(n);
393 nn = new_ir_node(get_irn_dbg_info(n),
395 NULL, /* no block yet, will be set later */
402 /* Copy the attributes. These might point to additional data. If this
403 was allocated on the old obstack the pointers now are dangling. This
404 frees e.g. the memory of the graph_arr allocated in new_immBlock. */
405 copy_node_attr(n, nn);
406 new_backedge_info(nn);
409 /* fix the irg for blocks */
411 nn->attr.block.irg = irg;
413 /* fix access to entities on the stack frame */
415 ir_entity *ent = get_Sel_entity(nn);
416 ir_type *tp = get_entity_owner(ent);
418 if (is_frame_type(tp)) {
419 /* replace by the copied entity */
420 ent = get_entity_link(ent);
422 assert(is_entity(ent));
423 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
424 set_Sel_entity(nn, ent);
430 * Post-walker: Set the predecessors of the copied nodes.
431 * The copied nodes are set as link of their original nodes. The links of
432 * "irn" predecessors are the predecessors of copied node.
434 static void set_all_preds(ir_node *irn, void *env) {
439 nn = get_irn_link(irn);
442 ir_node *mbh = get_Block_MacroBlock(irn);
443 set_Block_MacroBlock(nn, get_irn_link(mbh));
444 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
445 pred = get_Block_cfgpred(irn, i);
446 set_Block_cfgpred(nn, i, get_irn_link(pred));
449 /* First we set the block our copy if it is not a block.*/
450 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
451 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
452 pred = get_irn_n(irn, i);
453 set_irn_n(nn, i, get_irn_link(pred));
458 #define NN(irn) get_irn_link(irn)
461 * Create a new graph that is a copy of a given one.
463 ir_graph *create_irg_copy(ir_graph *irg) {
469 res->visited = 0; /* visited flag, for the ir walker */
470 res->block_visited = 0; /* visited flag, for the 'block'-walker */
471 #if USE_EXPLICIT_PHI_IN_STACK
472 res->Phi_in_stack = NULL;
474 res->obst = xmalloc(sizeof(*res->obst));
475 obstack_init(res->obst);
476 res->extbb_obst = NULL;
478 res->last_node_idx = 0;
480 res->phase_state = irg->phase_state;
481 res->irg_pinned_state = irg->irg_pinned_state;
482 res->extblk_state = ir_extblk_info_none;
483 res->fp_model = irg->fp_model;
485 res->value_table = new_identities();
487 /* clone the frame type here for safety */
488 res->frame_type = clone_frame_type(irg->frame_type);
490 res->phase_state = irg->phase_state;
492 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
494 /* copy all nodes from the graph irg to the new graph res */
495 irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
497 /* copy the Anchor node */
498 res->anchor = NN(irg->anchor);
500 /* -- The end block -- */
501 set_irg_end_block (res, NN(get_irg_end_block(irg)));
502 set_irg_end (res, NN(get_irg_end(irg)));
503 set_irg_end_reg (res, NN(get_irg_end_reg(irg)));
504 set_irg_end_except(res, NN(get_irg_end_except(irg)));
506 /* -- The start block -- */
507 set_irg_start_block(res, NN(get_irg_start_block(irg)));
508 set_irg_bad (res, NN(get_irg_bad(irg)));
509 set_irg_no_mem (res, NN(get_irg_no_mem(irg)));
510 set_irg_start (res, NN(get_irg_start(irg)));
512 /* Proj results of start node */
513 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
515 /* Copy the node count estimation. Would be strange if this
516 is different from the original one. */
517 res->estimated_node_count = irg->estimated_node_count;
519 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
526 /* Frees the passed irgraph.
527 Deallocates all nodes in this graph and the ir_graph structure.
528 Sets the field irgraph in the corresponding entity to NULL.
529 Does not remove the irgraph from the list in irprog (requires
530 inefficient search, call remove_irp_irg by hand).
531 Does not free types, entities or modes that are used only by this
532 graph, nor the entity standing for this graph. */
533 void free_ir_graph(ir_graph *irg) {
534 assert(is_ir_graph(irg));
536 edges_deactivate(irg);
538 hook_free_graph(irg);
539 if (irg->outs_state != outs_none)
542 free_type(irg->frame_type);
543 if (irg->value_table)
544 del_identities(irg->value_table);
546 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
547 set_entity_peculiarity (irg->ent, peculiarity_description);
548 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
549 set_entity_peculiarity (irg->ent, pec);
552 free_End(get_irg_end(irg));
553 obstack_free(irg->obst,NULL);
555 #if USE_EXPLICIT_PHI_IN_STACK
556 free_Phi_in_stack(irg->Phi_in_stack);
558 if (irg->loc_descriptions)
559 free(irg->loc_descriptions);
564 /* access routines for all ir_graph attributes:
566 {attr type} get_irg_{attribute name} (ir_graph *irg);
567 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
570 (is_ir_graph)(const void *thing) {
571 return _is_ir_graph(thing);
575 /* Outputs a unique number for this node */
576 long get_irg_graph_nr(const ir_graph *irg) {
577 return irg->graph_nr;
580 long get_irg_graph_nr(const ir_graph *irg) {
581 return PTR_TO_INT(irg);
585 int get_irg_idx(const ir_graph *irg) {
590 (get_irg_start_block)(const ir_graph *irg) {
591 return _get_irg_start_block(irg);
595 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
596 _set_irg_start_block(irg, node);
600 (get_irg_start)(const ir_graph *irg) {
601 return _get_irg_start(irg);
605 (set_irg_start)(ir_graph *irg, ir_node *node) {
606 _set_irg_start(irg, node);
610 (get_irg_end_block)(const ir_graph *irg) {
611 return _get_irg_end_block(irg);
615 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
616 _set_irg_end_block(irg, node);
620 (get_irg_end)(const ir_graph *irg) {
621 return _get_irg_end(irg);
625 (set_irg_end)(ir_graph *irg, ir_node *node) {
626 _set_irg_end(irg, node);
630 (get_irg_end_reg)(const ir_graph *irg) {
631 return _get_irg_end_reg(irg);
635 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
636 _set_irg_end_reg(irg, node);
640 (get_irg_end_except)(const ir_graph *irg) {
641 return _get_irg_end_except(irg);
645 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
646 assert(get_irn_op(node) == op_EndExcept || is_End(node));
647 _set_irg_end_except(irg, node);
651 (get_irg_initial_exec)(const ir_graph *irg) {
652 return _get_irg_initial_exec(irg);
656 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
657 _set_irg_initial_exec(irg, node);
661 (get_irg_frame)(const ir_graph *irg) {
662 return _get_irg_frame(irg);
666 (set_irg_frame)(ir_graph *irg, ir_node *node) {
667 _set_irg_frame(irg, node);
671 (get_irg_tls)(const ir_graph *irg) {
672 return _get_irg_tls(irg);
676 (set_irg_tls)(ir_graph *irg, ir_node *node) {
677 _set_irg_tls(irg, node);
681 (get_irg_initial_mem)(const ir_graph *irg) {
682 return _get_irg_initial_mem(irg);
686 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
687 _set_irg_initial_mem(irg, node);
691 (get_irg_args)(const ir_graph *irg) {
692 return _get_irg_args(irg);
696 (set_irg_args)(ir_graph *irg, ir_node *node) {
697 _set_irg_args(irg, node);
701 (get_irg_value_param_base)(const ir_graph *irg) {
702 return _get_irg_value_param_base(irg);
706 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
707 _set_irg_value_param_base(irg, node);
711 (get_irg_bad)(const ir_graph *irg) {
712 return _get_irg_bad(irg);
716 (set_irg_bad)(ir_graph *irg, ir_node *node) {
717 _set_irg_bad(irg, node);
721 (get_irg_no_mem)(const ir_graph *irg) {
722 return _get_irg_no_mem(irg);
726 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
727 _set_irg_no_mem(irg, node);
731 (get_irg_current_block)(const ir_graph *irg) {
732 return _get_irg_current_block(irg);
736 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
737 _set_irg_current_block(irg, node);
741 (get_irg_entity)(const ir_graph *irg) {
742 return _get_irg_entity(irg);
746 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
747 _set_irg_entity(irg, ent);
751 (get_irg_frame_type)(ir_graph *irg) {
752 return _get_irg_frame_type(irg);
756 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
757 _set_irg_frame_type(irg, ftp);
761 get_irg_n_locs(ir_graph *irg) {
762 if (get_opt_precise_exc_context())
763 return irg->n_loc - 1 - 1;
765 return irg->n_loc - 1;
769 set_irg_n_loc(ir_graph *irg, int n_loc) {
770 if (get_opt_precise_exc_context())
771 irg->n_loc = n_loc + 1 + 1;
773 irg->n_loc = n_loc + 1;
778 /* Returns the obstack associated with the graph. */
780 (get_irg_obstack)(const ir_graph *irg) {
781 return _get_irg_obstack(irg);
785 * Returns true if the node n is allocated on the storage of graph irg.
787 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
789 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
790 struct _obstack_chunk *p;
793 * checks weather the ir_node pointer is on the obstack.
794 * A more sophisticated check would test the "whole" ir_node
796 for (p = irg->obst->chunk; p; p = p->prev) {
797 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
805 (get_irg_phase_state)(const ir_graph *irg) {
806 return _get_irg_phase_state(irg);
810 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
811 _set_irg_phase_state(irg, state);
815 (get_irg_pinned)(const ir_graph *irg) {
816 return _get_irg_pinned(irg);
820 (get_irg_outs_state)(const ir_graph *irg) {
821 return _get_irg_outs_state(irg);
825 (set_irg_outs_inconsistent)(ir_graph *irg) {
826 _set_irg_outs_inconsistent(irg);
830 (get_irg_extblk_state)(const ir_graph *irg) {
831 return _get_irg_extblk_state(irg);
835 (set_irg_extblk_inconsistent)(ir_graph *irg) {
836 _set_irg_extblk_inconsistent(irg);
840 (get_irg_dom_state)(const ir_graph *irg) {
841 return _get_irg_dom_state(irg);
845 (get_irg_postdom_state)(const ir_graph *irg) {
846 return _get_irg_postdom_state(irg);
850 (set_irg_doms_inconsistent)(ir_graph *irg) {
851 _set_irg_doms_inconsistent(irg);
855 (get_irg_loopinfo_state)(const ir_graph *irg) {
856 return _get_irg_loopinfo_state(irg);
860 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
861 _set_irg_loopinfo_state(irg, s);
865 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
866 _set_irg_loopinfo_inconsistent(irg);
869 void set_irp_loopinfo_inconsistent(void) {
871 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
872 set_irg_loopinfo_inconsistent(get_irp_irg(i));
879 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
880 _set_irg_pinned(irg, p);
883 irg_callee_info_state
884 (get_irg_callee_info_state)(const ir_graph *irg) {
885 return _get_irg_callee_info_state(irg);
889 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
890 _set_irg_callee_info_state(irg, s);
894 (get_irg_inline_property)(const ir_graph *irg) {
895 return _get_irg_inline_property(irg);
899 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
900 _set_irg_inline_property(irg, s);
904 (get_irg_additional_properties)(const ir_graph *irg) {
905 return _get_irg_additional_properties(irg);
909 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
910 _set_irg_additional_properties(irg, property_mask);
914 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
915 _set_irg_additional_property(irg, flag);
919 (set_irg_link)(ir_graph *irg, void *thing) {
920 _set_irg_link(irg, thing);
924 (get_irg_link)(const ir_graph *irg) {
925 return _get_irg_link(irg);
929 (get_irg_visited)(const ir_graph *irg) {
930 return _get_irg_visited(irg);
933 #ifdef INTERPROCEDURAL_VIEW
934 /** maximum visited flag content of all ir_graph visited fields. */
935 static ir_visited_t max_irg_visited = 0;
936 #endif /* INTERPROCEDURAL_VIEW */
939 set_irg_visited(ir_graph *irg, ir_visited_t visited) {
940 irg->visited = visited;
941 #ifdef INTERPROCEDURAL_VIEW
942 if (irg->visited > max_irg_visited) {
943 max_irg_visited = irg->visited;
945 #endif /* INTERPROCEDURAL_VIEW */
949 inc_irg_visited(ir_graph *irg) {
950 #ifdef INTERPROCEDURAL_VIEW
951 if (++irg->visited > max_irg_visited) {
952 max_irg_visited = irg->visited;
956 #endif /* INTERPROCEDURAL_VIEW */
959 #ifdef INTERPROCEDURAL_VIEW
961 get_max_irg_visited(void) {
964 for(i = 0; i < get_irp_n_irgs(); i++)
965 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
967 return max_irg_visited;
970 void set_max_irg_visited(int val) {
971 max_irg_visited = val;
975 inc_max_irg_visited(void) {
978 for(i = 0; i < get_irp_n_irgs(); i++)
979 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
981 return ++max_irg_visited;
983 #endif /* INTERPROCEDURAL_VIEW */
986 (get_irg_block_visited)(const ir_graph *irg) {
987 return _get_irg_block_visited(irg);
991 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
992 _set_irg_block_visited(irg, visited);
996 (inc_irg_block_visited)(ir_graph *irg) {
997 _inc_irg_block_visited(irg);
1000 /* Return the floating point model of this graph. */
1001 unsigned (get_irg_fp_model)(const ir_graph *irg) {
1002 return _get_irg_fp_model(irg);
1005 /* Sets the floating point model for this graph. */
1006 void set_irg_fp_model(ir_graph *irg, unsigned model) {
1007 irg->fp_model = model;
1011 * walker Start->End: places Proj nodes into the same block
1012 * as it's predecessors
1015 * @param env ignored
1017 static void normalize_proj_walker(ir_node *n, void *env) {
1020 ir_node *pred = get_Proj_pred(n);
1021 ir_node *block = get_nodes_block(pred);
1023 set_nodes_block(n, block);
1027 /* move Proj nodes into the same block as its predecessors */
1028 void normalize_proj_nodes(ir_graph *irg) {
1029 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1030 set_irg_outs_inconsistent(irg);
1033 /* set a description for local value n */
1034 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1035 assert(0 <= n && n < irg->n_loc);
1037 if (! irg->loc_descriptions)
1038 irg->loc_descriptions = xcalloc(sizeof(*irg->loc_descriptions), irg->n_loc);
1040 irg->loc_descriptions[n] = description;
1043 /* get the description for local value n */
1044 void *get_irg_loc_description(ir_graph *irg, int n) {
1045 assert(0 <= n && n < irg->n_loc);
1046 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1050 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
1052 assert((irg->reserved_resources & resources) == 0);
1053 irg->reserved_resources |= resources;
1056 void ir_free_resources(ir_graph *irg, ir_resources_t resources)
1058 assert((irg->reserved_resources & resources) == resources);
1059 irg->reserved_resources &= ~resources;
1062 ir_resources_t ir_resources_reserved(const ir_graph *irg)
1064 return irg->reserved_resources;
1068 /* Returns a estimated node count of the irg. */
1069 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1070 return _get_irg_estimated_node_cnt(irg);
1073 /* Returns the last irn index for this graph. */
1074 unsigned get_irg_last_idx(const ir_graph *irg) {
1075 return irg->last_node_idx;
1078 /* register additional space in an IR graph */
1079 size_t register_additional_graph_data(size_t size) {
1080 assert(!forbid_new_data && "Too late to register additional node data");
1082 if (forbid_new_data)
1085 return additional_graph_data_size += size;