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;
138 for (i = 0; i < EDGE_KIND_LAST; ++i)
139 edges_deactivate_kind(irg, i);
140 DEL_ARR_F(irg->idx_irn_map);
141 free(ptr - additional_graph_data_size);
145 * Set the number of locals for a given graph.
147 * @param irg the graph
148 * @param n_loc number of locals
150 void irg_set_nloc(ir_graph *res, int n_loc) {
151 assert(res->phase_state == phase_building);
153 if (get_opt_precise_exc_context()) {
154 res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
155 dereferenced in this graph plus one for
156 the store plus one for links to fragile
157 operations. n_loc is not the number of
158 parameters to the procedure! */
160 res->n_loc = n_loc + 1; /* number of local variables that are never
161 dereferenced in this graph plus one for
162 the store. This is not the number of parameters
165 if (res->loc_descriptions) {
166 xfree(res->loc_descriptions);
167 res->loc_descriptions = NULL;
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
180 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc) {
182 ir_node *first_block;
183 ir_node *end, *start, *start_block, *initial_mem, *projX;
187 /* inform statistics here, as blocks will be already build on this graph */
188 hook_new_graph(res, ent);
190 current_ir_graph = res;
192 /*-- initialized for each graph. --*/
193 res->kind = k_ir_graph;
194 res->obst = XMALLOC(struct obstack);
195 obstack_init(res->obst);
197 res->phase_state = phase_building;
198 irg_set_nloc(res, n_loc);
200 /* descriptions will be allocated on demand */
201 res->loc_descriptions = NULL;
203 res->visited = 0; /* visited flag, for the ir walker */
204 res->block_visited = 0; /* visited flag, for the 'block'-walker */
206 res->extbb_obst = NULL;
208 res->last_node_idx = 0;
210 res->value_table = new_identities (); /* value table for global value
211 numbering for optimizing use in iropt.c */
214 res->inline_property = irg_inline_any;
215 res->additional_properties = mtp_property_inherited; /* inherited from type */
217 res->irg_pinned_state = op_pin_state_pinned;
218 res->outs_state = outs_none;
219 res->dom_state = dom_none;
220 res->pdom_state = dom_none;
221 res->typeinfo_state = ir_typeinfo_none;
222 set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
223 res->callee_info_state = irg_callee_info_none;
224 res->loopinfo_state = loopinfo_none;
225 res->class_cast_state = ir_class_casts_transitive;
226 res->extblk_state = ir_extblk_info_none;
227 res->execfreq_state = exec_freq_none;
228 res->fp_model = fp_model_precise;
229 res->entity_usage_state = ir_entity_usage_not_computed;
230 res->mem_disambig_opt = aa_opt_inherited;
232 /*-- Type information for the procedure of the graph --*/
234 set_entity_irg(ent, res);
236 /*-- a class type so that it can contain "inner" methods as in Pascal. --*/
237 res->frame_type = new_type_frame(mangle(get_entity_ident(ent), frame_type_suffix));
239 /* the Anchor node must be created first */
240 res->anchor = new_Anchor(res);
242 /*-- Nodes needed in every graph --*/
243 set_irg_end_block (res, new_immBlock());
245 set_irg_end (res, end);
246 set_irg_end_reg (res, end);
247 set_irg_end_except(res, end);
249 start_block = new_immBlock();
250 set_irg_start_block(res, start_block);
251 set_irg_bad (res, new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL));
252 set_irg_no_mem (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
254 set_irg_start (res, start);
256 /* Proj results of start node */
257 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
258 set_irg_initial_exec (res, projX);
259 set_irg_frame (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
260 set_irg_tls (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
261 set_irg_args (res, new_Proj(start, mode_T, pn_Start_T_args));
262 set_irg_value_param_base(res, new_Proj(start, mode_P_data, pn_Start_P_value_arg_base));
263 initial_mem = new_Proj(start, mode_M, pn_Start_M);
264 set_irg_initial_mem(res, initial_mem);
266 add_immBlock_pred(start_block, projX);
267 set_store(initial_mem);
269 res->index = get_irp_new_irg_idx();
271 res->graph_nr = get_irp_new_node_nr();
275 * The code generation needs it. leave it in now.
276 * Use of this edge is matter of discussion, unresolved. Also possible:
277 * add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
279 mature_immBlock(res->current_block);
281 /*-- Make a block to start with --*/
282 first_block = new_immBlock();
283 add_immBlock_pred(first_block, projX);
285 res->method_execution_frequency = -1.0;
286 res->estimated_node_count = 0;
291 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
292 ir_graph *res = new_r_ir_graph(ent, n_loc);
293 add_irp_irg(res); /* remember this graph global. */
297 /* Make a rudimentary IR graph for the constant code.
298 Must look like a correct irg, spare everything else. */
299 ir_graph *new_const_code_irg(void) {
301 ir_node *end, *start_block, *start, *projX;
305 /* inform statistics here, as blocks will be already build on this graph */
306 hook_new_graph(res, NULL);
308 current_ir_graph = res;
309 res->n_loc = 1; /* Only the memory. */
310 res->visited = 0; /* visited flag, for the ir walker */
311 res->block_visited = 0; /* visited flag, for the 'block'-walker */
312 res->obst = XMALLOC(struct obstack);
313 obstack_init (res->obst);
314 res->extbb_obst = NULL;
316 res->last_node_idx = 0;
318 res->phase_state = phase_building;
319 res->irg_pinned_state = op_pin_state_pinned;
320 res->extblk_state = ir_extblk_info_none;
321 res->fp_model = fp_model_precise;
323 res->value_table = new_identities(); /* value table for global value
324 numbering for optimizing use in
327 res->frame_type = NULL;
329 /* the Anchor node must be created first */
330 res->anchor = new_Anchor(res);
332 /* -- The end block -- */
333 set_irg_end_block (res, new_immBlock());
335 set_irg_end (res, end);
336 set_irg_end_reg (res, end);
337 set_irg_end_except(res, end);
338 mature_immBlock(get_cur_block()); /* mature the end block */
340 /* -- The start block -- */
341 start_block = new_immBlock();
342 set_irg_start_block(res, start_block);
343 set_irg_bad (res, new_ir_node (NULL, res, start_block, op_Bad, mode_T, 0, NULL));
344 set_irg_no_mem (res, new_ir_node (NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
346 set_irg_start (res, start);
348 /* Proj results of start node */
349 set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
350 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
351 add_immBlock_pred(start_block, projX);
352 mature_immBlock (start_block); /* mature the start block */
354 add_immBlock_pred(new_immBlock(), projX);
355 mature_immBlock (get_cur_block()); /* mature the 'body' block for expressions */
357 /* Set the visited flag high enough that the blocks will never be visited. */
358 set_irn_visited(get_cur_block(), -1);
359 set_Block_block_visited(get_cur_block(), -1);
360 set_Block_block_visited(start_block, -1);
361 set_irn_visited(start_block, -1);
362 set_irn_visited(get_irg_bad(res), -1);
363 set_irn_visited(get_irg_no_mem(res), -1);
365 res->phase_state = phase_high;
371 * Pre-Walker: Copies blocks and nodes from the original method graph
372 * to the copied graph.
374 * @param n A node from the original method graph.
375 * @param env The copied graph.
377 static void copy_all_nodes(ir_node *n, void *env) {
379 ir_op *op = get_irn_op(n);
382 nn = new_ir_node(get_irn_dbg_info(n),
384 NULL, /* no block yet, will be set later */
391 /* Copy the attributes. These might point to additional data. If this
392 was allocated on the old obstack the pointers now are dangling. This
393 frees e.g. the memory of the graph_arr allocated in new_immBlock. */
394 copy_node_attr(n, nn);
395 new_backedge_info(nn);
398 /* fix the irg for blocks */
400 nn->attr.block.irg = irg;
402 /* fix access to entities on the stack frame */
404 ir_entity *ent = get_Sel_entity(nn);
405 ir_type *tp = get_entity_owner(ent);
407 if (is_frame_type(tp)) {
408 /* replace by the copied entity */
409 ent = get_entity_link(ent);
411 assert(is_entity(ent));
412 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
413 set_Sel_entity(nn, ent);
419 * Post-walker: Set the predecessors of the copied nodes.
420 * The copied nodes are set as link of their original nodes. The links of
421 * "irn" predecessors are the predecessors of copied node.
423 static void set_all_preds(ir_node *irn, void *env) {
428 nn = get_irn_link(irn);
431 ir_node *mbh = get_Block_MacroBlock(irn);
432 set_Block_MacroBlock(nn, get_irn_link(mbh));
433 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
434 pred = get_Block_cfgpred(irn, i);
435 set_Block_cfgpred(nn, i, get_irn_link(pred));
438 /* First we set the block our copy if it is not a block.*/
439 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
440 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
441 pred = get_irn_n(irn, i);
442 set_irn_n(nn, i, get_irn_link(pred));
447 #define NN(irn) get_irn_link(irn)
450 * Create a new graph that is a copy of a given one.
452 ir_graph *create_irg_copy(ir_graph *irg) {
458 res->visited = 0; /* visited flag, for the ir walker */
459 res->block_visited = 0; /* visited flag, for the 'block'-walker */
460 res->obst = XMALLOC(struct obstack);
461 obstack_init(res->obst);
462 res->extbb_obst = NULL;
464 res->last_node_idx = 0;
466 res->phase_state = irg->phase_state;
467 res->irg_pinned_state = irg->irg_pinned_state;
468 res->extblk_state = ir_extblk_info_none;
469 res->fp_model = irg->fp_model;
471 res->value_table = new_identities();
473 /* clone the frame type here for safety */
474 irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
475 res->frame_type = clone_frame_type(irg->frame_type);
477 res->phase_state = irg->phase_state;
479 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
481 /* copy all nodes from the graph irg to the new graph res */
482 irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
484 /* copy the Anchor node */
485 res->anchor = NN(irg->anchor);
487 /* -- The end block -- */
488 set_irg_end_block (res, NN(get_irg_end_block(irg)));
489 set_irg_end (res, NN(get_irg_end(irg)));
490 set_irg_end_reg (res, NN(get_irg_end_reg(irg)));
491 set_irg_end_except(res, NN(get_irg_end_except(irg)));
493 /* -- The start block -- */
494 set_irg_start_block(res, NN(get_irg_start_block(irg)));
495 set_irg_bad (res, NN(get_irg_bad(irg)));
496 set_irg_no_mem (res, NN(get_irg_no_mem(irg)));
497 set_irg_start (res, NN(get_irg_start(irg)));
499 /* Proj results of start node */
500 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
502 /* Copy the node count estimation. Would be strange if this
503 is different from the original one. */
504 res->estimated_node_count = irg->estimated_node_count;
506 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
507 irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
514 /* Frees the passed irgraph.
515 Deallocates all nodes in this graph and the ir_graph structure.
516 Sets the field irgraph in the corresponding entity to NULL.
517 Does not remove the irgraph from the list in irprog (requires
518 inefficient search, call remove_irp_irg by hand).
519 Does not free types, entities or modes that are used only by this
520 graph, nor the entity standing for this graph. */
521 void free_ir_graph(ir_graph *irg) {
522 assert(is_ir_graph(irg));
524 edges_deactivate(irg);
526 hook_free_graph(irg);
527 if (irg->outs_state != outs_none)
530 free_type(irg->frame_type);
531 if (irg->value_table)
532 del_identities(irg->value_table);
534 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
535 set_entity_peculiarity (irg->ent, peculiarity_description);
536 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
537 set_entity_peculiarity (irg->ent, pec);
540 free_End(get_irg_end(irg));
541 obstack_free(irg->obst,NULL);
543 if (irg->loc_descriptions)
544 free(irg->loc_descriptions);
549 /* access routines for all ir_graph attributes:
551 {attr type} get_irg_{attribute name} (ir_graph *irg);
552 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
555 (is_ir_graph)(const void *thing) {
556 return _is_ir_graph(thing);
560 /* Outputs a unique number for this node */
561 long get_irg_graph_nr(const ir_graph *irg) {
562 return irg->graph_nr;
565 long get_irg_graph_nr(const ir_graph *irg) {
566 return PTR_TO_INT(irg);
570 int get_irg_idx(const ir_graph *irg) {
575 (get_irg_start_block)(const ir_graph *irg) {
576 return _get_irg_start_block(irg);
580 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
581 _set_irg_start_block(irg, node);
585 (get_irg_start)(const ir_graph *irg) {
586 return _get_irg_start(irg);
590 (set_irg_start)(ir_graph *irg, ir_node *node) {
591 _set_irg_start(irg, node);
595 (get_irg_end_block)(const ir_graph *irg) {
596 return _get_irg_end_block(irg);
600 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
601 _set_irg_end_block(irg, node);
605 (get_irg_end)(const ir_graph *irg) {
606 return _get_irg_end(irg);
610 (set_irg_end)(ir_graph *irg, ir_node *node) {
611 _set_irg_end(irg, node);
615 (get_irg_end_reg)(const ir_graph *irg) {
616 return _get_irg_end_reg(irg);
620 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
621 _set_irg_end_reg(irg, node);
625 (get_irg_end_except)(const ir_graph *irg) {
626 return _get_irg_end_except(irg);
630 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
631 assert(get_irn_op(node) == op_EndExcept || is_End(node));
632 _set_irg_end_except(irg, node);
636 (get_irg_initial_exec)(const ir_graph *irg) {
637 return _get_irg_initial_exec(irg);
641 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
642 _set_irg_initial_exec(irg, node);
646 (get_irg_frame)(const ir_graph *irg) {
647 return _get_irg_frame(irg);
651 (set_irg_frame)(ir_graph *irg, ir_node *node) {
652 _set_irg_frame(irg, node);
656 (get_irg_tls)(const ir_graph *irg) {
657 return _get_irg_tls(irg);
661 (set_irg_tls)(ir_graph *irg, ir_node *node) {
662 _set_irg_tls(irg, node);
666 (get_irg_initial_mem)(const ir_graph *irg) {
667 return _get_irg_initial_mem(irg);
671 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
672 _set_irg_initial_mem(irg, node);
676 (get_irg_args)(const ir_graph *irg) {
677 return _get_irg_args(irg);
681 (set_irg_args)(ir_graph *irg, ir_node *node) {
682 _set_irg_args(irg, node);
686 (get_irg_value_param_base)(const ir_graph *irg) {
687 return _get_irg_value_param_base(irg);
691 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
692 _set_irg_value_param_base(irg, node);
696 (get_irg_bad)(const ir_graph *irg) {
697 return _get_irg_bad(irg);
701 (set_irg_bad)(ir_graph *irg, ir_node *node) {
702 _set_irg_bad(irg, node);
706 (get_irg_no_mem)(const ir_graph *irg) {
707 return _get_irg_no_mem(irg);
711 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
712 _set_irg_no_mem(irg, node);
716 (get_irg_current_block)(const ir_graph *irg) {
717 return _get_irg_current_block(irg);
721 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
722 _set_irg_current_block(irg, node);
726 (get_irg_entity)(const ir_graph *irg) {
727 return _get_irg_entity(irg);
731 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
732 _set_irg_entity(irg, ent);
736 (get_irg_frame_type)(ir_graph *irg) {
737 return _get_irg_frame_type(irg);
741 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
742 _set_irg_frame_type(irg, ftp);
746 get_irg_n_locs(ir_graph *irg) {
747 if (get_opt_precise_exc_context())
748 return irg->n_loc - 1 - 1;
750 return irg->n_loc - 1;
754 set_irg_n_loc(ir_graph *irg, int n_loc) {
755 if (get_opt_precise_exc_context())
756 irg->n_loc = n_loc + 1 + 1;
758 irg->n_loc = n_loc + 1;
763 /* Returns the obstack associated with the graph. */
765 (get_irg_obstack)(const ir_graph *irg) {
766 return _get_irg_obstack(irg);
770 * Returns true if the node n is allocated on the storage of graph irg.
772 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
774 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
775 struct _obstack_chunk *p;
778 * checks weather the ir_node pointer is on the obstack.
779 * A more sophisticated check would test the "whole" ir_node
781 for (p = irg->obst->chunk; p; p = p->prev) {
782 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
790 (get_irg_phase_state)(const ir_graph *irg) {
791 return _get_irg_phase_state(irg);
795 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
796 _set_irg_phase_state(irg, state);
800 (get_irg_pinned)(const ir_graph *irg) {
801 return _get_irg_pinned(irg);
805 (get_irg_outs_state)(const ir_graph *irg) {
806 return _get_irg_outs_state(irg);
810 (set_irg_outs_inconsistent)(ir_graph *irg) {
811 _set_irg_outs_inconsistent(irg);
815 (get_irg_extblk_state)(const ir_graph *irg) {
816 return _get_irg_extblk_state(irg);
820 (set_irg_extblk_inconsistent)(ir_graph *irg) {
821 _set_irg_extblk_inconsistent(irg);
825 (get_irg_dom_state)(const ir_graph *irg) {
826 return _get_irg_dom_state(irg);
830 (get_irg_postdom_state)(const ir_graph *irg) {
831 return _get_irg_postdom_state(irg);
835 (set_irg_doms_inconsistent)(ir_graph *irg) {
836 _set_irg_doms_inconsistent(irg);
840 (get_irg_loopinfo_state)(const ir_graph *irg) {
841 return _get_irg_loopinfo_state(irg);
845 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
846 _set_irg_loopinfo_state(irg, s);
850 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
851 _set_irg_loopinfo_inconsistent(irg);
854 void set_irp_loopinfo_inconsistent(void) {
856 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
857 set_irg_loopinfo_inconsistent(get_irp_irg(i));
864 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
865 _set_irg_pinned(irg, p);
868 irg_callee_info_state
869 (get_irg_callee_info_state)(const ir_graph *irg) {
870 return _get_irg_callee_info_state(irg);
874 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
875 _set_irg_callee_info_state(irg, s);
879 (get_irg_inline_property)(const ir_graph *irg) {
880 return _get_irg_inline_property(irg);
884 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
885 _set_irg_inline_property(irg, s);
889 (get_irg_additional_properties)(const ir_graph *irg) {
890 return _get_irg_additional_properties(irg);
894 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
895 _set_irg_additional_properties(irg, property_mask);
899 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
900 _set_irg_additional_property(irg, flag);
904 (set_irg_link)(ir_graph *irg, void *thing) {
905 _set_irg_link(irg, thing);
909 (get_irg_link)(const ir_graph *irg) {
910 return _get_irg_link(irg);
914 (get_irg_visited)(const ir_graph *irg) {
915 return _get_irg_visited(irg);
918 #ifdef INTERPROCEDURAL_VIEW
919 /** maximum visited flag content of all ir_graph visited fields. */
920 static ir_visited_t max_irg_visited = 0;
921 #endif /* INTERPROCEDURAL_VIEW */
924 set_irg_visited(ir_graph *irg, ir_visited_t visited) {
925 irg->visited = visited;
926 #ifdef INTERPROCEDURAL_VIEW
927 if (irg->visited > max_irg_visited) {
928 max_irg_visited = irg->visited;
930 #endif /* INTERPROCEDURAL_VIEW */
934 inc_irg_visited(ir_graph *irg) {
935 #ifdef INTERPROCEDURAL_VIEW
936 if (++irg->visited > max_irg_visited) {
937 max_irg_visited = irg->visited;
941 #endif /* INTERPROCEDURAL_VIEW */
944 #ifdef INTERPROCEDURAL_VIEW
946 get_max_irg_visited(void) {
949 for(i = 0; i < get_irp_n_irgs(); i++)
950 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
952 return max_irg_visited;
955 void set_max_irg_visited(int val) {
956 max_irg_visited = val;
960 inc_max_irg_visited(void) {
963 for(i = 0; i < get_irp_n_irgs(); i++)
964 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
966 return ++max_irg_visited;
968 #endif /* INTERPROCEDURAL_VIEW */
971 (get_irg_block_visited)(const ir_graph *irg) {
972 return _get_irg_block_visited(irg);
976 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
977 _set_irg_block_visited(irg, visited);
981 (inc_irg_block_visited)(ir_graph *irg) {
982 _inc_irg_block_visited(irg);
985 /* Return the floating point model of this graph. */
986 unsigned (get_irg_fp_model)(const ir_graph *irg) {
987 return _get_irg_fp_model(irg);
990 /* Sets the floating point model for this graph. */
991 void set_irg_fp_model(ir_graph *irg, unsigned model) {
992 irg->fp_model = model;
996 * walker Start->End: places Proj nodes into the same block
997 * as it's predecessors
1000 * @param env ignored
1002 static void normalize_proj_walker(ir_node *n, void *env) {
1005 ir_node *pred = get_Proj_pred(n);
1006 ir_node *block = get_nodes_block(pred);
1008 set_nodes_block(n, block);
1012 /* move Proj nodes into the same block as its predecessors */
1013 void normalize_proj_nodes(ir_graph *irg) {
1014 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1015 set_irg_outs_inconsistent(irg);
1018 /* set a description for local value n */
1019 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1020 assert(0 <= n && n < irg->n_loc);
1022 if (! irg->loc_descriptions)
1023 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1025 irg->loc_descriptions[n] = description;
1028 /* get the description for local value n */
1029 void *get_irg_loc_description(ir_graph *irg, int n) {
1030 assert(0 <= n && n < irg->n_loc);
1031 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1035 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources) {
1036 assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1037 assert((irg->reserved_resources & resources) == 0);
1038 irg->reserved_resources |= resources;
1041 void ir_free_resources(ir_graph *irg, ir_resources_t resources) {
1042 assert((irg->reserved_resources & resources) == resources);
1043 irg->reserved_resources &= ~resources;
1046 ir_resources_t ir_resources_reserved(const ir_graph *irg) {
1047 return irg->reserved_resources;
1051 /* Returns a estimated node count of the irg. */
1052 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1053 return _get_irg_estimated_node_cnt(irg);
1056 /* Returns the last irn index for this graph. */
1057 unsigned get_irg_last_idx(const ir_graph *irg) {
1058 return irg->last_node_idx;
1061 /* register additional space in an IR graph */
1062 size_t register_additional_graph_data(size_t size) {
1063 assert(!forbid_new_data && "Too late to register additional node data");
1065 if (forbid_new_data)
1068 return additional_graph_data_size += size;