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