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