Clean up new_const_code_irg() a bit.
[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 *
588 (get_irg_start_block)(const ir_graph *irg) {
589         return _get_irg_start_block(irg);
590 }
591
592 void
593 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
594         _set_irg_start_block(irg, node);
595 }
596
597 ir_node *
598 (get_irg_start)(const ir_graph *irg) {
599         return _get_irg_start(irg);
600 }
601
602 void
603 (set_irg_start)(ir_graph *irg, ir_node *node) {
604         _set_irg_start(irg, node);
605 }
606
607 ir_node *
608 (get_irg_end_block)(const ir_graph *irg) {
609         return _get_irg_end_block(irg);
610 }
611
612 void
613 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
614   _set_irg_end_block(irg, node);
615 }
616
617 ir_node *
618 (get_irg_end)(const ir_graph *irg) {
619         return _get_irg_end(irg);
620 }
621
622 void
623 (set_irg_end)(ir_graph *irg, ir_node *node) {
624         _set_irg_end(irg, node);
625 }
626
627 ir_node *
628 (get_irg_end_reg)(const ir_graph *irg) {
629         return _get_irg_end_reg(irg);
630 }
631
632 void
633 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
634         _set_irg_end_reg(irg, node);
635 }
636
637 ir_node *
638 (get_irg_end_except)(const ir_graph *irg) {
639         return _get_irg_end_except(irg);
640 }
641
642 void
643 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
644         assert(get_irn_op(node) == op_EndExcept || is_End(node));
645         _set_irg_end_except(irg, node);
646 }
647
648 ir_node *
649 (get_irg_initial_exec)(const ir_graph *irg) {
650         return _get_irg_initial_exec(irg);
651 }
652
653 void
654 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
655         _set_irg_initial_exec(irg, node);
656 }
657
658 ir_node *
659 (get_irg_frame)(const ir_graph *irg) {
660         return _get_irg_frame(irg);
661 }
662
663 void
664 (set_irg_frame)(ir_graph *irg, ir_node *node) {
665         _set_irg_frame(irg, node);
666 }
667
668 ir_node *
669 (get_irg_tls)(const ir_graph *irg) {
670         return _get_irg_tls(irg);
671 }
672
673 void
674 (set_irg_tls)(ir_graph *irg, ir_node *node) {
675         _set_irg_tls(irg, node);
676 }
677
678 ir_node *
679 (get_irg_initial_mem)(const ir_graph *irg) {
680         return _get_irg_initial_mem(irg);
681 }
682
683 void
684 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
685         _set_irg_initial_mem(irg, node);
686 }
687
688 ir_node *
689 (get_irg_args)(const ir_graph *irg) {
690         return _get_irg_args(irg);
691 }
692
693 void
694 (set_irg_args)(ir_graph *irg, ir_node *node) {
695         _set_irg_args(irg, node);
696 }
697
698 ir_node *
699 (get_irg_value_param_base)(const ir_graph *irg) {
700         return _get_irg_value_param_base(irg);
701 }
702
703 void
704 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
705         _set_irg_value_param_base(irg, node);
706 }
707
708 ir_node *
709 (get_irg_bad)(const ir_graph *irg) {
710         return _get_irg_bad(irg);
711 }
712
713 void
714 (set_irg_bad)(ir_graph *irg, ir_node *node) {
715         _set_irg_bad(irg, node);
716 }
717
718 ir_node *
719 (get_irg_no_mem)(const ir_graph *irg) {
720         return _get_irg_no_mem(irg);
721 }
722
723 void
724 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
725         _set_irg_no_mem(irg, node);
726 }
727
728 ir_node *
729 (get_irg_current_block)(const ir_graph *irg) {
730         return _get_irg_current_block(irg);
731 }
732
733 void
734 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
735         _set_irg_current_block(irg, node);
736 }
737
738 ir_entity *
739 (get_irg_entity)(const ir_graph *irg) {
740         return _get_irg_entity(irg);
741 }
742
743 void
744 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
745         _set_irg_entity(irg, ent);
746 }
747
748 ir_type *
749 (get_irg_frame_type)(ir_graph *irg) {
750         return _get_irg_frame_type(irg);
751 }
752
753 void
754 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
755         _set_irg_frame_type(irg, ftp);
756 }
757
758 int
759 get_irg_n_locs(ir_graph *irg) {
760         if (get_opt_precise_exc_context())
761                 return irg->n_loc - 1 - 1;
762         else
763                 return irg->n_loc - 1;
764 }
765
766 void
767 set_irg_n_loc(ir_graph *irg, int n_loc) {
768         if (get_opt_precise_exc_context())
769                 irg->n_loc = n_loc + 1 + 1;
770         else
771                 irg->n_loc = n_loc + 1;
772 }
773
774
775
776 /* Returns the obstack associated with the graph. */
777 struct obstack *
778 (get_irg_obstack)(const ir_graph *irg) {
779         return _get_irg_obstack(irg);
780 }
781
782 /*
783  * Returns true if the node n is allocated on the storage of graph irg.
784  *
785  * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
786  */
787 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
788         struct _obstack_chunk *p;
789
790         /*
791          * checks weather the ir_node pointer is on the obstack.
792          * A more sophisticated check would test the "whole" ir_node
793          */
794         for (p = irg->obst->chunk; p; p = p->prev) {
795                 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
796                         return 1;
797         }
798
799         return 0;
800 }
801
802 irg_phase_state
803 (get_irg_phase_state)(const ir_graph *irg) {
804         return _get_irg_phase_state(irg);
805 }
806
807 void
808 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
809         _set_irg_phase_state(irg, state);
810 }
811
812 op_pin_state
813 (get_irg_pinned)(const ir_graph *irg) {
814         return _get_irg_pinned(irg);
815 }
816
817 irg_outs_state
818 (get_irg_outs_state)(const ir_graph *irg) {
819         return _get_irg_outs_state(irg);
820 }
821
822 void
823 (set_irg_outs_inconsistent)(ir_graph *irg) {
824         _set_irg_outs_inconsistent(irg);
825 }
826
827 irg_extblk_state
828 (get_irg_extblk_state)(const ir_graph *irg) {
829         return _get_irg_extblk_state(irg);
830 }
831
832 void
833 (set_irg_extblk_inconsistent)(ir_graph *irg) {
834         _set_irg_extblk_inconsistent(irg);
835 }
836
837 irg_dom_state
838 (get_irg_dom_state)(const ir_graph *irg) {
839         return _get_irg_dom_state(irg);
840 }
841
842 irg_dom_state
843 (get_irg_postdom_state)(const ir_graph *irg) {
844         return _get_irg_postdom_state(irg);
845 }
846
847 void
848 (set_irg_doms_inconsistent)(ir_graph *irg) {
849         _set_irg_doms_inconsistent(irg);
850 }
851
852 irg_loopinfo_state
853 (get_irg_loopinfo_state)(const ir_graph *irg) {
854         return _get_irg_loopinfo_state(irg);
855 }
856
857 void
858 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
859         _set_irg_loopinfo_state(irg, s);
860 }
861
862 void
863 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
864         _set_irg_loopinfo_inconsistent(irg);
865 }
866
867 void set_irp_loopinfo_inconsistent(void) {
868         int i;
869         for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
870                 set_irg_loopinfo_inconsistent(get_irp_irg(i));
871         }
872 }
873
874
875
876 void
877 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
878         _set_irg_pinned(irg, p);
879 }
880
881 irg_callee_info_state
882 (get_irg_callee_info_state)(const ir_graph *irg) {
883         return _get_irg_callee_info_state(irg);
884 }
885
886 void
887 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
888         _set_irg_callee_info_state(irg, s);
889 }
890
891 irg_inline_property
892 (get_irg_inline_property)(const ir_graph *irg) {
893         return _get_irg_inline_property(irg);
894 }
895
896 void
897 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
898         _set_irg_inline_property(irg, s);
899 }
900
901 unsigned
902 (get_irg_additional_properties)(const ir_graph *irg) {
903         return _get_irg_additional_properties(irg);
904 }
905
906 void
907 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
908         _set_irg_additional_properties(irg, property_mask);
909 }
910
911 void
912 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
913         _set_irg_additional_property(irg, flag);
914 }
915
916 void
917 (set_irg_link)(ir_graph *irg, void *thing) {
918         _set_irg_link(irg, thing);
919 }
920
921 void *
922 (get_irg_link)(const ir_graph *irg) {
923         return _get_irg_link(irg);
924 }
925
926 ir_visited_t
927 (get_irg_visited)(const ir_graph *irg) {
928         return _get_irg_visited(irg);
929 }
930
931 #ifdef INTERPROCEDURAL_VIEW
932 /** maximum visited flag content of all ir_graph visited fields. */
933 static ir_visited_t max_irg_visited = 0;
934 #endif /* INTERPROCEDURAL_VIEW */
935
936 void
937 set_irg_visited(ir_graph *irg, ir_visited_t visited) {
938         irg->visited = visited;
939 #ifdef INTERPROCEDURAL_VIEW
940         if (irg->visited > max_irg_visited) {
941                 max_irg_visited = irg->visited;
942         }
943 #endif /* INTERPROCEDURAL_VIEW */
944 }
945
946 void
947 inc_irg_visited(ir_graph *irg) {
948 #ifdef INTERPROCEDURAL_VIEW
949         if (++irg->visited > max_irg_visited) {
950                 max_irg_visited = irg->visited;
951         }
952 #else
953         ++irg->visited;
954 #endif /* INTERPROCEDURAL_VIEW */
955 }
956
957 #ifdef INTERPROCEDURAL_VIEW
958 ir_visited_t
959 get_max_irg_visited(void) {
960 #ifndef NDEBUG
961         int i;
962         for(i = 0; i < get_irp_n_irgs(); i++)
963                 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
964 #endif
965         return max_irg_visited;
966 }
967
968 void set_max_irg_visited(int val) {
969         max_irg_visited = val;
970 }
971
972 ir_visited_t
973 inc_max_irg_visited(void) {
974 #ifndef NDEBUG
975         int i;
976         for(i = 0; i < get_irp_n_irgs(); i++)
977                 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
978 #endif
979         return ++max_irg_visited;
980 }
981 #endif /* INTERPROCEDURAL_VIEW */
982
983 ir_visited_t
984 (get_irg_block_visited)(const ir_graph *irg) {
985         return _get_irg_block_visited(irg);
986 }
987
988 void
989 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
990         _set_irg_block_visited(irg, visited);
991 }
992
993 void
994 (inc_irg_block_visited)(ir_graph *irg) {
995   _inc_irg_block_visited(irg);
996 }
997
998 /* Return the floating point model of this graph. */
999 unsigned (get_irg_fp_model)(const ir_graph *irg) {
1000         return _get_irg_fp_model(irg);
1001 }
1002
1003 /* Sets the floating point model for this graph. */
1004 void set_irg_fp_model(ir_graph *irg, unsigned model) {
1005         irg->fp_model = model;
1006 }
1007
1008 /**
1009  * walker Start->End: places Proj nodes into the same block
1010  * as it's predecessors
1011  *
1012  * @param n    the node
1013  * @param env  ignored
1014  */
1015 static void normalize_proj_walker(ir_node *n, void *env) {
1016         (void) env;
1017         if (is_Proj(n)) {
1018                 ir_node *pred  = get_Proj_pred(n);
1019                 ir_node *block = get_nodes_block(pred);
1020
1021                 set_nodes_block(n, block);
1022         }
1023 }
1024
1025 /* move Proj nodes into the same block as its predecessors */
1026 void normalize_proj_nodes(ir_graph *irg) {
1027         irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1028         set_irg_outs_inconsistent(irg);
1029 }
1030
1031 /* set a description for local value n */
1032 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1033         assert(0 <= n && n < irg->n_loc);
1034
1035         if (! irg->loc_descriptions)
1036                 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1037
1038         irg->loc_descriptions[n] = description;
1039 }
1040
1041 /* get the description for local value n */
1042 void *get_irg_loc_description(ir_graph *irg, int n) {
1043         assert(0 <= n && n < irg->n_loc);
1044         return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1045 }
1046
1047 #ifndef NDEBUG
1048 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources) {
1049         assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1050         assert((irg->reserved_resources & resources) == 0);
1051         irg->reserved_resources |= resources;
1052 }
1053
1054 void ir_free_resources(ir_graph *irg, ir_resources_t resources) {
1055         assert((irg->reserved_resources & resources) == resources);
1056         irg->reserved_resources &= ~resources;
1057 }
1058
1059 ir_resources_t ir_resources_reserved(const ir_graph *irg) {
1060         return irg->reserved_resources;
1061 }
1062 #endif /* NDEBUG */
1063
1064 /* Returns a estimated node count of the irg. */
1065 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1066         return _get_irg_estimated_node_cnt(irg);
1067 }
1068
1069 /* Returns the last irn index for this graph. */
1070 unsigned get_irg_last_idx(const ir_graph *irg) {
1071         return irg->last_node_idx;
1072 }
1073
1074 /* register additional space in an IR graph */
1075 size_t register_additional_graph_data(size_t size) {
1076         assert(!forbid_new_data && "Too late to register additional node data");
1077
1078         if (forbid_new_data)
1079                 return 0;
1080
1081         return additional_graph_data_size += size;
1082 }