Primitive, Pointer, Array and Method types are anonymous now
[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, *bad;
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();
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         bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
252         bad->attr.irg.irg = res;
253         set_irg_bad        (res, bad);
254         set_irg_no_mem     (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
255         start = new_Start();
256         set_irg_start      (res, start);
257
258         /* Proj results of start node */
259         projX                   = new_Proj(start, mode_X, pn_Start_X_initial_exec);
260         set_irg_initial_exec    (res, projX);
261         set_irg_frame           (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
262         set_irg_tls             (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
263         set_irg_args            (res, new_Proj(start, mode_T,      pn_Start_T_args));
264         initial_mem             = new_Proj(start, mode_M, pn_Start_M);
265         set_irg_initial_mem(res, initial_mem);
266
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         mature_immBlock(res->current_block);
275
276         /*-- Make a block to start with --*/
277         first_block = new_immBlock();
278         set_cur_block(first_block);
279         add_immBlock_pred(first_block, projX);
280
281         res->method_execution_frequency = -1.0;
282         res->estimated_node_count       = 0;
283
284         return res;
285 }
286
287 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
288         ir_graph *res = new_r_ir_graph(ent, n_loc);
289         add_irp_irg(res);          /* remember this graph global. */
290         return res;
291 }
292
293 /* Make a rudimentary IR graph for the constant code.
294    Must look like a correct irg, spare everything else. */
295 ir_graph *new_const_code_irg(void)
296 {
297         ir_graph *res = alloc_graph();
298         ir_node  *bad;
299         ir_node  *body_block;
300         ir_node  *end;
301         ir_node  *end_block;
302         ir_node  *no_mem;
303         ir_node  *projX;
304         ir_node  *start_block;
305         ir_node  *start;
306
307         /* inform statistics here, as blocks will be already build on this graph */
308         hook_new_graph(res, NULL);
309
310         current_ir_graph   = res;
311         res->n_loc         = 1; /* Only the memory. */
312         res->visited       = 0; /* visited flag, for the ir walker */
313         res->block_visited = 0; /* visited flag, for the 'block'-walker */
314         res->obst          = XMALLOC(struct obstack);
315         obstack_init(res->obst);
316         res->extbb_obst = NULL;
317
318         res->last_node_idx = 0;
319
320         res->phase_state      = phase_building;
321         res->irg_pinned_state = op_pin_state_pinned;
322         res->extblk_state     = ir_extblk_info_none;
323         res->fp_model         = fp_model_precise;
324
325         /* value table for global value numbering for optimizing use in iropt.c */
326         res->value_table = new_identities();
327         res->ent         = NULL;
328         res->frame_type  = NULL;
329
330         /* the Anchor node must be created first */
331         res->anchor = new_Anchor(res);
332
333         /* -- The end block -- */
334         end_block = new_immBlock();
335         set_irg_end_block(res, end_block);
336         set_cur_block(end_block);
337         end = new_End();
338         set_irg_end       (res, end);
339         set_irg_end_reg   (res, end);
340         set_irg_end_except(res, end);
341         mature_immBlock(end_block);
342
343         /* -- The start block -- */
344         start_block        = new_immBlock();
345         set_cur_block(start_block);
346         set_irg_start_block(res, start_block);
347         bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
348         bad->attr.irg.irg = res;
349         set_irg_bad(res, bad);
350         no_mem = new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL);
351         set_irg_no_mem(res, no_mem);
352         start = new_Start();
353         set_irg_start(res, start);
354
355         /* Proj results of start node */
356         set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
357         projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
358         mature_immBlock(start_block);
359
360         body_block = new_immBlock();
361         add_immBlock_pred(body_block, projX);
362         mature_immBlock(body_block); /* mature the 'body' block for expressions */
363         set_cur_block(body_block);
364
365         /* Set the visited flag high enough that the blocks will never be visited. */
366         set_irn_visited(body_block, -1);
367         set_Block_block_visited(body_block, -1);
368         set_Block_block_visited(start_block, -1);
369         set_irn_visited(start_block, -1);
370         set_irn_visited(bad, -1);
371         set_irn_visited(no_mem, -1);
372
373         res->phase_state = phase_high;
374
375         return res;
376 }
377
378 /**
379  * Pre-Walker: Copies blocks and nodes from the original method graph
380  * to the copied graph.
381  *
382  * @param n    A node from the original method graph.
383  * @param env  The copied graph.
384  */
385 static void copy_all_nodes(ir_node *n, void *env) {
386         ir_graph *irg = env;
387         ir_op    *op  = get_irn_op(n);
388         ir_node  *nn;
389
390         nn = new_ir_node(get_irn_dbg_info(n),
391                          irg,
392                          NULL,            /* no block yet, will be set later */
393                          op,
394                          get_irn_mode(n),
395                          get_irn_arity(n),
396                          get_irn_in(n) + 1);
397
398
399         /* Copy the attributes.  These might point to additional data.  If this
400            was allocated on the old obstack the pointers now are dangling.  This
401            frees e.g. the memory of the graph_arr allocated in new_immBlock. */
402         copy_node_attr(n, nn);
403         new_backedge_info(nn);
404         set_irn_link(n, nn);
405
406         /* fix the irg for Blocks: as Bad nodes are NOT copied, no
407            need t fix them */
408         if (is_Block(nn))
409                 nn->attr.block.irg.irg = irg;
410
411         /* fix access to entities on the stack frame */
412         if (is_Sel(nn)) {
413                 ir_entity *ent = get_Sel_entity(nn);
414                 ir_type   *tp = get_entity_owner(ent);
415
416                 if (is_frame_type(tp)) {
417                         /* replace by the copied entity */
418                         ent = get_entity_link(ent);
419
420                         assert(is_entity(ent));
421                         assert(get_entity_owner(ent) == get_irg_frame_type(irg));
422                         set_Sel_entity(nn, ent);
423                 }
424         }
425 }
426
427 /**
428  * Post-walker: Set the predecessors of the copied nodes.
429  * The copied nodes are set as link of their original nodes. The links of
430  * "irn" predecessors are the predecessors of copied node.
431  */
432 static void set_all_preds(ir_node *irn, void *env) {
433         int      i;
434         ir_node  *nn, *pred;
435         (void) env;
436
437         nn = get_irn_link(irn);
438
439         if (is_Block(irn)) {
440                 ir_node *mbh = get_Block_MacroBlock(irn);
441                 set_Block_MacroBlock(nn, get_irn_link(mbh));
442                 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
443                         pred = get_Block_cfgpred(irn, i);
444                         set_Block_cfgpred(nn, i, get_irn_link(pred));
445                 }
446         } else {
447                 /* First we set the block our copy if it is not a block.*/
448                 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
449                 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
450                         pred = get_irn_n(irn, i);
451                         set_irn_n(nn, i, get_irn_link(pred));
452                 }
453         }
454 }
455
456 #define NN(irn)  get_irn_link(irn)
457
458 /*
459  * Create a new graph that is a copy of a given one.
460  */
461 ir_graph *create_irg_copy(ir_graph *irg) {
462         ir_graph *res;
463
464         res = alloc_graph();
465
466         res->n_loc = 0;
467         res->visited = 0;       /* visited flag, for the ir walker */
468         res->block_visited = 0; /* visited flag, for the 'block'-walker */
469         res->obst       = XMALLOC(struct obstack);
470         obstack_init(res->obst);
471         res->extbb_obst = NULL;
472
473         res->last_node_idx = 0;
474
475         res->phase_state      = irg->phase_state;
476         res->irg_pinned_state = irg->irg_pinned_state;
477         res->extblk_state     = ir_extblk_info_none;
478         res->fp_model         = irg->fp_model;
479
480         res->value_table = new_identities();
481
482         /* clone the frame type here for safety */
483         irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
484         res->frame_type  = clone_frame_type(irg->frame_type);
485
486         res->phase_state = irg->phase_state;
487
488         ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
489
490         /* copy all nodes from the graph irg to the new graph res */
491         irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
492
493         /* copy the Anchor node */
494         res->anchor = NN(irg->anchor);
495
496         /* -- The end block -- */
497         set_irg_end_block (res, NN(get_irg_end_block(irg)));
498         set_irg_end       (res, NN(get_irg_end(irg)));
499         set_irg_end_reg   (res, NN(get_irg_end_reg(irg)));
500         set_irg_end_except(res, NN(get_irg_end_except(irg)));
501
502         /* -- The start block -- */
503         set_irg_start_block(res, NN(get_irg_start_block(irg)));
504         set_irg_bad        (res, NN(get_irg_bad(irg)));
505         set_irg_no_mem     (res, NN(get_irg_no_mem(irg)));
506         set_irg_start      (res, NN(get_irg_start(irg)));
507
508         /* Proj results of start node */
509         set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
510
511         /* Copy the node count estimation. Would be strange if this
512            is different from the original one. */
513         res->estimated_node_count = irg->estimated_node_count;
514
515         ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
516         irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
517
518         return res;
519 }
520 #undef NN
521
522
523 /* Frees the passed irgraph.
524    Deallocates all nodes in this graph and the ir_graph structure.
525    Sets the field irgraph in the corresponding entity to NULL.
526    Does not remove the irgraph from the list in irprog (requires
527    inefficient search, call remove_irp_irg by hand).
528    Does not free types, entities or modes that are used only by this
529    graph, nor the entity standing for this graph. */
530 void free_ir_graph(ir_graph *irg) {
531         assert(is_ir_graph(irg));
532
533         edges_deactivate(irg);
534
535         hook_free_graph(irg);
536         if (irg->outs_state != outs_none)
537                 free_irg_outs(irg);
538         if (irg->frame_type)
539                 free_type(irg->frame_type);
540         if (irg->value_table)
541                 del_identities(irg->value_table);
542         if (irg->ent) {
543                 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
544                 set_entity_peculiarity (irg->ent, peculiarity_description);
545                 set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
546                 set_entity_peculiarity (irg->ent, pec);
547         }
548
549         free_End(get_irg_end(irg));
550         obstack_free(irg->obst,NULL);
551         free(irg->obst);
552         if (irg->loc_descriptions)
553                 free(irg->loc_descriptions);
554         irg->kind = k_BAD;
555         free_graph(irg);
556 }
557
558 /* access routines for all ir_graph attributes:
559    templates:
560    {attr type} get_irg_{attribute name} (ir_graph *irg);
561    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
562
563 int
564 (is_ir_graph)(const void *thing) {
565         return _is_ir_graph(thing);
566 }
567
568 #ifdef DEBUG_libfirm
569 /* Outputs a unique number for this node */
570 long get_irg_graph_nr(const ir_graph *irg) {
571         return irg->graph_nr;
572 }
573 #else
574 long get_irg_graph_nr(const ir_graph *irg) {
575         return PTR_TO_INT(irg);
576 }
577 #endif
578
579 int get_irg_idx(const ir_graph *irg) {
580         return irg->index;
581 }
582
583 ir_node *(get_idx_irn)(ir_graph *irg, unsigned idx) {
584         return _get_idx_irn(irg, idx);
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_bad)(const ir_graph *irg) {
700         return _get_irg_bad(irg);
701 }
702
703 void
704 (set_irg_bad)(ir_graph *irg, ir_node *node) {
705         _set_irg_bad(irg, node);
706 }
707
708 ir_node *
709 (get_irg_no_mem)(const ir_graph *irg) {
710         return _get_irg_no_mem(irg);
711 }
712
713 void
714 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
715         _set_irg_no_mem(irg, node);
716 }
717
718 ir_node *
719 (get_irg_current_block)(const ir_graph *irg) {
720         return _get_irg_current_block(irg);
721 }
722
723 void
724 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
725         _set_irg_current_block(irg, node);
726 }
727
728 ir_entity *
729 (get_irg_entity)(const ir_graph *irg) {
730         return _get_irg_entity(irg);
731 }
732
733 void
734 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
735         _set_irg_entity(irg, ent);
736 }
737
738 ir_type *
739 (get_irg_frame_type)(ir_graph *irg) {
740         return _get_irg_frame_type(irg);
741 }
742
743 void
744 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
745         _set_irg_frame_type(irg, ftp);
746 }
747
748 /* Returns the value parameter type of an IR graph. */
749 ir_type *get_irg_value_param_type(ir_graph *irg) {
750         ir_entity *ent = get_irg_entity(irg);
751         ir_type   *mtp = get_entity_type(ent);
752         return get_method_value_param_type(mtp);
753 }
754
755 int
756 get_irg_n_locs(ir_graph *irg) {
757         if (get_opt_precise_exc_context())
758                 return irg->n_loc - 1 - 1;
759         else
760                 return irg->n_loc - 1;
761 }
762
763 void
764 set_irg_n_loc(ir_graph *irg, int n_loc) {
765         if (get_opt_precise_exc_context())
766                 irg->n_loc = n_loc + 1 + 1;
767         else
768                 irg->n_loc = n_loc + 1;
769 }
770
771
772
773 /* Returns the obstack associated with the graph. */
774 struct obstack *
775 (get_irg_obstack)(const ir_graph *irg) {
776         return _get_irg_obstack(irg);
777 }
778
779 /*
780  * Returns true if the node n is allocated on the storage of graph irg.
781  *
782  * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
783  */
784 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
785         struct _obstack_chunk *p;
786
787         /*
788          * checks weather the ir_node pointer is on the obstack.
789          * A more sophisticated check would test the "whole" ir_node
790          */
791         for (p = irg->obst->chunk; p; p = p->prev) {
792                 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
793                         return 1;
794         }
795
796         return 0;
797 }
798
799 irg_phase_state
800 (get_irg_phase_state)(const ir_graph *irg) {
801         return _get_irg_phase_state(irg);
802 }
803
804 void
805 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
806         _set_irg_phase_state(irg, state);
807 }
808
809 op_pin_state
810 (get_irg_pinned)(const ir_graph *irg) {
811         return _get_irg_pinned(irg);
812 }
813
814 irg_outs_state
815 (get_irg_outs_state)(const ir_graph *irg) {
816         return _get_irg_outs_state(irg);
817 }
818
819 void
820 (set_irg_outs_inconsistent)(ir_graph *irg) {
821         _set_irg_outs_inconsistent(irg);
822 }
823
824 irg_extblk_state
825 (get_irg_extblk_state)(const ir_graph *irg) {
826         return _get_irg_extblk_state(irg);
827 }
828
829 void
830 (set_irg_extblk_inconsistent)(ir_graph *irg) {
831         _set_irg_extblk_inconsistent(irg);
832 }
833
834 irg_dom_state
835 (get_irg_dom_state)(const ir_graph *irg) {
836         return _get_irg_dom_state(irg);
837 }
838
839 irg_dom_state
840 (get_irg_postdom_state)(const ir_graph *irg) {
841         return _get_irg_postdom_state(irg);
842 }
843
844 void
845 (set_irg_doms_inconsistent)(ir_graph *irg) {
846         _set_irg_doms_inconsistent(irg);
847 }
848
849 irg_loopinfo_state
850 (get_irg_loopinfo_state)(const ir_graph *irg) {
851         return _get_irg_loopinfo_state(irg);
852 }
853
854 void
855 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
856         _set_irg_loopinfo_state(irg, s);
857 }
858
859 void
860 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
861         _set_irg_loopinfo_inconsistent(irg);
862 }
863
864 void set_irp_loopinfo_inconsistent(void) {
865         int i;
866         for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
867                 set_irg_loopinfo_inconsistent(get_irp_irg(i));
868         }
869 }
870
871
872
873 void
874 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
875         _set_irg_pinned(irg, p);
876 }
877
878 irg_callee_info_state
879 (get_irg_callee_info_state)(const ir_graph *irg) {
880         return _get_irg_callee_info_state(irg);
881 }
882
883 void
884 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
885         _set_irg_callee_info_state(irg, s);
886 }
887
888 irg_inline_property
889 (get_irg_inline_property)(const ir_graph *irg) {
890         return _get_irg_inline_property(irg);
891 }
892
893 void
894 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
895         _set_irg_inline_property(irg, s);
896 }
897
898 unsigned
899 (get_irg_additional_properties)(const ir_graph *irg) {
900         return _get_irg_additional_properties(irg);
901 }
902
903 void
904 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
905         _set_irg_additional_properties(irg, property_mask);
906 }
907
908 void
909 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
910         _set_irg_additional_property(irg, flag);
911 }
912
913 void
914 (set_irg_link)(ir_graph *irg, void *thing) {
915         _set_irg_link(irg, thing);
916 }
917
918 void *
919 (get_irg_link)(const ir_graph *irg) {
920         return _get_irg_link(irg);
921 }
922
923 ir_visited_t
924 (get_irg_visited)(const ir_graph *irg) {
925         return _get_irg_visited(irg);
926 }
927
928 #ifdef INTERPROCEDURAL_VIEW
929 /** maximum visited flag content of all ir_graph visited fields. */
930 static ir_visited_t max_irg_visited = 0;
931 #endif /* INTERPROCEDURAL_VIEW */
932
933 void
934 set_irg_visited(ir_graph *irg, ir_visited_t visited) {
935         irg->visited = visited;
936 #ifdef INTERPROCEDURAL_VIEW
937         if (irg->visited > max_irg_visited) {
938                 max_irg_visited = irg->visited;
939         }
940 #endif /* INTERPROCEDURAL_VIEW */
941 }
942
943 void
944 inc_irg_visited(ir_graph *irg) {
945 #ifdef INTERPROCEDURAL_VIEW
946         if (++irg->visited > max_irg_visited) {
947                 max_irg_visited = irg->visited;
948         }
949 #else
950         ++irg->visited;
951 #endif /* INTERPROCEDURAL_VIEW */
952 }
953
954 #ifdef INTERPROCEDURAL_VIEW
955 ir_visited_t
956 get_max_irg_visited(void) {
957 #ifndef NDEBUG
958         int i;
959         for(i = 0; i < get_irp_n_irgs(); i++)
960                 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
961 #endif
962         return max_irg_visited;
963 }
964
965 void set_max_irg_visited(int val) {
966         max_irg_visited = val;
967 }
968
969 ir_visited_t
970 inc_max_irg_visited(void) {
971 #ifndef NDEBUG
972         int i;
973         for(i = 0; i < get_irp_n_irgs(); i++)
974                 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
975 #endif
976         return ++max_irg_visited;
977 }
978 #endif /* INTERPROCEDURAL_VIEW */
979
980 ir_visited_t
981 (get_irg_block_visited)(const ir_graph *irg) {
982         return _get_irg_block_visited(irg);
983 }
984
985 void
986 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
987         _set_irg_block_visited(irg, visited);
988 }
989
990 void
991 (inc_irg_block_visited)(ir_graph *irg) {
992   _inc_irg_block_visited(irg);
993 }
994
995 /* Return the floating point model of this graph. */
996 unsigned (get_irg_fp_model)(const ir_graph *irg) {
997         return _get_irg_fp_model(irg);
998 }
999
1000 /* Sets the floating point model for this graph. */
1001 void set_irg_fp_model(ir_graph *irg, unsigned model) {
1002         irg->fp_model = model;
1003 }
1004
1005 /**
1006  * walker Start->End: places Proj nodes into the same block
1007  * as it's predecessors
1008  *
1009  * @param n    the node
1010  * @param env  ignored
1011  */
1012 static void normalize_proj_walker(ir_node *n, void *env) {
1013         (void) env;
1014         if (is_Proj(n)) {
1015                 ir_node *pred  = get_Proj_pred(n);
1016                 ir_node *block = get_nodes_block(pred);
1017
1018                 set_nodes_block(n, block);
1019         }
1020 }
1021
1022 /* move Proj nodes into the same block as its predecessors */
1023 void normalize_proj_nodes(ir_graph *irg) {
1024         irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1025         set_irg_outs_inconsistent(irg);
1026 }
1027
1028 /* set a description for local value n */
1029 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1030         assert(0 <= n && n < irg->n_loc);
1031
1032         if (! irg->loc_descriptions)
1033                 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1034
1035         irg->loc_descriptions[n] = description;
1036 }
1037
1038 /* get the description for local value n */
1039 void *get_irg_loc_description(ir_graph *irg, int n) {
1040         assert(0 <= n && n < irg->n_loc);
1041         return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1042 }
1043
1044 #ifndef NDEBUG
1045 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources) {
1046         assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1047         assert((irg->reserved_resources & resources) == 0);
1048         irg->reserved_resources |= resources;
1049 }
1050
1051 void ir_free_resources(ir_graph *irg, ir_resources_t resources) {
1052         assert((irg->reserved_resources & resources) == resources);
1053         irg->reserved_resources &= ~resources;
1054 }
1055
1056 ir_resources_t ir_resources_reserved(const ir_graph *irg) {
1057         return irg->reserved_resources;
1058 }
1059 #endif /* NDEBUG */
1060
1061 /* Returns a estimated node count of the irg. */
1062 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1063         return _get_irg_estimated_node_cnt(irg);
1064 }
1065
1066 /* Returns the last irn index for this graph. */
1067 unsigned get_irg_last_idx(const ir_graph *irg) {
1068         return irg->last_node_idx;
1069 }
1070
1071 /* register additional space in an IR graph */
1072 size_t register_additional_graph_data(size_t size) {
1073         assert(!forbid_new_data && "Too late to register additional node data");
1074
1075         if (forbid_new_data)
1076                 return 0;
1077
1078         return additional_graph_data_size += size;
1079 }
1080
1081 void (set_irg_state)(ir_graph *irg, ir_graph_state_t state)
1082 {
1083         _set_irg_state(irg, state);
1084 }
1085
1086 void (clear_irg_state)(ir_graph *irg, ir_graph_state_t state)
1087 {
1088         _clear_irg_state(irg, state);
1089 }
1090
1091 int (is_irg_state)(const ir_graph *irg, ir_graph_state_t state)
1092 {
1093         return _is_irg_state(irg, state);
1094 }