2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Entry point to the representation of procedure code.
23 * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
37 #include "irgraph_t.h"
39 #include "irgraph_t.h"
49 #include "irbackedge_t.h"
50 #include "iredges_t.h"
54 #define INITIAL_IDX_IRN_MAP_SIZE 1024
57 * Indicates, whether additional data can be registered to graphs.
58 * If set to 1, this is not possible anymore.
60 static int forbid_new_data = 0;
63 * The amount of additional space for custom data to be allocated upon
64 * creating a new graph.
66 static size_t additional_graph_data_size = 0;
68 ir_graph *current_ir_graph;
69 ir_graph *get_current_ir_graph(void) {
70 return current_ir_graph;
73 void set_current_ir_graph(ir_graph *graph) {
74 current_ir_graph = graph;
77 #ifdef INTERPROCEDURAL_VIEW
78 int firm_interprocedural_view = 0;
80 int (get_interprocedural_view)(void) {
81 return _get_interprocedural_view();
84 void (set_interprocedural_view)(int state) {
85 firm_interprocedural_view = state;
87 /* set function vectors for faster access */
89 _get_irn_arity = _get_irn_inter_arity;
90 _get_irn_n = _get_irn_inter_n;
93 _get_irn_arity = _get_irn_intra_arity;
94 _get_irn_n = _get_irn_intra_n;
99 /** contains the suffix for frame type names */
100 static ident *frame_type_suffix = NULL;
102 /* initialize the IR graph module */
103 void firm_init_irgraph(void) {
104 frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
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.
115 static ir_graph *alloc_graph(void) {
117 size_t size = sizeof(ir_graph) + additional_graph_data_size;
118 char *ptr = xmalloc(size);
119 memset(ptr, 0, size);
121 res = (ir_graph *)(ptr + additional_graph_data_size);
122 res->kind = k_ir_graph;
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]));
132 * Frees an allocated IR graph
134 static void free_graph(ir_graph *irg) {
135 char *ptr = (char *)irg;
136 free(ptr - additional_graph_data_size);
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);
147 * Set the number of locals for a given graph.
149 * @param irg the graph
150 * @param n_loc number of locals
152 void irg_set_nloc(ir_graph *res, int n_loc) {
153 assert(res->phase_state == phase_building);
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! */
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
167 if (res->loc_descriptions) {
168 xfree(res->loc_descriptions);
169 res->loc_descriptions = NULL;
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
182 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
184 ir_node *first_block;
185 ir_node *end, *start, *start_block, *initial_mem, *projX;
189 /* inform statistics here, as blocks will be already build on this graph */
190 hook_new_graph(res, ent);
192 current_ir_graph = res;
194 /*-- initialized for each graph. --*/
195 res->kind = k_ir_graph;
196 res->obst = XMALLOC(struct obstack);
197 obstack_init(res->obst);
199 res->phase_state = phase_building;
200 irg_set_nloc(res, n_loc);
202 /* descriptions will be allocated on demand */
203 res->loc_descriptions = NULL;
205 res->visited = 0; /* visited flag, for the ir walker */
206 res->block_visited = 0; /* visited flag, for the 'block'-walker */
208 #if USE_EXPLICIT_PHI_IN_STACK
209 res->Phi_in_stack = new_Phi_in_stack(); /* A stack needed for automatic Phi
212 res->extbb_obst = NULL;
214 res->last_node_idx = 0;
216 res->value_table = new_identities (); /* value table for global value
217 numbering for optimizing use in iropt.c */
220 res->inline_property = irg_inline_any;
221 res->additional_properties = mtp_property_inherited; /* inherited from type */
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;
238 /*-- Type information for the procedure of the graph --*/
240 set_entity_irg(ent, res);
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));
245 /* the Anchor node must be created first */
246 res->anchor = new_Anchor(res);
248 /*-- Nodes needed in every graph --*/
249 set_irg_end_block (res, new_immBlock());
251 set_irg_end (res, end);
252 set_irg_end_reg (res, end);
253 set_irg_end_except(res, end);
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));
260 set_irg_start (res, start);
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);
272 add_immBlock_pred(start_block, projX);
273 set_store(initial_mem);
275 res->index = get_irp_new_irg_idx();
277 res->graph_nr = get_irp_new_node_nr();
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.
285 mature_immBlock(res->current_block);
287 /*-- Make a block to start with --*/
288 first_block = new_immBlock();
289 add_immBlock_pred(first_block, projX);
291 res->method_execution_frequency = -1.0;
292 res->estimated_node_count = 0;
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. */
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) {
307 ir_node *end, *start_block, *start, *projX;
311 /* inform statistics here, as blocks will be already build on this graph */
312 hook_new_graph(res, NULL);
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;
321 res->obst = XMALLOC(struct obstack);
322 obstack_init (res->obst);
323 res->extbb_obst = NULL;
325 res->last_node_idx = 0;
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;
332 res->value_table = new_identities(); /* value table for global value
333 numbering for optimizing use in
336 res->frame_type = NULL;
338 /* the Anchor node must be created first */
339 res->anchor = new_Anchor(res);
341 /* -- The end block -- */
342 set_irg_end_block (res, new_immBlock());
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 */
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));
355 set_irg_start (res, start);
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 */
363 add_immBlock_pred(new_immBlock(), projX);
364 mature_immBlock (get_cur_block()); /* mature the 'body' block for expressions */
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);
374 res->phase_state = phase_high;
380 * Pre-Walker: Copies blocks and nodes from the original method graph
381 * to the copied graph.
383 * @param n A node from the original method graph.
384 * @param env The copied graph.
386 static void copy_all_nodes(ir_node *n, void *env) {
388 ir_op *op = get_irn_op(n);
391 nn = new_ir_node(get_irn_dbg_info(n),
393 NULL, /* no block yet, will be set later */
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);
407 /* fix the irg for blocks */
409 nn->attr.block.irg = irg;
411 /* fix access to entities on the stack frame */
413 ir_entity *ent = get_Sel_entity(nn);
414 ir_type *tp = get_entity_owner(ent);
416 if (is_frame_type(tp)) {
417 /* replace by the copied entity */
418 ent = get_entity_link(ent);
420 assert(is_entity(ent));
421 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
422 set_Sel_entity(nn, ent);
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.
432 static void set_all_preds(ir_node *irn, void *env) {
437 nn = get_irn_link(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));
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));
456 #define NN(irn) get_irn_link(irn)
459 * Create a new graph that is a copy of a given one.
461 ir_graph *create_irg_copy(ir_graph *irg) {
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;
472 res->obst = XMALLOC(struct obstack);
473 obstack_init(res->obst);
474 res->extbb_obst = NULL;
476 res->last_node_idx = 0;
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;
483 res->value_table = new_identities();
485 /* clone the frame type here for safety */
486 res->frame_type = clone_frame_type(irg->frame_type);
488 res->phase_state = irg->phase_state;
490 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
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);
495 /* copy the Anchor node */
496 res->anchor = NN(irg->anchor);
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)));
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)));
510 /* Proj results of start node */
511 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
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;
517 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
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));
534 edges_deactivate(irg);
536 hook_free_graph(irg);
537 if (irg->outs_state != outs_none)
540 free_type(irg->frame_type);
541 if (irg->value_table)
542 del_identities(irg->value_table);
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);
550 free_End(get_irg_end(irg));
551 obstack_free(irg->obst,NULL);
553 #if USE_EXPLICIT_PHI_IN_STACK
554 free_Phi_in_stack(irg->Phi_in_stack);
556 if (irg->loc_descriptions)
557 free(irg->loc_descriptions);
562 /* access routines for all ir_graph attributes:
564 {attr type} get_irg_{attribute name} (ir_graph *irg);
565 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
568 (is_ir_graph)(const void *thing) {
569 return _is_ir_graph(thing);
573 /* Outputs a unique number for this node */
574 long get_irg_graph_nr(const ir_graph *irg) {
575 return irg->graph_nr;
578 long get_irg_graph_nr(const ir_graph *irg) {
579 return PTR_TO_INT(irg);
583 int get_irg_idx(const ir_graph *irg) {
588 (get_irg_start_block)(const ir_graph *irg) {
589 return _get_irg_start_block(irg);
593 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
594 _set_irg_start_block(irg, node);
598 (get_irg_start)(const ir_graph *irg) {
599 return _get_irg_start(irg);
603 (set_irg_start)(ir_graph *irg, ir_node *node) {
604 _set_irg_start(irg, node);
608 (get_irg_end_block)(const ir_graph *irg) {
609 return _get_irg_end_block(irg);
613 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
614 _set_irg_end_block(irg, node);
618 (get_irg_end)(const ir_graph *irg) {
619 return _get_irg_end(irg);
623 (set_irg_end)(ir_graph *irg, ir_node *node) {
624 _set_irg_end(irg, node);
628 (get_irg_end_reg)(const ir_graph *irg) {
629 return _get_irg_end_reg(irg);
633 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
634 _set_irg_end_reg(irg, node);
638 (get_irg_end_except)(const ir_graph *irg) {
639 return _get_irg_end_except(irg);
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);
649 (get_irg_initial_exec)(const ir_graph *irg) {
650 return _get_irg_initial_exec(irg);
654 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
655 _set_irg_initial_exec(irg, node);
659 (get_irg_frame)(const ir_graph *irg) {
660 return _get_irg_frame(irg);
664 (set_irg_frame)(ir_graph *irg, ir_node *node) {
665 _set_irg_frame(irg, node);
669 (get_irg_tls)(const ir_graph *irg) {
670 return _get_irg_tls(irg);
674 (set_irg_tls)(ir_graph *irg, ir_node *node) {
675 _set_irg_tls(irg, node);
679 (get_irg_initial_mem)(const ir_graph *irg) {
680 return _get_irg_initial_mem(irg);
684 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
685 _set_irg_initial_mem(irg, node);
689 (get_irg_args)(const ir_graph *irg) {
690 return _get_irg_args(irg);
694 (set_irg_args)(ir_graph *irg, ir_node *node) {
695 _set_irg_args(irg, node);
699 (get_irg_value_param_base)(const ir_graph *irg) {
700 return _get_irg_value_param_base(irg);
704 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
705 _set_irg_value_param_base(irg, node);
709 (get_irg_bad)(const ir_graph *irg) {
710 return _get_irg_bad(irg);
714 (set_irg_bad)(ir_graph *irg, ir_node *node) {
715 _set_irg_bad(irg, node);
719 (get_irg_no_mem)(const ir_graph *irg) {
720 return _get_irg_no_mem(irg);
724 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
725 _set_irg_no_mem(irg, node);
729 (get_irg_current_block)(const ir_graph *irg) {
730 return _get_irg_current_block(irg);
734 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
735 _set_irg_current_block(irg, node);
739 (get_irg_entity)(const ir_graph *irg) {
740 return _get_irg_entity(irg);
744 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
745 _set_irg_entity(irg, ent);
749 (get_irg_frame_type)(ir_graph *irg) {
750 return _get_irg_frame_type(irg);
754 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
755 _set_irg_frame_type(irg, ftp);
759 get_irg_n_locs(ir_graph *irg) {
760 if (get_opt_precise_exc_context())
761 return irg->n_loc - 1 - 1;
763 return irg->n_loc - 1;
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;
771 irg->n_loc = n_loc + 1;
776 /* Returns the obstack associated with the graph. */
778 (get_irg_obstack)(const ir_graph *irg) {
779 return _get_irg_obstack(irg);
783 * Returns true if the node n is allocated on the storage of graph irg.
785 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
787 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
788 struct _obstack_chunk *p;
791 * checks weather the ir_node pointer is on the obstack.
792 * A more sophisticated check would test the "whole" ir_node
794 for (p = irg->obst->chunk; p; p = p->prev) {
795 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
803 (get_irg_phase_state)(const ir_graph *irg) {
804 return _get_irg_phase_state(irg);
808 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
809 _set_irg_phase_state(irg, state);
813 (get_irg_pinned)(const ir_graph *irg) {
814 return _get_irg_pinned(irg);
818 (get_irg_outs_state)(const ir_graph *irg) {
819 return _get_irg_outs_state(irg);
823 (set_irg_outs_inconsistent)(ir_graph *irg) {
824 _set_irg_outs_inconsistent(irg);
828 (get_irg_extblk_state)(const ir_graph *irg) {
829 return _get_irg_extblk_state(irg);
833 (set_irg_extblk_inconsistent)(ir_graph *irg) {
834 _set_irg_extblk_inconsistent(irg);
838 (get_irg_dom_state)(const ir_graph *irg) {
839 return _get_irg_dom_state(irg);
843 (get_irg_postdom_state)(const ir_graph *irg) {
844 return _get_irg_postdom_state(irg);
848 (set_irg_doms_inconsistent)(ir_graph *irg) {
849 _set_irg_doms_inconsistent(irg);
853 (get_irg_loopinfo_state)(const ir_graph *irg) {
854 return _get_irg_loopinfo_state(irg);
858 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
859 _set_irg_loopinfo_state(irg, s);
863 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
864 _set_irg_loopinfo_inconsistent(irg);
867 void set_irp_loopinfo_inconsistent(void) {
869 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
870 set_irg_loopinfo_inconsistent(get_irp_irg(i));
877 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
878 _set_irg_pinned(irg, p);
881 irg_callee_info_state
882 (get_irg_callee_info_state)(const ir_graph *irg) {
883 return _get_irg_callee_info_state(irg);
887 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
888 _set_irg_callee_info_state(irg, s);
892 (get_irg_inline_property)(const ir_graph *irg) {
893 return _get_irg_inline_property(irg);
897 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
898 _set_irg_inline_property(irg, s);
902 (get_irg_additional_properties)(const ir_graph *irg) {
903 return _get_irg_additional_properties(irg);
907 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
908 _set_irg_additional_properties(irg, property_mask);
912 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
913 _set_irg_additional_property(irg, flag);
917 (set_irg_link)(ir_graph *irg, void *thing) {
918 _set_irg_link(irg, thing);
922 (get_irg_link)(const ir_graph *irg) {
923 return _get_irg_link(irg);
927 (get_irg_visited)(const ir_graph *irg) {
928 return _get_irg_visited(irg);
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 */
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;
943 #endif /* INTERPROCEDURAL_VIEW */
947 inc_irg_visited(ir_graph *irg) {
948 #ifdef INTERPROCEDURAL_VIEW
949 if (++irg->visited > max_irg_visited) {
950 max_irg_visited = irg->visited;
954 #endif /* INTERPROCEDURAL_VIEW */
957 #ifdef INTERPROCEDURAL_VIEW
959 get_max_irg_visited(void) {
962 for(i = 0; i < get_irp_n_irgs(); i++)
963 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
965 return max_irg_visited;
968 void set_max_irg_visited(int val) {
969 max_irg_visited = val;
973 inc_max_irg_visited(void) {
976 for(i = 0; i < get_irp_n_irgs(); i++)
977 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
979 return ++max_irg_visited;
981 #endif /* INTERPROCEDURAL_VIEW */
984 (get_irg_block_visited)(const ir_graph *irg) {
985 return _get_irg_block_visited(irg);
989 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
990 _set_irg_block_visited(irg, visited);
994 (inc_irg_block_visited)(ir_graph *irg) {
995 _inc_irg_block_visited(irg);
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);
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;
1009 * walker Start->End: places Proj nodes into the same block
1010 * as it's predecessors
1013 * @param env ignored
1015 static void normalize_proj_walker(ir_node *n, void *env) {
1018 ir_node *pred = get_Proj_pred(n);
1019 ir_node *block = get_nodes_block(pred);
1021 set_nodes_block(n, block);
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);
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);
1035 if (! irg->loc_descriptions)
1036 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1038 irg->loc_descriptions[n] = description;
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;
1048 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
1050 assert((irg->reserved_resources & resources) == 0);
1051 irg->reserved_resources |= resources;
1054 void ir_free_resources(ir_graph *irg, ir_resources_t resources)
1056 assert((irg->reserved_resources & resources) == resources);
1057 irg->reserved_resources &= ~resources;
1060 ir_resources_t ir_resources_reserved(const ir_graph *irg)
1062 return irg->reserved_resources;
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);
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;
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");
1080 if (forbid_new_data)
1083 return additional_graph_data_size += size;