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
35 #include "irgraph_t.h"
37 #include "irgraph_t.h"
47 #include "irbackedge_t.h"
48 #include "iredges_t.h"
52 #define INITIAL_IDX_IRN_MAP_SIZE 1024
55 * Indicates, whether additional data can be registered to graphs.
56 * If set to 1, this is not possible anymore.
58 static int forbid_new_data = 0;
61 * The amount of additional space for custom data to be allocated upon
62 * creating a new graph.
64 static size_t additional_graph_data_size = 0;
66 ir_graph *current_ir_graph;
67 ir_graph *get_current_ir_graph(void) {
68 return current_ir_graph;
71 void set_current_ir_graph(ir_graph *graph) {
72 current_ir_graph = graph;
75 #ifdef INTERPROCEDURAL_VIEW
76 int firm_interprocedural_view = 0;
78 int (get_interprocedural_view)(void) {
79 return _get_interprocedural_view();
82 void (set_interprocedural_view)(int state) {
83 firm_interprocedural_view = state;
85 /* set function vectors for faster access */
87 _get_irn_arity = _get_irn_inter_arity;
88 _get_irn_n = _get_irn_inter_n;
91 _get_irn_arity = _get_irn_intra_arity;
92 _get_irn_n = _get_irn_intra_n;
97 /** contains the suffix for frame type names */
98 static ident *frame_type_suffix = NULL;
100 /* initialize the IR graph module */
101 void firm_init_irgraph(void) {
102 frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
107 * Allocate a new IR graph.
108 * This function respects the registered graph data. The only reason for
109 * this function is, that there are two locations, where graphs are
110 * allocated (new_r_ir_graph, new_const_code_irg).
111 * @return Memory for a new graph.
113 static ir_graph *alloc_graph(void) {
115 size_t size = sizeof(ir_graph) + additional_graph_data_size;
116 char *ptr = xmalloc(size);
117 memset(ptr, 0, size);
119 res = (ir_graph *)(ptr + additional_graph_data_size);
120 res->kind = k_ir_graph;
122 /* initialize the idx->node map. */
123 res->idx_irn_map = NEW_ARR_F(ir_node *, INITIAL_IDX_IRN_MAP_SIZE);
124 memset(res->idx_irn_map, 0, INITIAL_IDX_IRN_MAP_SIZE * sizeof(res->idx_irn_map[0]));
130 * Frees an allocated IR graph
132 static void free_graph(ir_graph *irg) {
133 char *ptr = (char *)irg;
136 for (i = 0; i < EDGE_KIND_LAST; ++i)
137 edges_deactivate_kind(irg, i);
138 DEL_ARR_F(irg->idx_irn_map);
139 free(ptr - additional_graph_data_size);
143 * Set the number of locals for a given graph.
145 * @param irg the graph
146 * @param n_loc number of locals
148 void irg_set_nloc(ir_graph *res, int n_loc) {
149 assert(res->phase_state == phase_building);
151 if (get_opt_precise_exc_context()) {
152 res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
153 dereferenced in this graph plus one for
154 the store plus one for links to fragile
155 operations. n_loc is not the number of
156 parameters to the procedure! */
158 res->n_loc = n_loc + 1; /* number of local variables that are never
159 dereferenced in this graph plus one for
160 the store. This is not the number of parameters
163 if (res->loc_descriptions) {
164 xfree(res->loc_descriptions);
165 res->loc_descriptions = NULL;
169 /* Allocates a list of nodes:
170 - The start block containing a start node and Proj nodes for it's four
171 results (X, M, P, Tuple).
172 - The end block containing an end node. This block is not matured after
173 new_ir_graph as predecessors need to be added to it.
174 - The current block, which is empty and also not matured.
175 Further it allocates several datastructures needed for graph construction
178 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
180 ir_node *first_block;
181 ir_node *end, *start, *start_block, *initial_mem, *projX;
185 /* inform statistics here, as blocks will be already build on this graph */
186 hook_new_graph(res, ent);
188 current_ir_graph = res;
190 /*-- initialized for each graph. --*/
191 res->kind = k_ir_graph;
192 res->obst = XMALLOC(struct obstack);
193 obstack_init(res->obst);
195 res->phase_state = phase_building;
196 irg_set_nloc(res, n_loc);
198 /* descriptions will be allocated on demand */
199 res->loc_descriptions = NULL;
201 res->visited = 0; /* visited flag, for the ir walker */
202 res->block_visited = 0; /* visited flag, for the 'block'-walker */
204 res->extbb_obst = NULL;
206 res->last_node_idx = 0;
208 res->value_table = new_identities (); /* value table for global value
209 numbering for optimizing use in iropt.c */
212 res->inline_property = irg_inline_any;
213 res->additional_properties = mtp_property_inherited; /* inherited from type */
215 res->irg_pinned_state = op_pin_state_pinned;
216 res->outs_state = outs_none;
217 res->dom_state = dom_none;
218 res->pdom_state = dom_none;
219 res->typeinfo_state = ir_typeinfo_none;
220 set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
221 res->callee_info_state = irg_callee_info_none;
222 res->loopinfo_state = loopinfo_none;
223 res->class_cast_state = ir_class_casts_transitive;
224 res->extblk_state = ir_extblk_info_none;
225 res->execfreq_state = exec_freq_none;
226 res->fp_model = fp_model_precise;
227 res->entity_usage_state = ir_entity_usage_not_computed;
228 res->mem_disambig_opt = aa_opt_inherited;
230 /*-- Type information for the procedure of the graph --*/
232 set_entity_irg(ent, res);
234 /*-- a class type so that it can contain "inner" methods as in Pascal. --*/
235 res->frame_type = new_type_frame(id_mangle(get_entity_ident(ent), frame_type_suffix));
237 /* the Anchor node must be created first */
238 res->anchor = new_Anchor(res);
240 /*-- Nodes needed in every graph --*/
241 set_irg_end_block (res, new_immBlock());
243 set_irg_end (res, end);
244 set_irg_end_reg (res, end);
245 set_irg_end_except(res, end);
247 start_block = new_immBlock();
248 set_irg_start_block(res, start_block);
249 set_irg_bad (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
250 set_irg_no_mem (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
252 set_irg_start (res, start);
254 /* Proj results of start node */
255 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
256 set_irg_initial_exec (res, projX);
257 set_irg_frame (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
258 set_irg_tls (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
259 set_irg_args (res, new_Proj(start, mode_T, pn_Start_T_args));
260 set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
261 initial_mem = new_Proj(start, mode_M, pn_Start_M);
262 set_irg_initial_mem(res, initial_mem);
264 add_immBlock_pred(start_block, projX);
265 set_store(initial_mem);
267 res->index = get_irp_new_irg_idx();
269 res->graph_nr = get_irp_new_node_nr();
273 * The code generation needs it. leave it in now.
274 * Use of this edge is matter of discussion, unresolved. Also possible:
275 * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
277 mature_immBlock(res->current_block);
279 /*-- Make a block to start with --*/
280 first_block = new_immBlock();
281 add_immBlock_pred(first_block, projX);
283 res->method_execution_frequency = -1.0;
284 res->estimated_node_count = 0;
289 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
290 ir_graph *res = new_r_ir_graph(ent, n_loc);
291 add_irp_irg(res); /* remember this graph global. */
295 /* Make a rudimentary IR graph for the constant code.
296 Must look like a correct irg, spare everything else. */
297 ir_graph *new_const_code_irg(void) {
299 ir_node *end, *start_block, *start, *projX;
303 /* inform statistics here, as blocks will be already build on this graph */
304 hook_new_graph(res, NULL);
306 current_ir_graph = res;
307 res->n_loc = 1; /* Only the memory. */
308 res->visited = 0; /* visited flag, for the ir walker */
309 res->block_visited = 0; /* visited flag, for the 'block'-walker */
310 res->obst = XMALLOC(struct obstack);
311 obstack_init (res->obst);
312 res->extbb_obst = NULL;
314 res->last_node_idx = 0;
316 res->phase_state = phase_building;
317 res->irg_pinned_state = op_pin_state_pinned;
318 res->extblk_state = ir_extblk_info_none;
319 res->fp_model = fp_model_precise;
321 res->value_table = new_identities(); /* value table for global value
322 numbering for optimizing use in
325 res->frame_type = NULL;
327 /* the Anchor node must be created first */
328 res->anchor = new_Anchor(res);
330 /* -- The end block -- */
331 set_irg_end_block (res, new_immBlock());
333 set_irg_end (res, end);
334 set_irg_end_reg (res, end);
335 set_irg_end_except(res, end);
336 mature_immBlock(get_cur_block()); /* mature the end block */
338 /* -- The start block -- */
339 start_block = new_immBlock();
340 set_irg_start_block(res, start_block);
341 set_irg_bad (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
342 set_irg_no_mem (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
344 set_irg_start (res, start);
346 /* Proj results of start node */
347 set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
348 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
349 add_immBlock_pred(start_block, projX);
350 mature_immBlock (start_block); /* mature the start block */
352 add_immBlock_pred(new_immBlock(), projX);
353 mature_immBlock (get_cur_block()); /* mature the 'body' block for expressions */
355 /* Set the visited flag high enough that the blocks will never be visited. */
356 set_irn_visited(get_cur_block(), -1);
357 set_Block_block_visited(get_cur_block(), -1);
358 set_Block_block_visited(start_block, -1);
359 set_irn_visited(start_block, -1);
360 set_irn_visited(get_irg_bad(res), -1);
361 set_irn_visited(get_irg_no_mem(res), -1);
363 res->phase_state = phase_high;
369 * Pre-Walker: Copies blocks and nodes from the original method graph
370 * to the copied graph.
372 * @param n A node from the original method graph.
373 * @param env The copied graph.
375 static void copy_all_nodes(ir_node *n, void *env) {
377 ir_op *op = get_irn_op(n);
380 nn = new_ir_node(get_irn_dbg_info(n),
382 NULL, /* no block yet, will be set later */
389 /* Copy the attributes. These might point to additional data. If this
390 was allocated on the old obstack the pointers now are dangling. This
391 frees e.g. the memory of the graph_arr allocated in new_immBlock. */
392 copy_node_attr(n, nn);
393 new_backedge_info(nn);
396 /* fix the irg for blocks */
398 nn->attr.block.irg = irg;
400 /* fix access to entities on the stack frame */
402 ir_entity *ent = get_Sel_entity(nn);
403 ir_type *tp = get_entity_owner(ent);
405 if (is_frame_type(tp)) {
406 /* replace by the copied entity */
407 ent = get_entity_link(ent);
409 assert(is_entity(ent));
410 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
411 set_Sel_entity(nn, ent);
417 * Post-walker: Set the predecessors of the copied nodes.
418 * The copied nodes are set as link of their original nodes. The links of
419 * "irn" predecessors are the predecessors of copied node.
421 static void set_all_preds(ir_node *irn, void *env) {
426 nn = get_irn_link(irn);
429 ir_node *mbh = get_Block_MacroBlock(irn);
430 set_Block_MacroBlock(nn, get_irn_link(mbh));
431 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
432 pred = get_Block_cfgpred(irn, i);
433 set_Block_cfgpred(nn, i, get_irn_link(pred));
436 /* First we set the block our copy if it is not a block.*/
437 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
438 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
439 pred = get_irn_n(irn, i);
440 set_irn_n(nn, i, get_irn_link(pred));
445 #define NN(irn) get_irn_link(irn)
448 * Create a new graph that is a copy of a given one.
450 ir_graph *create_irg_copy(ir_graph *irg) {
456 res->visited = 0; /* visited flag, for the ir walker */
457 res->block_visited = 0; /* visited flag, for the 'block'-walker */
458 res->obst = XMALLOC(struct obstack);
459 obstack_init(res->obst);
460 res->extbb_obst = NULL;
462 res->last_node_idx = 0;
464 res->phase_state = irg->phase_state;
465 res->irg_pinned_state = irg->irg_pinned_state;
466 res->extblk_state = ir_extblk_info_none;
467 res->fp_model = irg->fp_model;
469 res->value_table = new_identities();
471 /* clone the frame type here for safety */
472 irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
473 res->frame_type = clone_frame_type(irg->frame_type);
475 res->phase_state = irg->phase_state;
477 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
479 /* copy all nodes from the graph irg to the new graph res */
480 irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
482 /* copy the Anchor node */
483 res->anchor = NN(irg->anchor);
485 /* -- The end block -- */
486 set_irg_end_block (res, NN(get_irg_end_block(irg)));
487 set_irg_end (res, NN(get_irg_end(irg)));
488 set_irg_end_reg (res, NN(get_irg_end_reg(irg)));
489 set_irg_end_except(res, NN(get_irg_end_except(irg)));
491 /* -- The start block -- */
492 set_irg_start_block(res, NN(get_irg_start_block(irg)));
493 set_irg_bad (res, NN(get_irg_bad(irg)));
494 set_irg_no_mem (res, NN(get_irg_no_mem(irg)));
495 set_irg_start (res, NN(get_irg_start(irg)));
497 /* Proj results of start node */
498 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
500 /* Copy the node count estimation. Would be strange if this
501 is different from the original one. */
502 res->estimated_node_count = irg->estimated_node_count;
504 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
505 irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
512 /* Frees the passed irgraph.
513 Deallocates all nodes in this graph and the ir_graph structure.
514 Sets the field irgraph in the corresponding entity to NULL.
515 Does not remove the irgraph from the list in irprog (requires
516 inefficient search, call remove_irp_irg by hand).
517 Does not free types, entities or modes that are used only by this
518 graph, nor the entity standing for this graph. */
519 void free_ir_graph(ir_graph *irg) {
520 assert(is_ir_graph(irg));
522 edges_deactivate(irg);
524 hook_free_graph(irg);
525 if (irg->outs_state != outs_none)
528 free_type(irg->frame_type);
529 if (irg->value_table)
530 del_identities(irg->value_table);
532 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
533 set_entity_peculiarity (irg->ent, peculiarity_description);
534 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
535 set_entity_peculiarity (irg->ent, pec);
538 free_End(get_irg_end(irg));
539 obstack_free(irg->obst,NULL);
541 if (irg->loc_descriptions)
542 free(irg->loc_descriptions);
547 /* access routines for all ir_graph attributes:
549 {attr type} get_irg_{attribute name} (ir_graph *irg);
550 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
553 (is_ir_graph)(const void *thing) {
554 return _is_ir_graph(thing);
558 /* Outputs a unique number for this node */
559 long get_irg_graph_nr(const ir_graph *irg) {
560 return irg->graph_nr;
563 long get_irg_graph_nr(const ir_graph *irg) {
564 return PTR_TO_INT(irg);
568 int get_irg_idx(const ir_graph *irg) {
573 (get_irg_start_block)(const ir_graph *irg) {
574 return _get_irg_start_block(irg);
578 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
579 _set_irg_start_block(irg, node);
583 (get_irg_start)(const ir_graph *irg) {
584 return _get_irg_start(irg);
588 (set_irg_start)(ir_graph *irg, ir_node *node) {
589 _set_irg_start(irg, node);
593 (get_irg_end_block)(const ir_graph *irg) {
594 return _get_irg_end_block(irg);
598 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
599 _set_irg_end_block(irg, node);
603 (get_irg_end)(const ir_graph *irg) {
604 return _get_irg_end(irg);
608 (set_irg_end)(ir_graph *irg, ir_node *node) {
609 _set_irg_end(irg, node);
613 (get_irg_end_reg)(const ir_graph *irg) {
614 return _get_irg_end_reg(irg);
618 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
619 _set_irg_end_reg(irg, node);
623 (get_irg_end_except)(const ir_graph *irg) {
624 return _get_irg_end_except(irg);
628 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
629 assert(get_irn_op(node) == op_EndExcept || is_End(node));
630 _set_irg_end_except(irg, node);
634 (get_irg_initial_exec)(const ir_graph *irg) {
635 return _get_irg_initial_exec(irg);
639 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
640 _set_irg_initial_exec(irg, node);
644 (get_irg_frame)(const ir_graph *irg) {
645 return _get_irg_frame(irg);
649 (set_irg_frame)(ir_graph *irg, ir_node *node) {
650 _set_irg_frame(irg, node);
654 (get_irg_tls)(const ir_graph *irg) {
655 return _get_irg_tls(irg);
659 (set_irg_tls)(ir_graph *irg, ir_node *node) {
660 _set_irg_tls(irg, node);
664 (get_irg_initial_mem)(const ir_graph *irg) {
665 return _get_irg_initial_mem(irg);
669 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
670 _set_irg_initial_mem(irg, node);
674 (get_irg_args)(const ir_graph *irg) {
675 return _get_irg_args(irg);
679 (set_irg_args)(ir_graph *irg, ir_node *node) {
680 _set_irg_args(irg, node);
684 (get_irg_value_param_base)(const ir_graph *irg) {
685 return _get_irg_value_param_base(irg);
689 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
690 _set_irg_value_param_base(irg, node);
694 (get_irg_bad)(const ir_graph *irg) {
695 return _get_irg_bad(irg);
699 (set_irg_bad)(ir_graph *irg, ir_node *node) {
700 _set_irg_bad(irg, node);
704 (get_irg_no_mem)(const ir_graph *irg) {
705 return _get_irg_no_mem(irg);
709 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
710 _set_irg_no_mem(irg, node);
714 (get_irg_current_block)(const ir_graph *irg) {
715 return _get_irg_current_block(irg);
719 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
720 _set_irg_current_block(irg, node);
724 (get_irg_entity)(const ir_graph *irg) {
725 return _get_irg_entity(irg);
729 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
730 _set_irg_entity(irg, ent);
734 (get_irg_frame_type)(ir_graph *irg) {
735 return _get_irg_frame_type(irg);
739 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
740 _set_irg_frame_type(irg, ftp);
744 get_irg_n_locs(ir_graph *irg) {
745 if (get_opt_precise_exc_context())
746 return irg->n_loc - 1 - 1;
748 return irg->n_loc - 1;
752 set_irg_n_loc(ir_graph *irg, int n_loc) {
753 if (get_opt_precise_exc_context())
754 irg->n_loc = n_loc + 1 + 1;
756 irg->n_loc = n_loc + 1;
761 /* Returns the obstack associated with the graph. */
763 (get_irg_obstack)(const ir_graph *irg) {
764 return _get_irg_obstack(irg);
768 * Returns true if the node n is allocated on the storage of graph irg.
770 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
772 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
773 struct _obstack_chunk *p;
776 * checks weather the ir_node pointer is on the obstack.
777 * A more sophisticated check would test the "whole" ir_node
779 for (p = irg->obst->chunk; p; p = p->prev) {
780 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
788 (get_irg_phase_state)(const ir_graph *irg) {
789 return _get_irg_phase_state(irg);
793 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
794 _set_irg_phase_state(irg, state);
798 (get_irg_pinned)(const ir_graph *irg) {
799 return _get_irg_pinned(irg);
803 (get_irg_outs_state)(const ir_graph *irg) {
804 return _get_irg_outs_state(irg);
808 (set_irg_outs_inconsistent)(ir_graph *irg) {
809 _set_irg_outs_inconsistent(irg);
813 (get_irg_extblk_state)(const ir_graph *irg) {
814 return _get_irg_extblk_state(irg);
818 (set_irg_extblk_inconsistent)(ir_graph *irg) {
819 _set_irg_extblk_inconsistent(irg);
823 (get_irg_dom_state)(const ir_graph *irg) {
824 return _get_irg_dom_state(irg);
828 (get_irg_postdom_state)(const ir_graph *irg) {
829 return _get_irg_postdom_state(irg);
833 (set_irg_doms_inconsistent)(ir_graph *irg) {
834 _set_irg_doms_inconsistent(irg);
838 (get_irg_loopinfo_state)(const ir_graph *irg) {
839 return _get_irg_loopinfo_state(irg);
843 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
844 _set_irg_loopinfo_state(irg, s);
848 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
849 _set_irg_loopinfo_inconsistent(irg);
852 void set_irp_loopinfo_inconsistent(void) {
854 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
855 set_irg_loopinfo_inconsistent(get_irp_irg(i));
862 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
863 _set_irg_pinned(irg, p);
866 irg_callee_info_state
867 (get_irg_callee_info_state)(const ir_graph *irg) {
868 return _get_irg_callee_info_state(irg);
872 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
873 _set_irg_callee_info_state(irg, s);
877 (get_irg_inline_property)(const ir_graph *irg) {
878 return _get_irg_inline_property(irg);
882 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
883 _set_irg_inline_property(irg, s);
887 (get_irg_additional_properties)(const ir_graph *irg) {
888 return _get_irg_additional_properties(irg);
892 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
893 _set_irg_additional_properties(irg, property_mask);
897 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
898 _set_irg_additional_property(irg, flag);
902 (set_irg_link)(ir_graph *irg, void *thing) {
903 _set_irg_link(irg, thing);
907 (get_irg_link)(const ir_graph *irg) {
908 return _get_irg_link(irg);
912 (get_irg_visited)(const ir_graph *irg) {
913 return _get_irg_visited(irg);
916 #ifdef INTERPROCEDURAL_VIEW
917 /** maximum visited flag content of all ir_graph visited fields. */
918 static ir_visited_t max_irg_visited = 0;
919 #endif /* INTERPROCEDURAL_VIEW */
922 set_irg_visited(ir_graph *irg, ir_visited_t visited) {
923 irg->visited = visited;
924 #ifdef INTERPROCEDURAL_VIEW
925 if (irg->visited > max_irg_visited) {
926 max_irg_visited = irg->visited;
928 #endif /* INTERPROCEDURAL_VIEW */
932 inc_irg_visited(ir_graph *irg) {
933 #ifdef INTERPROCEDURAL_VIEW
934 if (++irg->visited > max_irg_visited) {
935 max_irg_visited = irg->visited;
939 #endif /* INTERPROCEDURAL_VIEW */
942 #ifdef INTERPROCEDURAL_VIEW
944 get_max_irg_visited(void) {
947 for(i = 0; i < get_irp_n_irgs(); i++)
948 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
950 return max_irg_visited;
953 void set_max_irg_visited(int val) {
954 max_irg_visited = val;
958 inc_max_irg_visited(void) {
961 for(i = 0; i < get_irp_n_irgs(); i++)
962 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
964 return ++max_irg_visited;
966 #endif /* INTERPROCEDURAL_VIEW */
969 (get_irg_block_visited)(const ir_graph *irg) {
970 return _get_irg_block_visited(irg);
974 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
975 _set_irg_block_visited(irg, visited);
979 (inc_irg_block_visited)(ir_graph *irg) {
980 _inc_irg_block_visited(irg);
983 /* Return the floating point model of this graph. */
984 unsigned (get_irg_fp_model)(const ir_graph *irg) {
985 return _get_irg_fp_model(irg);
988 /* Sets the floating point model for this graph. */
989 void set_irg_fp_model(ir_graph *irg, unsigned model) {
990 irg->fp_model = model;
994 * walker Start->End: places Proj nodes into the same block
995 * as it's predecessors
1000 static void normalize_proj_walker(ir_node *n, void *env) {
1003 ir_node *pred = get_Proj_pred(n);
1004 ir_node *block = get_nodes_block(pred);
1006 set_nodes_block(n, block);
1010 /* move Proj nodes into the same block as its predecessors */
1011 void normalize_proj_nodes(ir_graph *irg) {
1012 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1013 set_irg_outs_inconsistent(irg);
1016 /* set a description for local value n */
1017 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1018 assert(0 <= n && n < irg->n_loc);
1020 if (! irg->loc_descriptions)
1021 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1023 irg->loc_descriptions[n] = description;
1026 /* get the description for local value n */
1027 void *get_irg_loc_description(ir_graph *irg, int n) {
1028 assert(0 <= n && n < irg->n_loc);
1029 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1033 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources) {
1034 assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1035 assert((irg->reserved_resources & resources) == 0);
1036 irg->reserved_resources |= resources;
1039 void ir_free_resources(ir_graph *irg, ir_resources_t resources) {
1040 assert((irg->reserved_resources & resources) == resources);
1041 irg->reserved_resources &= ~resources;
1044 ir_resources_t ir_resources_reserved(const ir_graph *irg) {
1045 return irg->reserved_resources;
1049 /* Returns a estimated node count of the irg. */
1050 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1051 return _get_irg_estimated_node_cnt(irg);
1054 /* Returns the last irn index for this graph. */
1055 unsigned get_irg_last_idx(const ir_graph *irg) {
1056 return irg->last_node_idx;
1059 /* register additional space in an IR graph */
1060 size_t register_additional_graph_data(size_t size) {
1061 assert(!forbid_new_data && "Too late to register additional node data");
1063 if (forbid_new_data)
1066 return additional_graph_data_size += size;