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