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
171 /* Allocates a list of nodes:
172 - The start block containing a start node and Proj nodes for it's four
173 results (X, M, P, Tuple).
174 - The end block containing an end node. This block is not matured after
175 new_ir_graph as predecessors need to be added to it.
176 - The current block, which is empty and also not matured.
177 Further it allocates several datastructures needed for graph construction
180 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
182 ir_node *first_block;
183 ir_node *end, *start, *start_block, *initial_mem, *projX;
187 /* inform statistics here, as blocks will be already build on this graph */
188 hook_new_graph(res, ent);
190 current_ir_graph = res;
192 /*-- initialized for each graph. --*/
193 res->kind = k_ir_graph;
194 res->obst = xmalloc (sizeof(*res->obst));
195 obstack_init(res->obst);
197 res->phase_state = phase_building;
198 irg_set_nloc(res, n_loc);
200 /* descriptions will be allocated on demand */
201 res->loc_descriptions = NULL;
203 res->visited = 0; /* visited flag, for the ir walker */
204 res->block_visited = 0; /* visited flag, for the 'block'-walker */
206 #if USE_EXPLICIT_PHI_IN_STACK
207 res->Phi_in_stack = new_Phi_in_stack(); /* A stack needed for automatic Phi
210 res->extbb_obst = NULL;
212 res->last_node_idx = 0;
214 res->value_table = new_identities (); /* value table for global value
215 numbering for optimizing use in iropt.c */
218 res->inline_property = irg_inline_any;
219 res->additional_properties = mtp_property_inherited; /* inherited from type */
221 res->irg_pinned_state = op_pin_state_pinned;
222 res->outs_state = outs_none;
223 res->dom_state = dom_none;
224 res->pdom_state = dom_none;
225 res->typeinfo_state = ir_typeinfo_none;
226 set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
227 res->callee_info_state = irg_callee_info_none;
228 res->loopinfo_state = loopinfo_none;
229 res->class_cast_state = ir_class_casts_transitive;
230 res->extblk_state = ir_extblk_info_none;
231 res->execfreq_state = exec_freq_none;
232 res->fp_model = fp_model_precise;
233 res->adr_taken_state = ir_address_taken_not_computed;
234 res->mem_disambig_opt = aa_opt_inherited;
236 /*-- Type information for the procedure of the graph --*/
238 set_entity_irg(ent, res);
240 /*-- a class type so that it can contain "inner" methods as in Pascal. --*/
241 res->frame_type = new_type_frame(mangle(get_entity_ident(ent), frame_type_suffix));
243 /* the Anchor node must be created first */
244 res->anchor = new_Anchor(res);
246 /*-- Nodes needed in every graph --*/
247 set_irg_end_block (res, new_immBlock());
249 set_irg_end (res, end);
250 set_irg_end_reg (res, end);
251 set_irg_end_except(res, end);
253 start_block = new_immBlock();
254 set_irg_start_block(res, start_block);
255 set_irg_bad (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
256 set_irg_no_mem (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
258 set_irg_start (res, start);
260 /* Proj results of start node */
261 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
262 set_irg_frame (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
263 set_irg_globals (res, new_Proj(start, mode_P_data, pn_Start_P_globals));
264 set_irg_tls (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
265 set_irg_args (res, new_Proj(start, mode_T, pn_Start_T_args));
266 set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
267 initial_mem = new_Proj(start, mode_M, pn_Start_M);
268 set_irg_initial_mem(res, initial_mem);
270 add_immBlock_pred(start_block, projX);
271 set_store(initial_mem);
273 res->index = get_irp_new_irg_idx();
275 res->graph_nr = get_irp_new_node_nr();
279 * The code generation needs it. leave it in now.
280 * Use of this edge is matter of discussion, unresolved. Also possible:
281 * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
283 mature_immBlock(res->current_block);
285 /*-- Make a block to start with --*/
286 first_block = new_immBlock();
287 add_immBlock_pred(first_block, projX);
289 res->method_execution_frequency = -1.0;
290 res->estimated_node_count = 0;
295 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
296 ir_graph *res = new_r_ir_graph(ent, n_loc);
297 add_irp_irg(res); /* remember this graph global. */
301 /* Make a rudimentary IR graph for the constant code.
302 Must look like a correct irg, spare everything else. */
303 ir_graph *new_const_code_irg(void) {
305 ir_node *end, *start_block, *start, *projX;
309 /* inform statistics here, as blocks will be already build on this graph */
310 hook_new_graph(res, NULL);
312 current_ir_graph = res;
313 res->n_loc = 1; /* Only the memory. */
314 res->visited = 0; /* visited flag, for the ir walker */
315 res->block_visited = 0; /* visited flag, for the 'block'-walker */
316 #if USE_EXPLICIT_PHI_IN_STACK
317 res->Phi_in_stack = NULL;
319 res->obst = xmalloc(sizeof(*res->obst));
320 obstack_init (res->obst);
321 res->extbb_obst = NULL;
323 res->last_node_idx = 0;
325 res->phase_state = phase_building;
326 res->irg_pinned_state = op_pin_state_pinned;
327 res->extblk_state = ir_extblk_info_none;
328 res->fp_model = fp_model_precise;
330 res->value_table = new_identities(); /* value table for global value
331 numbering for optimizing use in
334 res->frame_type = NULL;
336 /* the Anchor node must be created first */
337 res->anchor = new_Anchor(res);
339 /* -- The end block -- */
340 set_irg_end_block (res, new_immBlock());
342 set_irg_end (res, end);
343 set_irg_end_reg (res, end);
344 set_irg_end_except(res, end);
345 mature_immBlock(get_cur_block()); /* mature the end block */
347 /* -- The start block -- */
348 start_block = new_immBlock();
349 set_irg_start_block(res, start_block);
350 set_irg_bad (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
351 set_irg_no_mem (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
353 set_irg_start (res, start);
355 /* Proj results of start node */
356 set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
357 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
358 add_immBlock_pred(start_block, projX);
359 mature_immBlock (start_block); /* mature the start block */
361 add_immBlock_pred(new_immBlock(), projX);
362 mature_immBlock (get_cur_block()); /* mature the 'body' block for expressions */
364 /* Set the visited flag high enough that the blocks will never be visited. */
365 set_irn_visited(get_cur_block(), -1);
366 set_Block_block_visited(get_cur_block(), -1);
367 set_Block_block_visited(start_block, -1);
368 set_irn_visited(start_block, -1);
369 set_irn_visited(get_irg_bad(res), -1);
370 set_irn_visited(get_irg_no_mem(res), -1);
372 res->phase_state = phase_high;
378 * Pre-Walker: Copies blocks and nodes from the original method graph
379 * to the copied graph.
381 * @param n A node from the original method graph.
382 * @param env The copied graph.
384 static void copy_all_nodes(ir_node *n, void *env) {
385 ir_graph *irg = current_ir_graph;
386 ir_op *op = get_irn_op(n);
390 nn = new_ir_node(get_irn_dbg_info(n),
392 NULL, /* no block yet, will be set later */
399 /* Copy the attributes. These might point to additional data. If this
400 was allocated on the old obstack the pointers now are dangling. This
401 frees e.g. the memory of the graph_arr allocated in new_immBlock. */
402 copy_node_attr(n, nn);
403 new_backedge_info(nn);
406 /* fix the irg for blocks */
408 nn->attr.block.irg = irg;
410 /* fix access to entities on the stack frame */
412 ir_entity *ent = get_Sel_entity(nn);
413 ir_type *tp = get_entity_owner(ent);
415 if (is_frame_type(tp)) {
416 /* replace by the copied entity */
417 ent = get_entity_link(ent);
419 assert(is_entity(ent));
420 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
421 set_Sel_entity(nn, ent);
427 * Post-walker: Set the predecessors of the copied nodes.
428 * The copied nodes are set as link of their original nodes. The links of
429 * "irn" predecessors are the predecessors of copied node.
431 static void set_all_preds(ir_node *irn, void *env) {
436 nn = get_irn_link(irn);
439 ir_node *mbh = get_Block_MacroBlock(irn);
440 set_Block_MacroBlock(nn, get_irn_link(mbh));
441 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
442 pred = get_Block_cfgpred(irn, i);
443 set_Block_cfgpred(nn, i, get_irn_link(pred));
446 /* First we set the block our copy if it is not a block.*/
447 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
448 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
449 pred = get_irn_n(irn, i);
450 set_irn_n(nn, i, get_irn_link(pred));
455 #define NN(irn) get_irn_link(irn)
458 * Create a new graph that is a copy of a given one.
460 ir_graph *create_irg_copy(ir_graph *irg) {
466 res->visited = 0; /* visited flag, for the ir walker */
467 res->block_visited = 0; /* visited flag, for the 'block'-walker */
468 #if USE_EXPLICIT_PHI_IN_STACK
469 res->Phi_in_stack = NULL;
471 res->obst = xmalloc(sizeof(*res->obst));
472 obstack_init(res->obst);
473 res->extbb_obst = NULL;
475 res->last_node_idx = 0;
477 res->phase_state = irg->phase_state;
478 res->irg_pinned_state = irg->irg_pinned_state;
479 res->extblk_state = ir_extblk_info_none;
480 res->fp_model = irg->fp_model;
482 res->value_table = new_identities();
484 /* clone the frame type here for safety */
485 res->frame_type = clone_frame_type(irg->frame_type);
487 res->phase_state = irg->phase_state;
489 set_using_irn_link(irg);
491 /* copy all nodes from the graph irg to the new graph res */
492 irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
494 /* copy the Anchor node */
495 res->anchor = NN(irg->anchor);
497 /* -- The end block -- */
498 set_irg_end_block (res, NN(get_irg_end_block(irg)));
499 set_irg_end (res, NN(get_irg_end(irg)));
500 set_irg_end_reg (res, NN(get_irg_end_reg(irg)));
501 set_irg_end_except(res, NN(get_irg_end_except(irg)));
503 /* -- The start block -- */
504 set_irg_start_block(res, NN(get_irg_start_block(irg)));
505 set_irg_bad (res, NN(get_irg_bad(irg)));
506 set_irg_no_mem (res, NN(get_irg_no_mem(irg)));
507 set_irg_start (res, NN(get_irg_start(irg)));
509 /* Proj results of start node */
510 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
512 /* Copy the node count estimation. Would be strange if this
513 is different from the original one. */
514 res->estimated_node_count = irg->estimated_node_count;
516 clear_using_irn_link(irg);
523 /* Frees the passed irgraph.
524 Deallocates all nodes in this graph and the ir_graph structure.
525 Sets the field irgraph in the corresponding entity to NULL.
526 Does not remove the irgraph from the list in irprog (requires
527 inefficient search, call remove_irp_irg by hand).
528 Does not free types, entities or modes that are used only by this
529 graph, nor the entity standing for this graph. */
530 void free_ir_graph(ir_graph *irg) {
531 assert(is_ir_graph(irg));
533 hook_free_graph(irg);
534 if (irg->outs_state != outs_none)
537 free_type(irg->frame_type);
538 if (irg->value_table)
539 del_identities(irg->value_table);
541 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
542 set_entity_peculiarity (irg->ent, peculiarity_description);
543 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
544 set_entity_peculiarity (irg->ent, pec);
547 free_End(get_irg_end(irg));
548 obstack_free(irg->obst,NULL);
550 #if USE_EXPLICIT_PHI_IN_STACK
551 free_Phi_in_stack(irg->Phi_in_stack);
553 if (irg->loc_descriptions)
554 free(irg->loc_descriptions);
559 /* access routines for all ir_graph attributes:
561 {attr type} get_irg_{attribute name} (ir_graph *irg);
562 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
565 (is_ir_graph)(const void *thing) {
566 return _is_ir_graph(thing);
570 /* Outputs a unique number for this node */
571 long get_irg_graph_nr(const ir_graph *irg) {
572 return irg->graph_nr;
575 long get_irg_graph_nr(const ir_graph *irg) {
576 return PTR_TO_INT(irg);
580 int get_irg_idx(const ir_graph *irg) {
585 (get_irg_start_block)(const ir_graph *irg) {
586 return _get_irg_start_block(irg);
590 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
591 _set_irg_start_block(irg, node);
595 (get_irg_start)(const ir_graph *irg) {
596 return _get_irg_start(irg);
600 (set_irg_start)(ir_graph *irg, ir_node *node) {
601 _set_irg_start(irg, node);
605 (get_irg_end_block)(const ir_graph *irg) {
606 return _get_irg_end_block(irg);
610 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
611 _set_irg_end_block(irg, node);
615 (get_irg_end)(const ir_graph *irg) {
616 return _get_irg_end(irg);
620 (set_irg_end)(ir_graph *irg, ir_node *node) {
621 _set_irg_end(irg, node);
625 (get_irg_end_reg)(const ir_graph *irg) {
626 return _get_irg_end_reg(irg);
630 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
631 _set_irg_end_reg(irg, node);
635 (get_irg_end_except)(const ir_graph *irg) {
636 return _get_irg_end_except(irg);
640 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
641 assert(get_irn_op(node) == op_EndExcept || get_irn_op(node) == op_End);
642 _set_irg_end_except(irg, node);
646 (get_irg_frame)(const ir_graph *irg) {
647 return _get_irg_frame(irg);
651 (set_irg_frame)(ir_graph *irg, ir_node *node) {
652 _set_irg_frame(irg, node);
656 (get_irg_globals)(const ir_graph *irg) {
657 return _get_irg_globals(irg);
661 (set_irg_globals)(ir_graph *irg, ir_node *node) {
662 _set_irg_globals(irg, node);
666 (get_irg_tls)(const ir_graph *irg) {
667 return _get_irg_tls(irg);
671 (set_irg_tls)(ir_graph *irg, ir_node *node) {
672 _set_irg_tls(irg, node);
676 (get_irg_initial_mem)(const ir_graph *irg) {
677 return _get_irg_initial_mem(irg);
681 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
682 _set_irg_initial_mem(irg, node);
686 (get_irg_args)(const ir_graph *irg) {
687 return _get_irg_args(irg);
691 (set_irg_args)(ir_graph *irg, ir_node *node) {
692 _set_irg_args(irg, node);
696 (get_irg_value_param_base)(const ir_graph *irg) {
697 return _get_irg_value_param_base(irg);
701 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
702 _set_irg_value_param_base(irg, node);
706 (get_irg_bad)(const ir_graph *irg) {
707 return _get_irg_bad(irg);
711 (set_irg_bad)(ir_graph *irg, ir_node *node) {
712 _set_irg_bad(irg, node);
716 (get_irg_no_mem)(const ir_graph *irg) {
717 return _get_irg_no_mem(irg);
721 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
722 _set_irg_no_mem(irg, node);
726 (get_irg_current_block)(const ir_graph *irg) {
727 return _get_irg_current_block(irg);
731 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
732 _set_irg_current_block(irg, node);
736 (get_irg_entity)(const ir_graph *irg) {
737 return _get_irg_entity(irg);
741 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
742 _set_irg_entity(irg, ent);
746 (get_irg_frame_type)(ir_graph *irg) {
747 return _get_irg_frame_type(irg);
751 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
752 _set_irg_frame_type(irg, ftp);
756 get_irg_n_locs(ir_graph *irg) {
757 if (get_opt_precise_exc_context())
758 return irg->n_loc - 1 - 1;
760 return irg->n_loc - 1;
764 set_irg_n_loc(ir_graph *irg, int n_loc) {
765 if (get_opt_precise_exc_context())
766 irg->n_loc = n_loc + 1 + 1;
768 irg->n_loc = n_loc + 1;
773 /* Returns the obstack associated with the graph. */
775 (get_irg_obstack)(const ir_graph *irg) {
776 return _get_irg_obstack(irg);
780 * Returns true if the node n is allocated on the storage of graph irg.
782 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
784 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
785 struct _obstack_chunk *p;
788 * checks weather the ir_node pointer is on the obstack.
789 * A more sophisticated check would test the "whole" ir_node
791 for (p = irg->obst->chunk; p; p = p->prev) {
792 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
800 (get_irg_phase_state)(const ir_graph *irg) {
801 return _get_irg_phase_state(irg);
805 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
806 _set_irg_phase_state(irg, state);
810 (get_irg_pinned)(const ir_graph *irg) {
811 return _get_irg_pinned(irg);
815 (get_irg_outs_state)(const ir_graph *irg) {
816 return _get_irg_outs_state(irg);
820 (set_irg_outs_inconsistent)(ir_graph *irg) {
821 _set_irg_outs_inconsistent(irg);
825 (get_irg_extblk_state)(const ir_graph *irg) {
826 return _get_irg_extblk_state(irg);
830 (set_irg_extblk_inconsistent)(ir_graph *irg) {
831 _set_irg_extblk_inconsistent(irg);
835 (get_irg_dom_state)(const ir_graph *irg) {
836 return _get_irg_dom_state(irg);
840 (get_irg_postdom_state)(const ir_graph *irg) {
841 return _get_irg_postdom_state(irg);
845 (set_irg_doms_inconsistent)(ir_graph *irg) {
846 _set_irg_doms_inconsistent(irg);
850 (get_irg_loopinfo_state)(const ir_graph *irg) {
851 return _get_irg_loopinfo_state(irg);
855 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
856 _set_irg_loopinfo_state(irg, s);
860 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
861 _set_irg_loopinfo_inconsistent(irg);
864 void set_irp_loopinfo_inconsistent(void) {
866 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
867 set_irg_loopinfo_inconsistent(get_irp_irg(i));
874 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
875 _set_irg_pinned(irg, p);
878 irg_callee_info_state
879 (get_irg_callee_info_state)(const ir_graph *irg) {
880 return _get_irg_callee_info_state(irg);
884 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
885 _set_irg_callee_info_state(irg, s);
889 (get_irg_inline_property)(const ir_graph *irg) {
890 return _get_irg_inline_property(irg);
894 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
895 _set_irg_inline_property(irg, s);
899 (get_irg_additional_properties)(const ir_graph *irg) {
900 return _get_irg_additional_properties(irg);
904 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
905 _set_irg_additional_properties(irg, property_mask);
909 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
910 _set_irg_additional_property(irg, flag);
914 (set_irg_link)(ir_graph *irg, void *thing) {
915 _set_irg_link(irg, thing);
919 (get_irg_link)(const ir_graph *irg) {
920 return _get_irg_link(irg);
924 (get_irg_visited)(const ir_graph *irg) {
925 return _get_irg_visited(irg);
928 #ifdef INTERPROCEDURAL_VIEW
929 /** maximum visited flag content of all ir_graph visited fields. */
930 static unsigned long max_irg_visited = 0;
931 #endif /* INTERPROCEDURAL_VIEW */
934 set_irg_visited(ir_graph *irg, unsigned long visited) {
935 irg->visited = visited;
936 #ifdef INTERPROCEDURAL_VIEW
937 if (irg->visited > max_irg_visited) {
938 max_irg_visited = irg->visited;
940 #endif /* INTERPROCEDURAL_VIEW */
944 inc_irg_visited(ir_graph *irg) {
945 #ifdef INTERPROCEDURAL_VIEW
946 if (++irg->visited > max_irg_visited) {
947 max_irg_visited = irg->visited;
951 #endif /* INTERPROCEDURAL_VIEW */
954 #ifdef INTERPROCEDURAL_VIEW
956 get_max_irg_visited(void) {
959 for(i = 0; i < get_irp_n_irgs(); i++)
960 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
962 return max_irg_visited;
965 void set_max_irg_visited(int val) {
966 max_irg_visited = val;
970 inc_max_irg_visited(void) {
973 for(i = 0; i < get_irp_n_irgs(); i++)
974 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
976 return ++max_irg_visited;
978 #endif /* INTERPROCEDURAL_VIEW */
981 (get_irg_block_visited)(const ir_graph *irg) {
982 return _get_irg_block_visited(irg);
986 (set_irg_block_visited)(ir_graph *irg, unsigned long visited) {
987 _set_irg_block_visited(irg, visited);
991 (inc_irg_block_visited)(ir_graph *irg) {
992 _inc_irg_block_visited(irg);
995 /* Return the floating point model of this graph. */
996 unsigned (get_irg_fp_model)(const ir_graph *irg) {
997 return _get_irg_fp_model(irg);
1000 /* Sets the floating point model for this graph. */
1001 void set_irg_fp_model(ir_graph *irg, unsigned model) {
1002 irg->fp_model = model;
1006 * walker Start->End: places Proj nodes into the same block
1007 * as it's predecessors
1010 * @param env ignored
1012 static void normalize_proj_walker(ir_node *n, void *env) {
1015 ir_node *pred = get_Proj_pred(n);
1016 ir_node *block = get_nodes_block(pred);
1018 set_nodes_block(n, block);
1022 /* move Proj nodes into the same block as its predecessors */
1023 void normalize_proj_nodes(ir_graph *irg) {
1024 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1025 set_irg_outs_inconsistent(irg);
1028 /* set a description for local value n */
1029 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1030 assert(0 <= n && n < irg->n_loc);
1032 if (! irg->loc_descriptions)
1033 irg->loc_descriptions = xcalloc(sizeof(*irg->loc_descriptions), irg->n_loc);
1035 irg->loc_descriptions[n] = description;
1038 /* get the description for local value n */
1039 void *get_irg_loc_description(ir_graph *irg, int n) {
1040 assert(0 <= n && n < irg->n_loc);
1041 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1045 void set_using_block_visited(ir_graph *irg) {
1046 assert(irg->using_block_visited == 0);
1047 irg->using_block_visited = 1;
1050 void clear_using_block_visited(ir_graph *irg) {
1051 assert(irg->using_block_visited == 1);
1052 irg->using_block_visited = 0;
1055 int using_block_visited(const ir_graph *irg) {
1056 return irg->using_block_visited;
1060 void set_using_irn_visited(ir_graph *irg) {
1061 assert(irg->using_irn_visited == 0);
1062 irg->using_irn_visited = 1;
1065 void clear_using_irn_visited(ir_graph *irg) {
1066 assert(irg->using_irn_visited == 1);
1067 irg->using_irn_visited = 0;
1070 int using_irn_visited(const ir_graph *irg) {
1071 return irg->using_irn_visited;
1075 void set_using_irn_link(ir_graph *irg) {
1076 assert(irg->using_irn_link == 0);
1077 irg->using_irn_link = 1;
1080 void clear_using_irn_link(ir_graph *irg) {
1081 assert(irg->using_irn_link == 1);
1082 irg->using_irn_link = 0;
1085 int using_irn_link(const ir_graph *irg) {
1086 return irg->using_irn_link;
1090 /* Returns a estimated node count of the irg. */
1091 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1092 return _get_irg_estimated_node_cnt(irg);
1095 /* Returns the last irn index for this graph. */
1096 unsigned get_irg_last_idx(const ir_graph *irg) {
1097 return irg->last_node_idx;
1100 /* register additional space in an IR graph */
1101 size_t register_additional_graph_data(size_t size) {
1102 assert(!forbid_new_data && "Too late to register additional node data");
1104 if (forbid_new_data)
1107 return additional_graph_data_size += size;