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