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);
148 /* Allocates a list of nodes:
149 - The start block containing a start node and Proj nodes for it's four
150 results (X, M, P, Tuple).
151 - The end block containing an end node. This block is not matured after
152 new_ir_graph as predecessors need to be added to it.
153 - The current block, which is empty and also not matured.
154 Further it allocates several datastructures needed for graph construction
157 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
159 ir_node *first_block;
160 ir_node *end, *start, *start_block, *initial_mem, *projX;
164 /* inform statistics here, as blocks will be already build on this graph */
165 hook_new_graph(res, ent);
167 current_ir_graph = res;
169 /*-- initialized for each graph. --*/
170 if (get_opt_precise_exc_context()) {
171 res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
172 dereferenced in this graph plus one for
173 the store plus one for links to fragile
174 operations. n_loc is not the number of
175 parameters to the procedure! */
177 res->n_loc = n_loc + 1; /* number of local variables that are never
178 dereferenced in this graph plus one for
179 the store. This is not the number of parameters
183 /* descriptions will be allocated on demand */
184 res->loc_descriptions = NULL;
186 res->visited = 0; /* visited flag, for the ir walker */
187 res->block_visited = 0; /* visited flag, for the 'block'-walker */
189 #if USE_EXPLICIT_PHI_IN_STACK
190 res->Phi_in_stack = new_Phi_in_stack(); /* A stack needed for automatic Phi
193 res->kind = k_ir_graph;
194 res->obst = xmalloc (sizeof(*res->obst));
195 obstack_init(res->obst);
196 res->extbb_obst = NULL;
198 res->last_node_idx = 0;
200 res->value_table = new_identities (); /* value table for global value
201 numbering for optimizing use in iropt.c */
204 res->inline_property = irg_inline_any;
205 res->additional_properties = mtp_property_inherited; /* inherited from type */
207 res->phase_state = phase_building;
208 res->irg_pinned_state = op_pin_state_pinned;
209 res->outs_state = outs_none;
210 res->dom_state = dom_none;
211 res->pdom_state = dom_none;
212 res->typeinfo_state = ir_typeinfo_none;
213 set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
214 res->callee_info_state = irg_callee_info_none;
215 res->loopinfo_state = loopinfo_none;
216 res->class_cast_state = ir_class_casts_transitive;
217 res->extblk_state = ir_extblk_info_none;
218 res->execfreq_state = exec_freq_none;
219 res->fp_model = fp_model_precise;
220 res->adr_taken_state = ir_address_taken_not_computed;
221 res->mem_disambig_opt = aa_opt_inherited;
223 /*-- Type information for the procedure of the graph --*/
225 set_entity_irg(ent, res);
227 /*-- a class type so that it can contain "inner" methods as in Pascal. --*/
228 res->frame_type = new_type_frame(mangle(get_entity_ident(ent), frame_type_suffix));
230 /* the Anchor node must be created first */
231 res->anchor = new_Anchor(res);
233 /*-- Nodes needed in every graph --*/
234 set_irg_end_block (res, new_immBlock());
236 set_irg_end (res, end);
237 set_irg_end_reg (res, end);
238 set_irg_end_except(res, end);
240 start_block = new_immBlock();
241 set_irg_start_block(res, start_block);
242 set_irg_bad (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
243 set_irg_no_mem (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
245 set_irg_start (res, start);
247 /* Proj results of start node */
248 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
249 set_irg_frame (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
250 set_irg_globals (res, new_Proj(start, mode_P_data, pn_Start_P_globals));
251 set_irg_tls (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
252 set_irg_args (res, new_Proj(start, mode_T, pn_Start_T_args));
253 set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
254 initial_mem = new_Proj(start, mode_M, pn_Start_M);
255 set_irg_initial_mem(res, initial_mem);
257 add_immBlock_pred(start_block, projX);
258 set_store(initial_mem);
260 res->index = get_irp_new_irg_idx();
262 res->graph_nr = get_irp_new_node_nr();
266 * The code generation needs it. leave it in now.
267 * Use of this edge is matter of discussion, unresolved. Also possible:
268 * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
270 mature_immBlock(res->current_block);
272 /*-- Make a block to start with --*/
273 first_block = new_immBlock();
274 add_immBlock_pred(first_block, projX);
276 res->method_execution_frequency = -1.0;
277 res->estimated_node_count = 0;
282 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
283 ir_graph *res = new_r_ir_graph(ent, n_loc);
284 add_irp_irg(res); /* remember this graph global. */
288 /* Make a rudimentary IR graph for the constant code.
289 Must look like a correct irg, spare everything else. */
290 ir_graph *new_const_code_irg(void) {
292 ir_node *end, *start_block, *start, *projX;
296 /* inform statistics here, as blocks will be already build on this graph */
297 hook_new_graph(res, NULL);
299 current_ir_graph = res;
300 res->n_loc = 1; /* Only the memory. */
301 res->visited = 0; /* visited flag, for the ir walker */
302 res->block_visited = 0; /* visited flag, for the 'block'-walker */
303 #if USE_EXPLICIT_PHI_IN_STACK
304 res->Phi_in_stack = NULL;
306 res->obst = xmalloc(sizeof(*res->obst));
307 obstack_init (res->obst);
308 res->extbb_obst = NULL;
310 res->last_node_idx = 0;
312 res->phase_state = phase_building;
313 res->irg_pinned_state = op_pin_state_pinned;
314 res->extblk_state = ir_extblk_info_none;
315 res->fp_model = fp_model_precise;
317 res->value_table = new_identities(); /* value table for global value
318 numbering for optimizing use in
321 res->frame_type = NULL;
323 /* the Anchor node must be created first */
324 res->anchor = new_Anchor(res);
326 /* -- The end block -- */
327 set_irg_end_block (res, new_immBlock());
329 set_irg_end (res, end);
330 set_irg_end_reg (res, end);
331 set_irg_end_except(res, end);
332 mature_immBlock(get_cur_block()); /* mature the end block */
334 /* -- The start block -- */
335 start_block = new_immBlock();
336 set_irg_start_block(res, start_block);
337 set_irg_bad (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
338 set_irg_no_mem (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
340 set_irg_start (res, start);
342 /* Proj results of start node */
343 set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
344 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
345 add_immBlock_pred(start_block, projX);
346 mature_immBlock (start_block); /* mature the start block */
348 add_immBlock_pred(new_immBlock(), projX);
349 mature_immBlock (get_cur_block()); /* mature the 'body' block for expressions */
351 /* Set the visited flag high enough that the blocks will never be visited. */
352 set_irn_visited(get_cur_block(), -1);
353 set_Block_block_visited(get_cur_block(), -1);
354 set_Block_block_visited(start_block, -1);
355 set_irn_visited(start_block, -1);
356 set_irn_visited(get_irg_bad(res), -1);
357 set_irn_visited(get_irg_no_mem(res), -1);
359 res->phase_state = phase_high;
365 * Pre-Walker: Copies blocks and nodes from the original method graph
366 * to the copied graph.
368 * @param n A node from the original method graph.
369 * @param env The copied graph.
371 static void copy_all_nodes(ir_node *n, void *env) {
372 ir_graph *irg = current_ir_graph;
373 ir_op *op = get_irn_op(n);
376 nn = new_ir_node(get_irn_dbg_info(n),
378 NULL, /* no block yet, will be set later */
385 /* Copy the attributes. These might point to additional data. If this
386 was allocated on the old obstack the pointers now are dangling. This
387 frees e.g. the memory of the graph_arr allocated in new_immBlock. */
388 copy_node_attr(n, nn);
389 new_backedge_info(nn);
392 /* fix the irg for blocks */
394 nn->attr.block.irg = irg;
396 /* fix access to entities on the stack frame */
398 ir_entity *ent = get_Sel_entity(nn);
399 ir_type *tp = get_entity_owner(ent);
401 if (is_frame_type(tp)) {
402 /* replace by the copied entity */
403 ent = get_entity_link(ent);
405 assert(is_entity(ent));
406 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
407 set_Sel_entity(nn, ent);
413 * Post-walker: Set the predecessors of the copied nodes.
414 * The copied nodes are set as link of their original nodes. The links of
415 * "irn" predecessors are the predecessors of copied node.
417 static void set_all_preds(ir_node *irn, void *env) {
420 ir_graph *clone_irg = env;
422 nn = get_irn_link(irn);
425 ir_node *mbh = get_Block_MacroBlock(irn);
426 set_Block_MacroBlock(nn, get_irn_link(mbh));
427 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
428 pred = get_Block_cfgpred(irn, i);
429 set_Block_cfgpred(nn, i, get_irn_link(pred));
432 /* First we set the block our copy if it is not a block.*/
433 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
434 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
435 pred = get_irn_n(irn, i);
436 set_irn_n(nn, i, get_irn_link(pred));
441 #define NN(irn) get_irn_link(irn)
444 * Create a new graph that is a copy of a given one.
446 ir_graph *create_irg_copy(ir_graph *irg) {
452 res->visited = 0; /* visited flag, for the ir walker */
453 res->block_visited = 0; /* visited flag, for the 'block'-walker */
454 #if USE_EXPLICIT_PHI_IN_STACK
455 res->Phi_in_stack = NULL;
457 res->obst = xmalloc(sizeof(*res->obst));
458 obstack_init(res->obst);
459 res->extbb_obst = NULL;
461 res->last_node_idx = 0;
463 res->phase_state = irg->phase_state;
464 res->irg_pinned_state = irg->irg_pinned_state;
465 res->extblk_state = ir_extblk_info_none;
466 res->fp_model = irg->fp_model;
468 res->value_table = new_identities();
470 /* clone the frame type here for safety */
471 res->frame_type = clone_frame_type(irg->frame_type);
473 res->phase_state = irg->phase_state;
475 set_using_irn_link(irg);
477 /* copy all nodes from the graph irg to the new graph res */
478 irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
480 /* copy the Anchor node */
481 res->anchor = NN(irg->anchor);
483 /* -- The end block -- */
484 set_irg_end_block (res, NN(get_irg_end_block(irg)));
485 set_irg_end (res, NN(get_irg_end(irg)));
486 set_irg_end_reg (res, NN(get_irg_end_reg(irg)));
487 set_irg_end_except(res, NN(get_irg_end_except(irg)));
489 /* -- The start block -- */
490 set_irg_start_block(res, NN(get_irg_start_block(irg)));
491 set_irg_bad (res, NN(get_irg_bad(irg)));
492 set_irg_no_mem (res, NN(get_irg_no_mem(irg)));
493 set_irg_start (res, NN(get_irg_start(irg)));
495 /* Proj results of start node */
496 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
498 /* Copy the node count estimation. Would be strange if this
499 is different from the original one. */
500 res->estimated_node_count = irg->estimated_node_count;
502 clear_using_irn_link(irg);
509 /* Frees the passed irgraph.
510 Deallocates all nodes in this graph and the ir_graph structure.
511 Sets the field irgraph in the corresponding entity to NULL.
512 Does not remove the irgraph from the list in irprog (requires
513 inefficient search, call remove_irp_irg by hand).
514 Does not free types, entities or modes that are used only by this
515 graph, nor the entity standing for this graph. */
516 void free_ir_graph(ir_graph *irg) {
517 assert(is_ir_graph(irg));
519 hook_free_graph(irg);
520 if (irg->outs_state != outs_none)
523 free_type(irg->frame_type);
524 if (irg->value_table)
525 del_identities(irg->value_table);
527 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
528 set_entity_peculiarity (irg->ent, peculiarity_description);
529 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
530 set_entity_peculiarity (irg->ent, pec);
533 free_End(get_irg_end(irg));
534 obstack_free(irg->obst,NULL);
536 #if USE_EXPLICIT_PHI_IN_STACK
537 free_Phi_in_stack(irg->Phi_in_stack);
539 if (irg->loc_descriptions)
540 free(irg->loc_descriptions);
545 /* access routines for all ir_graph attributes:
547 {attr type} get_irg_{attribute name} (ir_graph *irg);
548 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
551 (is_ir_graph)(const void *thing) {
552 return _is_ir_graph(thing);
556 /* Outputs a unique number for this node */
557 long get_irg_graph_nr(const ir_graph *irg) {
558 return irg->graph_nr;
561 long get_irg_graph_nr(const ir_graph *irg) {
562 return PTR_TO_INT(irg);
566 int get_irg_idx(const ir_graph *irg) {
571 (get_irg_start_block)(const ir_graph *irg) {
572 return _get_irg_start_block(irg);
576 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
577 _set_irg_start_block(irg, node);
581 (get_irg_start)(const ir_graph *irg) {
582 return _get_irg_start(irg);
586 (set_irg_start)(ir_graph *irg, ir_node *node) {
587 _set_irg_start(irg, node);
591 (get_irg_end_block)(const ir_graph *irg) {
592 return _get_irg_end_block(irg);
596 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
597 _set_irg_end_block(irg, node);
601 (get_irg_end)(const ir_graph *irg) {
602 return _get_irg_end(irg);
606 (set_irg_end)(ir_graph *irg, ir_node *node) {
607 _set_irg_end(irg, node);
611 (get_irg_end_reg)(const ir_graph *irg) {
612 return _get_irg_end_reg(irg);
616 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
617 _set_irg_end_reg(irg, node);
621 (get_irg_end_except)(const ir_graph *irg) {
622 return _get_irg_end_except(irg);
626 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
627 assert(get_irn_op(node) == op_EndExcept || get_irn_op(node) == op_End);
628 _set_irg_end_except(irg, node);
632 (get_irg_frame)(const ir_graph *irg) {
633 return _get_irg_frame(irg);
637 (set_irg_frame)(ir_graph *irg, ir_node *node) {
638 _set_irg_frame(irg, node);
642 (get_irg_globals)(const ir_graph *irg) {
643 return _get_irg_globals(irg);
647 (set_irg_globals)(ir_graph *irg, ir_node *node) {
648 _set_irg_globals(irg, node);
652 (get_irg_tls)(const ir_graph *irg) {
653 return _get_irg_tls(irg);
657 (set_irg_tls)(ir_graph *irg, ir_node *node) {
658 _set_irg_tls(irg, node);
662 (get_irg_initial_mem)(const ir_graph *irg) {
663 return _get_irg_initial_mem(irg);
667 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
668 _set_irg_initial_mem(irg, node);
672 (get_irg_args)(const ir_graph *irg) {
673 return _get_irg_args(irg);
677 (set_irg_args)(ir_graph *irg, ir_node *node) {
678 _set_irg_args(irg, node);
682 (get_irg_value_param_base)(const ir_graph *irg) {
683 return _get_irg_value_param_base(irg);
687 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
688 _set_irg_value_param_base(irg, node);
692 (get_irg_bad)(const ir_graph *irg) {
693 return _get_irg_bad(irg);
697 (set_irg_bad)(ir_graph *irg, ir_node *node) {
698 _set_irg_bad(irg, node);
702 (get_irg_no_mem)(const ir_graph *irg) {
703 return _get_irg_no_mem(irg);
707 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
708 _set_irg_no_mem(irg, node);
712 (get_irg_current_block)(const ir_graph *irg) {
713 return _get_irg_current_block(irg);
717 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
718 _set_irg_current_block(irg, node);
722 (get_irg_entity)(const ir_graph *irg) {
723 return _get_irg_entity(irg);
727 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
728 _set_irg_entity(irg, ent);
732 (get_irg_frame_type)(ir_graph *irg) {
733 return _get_irg_frame_type(irg);
737 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
738 _set_irg_frame_type(irg, ftp);
742 get_irg_n_locs(ir_graph *irg) {
743 if (get_opt_precise_exc_context())
744 return irg->n_loc - 1 - 1;
746 return irg->n_loc - 1;
750 set_irg_n_loc(ir_graph *irg, int n_loc) {
751 if (get_opt_precise_exc_context())
752 irg->n_loc = n_loc + 1 + 1;
754 irg->n_loc = n_loc + 1;
759 /* Returns the obstack associated with the graph. */
761 (get_irg_obstack)(const ir_graph *irg) {
762 return _get_irg_obstack(irg);
766 * Returns true if the node n is allocated on the storage of graph irg.
768 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
770 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
771 struct _obstack_chunk *p;
774 * checks weather the ir_node pointer is on the obstack.
775 * A more sophisticated check would test the "whole" ir_node
777 for (p = irg->obst->chunk; p; p = p->prev) {
778 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
786 (get_irg_phase_state)(const ir_graph *irg) {
787 return _get_irg_phase_state(irg);
791 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
792 _set_irg_phase_state(irg, state);
796 (get_irg_pinned)(const ir_graph *irg) {
797 return _get_irg_pinned(irg);
801 (get_irg_outs_state)(const ir_graph *irg) {
802 return _get_irg_outs_state(irg);
806 (set_irg_outs_inconsistent)(ir_graph *irg) {
807 _set_irg_outs_inconsistent(irg);
811 (get_irg_extblk_state)(const ir_graph *irg) {
812 return _get_irg_extblk_state(irg);
816 (set_irg_extblk_inconsistent)(ir_graph *irg) {
817 _set_irg_extblk_inconsistent(irg);
821 (get_irg_dom_state)(const ir_graph *irg) {
822 return _get_irg_dom_state(irg);
826 (get_irg_postdom_state)(const ir_graph *irg) {
827 return _get_irg_postdom_state(irg);
831 (set_irg_doms_inconsistent)(ir_graph *irg) {
832 _set_irg_doms_inconsistent(irg);
836 (get_irg_loopinfo_state)(const ir_graph *irg) {
837 return _get_irg_loopinfo_state(irg);
841 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
842 _set_irg_loopinfo_state(irg, s);
846 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
847 _set_irg_loopinfo_inconsistent(irg);
850 void set_irp_loopinfo_inconsistent(void) {
852 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
853 set_irg_loopinfo_inconsistent(get_irp_irg(i));
860 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
861 _set_irg_pinned(irg, p);
864 irg_callee_info_state
865 (get_irg_callee_info_state)(const ir_graph *irg) {
866 return _get_irg_callee_info_state(irg);
870 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
871 _set_irg_callee_info_state(irg, s);
875 (get_irg_inline_property)(const ir_graph *irg) {
876 return _get_irg_inline_property(irg);
880 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
881 _set_irg_inline_property(irg, s);
885 (get_irg_additional_properties)(const ir_graph *irg) {
886 return _get_irg_additional_properties(irg);
890 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
891 _set_irg_additional_properties(irg, property_mask);
895 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
896 _set_irg_additional_property(irg, flag);
900 (set_irg_link)(ir_graph *irg, void *thing) {
901 _set_irg_link(irg, thing);
905 (get_irg_link)(const ir_graph *irg) {
906 return _get_irg_link(irg);
910 (get_irg_visited)(const ir_graph *irg) {
911 return _get_irg_visited(irg);
914 #ifdef INTERPROCEDURAL_VIEW
915 /** maximum visited flag content of all ir_graph visited fields. */
916 static unsigned long max_irg_visited = 0;
917 #endif /* INTERPROCEDURAL_VIEW */
920 set_irg_visited(ir_graph *irg, unsigned long visited) {
921 irg->visited = visited;
922 #ifdef INTERPROCEDURAL_VIEW
923 if (irg->visited > max_irg_visited) {
924 max_irg_visited = irg->visited;
926 #endif /* INTERPROCEDURAL_VIEW */
930 inc_irg_visited(ir_graph *irg) {
931 #ifdef INTERPROCEDURAL_VIEW
932 if (++irg->visited > max_irg_visited) {
933 max_irg_visited = irg->visited;
937 #endif /* INTERPROCEDURAL_VIEW */
940 #ifdef INTERPROCEDURAL_VIEW
942 get_max_irg_visited(void) {
945 for(i = 0; i < get_irp_n_irgs(); i++)
946 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
948 return max_irg_visited;
951 void set_max_irg_visited(int val) {
952 max_irg_visited = val;
956 inc_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;
964 #endif /* INTERPROCEDURAL_VIEW */
967 (get_irg_block_visited)(const ir_graph *irg) {
968 return _get_irg_block_visited(irg);
972 (set_irg_block_visited)(ir_graph *irg, unsigned long visited) {
973 _set_irg_block_visited(irg, visited);
977 (inc_irg_block_visited)(ir_graph *irg) {
978 _inc_irg_block_visited(irg);
981 /* Return the floating point model of this graph. */
982 unsigned (get_irg_fp_model)(const ir_graph *irg) {
983 return _get_irg_fp_model(irg);
986 /* Sets the floating point model for this graph. */
987 void set_irg_fp_model(ir_graph *irg, unsigned model) {
988 irg->fp_model = model;
992 * walker Start->End: places Proj nodes into the same block
993 * as it's predecessors
998 static void normalize_proj_walker(ir_node *n, void *env) {
1001 ir_node *pred = get_Proj_pred(n);
1002 ir_node *block = get_nodes_block(pred);
1004 set_nodes_block(n, block);
1008 /* move Proj nodes into the same block as its predecessors */
1009 void normalize_proj_nodes(ir_graph *irg) {
1010 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1011 set_irg_outs_inconsistent(irg);
1014 /* set a description for local value n */
1015 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1016 assert(0 <= n && n < irg->n_loc);
1018 if (! irg->loc_descriptions)
1019 irg->loc_descriptions = xcalloc(sizeof(*irg->loc_descriptions), irg->n_loc);
1021 irg->loc_descriptions[n] = description;
1024 /* get the description for local value n */
1025 void *get_irg_loc_description(ir_graph *irg, int n) {
1026 assert(0 <= n && n < irg->n_loc);
1027 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1031 void set_using_block_visited(ir_graph *irg) {
1032 assert(irg->using_block_visited == 0);
1033 irg->using_block_visited = 1;
1036 void clear_using_block_visited(ir_graph *irg) {
1037 assert(irg->using_block_visited == 1);
1038 irg->using_block_visited = 0;
1041 int using_block_visited(const ir_graph *irg) {
1042 return irg->using_block_visited;
1046 void set_using_irn_visited(ir_graph *irg) {
1047 assert(irg->using_irn_visited == 0);
1048 irg->using_irn_visited = 1;
1051 void clear_using_irn_visited(ir_graph *irg) {
1052 assert(irg->using_irn_visited == 1);
1053 irg->using_irn_visited = 0;
1056 int using_irn_visited(const ir_graph *irg) {
1057 return irg->using_irn_visited;
1061 void set_using_irn_link(ir_graph *irg) {
1062 assert(irg->using_irn_link == 0);
1063 irg->using_irn_link = 1;
1066 void clear_using_irn_link(ir_graph *irg) {
1067 assert(irg->using_irn_link == 1);
1068 irg->using_irn_link = 0;
1071 int using_irn_link(const ir_graph *irg) {
1072 return irg->using_irn_link;
1076 /* Returns a estimated node count of the irg. */
1077 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1078 return _get_irg_estimated_node_cnt(irg);
1081 /* Returns the last irn index for this graph. */
1082 unsigned get_irg_last_idx(const ir_graph *irg) {
1083 return irg->last_node_idx;
1086 /* register additional space in an IR graph */
1087 size_t register_additional_graph_data(size_t size) {
1088 assert(!forbid_new_data && "Too late to register additional node data");
1090 if (forbid_new_data)
1093 return additional_graph_data_size += size;