f84f4e78e570c598035419a9dd155550fe1eb313
[libfirm] / ir / ir / irgraph.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irgraph.c
4  * Purpose:     Entry point to the representation of procedure code.
5  * Author:      Martin Trapp, Christian Schaefer
6  * Modified by: Goetz Lindenmaier
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #ifdef HAVE_STRING_H
18 # include <string.h>
19 #endif
20 #ifdef HAVE_STDDEF_H
21 # include <stddef.h>
22 #endif
23
24 #include "xmalloc.h"
25 #include "ircons.h"
26 #include "irgraph_t.h"
27 #include "irprog_t.h"
28 #include "irnode_t.h"
29 #include "iropt_t.h"
30 #include "irflag_t.h"
31 #include "array.h"
32 #include "irgmod.h"
33 #include "mangle.h"
34 #include "irouts.h"
35 #include "irhooks.h"
36 #include "irtools.h"
37 #include "irgwalk.h"
38 #include "iredges_t.h"
39 #include "type_t.h"
40
41 #define INITIAL_IDX_IRN_MAP_SIZE 1024
42
43 /**
44  * Indicates, whether additional data can be registered to graphs.
45  * If set to 1, this is not possible anymore.
46  */
47 static int forbid_new_data = 0;
48
49 /**
50  * The amount of additional space for custom data to be allocated upon
51  * creating a new graph.
52  */
53 static size_t additional_graph_data_size = 0;
54
55 ir_graph *current_ir_graph;
56 ir_graph *get_current_ir_graph(void) {
57   return current_ir_graph;
58 }
59 void set_current_ir_graph(ir_graph *graph) {
60   current_ir_graph = graph;
61 }
62
63
64 int firm_interprocedural_view = 0;
65
66 int (get_interprocedural_view)(void) {
67   return _get_interprocedural_view();
68 }
69
70 void (set_interprocedural_view)(int state) {
71   firm_interprocedural_view = state;
72
73   /* set function vectors for faster access */
74   if (state) {
75     _get_irn_arity = _get_irn_inter_arity;
76     _get_irn_n     = _get_irn_inter_n;
77   }
78   else {
79     _get_irn_arity = _get_irn_intra_arity;
80     _get_irn_n     = _get_irn_intra_n;
81   }
82 }
83
84 /** contains the suffix for frame type names */
85 static ident *frame_type_suffix = NULL;
86
87 /* initialize the IR graph module */
88 void firm_init_irgraph(void) {
89   frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
90   forbid_new_data   = 1;
91 }
92
93 /**
94  * Allocate a new IR graph.
95  * This function respects the registered graph data. The only reason for
96  * this function is, that there are two locations, where graphs are
97  * allocated (new_r_ir_graph, new_const_code_irg).
98  * @return Memory for a new graph.
99  */
100 static ir_graph *alloc_graph(void) {
101   size_t size = sizeof(ir_graph) + additional_graph_data_size;
102   char *ptr = xmalloc(size);
103   memset(ptr, 0, size);
104
105   return (ir_graph *) (ptr + additional_graph_data_size);
106 }
107
108 /**
109  * Frees an allocated IR graph
110  */
111 static void free_graph(ir_graph *irg) {
112   char *ptr = (char *)irg;
113   free(ptr - additional_graph_data_size);
114 }
115
116 #if USE_EXPLICIT_PHI_IN_STACK
117 /* really defined in ircons.c */
118 typedef struct Phi_in_stack Phi_in_stack;
119 Phi_in_stack *new_Phi_in_stack();
120 void free_Phi_in_stack(Phi_in_stack *s);
121 #endif
122
123 /* Allocates a list of nodes:
124     - The start block containing a start node and Proj nodes for it's four
125       results (X, M, P, Tuple).
126     - The end block containing an end node. This block is not matured after
127       new_ir_graph as predecessors need to be added to it.
128     - The current block, which is empty and also not matured.
129    Further it allocates several datastructures needed for graph construction
130    and optimization.
131 */
132 ir_graph *
133 new_r_ir_graph (ir_entity *ent, int n_loc)
134 {
135   ir_graph *res;
136   ir_node  *first_block;
137   ir_node  *end, *start, *start_block, *initial_mem, *projX;
138
139   res = alloc_graph();
140   res->kind = k_ir_graph;
141
142   //edges_init_graph_kind(res, EDGE_KIND_NORMAL);
143   //edges_init_graph_kind(res, EDGE_KIND_BLOCK);
144
145   /* initialize the idx->node map. */
146   res->idx_irn_map = NEW_ARR_F(ir_node *, INITIAL_IDX_IRN_MAP_SIZE);
147   memset(res->idx_irn_map, 0, INITIAL_IDX_IRN_MAP_SIZE * sizeof(res->idx_irn_map[0]));
148
149   /* inform statistics here, as blocks will be already build on this graph */
150   hook_new_graph(res, ent);
151
152   current_ir_graph = res;
153
154   /*-- initialized for each graph. --*/
155   if (get_opt_precise_exc_context()) {
156     res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
157                    dereferenced in this graph plus one for
158                    the store plus one for links to fragile
159                    operations.  n_loc is not the number of
160                    parameters to the procedure!  */
161   }
162   else {
163     res->n_loc = n_loc + 1;  /* number of local variables that are never
164                 dereferenced in this graph plus one for
165                 the store. This is not the number of parameters
166                 to the procedure!  */
167   }
168
169   /* descriptions will be allocated on demand */
170   res->loc_descriptions = NULL;
171
172   res->visited       = 0; /* visited flag, for the ir walker */
173   res->block_visited = 0; /* visited flag, for the 'block'-walker */
174
175 #if USE_EXPLICIT_PHI_IN_STACK
176   res->Phi_in_stack = new_Phi_in_stack();  /* A stack needed for automatic Phi
177                                 generation */
178 #endif
179   res->kind = k_ir_graph;
180   res->obst = xmalloc (sizeof(*res->obst));
181   obstack_init(res->obst);
182   res->extbb_obst = NULL;
183
184   res->last_node_idx = 0;
185
186   res->value_table = new_identities (); /* value table for global value
187                        numbering for optimizing use in
188                        iropt.c */
189   res->outs = NULL;
190
191   res->inline_property       = irg_inline_any;
192   res->additional_properties = mtp_property_inherited;  /* inherited from type */
193
194   res->phase_state         = phase_building;
195   res->irg_pinned_state    = op_pin_state_pinned;
196   res->outs_state          = outs_none;
197   res->dom_state           = dom_none;
198   res->pdom_state          = dom_none;
199   res->typeinfo_state      = ir_typeinfo_none;
200   set_irp_typeinfo_inconsistent();           /* there is a new graph with typeinfo_none. */
201   res->callee_info_state   = irg_callee_info_none;
202   res->loopinfo_state      = loopinfo_none;
203   res->execfreq_state      = exec_freq_none;
204   res->class_cast_state    = ir_class_casts_transitive;
205   res->extblk_state        = ir_extblk_info_none;
206   res->fp_model            = fp_model_precise;
207
208   /*-- Type information for the procedure of the graph --*/
209   res->ent = ent;
210   set_entity_irg(ent, res);
211
212   /*--  a class type so that it can contain "inner" methods as in Pascal. --*/
213   res->frame_type = new_type_frame(mangle(get_entity_ident(ent), frame_type_suffix));
214
215   /*-- Nodes needed in every graph --*/
216   set_irg_end_block (res, new_immBlock());
217   end               = new_End();
218   set_irg_end       (res, end);
219   set_irg_end_reg   (res, end);
220   set_irg_end_except(res, end);
221
222   start_block = new_immBlock();
223   set_irg_start_block(res, start_block);
224   set_irg_bad        (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
225   set_irg_no_mem     (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
226   start = new_Start();
227   set_irg_start      (res, start);
228
229   /* Proj results of start node */
230   projX                   = new_Proj(start, mode_X, pn_Start_X_initial_exec);
231   set_irg_frame           (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
232   set_irg_globals         (res, new_Proj(start, mode_P_data, pn_Start_P_globals));
233   set_irg_tls             (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
234   set_irg_args            (res, new_Proj(start, mode_T,      pn_Start_T_args));
235   set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
236   initial_mem             = new_Proj(start, mode_M, pn_Start_M);
237   set_irg_initial_mem(res, initial_mem);
238
239   add_immBlock_pred(start_block, projX);
240   set_store(initial_mem);
241
242 #ifdef DEBUG_libfirm
243   res->graph_nr    = get_irp_new_node_nr();
244 #endif
245   res->proj_args   = NULL;
246
247   /*
248    * The code generation needs it. leave it in now.
249    * Use of this edge is matter of discussion, unresolved. Also possible:
250    * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
251    */
252   mature_immBlock(res->current_block);
253
254   /*-- Make a block to start with --*/
255   first_block = new_immBlock();
256   add_immBlock_pred(first_block, projX);
257
258   res->method_execution_frequency = -1;
259   res->estimated_node_count       = 0;
260
261   return res;
262 }
263
264
265 ir_graph *
266 new_ir_graph(ir_entity *ent, int n_loc)
267 {
268   ir_graph *res = new_r_ir_graph(ent, n_loc);
269   add_irp_irg(res);          /* remember this graph global. */
270   return res;
271 }
272
273 /* Make a rudimentary IR graph for the constant code.
274    Must look like a correct irg, spare everything else. */
275 ir_graph *new_const_code_irg(void) {
276   ir_graph *res;
277   ir_node  *end, *start_block, *start, *projX;
278
279   res = alloc_graph();
280
281   /* initialize the idx->node map. */
282   res->idx_irn_map = NEW_ARR_F(ir_node *, INITIAL_IDX_IRN_MAP_SIZE);
283   memset(res->idx_irn_map, 0, INITIAL_IDX_IRN_MAP_SIZE * sizeof(res->idx_irn_map[0]));
284
285   /* inform statistics here, as blocks will be already build on this graph */
286   hook_new_graph(res, NULL);
287
288   current_ir_graph = res;
289   res->n_loc = 1;         /* Only the memory. */
290   res->visited = 0;       /* visited flag, for the ir walker */
291   res->block_visited = 0; /* visited flag, for the 'block'-walker */
292 #if USE_EXPLICIT_PHI_IN_STACK
293   res->Phi_in_stack = NULL;
294 #endif
295   res->kind = k_ir_graph;
296   res->obst      = xmalloc (sizeof(*res->obst));
297   obstack_init (res->obst);
298   res->extbb_obst = NULL;
299
300   res->last_node_idx = 0;
301
302   res->phase_state      = phase_building;
303   res->irg_pinned_state = op_pin_state_pinned;
304   res->extblk_state     = ir_extblk_info_none;
305   res->fp_model         = fp_model_precise;
306
307   res->value_table = new_identities (); /* value table for global value
308                        numbering for optimizing use in
309                        iropt.c */
310   res->ent = NULL;
311   res->frame_type  = NULL;
312
313   /* -- The end block -- */
314   set_irg_end_block (res, new_immBlock());
315   end = new_End();
316   set_irg_end       (res, end);
317   set_irg_end_reg   (res, end);
318   set_irg_end_except(res, end);
319   mature_immBlock(get_cur_block());  /* mature the end block */
320
321   /* -- The start block -- */
322   start_block        = new_immBlock();
323   set_irg_start_block(res, start_block);
324   set_irg_bad        (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
325   set_irg_no_mem     (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
326   start              = new_Start();
327   set_irg_start      (res, start);
328
329   /* Proj results of start node */
330   set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
331   projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
332   add_immBlock_pred(start_block, projX);
333   mature_immBlock  (start_block);  /* mature the start block */
334
335   add_immBlock_pred(new_immBlock(), projX);
336   mature_immBlock  (get_cur_block());   /* mature the 'body' block for expressions */
337
338   /* Set the visited flag high enough that the blocks will never be visited. */
339   set_irn_visited(get_cur_block(), -1);
340   set_Block_block_visited(get_cur_block(), -1);
341   set_Block_block_visited(start_block, -1);
342   set_irn_visited(start_block, -1);
343   set_irn_visited(get_irg_bad(res), -1);
344   set_irn_visited(get_irg_no_mem(res), -1);
345
346   res->phase_state = phase_high;
347
348   return res;
349 }
350
351 /* Defined in iropt.c */
352 void  del_identities (pset *value_table);
353
354 /* Frees the passed irgraph.
355    Deallocates all nodes in this graph and the ir_graph structure.
356    Sets the field irgraph in the corresponding entity to NULL.
357    Does not remove the irgraph from the list in irprog (requires
358    inefficient search, call remove_irp_irg by hand).
359    Does not free types, entities or modes that are used only by this
360    graph, nor the entity standing for this graph. */
361 void free_ir_graph (ir_graph *irg) {
362   assert(is_ir_graph(irg));
363
364   hook_free_graph(irg);
365   if (irg->outs_state != outs_none) free_irg_outs(irg);
366   if (irg->frame_type)  free_type(irg->frame_type);
367   if (irg->value_table) del_identities(irg->value_table);
368   if (irg->ent) {
369     ir_peculiarity pec = get_entity_peculiarity (irg->ent);
370     set_entity_peculiarity (irg->ent, peculiarity_description);
371     set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
372     set_entity_peculiarity (irg->ent, pec);
373   }
374
375   free_End(get_irg_end(irg));
376   obstack_free(irg->obst,NULL);
377   free(irg->obst);
378 #if USE_EXPLICIT_PHI_IN_STACK
379   free_Phi_in_stack(irg->Phi_in_stack);
380 #endif
381   if (irg->loc_descriptions)
382     free(irg->loc_descriptions);
383   irg->kind = k_BAD;
384   free_graph(irg);
385 }
386
387 /* access routines for all ir_graph attributes:
388    templates:
389    {attr type} get_irg_{attribute name} (ir_graph *irg);
390    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
391
392 int
393 (is_ir_graph)(const void *thing) {
394   return _is_ir_graph(thing);
395 }
396
397 /* Outputs a unique number for this node */
398 long get_irg_graph_nr(ir_graph *irg) {
399   assert(irg);
400 #ifdef DEBUG_libfirm
401   return irg->graph_nr;
402 #else
403   return (long)PTR_TO_INT(irg);
404 #endif
405 }
406
407 ir_node *
408 (get_irg_start_block)(const ir_graph *irg) {
409   return _get_irg_start_block(irg);
410 }
411
412 void
413 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
414   _set_irg_start_block(irg, node);
415 }
416
417 ir_node *
418 (get_irg_start)(const ir_graph *irg) {
419   return _get_irg_start(irg);
420 }
421
422 void
423 (set_irg_start)(ir_graph *irg, ir_node *node) {
424   _set_irg_start(irg, node);
425 }
426
427 ir_node *
428 (get_irg_end_block)(const ir_graph *irg) {
429   return _get_irg_end_block(irg);
430 }
431
432 void
433 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
434   _set_irg_end_block(irg, node);
435 }
436
437 ir_node *
438 (get_irg_end)(const ir_graph *irg) {
439   return _get_irg_end(irg);
440 }
441
442 void
443 (set_irg_end)(ir_graph *irg, ir_node *node) {
444   _set_irg_end(irg, node);
445 }
446
447 ir_node *
448 (get_irg_end_reg)(const ir_graph *irg) {
449   return _get_irg_end_reg(irg);
450 }
451
452 void     set_irg_end_reg (ir_graph *irg, ir_node *node) {
453   assert(get_irn_op(node) == op_EndReg || get_irn_op(node) == op_End);
454   irg->anchors[anchor_end_reg] = node;
455 }
456
457 ir_node *
458 (get_irg_end_except)(const ir_graph *irg) {
459   return _get_irg_end_except(irg);
460 }
461
462 void     set_irg_end_except (ir_graph *irg, ir_node *node) {
463   assert(get_irn_op(node) == op_EndExcept || get_irn_op(node) == op_End);
464   irg->anchors[anchor_end_except] = node;
465 }
466
467 ir_node *
468 (get_irg_frame)(const ir_graph *irg) {
469   return _get_irg_frame(irg);
470 }
471
472 void
473 (set_irg_frame)(ir_graph *irg, ir_node *node) {
474   _set_irg_frame(irg, node);
475 }
476
477 ir_node *
478 (get_irg_globals)(const ir_graph *irg) {
479   return _get_irg_globals(irg);
480 }
481
482 void
483 (set_irg_globals)(ir_graph *irg, ir_node *node) {
484   _set_irg_globals(irg, node);
485 }
486
487 ir_node *
488 (get_irg_tls)(const ir_graph *irg) {
489   return _get_irg_tls(irg);
490 }
491
492 void
493 (set_irg_tls)(ir_graph *irg, ir_node *node) {
494   _set_irg_tls(irg, node);
495 }
496
497 ir_node *
498 (get_irg_initial_mem)(const ir_graph *irg) {
499   return _get_irg_initial_mem(irg);
500 }
501
502 void
503 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
504   _set_irg_initial_mem(irg, node);
505 }
506
507 ir_node *
508 (get_irg_args)(const ir_graph *irg) {
509   return _get_irg_args(irg);
510 }
511
512 void
513 (set_irg_args)(ir_graph *irg, ir_node *node) {
514   _set_irg_args(irg, node);
515 }
516
517 ir_node *
518 (get_irg_value_param_base)(const ir_graph *irg) {
519   return _get_irg_value_param_base(irg);
520 }
521
522 void
523 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
524   _set_irg_value_param_base(irg, node);
525 }
526
527 ir_node **
528 (get_irg_proj_args) (const ir_graph *irg) {
529   return _get_irg_proj_args (irg);
530 }
531
532 void
533 (set_irg_proj_args) (ir_graph *irg, ir_node **nodes) {
534   _set_irg_proj_args (irg, nodes);
535 }
536
537 ir_node *
538 (get_irg_bad)(const ir_graph *irg) {
539   return _get_irg_bad(irg);
540 }
541
542 void
543 (set_irg_bad)(ir_graph *irg, ir_node *node) {
544   _set_irg_bad(irg, node);
545 }
546
547 ir_node *
548 (get_irg_no_mem)(const ir_graph *irg) {
549   return _get_irg_no_mem(irg);
550 }
551
552 void
553 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
554   _set_irg_no_mem(irg, node);
555 }
556
557 ir_node *
558 (get_irg_current_block)(const ir_graph *irg) {
559   return _get_irg_current_block(irg);
560 }
561
562 void
563 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
564   _set_irg_current_block(irg, node);
565 }
566
567 ir_entity *
568 (get_irg_entity)(const ir_graph *irg) {
569   return _get_irg_entity(irg);
570 }
571
572 void
573 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
574   _set_irg_entity(irg, ent);
575 }
576
577 ir_type *
578 (get_irg_frame_type)(ir_graph *irg) {
579   return _get_irg_frame_type(irg);
580 }
581
582 void
583 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
584   _set_irg_frame_type(irg, ftp);
585 }
586
587 int
588 get_irg_n_locs (ir_graph *irg)
589 {
590   if (get_opt_precise_exc_context())
591     return irg->n_loc - 1 - 1;
592   else
593     return irg->n_loc - 1;
594 }
595
596 void
597 set_irg_n_loc (ir_graph *irg, int n_loc)
598 {
599   if (get_opt_precise_exc_context())
600     irg->n_loc = n_loc + 1 + 1;
601   else
602     irg->n_loc = n_loc + 1;
603 }
604
605
606
607 /* Returns the obstack associated with the graph. */
608 struct obstack *
609 (get_irg_obstack)(const ir_graph *irg) {
610   return _get_irg_obstack(irg);
611 }
612
613 /*
614  * Returns true if the node n is allocated on the storage of graph irg.
615  *
616  * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
617  */
618 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n)
619 {
620   struct _obstack_chunk *p;
621
622   /*
623    * checks weather the ir_node pointer is on the obstack.
624    * A more sophisticated check would test the "whole" ir_node
625    */
626   for (p = irg->obst->chunk; p; p = p->prev) {
627     if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
628       return 1;
629   }
630
631   return 0;
632 }
633
634 irg_phase_state
635 (get_irg_phase_state)(const ir_graph *irg) {
636   return _get_irg_phase_state(irg);
637 }
638
639 void
640 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
641   _set_irg_phase_state(irg, state);
642 }
643
644 op_pin_state
645 (get_irg_pinned)(const ir_graph *irg) {
646   return _get_irg_pinned(irg);
647 }
648
649 irg_outs_state
650 (get_irg_outs_state)(const ir_graph *irg) {
651   return _get_irg_outs_state(irg);
652 }
653
654 void
655 (set_irg_outs_inconsistent)(ir_graph *irg) {
656   _set_irg_outs_inconsistent(irg);
657 }
658
659 irg_extblk_state
660 (get_irg_extblk_state)(const ir_graph *irg) {
661   return _get_irg_extblk_state(irg);
662 }
663
664 void
665 (set_irg_extblk_inconsistent)(ir_graph *irg) {
666   _set_irg_extblk_inconsistent(irg);
667 }
668
669 irg_dom_state
670 (get_irg_dom_state)(const ir_graph *irg) {
671   return _get_irg_dom_state(irg);
672 }
673
674 irg_dom_state
675 (get_irg_postdom_state)(const ir_graph *irg) {
676   return _get_irg_postdom_state(irg);
677 }
678
679 void
680 (set_irg_doms_inconsistent)(ir_graph *irg) {
681   _set_irg_doms_inconsistent(irg);
682 }
683
684 irg_loopinfo_state
685 (get_irg_loopinfo_state)(const ir_graph *irg) {
686   return _get_irg_loopinfo_state(irg);
687 }
688
689 void
690 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
691   _set_irg_loopinfo_state(irg, s);
692 }
693
694 void
695 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
696   _set_irg_loopinfo_inconsistent(irg);
697 }
698
699 void set_irp_loopinfo_inconsistent(void) {
700   int i, n_irgs = get_irp_n_irgs();
701   for (i = 0; i < n_irgs; ++i) {
702     set_irg_loopinfo_inconsistent(get_irp_irg(i));
703   }
704 }
705
706
707
708 void
709 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
710   _set_irg_pinned(irg, p);
711 }
712
713 irg_callee_info_state
714 (get_irg_callee_info_state)(const ir_graph *irg) {
715   return _get_irg_callee_info_state(irg);
716 }
717
718 void
719 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
720   _set_irg_callee_info_state(irg, s);
721 }
722
723 irg_inline_property
724 (get_irg_inline_property)(const ir_graph *irg) {
725   return _get_irg_inline_property(irg);
726 }
727
728 void
729 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
730   _set_irg_inline_property(irg, s);
731 }
732
733 unsigned
734 (get_irg_additional_properties)(const ir_graph *irg) {
735   return _get_irg_additional_properties(irg);
736 }
737
738 void
739 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
740   _set_irg_additional_properties(irg, property_mask);
741 }
742
743 void
744 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
745   _set_irg_additional_property(irg, flag);
746 }
747
748 void
749 (set_irg_link)(ir_graph *irg, void *thing) {
750   _set_irg_link(irg, thing);
751 }
752
753 void *
754 (get_irg_link)(const ir_graph *irg) {
755   return _get_irg_link(irg);
756 }
757
758 /** maximum visited flag content of all ir_graph visited fields. */
759 static unsigned long max_irg_visited = 0;
760
761 unsigned long
762 (get_irg_visited)(const ir_graph *irg) {
763   return _get_irg_visited(irg);
764 }
765
766 void
767 set_irg_visited (ir_graph *irg, unsigned long visited)
768 {
769   irg->visited = visited;
770   if (irg->visited > max_irg_visited) {
771     max_irg_visited = irg->visited;
772   }
773 }
774
775 void
776 inc_irg_visited (ir_graph *irg)
777 {
778   if (++irg->visited > max_irg_visited) {
779     max_irg_visited = irg->visited;
780   }
781 }
782
783 unsigned long
784 get_max_irg_visited(void)
785 {
786   /*
787   int i;
788   for(i = 0; i < get_irp_n_irgs(); i++)
789   assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
790    */
791   return max_irg_visited;
792 }
793
794 void set_max_irg_visited(int val) {
795   max_irg_visited = val;
796 }
797
798 unsigned long
799 inc_max_irg_visited(void)
800 {
801   /*
802   int i;
803   for(i = 0; i < get_irp_n_irgs(); i++)
804   assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
805   */
806   max_irg_visited++;
807   return max_irg_visited;
808 }
809
810 unsigned long
811 (get_irg_block_visited)(const ir_graph *irg) {
812   return _get_irg_block_visited(irg);
813 }
814
815 void
816 (set_irg_block_visited)(ir_graph *irg, unsigned long visited) {
817   _set_irg_block_visited(irg, visited);
818 }
819
820 void
821 (inc_irg_block_visited)(ir_graph *irg) {
822   _inc_irg_block_visited(irg);
823 }
824
825 /* Return the floating point model of this graph. */
826 unsigned (get_irg_fp_model)(const ir_graph *irg) {
827   return _get_irg_fp_model(irg);
828 }
829
830 /* Sets the floating point model for this graph. */
831 void set_irg_fp_model(ir_graph *irg, unsigned model) {
832   irg->fp_model = model;
833 }
834
835 /**
836  * walker Start->End: places Proj nodes into the same block
837  * as it's predecessors
838  *
839  * @param n    the node
840  * @param env  ignored
841  */
842 static void normalize_proj_walker(ir_node *n, void *env){
843   if (is_Proj(n)) {
844     ir_node *pred  = get_Proj_pred(n);
845     ir_node *block = get_nodes_block(pred);
846
847     set_nodes_block(n, block);
848   }
849 }
850
851 /* move Proj nodes into the same block as its predecessors */
852 void normalize_proj_nodes(ir_graph *irg) {
853   irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
854   set_irg_outs_inconsistent(irg);
855 }
856
857 /* set a description for local value n */
858 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
859   assert(0 <= n && n < irg->n_loc);
860
861   if (! irg->loc_descriptions)
862     irg->loc_descriptions = xcalloc(sizeof(*irg->loc_descriptions), irg->n_loc);
863
864   irg->loc_descriptions[n] = description;
865 }
866
867 /* get the description for local value n */
868 void *get_irg_loc_description(ir_graph *irg, int n) {
869   assert(0 <= n && n < irg->n_loc);
870   return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
871 }
872
873 /* Returns a estimated node count of the irg. */
874 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
875   return _get_irg_estimated_node_cnt(irg);
876 }
877
878 /* Returns the last irn index for this graph. */
879 unsigned get_irg_last_idx(const ir_graph *irg) {
880   return irg->last_node_idx;
881 }
882
883 /* register additional space in an IR graph */
884 size_t register_additional_graph_data(size_t size)
885 {
886   assert(!forbid_new_data && "Too late to register additional node data");
887
888   if (forbid_new_data)
889     return 0;
890
891   return additional_graph_data_size += size;
892 }