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