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