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_initial_exec (res, projX);
263 set_irg_frame (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
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) {
386 ir_op *op = get_irn_op(n);
389 nn = new_ir_node(get_irn_dbg_info(n),
391 NULL, /* no block yet, will be set later */
398 /* Copy the attributes. These might point to additional data. If this
399 was allocated on the old obstack the pointers now are dangling. This
400 frees e.g. the memory of the graph_arr allocated in new_immBlock. */
401 copy_node_attr(n, nn);
402 new_backedge_info(nn);
405 /* fix the irg for blocks */
407 nn->attr.block.irg = irg;
409 /* fix access to entities on the stack frame */
411 ir_entity *ent = get_Sel_entity(nn);
412 ir_type *tp = get_entity_owner(ent);
414 if (is_frame_type(tp)) {
415 /* replace by the copied entity */
416 ent = get_entity_link(ent);
418 assert(is_entity(ent));
419 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
420 set_Sel_entity(nn, ent);
426 * Post-walker: Set the predecessors of the copied nodes.
427 * The copied nodes are set as link of their original nodes. The links of
428 * "irn" predecessors are the predecessors of copied node.
430 static void set_all_preds(ir_node *irn, void *env) {
435 nn = get_irn_link(irn);
438 ir_node *mbh = get_Block_MacroBlock(irn);
439 set_Block_MacroBlock(nn, get_irn_link(mbh));
440 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
441 pred = get_Block_cfgpred(irn, i);
442 set_Block_cfgpred(nn, i, get_irn_link(pred));
445 /* First we set the block our copy if it is not a block.*/
446 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
447 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
448 pred = get_irn_n(irn, i);
449 set_irn_n(nn, i, get_irn_link(pred));
454 #define NN(irn) get_irn_link(irn)
457 * Create a new graph that is a copy of a given one.
459 ir_graph *create_irg_copy(ir_graph *irg) {
465 res->visited = 0; /* visited flag, for the ir walker */
466 res->block_visited = 0; /* visited flag, for the 'block'-walker */
467 #if USE_EXPLICIT_PHI_IN_STACK
468 res->Phi_in_stack = NULL;
470 res->obst = xmalloc(sizeof(*res->obst));
471 obstack_init(res->obst);
472 res->extbb_obst = NULL;
474 res->last_node_idx = 0;
476 res->phase_state = irg->phase_state;
477 res->irg_pinned_state = irg->irg_pinned_state;
478 res->extblk_state = ir_extblk_info_none;
479 res->fp_model = irg->fp_model;
481 res->value_table = new_identities();
483 /* clone the frame type here for safety */
484 res->frame_type = clone_frame_type(irg->frame_type);
486 res->phase_state = irg->phase_state;
488 set_using_irn_link(irg);
490 /* copy all nodes from the graph irg to the new graph res */
491 irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
493 /* copy the Anchor node */
494 res->anchor = NN(irg->anchor);
496 /* -- The end block -- */
497 set_irg_end_block (res, NN(get_irg_end_block(irg)));
498 set_irg_end (res, NN(get_irg_end(irg)));
499 set_irg_end_reg (res, NN(get_irg_end_reg(irg)));
500 set_irg_end_except(res, NN(get_irg_end_except(irg)));
502 /* -- The start block -- */
503 set_irg_start_block(res, NN(get_irg_start_block(irg)));
504 set_irg_bad (res, NN(get_irg_bad(irg)));
505 set_irg_no_mem (res, NN(get_irg_no_mem(irg)));
506 set_irg_start (res, NN(get_irg_start(irg)));
508 /* Proj results of start node */
509 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
511 /* Copy the node count estimation. Would be strange if this
512 is different from the original one. */
513 res->estimated_node_count = irg->estimated_node_count;
515 clear_using_irn_link(irg);
522 /* Frees the passed irgraph.
523 Deallocates all nodes in this graph and the ir_graph structure.
524 Sets the field irgraph in the corresponding entity to NULL.
525 Does not remove the irgraph from the list in irprog (requires
526 inefficient search, call remove_irp_irg by hand).
527 Does not free types, entities or modes that are used only by this
528 graph, nor the entity standing for this graph. */
529 void free_ir_graph(ir_graph *irg) {
530 assert(is_ir_graph(irg));
532 edges_deactivate(irg);
534 hook_free_graph(irg);
535 if (irg->outs_state != outs_none)
538 free_type(irg->frame_type);
539 if (irg->value_table)
540 del_identities(irg->value_table);
542 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
543 set_entity_peculiarity (irg->ent, peculiarity_description);
544 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
545 set_entity_peculiarity (irg->ent, pec);
548 free_End(get_irg_end(irg));
549 obstack_free(irg->obst,NULL);
551 #if USE_EXPLICIT_PHI_IN_STACK
552 free_Phi_in_stack(irg->Phi_in_stack);
554 if (irg->loc_descriptions)
555 free(irg->loc_descriptions);
560 /* access routines for all ir_graph attributes:
562 {attr type} get_irg_{attribute name} (ir_graph *irg);
563 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
566 (is_ir_graph)(const void *thing) {
567 return _is_ir_graph(thing);
571 /* Outputs a unique number for this node */
572 long get_irg_graph_nr(const ir_graph *irg) {
573 return irg->graph_nr;
576 long get_irg_graph_nr(const ir_graph *irg) {
577 return PTR_TO_INT(irg);
581 int get_irg_idx(const ir_graph *irg) {
586 (get_irg_start_block)(const ir_graph *irg) {
587 return _get_irg_start_block(irg);
591 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
592 _set_irg_start_block(irg, node);
596 (get_irg_start)(const ir_graph *irg) {
597 return _get_irg_start(irg);
601 (set_irg_start)(ir_graph *irg, ir_node *node) {
602 _set_irg_start(irg, node);
606 (get_irg_end_block)(const ir_graph *irg) {
607 return _get_irg_end_block(irg);
611 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
612 _set_irg_end_block(irg, node);
616 (get_irg_end)(const ir_graph *irg) {
617 return _get_irg_end(irg);
621 (set_irg_end)(ir_graph *irg, ir_node *node) {
622 _set_irg_end(irg, node);
626 (get_irg_end_reg)(const ir_graph *irg) {
627 return _get_irg_end_reg(irg);
631 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
632 _set_irg_end_reg(irg, node);
636 (get_irg_end_except)(const ir_graph *irg) {
637 return _get_irg_end_except(irg);
641 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
642 assert(get_irn_op(node) == op_EndExcept || get_irn_op(node) == op_End);
643 _set_irg_end_except(irg, node);
647 (get_irg_initial_exec)(const ir_graph *irg) {
648 return _get_irg_initial_exec(irg);
652 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
653 _set_irg_initial_exec(irg, node);
657 (get_irg_frame)(const ir_graph *irg) {
658 return _get_irg_frame(irg);
662 (set_irg_frame)(ir_graph *irg, ir_node *node) {
663 _set_irg_frame(irg, node);
667 (get_irg_tls)(const ir_graph *irg) {
668 return _get_irg_tls(irg);
672 (set_irg_tls)(ir_graph *irg, ir_node *node) {
673 _set_irg_tls(irg, node);
677 (get_irg_initial_mem)(const ir_graph *irg) {
678 return _get_irg_initial_mem(irg);
682 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
683 _set_irg_initial_mem(irg, node);
687 (get_irg_args)(const ir_graph *irg) {
688 return _get_irg_args(irg);
692 (set_irg_args)(ir_graph *irg, ir_node *node) {
693 _set_irg_args(irg, node);
697 (get_irg_value_param_base)(const ir_graph *irg) {
698 return _get_irg_value_param_base(irg);
702 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
703 _set_irg_value_param_base(irg, node);
707 (get_irg_bad)(const ir_graph *irg) {
708 return _get_irg_bad(irg);
712 (set_irg_bad)(ir_graph *irg, ir_node *node) {
713 _set_irg_bad(irg, node);
717 (get_irg_no_mem)(const ir_graph *irg) {
718 return _get_irg_no_mem(irg);
722 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
723 _set_irg_no_mem(irg, node);
727 (get_irg_current_block)(const ir_graph *irg) {
728 return _get_irg_current_block(irg);
732 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
733 _set_irg_current_block(irg, node);
737 (get_irg_entity)(const ir_graph *irg) {
738 return _get_irg_entity(irg);
742 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
743 _set_irg_entity(irg, ent);
747 (get_irg_frame_type)(ir_graph *irg) {
748 return _get_irg_frame_type(irg);
752 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
753 _set_irg_frame_type(irg, ftp);
757 get_irg_n_locs(ir_graph *irg) {
758 if (get_opt_precise_exc_context())
759 return irg->n_loc - 1 - 1;
761 return irg->n_loc - 1;
765 set_irg_n_loc(ir_graph *irg, int n_loc) {
766 if (get_opt_precise_exc_context())
767 irg->n_loc = n_loc + 1 + 1;
769 irg->n_loc = n_loc + 1;
774 /* Returns the obstack associated with the graph. */
776 (get_irg_obstack)(const ir_graph *irg) {
777 return _get_irg_obstack(irg);
781 * Returns true if the node n is allocated on the storage of graph irg.
783 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
785 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
786 struct _obstack_chunk *p;
789 * checks weather the ir_node pointer is on the obstack.
790 * A more sophisticated check would test the "whole" ir_node
792 for (p = irg->obst->chunk; p; p = p->prev) {
793 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
801 (get_irg_phase_state)(const ir_graph *irg) {
802 return _get_irg_phase_state(irg);
806 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
807 _set_irg_phase_state(irg, state);
811 (get_irg_pinned)(const ir_graph *irg) {
812 return _get_irg_pinned(irg);
816 (get_irg_outs_state)(const ir_graph *irg) {
817 return _get_irg_outs_state(irg);
821 (set_irg_outs_inconsistent)(ir_graph *irg) {
822 _set_irg_outs_inconsistent(irg);
826 (get_irg_extblk_state)(const ir_graph *irg) {
827 return _get_irg_extblk_state(irg);
831 (set_irg_extblk_inconsistent)(ir_graph *irg) {
832 _set_irg_extblk_inconsistent(irg);
836 (get_irg_dom_state)(const ir_graph *irg) {
837 return _get_irg_dom_state(irg);
841 (get_irg_postdom_state)(const ir_graph *irg) {
842 return _get_irg_postdom_state(irg);
846 (set_irg_doms_inconsistent)(ir_graph *irg) {
847 _set_irg_doms_inconsistent(irg);
851 (get_irg_loopinfo_state)(const ir_graph *irg) {
852 return _get_irg_loopinfo_state(irg);
856 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
857 _set_irg_loopinfo_state(irg, s);
861 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
862 _set_irg_loopinfo_inconsistent(irg);
865 void set_irp_loopinfo_inconsistent(void) {
867 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
868 set_irg_loopinfo_inconsistent(get_irp_irg(i));
875 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
876 _set_irg_pinned(irg, p);
879 irg_callee_info_state
880 (get_irg_callee_info_state)(const ir_graph *irg) {
881 return _get_irg_callee_info_state(irg);
885 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
886 _set_irg_callee_info_state(irg, s);
890 (get_irg_inline_property)(const ir_graph *irg) {
891 return _get_irg_inline_property(irg);
895 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
896 _set_irg_inline_property(irg, s);
900 (get_irg_additional_properties)(const ir_graph *irg) {
901 return _get_irg_additional_properties(irg);
905 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
906 _set_irg_additional_properties(irg, property_mask);
910 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
911 _set_irg_additional_property(irg, flag);
915 (set_irg_link)(ir_graph *irg, void *thing) {
916 _set_irg_link(irg, thing);
920 (get_irg_link)(const ir_graph *irg) {
921 return _get_irg_link(irg);
925 (get_irg_visited)(const ir_graph *irg) {
926 return _get_irg_visited(irg);
929 #ifdef INTERPROCEDURAL_VIEW
930 /** maximum visited flag content of all ir_graph visited fields. */
931 static unsigned long max_irg_visited = 0;
932 #endif /* INTERPROCEDURAL_VIEW */
935 set_irg_visited(ir_graph *irg, unsigned long visited) {
936 irg->visited = visited;
937 #ifdef INTERPROCEDURAL_VIEW
938 if (irg->visited > max_irg_visited) {
939 max_irg_visited = irg->visited;
941 #endif /* INTERPROCEDURAL_VIEW */
945 inc_irg_visited(ir_graph *irg) {
946 #ifdef INTERPROCEDURAL_VIEW
947 if (++irg->visited > max_irg_visited) {
948 max_irg_visited = irg->visited;
952 #endif /* INTERPROCEDURAL_VIEW */
955 #ifdef INTERPROCEDURAL_VIEW
957 get_max_irg_visited(void) {
960 for(i = 0; i < get_irp_n_irgs(); i++)
961 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
963 return max_irg_visited;
966 void set_max_irg_visited(int val) {
967 max_irg_visited = val;
971 inc_max_irg_visited(void) {
974 for(i = 0; i < get_irp_n_irgs(); i++)
975 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
977 return ++max_irg_visited;
979 #endif /* INTERPROCEDURAL_VIEW */
982 (get_irg_block_visited)(const ir_graph *irg) {
983 return _get_irg_block_visited(irg);
987 (set_irg_block_visited)(ir_graph *irg, unsigned long visited) {
988 _set_irg_block_visited(irg, visited);
992 (inc_irg_block_visited)(ir_graph *irg) {
993 _inc_irg_block_visited(irg);
996 /* Return the floating point model of this graph. */
997 unsigned (get_irg_fp_model)(const ir_graph *irg) {
998 return _get_irg_fp_model(irg);
1001 /* Sets the floating point model for this graph. */
1002 void set_irg_fp_model(ir_graph *irg, unsigned model) {
1003 irg->fp_model = model;
1007 * walker Start->End: places Proj nodes into the same block
1008 * as it's predecessors
1011 * @param env ignored
1013 static void normalize_proj_walker(ir_node *n, void *env) {
1016 ir_node *pred = get_Proj_pred(n);
1017 ir_node *block = get_nodes_block(pred);
1019 set_nodes_block(n, block);
1023 /* move Proj nodes into the same block as its predecessors */
1024 void normalize_proj_nodes(ir_graph *irg) {
1025 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1026 set_irg_outs_inconsistent(irg);
1029 /* set a description for local value n */
1030 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1031 assert(0 <= n && n < irg->n_loc);
1033 if (! irg->loc_descriptions)
1034 irg->loc_descriptions = xcalloc(sizeof(*irg->loc_descriptions), irg->n_loc);
1036 irg->loc_descriptions[n] = description;
1039 /* get the description for local value n */
1040 void *get_irg_loc_description(ir_graph *irg, int n) {
1041 assert(0 <= n && n < irg->n_loc);
1042 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1046 void set_using_block_visited(ir_graph *irg) {
1047 assert(irg->using_block_visited == 0);
1048 irg->using_block_visited = 1;
1051 void clear_using_block_visited(ir_graph *irg) {
1052 assert(irg->using_block_visited == 1);
1053 irg->using_block_visited = 0;
1056 int using_block_visited(const ir_graph *irg) {
1057 return irg->using_block_visited;
1061 void set_using_irn_visited(ir_graph *irg) {
1062 assert(irg->using_irn_visited == 0);
1063 irg->using_irn_visited = 1;
1066 void clear_using_irn_visited(ir_graph *irg) {
1067 assert(irg->using_irn_visited == 1);
1068 irg->using_irn_visited = 0;
1071 int using_irn_visited(const ir_graph *irg) {
1072 return irg->using_irn_visited;
1076 void set_using_irn_link(ir_graph *irg) {
1077 assert(irg->using_irn_link == 0);
1078 irg->using_irn_link = 1;
1081 void clear_using_irn_link(ir_graph *irg) {
1082 assert(irg->using_irn_link == 1);
1083 irg->using_irn_link = 0;
1086 int using_irn_link(const ir_graph *irg) {
1087 return irg->using_irn_link;
1090 void set_using_block_mark(ir_graph *irg) {
1091 assert(irg->using_block_mark == 0);
1092 irg->using_block_mark = 1;
1095 void clear_using_block_mark(ir_graph *irg) {
1096 assert(irg->using_block_mark == 1);
1097 irg->using_block_mark = 0;
1100 int using_block_mark(const ir_graph *irg) {
1101 return irg->using_block_mark;
1105 /* Returns a estimated node count of the irg. */
1106 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1107 return _get_irg_estimated_node_cnt(irg);
1110 /* Returns the last irn index for this graph. */
1111 unsigned get_irg_last_idx(const ir_graph *irg) {
1112 return irg->last_node_idx;
1115 /* register additional space in an IR graph */
1116 size_t register_additional_graph_data(size_t size) {
1117 assert(!forbid_new_data && "Too late to register additional node data");
1119 if (forbid_new_data)
1122 return additional_graph_data_size += size;