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());
242 set_cur_block(get_irg_end_block(res));
244 set_irg_end (res, end);
245 set_irg_end_reg (res, end);
246 set_irg_end_except(res, end);
248 start_block = new_immBlock();
249 set_cur_block(start_block);
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 set_cur_block(first_block);
284 add_immBlock_pred(first_block, projX);
286 res->method_execution_frequency = -1.0;
287 res->estimated_node_count = 0;
292 ir_graph *new_ir_graph(ir_entity *ent, int n_loc) {
293 ir_graph *res = new_r_ir_graph(ent, n_loc);
294 add_irp_irg(res); /* remember this graph global. */
298 /* Make a rudimentary IR graph for the constant code.
299 Must look like a correct irg, spare everything else. */
300 ir_graph *new_const_code_irg(void)
302 ir_graph *res = alloc_graph();
309 ir_node *start_block;
312 /* inform statistics here, as blocks will be already build on this graph */
313 hook_new_graph(res, NULL);
315 current_ir_graph = res;
316 res->n_loc = 1; /* Only the memory. */
317 res->visited = 0; /* visited flag, for the ir walker */
318 res->block_visited = 0; /* visited flag, for the 'block'-walker */
319 res->obst = XMALLOC(struct obstack);
320 obstack_init(res->obst);
321 res->extbb_obst = NULL;
323 res->last_node_idx = 0;
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;
330 /* value table for global value numbering for optimizing use in iropt.c */
331 res->value_table = new_identities();
333 res->frame_type = NULL;
335 /* the Anchor node must be created first */
336 res->anchor = new_Anchor(res);
338 /* -- The end block -- */
339 end_block = new_immBlock();
340 set_irg_end_block(res, end_block);
341 set_cur_block(end_block);
343 set_irg_end (res, end);
344 set_irg_end_reg (res, end);
345 set_irg_end_except(res, end);
346 mature_immBlock(end_block);
348 /* -- The start block -- */
349 start_block = new_immBlock();
350 set_cur_block(start_block);
351 set_irg_start_block(res, start_block);
352 bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
353 set_irg_bad(res, bad);
354 no_mem = new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL);
355 set_irg_no_mem(res, no_mem);
357 set_irg_start(res, start);
359 /* Proj results of start node */
360 set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
361 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
362 add_immBlock_pred(start_block, projX);
363 mature_immBlock(start_block);
365 body_block = new_immBlock();
366 add_immBlock_pred(body_block, projX);
367 mature_immBlock(body_block); /* mature the 'body' block for expressions */
368 set_cur_block(body_block);
370 /* Set the visited flag high enough that the blocks will never be visited. */
371 set_irn_visited(body_block, -1);
372 set_Block_block_visited(body_block, -1);
373 set_Block_block_visited(start_block, -1);
374 set_irn_visited(start_block, -1);
375 set_irn_visited(bad, -1);
376 set_irn_visited(no_mem, -1);
378 res->phase_state = phase_high;
384 * Pre-Walker: Copies blocks and nodes from the original method graph
385 * to the copied graph.
387 * @param n A node from the original method graph.
388 * @param env The copied graph.
390 static void copy_all_nodes(ir_node *n, void *env) {
392 ir_op *op = get_irn_op(n);
395 nn = new_ir_node(get_irn_dbg_info(n),
397 NULL, /* no block yet, will be set later */
404 /* Copy the attributes. These might point to additional data. If this
405 was allocated on the old obstack the pointers now are dangling. This
406 frees e.g. the memory of the graph_arr allocated in new_immBlock. */
407 copy_node_attr(n, nn);
408 new_backedge_info(nn);
411 /* fix the irg for blocks */
413 nn->attr.block.irg = irg;
415 /* fix access to entities on the stack frame */
417 ir_entity *ent = get_Sel_entity(nn);
418 ir_type *tp = get_entity_owner(ent);
420 if (is_frame_type(tp)) {
421 /* replace by the copied entity */
422 ent = get_entity_link(ent);
424 assert(is_entity(ent));
425 assert(get_entity_owner(ent) == get_irg_frame_type(irg));
426 set_Sel_entity(nn, ent);
432 * Post-walker: Set the predecessors of the copied nodes.
433 * The copied nodes are set as link of their original nodes. The links of
434 * "irn" predecessors are the predecessors of copied node.
436 static void set_all_preds(ir_node *irn, void *env) {
441 nn = get_irn_link(irn);
444 ir_node *mbh = get_Block_MacroBlock(irn);
445 set_Block_MacroBlock(nn, get_irn_link(mbh));
446 for (i = get_Block_n_cfgpreds(irn) - 1; i >= 0; i--) {
447 pred = get_Block_cfgpred(irn, i);
448 set_Block_cfgpred(nn, i, get_irn_link(pred));
451 /* First we set the block our copy if it is not a block.*/
452 set_nodes_block(nn, get_irn_link(get_nodes_block(irn)));
453 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
454 pred = get_irn_n(irn, i);
455 set_irn_n(nn, i, get_irn_link(pred));
460 #define NN(irn) get_irn_link(irn)
463 * Create a new graph that is a copy of a given one.
465 ir_graph *create_irg_copy(ir_graph *irg) {
471 res->visited = 0; /* visited flag, for the ir walker */
472 res->block_visited = 0; /* visited flag, for the 'block'-walker */
473 res->obst = XMALLOC(struct obstack);
474 obstack_init(res->obst);
475 res->extbb_obst = NULL;
477 res->last_node_idx = 0;
479 res->phase_state = irg->phase_state;
480 res->irg_pinned_state = irg->irg_pinned_state;
481 res->extblk_state = ir_extblk_info_none;
482 res->fp_model = irg->fp_model;
484 res->value_table = new_identities();
486 /* clone the frame type here for safety */
487 irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
488 res->frame_type = clone_frame_type(irg->frame_type);
490 res->phase_state = irg->phase_state;
492 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
494 /* copy all nodes from the graph irg to the new graph res */
495 irg_walk_anchors(irg, copy_all_nodes, set_all_preds, res);
497 /* copy the Anchor node */
498 res->anchor = NN(irg->anchor);
500 /* -- The end block -- */
501 set_irg_end_block (res, NN(get_irg_end_block(irg)));
502 set_irg_end (res, NN(get_irg_end(irg)));
503 set_irg_end_reg (res, NN(get_irg_end_reg(irg)));
504 set_irg_end_except(res, NN(get_irg_end_except(irg)));
506 /* -- The start block -- */
507 set_irg_start_block(res, NN(get_irg_start_block(irg)));
508 set_irg_bad (res, NN(get_irg_bad(irg)));
509 set_irg_no_mem (res, NN(get_irg_no_mem(irg)));
510 set_irg_start (res, NN(get_irg_start(irg)));
512 /* Proj results of start node */
513 set_irg_initial_mem(res, NN(get_irg_initial_mem(irg)));
515 /* Copy the node count estimation. Would be strange if this
516 is different from the original one. */
517 res->estimated_node_count = irg->estimated_node_count;
519 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
520 irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
527 /* Frees the passed irgraph.
528 Deallocates all nodes in this graph and the ir_graph structure.
529 Sets the field irgraph in the corresponding entity to NULL.
530 Does not remove the irgraph from the list in irprog (requires
531 inefficient search, call remove_irp_irg by hand).
532 Does not free types, entities or modes that are used only by this
533 graph, nor the entity standing for this graph. */
534 void free_ir_graph(ir_graph *irg) {
535 assert(is_ir_graph(irg));
537 edges_deactivate(irg);
539 hook_free_graph(irg);
540 if (irg->outs_state != outs_none)
543 free_type(irg->frame_type);
544 if (irg->value_table)
545 del_identities(irg->value_table);
547 ir_peculiarity pec = get_entity_peculiarity (irg->ent);
548 set_entity_peculiarity (irg->ent, peculiarity_description);
549 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
550 set_entity_peculiarity (irg->ent, pec);
553 free_End(get_irg_end(irg));
554 obstack_free(irg->obst,NULL);
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) {
587 ir_node *(get_idx_irn)(ir_graph *irg, unsigned idx) {
588 return _get_idx_irn(irg, idx);
592 (get_irg_start_block)(const ir_graph *irg) {
593 return _get_irg_start_block(irg);
597 (set_irg_start_block)(ir_graph *irg, ir_node *node) {
598 _set_irg_start_block(irg, node);
602 (get_irg_start)(const ir_graph *irg) {
603 return _get_irg_start(irg);
607 (set_irg_start)(ir_graph *irg, ir_node *node) {
608 _set_irg_start(irg, node);
612 (get_irg_end_block)(const ir_graph *irg) {
613 return _get_irg_end_block(irg);
617 (set_irg_end_block)(ir_graph *irg, ir_node *node) {
618 _set_irg_end_block(irg, node);
622 (get_irg_end)(const ir_graph *irg) {
623 return _get_irg_end(irg);
627 (set_irg_end)(ir_graph *irg, ir_node *node) {
628 _set_irg_end(irg, node);
632 (get_irg_end_reg)(const ir_graph *irg) {
633 return _get_irg_end_reg(irg);
637 (set_irg_end_reg)(ir_graph *irg, ir_node *node) {
638 _set_irg_end_reg(irg, node);
642 (get_irg_end_except)(const ir_graph *irg) {
643 return _get_irg_end_except(irg);
647 (set_irg_end_except)(ir_graph *irg, ir_node *node) {
648 assert(get_irn_op(node) == op_EndExcept || is_End(node));
649 _set_irg_end_except(irg, node);
653 (get_irg_initial_exec)(const ir_graph *irg) {
654 return _get_irg_initial_exec(irg);
658 (set_irg_initial_exec)(ir_graph *irg, ir_node *node) {
659 _set_irg_initial_exec(irg, node);
663 (get_irg_frame)(const ir_graph *irg) {
664 return _get_irg_frame(irg);
668 (set_irg_frame)(ir_graph *irg, ir_node *node) {
669 _set_irg_frame(irg, node);
673 (get_irg_tls)(const ir_graph *irg) {
674 return _get_irg_tls(irg);
678 (set_irg_tls)(ir_graph *irg, ir_node *node) {
679 _set_irg_tls(irg, node);
683 (get_irg_initial_mem)(const ir_graph *irg) {
684 return _get_irg_initial_mem(irg);
688 (set_irg_initial_mem)(ir_graph *irg, ir_node *node) {
689 _set_irg_initial_mem(irg, node);
693 (get_irg_args)(const ir_graph *irg) {
694 return _get_irg_args(irg);
698 (set_irg_args)(ir_graph *irg, ir_node *node) {
699 _set_irg_args(irg, node);
703 (get_irg_value_param_base)(const ir_graph *irg) {
704 return _get_irg_value_param_base(irg);
708 (set_irg_value_param_base)(ir_graph *irg, ir_node *node) {
709 _set_irg_value_param_base(irg, node);
713 (get_irg_bad)(const ir_graph *irg) {
714 return _get_irg_bad(irg);
718 (set_irg_bad)(ir_graph *irg, ir_node *node) {
719 _set_irg_bad(irg, node);
723 (get_irg_no_mem)(const ir_graph *irg) {
724 return _get_irg_no_mem(irg);
728 (set_irg_no_mem)(ir_graph *irg, ir_node *node) {
729 _set_irg_no_mem(irg, node);
733 (get_irg_current_block)(const ir_graph *irg) {
734 return _get_irg_current_block(irg);
738 (set_irg_current_block)(ir_graph *irg, ir_node *node) {
739 _set_irg_current_block(irg, node);
743 (get_irg_entity)(const ir_graph *irg) {
744 return _get_irg_entity(irg);
748 (set_irg_entity)(ir_graph *irg, ir_entity *ent) {
749 _set_irg_entity(irg, ent);
753 (get_irg_frame_type)(ir_graph *irg) {
754 return _get_irg_frame_type(irg);
758 (set_irg_frame_type)(ir_graph *irg, ir_type *ftp) {
759 _set_irg_frame_type(irg, ftp);
763 get_irg_n_locs(ir_graph *irg) {
764 if (get_opt_precise_exc_context())
765 return irg->n_loc - 1 - 1;
767 return irg->n_loc - 1;
771 set_irg_n_loc(ir_graph *irg, int n_loc) {
772 if (get_opt_precise_exc_context())
773 irg->n_loc = n_loc + 1 + 1;
775 irg->n_loc = n_loc + 1;
780 /* Returns the obstack associated with the graph. */
782 (get_irg_obstack)(const ir_graph *irg) {
783 return _get_irg_obstack(irg);
787 * Returns true if the node n is allocated on the storage of graph irg.
789 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
791 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) {
792 struct _obstack_chunk *p;
795 * checks weather the ir_node pointer is on the obstack.
796 * A more sophisticated check would test the "whole" ir_node
798 for (p = irg->obst->chunk; p; p = p->prev) {
799 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
807 (get_irg_phase_state)(const ir_graph *irg) {
808 return _get_irg_phase_state(irg);
812 (set_irg_phase_state)(ir_graph *irg, irg_phase_state state) {
813 _set_irg_phase_state(irg, state);
817 (get_irg_pinned)(const ir_graph *irg) {
818 return _get_irg_pinned(irg);
822 (get_irg_outs_state)(const ir_graph *irg) {
823 return _get_irg_outs_state(irg);
827 (set_irg_outs_inconsistent)(ir_graph *irg) {
828 _set_irg_outs_inconsistent(irg);
832 (get_irg_extblk_state)(const ir_graph *irg) {
833 return _get_irg_extblk_state(irg);
837 (set_irg_extblk_inconsistent)(ir_graph *irg) {
838 _set_irg_extblk_inconsistent(irg);
842 (get_irg_dom_state)(const ir_graph *irg) {
843 return _get_irg_dom_state(irg);
847 (get_irg_postdom_state)(const ir_graph *irg) {
848 return _get_irg_postdom_state(irg);
852 (set_irg_doms_inconsistent)(ir_graph *irg) {
853 _set_irg_doms_inconsistent(irg);
857 (get_irg_loopinfo_state)(const ir_graph *irg) {
858 return _get_irg_loopinfo_state(irg);
862 (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) {
863 _set_irg_loopinfo_state(irg, s);
867 (set_irg_loopinfo_inconsistent)(ir_graph *irg) {
868 _set_irg_loopinfo_inconsistent(irg);
871 void set_irp_loopinfo_inconsistent(void) {
873 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
874 set_irg_loopinfo_inconsistent(get_irp_irg(i));
881 (set_irg_pinned)(ir_graph *irg, op_pin_state p) {
882 _set_irg_pinned(irg, p);
885 irg_callee_info_state
886 (get_irg_callee_info_state)(const ir_graph *irg) {
887 return _get_irg_callee_info_state(irg);
891 (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) {
892 _set_irg_callee_info_state(irg, s);
896 (get_irg_inline_property)(const ir_graph *irg) {
897 return _get_irg_inline_property(irg);
901 (set_irg_inline_property)(ir_graph *irg, irg_inline_property s) {
902 _set_irg_inline_property(irg, s);
906 (get_irg_additional_properties)(const ir_graph *irg) {
907 return _get_irg_additional_properties(irg);
911 (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask) {
912 _set_irg_additional_properties(irg, property_mask);
916 (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag) {
917 _set_irg_additional_property(irg, flag);
921 (set_irg_link)(ir_graph *irg, void *thing) {
922 _set_irg_link(irg, thing);
926 (get_irg_link)(const ir_graph *irg) {
927 return _get_irg_link(irg);
931 (get_irg_visited)(const ir_graph *irg) {
932 return _get_irg_visited(irg);
935 #ifdef INTERPROCEDURAL_VIEW
936 /** maximum visited flag content of all ir_graph visited fields. */
937 static ir_visited_t max_irg_visited = 0;
938 #endif /* INTERPROCEDURAL_VIEW */
941 set_irg_visited(ir_graph *irg, ir_visited_t visited) {
942 irg->visited = visited;
943 #ifdef INTERPROCEDURAL_VIEW
944 if (irg->visited > max_irg_visited) {
945 max_irg_visited = irg->visited;
947 #endif /* INTERPROCEDURAL_VIEW */
951 inc_irg_visited(ir_graph *irg) {
952 #ifdef INTERPROCEDURAL_VIEW
953 if (++irg->visited > max_irg_visited) {
954 max_irg_visited = irg->visited;
958 #endif /* INTERPROCEDURAL_VIEW */
961 #ifdef INTERPROCEDURAL_VIEW
963 get_max_irg_visited(void) {
966 for(i = 0; i < get_irp_n_irgs(); i++)
967 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
969 return max_irg_visited;
972 void set_max_irg_visited(int val) {
973 max_irg_visited = val;
977 inc_max_irg_visited(void) {
980 for(i = 0; i < get_irp_n_irgs(); i++)
981 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
983 return ++max_irg_visited;
985 #endif /* INTERPROCEDURAL_VIEW */
988 (get_irg_block_visited)(const ir_graph *irg) {
989 return _get_irg_block_visited(irg);
993 (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited) {
994 _set_irg_block_visited(irg, visited);
998 (inc_irg_block_visited)(ir_graph *irg) {
999 _inc_irg_block_visited(irg);
1002 /* Return the floating point model of this graph. */
1003 unsigned (get_irg_fp_model)(const ir_graph *irg) {
1004 return _get_irg_fp_model(irg);
1007 /* Sets the floating point model for this graph. */
1008 void set_irg_fp_model(ir_graph *irg, unsigned model) {
1009 irg->fp_model = model;
1013 * walker Start->End: places Proj nodes into the same block
1014 * as it's predecessors
1017 * @param env ignored
1019 static void normalize_proj_walker(ir_node *n, void *env) {
1022 ir_node *pred = get_Proj_pred(n);
1023 ir_node *block = get_nodes_block(pred);
1025 set_nodes_block(n, block);
1029 /* move Proj nodes into the same block as its predecessors */
1030 void normalize_proj_nodes(ir_graph *irg) {
1031 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
1032 set_irg_outs_inconsistent(irg);
1035 /* set a description for local value n */
1036 void set_irg_loc_description(ir_graph *irg, int n, void *description) {
1037 assert(0 <= n && n < irg->n_loc);
1039 if (! irg->loc_descriptions)
1040 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
1042 irg->loc_descriptions[n] = description;
1045 /* get the description for local value n */
1046 void *get_irg_loc_description(ir_graph *irg, int n) {
1047 assert(0 <= n && n < irg->n_loc);
1048 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1052 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources) {
1053 assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1054 assert((irg->reserved_resources & resources) == 0);
1055 irg->reserved_resources |= resources;
1058 void ir_free_resources(ir_graph *irg, ir_resources_t resources) {
1059 assert((irg->reserved_resources & resources) == resources);
1060 irg->reserved_resources &= ~resources;
1063 ir_resources_t ir_resources_reserved(const ir_graph *irg) {
1064 return irg->reserved_resources;
1068 /* Returns a estimated node count of the irg. */
1069 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg) {
1070 return _get_irg_estimated_node_cnt(irg);
1073 /* Returns the last irn index for this graph. */
1074 unsigned get_irg_last_idx(const ir_graph *irg) {
1075 return irg->last_node_idx;
1078 /* register additional space in an IR graph */
1079 size_t register_additional_graph_data(size_t size) {
1080 assert(!forbid_new_data && "Too late to register additional node data");
1082 if (forbid_new_data)
1085 return additional_graph_data_size += size;