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