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