Get rid of pn_Start_value_param:
[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         add_immBlock_pred(start_block, projX);
266         set_store(initial_mem);
267
268         res->index       = get_irp_new_irg_idx();
269 #ifdef DEBUG_libfirm
270         res->graph_nr    = get_irp_new_node_nr();
271 #endif
272
273         /*
274          * The code generation needs it. leave it in now.
275          * Use of this edge is matter of discussion, unresolved. Also possible:
276          * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
277          */
278         mature_immBlock(res->current_block);
279
280         /*-- Make a block to start with --*/
281         first_block = new_immBlock();
282         set_cur_block(first_block);
283         add_immBlock_pred(first_block, projX);
284
285         res->method_execution_frequency = -1.0;
286         res->estimated_node_count       = 0;
287
288         return res;
289 }
290
291 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
292         ir_graph *res = new_r_ir_graph(ent, n_loc);
293         add_irp_irg(res);          /* remember this graph global. */
294         return res;
295 }
296
297 /* Make a rudimentary IR graph for the constant code.
298    Must look like a correct irg, spare everything else. */
299 ir_graph *new_const_code_irg(void)
300 {
301         ir_graph *res = alloc_graph();
302         ir_node  *bad;
303         ir_node  *body_block;
304         ir_node  *end;
305         ir_node  *end_block;
306         ir_node  *no_mem;
307         ir_node  *projX;
308         ir_node  *start_block;
309         ir_node  *start;
310
311         /* inform statistics here, as blocks will be already build on this graph */
312         hook_new_graph(res, NULL);
313
314         current_ir_graph   = res;
315         res->n_loc         = 1; /* Only the memory. */
316         res->visited       = 0; /* visited flag, for the ir walker */
317         res->block_visited = 0; /* visited flag, for the 'block'-walker */
318         res->obst          = XMALLOC(struct obstack);
319         obstack_init(res->obst);
320         res->extbb_obst = NULL;
321
322         res->last_node_idx = 0;
323
324         res->phase_state      = phase_building;
325         res->irg_pinned_state = op_pin_state_pinned;
326         res->extblk_state     = ir_extblk_info_none;
327         res->fp_model         = fp_model_precise;
328
329         /* value table for global value numbering for optimizing use in iropt.c */
330         res->value_table = new_identities();
331         res->ent         = NULL;
332         res->frame_type  = NULL;
333
334         /* the Anchor node must be created first */
335         res->anchor = new_Anchor(res);
336
337         /* -- The end block -- */
338         end_block = new_immBlock();
339         set_irg_end_block(res, end_block);
340         set_cur_block(end_block);
341         end = new_End();
342         set_irg_end       (res, end);
343         set_irg_end_reg   (res, end);
344         set_irg_end_except(res, end);
345         mature_immBlock(end_block);
346
347         /* -- The start block -- */
348         start_block        = new_immBlock();
349         set_cur_block(start_block);
350         set_irg_start_block(res, start_block);
351         bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
352         set_irg_bad(res, bad);
353         no_mem = new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL);
354         set_irg_no_mem(res, no_mem);
355         start = new_Start();
356         set_irg_start(res, start);
357
358         /* Proj results of start node */
359         set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
360         projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
361         add_immBlock_pred(start_block, projX);
362         mature_immBlock(start_block);
363
364         body_block = new_immBlock();
365         add_immBlock_pred(body_block, projX);
366         mature_immBlock(body_block); /* mature the 'body' block for expressions */
367         set_cur_block(body_block);
368
369         /* Set the visited flag high enough that the blocks will never be visited. */
370         set_irn_visited(body_block, -1);
371         set_Block_block_visited(body_block, -1);
372         set_Block_block_visited(start_block, -1);
373         set_irn_visited(start_block, -1);
374         set_irn_visited(bad, -1);
375         set_irn_visited(no_mem, -1);
376
377         res->phase_state = phase_high;
378
379         return res;
380 }
381
382 /**
383  * Pre-Walker: Copies blocks and nodes from the original method graph
384  * to the copied graph.
385  *
386  * @param n    A node from the original method graph.
387  * @param env  The copied graph.
388  */
389 static void copy_all_nodes(ir_node *n, void *env) {
390         ir_graph *irg = env;
391         ir_op    *op  = get_irn_op(n);
392         ir_node  *nn;
393
394         nn = new_ir_node(get_irn_dbg_info(n),
395                          irg,
396                          NULL,            /* no block yet, will be set later */
397                          op,
398                          get_irn_mode(n),
399                          get_irn_arity(n),
400                          get_irn_in(n) + 1);
401
402
403         /* Copy the attributes.  These might point to additional data.  If this
404            was allocated on the old obstack the pointers now are dangling.  This
405            frees e.g. the memory of the graph_arr allocated in new_immBlock. */
406         copy_node_attr(n, nn);
407         new_backedge_info(nn);
408         set_irn_link(n, nn);
409
410         /* fix the irg for blocks */
411         if (is_Block(nn))
412                 nn->attr.block.irg = irg;
413
414         /* fix access to entities on the stack frame */
415         if (is_Sel(nn)) {
416                 ir_entity *ent = get_Sel_entity(nn);
417                 ir_type   *tp = get_entity_owner(ent);
418
419                 if (is_frame_type(tp)) {
420                         /* replace by the copied entity */
421                         ent = get_entity_link(ent);
422
423                         assert(is_entity(ent));
424                         assert(get_entity_owner(ent) == get_irg_frame_type(irg));
425                         set_Sel_entity(nn, ent);
426                 }
427         }
428 }
429
430 /**
431  * Post-walker: Set the predecessors of the copied nodes.
432  * The copied nodes are set as link of their original nodes. The links of
433  * "irn" predecessors are the predecessors of copied node.
434  */
435 static void set_all_preds(ir_node *irn, void *env) {
436         int      i;
437         ir_node  *nn, *pred;
438         (void) env;
439
440         nn = get_irn_link(irn);
441
442         if (is_Block(irn)) {
443                 ir_node *mbh = get_Block_MacroBlock(irn);
444                 set_Block_MacroBlock(nn, get_irn_link(mbh));
445                 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
446                         pred = get_Block_cfgpred(irn, i);
447                         set_Block_cfgpred(nn, i, get_irn_link(pred));
448                 }
449         } else {
450                 /* First we set the block our copy if it is not a block.*/
451                 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
452                 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
453                         pred = get_irn_n(irn, i);
454                         set_irn_n(nn, i, get_irn_link(pred));
455                 }
456         }
457 }
458
459 #define NN(irn)  get_irn_link(irn)
460
461 /*
462  * Create a new graph that is a copy of a given one.
463  */
464 ir_graph *create_irg_copy(ir_graph *irg) {
465         ir_graph *res;
466
467         res = alloc_graph();
468
469         res->n_loc = 0;
470         res->visited = 0;       /* visited flag, for the ir walker */
471         res->block_visited = 0; /* visited flag, for the 'block'-walker */
472         res->obst       = XMALLOC(struct obstack);
473         obstack_init(res->obst);
474         res->extbb_obst = NULL;
475
476         res->last_node_idx = 0;
477
478         res->phase_state      = irg->phase_state;
479         res->irg_pinned_state = irg->irg_pinned_state;
480         res->extblk_state     = ir_extblk_info_none;
481         res->fp_model         = irg->fp_model;
482
483         res->value_table = new_identities();
484
485         /* clone the frame type here for safety */
486         irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
487         res->frame_type  = clone_frame_type(irg->frame_type);
488
489         res->phase_state = irg->phase_state;
490
491         ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
492
493         /* copy all nodes from the graph irg to the new graph res */
494         irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
495
496         /* copy the Anchor node */
497         res->anchor = NN(irg->anchor);
498
499         /* -- The end block -- */
500         set_irg_end_block (res, NN(get_irg_end_block(irg)));
501         set_irg_end       (res, NN(get_irg_end(irg)));
502         set_irg_end_reg   (res, NN(get_irg_end_reg(irg)));
503         set_irg_end_except(res, NN(get_irg_end_except(irg)));
504
505         /* -- The start block -- */
506         set_irg_start_block(res, NN(get_irg_start_block(irg)));
507         set_irg_bad        (res, NN(get_irg_bad(irg)));
508         set_irg_no_mem     (res, NN(get_irg_no_mem(irg)));
509         set_irg_start      (res, NN(get_irg_start(irg)));
510
511         /* Proj results of start node */
512         set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
513
514         /* Copy the node count estimation. Would be strange if this
515            is different from the original one. */
516         res->estimated_node_count = irg->estimated_node_count;
517
518         ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
519         irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
520
521         return res;
522 }
523 #undef NN
524
525
526 /* Frees the passed irgraph.
527    Deallocates all nodes in this graph and the ir_graph structure.
528    Sets the field irgraph in the corresponding entity to NULL.
529    Does not remove the irgraph from the list in irprog (requires
530    inefficient search, call remove_irp_irg by hand).
531    Does not free types, entities or modes that are used only by this
532    graph, nor the entity standing for this graph. */
533 void free_ir_graph(ir_graph *irg) {
534         assert(is_ir_graph(irg));
535
536         edges_deactivate(irg);
537
538         hook_free_graph(irg);
539         if (irg->outs_state != outs_none)
540                 free_irg_outs(irg);
541         if (irg->frame_type)
542                 free_type(irg->frame_type);
543         if (irg->value_table)
544                 del_identities(irg->value_table);
545         if (irg->ent) {
546                 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
547                 set_entity_peculiarity (irg->ent, peculiarity_description);
548                 set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
549                 set_entity_peculiarity (irg->ent, pec);
550         }
551
552         free_End(get_irg_end(irg));
553         obstack_free(irg->obst,NULL);
554         free(irg->obst);
555         if (irg->loc_descriptions)
556                 free(irg->loc_descriptions);
557         irg->kind = k_BAD;
558         free_graph(irg);
559 }
560
561 /* access routines for all ir_graph attributes:
562    templates:
563    {attr type} get_irg_{attribute name} (ir_graph *irg);
564    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
565
566 int
567 (is_ir_graph)(const void *thing) {
568         return _is_ir_graph(thing);
569 }
570
571 #ifdef DEBUG_libfirm
572 /* Outputs a unique number for this node */
573 long get_irg_graph_nr(const ir_graph *irg) {
574         return irg->graph_nr;
575 }
576 #else
577 long get_irg_graph_nr(const ir_graph *irg) {
578         return PTR_TO_INT(irg);
579 }
580 #endif
581
582 int get_irg_idx(const ir_graph *irg) {
583         return irg->index;
584 }
585
586 ir_node *(get_idx_irn)(ir_graph *irg, unsigned idx) {
587         return _get_idx_irn(irg, idx);
588 }
589
590 ir_node *
591 (get_irg_start_block)(const ir_graph *irg) {
592         return _get_irg_start_block(irg);
593 }
594
595 void
596 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
597         _set_irg_start_block(irg, node);
598 }
599
600 ir_node *
601 (get_irg_start)(const ir_graph *irg) {
602         return _get_irg_start(irg);
603 }
604
605 void
606 (set_irg_start)(ir_graph *irg, ir_node *node) {
607         _set_irg_start(irg, node);
608 }
609
610 ir_node *
611 (get_irg_end_block)(const ir_graph *irg) {
612         return _get_irg_end_block(irg);
613 }
614
615 void
616 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
617   _set_irg_end_block(irg, node);
618 }
619
620 ir_node *
621 (get_irg_end)(const ir_graph *irg) {
622         return _get_irg_end(irg);
623 }
624
625 void
626 (set_irg_end)(ir_graph *irg, ir_node *node) {
627         _set_irg_end(irg, node);
628 }
629
630 ir_node *
631 (get_irg_end_reg)(const ir_graph *irg) {
632         return _get_irg_end_reg(irg);
633 }
634
635 void
636 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
637         _set_irg_end_reg(irg, node);
638 }
639
640 ir_node *
641 (get_irg_end_except)(const ir_graph *irg) {
642         return _get_irg_end_except(irg);
643 }
644
645 void
646 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
647         assert(get_irn_op(node) == op_EndExcept || is_End(node));
648         _set_irg_end_except(irg, node);
649 }
650
651 ir_node *
652 (get_irg_initial_exec)(const ir_graph *irg) {
653         return _get_irg_initial_exec(irg);
654 }
655
656 void
657 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
658         _set_irg_initial_exec(irg, node);
659 }
660
661 ir_node *
662 (get_irg_frame)(const ir_graph *irg) {
663         return _get_irg_frame(irg);
664 }
665
666 void
667 (set_irg_frame)(ir_graph *irg, ir_node *node) {
668         _set_irg_frame(irg, node);
669 }
670
671 ir_node *
672 (get_irg_tls)(const ir_graph *irg) {
673         return _get_irg_tls(irg);
674 }
675
676 void
677 (set_irg_tls)(ir_graph *irg, ir_node *node) {
678         _set_irg_tls(irg, node);
679 }
680
681 ir_node *
682 (get_irg_initial_mem)(const ir_graph *irg) {
683         return _get_irg_initial_mem(irg);
684 }
685
686 void
687 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
688         _set_irg_initial_mem(irg, node);
689 }
690
691 ir_node *
692 (get_irg_args)(const ir_graph *irg) {
693         return _get_irg_args(irg);
694 }
695
696 void
697 (set_irg_args)(ir_graph *irg, ir_node *node) {
698         _set_irg_args(irg, node);
699 }
700
701 ir_node *
702 (get_irg_bad)(const ir_graph *irg) {
703         return _get_irg_bad(irg);
704 }
705
706 void
707 (set_irg_bad)(ir_graph *irg, ir_node *node) {
708         _set_irg_bad(irg, node);
709 }
710
711 ir_node *
712 (get_irg_no_mem)(const ir_graph *irg) {
713         return _get_irg_no_mem(irg);
714 }
715
716 void
717 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
718         _set_irg_no_mem(irg, node);
719 }
720
721 ir_node *
722 (get_irg_current_block)(const ir_graph *irg) {
723         return _get_irg_current_block(irg);
724 }
725
726 void
727 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
728         _set_irg_current_block(irg, node);
729 }
730
731 ir_entity *
732 (get_irg_entity)(const ir_graph *irg) {
733         return _get_irg_entity(irg);
734 }
735
736 void
737 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
738         _set_irg_entity(irg, ent);
739 }
740
741 ir_type *
742 (get_irg_frame_type)(ir_graph *irg) {
743         return _get_irg_frame_type(irg);
744 }
745
746 void
747 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
748         _set_irg_frame_type(irg, ftp);
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 }