- add block Phi list resource
[libfirm] / ir / ir / irgraph.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
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.
10  *
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.
14  *
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
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief    Entry point to the representation of procedure code.
23  * @author   Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
24  * @version  $Id$
25  */
26 #include "config.h"
27
28 #ifdef HAVE_STRING_H
29 # include <string.h>
30 #endif
31 #ifdef HAVE_STDDEF_H
32 # include <stddef.h>
33 #endif
34
35 #include "xmalloc.h"
36 #include "ircons_t.h"
37 #include "irgraph_t.h"
38 #include "irprog_t.h"
39 #include "irgraph_t.h"
40 #include "irnode_t.h"
41 #include "iropt_t.h"
42 #include "irflag_t.h"
43 #include "array.h"
44 #include "irgmod.h"
45 #include "irouts.h"
46 #include "irhooks.h"
47 #include "irtools.h"
48 #include "irgwalk.h"
49 #include "irbackedge_t.h"
50 #include "iredges_t.h"
51 #include "type_t.h"
52 #include "irmemory.h"
53
54 #define INITIAL_IDX_IRN_MAP_SIZE 1024
55
56 /**
57  * Indicates, whether additional data can be registered to graphs.
58  * If set to 1, this is not possible anymore.
59  */
60 static int forbid_new_data = 0;
61
62 /**
63  * The amount of additional space for custom data to be allocated upon
64  * creating a new graph.
65  */
66 static size_t additional_graph_data_size = 0;
67
68 ir_graph *current_ir_graph;
69 ir_graph *get_current_ir_graph(void) {
70         return current_ir_graph;
71 }
72
73 void set_current_ir_graph(ir_graph *graph) {
74         current_ir_graph = graph;
75 }
76
77 #ifdef INTERPROCEDURAL_VIEW
78 int firm_interprocedural_view = 0;
79
80 int (get_interprocedural_view)(void) {
81         return _get_interprocedural_view();
82 }
83
84 void (set_interprocedural_view)(int state) {
85         firm_interprocedural_view = state;
86
87         /* set function vectors for faster access */
88         if (state) {
89                 _get_irn_arity = _get_irn_inter_arity;
90                 _get_irn_n     = _get_irn_inter_n;
91         }
92         else {
93                 _get_irn_arity = _get_irn_intra_arity;
94                 _get_irn_n     = _get_irn_intra_n;
95         }
96 }
97 #endif
98
99 /** contains the suffix for frame type names */
100 static ident *frame_type_suffix = NULL;
101
102 /* initialize the IR graph module */
103 void firm_init_irgraph(void) {
104         frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
105         forbid_new_data   = 1;
106 }
107
108 /**
109  * Allocate a new IR graph.
110  * This function respects the registered graph data. The only reason for
111  * this function is, that there are two locations, where graphs are
112  * allocated (new_r_ir_graph, new_const_code_irg).
113  * @return Memory for a new graph.
114  */
115 static ir_graph *alloc_graph(void) {
116         ir_graph *res;
117         size_t   size = sizeof(ir_graph) + additional_graph_data_size;
118         char     *ptr = xmalloc(size);
119         memset(ptr, 0, size);
120
121         res = (ir_graph *)(ptr + additional_graph_data_size);
122         res->kind = k_ir_graph;
123
124         /* initialize the idx->node map. */
125         res->idx_irn_map = NEW_ARR_F(ir_node *, INITIAL_IDX_IRN_MAP_SIZE);
126         memset(res->idx_irn_map, 0, INITIAL_IDX_IRN_MAP_SIZE * sizeof(res->idx_irn_map[0]));
127
128         return res;
129 }
130
131 /**
132  * Frees an allocated IR graph
133  */
134 static void free_graph(ir_graph *irg) {
135         char *ptr = (char *)irg;
136         int  i;
137
138         for (i = 0; i < EDGE_KIND_LAST; ++i)
139                 edges_deactivate_kind(irg, i);
140         DEL_ARR_F(irg->idx_irn_map);
141         free(ptr - additional_graph_data_size);
142 }
143
144 #if USE_EXPLICIT_PHI_IN_STACK
145 /* really defined in ircons.c */
146 typedef struct Phi_in_stack Phi_in_stack;
147 Phi_in_stack *new_Phi_in_stack();
148 void free_Phi_in_stack(Phi_in_stack *s);
149 #endif
150
151 /**
152  * Set the number of locals for a given graph.
153  *
154  * @param irg    the graph
155  * @param n_loc  number of locals
156  */
157 void irg_set_nloc(ir_graph *res, int n_loc) {
158         assert(res->phase_state == phase_building);
159
160         if (get_opt_precise_exc_context()) {
161                 res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
162                                                dereferenced in this graph plus one for
163                                                the store plus one for links to fragile
164                                                operations.  n_loc is not the number of
165                                                parameters to the procedure!  */
166         } else {
167                 res->n_loc = n_loc + 1;     /* number of local variables that are never
168                                                dereferenced in this graph plus one for
169                                                the store. This is not the number of parameters
170                                                to the procedure!  */
171         }
172         if (res->loc_descriptions) {
173                 xfree(res->loc_descriptions);
174                 res->loc_descriptions = NULL;
175         }
176 }
177
178 /* Allocates a list of nodes:
179     - The start block containing a start node and Proj nodes for it's four
180       results (X, M, P, Tuple).
181     - The end block containing an end node. This block is not matured after
182       new_ir_graph as predecessors need to be added to it.
183     - The current block, which is empty and also not matured.
184    Further it allocates several datastructures needed for graph construction
185    and optimization.
186 */
187 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
188         ir_graph *res;
189         ir_node  *first_block;
190         ir_node  *end, *start, *start_block, *initial_mem, *projX;
191
192         res = alloc_graph();
193
194         /* inform statistics here, as blocks will be already build on this graph */
195         hook_new_graph(res, ent);
196
197         current_ir_graph = res;
198
199         /*-- initialized for each graph. --*/
200         res->kind = k_ir_graph;
201         res->obst = XMALLOC(struct obstack);
202         obstack_init(res->obst);
203
204         res->phase_state = phase_building;
205         irg_set_nloc(res, n_loc);
206
207         /* descriptions will be allocated on demand */
208         res->loc_descriptions = NULL;
209
210         res->visited       = 0; /* visited flag, for the ir walker */
211         res->block_visited = 0; /* visited flag, for the 'block'-walker */
212
213 #if USE_EXPLICIT_PHI_IN_STACK
214         res->Phi_in_stack = new_Phi_in_stack();  /* A stack needed for automatic Phi
215                                                     generation */
216 #endif
217         res->extbb_obst = NULL;
218
219         res->last_node_idx = 0;
220
221         res->value_table = new_identities (); /* value table for global value
222                                                  numbering for optimizing use in iropt.c */
223         res->outs = NULL;
224
225         res->inline_property       = irg_inline_any;
226         res->additional_properties = mtp_property_inherited;  /* inherited from type */
227
228         res->irg_pinned_state    = op_pin_state_pinned;
229         res->outs_state          = outs_none;
230         res->dom_state           = dom_none;
231         res->pdom_state          = dom_none;
232         res->typeinfo_state      = ir_typeinfo_none;
233         set_irp_typeinfo_inconsistent();           /* there is a new graph with typeinfo_none. */
234         res->callee_info_state   = irg_callee_info_none;
235         res->loopinfo_state      = loopinfo_none;
236         res->class_cast_state    = ir_class_casts_transitive;
237         res->extblk_state        = ir_extblk_info_none;
238         res->execfreq_state      = exec_freq_none;
239         res->fp_model            = fp_model_precise;
240         res->entity_usage_state  = ir_entity_usage_not_computed;
241         res->mem_disambig_opt    = aa_opt_inherited;
242
243         /*-- Type information for the procedure of the graph --*/
244         res->ent = ent;
245         set_entity_irg(ent, res);
246
247         /*--  a class type so that it can contain "inner" methods as in Pascal. --*/
248         res->frame_type = new_type_frame(mangle(get_entity_ident(ent), frame_type_suffix));
249
250         /* the Anchor node must be created first */
251         res->anchor = new_Anchor(res);
252
253         /*-- Nodes needed in every graph --*/
254         set_irg_end_block (res, new_immBlock());
255         end               = new_End();
256         set_irg_end       (res, end);
257         set_irg_end_reg   (res, end);
258         set_irg_end_except(res, end);
259
260         start_block = new_immBlock();
261         set_irg_start_block(res, start_block);
262         set_irg_bad        (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
263         set_irg_no_mem     (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
264         start = new_Start();
265         set_irg_start      (res, start);
266
267         /* Proj results of start node */
268         projX                   = new_Proj(start, mode_X, pn_Start_X_initial_exec);
269         set_irg_initial_exec    (res, projX);
270         set_irg_frame           (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
271         set_irg_tls             (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
272         set_irg_args            (res, new_Proj(start, mode_T,      pn_Start_T_args));
273         set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
274         initial_mem             = new_Proj(start, mode_M, pn_Start_M);
275         set_irg_initial_mem(res, initial_mem);
276
277         add_immBlock_pred(start_block, projX);
278         set_store(initial_mem);
279
280         res->index       = get_irp_new_irg_idx();
281 #ifdef DEBUG_libfirm
282         res->graph_nr    = get_irp_new_node_nr();
283 #endif
284
285         /*
286          * The code generation needs it. leave it in now.
287          * Use of this edge is matter of discussion, unresolved. Also possible:
288          * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
289          */
290         mature_immBlock(res->current_block);
291
292         /*-- Make a block to start with --*/
293         first_block = new_immBlock();
294         add_immBlock_pred(first_block, projX);
295
296         res->method_execution_frequency = -1.0;
297         res->estimated_node_count       = 0;
298
299         return res;
300 }
301
302 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
303         ir_graph *res = new_r_ir_graph(ent, n_loc);
304         add_irp_irg(res);          /* remember this graph global. */
305         return res;
306 }
307
308 /* Make a rudimentary IR graph for the constant code.
309    Must look like a correct irg, spare everything else. */
310 ir_graph *new_const_code_irg(void) {
311         ir_graph *res;
312         ir_node  *end, *start_block, *start, *projX;
313
314         res = alloc_graph();
315
316         /* inform statistics here, as blocks will be already build on this graph */
317         hook_new_graph(res, NULL);
318
319         current_ir_graph = res;
320         res->n_loc = 1;         /* Only the memory. */
321         res->visited = 0;       /* visited flag, for the ir walker */
322         res->block_visited = 0; /* visited flag, for the 'block'-walker */
323 #if USE_EXPLICIT_PHI_IN_STACK
324         res->Phi_in_stack = NULL;
325 #endif
326         res->obst       = XMALLOC(struct obstack);
327         obstack_init (res->obst);
328         res->extbb_obst = NULL;
329
330         res->last_node_idx = 0;
331
332         res->phase_state      = phase_building;
333         res->irg_pinned_state = op_pin_state_pinned;
334         res->extblk_state     = ir_extblk_info_none;
335         res->fp_model         = fp_model_precise;
336
337         res->value_table = new_identities(); /* value table for global value
338                                            numbering for optimizing use in
339                                            iropt.c */
340         res->ent = NULL;
341         res->frame_type  = NULL;
342
343         /* the Anchor node must be created first */
344         res->anchor = new_Anchor(res);
345
346         /* -- The end block -- */
347         set_irg_end_block (res, new_immBlock());
348         end = new_End();
349         set_irg_end       (res, end);
350         set_irg_end_reg   (res, end);
351         set_irg_end_except(res, end);
352         mature_immBlock(get_cur_block());  /* mature the end block */
353
354         /* -- The start block -- */
355         start_block        = new_immBlock();
356         set_irg_start_block(res, start_block);
357         set_irg_bad        (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
358         set_irg_no_mem     (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
359         start              = new_Start();
360         set_irg_start      (res, start);
361
362         /* Proj results of start node */
363         set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
364         projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
365         add_immBlock_pred(start_block, projX);
366         mature_immBlock  (start_block);  /* mature the start block */
367
368         add_immBlock_pred(new_immBlock(), projX);
369         mature_immBlock  (get_cur_block());   /* mature the 'body' block for expressions */
370
371         /* Set the visited flag high enough that the blocks will never be visited. */
372         set_irn_visited(get_cur_block(), -1);
373         set_Block_block_visited(get_cur_block(), -1);
374         set_Block_block_visited(start_block, -1);
375         set_irn_visited(start_block, -1);
376         set_irn_visited(get_irg_bad(res), -1);
377         set_irn_visited(get_irg_no_mem(res), -1);
378
379         res->phase_state = phase_high;
380
381         return res;
382 }
383
384 /**
385  * Pre-Walker: Copies blocks and nodes from the original method graph
386  * to the copied graph.
387  *
388  * @param n    A node from the original method graph.
389  * @param env  The copied graph.
390  */
391 static void copy_all_nodes(ir_node *n, void *env) {
392         ir_graph *irg = env;
393         ir_op    *op  = get_irn_op(n);
394         ir_node  *nn;
395
396         nn = new_ir_node(get_irn_dbg_info(n),
397                          irg,
398                          NULL,            /* no block yet, will be set later */
399                          op,
400                          get_irn_mode(n),
401                          get_irn_arity(n),
402                          get_irn_in(n) + 1);
403
404
405         /* Copy the attributes.  These might point to additional data.  If this
406            was allocated on the old obstack the pointers now are dangling.  This
407            frees e.g. the memory of the graph_arr allocated in new_immBlock. */
408         copy_node_attr(n, nn);
409         new_backedge_info(nn);
410         set_irn_link(n, nn);
411
412         /* fix the irg for blocks */
413         if (is_Block(nn))
414                 nn->attr.block.irg = irg;
415
416         /* fix access to entities on the stack frame */
417         if (is_Sel(nn)) {
418                 ir_entity *ent = get_Sel_entity(nn);
419                 ir_type   *tp = get_entity_owner(ent);
420
421                 if (is_frame_type(tp)) {
422                         /* replace by the copied entity */
423                         ent = get_entity_link(ent);
424
425                         assert(is_entity(ent));
426                         assert(get_entity_owner(ent) == get_irg_frame_type(irg));
427                         set_Sel_entity(nn, ent);
428                 }
429         }
430 }
431
432 /**
433  * Post-walker: Set the predecessors of the copied nodes.
434  * The copied nodes are set as link of their original nodes. The links of
435  * "irn" predecessors are the predecessors of copied node.
436  */
437 static void set_all_preds(ir_node *irn, void *env) {
438         int      i;
439         ir_node  *nn, *pred;
440         (void) env;
441
442         nn = get_irn_link(irn);
443
444         if (is_Block(irn)) {
445                 ir_node *mbh = get_Block_MacroBlock(irn);
446                 set_Block_MacroBlock(nn, get_irn_link(mbh));
447                 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
448                         pred = get_Block_cfgpred(irn, i);
449                         set_Block_cfgpred(nn, i, get_irn_link(pred));
450                 }
451         } else {
452                 /* First we set the block our copy if it is not a block.*/
453                 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
454                 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
455                         pred = get_irn_n(irn, i);
456                         set_irn_n(nn, i, get_irn_link(pred));
457                 }
458         }
459 }
460
461 #define NN(irn)  get_irn_link(irn)
462
463 /*
464  * Create a new graph that is a copy of a given one.
465  */
466 ir_graph *create_irg_copy(ir_graph *irg) {
467         ir_graph *res;
468
469         res = alloc_graph();
470
471         res->n_loc = 0;
472         res->visited = 0;       /* visited flag, for the ir walker */
473         res->block_visited = 0; /* visited flag, for the 'block'-walker */
474 #if USE_EXPLICIT_PHI_IN_STACK
475         res->Phi_in_stack = NULL;
476 #endif
477         res->obst       = XMALLOC(struct obstack);
478         obstack_init(res->obst);
479         res->extbb_obst = NULL;
480
481         res->last_node_idx = 0;
482
483         res->phase_state      = irg->phase_state;
484         res->irg_pinned_state = irg->irg_pinned_state;
485         res->extblk_state     = ir_extblk_info_none;
486         res->fp_model         = irg->fp_model;
487
488         res->value_table = new_identities();
489
490         /* clone the frame type here for safety */
491         irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
492         res->frame_type  = clone_frame_type(irg->frame_type);
493
494         res->phase_state = irg->phase_state;
495
496         ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
497
498         /* copy all nodes from the graph irg to the new graph res */
499         irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
500
501         /* copy the Anchor node */
502         res->anchor = NN(irg->anchor);
503
504         /* -- The end block -- */
505         set_irg_end_block (res, NN(get_irg_end_block(irg)));
506         set_irg_end       (res, NN(get_irg_end(irg)));
507         set_irg_end_reg   (res, NN(get_irg_end_reg(irg)));
508         set_irg_end_except(res, NN(get_irg_end_except(irg)));
509
510         /* -- The start block -- */
511         set_irg_start_block(res, NN(get_irg_start_block(irg)));
512         set_irg_bad        (res, NN(get_irg_bad(irg)));
513         set_irg_no_mem     (res, NN(get_irg_no_mem(irg)));
514         set_irg_start      (res, NN(get_irg_start(irg)));
515
516         /* Proj results of start node */
517         set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
518
519         /* Copy the node count estimation. Would be strange if this
520            is different from the original one. */
521         res->estimated_node_count = irg->estimated_node_count;
522
523         ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
524         irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
525
526         return res;
527 }
528 #undef NN
529
530
531 /* Frees the passed irgraph.
532    Deallocates all nodes in this graph and the ir_graph structure.
533    Sets the field irgraph in the corresponding entity to NULL.
534    Does not remove the irgraph from the list in irprog (requires
535    inefficient search, call remove_irp_irg by hand).
536    Does not free types, entities or modes that are used only by this
537    graph, nor the entity standing for this graph. */
538 void free_ir_graph(ir_graph *irg) {
539         assert(is_ir_graph(irg));
540
541         edges_deactivate(irg);
542
543         hook_free_graph(irg);
544         if (irg->outs_state != outs_none)
545                 free_irg_outs(irg);
546         if (irg->frame_type)
547                 free_type(irg->frame_type);
548         if (irg->value_table)
549                 del_identities(irg->value_table);
550         if (irg->ent) {
551                 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
552                 set_entity_peculiarity (irg->ent, peculiarity_description);
553                 set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
554                 set_entity_peculiarity (irg->ent, pec);
555         }
556
557         free_End(get_irg_end(irg));
558         obstack_free(irg->obst,NULL);
559         free(irg->obst);
560 #if USE_EXPLICIT_PHI_IN_STACK
561         free_Phi_in_stack(irg->Phi_in_stack);
562 #endif
563         if (irg->loc_descriptions)
564                 free(irg->loc_descriptions);
565         irg->kind = k_BAD;
566         free_graph(irg);
567 }
568
569 /* access routines for all ir_graph attributes:
570    templates:
571    {attr type} get_irg_{attribute name} (ir_graph *irg);
572    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
573
574 int
575 (is_ir_graph)(const void *thing) {
576         return _is_ir_graph(thing);
577 }
578
579 #ifdef DEBUG_libfirm
580 /* Outputs a unique number for this node */
581 long get_irg_graph_nr(const ir_graph *irg) {
582         return irg->graph_nr;
583 }
584 #else
585 long get_irg_graph_nr(const ir_graph *irg) {
586         return PTR_TO_INT(irg);
587 }
588 #endif
589
590 int get_irg_idx(const ir_graph *irg) {
591         return irg->index;
592 }
593
594 ir_node *
595 (get_irg_start_block)(const ir_graph *irg) {
596         return _get_irg_start_block(irg);
597 }
598
599 void
600 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
601         _set_irg_start_block(irg, node);
602 }
603
604 ir_node *
605 (get_irg_start)(const ir_graph *irg) {
606         return _get_irg_start(irg);
607 }
608
609 void
610 (set_irg_start)(ir_graph *irg, ir_node *node) {
611         _set_irg_start(irg, node);
612 }
613
614 ir_node *
615 (get_irg_end_block)(const ir_graph *irg) {
616         return _get_irg_end_block(irg);
617 }
618
619 void
620 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
621   _set_irg_end_block(irg, node);
622 }
623
624 ir_node *
625 (get_irg_end)(const ir_graph *irg) {
626         return _get_irg_end(irg);
627 }
628
629 void
630 (set_irg_end)(ir_graph *irg, ir_node *node) {
631         _set_irg_end(irg, node);
632 }
633
634 ir_node *
635 (get_irg_end_reg)(const ir_graph *irg) {
636         return _get_irg_end_reg(irg);
637 }
638
639 void
640 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
641         _set_irg_end_reg(irg, node);
642 }
643
644 ir_node *
645 (get_irg_end_except)(const ir_graph *irg) {
646         return _get_irg_end_except(irg);
647 }
648
649 void
650 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
651         assert(get_irn_op(node) == op_EndExcept || is_End(node));
652         _set_irg_end_except(irg, node);
653 }
654
655 ir_node *
656 (get_irg_initial_exec)(const ir_graph *irg) {
657         return _get_irg_initial_exec(irg);
658 }
659
660 void
661 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
662         _set_irg_initial_exec(irg, node);
663 }
664
665 ir_node *
666 (get_irg_frame)(const ir_graph *irg) {
667         return _get_irg_frame(irg);
668 }
669
670 void
671 (set_irg_frame)(ir_graph *irg, ir_node *node) {
672         _set_irg_frame(irg, node);
673 }
674
675 ir_node *
676 (get_irg_tls)(const ir_graph *irg) {
677         return _get_irg_tls(irg);
678 }
679
680 void
681 (set_irg_tls)(ir_graph *irg, ir_node *node) {
682         _set_irg_tls(irg, node);
683 }
684
685 ir_node *
686 (get_irg_initial_mem)(const ir_graph *irg) {
687         return _get_irg_initial_mem(irg);
688 }
689
690 void
691 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
692         _set_irg_initial_mem(irg, node);
693 }
694
695 ir_node *
696 (get_irg_args)(const ir_graph *irg) {
697         return _get_irg_args(irg);
698 }
699
700 void
701 (set_irg_args)(ir_graph *irg, ir_node *node) {
702         _set_irg_args(irg, node);
703 }
704
705 ir_node *
706 (get_irg_value_param_base)(const ir_graph *irg) {
707         return _get_irg_value_param_base(irg);
708 }
709
710 void
711 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
712         _set_irg_value_param_base(irg, node);
713 }
714
715 ir_node *
716 (get_irg_bad)(const ir_graph *irg) {
717         return _get_irg_bad(irg);
718 }
719
720 void
721 (set_irg_bad)(ir_graph *irg, ir_node *node) {
722         _set_irg_bad(irg, node);
723 }
724
725 ir_node *
726 (get_irg_no_mem)(const ir_graph *irg) {
727         return _get_irg_no_mem(irg);
728 }
729
730 void
731 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
732         _set_irg_no_mem(irg, node);
733 }
734
735 ir_node *
736 (get_irg_current_block)(const ir_graph *irg) {
737         return _get_irg_current_block(irg);
738 }
739
740 void
741 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
742         _set_irg_current_block(irg, node);
743 }
744
745 ir_entity *
746 (get_irg_entity)(const ir_graph *irg) {
747         return _get_irg_entity(irg);
748 }
749
750 void
751 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
752         _set_irg_entity(irg, ent);
753 }
754
755 ir_type *
756 (get_irg_frame_type)(ir_graph *irg) {
757         return _get_irg_frame_type(irg);
758 }
759
760 void
761 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
762         _set_irg_frame_type(irg, ftp);
763 }
764
765 int
766 get_irg_n_locs(ir_graph *irg) {
767         if (get_opt_precise_exc_context())
768                 return irg->n_loc - 1 - 1;
769         else
770                 return irg->n_loc - 1;
771 }
772
773 void
774 set_irg_n_loc(ir_graph *irg, int n_loc) {
775         if (get_opt_precise_exc_context())
776                 irg->n_loc = n_loc + 1 + 1;
777         else
778                 irg->n_loc = n_loc + 1;
779 }
780
781
782
783 /* Returns the obstack associated with the graph. */
784 struct obstack *
785 (get_irg_obstack)(const ir_graph *irg) {
786         return _get_irg_obstack(irg);
787 }
788
789 /*
790  * Returns true if the node n is allocated on the storage of graph irg.
791  *
792  * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
793  */
794 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
795         struct _obstack_chunk *p;
796
797         /*
798          * checks weather the ir_node pointer is on the obstack.
799          * A more sophisticated check would test the "whole" ir_node
800          */
801         for (p = irg->obst->chunk; p; p = p->prev) {
802                 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
803                         return 1;
804         }
805
806         return 0;
807 }
808
809 irg_phase_state
810 (get_irg_phase_state)(const ir_graph *irg) {
811         return _get_irg_phase_state(irg);
812 }
813
814 void
815 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
816         _set_irg_phase_state(irg, state);
817 }
818
819 op_pin_state
820 (get_irg_pinned)(const ir_graph *irg) {
821         return _get_irg_pinned(irg);
822 }
823
824 irg_outs_state
825 (get_irg_outs_state)(const ir_graph *irg) {
826         return _get_irg_outs_state(irg);
827 }
828
829 void
830 (set_irg_outs_inconsistent)(ir_graph *irg) {
831         _set_irg_outs_inconsistent(irg);
832 }
833
834 irg_extblk_state
835 (get_irg_extblk_state)(const ir_graph *irg) {
836         return _get_irg_extblk_state(irg);
837 }
838
839 void
840 (set_irg_extblk_inconsistent)(ir_graph *irg) {
841         _set_irg_extblk_inconsistent(irg);
842 }
843
844 irg_dom_state
845 (get_irg_dom_state)(const ir_graph *irg) {
846         return _get_irg_dom_state(irg);
847 }
848
849 irg_dom_state
850 (get_irg_postdom_state)(const ir_graph *irg) {
851         return _get_irg_postdom_state(irg);
852 }
853
854 void
855 (set_irg_doms_inconsistent)(ir_graph *irg) {
856         _set_irg_doms_inconsistent(irg);
857 }
858
859 irg_loopinfo_state
860 (get_irg_loopinfo_state)(const ir_graph *irg) {
861         return _get_irg_loopinfo_state(irg);
862 }
863
864 void
865 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
866         _set_irg_loopinfo_state(irg, s);
867 }
868
869 void
870 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
871         _set_irg_loopinfo_inconsistent(irg);
872 }
873
874 void set_irp_loopinfo_inconsistent(void) {
875         int i;
876         for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
877                 set_irg_loopinfo_inconsistent(get_irp_irg(i));
878         }
879 }
880
881
882
883 void
884 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
885         _set_irg_pinned(irg, p);
886 }
887
888 irg_callee_info_state
889 (get_irg_callee_info_state)(const ir_graph *irg) {
890         return _get_irg_callee_info_state(irg);
891 }
892
893 void
894 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
895         _set_irg_callee_info_state(irg, s);
896 }
897
898 irg_inline_property
899 (get_irg_inline_property)(const ir_graph *irg) {
900         return _get_irg_inline_property(irg);
901 }
902
903 void
904 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
905         _set_irg_inline_property(irg, s);
906 }
907
908 unsigned
909 (get_irg_additional_properties)(const ir_graph *irg) {
910         return _get_irg_additional_properties(irg);
911 }
912
913 void
914 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
915         _set_irg_additional_properties(irg, property_mask);
916 }
917
918 void
919 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
920         _set_irg_additional_property(irg, flag);
921 }
922
923 void
924 (set_irg_link)(ir_graph *irg, void *thing) {
925         _set_irg_link(irg, thing);
926 }
927
928 void *
929 (get_irg_link)(const ir_graph *irg) {
930         return _get_irg_link(irg);
931 }
932
933 ir_visited_t
934 (get_irg_visited)(const ir_graph *irg) {
935         return _get_irg_visited(irg);
936 }
937
938 #ifdef INTERPROCEDURAL_VIEW
939 /** maximum visited flag content of all ir_graph visited fields. */
940 static ir_visited_t max_irg_visited = 0;
941 #endif /* INTERPROCEDURAL_VIEW */
942
943 void
944 set_irg_visited(ir_graph *irg, ir_visited_t visited) {
945         irg->visited = visited;
946 #ifdef INTERPROCEDURAL_VIEW
947         if (irg->visited > max_irg_visited) {
948                 max_irg_visited = irg->visited;
949         }
950 #endif /* INTERPROCEDURAL_VIEW */
951 }
952
953 void
954 inc_irg_visited(ir_graph *irg) {
955 #ifdef INTERPROCEDURAL_VIEW
956         if (++irg->visited > max_irg_visited) {
957                 max_irg_visited = irg->visited;
958         }
959 #else
960         ++irg->visited;
961 #endif /* INTERPROCEDURAL_VIEW */
962 }
963
964 #ifdef INTERPROCEDURAL_VIEW
965 ir_visited_t
966 get_max_irg_visited(void) {
967 #ifndef NDEBUG
968         int i;
969         for(i = 0; i < get_irp_n_irgs(); i++)
970                 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
971 #endif
972         return max_irg_visited;
973 }
974
975 void set_max_irg_visited(int val) {
976         max_irg_visited = val;
977 }
978
979 ir_visited_t
980 inc_max_irg_visited(void) {
981 #ifndef NDEBUG
982         int i;
983         for(i = 0; i < get_irp_n_irgs(); i++)
984                 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
985 #endif
986         return ++max_irg_visited;
987 }
988 #endif /* INTERPROCEDURAL_VIEW */
989
990 ir_visited_t
991 (get_irg_block_visited)(const ir_graph *irg) {
992         return _get_irg_block_visited(irg);
993 }
994
995 void
996 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
997         _set_irg_block_visited(irg, visited);
998 }
999
1000 void
1001 (inc_irg_block_visited)(ir_graph *irg) {
1002   _inc_irg_block_visited(irg);
1003 }
1004
1005 /* Return the floating point model of this graph. */
1006 unsigned (get_irg_fp_model)(const ir_graph *irg) {
1007         return _get_irg_fp_model(irg);
1008 }
1009
1010 /* Sets the floating point model for this graph. */
1011 void set_irg_fp_model(ir_graph *irg, unsigned model) {
1012         irg->fp_model = model;
1013 }
1014
1015 /**
1016  * walker Start->End: places Proj nodes into the same block
1017  * as it's predecessors
1018  *
1019  * @param n    the node
1020  * @param env  ignored
1021  */
1022 static void normalize_proj_walker(ir_node *n, void *env) {
1023         (void) env;
1024         if (is_Proj(n)) {
1025                 ir_node *pred  = get_Proj_pred(n);
1026                 ir_node *block = get_nodes_block(pred);
1027
1028                 set_nodes_block(n, block);
1029         }
1030 }
1031
1032 /* move Proj nodes into the same block as its predecessors */
1033 void normalize_proj_nodes(ir_graph *irg) {
1034         irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1035         set_irg_outs_inconsistent(irg);
1036 }
1037
1038 /* set a description for local value n */
1039 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1040         assert(0 <= n && n < irg->n_loc);
1041
1042         if (! irg->loc_descriptions)
1043                 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1044
1045         irg->loc_descriptions[n] = description;
1046 }
1047
1048 /* get the description for local value n */
1049 void *get_irg_loc_description(ir_graph *irg, int n) {
1050         assert(0 <= n && n < irg->n_loc);
1051         return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1052 }
1053
1054 #ifndef NDEBUG
1055 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources) {
1056         assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1057         assert((irg->reserved_resources & resources) == 0);
1058         irg->reserved_resources |= resources;
1059 }
1060
1061 void ir_free_resources(ir_graph *irg, ir_resources_t resources) {
1062         assert((irg->reserved_resources & resources) == resources);
1063         irg->reserved_resources &= ~resources;
1064 }
1065
1066 ir_resources_t ir_resources_reserved(const ir_graph *irg) {
1067         return irg->reserved_resources;
1068 }
1069 #endif /* NDEBUG */
1070
1071 /* Returns a estimated node count of the irg. */
1072 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1073         return _get_irg_estimated_node_cnt(irg);
1074 }
1075
1076 /* Returns the last irn index for this graph. */
1077 unsigned get_irg_last_idx(const ir_graph *irg) {
1078         return irg->last_node_idx;
1079 }
1080
1081 /* register additional space in an IR graph */
1082 size_t register_additional_graph_data(size_t size) {
1083         assert(!forbid_new_data && "Too late to register additional node data");
1084
1085         if (forbid_new_data)
1086                 return 0;
1087
1088         return additional_graph_data_size += size;
1089 }