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