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