- cleanup and simplify inlining code
[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(irg, n, nn);
414         set_irn_link(n, nn);
415
416         /* fix the irg for Blocks: as Bad nodes are NOT copied, no
417            need t fix them */
418         if (is_Block(nn))
419                 nn->attr.block.irg.irg = irg;
420
421         /* fix access to entities on the stack frame */
422         if (is_Sel(nn)) {
423                 ir_entity *ent = get_Sel_entity(nn);
424                 ir_type   *tp = get_entity_owner(ent);
425
426                 if (is_frame_type(tp)) {
427                         /* replace by the copied entity */
428                         ent = get_entity_link(ent);
429
430                         assert(is_entity(ent));
431                         assert(get_entity_owner(ent) == get_irg_frame_type(irg));
432                         set_Sel_entity(nn, ent);
433                 }
434         }
435 }
436
437 /**
438  * Post-walker: Set the predecessors of the copied nodes.
439  * The copied nodes are set as link of their original nodes. The links of
440  * "irn" predecessors are the predecessors of copied node.
441  */
442 static void set_all_preds(ir_node *irn, void *env)
443 {
444         int      i;
445         ir_node  *nn, *pred;
446         (void) env;
447
448         nn = get_irn_link(irn);
449
450         if (is_Block(irn)) {
451                 ir_node *mbh = get_Block_MacroBlock(irn);
452                 set_Block_MacroBlock(nn, get_irn_link(mbh));
453                 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
454                         pred = get_Block_cfgpred(irn, i);
455                         set_Block_cfgpred(nn, i, get_irn_link(pred));
456                 }
457         } else {
458                 /* First we set the block our copy if it is not a block.*/
459                 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
460                 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
461                         pred = get_irn_n(irn, i);
462                         set_irn_n(nn, i, get_irn_link(pred));
463                 }
464         }
465 }
466
467 #define NN(irn)  get_irn_link(irn)
468
469 /*
470  * Create a new graph that is a copy of a given one.
471  */
472 ir_graph *create_irg_copy(ir_graph *irg)
473 {
474         ir_graph *res;
475
476         res = alloc_graph();
477
478         res->n_loc = 0;
479         res->visited = 0;       /* visited flag, for the ir walker */
480         res->block_visited = 0; /* visited flag, for the 'block'-walker */
481         res->obst       = XMALLOC(struct obstack);
482         obstack_init(res->obst);
483         res->extbb_obst = NULL;
484
485         res->last_node_idx = 0;
486
487         res->phase_state      = irg->phase_state;
488         res->irg_pinned_state = irg->irg_pinned_state;
489         res->extblk_state     = ir_extblk_info_none;
490         res->fp_model         = irg->fp_model;
491
492         res->value_table = new_identities();
493
494         /* clone the frame type here for safety */
495         irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
496         res->frame_type  = clone_frame_type(irg->frame_type);
497
498         res->phase_state = irg->phase_state;
499
500         ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
501
502         /* copy all nodes from the graph irg to the new graph res */
503         irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
504
505         /* copy the Anchor node */
506         res->anchor = NN(irg->anchor);
507
508         /* -- The end block -- */
509         set_irg_end_block (res, NN(get_irg_end_block(irg)));
510         set_irg_end       (res, NN(get_irg_end(irg)));
511         set_irg_end_reg   (res, NN(get_irg_end_reg(irg)));
512         set_irg_end_except(res, NN(get_irg_end_except(irg)));
513
514         /* -- The start block -- */
515         set_irg_start_block(res, NN(get_irg_start_block(irg)));
516         set_irg_bad        (res, NN(get_irg_bad(irg)));
517         set_irg_no_mem     (res, NN(get_irg_no_mem(irg)));
518         set_irg_start      (res, NN(get_irg_start(irg)));
519
520         /* Proj results of start node */
521         set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
522
523         /* Copy the node count estimation. Would be strange if this
524            is different from the original one. */
525         res->estimated_node_count = irg->estimated_node_count;
526
527         ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
528         irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
529
530         return res;
531 }
532 #undef NN
533
534
535 /* Frees the passed irgraph.
536    Deallocates all nodes in this graph and the ir_graph structure.
537    Sets the field irgraph in the corresponding entity to NULL.
538    Does not remove the irgraph from the list in irprog (requires
539    inefficient search, call remove_irp_irg by hand).
540    Does not free types, entities or modes that are used only by this
541    graph, nor the entity standing for this graph. */
542 void free_ir_graph(ir_graph *irg)
543 {
544         assert(is_ir_graph(irg));
545
546         edges_deactivate(irg);
547
548         hook_free_graph(irg);
549         if (irg->outs_state != outs_none)
550                 free_irg_outs(irg);
551         if (irg->frame_type)
552                 free_type(irg->frame_type);
553         if (irg->value_table)
554                 del_identities(irg->value_table);
555         if (irg->ent) {
556                 set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
557         }
558
559         free_End(get_irg_end(irg));
560         obstack_free(irg->obst,NULL);
561         free(irg->obst);
562         if (irg->loc_descriptions)
563                 free(irg->loc_descriptions);
564         irg->kind = k_BAD;
565         free_graph(irg);
566 }
567
568 /* access routines for all ir_graph attributes:
569    templates:
570    {attr type} get_irg_{attribute name} (ir_graph *irg);
571    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
572
573 int (is_ir_graph)(const void *thing)
574 {
575         return _is_ir_graph(thing);
576 }
577
578 #ifdef DEBUG_libfirm
579 /* Outputs a unique number for this node */
580 long get_irg_graph_nr(const ir_graph *irg)
581 {
582         return irg->graph_nr;
583 }
584 #else
585 long get_irg_graph_nr(const ir_graph *irg)
586 {
587         return PTR_TO_INT(irg);
588 }
589 #endif
590
591 int get_irg_idx(const ir_graph *irg)
592 {
593         return irg->index;
594 }
595
596 ir_node *(get_idx_irn)(ir_graph *irg, unsigned idx)
597 {
598         return _get_idx_irn(irg, idx);
599 }
600
601 ir_node *(get_irg_start_block)(const ir_graph *irg)
602 {
603         return _get_irg_start_block(irg);
604 }
605
606 void (set_irg_start_block)(ir_graph *irg, ir_node *node)
607 {
608         _set_irg_start_block(irg, node);
609 }
610
611 ir_node *(get_irg_start)(const ir_graph *irg)
612 {
613         return _get_irg_start(irg);
614 }
615
616 void (set_irg_start)(ir_graph *irg, ir_node *node)
617 {
618         _set_irg_start(irg, node);
619 }
620
621 ir_node *(get_irg_end_block)(const ir_graph *irg)
622 {
623         return _get_irg_end_block(irg);
624 }
625
626 void (set_irg_end_block)(ir_graph *irg, ir_node *node)
627 {
628   _set_irg_end_block(irg, node);
629 }
630
631 ir_node *(get_irg_end)(const ir_graph *irg)
632 {
633         return _get_irg_end(irg);
634 }
635
636 void (set_irg_end)(ir_graph *irg, ir_node *node)
637 {
638         _set_irg_end(irg, node);
639 }
640
641 ir_node *(get_irg_end_reg)(const ir_graph *irg)
642 {
643         return _get_irg_end_reg(irg);
644 }
645
646 void (set_irg_end_reg)(ir_graph *irg, ir_node *node)
647 {
648         _set_irg_end_reg(irg, node);
649 }
650
651 ir_node *(get_irg_end_except)(const ir_graph *irg)
652 {
653         return _get_irg_end_except(irg);
654 }
655
656 void (set_irg_end_except)(ir_graph *irg, ir_node *node)
657 {
658         assert(get_irn_op(node) == op_EndExcept || is_End(node));
659         _set_irg_end_except(irg, node);
660 }
661
662 ir_node *(get_irg_initial_exec)(const ir_graph *irg)
663 {
664         return _get_irg_initial_exec(irg);
665 }
666
667 void (set_irg_initial_exec)(ir_graph *irg, ir_node *node)
668 {
669         _set_irg_initial_exec(irg, node);
670 }
671
672 ir_node *(get_irg_frame)(const ir_graph *irg)
673 {
674         return _get_irg_frame(irg);
675 }
676
677 void (set_irg_frame)(ir_graph *irg, ir_node *node)
678 {
679         _set_irg_frame(irg, node);
680 }
681
682 ir_node *(get_irg_tls)(const ir_graph *irg)
683 {
684         return _get_irg_tls(irg);
685 }
686
687 void (set_irg_tls)(ir_graph *irg, ir_node *node)
688 {
689         _set_irg_tls(irg, node);
690 }
691
692 ir_node *(get_irg_initial_mem)(const ir_graph *irg)
693 {
694         return _get_irg_initial_mem(irg);
695 }
696
697 void (set_irg_initial_mem)(ir_graph *irg, ir_node *node)
698 {
699         _set_irg_initial_mem(irg, node);
700 }
701
702 ir_node *(get_irg_args)(const ir_graph *irg)
703 {
704         return _get_irg_args(irg);
705 }
706
707 void (set_irg_args)(ir_graph *irg, ir_node *node)
708 {
709         _set_irg_args(irg, node);
710 }
711
712 ir_node *(get_irg_bad)(const ir_graph *irg)
713 {
714         return _get_irg_bad(irg);
715 }
716
717 void (set_irg_bad)(ir_graph *irg, ir_node *node)
718 {
719         _set_irg_bad(irg, node);
720 }
721
722 ir_node *(get_irg_no_mem)(const ir_graph *irg)
723 {
724         return _get_irg_no_mem(irg);
725 }
726
727 void (set_irg_no_mem)(ir_graph *irg, ir_node *node)
728 {
729         _set_irg_no_mem(irg, node);
730 }
731
732 ir_node *(get_irg_current_block)(const ir_graph *irg)
733 {
734         return _get_irg_current_block(irg);
735 }
736
737 void (set_irg_current_block)(ir_graph *irg, ir_node *node)
738 {
739         _set_irg_current_block(irg, node);
740 }
741
742 ir_entity *(get_irg_entity)(const ir_graph *irg)
743 {
744         return _get_irg_entity(irg);
745 }
746
747 void (set_irg_entity)(ir_graph *irg, ir_entity *ent)
748 {
749         _set_irg_entity(irg, ent);
750 }
751
752 ir_type *(get_irg_frame_type)(ir_graph *irg)
753 {
754         return _get_irg_frame_type(irg);
755 }
756
757 void (set_irg_frame_type)(ir_graph *irg, ir_type *ftp)
758 {
759         _set_irg_frame_type(irg, ftp);
760 }
761
762 /* Returns the value parameter type of an IR graph. */
763 ir_type *get_irg_value_param_type(ir_graph *irg)
764 {
765         ir_entity *ent = get_irg_entity(irg);
766         ir_type   *mtp = get_entity_type(ent);
767         return get_method_value_param_type(mtp);
768 }
769
770 int get_irg_n_locs(ir_graph *irg)
771 {
772         if (get_opt_precise_exc_context())
773                 return irg->n_loc - 1 - 1;
774         else
775                 return irg->n_loc - 1;
776 }
777
778 void set_irg_n_loc(ir_graph *irg, int n_loc)
779 {
780         if (get_opt_precise_exc_context())
781                 irg->n_loc = n_loc + 1 + 1;
782         else
783                 irg->n_loc = n_loc + 1;
784 }
785
786
787
788 /* Returns the obstack associated with the graph. */
789 struct obstack *
790 (get_irg_obstack)(const ir_graph *irg) {
791         return _get_irg_obstack(irg);
792 }
793
794 /*
795  * Returns true if the node n is allocated on the storage of graph irg.
796  *
797  * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
798  */
799 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n)
800 {
801         struct _obstack_chunk *p;
802
803         /*
804          * checks weather the ir_node pointer is on the obstack.
805          * A more sophisticated check would test the "whole" ir_node
806          */
807         for (p = irg->obst->chunk; p; p = p->prev) {
808                 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
809                         return 1;
810         }
811
812         return 0;
813 }
814
815 irg_phase_state (get_irg_phase_state)(const ir_graph *irg)
816 {
817         return _get_irg_phase_state(irg);
818 }
819
820 void (set_irg_phase_state)(ir_graph *irg, irg_phase_state state)
821 {
822         _set_irg_phase_state(irg, state);
823 }
824
825 op_pin_state (get_irg_pinned)(const ir_graph *irg)
826 {
827         return _get_irg_pinned(irg);
828 }
829
830 irg_outs_state (get_irg_outs_state)(const ir_graph *irg)
831 {
832         return _get_irg_outs_state(irg);
833 }
834
835 void (set_irg_outs_inconsistent)(ir_graph *irg)
836 {
837         _set_irg_outs_inconsistent(irg);
838 }
839
840 irg_extblk_state (get_irg_extblk_state)(const ir_graph *irg)
841 {
842         return _get_irg_extblk_state(irg);
843 }
844
845 void (set_irg_extblk_inconsistent)(ir_graph *irg)
846 {
847         _set_irg_extblk_inconsistent(irg);
848 }
849
850 irg_dom_state (get_irg_dom_state)(const ir_graph *irg)
851 {
852         return _get_irg_dom_state(irg);
853 }
854
855 irg_dom_state (get_irg_postdom_state)(const ir_graph *irg)
856 {
857         return _get_irg_postdom_state(irg);
858 }
859
860 void (set_irg_doms_inconsistent)(ir_graph *irg)
861 {
862         _set_irg_doms_inconsistent(irg);
863 }
864
865 irg_loopinfo_state (get_irg_loopinfo_state)(const ir_graph *irg)
866 {
867         return _get_irg_loopinfo_state(irg);
868 }
869
870 void (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s)
871 {
872         _set_irg_loopinfo_state(irg, s);
873 }
874
875 void (set_irg_loopinfo_inconsistent)(ir_graph *irg)
876 {
877         _set_irg_loopinfo_inconsistent(irg);
878 }
879
880 void set_irp_loopinfo_inconsistent(void)
881 {
882         int i;
883         for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
884                 set_irg_loopinfo_inconsistent(get_irp_irg(i));
885         }
886 }
887
888
889
890 void (set_irg_pinned)(ir_graph *irg, op_pin_state p)
891 {
892         _set_irg_pinned(irg, p);
893 }
894
895 irg_callee_info_state (get_irg_callee_info_state)(const ir_graph *irg)
896 {
897         return _get_irg_callee_info_state(irg);
898 }
899
900 void (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s)
901 {
902         _set_irg_callee_info_state(irg, s);
903 }
904
905 irg_inline_property (get_irg_inline_property)(const ir_graph *irg)
906 {
907         return _get_irg_inline_property(irg);
908 }
909
910 void (set_irg_inline_property)(ir_graph *irg, irg_inline_property s)
911 {
912         _set_irg_inline_property(irg, s);
913 }
914
915 unsigned (get_irg_additional_properties)(const ir_graph *irg)
916 {
917         return _get_irg_additional_properties(irg);
918 }
919
920 void (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask)
921 {
922         _set_irg_additional_properties(irg, property_mask);
923 }
924
925 void (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag)
926 {
927         _set_irg_additional_property(irg, flag);
928 }
929
930 void (set_irg_link)(ir_graph *irg, void *thing)
931 {
932         _set_irg_link(irg, thing);
933 }
934
935 void *(get_irg_link)(const ir_graph *irg)
936 {
937         return _get_irg_link(irg);
938 }
939
940 ir_visited_t (get_irg_visited)(const ir_graph *irg)
941 {
942         return _get_irg_visited(irg);
943 }
944
945 /** maximum visited flag content of all ir_graph visited fields. */
946 static ir_visited_t max_irg_visited = 0;
947
948 void set_irg_visited(ir_graph *irg, ir_visited_t visited)
949 {
950         irg->visited = visited;
951         if (irg->visited > max_irg_visited) {
952                 max_irg_visited = irg->visited;
953         }
954 }
955
956 void inc_irg_visited(ir_graph *irg)
957 {
958         ++irg->visited;
959         if (irg->visited > max_irg_visited) {
960                 max_irg_visited = irg->visited;
961         }
962 }
963
964 ir_visited_t get_max_irg_visited(void)
965 {
966         return max_irg_visited;
967 }
968
969 void set_max_irg_visited(int val)
970 {
971         max_irg_visited = val;
972 }
973
974 ir_visited_t inc_max_irg_visited(void)
975 {
976 #ifndef NDEBUG
977         int i;
978         for (i = 0; i < get_irp_n_irgs(); i++)
979                 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
980 #endif
981         return ++max_irg_visited;
982 }
983
984 ir_visited_t (get_irg_block_visited)(const ir_graph *irg)
985 {
986         return _get_irg_block_visited(irg);
987 }
988
989 void (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited)
990 {
991         _set_irg_block_visited(irg, visited);
992 }
993
994 void (inc_irg_block_visited)(ir_graph *irg)
995 {
996   _inc_irg_block_visited(irg);
997 }
998
999 /* Return the floating point model of this graph. */
1000 unsigned (get_irg_fp_model)(const ir_graph *irg)
1001 {
1002         return _get_irg_fp_model(irg);
1003 }
1004
1005 /* Sets the floating point model for this graph. */
1006 void set_irg_fp_model(ir_graph *irg, unsigned model)
1007 {
1008         irg->fp_model = model;
1009 }
1010
1011 /**
1012  * walker Start->End: places Proj nodes into the same block
1013  * as it's predecessors
1014  *
1015  * @param n    the node
1016  * @param env  ignored
1017  */
1018 static void normalize_proj_walker(ir_node *n, void *env)
1019 {
1020         (void) env;
1021         if (is_Proj(n)) {
1022                 ir_node *pred  = get_Proj_pred(n);
1023                 ir_node *block = get_nodes_block(pred);
1024
1025                 set_nodes_block(n, block);
1026         }
1027 }
1028
1029 /* move Proj nodes into the same block as its predecessors */
1030 void normalize_proj_nodes(ir_graph *irg)
1031 {
1032         irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1033         set_irg_outs_inconsistent(irg);
1034 }
1035
1036 /* set a description for local value n */
1037 void set_irg_loc_description(ir_graph *irg, int n, void *description)
1038 {
1039         assert(0 <= n && n < irg->n_loc);
1040
1041         if (! irg->loc_descriptions)
1042                 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1043
1044         irg->loc_descriptions[n] = description;
1045 }
1046
1047 /* get the description for local value n */
1048 void *get_irg_loc_description(ir_graph *irg, int n)
1049 {
1050         assert(0 <= n && n < irg->n_loc);
1051         return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1052 }
1053
1054 #ifndef NDEBUG
1055 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
1056 {
1057         assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1058         assert((irg->reserved_resources & resources) == 0);
1059         irg->reserved_resources |= resources;
1060 }
1061
1062 void ir_free_resources(ir_graph *irg, ir_resources_t resources)
1063 {
1064         assert((irg->reserved_resources & resources) == resources);
1065         irg->reserved_resources &= ~resources;
1066 }
1067
1068 ir_resources_t ir_resources_reserved(const ir_graph *irg)
1069 {
1070         return irg->reserved_resources;
1071 }
1072 #endif /* NDEBUG */
1073
1074 /* Returns a estimated node count of the irg. */
1075 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg)
1076 {
1077         return _get_irg_estimated_node_cnt(irg);
1078 }
1079
1080 /* Returns the last irn index for this graph. */
1081 unsigned get_irg_last_idx(const ir_graph *irg)
1082 {
1083         return irg->last_node_idx;
1084 }
1085
1086 /* register additional space in an IR graph */
1087 size_t register_additional_graph_data(size_t size)
1088 {
1089         assert(!forbid_new_data && "Too late to register additional node data");
1090
1091         if (forbid_new_data)
1092                 return 0;
1093
1094         return additional_graph_data_size += size;
1095 }
1096
1097 void (set_irg_state)(ir_graph *irg, ir_graph_state_t state)
1098 {
1099         _set_irg_state(irg, state);
1100 }
1101
1102 void (clear_irg_state)(ir_graph *irg, ir_graph_state_t state)
1103 {
1104         _clear_irg_state(irg, state);
1105 }
1106
1107 int (is_irg_state)(const ir_graph *irg, ir_graph_state_t state)
1108 {
1109         return _is_irg_state(irg, state);
1110 }