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