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