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