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